button.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. #include <precomp.h>
  2. #include <wasabicfg.h>
  3. #include "button.h"
  4. #include <api/skin/skinparse.h>
  5. #include <api/script/scriptmgr.h>
  6. #ifdef WASABI_WIDGETS_COMPBUCK
  7. #include <api/skin/widgets/compbuck2.h>
  8. #endif
  9. #ifdef WASABI_COMPILE_MEDIACORE
  10. #include <api/core/api_core.h>
  11. #endif
  12. #include <api/service/svcs/svc_action.h>
  13. const wchar_t buttonXuiObjectStr[] = L"Button"; // This is the xml tag
  14. char buttonXuiSvcName[] = "Button xui object"; // this is the name of the xuiservice
  15. ButtonScriptController _buttonController;
  16. ButtonScriptController *buttonController = &_buttonController;
  17. // -- Functions table -------------------------------------
  18. function_descriptor_struct ButtonScriptController::exportedFunction[] = {
  19. {L"onActivate", 1, (void*)Wasabi::Button::script_vcpu_onActivate },
  20. {L"setActivated", 1, (void*)Wasabi::Button::script_vcpu_setActivated },
  21. {L"getActivated", 0, (void*)Wasabi::Button::script_vcpu_getActivated },
  22. {L"onLeftClick", 0, (void*)Wasabi::Button::script_vcpu_onLeftClick },
  23. {L"onRightClick", 0, (void*)Wasabi::Button::script_vcpu_onRightClick },
  24. {L"leftClick", 0, (void*)Wasabi::Button::script_vcpu_leftClick },
  25. {L"rightClick", 0, (void*)Wasabi::Button::script_vcpu_rightClick },
  26. {L"setActivatedNoCallback", 1, (void*)Wasabi::Button::script_vcpu_setActivatedNoCallback },
  27. };
  28. // --------------------------------------------------------
  29. const wchar_t *ButtonScriptController::getClassName() {
  30. return L"Button";
  31. }
  32. const wchar_t *ButtonScriptController::getAncestorClassName() {
  33. return L"GuiObject";
  34. }
  35. ScriptObject *ButtonScriptController::instantiate() {
  36. Wasabi::Button *b = new Wasabi::Button;
  37. ASSERT(b != NULL);
  38. return b->getScriptObject();
  39. }
  40. void ButtonScriptController::destroy(ScriptObject *o) {
  41. Wasabi::Button *b = static_cast<Wasabi::Button *>(o->vcpu_getInterface(buttonGuid));
  42. ASSERT(b != NULL);
  43. delete b;
  44. }
  45. void *ButtonScriptController::encapsulate(ScriptObject *o) {
  46. return NULL; // no encapsulation for buttojn yet
  47. }
  48. void ButtonScriptController::deencapsulate(void *o) {
  49. }
  50. int ButtonScriptController::getNumFunctions() {
  51. return sizeof(exportedFunction) / sizeof(function_descriptor_struct);
  52. }
  53. const function_descriptor_struct *ButtonScriptController::getExportedFunctions() {
  54. return exportedFunction;
  55. }
  56. GUID ButtonScriptController::getClassGuid() {
  57. return buttonGuid;
  58. }
  59. XMLParamPair Wasabi::Button::params[] =
  60. {
  61. {BUTTON_ACTION, L"ACTION"},
  62. {BUTTON_ACTIONTARGET, L"ACTION_TARGET"},
  63. {BUTTON_ACTIVEIMAGE, L"ACTIVEIMAGE"},
  64. {BUTTON_BORDERS, L"BORDERS"},
  65. #ifdef WASABI_WIDGETS_COMPBUCK
  66. {BUTTON_CBTARGET, L"CBTARGET"},
  67. #endif
  68. {BUTTON_CENTER_IMAGE, L"CENTER_IMAGE"},
  69. {BUTTON_DOWNIMAGE, L"DOWNIMAGE"},
  70. {BUTTON_HOVERIMAGE, L"HOVERIMAGE"},
  71. {BUTTON_IMAGE, L"IMAGE"},
  72. {BUTTON_PARAM, L"PARAM"},
  73. // {BUTTON_RECTRGN, "RECTRGN"},
  74. {BUTTON_RETCODE, L"RETCODE"},
  75. {BUTTON_BORDERSTYLE, L"STYLE"},
  76. {BUTTON_TEXT, L"TEXT"},
  77. {BUTTON_TEXTCOLOR, L"TEXTCOLOR"},
  78. {BUTTON_TEXTHOVERCOLOR, L"TEXTDIMMEDCOLOR"},
  79. {BUTTON_TEXTHOVERCOLOR, L"TEXTHOVERCOLOR"},
  80. };
  81. // -----------------------------------------------------------------------
  82. Wasabi::Button::Button() {
  83. disablenextcontextmenu = 0;
  84. #ifdef WASABI_COMPILE_MEDIACORE
  85. WASABI_API_MEDIACORE->core_addCallback(0, this);
  86. #endif
  87. getScriptObject()->vcpu_setInterface(buttonGuid, (void *)static_cast<Button*>(this));
  88. getScriptObject()->vcpu_setClassName(L"Button");
  89. getScriptObject()->vcpu_setController(buttonController);
  90. cbtarget = NULL;
  91. setBorders(FALSE);
  92. xuihandle = newXuiHandle();
  93. CreateXMLParameters(xuihandle);
  94. }
  95. void Wasabi::Button::CreateXMLParameters(int master_handle)
  96. {
  97. //BUTTON_PARENT::CreateXMLParameters(master_handle);
  98. int numParams = sizeof(params) / sizeof(params[0]);
  99. hintNumberOfParams(xuihandle, numParams);
  100. for (int i = 0;i < numParams;i++)
  101. addParam(xuihandle, params[i], XUI_ATTRIBUTE_IMPLIED);
  102. }
  103. Wasabi::Button::~Button() {
  104. //int c=getNotifyId();
  105. #ifdef WASABI_COMPILE_MEDIACORE
  106. WASABI_API_MEDIACORE->core_delCallback(0, this);
  107. #endif
  108. WASABI_API_SYSCB->syscb_deregisterCallback(static_cast<WndCallbackI*>(this));
  109. }
  110. int Wasabi::Button::onInit()
  111. {
  112. BUTTON_PARENT::onInit();
  113. if (!action.isempty())
  114. setAction(action);
  115. //FG> this is retarded, and yes, i'm the one who coded it in
  116. //if (s_normal.isempty() && s_down.isempty() && s_hover.isempty() && s_active.isempty())
  117. // setRectRgn(1);
  118. setupBitmaps();
  119. //int c=getNotifyId();
  120. setHandleRightClick(TRUE);
  121. #ifdef WASABI_COMPILE_MEDIACORE
  122. if (WCSCASEEQLSAFE(actionstr, L"eq_toggle")
  123. || WCSCASEEQLSAFE(actionstr, L"eq_auto"))
  124. {
  125. if (WCSCASEEQLSAFE(actionstr, L"eq_toggle"))
  126. corecb_onEQStatusChange(WASABI_API_MEDIACORE->core_getEqStatus(0));
  127. else corecb_onEQAutoChange(WASABI_API_MEDIACORE->core_getEqAuto(0));
  128. }
  129. #endif
  130. WASABI_API_SYSCB->syscb_registerCallback(static_cast<WndCallbackI*>(this));
  131. return 1;
  132. }
  133. void Wasabi::Button::setupBitmaps()
  134. {
  135. setBitmaps(s_normal, s_down, s_hover, s_active);
  136. }
  137. void Wasabi::Button::setParam(const wchar_t *p)
  138. {
  139. param=p;
  140. }
  141. void Wasabi::Button::setAction(const wchar_t *_action)
  142. {
  143. actionstr = _action;
  144. const wchar_t *name;
  145. int id = SkinParser::getAction(_action, &name);
  146. actionname = name;
  147. if (id == ACTION_NONE || !action_target.isempty())
  148. action = _action;
  149. else {
  150. setNotifyId(id);
  151. action = L"";
  152. }
  153. }
  154. int Wasabi::Button::setXuiParam(int _xuihandle, int xmlattributeid, const wchar_t *paramname, const wchar_t *strvalue) {
  155. if (xuihandle == _xuihandle) {
  156. switch (xmlattributeid) {
  157. case BUTTON_TEXT: setButtonText(strvalue); return 1;
  158. case BUTTON_ACTION: action = strvalue; if (isInited()) { setAction(action); } return 1;
  159. case BUTTON_IMAGE: s_normal = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); } return 1;
  160. case BUTTON_DOWNIMAGE: s_down = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); } return 1;
  161. case BUTTON_HOVERIMAGE: s_hover = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); } return 1;
  162. case BUTTON_ACTIVEIMAGE: s_active = strvalue; if (isInited()) { setBitmaps(s_normal, s_down, s_hover, s_active); }return 1;
  163. case BUTTON_PARAM: setParam(strvalue); return 1;
  164. //case BUTTON_RECTRGN: setRectRgn(WTOI(strvalue)); return 1;
  165. #ifdef WASABI_WIDGETS_COMPBUCK
  166. case BUTTON_CBTARGET: setCBTarget(strvalue); return 1;
  167. #endif
  168. case BUTTON_BORDERS: setBorders(WTOI(strvalue)); return 1;
  169. case BUTTON_BORDERSTYLE: setBorderStyle(strvalue); return 1;
  170. case BUTTON_RETCODE: setModalRetCode(WTOI(strvalue)); return 1;
  171. case BUTTON_ACTIONTARGET: {
  172. action_target = strvalue;
  173. if (!actionstr.isempty()) {
  174. action = actionstr;
  175. setAction(action);
  176. }
  177. return 1;
  178. }
  179. case BUTTON_CENTER_IMAGE: setBitmapCenter(WTOI(strvalue)); return 1;
  180. case BUTTON_TEXTCOLOR: setTextColor(strvalue); return 1;
  181. case BUTTON_TEXTHOVERCOLOR: setTextHoverColor(strvalue); return 1;
  182. case BUTTON_TEXTDIMMEDCOLOR: setTextDimmedColor(strvalue); return 1;
  183. }
  184. }
  185. return BUTTON_PARENT::setXuiParam(_xuihandle, xmlattributeid, paramname, strvalue);
  186. }
  187. #ifdef WASABI_WIDGETS_COMPBUCK
  188. void Wasabi::Button::setCBTarget(const wchar_t *t) {
  189. cbtarget = ComponentBucket2::getComponentBucket(t);
  190. }
  191. #endif
  192. const wchar_t *Wasabi::Button::getParam()
  193. {
  194. return param;
  195. }
  196. int Wasabi::Button::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2) {
  197. #ifdef WASABI_COMPILE_WNDMGR
  198. switch(msg)
  199. {
  200. #ifdef _WIN32
  201. case WM_WA_CONTAINER_TOGGLED:
  202. if(!param) break;
  203. if(!WCSICMP((const wchar_t *)param1,param)) setActivatedButton(param2);
  204. break;
  205. #else
  206. #warning port me
  207. #endif
  208. #ifdef WASABI_COMPILE_COMPONENTS
  209. case WM_WA_COMPONENT_TOGGLED:
  210. if(!param) break;
  211. GUID *g;
  212. if(g=SkinParser::getComponentGuid(param)) {
  213. if(!MEMCMP((GUID *)param1,g,sizeof(GUID))) setActivatedButton(param2);
  214. }
  215. break;
  216. #endif
  217. }
  218. #endif
  219. return BUTTON_PARENT::childNotify(child, msg, param1, param2);
  220. }
  221. #ifdef WASABI_COMPILE_MEDIACORE
  222. int Wasabi::Button::corecb_onEQStatusChange(int newval) {
  223. if(WCSCASEEQLSAFE(actionstr, L"eq_toggle")) setActivatedButton(newval);
  224. return 0;
  225. }
  226. int Wasabi::Button::corecb_onEQAutoChange(int newval) {
  227. if(WCSCASEEQLSAFE(actionstr,L"eq_auto")) setActivatedButton(newval);
  228. return 0;
  229. }
  230. #endif
  231. int Wasabi::Button::onLeftButtonUp(int x, int y) {
  232. BUTTON_PARENT::onLeftButtonUp(x, y);
  233. if (!WASABI_API_MAKI->vcpu_getComplete()) {
  234. #ifdef WASABI_WIDGETS_COMPBUCK
  235. if (getNotifyId() == ACTION_CB_NEXT) {
  236. if (cbtarget)
  237. cbtarget->ComponentBucket2::next_up();
  238. else
  239. ComponentBucket2::next_up(getGuiObject()->guiobject_getParentGroup());
  240. } else if (getNotifyId() == ACTION_CB_PREV) {
  241. if (cbtarget)
  242. cbtarget->ComponentBucket2::prev_up();
  243. else
  244. ComponentBucket2::prev_up(getGuiObject()->guiobject_getParentGroup());
  245. } else if (getNotifyId() == ACTION_CB_NEXTPAGE) {
  246. if (cbtarget)
  247. cbtarget->ComponentBucket2::next_page();
  248. else
  249. ComponentBucket2::next_page(getGuiObject()->guiobject_getParentGroup());
  250. } else if (getNotifyId() == ACTION_CB_PREVPAGE) {
  251. if (cbtarget)
  252. cbtarget->ComponentBucket2::prev_page();
  253. else
  254. ComponentBucket2::prev_page(getGuiObject()->guiobject_getParentGroup());
  255. }
  256. #endif
  257. }
  258. return 1;
  259. }
  260. int Wasabi::Button::onLeftButtonDown(int x, int y) {
  261. BUTTON_PARENT::onLeftButtonDown(x, y);
  262. if (!WASABI_API_MAKI->vcpu_getComplete()) {
  263. #ifdef WASABI_WIDGETS_COMPBUCK
  264. if (getNotifyId() == ACTION_CB_NEXT) {
  265. if (cbtarget)
  266. cbtarget->ComponentBucket2::next_down();
  267. else
  268. ComponentBucket2::next_down(getGuiObject()->guiobject_getParentGroup());
  269. } else if (getNotifyId() == ACTION_CB_PREV) {
  270. if (cbtarget)
  271. cbtarget->ComponentBucket2::prev_down();
  272. else
  273. ComponentBucket2::prev_down(getGuiObject()->guiobject_getParentGroup());
  274. }
  275. #endif
  276. }
  277. return 1;
  278. }
  279. void Wasabi::Button::onLeftPush(int x, int y) {
  280. BUTTON_PARENT::onLeftPush(x, y);
  281. script_vcpu_onLeftClick(SCRIPT_CALL, getScriptObject());
  282. if (!WASABI_API_MAKI->vcpu_getComplete()) {
  283. if (!action.isempty()) {
  284. if (!action_target.isempty())
  285. {
  286. GuiObject *go = getGuiObject()->guiobject_findObject(action_target);
  287. if (!go)
  288. {
  289. ScriptObject *so = WASABI_API_MAKI->maki_findObject(action_target);
  290. if (so != NULL)
  291. go = static_cast<GuiObject *>(so->vcpu_getInterface(guiObjectGuid));
  292. }
  293. if (go) {
  294. ifc_window *w = go->guiobject_getRootWnd();
  295. if (w) {
  296. int _x = x;
  297. int _y = y;
  298. clientToScreen(&_x, &_y);
  299. sendAction(w, actionstr, getParam(), _x, _y);
  300. }
  301. }
  302. } else {
  303. svc_action *act = ActionEnum(actionstr).getNext();
  304. if (act) {
  305. int _x = x;
  306. int _y = y;
  307. clientToScreen(&_x, &_y);
  308. act->onAction(actionstr, getParam(), _x, _y, NULL, 0, this);
  309. SvcEnum::release(act);
  310. }
  311. }
  312. }
  313. }
  314. }
  315. int Wasabi::Button::wantAutoContextMenu() {
  316. int a = disablenextcontextmenu;
  317. disablenextcontextmenu = 0;
  318. return !a;
  319. }
  320. void Wasabi::Button::onRightPush(int x, int y) {
  321. BUTTON_PARENT::onRightPush(x, y);
  322. script_vcpu_onRightClick(SCRIPT_CALL, getScriptObject());
  323. if (!WASABI_API_MAKI->vcpu_getComplete()) {
  324. if (!action.isempty()) {
  325. if (!action_target.isempty())
  326. {
  327. GuiObject *go = getGuiObject()->guiobject_findObject(action_target);
  328. if (!go) {
  329. ScriptObject *so = WASABI_API_MAKI->maki_findObject(action_target);
  330. if (so != NULL)
  331. go = static_cast<GuiObject *>(so->vcpu_getInterface(guiObjectGuid));
  332. }
  333. if (go) {
  334. ifc_window *w = go->guiobject_getRootWnd();
  335. if (w) {
  336. int _x = x;
  337. int _y = y;
  338. clientToScreen(&_x, &_y);
  339. sendAction(w, actionstr, getParam(), _x, _y);
  340. disablenextcontextmenu = 1;
  341. }
  342. }
  343. } else {
  344. svc_action *act = ActionEnum(actionstr).getNext();
  345. if (act) {
  346. const wchar_t *par = getParam();
  347. if (par == NULL || *par == 0) par = L"1";
  348. int _x = x;
  349. int _y = y;
  350. clientToScreen(&_x, &_y);
  351. disablenextcontextmenu = act->onAction(actionstr, par, _x, _y, NULL, 0, this);
  352. SvcEnum::release(act);
  353. }
  354. }
  355. }
  356. }
  357. }
  358. int Wasabi::Button::onActivateButton(int is) {
  359. BUTTON_PARENT::onActivateButton(is);
  360. scriptVar _is = SOM::makeVar(SCRIPT_INT);
  361. SOM::assign(&_is, is);
  362. script_vcpu_onActivate(SCRIPT_CALL, getScriptObject(), _is);
  363. return 1;
  364. }
  365. int Wasabi::Button::getPreferences(int what) {
  366. if (what == SUGGESTED_W) return getWidth();
  367. if (what == SUGGESTED_H) return getHeight();
  368. return BUTTON_PARENT::getPreferences(what);
  369. }
  370. int Wasabi::Button::onShowWindow(Container *c, GUID guid, const wchar_t *groupid)
  371. {
  372. if(!param) return 1;
  373. if (groupid != NULL && !WCSICMP(groupid, param))
  374. {
  375. setActivatedButton(1);
  376. return 1;
  377. }
  378. #ifdef WASABI_COMPILE_WNDMGR
  379. GUID *g;
  380. if (g=SkinParser::getComponentGuid(param))
  381. {
  382. if(*g != INVALID_GUID && guid == *g) setActivatedButton(1);
  383. }
  384. #endif
  385. return 1;
  386. }
  387. int Wasabi::Button::onHideWindow(Container *c, GUID guid, const wchar_t *groupid) {
  388. if(!param) return 1;
  389. if (groupid != NULL && !WCSICMP(groupid, param)) {
  390. setActivatedButton(0);
  391. return 1;
  392. }
  393. #ifdef WASABI_COMPILE_WNDMGR
  394. GUID *g;
  395. if (g=SkinParser::getComponentGuid(param)) {
  396. if(guid == *g) setActivatedButton(0);
  397. }
  398. #endif
  399. return 1;
  400. }
  401. scriptVar Wasabi::Button::script_vcpu_setActivatedNoCallback(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
  402. SCRIPT_FUNCTION_INIT
  403. ASSERT(SOM::isNumeric(&v));
  404. Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid));
  405. if (b) b->setActivatedNoCallback(SOM::makeBoolean(&v));
  406. RETURN_SCRIPT_VOID;
  407. }
  408. scriptVar Wasabi::Button::script_vcpu_onLeftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
  409. SCRIPT_FUNCTION_INIT;
  410. PROCESS_HOOKS0(o, buttonController);
  411. SCRIPT_FUNCTION_CHECKABORTEVENT;
  412. SCRIPT_EXEC_EVENT0(o);
  413. }
  414. scriptVar Wasabi::Button::script_vcpu_onRightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
  415. SCRIPT_FUNCTION_INIT;
  416. PROCESS_HOOKS0(o, buttonController);
  417. SCRIPT_FUNCTION_CHECKABORTEVENT;
  418. SCRIPT_EXEC_EVENT0(o);
  419. }
  420. scriptVar Wasabi::Button::script_vcpu_leftClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
  421. SCRIPT_FUNCTION_INIT;
  422. RECT r;
  423. Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid));
  424. if (b) {
  425. b->getClientRect(&r);
  426. b->onLeftPush(r.left, r.top);
  427. }
  428. RETURN_SCRIPT_VOID;
  429. }
  430. scriptVar Wasabi::Button::script_vcpu_rightClick(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
  431. SCRIPT_FUNCTION_INIT;
  432. RECT r;
  433. Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid));
  434. if (b) {
  435. b->getClientRect(&r);
  436. b->onRightPush(r.left, r.top);
  437. }
  438. RETURN_SCRIPT_VOID;
  439. }
  440. scriptVar Wasabi::Button::script_vcpu_setActivated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
  441. SCRIPT_FUNCTION_INIT
  442. ASSERT(SOM::isNumeric(&v));
  443. Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid));
  444. if (b) b->setActivatedButton(SOM::makeBoolean(&v));
  445. RETURN_SCRIPT_VOID;
  446. }
  447. scriptVar Wasabi::Button::script_vcpu_getActivated(SCRIPT_FUNCTION_PARAMS, ScriptObject *o) {
  448. SCRIPT_FUNCTION_INIT
  449. Wasabi::Button *b = static_cast<Button *>(o->vcpu_getInterface(buttonGuid));
  450. if (b) return MAKE_SCRIPT_BOOLEAN(b->getActivatedButton());
  451. RETURN_SCRIPT_ZERO;
  452. }
  453. scriptVar Wasabi::Button::script_vcpu_onActivate(SCRIPT_FUNCTION_PARAMS, ScriptObject *o, scriptVar v) {
  454. SCRIPT_FUNCTION_INIT;
  455. PROCESS_HOOKS1(o, buttonController, v);
  456. SCRIPT_FUNCTION_CHECKABORTEVENT;
  457. SCRIPT_EXEC_EVENT1(o, v);
  458. }