#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); } }