checkbox.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. #include <precomp.h>
  2. #include "checkbox.h"
  3. #include <api/service/svcs/svc_action.h>
  4. #include <api/script/objects/c_script/c_text.h>
  5. #include <api/script/objects/c_script/c_button.h>
  6. #include <api/script/objects/guiobject.h>
  7. #include <api/script/scriptguid.h>
  8. #include <api/script/api_maki.h>
  9. // -----------------------------------------------------------------------
  10. CheckBox::CheckBox(const wchar_t *_text, const wchar_t *_radioid) :
  11. textclicks(NULL), toggleclicks(NULL), text(_text), radioid(_radioid),
  12. buttonGuiObj(NULL), use_radioval(0),
  13. CHECKBOX_PARENT() { }
  14. CheckBox::~CheckBox() {
  15. delete textclicks;
  16. delete toggleclicks;
  17. }
  18. int CheckBox::onInit() {
  19. int r = CHECKBOX_PARENT::onInit();
  20. if (radioid.len()) {
  21. abstract_setContent(L"wasabi.radiobutton.group");
  22. // After we set the content for radio, we should register ourselves
  23. // as a radio button under the radio group we are assigned.
  24. GuiObject *radioGuiObj = abstract_findObject(radioid); // this will actually go down a level
  25. if (radioGuiObj != NULL) {
  26. ifc_window *radioRootWnd = *radioGuiObj; // explicit cast operator :)
  27. // Now, once we have the rootwnd, we can send our radio group object a message, it will turn off other items as we turn on specific ones
  28. if (radioRootWnd != NULL) {
  29. sendAction(radioRootWnd, L"REGISTER", NULL, -1, -1, 0, 0, (void *)getGuiObject(), 4);
  30. }
  31. }
  32. } else {
  33. abstract_setContent(L"wasabi.checkbox.group");
  34. }
  35. return r;
  36. }
  37. void CheckBox::onNewContent() {
  38. // remove all previous hooks because our content changed
  39. delete toggleclicks;
  40. toggleclicks = NULL;
  41. delete textclicks;
  42. textclicks = NULL;
  43. // Capture the clicks on the button
  44. buttonGuiObj = abstract_findObject(L"checkbox.toggle");
  45. if (buttonGuiObj != NULL) {
  46. toggleclicks = new ToggleClicks(*buttonGuiObj, this);
  47. }
  48. // Capture the clicks on the text
  49. GuiObject *textGuiObj = abstract_findObject(L"checkbox.text");
  50. if (textGuiObj != NULL) {
  51. textclicks = new TextClicks(*textGuiObj, this);
  52. }
  53. // Set the text object to display the requested text.
  54. updateText();
  55. }
  56. int CheckBox::getPreferences(int what) {
  57. ifc_window *w = abstract_getContentRootWnd();
  58. if (w != NULL)
  59. return w->getPreferences(what);
  60. return CHECKBOX_PARENT::getPreferences(what);
  61. }
  62. void CheckBox::setActivated(int activated, int writetocfg) {
  63. // this is usually called as a response to onReloadConfig, but could also be called
  64. // directly by a 3rd party, so if we can, we read the current value and do nothing if
  65. // it hasn't changed.
  66. GuiObject *toggleGuiObj = abstract_findObject(L"checkbox.toggle");
  67. if (toggleGuiObj != NULL) {
  68. C_Button buttonObj(*toggleGuiObj);
  69. int act = buttonObj.getActivated();
  70. if (!!act == !!activated) return;
  71. buttonObj.setActivatedNoCallback(!!activated);
  72. }
  73. if (writetocfg) {
  74. if (use_radioval) {
  75. if (activated) {
  76. #ifdef WASABI_COMPILE_CONFIG
  77. getGuiObject()->guiobject_setCfgString(radioval);
  78. #endif
  79. if (radioval != 0) doAction();
  80. }
  81. } else {
  82. #ifdef WASABI_COMPILE_CONFIG
  83. getGuiObject()->guiobject_setCfgInt(activated);
  84. #endif
  85. if (activated) doAction();
  86. }
  87. }
  88. }
  89. // This is called by the click catchers
  90. void CheckBox::toggle(int self_switch) {
  91. if (!buttonGuiObj) return;
  92. int activated = !!isActivated();
  93. if (self_switch) activated = !activated;
  94. /* int no_setactive = self_switch;
  95. if (radioid.len() > 0 && activated) { // but if we're a radiobox, do not toggle if we're already activated
  96. no_setactive = 1;
  97. }
  98. if (self_switch) activated = !!!activated;
  99. */
  100. if (!(activated && !radioid.isempty()))
  101. activated = !activated;
  102. if (!use_radioval || activated) {
  103. C_Button b(*buttonGuiObj);
  104. b.setActivatedNoCallback(activated);
  105. }
  106. if (activated) {
  107. if (use_radioval) {
  108. #ifdef WASABI_COMPILE_CONFIG
  109. getGuiObject()->guiobject_setCfgString(radioval);
  110. #endif
  111. if (radioval != 0) doAction();
  112. } else {
  113. #ifdef WASABI_COMPILE_CONFIG
  114. getGuiObject()->guiobject_setCfgInt(activated);
  115. #endif
  116. if (activated) doAction();
  117. }
  118. } else
  119. #ifdef WASABI_COMPILE_CONFIG
  120. if (radioid.len() == 0) getGuiObject()->guiobject_setCfgInt(0); // if we're a radioid being turned off, we shouldn't write our value, as we'll prolly be sharing the same cfgattr with other radioboxes, todo: make that optional
  121. #endif
  122. if (radioid.len() > 0 && activated) {
  123. GuiObject *radioGuiObj = abstract_findObject(radioid);
  124. ifc_window *radioRootWnd = *radioGuiObj;
  125. if (radioRootWnd != NULL)
  126. sendAction(radioRootWnd, L"TOGGLE", NULL, -1, -1, 0, 0, (void *)getGuiObject(), 4);
  127. }
  128. onToggle();
  129. }
  130. void CheckBox::onToggle() {
  131. }
  132. void CheckBox::setText(const wchar_t *_text)
  133. {
  134. text = _text;
  135. setName(text);
  136. if (isInited()) {
  137. updateText();
  138. }
  139. }
  140. const wchar_t *CheckBox::getText() {
  141. return text;
  142. }
  143. void CheckBox::setRadioid(const wchar_t *_radioid)
  144. {
  145. radioid = _radioid;
  146. }
  147. void CheckBox::setRadioVal(const wchar_t *val, int _use_radioval)
  148. {
  149. radioval = val;
  150. use_radioval = _use_radioval;
  151. }
  152. #ifdef WASABI_COMPILE_CONFIG
  153. int CheckBox::onReloadConfig()
  154. {
  155. StringW newVal = getGuiObject()->guiobject_getCfgString();
  156. int checkit = use_radioval ? (newVal == radioval) : WTOI(newVal);
  157. setActivated(checkit, 0);
  158. return CHECKBOX_PARENT::onReloadConfig();
  159. }
  160. #endif
  161. void CheckBox::updateText() {
  162. GuiObject *textGuiObj = abstract_findObject(L"checkbox.text");
  163. if (textGuiObj != NULL) {
  164. textGuiObj->guiobject_setXmlParam(L"text", text);
  165. }
  166. }
  167. int CheckBox::isActivated() {
  168. if (!buttonGuiObj) return 0;
  169. C_Button b(*buttonGuiObj);
  170. return b.getActivated();
  171. }
  172. int CheckBox::onChar(unsigned int c) {
  173. switch (c) {
  174. #ifdef _WIN32
  175. case VK_SPACE:
  176. toggle(0);
  177. break;
  178. #else
  179. #warning port me
  180. #endif
  181. default:
  182. return CHECKBOX_PARENT::onChar(c);
  183. }
  184. return 1;
  185. }
  186. void CheckBox::setAction(const wchar_t *str)
  187. {
  188. action = str;
  189. }
  190. void CheckBox::setActionTarget(const wchar_t *target) {
  191. action_target = target;
  192. }
  193. void CheckBox::setActionParam(const wchar_t *param) {
  194. action_param = param;
  195. }
  196. const wchar_t *CheckBox::getActionParam()
  197. {
  198. return action_param;
  199. }
  200. void CheckBox::doAction()
  201. {
  202. if (!action_target.isempty())
  203. {
  204. GuiObject *go = getGuiObject()->guiobject_findObject(action_target);
  205. if (!go) {
  206. ScriptObject *so = WASABI_API_MAKI->maki_findObject(action_target);
  207. if (so != NULL)
  208. go = static_cast<GuiObject *>(so->vcpu_getInterface(guiObjectGuid));
  209. }
  210. if (go) {
  211. ifc_window *w = go->guiobject_getRootWnd();
  212. if (w) {
  213. RECT cr;
  214. getClientRect(&cr);
  215. int _x = cr.left;
  216. int _y = cr.top;
  217. clientToScreen(&_x, &_y);
  218. sendAction(w, action, action_target, _x, _y);
  219. }
  220. }
  221. } else {
  222. svc_action *act = ActionEnum(action).getNext();
  223. if (act) {
  224. act->onAction(action, getActionParam());
  225. SvcEnum::release(act);
  226. }
  227. }
  228. }