#include
#include
/********************************************************************
* Parameters
*/
name menudirection = /Down;
persist(menudirection);
persist(@menu);
unpersist(defaulted);
unpersist(justification);
/********************************************************************
* Dimensions
*/
float minwidth()
{
return preferredwidth();
}
float preferredwidth()
{
float W;
if (abbreviated)
return OLButW;
gsave();
setfont(textfont);
W = DIWidth(str) + OLMenuButtonCapW2 + 5;
grestore();
return W;
}
/********************************************************************
* Action
*/
void action()
{
if (((struct menu)@menu).defaultactive())
((struct menu)@menu).execdefault(self);
}
/********************************************************************
* Painting
*/
void PaintLabel(displayitem i)
{
setcolor(FG);
setfont(textfont);
DIPaintLeft(i,OLButtonCapW,2,w - OLMenuButtonCapW2,OLButtonH - 4);
}
void PaintDefaultChoice(displayitem i, boolean active)
{
setcolor(FG);
setfont(textfont);
OLShow(i,OLButtonCapW,2,w - OLButtonCapW2,OLButtonH - 4);
if (!active) {
setcolor(BG);
path();
OLStipple();
}
}
void PaintButton(boolean down)
{
if (abbreviated) {
OLMenuBut(menudirection == /Down,down);
if (down) {
if ((((struct menu)@menu).defaultitem() == null) ||
(!((struct menu)@menu).defaultactive())) {
setcolor(BG);
path();
OLStipple();
}
}
} else {
if (down) {
OLButton(true,w);
PaintDefaultChoice(((struct menu)@menu).defaultitem(),
((struct menu)@menu).defaultactive());
} else {
OLMenuButton(menudirection == /Down,down,w);
PaintLabel(str);
}
}
if ((!@menu) || (!active)) {
setcolor(BG);
path();
OLStipple();
}
}
/********************************************************************
* creating the menu
*/
void setmenu(any *list)
{
if (promoted(/@menu)) {
delslave((struct menu)@menu);
unpromote(/@menu);
}
if (list) {
addslave((struct menu)(@menu = (menu)newobject(/menu)));
((struct menu)@menu).setmenu(list);
}
}
/********************************************************************
* Events
*/
void OnSelect()
{
if (@menu && (!busy) && active)
super.OnSelect();
}
void OnMenu()
{
if (@menu && (!busy) && active) {
if (abbreviated) {
OLMenuBut(menudirection == /Down,true);
if (menudirection == /Down)
((struct menu)@menu).showmenuSE(self,0,0);
else
((struct menu)@menu).showmenuE(self,OLButW,OLButH/2);
} else {
OLMenuButton(menudirection == /Down,true,w);
PaintLabel(str);
if (menudirection == /Down)
((struct menu)@menu).showmenuS(self,w/2,0);
else
((struct menu)@menu).showmenuE(self,w,OLButtonH/2);
}
PaintButton(false);
}
}
void setmenudirection(name dir)
{
if (dir != menudirection) {
softpromote(/menudirection,dir);
gexec(/Paint);
}
}