/platform/win/gui/osbutton.d

http://github.com/wilkie/djehuty · D · 252 lines · 169 code · 62 blank · 21 comment · 31 complexity · a2f0fd7199d19ffcbd0327ab826762a3 MD5 · raw file

  1. module gui.osbutton;
  2. import gui.button;
  3. import binding.win32.windef;
  4. import binding.win32.winnt;
  5. import binding.win32.winbase;
  6. import binding.win32.wingdi;
  7. import binding.win32.winuser;
  8. import platform.win.widget;
  9. import platform.win.main;
  10. import platform.vars.view;
  11. import core.string;
  12. import core.definitions;
  13. import gui.widget;
  14. import gui.window;
  15. import gui.apploop;
  16. import io.console;
  17. import graphics.view;
  18. import graphics.graphics;
  19. class OSButton : Button, WinWidget {
  20. this(int x, int y, int width, int height, string value) {
  21. super(x,y,width,height,value);
  22. }
  23. override void onAdd() {
  24. ViewPlatformVars* viewVars = _window._viewVars;
  25. HDC dc = GetDC(_hWnd);
  26. HDC dc2 = CreateCompatibleDC(dc);
  27. HBITMAP hbmp = CreateCompatibleBitmap(viewVars.dc, this.width, this.height);
  28. SelectObject(dc2, hbmp);
  29. DeleteObject(hbmp);
  30. ReleaseDC(_hWnd, dc);
  31. newx = -this.width + 1;
  32. newy = -this.height + 1;
  33. _hdc = dc2;
  34. _hWnd = CreateWindowExW(0,
  35. "BUTTON\0", cast(wchar*)_value.ptr, WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_TEXT ,
  36. newx, newy, this.width, this.height,
  37. _window._pfvars.hWnd, null, cast(HINSTANCE)GetWindowLongW(_window._pfvars.hWnd,GWLP_HINSTANCE), null);
  38. SetWindowPos(_hWnd, cast(HWND)HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
  39. SendMessageW( _hWnd, WM_SETFONT, cast(WPARAM)GuiApplicationController.win_button_font, 1);
  40. SetWindowLongW(_hWnd, GWLP_USERDATA, cast(LONG)(cast(void*)(cast(WinWidget)this)));
  41. _oldproc = cast(WNDPROC)SetWindowLongW(_hWnd, GWLP_WNDPROC, cast(ULONG)&GuiApplicationController.CtrlProc);
  42. SendMessageW(_hWnd, WM_PRINTCLIENT, cast(DWORD)_hdc, PRF_CHILDREN | PRF_CLIENT | PRF_ERASEBKGND | PRF_NONCLIENT | PRF_OWNED);
  43. }
  44. override void onDraw(ref Graphics g) {
  45. // save current background for later
  46. // copy over current image
  47. ViewPlatformVars* viewVars = _window._viewVars;
  48. BitBlt(viewVars.dc, this.left, this.top, this.width, this.height, _hdc, 0,0,SRCCOPY);
  49. }
  50. override bool onPrimaryMouseDown(ref Mouse mouse) {
  51. hasCapture = true;
  52. SendMessageW(_hWnd, WM_LBUTTONDOWN, 0, 0);
  53. return true;
  54. }
  55. override bool onPrimaryMouseUp(ref Mouse mouse) {
  56. hasCapture = false;
  57. SendMessageW(_hWnd, WM_LBUTTONUP, 0, 0);
  58. requestRelease();
  59. return true;
  60. }
  61. override bool onMouseEnter() {
  62. return false;
  63. }
  64. override bool onMouseMove(ref Mouse mouse) {
  65. if (hasCapture) {
  66. return false;
  67. }
  68. POINT pt;
  69. GetCursorPos(&pt);
  70. RECT rect;
  71. RECT client;
  72. int ncx, ncy;
  73. GetWindowRect(_window._pfvars.hWnd, &rect);
  74. ncx = rect.left;
  75. ncy = rect.top;
  76. ncx = pt.x + (newx - this.left);
  77. ncy = pt.y + (newy - this.top);
  78. ncy &= 0xffff;
  79. ncx &= 0xffff;
  80. uint lparam = (ncy << 16) | (ncx);
  81. SendMessageW(_hWnd, WM_NCHITTEST, 0, lparam);
  82. lparam = ((mouse.y - this.top) << 16) | (mouse.x - this.left);
  83. SendMessageW(_hWnd, WM_MOUSEMOVE, 0, lparam);
  84. SendMessageW(_hWnd, WM_PAINT, 0, 0);
  85. //SendMessageW(_hWnd, WM_MOUSEHOVER, 0, lparam);
  86. return false;
  87. }
  88. override bool onMouseLeave() {
  89. // Console.putln("mouseleave");
  90. SendMessageW(_hWnd, WM_MOUSELEAVE, 0, 0);
  91. return true;
  92. }
  93. override void onRemove() {
  94. DestroyWindow(_hWnd);
  95. }
  96. protected:
  97. HDC _GetDC() {
  98. return _hdc;
  99. }
  100. LRESULT _AppLoopMessage(uint message, WPARAM wParam, LPARAM lParam) {
  101. // Console.putln("message: ", new String("%x",message), " ml:", new String("%x", WM_MOUSELEAVE));
  102. if (message == WM_COMMAND) {
  103. raiseSignal(Button.Signal.Selected);
  104. return 0;
  105. }
  106. else if (message == WM_LBUTTONUP && hasCapture) {
  107. short x, y;
  108. x = cast(short)(lParam & 0xffff);
  109. y = cast(short)((lParam >> 16) & 0xffff);
  110. // convert coords to window coords, send window WM_MOUSEMOVE
  111. x += newx; //this.left;
  112. y += newy;
  113. uint windowlParam = (y << 16) | x;
  114. x = cast(short)(lParam & 0xffff);
  115. y = cast(short)((lParam >> 16) & 0xffff);
  116. // Console.putln("mouse up (captured) x:", x, "y:",y);
  117. SendMessageW(_window._pfvars.hWnd, message, 0, windowlParam);
  118. }
  119. else if (message == WM_MOUSELEAVE) {
  120. // ignore!
  121. if (_hovered) {
  122. //Console.putln("message ignored");
  123. return 0;
  124. }
  125. else {
  126. //Console.putln("message meh!");
  127. }
  128. }
  129. else if (message == WM_NCHITTEST || message == WM_MOUSEMOVE) {
  130. // change wParam to point to where it thinks it is
  131. short x, y;
  132. x = cast(short)(lParam & 0xffff);
  133. y = cast(short)((lParam >> 16) & 0xffff);
  134. if (message == WM_NCHITTEST) {
  135. //Console.put("HT ");
  136. }
  137. else {
  138. //Console.put("MM ");
  139. }
  140. //Console.putln("x: ", x, " y: ", y);
  141. if (hasCapture) {
  142. // convert coords to window coords, send window WM_MOUSEMOVE
  143. x += newx; //this.left;
  144. y += newy;
  145. uint windowlParam = (y << 16) | x;
  146. x = cast(short)(lParam & 0xffff);
  147. y = cast(short)((lParam >> 16) & 0xffff);
  148. // Console.putln("mouse move (captured) x:", x, "y:",y);
  149. SendMessageW(_window._pfvars.hWnd,WM_MOUSEMOVE, 0, windowlParam);
  150. }
  151. else {
  152. //Console.putln("mouse move");
  153. }
  154. if (message == WM_MOUSEMOVE) {
  155. if (_hovered) {
  156. // Console.putln("hovered");
  157. x += (newx - this.left);
  158. y += (newy - this.top);
  159. lParam = (y << 16) | x;
  160. }
  161. else {
  162. //Console.putln("not hovered");
  163. }
  164. }
  165. // Console.putln("x: ", x, " y: ", y, " msg: ", new String("%x",message));
  166. }
  167. else if (message == WM_ERASEBKGND) {
  168. }
  169. auto ret = CallWindowProcW(_oldproc, _hWnd, message, wParam, lParam);
  170. //Console.putln("return: ", ret);
  171. if (message == WM_PAINT) {
  172. _window.onDraw();
  173. }
  174. return ret;
  175. }
  176. View _ReturnView(out int x, out int y, out int w, out int h) {
  177. x = this.left;
  178. y = this.top;
  179. w = this.width;
  180. h = this.height;
  181. return _view;
  182. }
  183. HWND _hWnd;
  184. HDC _hdc;
  185. WNDPROC _oldproc;
  186. bool noDraw;
  187. bool hasCapture;
  188. int newy;
  189. int newx;
  190. }