clickwnd.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. #include "precomp.h"
  2. #include <api/wnd/api_wnd.h>
  3. #include "clickwnd.h"
  4. #include <api/wnd/notifmsg.h>
  5. #include <api/wnd/wndclass/guiobjwnd.h>
  6. enum
  7. {
  8. CLICKWND_LBUTTONDOWN = 0,
  9. CLICKWND_LBUTTONUP,
  10. CLICKWND_RBUTTONDOWN,
  11. CLICKWND_RBUTTONUP,
  12. };
  13. ClickWnd::ClickWnd()
  14. {
  15. handleRight = TRUE;
  16. button = -1;
  17. mousedown = 0;
  18. mcaptured = 0;
  19. hilite = 0;
  20. down = 0;
  21. areacheck = 0;
  22. }
  23. ClickWnd::~ClickWnd()
  24. {
  25. BaseWnd::hintDestroying(); // so basewnd doesn't call onCancelCapture
  26. if (getCapture()) endCapture();
  27. }
  28. void ClickWnd::setHandleRightClick(int tf)
  29. {
  30. handleRight=tf;
  31. }
  32. int ClickWnd::getHandleRightClick()
  33. {
  34. return handleRight;
  35. }
  36. int ClickWnd::onLeftButtonDown(int x, int y)
  37. {
  38. notifyParent(ChildNotify::CLICKWND_LEFTDOWN, x, y);
  39. CLICKWND_PARENT::onLeftButtonDown(x, y);
  40. abortTip();
  41. #ifdef _WIN32
  42. ifc_window *dp = getDesktopParent();
  43. if (dp != NULL)
  44. {
  45. if (dp->wantActivation())
  46. {
  47. SetActiveWindow(getRootParent()->gethWnd());
  48. SetFocus(getRootParent()->gethWnd());
  49. }
  50. else
  51. {
  52. HWND w = dp->gethWnd();
  53. HWND owner = GetWindow(w, GW_OWNER);
  54. if (owner != NULL) {
  55. SetActiveWindow(owner);
  56. SetFocus(owner);
  57. }
  58. }
  59. }
  60. else
  61. {
  62. SetActiveWindow(getRootParent()->gethWnd());
  63. }
  64. #else
  65. #warning port me or remove me
  66. #endif
  67. if (ptInRegion(x, y))
  68. return onButtonDown(CLICKWND_LBUTTONDOWN, x, y);
  69. else
  70. return 1;
  71. }
  72. int ClickWnd::onRightButtonDown(int x, int y)
  73. {
  74. notifyParent(ChildNotify::CLICKWND_RIGHTDOWN, x, y);
  75. CLICKWND_PARENT::onRightButtonDown(x, y);
  76. abortTip();
  77. if (!handleRight) return 1;
  78. if (ptInRegion(x, y))
  79. return onButtonDown(CLICKWND_RBUTTONDOWN, x, y);
  80. else
  81. return 1;
  82. }
  83. int ClickWnd::onLeftButtonUp(int x, int y)
  84. {
  85. notifyParent(ChildNotify::CLICKWND_LEFTUP, x, y);
  86. CLICKWND_PARENT::onLeftButtonUp(x, y);
  87. //jf
  88. // if (ptInRegion())
  89. return onButtonUp(CLICKWND_LBUTTONUP, x, y);
  90. // else
  91. // return 1;
  92. }
  93. int ClickWnd::onRightButtonUp(int x, int y)
  94. {
  95. notifyParent(ChildNotify::CLICKWND_RIGHTUP, x, y);
  96. CLICKWND_PARENT::onRightButtonUp(x, y);
  97. //jf
  98. //if (ptInRegion())
  99. if (!handleRight) {
  100. onRightPush(x, y);
  101. return 1;
  102. }
  103. return onButtonUp(CLICKWND_RBUTTONUP, x, y);
  104. // else
  105. // return 1;
  106. }
  107. int ClickWnd::onMouseMove(int x, int y)
  108. {
  109. POINT pos, rpos={x,y};
  110. int mouseover;
  111. CLICKWND_PARENT::onMouseMove(x, y);
  112. pos=rpos;
  113. clientToScreen(&pos);
  114. int lasthilite = hilite;
  115. mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == static_cast<ifc_window *>(this) && ptInRegion(x, y));
  116. if (!mouseover && (!mousedown
  117. #ifdef _WIN32
  118. || !Std::keyDown(button?MK_RBUTTON:MK_LBUTTON)
  119. #else
  120. #warning port me
  121. #endif
  122. )) {
  123. if (mcaptured || getCapture()) {
  124. endCapture();
  125. mcaptured = 0;
  126. }
  127. mousedown = 0;
  128. down = 0;
  129. if (wantClickWndAutoInvalidate()) invalidate();
  130. if (hilite) _onLeaveArea();
  131. hilite = 0;
  132. return 1;
  133. } else if (!mouseover && hilite) {
  134. hilite = 0;
  135. _onLeaveArea();
  136. } else if (mouseover && !hilite) {
  137. hilite = 1;
  138. _onEnterArea();
  139. }
  140. if (!getCapture() && mouseover) { // capture to see when leave
  141. _enterCapture();
  142. }
  143. int lastdown = down;
  144. hilite = mouseover;
  145. #ifdef WASABI_COMPILE_WNDMGR
  146. int m = getGuiObject() ? getGuiObject()->guiobject_getMover() : 0;
  147. #else
  148. int m = 0;
  149. #endif
  150. if (!m) {
  151. down = userDown() || (mouseover && mousedown);
  152. } else
  153. down = userDown() || mousedown;
  154. // FG> note to self now that i finally fixed this... :
  155. // there is a potential bottleneck here, if for some reason this test is always true when moving the windows around like crazy.
  156. if (down != lastdown || (hilite != lasthilite && !m)) {
  157. if (wantClickWndAutoInvalidate()) invalidate();
  158. }
  159. //invalidate();
  160. return 1;
  161. }
  162. void ClickWnd::_enterCapture()
  163. {
  164. //gee!! if (!hilite) _onEnterArea();
  165. if (!getCapture()) beginCapture();
  166. mcaptured = 1;
  167. }
  168. int ClickWnd::onButtonDown(int which, int x, int y)
  169. {
  170. if (!wantClicks()) return 1;
  171. if (!getCapture()) {
  172. _enterCapture();
  173. }
  174. mousedown = 1;
  175. down = 1;
  176. button = -1;
  177. if (which == CLICKWND_LBUTTONDOWN) button = 0;
  178. else if (which == CLICKWND_RBUTTONDOWN) button = 1;
  179. if (wantClickWndAutoInvalidate()) invalidate();
  180. return 1;
  181. }
  182. int ClickWnd::onButtonUp(int which, int x, int y)
  183. {
  184. // make sure same button
  185. if (button == 0 && which == CLICKWND_RBUTTONUP) return 1;
  186. if (button == 1 && which == CLICKWND_LBUTTONUP) return 1;
  187. if (!down) {
  188. if (mcaptured) {
  189. endCapture();
  190. mcaptured = 0;
  191. }
  192. if (hilite) _onLeaveArea();
  193. hilite = 0;
  194. mousedown = 0;
  195. return 1;
  196. }
  197. POINT pos={x,y};
  198. clientToScreen(&pos);
  199. int mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == (ifc_window *)this && ptInRegion(x, y));
  200. if (!mouseover) {
  201. if (mcaptured) {
  202. endCapture();
  203. mcaptured = 0;
  204. }
  205. if (hilite) _onLeaveArea();
  206. hilite = 0;
  207. }
  208. // it was down, process the event
  209. int a = down;
  210. down = 0;
  211. mousedown = 0;
  212. if (wantClickWndAutoInvalidate()) invalidate();
  213. if (a) {
  214. if (button == 0) onLeftPush(x, y);
  215. else if (button == 1) onRightPush(x, y);
  216. }
  217. // we need to do this again (and get the new mouse pos) because onLeft/RightPush may have called a
  218. // message loop and let the mouse leave without us being aware of it
  219. Wasabi::Std::getMousePos(&x, &y);
  220. pos.x = x;
  221. pos.y = y;
  222. screenToClient(&x, &y);
  223. mouseover = (WASABI_API_WND->rootWndFromPoint(&pos) == (ifc_window *)this && ptInRegion(x, y));
  224. if (!mouseover && hilite) _onLeaveArea();
  225. else if (mouseover && !hilite) _onEnterArea();
  226. hilite = mouseover;
  227. return 1;
  228. }
  229. void ClickWnd::onSetVisible( int show )
  230. {
  231. CLICKWND_PARENT::onSetVisible( show );
  232. if ( !show )
  233. {
  234. if ( getCapture() )
  235. {
  236. mcaptured = 0;
  237. endCapture();
  238. }
  239. down = 0;
  240. mousedown = 0;
  241. if ( hilite )
  242. _onLeaveArea();
  243. hilite = 0;
  244. }
  245. }
  246. void ClickWnd::_onEnterArea()
  247. {
  248. if (areacheck == 0) {
  249. areacheck++;
  250. onEnterArea();
  251. } else
  252. DebugString("onEnterArea check failed %08X \n", this);
  253. }
  254. void ClickWnd::_onLeaveArea()
  255. {
  256. if (areacheck == 1) {
  257. areacheck--;
  258. onLeaveArea();
  259. } else
  260. DebugString("onLeaveArea check failed %08X\n", this);
  261. }
  262. void ClickWnd::onEnterArea()
  263. {
  264. // DebugString("onEnterArea %08X\n", this);
  265. }
  266. void ClickWnd::onLeaveArea()
  267. {
  268. // DebugString("onLeaveArea %08X\n", this);
  269. }
  270. void ClickWnd::onCancelCapture()
  271. {
  272. CLICKWND_PARENT::onCancelCapture();
  273. mcaptured=0;
  274. down = 0;
  275. mousedown = 0;
  276. if (hilite) _onLeaveArea();
  277. hilite = 0;
  278. }