1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720 |
- #include <precomp.h>
- #include <api/wnd/api_window.h>
- #include <api/locales/xlatstr.h>
- #ifndef WASABI_WANT_FF_POPUP
- #include "popup.h"
- #ifdef _WIN32
- #include "../../../Plugins/General/gen_ff/wa2frontend.h"
- extern HINSTANCE hInstance;
- #endif
- PopupMenu::PopupMenu()
- {
- hmenu = NULL;
- parent = NULL;
- }
- PopupMenu::PopupMenu(ifc_window *_parent)
- {
- hmenu = NULL;
- parent = _parent;
- }
- PopupMenu::PopupMenu(PopupMenu *_parent)
- {
- hmenu = NULL;
- parent = _parent->getParent();
- }
- PopupMenu::~PopupMenu()
- {
- invalidateMenu();
- entries.deleteAll();
- sortedentries.removeAll();
- }
- void PopupMenu::addSubMenu(PopupMenu *menu, const wchar_t *text, int disabled)
- {
- invalidateMenu();
- PopupMenuEntry *e = new PopupMenuEntry(text, -1, menu, 0, disabled);
- entries.addItem(e);
- sortedentries.addItem(e);
- }
- void PopupMenu::addSubMenuCallback(const wchar_t *text, PopupMenuCallback *cb, int param)
- {
- invalidateMenu();
- PopupMenuEntry *e = new PopupMenuEntry(text, -1, NULL, 0, 0, cb, param);
- entries.addItem(e);
- sortedentries.addItem(e);
- }
- void PopupMenu::addCommand(const wchar_t *text, int command, int checked, int disabled, int addpos)
- {
- invalidateMenu();
- PopupMenuEntry *e = new PopupMenuEntry(text, command, NULL, checked, disabled);
- entries.addItem(e);
- sortedentries.addItem(e, addpos);
- }
- void PopupMenu::addSeparator(int addpos)
- {
- invalidateMenu();
- PopupMenuEntry *e = new PopupMenuEntry(NULL, -1, NULL, 0, 0);
- entries.addItem(e);
- sortedentries.addItem(e, addpos);
- };
- void PopupMenu::checkCommand(int cmd, int check)
- {
- invalidateMenu();
- PopupMenuEntry *e = sortedentries.findItem((const wchar_t *) & cmd);
- if (e) e->setChecked(check);
- }
- void PopupMenu::disableCommand(int cmd, int disable)
- {
- invalidateMenu();
- PopupMenuEntry *e = sortedentries.findItem((const wchar_t *) & cmd);
- if (e) e->setDisabled(disable);
- }
- int PopupMenu::popAtXY(int x, int y, int native)
- {
- rebuildMenu();
- #ifdef _WIN32
- if (!native)
- return DoTrackPopup(getOSMenuHandle(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, (parent ? parent->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd())) - 1;
- else
- return TrackPopupMenuEx(getOSMenuHandle(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, (parent ? parent->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd()), NULL) - 1;
- #elif defined(__APPLE__)
- return PopUpMenuSelect(getOSMenuHandle(), x, y, 0);
- #endif
- }
- int PopupMenu::popAnchored(int type)
- { // dropped off the sourceWnd given above
- #ifdef _WIN32
- int flag = 0;
- switch (type)
- {
- case POPUP_ANCHOR_UL: flag |= TPM_LEFTALIGN | TPM_TOPALIGN; break;
- case POPUP_ANCHOR_LL: flag |= TPM_LEFTALIGN | TPM_BOTTOMALIGN; break;
- case POPUP_ANCHOR_UR: flag |= TPM_RIGHTALIGN | TPM_TOPALIGN; break;
- case POPUP_ANCHOR_LR: flag |= TPM_RIGHTALIGN | TPM_BOTTOMALIGN; break;
- }
- #endif
- rebuildMenu();
- int x, y;
- Wasabi::Std::getMousePos(&x, &y);
- #ifdef _WIN32
- return DoTrackPopup(getOSMenuHandle(), flag | TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, (parent ? parent->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd())) - 1;
- #elif defined(__APPLE__)
- return PopUpMenuSelect(getOSMenuHandle(), x, y, 0);
- #endif
- }
- int PopupMenu::popAtMouse()
- {
- rebuildMenu();
- int x, y;
- Wasabi::Std::getMousePos(&x, &y);
- #ifdef _WIN32
- return DoTrackPopup(getOSMenuHandle(), TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD | TPM_LEFTBUTTON | TPM_RIGHTBUTTON, x, y, (parent ? parent->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd())) - 1;
- #elif defined(__APPLE__)
- return PopUpMenuSelect(getOSMenuHandle(), x, y, 0);
- #endif
- }
- int PopupMenu::getNumCommands()
- {
- return entries.getNumItems();
- }
- const wchar_t *PopupMenu::getCommandText(int command)
- {
- PopupMenuEntry *e = sortedentries.findItem((const wchar_t *) &command);
- if (e) return e->getText();
- return NULL;
- }
- OSMENUHANDLE PopupMenu::getOSMenuHandle()
- {
- rebuildMenu();
- return hmenu;
- }
- void PopupMenu::rebuildMenu()
- {
- #ifdef WIN32
- if (hmenu != NULL) return ;
- hmenu = CreatePopupMenu();
- int i = 0;
- foreach(entries)
- PopupMenuEntry *e = entries.getfor();
- OSMENUHANDLE submenu = NULL;
- if (e->getCallback())
- {
- PopupMenu *m = e->getCallback()->popupMenuCallback(this, e->getCallbackParam());
- if (m) submenu = m->getOSMenuHandle();
- }
- else if (e->isSubmenu())
- {
- submenu = e->getSubmenu()->getOSMenuHandle();
- }
- InsertMenuW(hmenu, i++, MF_BYPOSITION | (e->getChecked() ? MF_CHECKED : MF_UNCHECKED) | (e->getDisabled() ? MF_GRAYED : 0) | (e->isSeparator() ? MF_SEPARATOR : (e->isSubmenu() ? MF_POPUP : 0) | (e->getText() ? MF_STRING : 0)), e->isSubmenu() ? (UINT_PTR)submenu : e->getCommand() + 1, e->getText());
- endfor;
- #else
- if (hmenu != NULL) return ;
- CreateNewMenu(0, 0, &hmenu);
- foreach(entries)
- PopupMenuEntry *e = entries.getfor();
- OSMENUHANDLE submenu = NULL;
- if (e->getCallback())
- {
- PopupMenu *m = e->getCallback()->popupMenuCallback(this, e->getCallbackParam());
- if (m) submenu = m->getOSMenuHandle();
- }
- else if (e->isSubmenu())
- {
- submenu = e->getSubmenu()->getOSMenuHandle();
- }
-
- const wchar_t *name = e->getText();
- CFStringRef menuStr = CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8 *)name, wcslen(name)*sizeof(wchar_t), kCFStringEncodingUTF32, false);
- MenuItemIndex newMenuItem;
- MenuItemAttributes menuAttr = kMenuItemAttrIgnoreMeta;
- if (e->getDisabled())
- menuAttr|=kMenuItemAttrDisabled;
- if (e->isSeparator())
- menuAttr|=kMenuItemAttrSeparator;
- AppendMenuItemTextWithCFString(hmenu, menuStr, menuAttr, e->getCommand(), &newMenuItem);
- if (submenu)
- SetMenuItemHierarchicalMenu(hmenu, newMenuItem, submenu);
- if (e->getChecked())
- CheckMenuItem(hmenu, newMenuItem, true);
-
- CFRelease(menuStr);
- endfor;
- #endif
- }
- void PopupMenu::invalidateMenu()
- {
- #ifdef WIN32
- if (hmenu) DestroyMenu(hmenu);
- #elif defined(__APPLE__)
- if (hmenu) DisposeMenu(hmenu);
- #endif
- hmenu = NULL;
- }
- void PopupMenu::abort()
- {
- #ifdef WIN32
- HWND w = (parent ? parent->gethWnd() : WASABI_API_WND->main_getRootWnd()->gethWnd());
- PostMessage(w, WM_LBUTTONDOWN, 0, 0xdeadc0de);
- PostMessage(w, WM_LBUTTONUP, 0, 0xdeadc0de);
- #elif defined(__APPLE__)
- CancelMenuTracking(hmenu, true, 0);
- #endif
- }
- #else // WASABI_WANT_FF_POPUP
- #include <bfc/api/api_wnd.h>
- #include <bfc/api/api_syscb.h>
- #include "popup.h"
- #include <bfc/notifmsg.h>
- #include <studio/assert.h>
- #include <studio/api.h>
- #include <bfc/wasabi_std.h>
- #include <common/xlatstr.h>
- #include <bfc/wnds/buttwnd.h>
- #include <bfc/util/pathparse.h>
- #include <bfc/attribs/cfgitem.h>
- #include <common/script/c_script/c_guiobject.h>
- #include <common/script/c_script/c_menubutton.h>
- #include <common/script/scriptguid.h>
- #include <common/menusurface.h>
- #ifndef WANT_NEW_POPUPMENU
- #define SELMARGIN 1
- // todo:
- // check marks
- // more?
- PopupMenu::PopupMenu(ifc_window *sourceWnd)
- {
- ASSERT(sourceWnd != NULL);
- setStartHidden(1);
- setRenderRatio(1.0);
- parentRootWnd = sourceWnd;
- parentWnd = sourceWnd->getOsWindowHandle();
- reverse_side = 0;
- kbdhooked = 0;
- keyctrl = 0;
- toplevelmenu = 0;
- chainmenu = NULL;
- lastxy.x = lastxy.y = -1;
- WASABI_API_WND->appdeactivation_push_disallow(this);
- init(sourceWnd->getOsModuleHandle(), parentWnd, TRUE);
- WASABI_API_WND->appdeactivation_pop_disallow(this);
- }
- PopupMenu::PopupMenu()
- {
- setStartHidden(1);
- setRenderRatio(1.0);
- parentRootWnd = NULL;
- parentWnd = INVALIDOSWINDOWHANDLE;
- chainmenu = NULL;
- reverse_side = 0;
- kbdhooked = 0;
- toplevelmenu = 0;
- keyctrl = 0;
- lastxy.x = lastxy.y = -1;
- WASABI_API_WND->appdeactivation_push_disallow(this);
- init(hInstance, WASABI_API_WND->main_getRootWnd()->gethWnd(), TRUE);
- WASABI_API_WND->appdeactivation_pop_disallow(this);
- }
- PopupMenu::PopupMenu(HWND sourceWnd)
- {
- parentRootWnd = NULL;
- parentWnd = sourceWnd;
- setStartHidden(1);
- setRenderRatio(1.0);
- reverse_side = 0;
- kbdhooked = 0;
- toplevelmenu = 0;
- keyctrl = 0;
- chainmenu = NULL;
- lastxy.x = lastxy.y = -1;
- WASABI_API_WND->appdeactivation_push_disallow(this);
- init(hInstance, sourceWnd, TRUE);
- WASABI_API_WND->appdeactivation_pop_disallow(this);
- }
- PopupMenu::PopupMenu(PopupMenu *sourceWnd)
- {
- parentRootWnd = sourceWnd;
- parentWnd = sourceWnd->gethWnd();
- setStartHidden(1);
- setRenderRatio(1.0);
- reverse_side = 0;
- kbdhooked = 0;
- toplevelmenu = 0;
- chainmenu = NULL;
- keyctrl = 0;
- lastxy.x = lastxy.y = -1;
- WASABI_API_WND->appdeactivation_push_disallow(this);
- init(sourceWnd, TRUE);
- WASABI_API_WND->appdeactivation_pop_disallow(this);
- }
- int PopupMenu::onInit()
- {
- POPUPMENU_PARENT::onInit();
- bdown = 0;
- lastitem = -1;
- rcp = 0;
- openmenuid = -1;
- timerset = 0;
- timeritem = -1;
- rcode = -1;
- toplevelmenu = 0;
- disable_autopop = 0;
- popupdelay = 250; //TODO: Config
- #ifdef WASABI_COMPILE_CONFIG
- // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
- const GUID uioptions_guid =
- { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
- setTransparency(_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), "Popup menu alpha", 255));
- #else
- setTransparency(255);
- #endif
- tex = "wasabi.popup.menu.background";
- ful = "wasabi.popup.menu.border.topLeft";
- fur = "wasabi.popup.menu.border.topRight";
- fll = "wasabi.popup.menu.border.bottomLeft";
- flr = "wasabi.popup.menu.border.bottomRight";
- fl = "wasabi.popup.menu.border.left";
- fr = "wasabi.popup.menu.border.right";
- ft = "wasabi.popup.menu.border.top";
- fb = "wasabi.popup.menu.border.bottom";
- sl = "wasabi.popup.menu.selection.left";
- sr = "wasabi.popup.menu.selection.right";
- sc = "wasabi.popup.menu.selection.center";
- return 1;
- }
- PopupMenu::~PopupMenu()
- {
- if (kbdhooked)
- {
- WASABI_API_WND->unhookKeyboard(this);
- kbdhooked = 0;
- }
- int x, n;
- n = items.getNumItems();
- for (x = 0; x < n; x ++)
- {
- if (items[x])
- {
- if (items[x]->butt) delete items[x]->butt;
- if (items[x]->menu) delete items[x]->menu;
- delete items[x];
- }
- }
- }
- void PopupMenu::addSubMenu(PopupMenu *menu, const wchar_t *text, int disabled)
- {
- ASSERT(text != NULL);
- ButtonWnd *b = new ButtonWnd();
- b->init(this);
- b->setParent(this);
- b->setNotifyId( -1);
- b->setButtonText(translateButtonText(text), 14);
- // b->setTextJustification(BUTTONJUSTIFY_LEFT);
- b->setTextAlign(TEXTALIGN_LEFT);
- b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
- if (disabled) b->enableButton(FALSE);
- ItemT *t = new ItemT;
- t->issep = 0;
- t->butt = b;
- t->menu = menu;
- t->cmd = -1;
- t->cb = NULL;
- items.addItem(t);
- }
- void PopupMenu::addSubMenuImage(PopupMenu *menu, const char *bitmap, const char *pushedbitmap, const char *highlightbitmap)
- {
- ButtonWnd *b = new ButtonWnd();
- b->init(this);
- b->setParent(this);
- b->setBitmaps(bitmap, pushedbitmap, highlightbitmap);
- b->setBitmapCenter(1);
- b->setNotifyId( -1);
- b->setAutoDim(1);
- b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
- ItemT *t = new ItemT;
- t->issep = 0;
- t->butt = b;
- t->menu = menu;
- t->cb = NULL;
- t->cmd = -1;
- items.addItem(t);
- }
- void PopupMenu::addSubMenuCallback(const wchar_t *text, PopupMenuCallback *cb, int param)
- {
- ASSERT(text != NULL);
- ASSERT(cb != NULL);
- ButtonWnd *b = new ButtonWnd();
- b->init(this);
- b->setParent(this);
- b->setNotifyId( -1);
- b->setButtonText(translateButtonText(text), 14);
- // b->setTextJustification(BUTTONJUSTIFY_LEFT);
- b->setTextAlign(TEXTALIGN_LEFT);
- b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
- ItemT *t = new ItemT;
- t->issep = 0;
- t->butt = b;
- t->menu = 0;
- t->cb = cb;
- t->cbparam = param;
- t->cmd = -1;
- items.addItem(t);
- }
- void PopupMenu::addSeparator(int addpos)
- {
- ButtonWnd *b = new ButtonWnd();
- b->init(this);
- b->setParent(this);
- b->setNotifyId( -1);
- b->setBitmaps("wasabi.popup.menu.seperator");
- b->setBitmapCenter(0);
- b->enableButton(0);
- b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
- ItemT *t = new ItemT;
- t->issep = 1;
- t->butt = b;
- t->menu = 0;
- t->cb = NULL;
- t->cmd = -1;
- items.addItem(t, addpos);
- }
- void PopupMenu::addCommandImage(const char *bitmap, const char *pushedbitmap, const char *highlightbitmap, int command, int checked, int disabled, int addpos)
- {
- ButtonWnd *b = new ButtonWnd();
- b->init(this);
- b->setParent(this);
- b->setBitmaps(bitmap, pushedbitmap, highlightbitmap);
- b->setBitmapCenter(1);
- b->setNotifyId(command);
- b->enableButton(disabled ? 0 : 1);
- b->setChecked(checked ? 1 : 0);
- b->setAutoDim(1);
- b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
- ItemT *t = new ItemT;
- t->issep = 0;
- t->butt = b;
- t->menu = 0;
- t->cb = NULL;
- t->cmd = -1;
- items.addItem(t);
- }
- void PopupMenu::addCommand(const wchar_t *_txt, int command, int checked, int disabled, int addpos)
- {
- if (!_txt)
- {
- addSeparator();
- return ;
- }
- String txt = translateButtonText(_txt);
- ButtonWnd *b = new ButtonWnd();
- b->init(this);
- b->setParent(this);
- b->setNotifyId(disabled ? -1 : command);
- #ifdef WASABI_COMPILE_LOCALES
- const wchar_t *bind = (command != 0) ? WASABI_API_LOCALE->locales_getBindFromAction(command) : NULL;
- if (bind) txt += StringPrintfW(L"\t%s", bind);
- #endif
- b->setButtonText(txt);
- // b->setTextJustification(BUTTONJUSTIFY_LEFT);
- b->setTextAlign(TEXTALIGN_LEFT);
- b->enableButton(disabled ? 0 : 1);
- b->setChecked(checked);
- if (checked == 2) b->setAlpha(128);
- b->setColors("wasabi.popup.text", "wasabi.popup.hiliteText", "wasabi.button.dimmedText");
- ItemT *t = new ItemT;
- t->issep = 0;
- t->butt = b;
- t->menu = 0;
- t->cmd = command;
- t->cb = NULL;
- ASSERT(PTRLIST_POS_LAST == -1); //BU
- items.addItem(t, addpos);
- }
- void PopupMenu::disableCommand(int cmd, int disable)
- {
- for (int i = 0;i < items.getNumItems();i++)
- if (items.enumItem(i)->cmd == cmd)
- {
- if (items.enumItem(i)->butt)
- items.enumItem(i)->butt->enableButton(!!!disable);
- break;
- }
- }
- void PopupMenu::checkCommand(int cmd, int check)
- {
- for (int i = 0;i < items.getNumItems();i++)
- if (items.enumItem(i)->cmd == cmd)
- {
- if (items.enumItem(i)->butt)
- items.enumItem(i)->butt->setChecked(check);
- break;
- }
- }
- const wchar_t *PopupMenu::getCommandText(int command)
- {
- for (int i = 0;i < items.getNumItems();i++)
- if (items.enumItem(i)->cmd == command && items.enumItem(i)->butt)
- return items.enumItem(i)->butt->getName();
- return NULL;
- }
- int PopupMenu::popAtXY(int x, int y)
- {
- toplevelmenu = 1;
- rcode = -1;
- if (items.getNumItems())
- {
- POINT pt = {x, y};
- #ifdef WIN32
- HWND oldcw = GetCapture(); // nonportable
- ifc_window *oldcrw = (ifc_window*)GetWindowLong(oldcw, GWL_USERDATA);
- if (oldcrw != NULL) oldcrw->cancelCapture();
- #endif
- WASABI_API_SYSCB->syscb_registerCallback(static_cast<SkinCallbackI*>(this));
- showAtXY(x, y, &rcode);
- beginCapture();
- MSG msg;
- #ifdef WIN32
- SetCursor(LoadCursor(NULL, IDC_ARROW)); // NONPORTABLE
- #endif
- while (rcode == -1 && GetMessage( &msg, INVALIDOSWINDOWHANDLE, 0, 0 ))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- endCapture();
- hide();
- // if (hadcapture && under) under->beginCapture();
- #ifdef WIN32
- if (rcode == -2 || rcode == -3)
- {
- DWORD p = GetMessagePos();
- POINT pt;
- pt.x = (signed short)LOWORD(p);
- pt.y = (signed short)HIWORD(p);
- HWND w = WindowFromPoint(pt);
- ScreenToClient(w, &pt);
- p = (pt.x & 0xFFFF) | (pt.y << 16);
- //if (under) under->getRootParent()->wndProc(under->getRootParent()->gethWnd(), WM_MOUSEMOVE, 0, p);
- //PostMessage(w, (rcode == -2) ? WM_MOUSEMOVE : WM_RBUTTONDOWN, 0, p);
- //PostMessage(w, (rcode == -2) ? WM_LBUTTONDOWN : WM_RBUTTONDOWN, 0, p);
- }
- #else
- DebugString("portme: popup.cpp pass on click");
- #endif
- }
- WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<SkinCallbackI*>(this));
- //DebugString("appdeactivation_pop_disallow\n");
- WASABI_API_WND->appdeactivation_pop_disallow(this);
- onPostPop(rcode);
- #ifdef WASABI_COMPILE_SKIN
- if (!switchskinto.isempty())
- {
- WASABI_API_SKIN->skin_switchSkin(switchskinto.getNonConstVal());
- switchskinto = "";
- }
- #endif
- return rcode;
- }
- void PopupMenu::showAtXY(int x, int y, int *rc, int revside, int parentW)
- {
- int i, n;
- int w = 0, h = 0;
- lastitem = -1;
- rcp = rc;
- n = items.getNumItems();
- for (i = 0; i < n; i ++)
- {
- if (items[i]->menu || items[i]->cb)
- items[i]->butt->setRightBitmap("wasabi.popup.menu.submenu");
- if (!items[i]->butt->getChecked()) items[i]->butt->setChecked( -1);
- h += items[i]->butt->getHeight();
- items[i]->butt->setUseBaseTexture(0);
- items[i]->butt->setBorders(0);
- int tw = items[i]->butt->getWidth();
- if (w < tw)w = tw;
- }
- int neww = w + 6 + fl.getWidth() + fr.getWidth();
- int newh = h + 6 + ft.getHeight() + fb.getHeight();
- POINT p = {x, y};
- RECT vp;
- Std::getViewport(&vp, &p);
- // maintain parent's reversal state
- reverse_side = revside;
- int savx = x;
- if (reverse_side) x -= (neww + parentW);
- if (x + neww > vp.right || x < 0)
- {
- reverse_side = !reverse_side;
- x = savx;
- if (reverse_side) x -= (neww + parentW);
- }
- if (y + newh > vp.bottom) y -= newh;
- if (x < vp.left) x = vp.left;
- if (y < vp.top) y = vp.top;
- resize(x, y, neww, newh);
- h = 0;
- for (i = 0; i < n; i ++)
- {
- int lh = h;
- h += items[i]->butt->getHeight();
- items[i]->butt->resize(3 + fl.getWidth(), 3 + lh + ft.getHeight(), w, h - lh);
- items[i]->butt->setHilite(0);
- items[i]->butt->setPushed(0);
- }
- WASABI_API_WND->appdeactivation_push_disallow(this);
- #ifdef WIN32
- SetWindowPos(gethWnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- #elif defined(LINUX)
- Atom NET_STATE = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE", True );
- Atom state[2];
- state[0] = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE_SKIP_TASKBAR", True );
- state[1] = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE_ABOVE", True );
- if ( NET_STATE && state[0] && state[1] )
- {
- XChangeProperty( Linux::getDisplay(), gethWnd(), NET_STATE, XA_ATOM, 32,
- PropModeReplace, (unsigned char *)state, 2 );
- }
- #endif
- WASABI_API_WND->appdeactivation_pop_disallow(this);
- setVisible(1);
- }
- void PopupMenu::onSetVisible(int v)
- {
- POPUPMENU_PARENT::onSetVisible(v);
- if (v && !kbdhooked)
- {
- WASABI_API_WND->hookKeyboard(this);
- kbdhooked = 1;
- }
- else if (!v && kbdhooked)
- {
- WASABI_API_WND->unhookKeyboard(this);
- kbdhooked = 0;
- }
- }
- void PopupMenu::hide()
- {
- if (lastitem >= 0 && items[lastitem]->menu)
- {
- items[lastitem]->menu->hide();
- lastitem = -1;
- }
- setVisible(0);
- }
- int PopupMenu::popAnchored(int type)
- {
- RECT wr;
- if (parentRootWnd != NULL)
- {
- parentRootWnd->getWindowRect(&wr);
- }
- else if (parentWnd != INVALIDOSWINDOWHANDLE)
- {
- #ifdef WIN32
- GetWindowRect(parentWnd, &wr);
- #else
- DebugString("portme PopupMenu::popAnchored\n");
- #endif
- }
- else
- {
- ASSERTALWAYS("can't call popAnchored without instantiating with a parent window");
- }
- switch (type)
- {
- case POPUP_ANCHOR_UL: return popAtXY(wr.left, wr.top);
- case POPUP_ANCHOR_LL: return popAtXY(wr.left, wr.bottom);
- case POPUP_ANCHOR_UR: return popAtXY(wr.right, wr.top);
- case POPUP_ANCHOR_LR: return popAtXY(wr.right, wr.bottom);
- }
- return 0;
- }
- int PopupMenu::popAtMouse()
- {
- int x, y;
- Std::getMousePos(&x, &y);
- return popAtXY(x, y);
- }
- int PopupMenu::childNotify(ifc_window *child, int msg, intptr_t p1, intptr_t p2)
- {
- if (msg == ChildNotify::BUTTON_LEFTPUSH || msg == ChildNotify::BUTTON_RIGHTPUSH)
- {
- for (int i = 0;i < items.getNumItems();i++)
- {
- if (child == items[i]->butt && (items[i]->menu || items[i]->cb))
- {
- if (!items[i]->butt->getEnabled()) continue;
- if (items[i]->cb) initMenuCallback(i);
- if (!items[i]->menu) continue;
- if (openmenuid == i) continue;
- RECT r;
- if (openmenuid >= 0)
- {
- items[openmenuid]->menu->hide();
- openmenuid = -1;
- }
- items[i]->butt->getWindowRect(&r);
- PopupMenu *p = items[i]->menu;
- p->showAtXY(r.right, r.top, rcp, reverse_side, r.right - r.left);
- if (p1)
- {
- p->selectFirst();
- }
- openmenuid = i;
- }
- }
- // mig: changed this to call getNotifyId();
- // *rcp=p1;
- *rcp = child->getNotifyId();
- return 0;
- }
- if (msg == ChildNotify::POPUP_SUBMENUCLOSE)
- {
- for (int i = 0;i < items.getNumItems();i++)
- {
- if (child == items[i]->menu)
- {
- if (openmenuid != i) continue;
- items[openmenuid]->menu->hide();
- openmenuid = -1;
- return 0;
- }
- }
- }
- return POPUPMENU_PARENT::childNotify(child, msg, p1, p2);
- }
- void PopupMenu::selectFirst()
- {
- ButtonWnd *b = NULL;
- int i;
- for (i = 0; i < items.getNumItems(); i++)
- {
- b = items.enumItem(i)->butt;
- if (b != NULL) break;
- }
- if (b == NULL) return ;
- lastitem = i;
- b->setHilite(1);
- invalidate();
- }
- int PopupMenu::getWhichItem(POINT &p)
- {
- int x, n;
- RECT r2;
- getWindowRect(&r2);
- n = items.getNumItems();
- for (x = 0; x < n; x ++)
- {
- RECT r;
- items[x]->butt->getWindowRect(&r);
- r.right = r2.right;
- r.left = r2.left;
- if (Std::pointInRect(r, p))
- {
- return x;
- }
- }
- return -1;
- }
- int PopupMenu::isMine(int x, int y)
- {
- RECT r;
- getWindowRect(&r);
- POINT p = {x, y};
- if (Std::pointInRect(r, p)) return 1;
- if (lastitem >= 0 && items[lastitem]->menu && items[lastitem]->menu->isMine(x, y)) return 1;
- return 0;
- }
- void PopupMenu::setFriendlyId(const char *id)
- {
- friendid = id;
- }
- int PopupMenu::onLeftButtonDown(int x, int y)
- {
- clientToScreen(&x, &y);
- onButtonDown(1, x, y);
- return 0;
- }
- int PopupMenu::onRightButtonDown(int x, int y)
- {
- clientToScreen(&x, &y);
- onButtonDown(2, x, y);
- return 0;
- }
- int PopupMenu::onMouseMove(int x, int y)
- {
- POPUPMENU_PARENT::onMouseMove(x, y);
- POINT pnt = {x, y};
- clientToScreen(&pnt);
- if (keyctrl && lastxy.x == pnt.x && lastxy.y == pnt.y) return 1;
- keyctrl = 0;
- lastxy = pnt;
- if (lastitem >= 0)
- {
- if (openmenuid >= 0 && items[openmenuid]->menu && items[openmenuid]->menu->isMine(pnt.x, pnt.y))
- {
- if (lastitem != openmenuid)
- {
- items[lastitem]->butt->setHilite(0);
- items[lastitem]->butt->setPushed(0);
- items[openmenuid]->butt->setHilite(1);
- items[openmenuid]->butt->setPushed(1);
- invalidateItem(lastitem);
- lastitem = openmenuid;
- invalidateItem(lastitem);
- }
- resetTimer( -1);
- items[openmenuid]->menu->screenToClient(&pnt);
- items[openmenuid]->menu->onMouseMove(pnt.x, pnt.y);
- return 0;
- }
- }
- int p = getWhichItem(pnt);
- if (p >= 0)
- {
- ItemT *it = items[p];
- if (!it->issep)
- {
- if (p != lastitem)
- {
- if (lastitem >= 0)
- {
- /* if (items[lastitem]->menu)
- {
- items[lastitem]->menu->hide();
- }*/
- items[lastitem]->butt->setHilite(0);
- items[lastitem]->butt->setPushed(0);
- invalidateItem(lastitem);
- }
- invalidateItem(lastitem);
- lastitem = p;
- invalidateItem(lastitem);
- items[p]->butt->setHilite(1);
- if (bdown) items[p]->butt->setPushed(1);
- /* if (items[p]->menu) {
- RECT r;
- items[p]->butt->getWindowRect(&r);
- items[p]->menu->showAtXY(r.right,r.top,rcp);
- }*/
- resetTimer(p);
- invalidateItem(lastitem);
- }
- }
- else
- {
- RECT _r;
- getClientRect(&_r);
- int inside = (x >= 0 && y >= 0 && x <= _r.right - _r.left && y <= _r.bottom - _r.top);
- if (lastitem >= 0 && !inside)
- {
- items[lastitem]->butt->setHilite(0);
- items[lastitem]->butt->setPushed(0);
- invalidateItem(lastitem);
- lastitem = -1;
- }
- }
- }
- else
- {
- if (!friendid.isempty())
- {
- ifc_window *w = WASABI_API_WND->rootWndFromPoint(&pnt);
- if (w != NULL)
- {
- MenuButtonSurface *s = static_cast<MenuButtonSurface *>(w->getInterface(menuButtonSurfaceGuid));
- if (s != NULL)
- {
- if (s->getParentWnd() != parentRootWnd)
- {
- const char *str = s->getParentMenuId();
- if (STRCASEEQLSAFE(str, friendid))
- {
- abort();
- rcode = -4;
- chainmenu = s;
- }
- }
- }
- }
- }
- }
- return 0;
- }
- void PopupMenu::resetTimer(int p)
- {
- if (timerset)
- {
- killTimer(POPUP_TIMERID);
- timeritem = -1;
- }
- if (p >= 0 && !disable_autopop)
- {
- setTimer(POPUP_TIMERID, popupdelay);
- timeritem = p;
- timerset = 1;
- }
- }
- void PopupMenu::timerCallback(int id)
- {
- switch (id)
- {
- case POPUP_TIMERID:
- killTimer(POPUP_TIMERID);
- timerset = 0;
- if (timeritem == openmenuid)
- {
- timeritem = -1;
- break;
- }
- if (openmenuid >= 0 && items[openmenuid]->menu)
- {
- items[openmenuid]->menu->hide();
- openmenuid = -1;
- }
- if (timeritem >= 0)
- {
- if (items[timeritem]->cb) initMenuCallback(timeritem);
- if (items[timeritem]->butt->getEnabled() && items[timeritem]->menu)
- {
- RECT r;
- items[timeritem]->butt->getWindowRect(&r);
- items[timeritem]->menu->showAtXY(r.right, r.top, rcp, reverse_side, r.right - r.left);
- openmenuid = timeritem;
- }
- timeritem = -1;
- }
- break;
- default:
- POPUPMENU_PARENT::timerCallback(id);
- break;
- }
- }
- void PopupMenu::initMenuCallback(int item)
- {
- int a = rcode;
- rcode = 0;
- PopupMenu *p = items[item]->cb->popupMenuCallback(this, items[item]->cbparam);
- rcode = a;
- if (p)
- {
- items[item]->cb = NULL;
- items[item]->menu = p;
- }
- }
- int PopupMenu::onLeftButtonUp(int x, int y)
- {
- clientToScreen(&x, &y);
- onButtonUp(1, x, y);
- return 0;
- }
- int PopupMenu::onRightButtonUp(int x, int y)
- {
- clientToScreen(&x, &y);
- onButtonUp(2, x, y);
- return 0;
- }
- void PopupMenu::onButtonDown(int wb, int x, int y)
- {
- POINT pos = {x, y};
- RECT r;
- bdown |= wb;
- if (lastitem >= 0)
- {
- if (items[lastitem]->menu && items[lastitem]->menu->isMine(pos.x, pos.y))
- {
- items[lastitem]->menu->onButtonDown(wb, x, y);
- return ;
- }
- }
- getWindowRect(&r);
- if (!Std::pointInRect(r, pos))
- {
- rcode = (wb == 1) ? -2 : -3;
- }
- else
- {
- int item = getWhichItem(pos);
- if (item >= 0) items[item]->butt->setPushed(1);
- }
- }
- void PopupMenu::onButtonUp(int wb, int x, int y)
- {
- if (lastitem >= 0)
- {
- POINT pos = {x, y};
- if (items[lastitem]->menu && items[lastitem]->menu->isMine(pos.x, pos.y))
- {
- items[lastitem]->menu->onButtonUp(wb, x, y);
- return ;
- }
- }
- if (bdown & wb)
- {
- bdown &= ~wb;
- POINT pnt = {x, y};
- int p = getWhichItem(pnt);
- if (p >= 0)
- {
- items[p]->butt->onLeftPush(x, y);
- if (!bdown)
- {
- items[p]->butt->setPushed(0);
- }
- }
- }
- }
- int PopupMenu::onKillFocus()
- {
- #ifndef LINUX
- if (rcode == -1) rcode = -2;
- #endif
- return POPUPMENU_PARENT::onKillFocus();
- }
- // only translates the text, not the optional accelerator
- String PopupMenu::translateButtonText(const wchar_t *text)
- {
- PathParser pp(text, "\t");
- String ret;
- for (int i = 0; i < pp.getNumStrings(); i++)
- {
- if (i == 0) ret += _(pp.enumString(i)); // translate first
- else ret += pp.enumString(i);
- if (i != pp.getNumStrings() - 1) ret += "\t";
- }
- return ret;
- }
- int PopupMenu::onPaint(Canvas *canvas)
- {
- PaintBltCanvas paintcanvas;
- if (canvas == NULL)
- {
- if (!paintcanvas.beginPaint(this)) return 0;
- canvas = &paintcanvas;
- }
- POPUPMENU_PARENT::onPaint(canvas);
- RECT r, r2;
- getClientRect(&r);
- tex.getBitmap()->blitTile(canvas, &r);
- // left side
- ful.getBitmap()->blitAlpha(canvas, 0, 0);
- r2.left = 0;
- r2.right = fl.getWidth();
- r2.top = ful.getHeight();
- r2.bottom = r.bottom - fll.getHeight();
- fl.getBitmap()->stretchToRectAlpha(canvas, &r2);
- fll.getBitmap()->blitAlpha(canvas, 0, r.bottom - fll.getHeight());
- // right side
- fur.getBitmap()->blitAlpha(canvas, r.right - fur.getWidth(), 0);
- r2.left = r.right - fr.getWidth();
- r2.right = r.right;
- r2.top = fur.getHeight();
- r2.bottom = r.bottom - flr.getHeight();
- fr.getBitmap()->stretchToRectAlpha(canvas, &r2);
- flr.getBitmap()->blitAlpha(canvas, r.right - flr.getWidth(), r.bottom - flr.getHeight());
- // top
- r2.left = ful.getWidth();
- r2.right = r.right - fur.getWidth();
- r2.top = 0;
- r2.bottom = ft.getHeight();
- ft.getBitmap()->stretchToRectAlpha(canvas, &r2);
- // bottom
- r2.left = fll.getWidth();
- r2.right = r.right - flr.getWidth();
- r2.top = r.bottom - fb.getHeight();
- r2.bottom = r.bottom;
- fb.getBitmap()->stretchToRectAlpha(canvas, &r2);
- // selection bar
- if (lastitem != -1)
- {
- ItemT *it = items[lastitem];
- RECT r3, c;
- it->butt->getClientRect(&r3);
- // left
- r2.left = r.left + fl.getWidth() + SELMARGIN;
- r2.top = r.top + r3.top;
- r2.right = r2.left + sl.getWidth();
- r2.bottom = r2.top + (r3.bottom - r3.top);
- sl.getBitmap()->stretchToRectAlpha(canvas, &r2);
- c = r2;
- c.left = c.right - 1;
- // right
- r2.right = r.right - fr.getWidth() - SELMARGIN;
- r2.left = r2.right - sr.getWidth();
- sr.getBitmap()->stretchToRectAlpha(canvas, &r2);
- c.right = r2.left;
- // center
- sc.getBitmap()->stretchToRectAlpha(canvas, &c);
- }
- return 1;
- }
- void PopupMenu::invalidateItem(int i)
- {
- if (i < 0 || i >= items.getNumItems()) return ;
- RECT r, r2, r3;
- getClientRect(&r);
- ItemT *it = items[i];
- it->butt->getClientRect(&r3);
- r2.left = r.left + fl.getWidth();
- r2.top = r.top + r3.top;
- r2.right = r.right - fl.getWidth();
- r2.bottom = r2.top + (r3.bottom - r3.top);
- invalidateRect(&r2);
- }
- int PopupMenu::getNumCommands()
- {
- return items.getNumItems();
- }
- #ifdef WASABI_COMPILE_SKIN
- int PopupMenu::skincb_onCheckPreventSwitch(const char *skinname)
- {
- switchskinto = skinname;
- rcode = -2;
- return 1;
- }
- #endif
- int PopupMenu::onSysKeyDown(int code, int d)
- {
- int a = POPUPMENU_PARENT::onSysKeyDown(code, d);
- /* if (d & (1<<29)) {
- //ALT key pressed, abort menu (mimics win32 popup behavior)
- abort();
- if(getParent()) SendMessageW(getParent()->gethWnd(),WM_SYSKEYDOWN,code,d);
- return 0;
- }*/
- if (a == 0)
- return onKeyDown(code);
- return 0;
- }
- int PopupMenu::onKeyDown(int code)
- {
- if (POPUPMENU_PARENT::onKeyDown(code)) return 1;
- switch (code)
- {
- case STDKEY_DOWN:
- navigate(1);
- return 1;
- case STDKEY_UP:
- navigate( -1);
- return 1;
- case STDKEY_RETURN:
- navigate(0, 1);
- return 1;
- case STDKEY_RIGHT:
- navigate(0, 0);
- return 1;
- case VK_LEFT:
- if (!toplevelmenu)
- notifyParent(ChildNotify::POPUP_SUBMENUCLOSE);
- return 1;
- case VK_ESCAPE:
- abort();
- return 1;
- }
- return 0;
- }
- void PopupMenu::abort()
- {
- if (toplevelmenu)
- rcode = -2;
- else
- notifyParent(ChildNotify::POPUP_SUBMENUCLOSE);
- }
- void PopupMenu::navigate(int p, int f)
- {
- keyctrl = 1;
- int i = lastitem;
- ItemT *t = NULL;
- if (p == 0)
- {
- if (lastitem >= 0)
- {
- ItemT *t = items.enumItem(lastitem);
- if (f || t->menu || t->cb)
- {
- t->butt->setHilite(1);
- t->butt->setPushed(1);
- childNotify(t->butt, ChildNotify::BUTTON_LEFTPUSH, 1, 0);
- }
- }
- return ;
- }
- while (!t || t->issep)
- {
- i += p;
- i %= items.getNumItems();
- if (i == -1) i = items.getNumItems() - 1;
- if (i >= items.getNumItems()) return ;
- t = items.enumItem(i);
- }
- if (t->butt)
- {
- int i;
- i = items.searchItem(t);
- t->butt->setHilite(1);
- if (lastitem != -1)
- {
- ItemT *s = items.enumItem(lastitem);
- if (s->butt)
- {
- s->butt->setPushed(0);
- s->butt->setHilite(0);
- }
- }
- lastitem = i;
- invalidate();
- }
- }
- #else
- //------------------------------------------------------------------------------------------------------------------------------------------
- //------------------------------------------------------------------------------------------------------------------------------------------
- //------------------------------------------------------------------------------------------------------------------------------------------
- // 3rd level popup menu, yay
- #include "script/c_script/c_text.h"
- #include "script/c_script/c_rootobj.h"
- #include "script/c_script/c_button.h"
- #include "script/c_script/c_group.h"
- PopupMenu::PopupMenu(ifc_window *sourceWnd)
- {
- ASSERT(sourceWnd != NULL);
- myInit();
- setParent(sourceWnd);
- sourceWnd->setAllowDeactivation(0);
- init(HINSTANCEfromHWND(getParent()->gethWnd()), sourceWnd->gethWnd(), TRUE);
- sourceWnd->setAllowDeactivation(1);
- }
- PopupMenu::PopupMenu()
- {
- myInit();
- setParent(WASABI_API_WND->main_getRootWnd());
- WASABI_API_WND->main_getRootWnd()->setAllowDeactivation(0);
- init(hInstance, WASABI_API_WND->main_getRootWnd()->gethWnd(), TRUE);
- WASABI_API_WND->main_getRootWnd()->setAllowDeactivation(1);
- }
- PopupMenu::PopupMenu(PopupMenu *sourceWnd)
- {
- myInit();
- setParent(sourceWnd);
- sourceWnd->setAllowDeactivation(0);
- init(GetModuleHandle(NULL), sourceWnd->gethWnd(), TRUE);
- sourceWnd->setAllowDeactivation(1);
- }
- void PopupMenu::myInit()
- {
- setVirtual(0);
- setStartHidden(1);
- setRenderRatio(1.0);
- reverse_side = 0;
- rcode = 0;
- submenus = 0;
- c_grouplist = NULL;
- WASABI_API_WND->popupexit_register(this, this);
- }
- PopupMenu::~PopupMenu()
- {
- WASABI_API_WND->popupexit_deregister(this);
- delete c_grouplist;
- }
- int PopupMenu::onInit()
- {
- POPUPMENU_PARENT::onInit();
- #ifdef WASABI_COMPILE_CONFIG
- // {9149C445-3C30-4e04-8433-5A518ED0FDDE}
- const GUID uioptions_guid =
- { 0x9149c445, 0x3c30, 0x4e04, { 0x84, 0x33, 0x5a, 0x51, 0x8e, 0xd0, 0xfd, 0xde } };
- setTransparency(_intVal(WASABI_API_CONFIG->config_getCfgItemByGuid(uioptions_guid), "Popup menu alpha", 255));
- #else
- setTransparency(255);
- #endif
- setContent("wasabi.popup.main.group");
- return 1;
- }
- int PopupMenu::popAtXY(int x, int y)
- {
- rcode = -1;
- if (1 /*items.getNumItems()*/)
- {
- POINT pt = {x, y};
- //DebugString("appdeactivation_push_disallow\n");
- WASABI_API_WND->appdeactivation_push_disallow(this);
- showAtXY(x, y, &rcode);
- //MSG msg;
- /*while (rcode == -1 && GetMessage( &msg, NULL, 0, 0 )) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }*/
- SetCursor(LoadCursor(NULL, IDC_ARROW)); // NONPORTABLE
- int quit = 0;
- while (!quit)
- {
- rcode = getGuiObject()->guiobject_runModal();
- if (rcode & 0x40000000 && rcode != -2 && rcode != -1)
- {
- int submenuentry = rcode & ~0x40000000;
- ItemT *t = items.enumItem(submenuentry);
- if (t->cb != NULL)
- initMenuCallback(submenuentry);
- if (t->menu != NULL)
- {
- setAllowDeactivation(0);
- t->menu->showAtXY(0, 0, NULL, 0, 0);
- setAllowDeactivation(1);
- }
- }
- else
- quit = 1;
- }
- setVisible(0);
- }
- //DebugString("appdeactivation_pop_disallow\n");
- WASABI_API_WND->appdeactivation_pop_disallow(this);
- onPostPop(rcode);
- return rcode;
- }
- void PopupMenu::showAtXY(int x, int y, int *rc, int revside /* =0 */, int parentW /* =0 */)
- {
- fillContent();
- int neww = getPreferences(SUGGESTED_W);
- int newh = getPreferences(SUGGESTED_H);;
- POINT p = {x, y};
- RECT vp;
- Std::getViewport(&vp, &p);
- // maintain parent's reversal state
- reverse_side = revside;
- int savx = x;
- if (reverse_side) x -= (neww + parentW);
- if (x + neww > vp.right || x < 0)
- {
- reverse_side = !reverse_side;
- x = savx;
- if (reverse_side) x -= (neww + parentW);
- }
- if (y + newh > vp.bottom) y -= newh;
- if (x < vp.left) x = vp.left;
- if (y < vp.top) y = vp.top;
- resize(x, y, neww, newh);
- WASABI_API_WND->appdeactivation_push_disallow(this);
- #ifdef WIN32
- SetWindowPos(gethWnd(), HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
- #else
- Atom NET_STATE = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE", True );
- Atom state[2];
- state[0] = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE_SKIP_TASKBAR", True );
- state[1] = XInternAtom( Linux::getDisplay(), "_NET_WM_STATE_ABOVE", True );
- if ( NET_STATE && state[0] && state[1] )
- {
- XChangeProperty( Linux::getDisplay(), gethWnd(), NET_STATE, XA_ATOM, 32,
- PropModeReplace, (unsigned char *)state, 2 );
- }
- #endif
- WASABI_API_WND->appdeactivation_pop_disallow(this);
- setVisible(1);
- }
- int PopupMenu::popAnchored(int type)
- {
- RECT wr;
- getParent()->getWindowRect(&wr);
- switch (type)
- {
- case POPUP_ANCHOR_UL: return popAtXY(wr.left, wr.top);
- case POPUP_ANCHOR_LL: return popAtXY(wr.left, wr.bottom);
- case POPUP_ANCHOR_UR: return popAtXY(wr.right, wr.top);
- case POPUP_ANCHOR_LR: return popAtXY(wr.right, wr.bottom);
- }
- return 0;
- }
- int PopupMenu::popAtMouse()
- {
- int x, y;
- Std::getMousePos(&x, &y);
- return popAtXY(x, y);
- }
- void PopupMenu::onNewContent()
- {
- POPUPMENU_PARENT::onNewContent();
- if (isVisible())
- fillContent();
- }
- void PopupMenu::fillContent()
- {
- GuiObject *grouplist = findObject("popup.content");
- if (grouplist != NULL)
- {
- delete c_grouplist;
- c_grouplist = new C_GroupList(*grouplist);
- c_grouplist->removeAll();
- c_grouplist->setRedraw(0);
- for (int i = 0;i < items.getNumItems();i++)
- {
- addItem(items.enumItem(i));
- }
- c_grouplist->setRedraw(1);
- }
- }
- void PopupMenu::addItem(ItemT *i)
- {
- if (c_grouplist == NULL) return ;
- switch (i->type)
- {
- case POPUPITEM_TYPE_TEXT:
- {
- c_grouplist->instantiate("wasabi.popup.text.item", 1);
- ScriptObject *o = c_grouplist->enumItem(c_grouplist->getNumItems() - 1);
- if (o != NULL)
- {
- C_Group grp(o);
- C_RootObject g(o);
- g.notify("arrow", StringPrintfW(L"%d", (submenus) ? 1 : 0), 0, 0);
- g.notify("checkmark", StringPrintfW(L"%d", menuchecks ? 1 : 0), 0, 0);
- g.notify("id", StringPrintfW(L"%d", i->cmd), 0, 0);
- ScriptObject *check = grp.getObject("popup.item.checkmark");
- if (check != NULL)
- {
- C_Button toggle(check);
- toggle.setActivated(i->checked);
- }
- ScriptObject *arrow = grp.getObject("popup.item.submenuarrow");
- if (check != NULL)
- {
- C_Button sub(arrow);
- sub.setActivated((i->menu != NULL || i->cb != NULL));
- }
- ScriptObject *txt = grp.getObject("popup.item.text");
- if (txt != NULL)
- {
- C_Text itemtxt(txt);
- itemtxt.setText(i->txt);
- }
- }
- break;
- }
- case POPUPITEM_TYPE_IMAGE:
- c_grouplist->instantiate("wasabi.popup.image.item", 1);
- break;
- case POPUPITEM_TYPE_SEPARATOR:
- c_grouplist->instantiate("wasabi.popup.separator.item", 1);
- break;
- }
- }
- String PopupMenu::translateButtonText(const wchar_t *text)
- {
- PathParser pp(text, "\t");
- String ret;
- for (int i = 0; i < pp.getNumStrings(); i++)
- {
- if (i == 0) ret += _(pp.enumString(i)); // translate first
- else ret += pp.enumString(i);
- if (i != pp.getNumStrings() - 1) ret += "\t";
- }
- return ret;
- }
- void PopupMenu::addCommand(const wchar_t *_txt, int command, int checked, int disabled, int addpos)
- {
- if (!_txt)
- {
- addSeparator();
- return ;
- }
- String txt = translateButtonText(_txt);
- #ifdef WASABI_COMPILE_LOCALES
- const char *bind = WASABI_API_LOCALE->locales_getBindFromAction(command);
- if (bind) txt += StringPrintfW(L"\t%s", bind);
- #endif
- ItemT *t = new ItemT;
- t->type = POPUPITEM_TYPE_TEXT;
- t->cmd = command;
- t->txt = txt;
- t->checked = checked;
- t->menu = NULL;
- t->cb = NULL;
- t->cmd = -1;
- ASSERT(PTRLIST_POS_LAST == -1); //BU
- items.addItem(t, addpos);
- }
- int PopupMenu::popupexitcb_onExitPopup()
- {
- getGuiObject()->guiobject_endModal( -2);
- return 1;
- }
- void PopupMenu::addSubMenu(PopupMenu *menu, const wchar_t *text)
- {
- ASSERT(text != NULL);
- submenus = 1;
- ItemT *t = new ItemT;
- t->type = POPUPITEM_TYPE_TEXT;
- t->cmd = items.getNumItems() | 0x40000000;
- t->txt = translateButtonText(text);
- t->checked = 0;
- t->menu = menu;
- t->cb = NULL;
- t->cmd = -1;
- t->cmd = -1;
- items.addItem(t);
- }
- void PopupMenu::addSubMenuCallback(const wchar_t *text, PopupMenuCallback *cb, int param)
- {
- ASSERT(text != NULL);
- ASSERT(cb != NULL);
- ItemT *t = new ItemT;
- submenus = 1;
- t->type = POPUPITEM_TYPE_TEXT;
- t->checked = 0;
- t->cmd = items.getNumItems() | 0x40000000;
- t->menu = NULL;
- t->cb = cb;
- t->cbparam = param;
- t->txt = translateButtonText(text);
- t->cmd = -1;
- items.addItem(t);
- }
- void PopupMenu::initMenuCallback(int item)
- {
- int a = rcode;
- rcode = 0;
- PopupMenu *p = items[item]->cb->popupMenuCallback(this, items[item]->cbparam);
- rcode = a;
- if (p)
- {
- items[item]->cb = NULL;
- items[item]->menu = p;
- }
- }
- #endif
- #endif //WASABI_WANT_FF_POPUP
|