UPLOAD - DOSUIT07.ZIP - MENU.CPP

 
Output of file : MENU.CPP contained in archive : DOSUIT07.ZIP

#ifdef ALL
#define MENUA
#define MENUB
#define MENUC
#define MENUD
#define MENUE
#define MENUF
#define MENUG
#define MENUH
#define MENUI
#define MENUJ
#define MENUK
#define MENUL
#define MENUM
#endif
#ifndef MENUA
#define LIBRARY_MODULE
#endif

/*
* Menus - bar and pop-down.
*/
#include
#include
#include
#include "menu.hpp"
#include "list.hpp"
#include "screen.hpp"
#include "event.hpp"
#include "command.hpp"
#include "text.hpp"
#include "applic.hpp"
#include "button.hpp"

#ifdef MENUA
implement(LCollection,Option)

void Option::build(const char *text,Keys hotkey)
{
quick = checkForTilde(text);
hot = (hotkey == Kauto) ? alt(quick) : hotkey;
}

Option::Option(const char *text,Command *command,Keys hotkey)
: ListElement(text), cmd(command), disabled(0)
{
build(text,hotkey);
}

Option::Option(const char *text,int (*func)(const char *),Keys hotkey)
: ListElement(text), cmd(new FunctionCommand(func)), disabled(0)
{
build(text,hotkey);
}

Option::~Option()
{
if(cmd)
delete cmd;
}

int Option::doit()
{
return (cmd && !disabled) ? cmd->doit(name()) : 0;
}

coord Option::minwidth() const
{
int w = strlen(name());
if(quick)
w--;
if(hot)
w += maxKeynameLength + 1;
return w;
}

void Option::paint(const Rectangle &t, Window *w, const Rectangle &clip, color col)
{
paintWithoutTilde(w,name(),col,t.topleft(),clip);
if(hotkey())
{
Point p = { t.right() - maxKeynameLength + 1, t.top() };
w->printstring(p,clip,col,keyname(hotkey()));
}
}

#endif

#ifdef MENUB
Menu::Menu(const char *name,const ColorSet &c)
: List(options,3,3,name), kbdhandler(0), popwin(new PopWindow(this,c))
{
}
#endif

#ifdef MENUC
Menu::Menu(const char *name,const ColorSet &c,Option *o,...)
: List(options,3,3,name), kbdhandler(0), popwin(new PopWindow(this,c))
{
va_list args;

va_start(args,o);
addvalist(o,args);
va_end(args);
}

Menu::Menu(const char *name,Option *o,...)
: List(options,3,3,name), kbdhandler(0), popwin(new PopWindow(this))
{
va_list args;

va_start(args,o);
addvalist(o,args);
va_end(args);
}
#endif

#ifdef MENUD
Menu::Menu(const char *name,const LCollection(Option) &opts,const ColorSet &c)
: List(options,3,opts.size()+2,name), kbdhandler(0),
popwin(new PopWindow(this,c))
{
*this + opts;
}

#endif

#ifdef MENUE
Menu::~Menu()
{
Option *o;

options.deleteall();
if(kbdhandler)
kbdhandler->contentsDeleted(this);
if(popwin)
{
VALIDATE(popwin);
popwin->contentsDeleted(this);
delete popwin;
popwin = 0;
window = 0;
container = 0;
}
}

int Menu::pick()
{
int l = line();

if(l >= 0)
{
if(options[l]->doit())
{
popwin->resetfocus();
if(kbdhandler)
{
kbdhandler->menudone();
kbdhandler->clearfocus();
}
return 1;
}
else
select(l);
}
return 0;
}

void Menu::resetfocus()
{
if(testcFlag(CFfocus))
{
List::resetfocus();
if(!popwin || !popwin->inspecting())
{
if(kbdhandler)
kbdhandler->unfocus();
deselect();
}
}
}

int Menu::leftup(MouseEvent &e)
{
List::leftup(e); // reset mouse focus etc.
return List::leftdoubleclick(e); // pick() if mouse on seln.
}

int Menu::rightclick(MouseEvent &)
{
if(!kbdhandler)
return 0;
kbdhandler->menudone();
kbdhandler->setfocus();
return 1;
}

int Menu::kbdevent(KeyboardEvent& e)
{
int r = 0;

switch(e.value())
{
case Kright:
case Kleft:
if(kbdhandler && kbdhandler->getcontainer())
r = kbdhandler->getcontainer()->kbdevent(e);
break;
case Kesc:

if(kbdhandler)
{
kbdhandler->menudone();
kbdhandler->setfocus();
r = 1;
}
break;
default:
if(e.value() >= ' ' && e.value() < 256)
{
int c = e.value();
Option *o;
LIterator(Option) next(options);

c = toupper(c);
for(int i = 0; (o = next()) != 0; i++)
{
if(c == o->quickkey() && select(i) && pick())
return 1;
}
}
}
if(!r)
r = List::kbdevent(e);
if(!r && e.value())
r = dohotkey(e); // test for hot keys in this menu
return 1; // prevent other hotkeys working
}

int Menu::dohotkey(KeyboardEvent& e)
{
LIterator(Option) next(options);
Option *o;

for(int i = 0; (o = next()) != 0; i++)
{
if(e.value() == o->hotkey() && select(i) && pick())
{
#ifndef NDEBUG
if(debug)
fprintf(debug,"%s->hotkey(%s)\n",debuginfo(),keyname(o->hotkey()));
#endif
return 1;
}
}
return List::dohotkey(e);
}

int Menu::help()
{
int l = line();

if(l >= 0 && Application::help(options[l]->name()))
return 1;
return Application::help(name());
}
#endif

#ifdef MENUF
void Menu::addOption(Option *o)
{
options.append(o);
resize(1);
changeCollection();
}

Menu& Menu::operator+ (const LCollection(Option) &c)
{
options + c;
resize(1);
changeCollection();
popwin->setwidth(width());
popwin->setheight(height());
return *this;
}
#endif

#ifdef MENUG
void Menu::addvalist(Option *o,va_list args)
{
options.append(o);
options.appendvalist(args);
resize(1);
changeCollection();
popwin->setwidth(width());
popwin->setheight(height());
}
#endif

#ifdef MENUH
void Menu::pop(VObject *v)
{
popwin->popin(v);
}
#endif

#ifdef MENUI
MenuButton::~MenuButton()
{
if(menu)
{
VALIDATE(menu);
delete menu;
}
}

void MenuButton::popmenu()
{
if(menu)
{
menu->pop(this);
setFlag(SFfocus);
if(kbdhandler)
kbdhandler->menustarted();
}
}
void MenuButton::contentsDeleted(VObject* v)
{
if(v == menu)
menu = 0;
}

int MenuButton::setpressed()
{
if(testFlag(SFdisabled))
return 0;
Control::setfocus();
popmenu();
return 1;
}
int MenuButton::setfocus(int tabstop)
{
if(testcFlag(CFfocus))
return 1;
if(!Control::setfocus(tabstop))
return 0;
if(container->testFlag(SFselected))
popmenu();
setFlag(SFfocus); // make sure, because Menu may have reset it
return 1;
}

coord MenuButton::minwidth() const
{
return lenWithoutTilde(name()) + 1;
}

void MenuButton::paint(Rectangle r)
{
r &= *this;
if(r.right() == right())
{
if(r.width() <= 1)
return;
r.setwidth(r.width() - 1);
}
Control::paint(r);
paintWithoutTilde(window,name(),getcolor(),topleft(),r);
}

int MenuButton::leftdown(MouseEvent&)
{
if(setfocus())
{
popmenu();
menu->setFlag(SFmousein);
menu->setmoufocus();
}
return 1;
}

int MenuButton::kbdevent(KeyboardEvent& e)
{
if(e.value() == '\r' || e.value() == '\n')
{
popmenu();
return 1;
}
return Control::kbdevent(e);
}

int MenuButton::dohotkey(KeyboardEvent& e)
{
int r = 0;

if(e.value() == hotkey() && setpressed())
r = 1;
if(!r && menu)
r = menu->dohotkey(e);
return r;
}
#endif

#ifdef MENUJ
MenuButton::MenuButton(const char *n,Menu *m,Keys hotkey)
: Control(lenWithoutTilde(n)+1,1,n), menu(m), quick(checkForTilde(n))
{
hot = (hotkey == Kauto) ? alt(quick) : hotkey;
setFlag(SFshowfocus);
m->kbdhandler = this;
}
#endif

#ifdef MENUK
implement(OCollection,MenuButton);

MenuButton::MenuButton(const char *n,Keys hotkey,Option *o,...)
: Control(lenWithoutTilde(n)+1,1,n), menu(new Menu(n)), quick(checkForTilde(n))
{
hot = (hotkey == Kauto) ? alt(quick) : hotkey;

va_list args;

va_start(args,o);
menu->addvalist(o,args);
va_end(args);
setFlag(SFshowfocus);
menu->kbdhandler = this;
}

MenuButton::MenuButton(const char *n,Keys hotkey,const LCollection(Option)& c)
: Control(lenWithoutTilde(n)+1,1,n), menu(new Menu(n,c)), quick(checkForTilde(n))
{
hot = (hotkey == Kauto) ? alt(quick) : hotkey;

setFlag(SFshowfocus);
menu->kbdhandler = this;
}
#endif

#ifdef MENUL
MenuBar::MenuBar(Keys hotkey,MenuButton *b,...)
: HCluster("MenuBar",AlignFlag(AFHleft|AFVtop)), hot(hotkey)
{
va_list args;

va_start(args,b);
addvalist(b,args);
for(b->kbdhandler = this; (b = va_arg(args,MenuButton *)) != 0; b->kbdhandler = this)
;
va_end(args);
}

MenuBar::MenuBar(Keys hotkey, const OCollection(MenuButton) &c)
: HCluster(c,"MenuBar",AlignFlag(AFHleft|AFVtop)), hot(hotkey)
{
OIterator(MenuButton) next(c);
MenuButton *b;

while((b = next()) != 0)
b->kbdhandler = this;
}

void MenuBar::setMenuColors(const ColorSet &c)
{
ObjectIterator next(objects);
MenuButton *b;

while((b = (MenuButton *)next()) != 0)
b->setMenuColor(c);
}

coord MenuBar::maxwidth() const
{
coord w = minwidth();
if(hot)
w += strlen(keyname(hot)) + 10;
return w;
}

void MenuBar::paint(Rectangle r)
{
HCluster::paint(r);
if(hot && width() >= maxwidth())
{
const char *s = form("%s for menu",keyname(hot));
Point p = { right() - strlen(s) + 1, top() };
window->printstring(p,r,getcolor(),s);
}
}

int MenuBar::kbdevent(KeyboardEvent& e)
{
if(e.value() == Kesc && kbdfocus)
{
kbdfocus->clearfocus();
return 1;
}
else if(e.value() >= ' ' && e.value() < 256)
{
char c = e.value();
ObjectIterator next(objects);
MenuButton *b;

c = toupper(c);
while((b = (MenuButton *)next()) != 0)
{
if(c == b->quickkey() && b->setpressed())
return 1;
}
}
return HCluster::kbdevent(e);
}

int MenuBar::dohotkey(KeyboardEvent& e)
{
if(e.value() == hot && setfocus())
{
#ifndef NDEBUG
if(debug)
fprintf(debug,"%s->hotkey(%s)\n",debuginfo(),keyname(hot));
#endif
return 1;
}
return HCluster::dohotkey(e);
}
#endif

#ifdef MENUM
TickOption::TickOption(const char *text, int &result, Keys hotkey,
Command *command)
: Option(text, command, hotkey), tick(result)
{
}

int TickOption::doit()
{
tick = !tick;
Option::doit();
return 1;
}

coord TickOption::minwidth() const
{
return Option::minwidth() + 2;
}

void TickOption::paint(const Rectangle &at, Window *w, const Rectangle &clip,
color col)
{

if(clip.encloses(at.topleft()))
w->printstring(at.topleft(),clip,col,tick ? Tick : " ");
Rectangle r(at.left() + 2, at.top(), at.right(), at.bottom());
Option::paint(r, w, clip, col);
}

#endif