resize.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. #include <precomp.h>
  2. #ifdef WIN32
  3. #include <windows.h>
  4. #endif
  5. #include <bfc/assert.h>
  6. #include <api/wndmgr/resize.h>
  7. #include <api/wnd/wndtrack.h>
  8. #include <api/wnd/basewnd.h>
  9. #include <api/wndmgr/layout.h>
  10. #define tag L"wa3_resizerclass"
  11. extern HINSTANCE hInstance;
  12. //----------------------------------------------------------------------
  13. resizeClass::resizeClass(ifc_window *wnd, int minx, int miny, int maxx, int maxy, int sugx, int sugy)
  14. {
  15. screenWidth = Wasabi::Std::getScreenWidth();
  16. screenHeight = Wasabi::Std::getScreenHeight();
  17. #if defined (_WIN32) || defined(_WIN64)
  18. WNDCLASSW wc;
  19. if (!GetClassInfoW(hInstance, tag, &wc))
  20. {
  21. MEMSET(&wc, 0, sizeof(wc));
  22. wc.lpfnWndProc = resizeWndProc;
  23. wc.hInstance = hInstance; // hInstance of DLL
  24. wc.lpszClassName = tag; // our window class name
  25. wc.style = 0;
  26. int _r = RegisterClassW(&wc);
  27. ASSERTPR(_r, "cannot create resizer wndclass");
  28. }
  29. hWnd = CreateWindowExW(0, tag, L"", 0, 0, 0, 1, 1, NULL, NULL, hInstance, NULL);
  30. ASSERT(hWnd);
  31. SetWindowLongPtrW(hWnd, GWLP_USERDATA, (LONG_PTR)this);
  32. if (minx > maxx && maxx != -1) minx = maxx;
  33. if (miny > maxy && maxy != -1) miny = maxy;
  34. #endif
  35. minWinWidth = minx;
  36. minWinHeight = miny;
  37. maxWinWidth = maxx;
  38. maxWinHeight = maxy;
  39. sugWinWidth = sugx;
  40. sugWinHeight = sugy;
  41. if (wnd->getInterface(layoutGuid))
  42. {
  43. static_cast<Layout *>(wnd)->getSnapAdjust(&snapAdjust);
  44. if (minWinWidth != -1) minWinWidth -= snapAdjust.left + snapAdjust.right;
  45. if (minWinHeight != -1) minWinHeight -= snapAdjust.bottom + snapAdjust.top;
  46. if (maxWinWidth != -1) maxWinWidth -= snapAdjust.left + snapAdjust.right;
  47. if (maxWinHeight != -1) maxWinHeight -= snapAdjust.bottom + snapAdjust.top;
  48. if (sugWinWidth != -1) sugWinWidth -= snapAdjust.left + snapAdjust.right;
  49. if (sugWinHeight != -1) sugWinHeight -= snapAdjust.bottom + snapAdjust.top;
  50. }
  51. dc = NULL;
  52. #ifdef WIN32
  53. oldB = NULL;
  54. brush = NULL;
  55. oldP = NULL;
  56. pen = NULL;
  57. #endif
  58. }
  59. //----------------------------------------------------------------------
  60. resizeClass::~resizeClass()
  61. {
  62. #ifdef WIN32
  63. if (dc)
  64. {
  65. SelectObject(dc, oldB);
  66. SelectObject(dc, oldP);
  67. SetROP2(dc, mix);
  68. DeleteObject(pen);
  69. DeleteObject(brush);
  70. ReleaseDC(NULL, dc);
  71. }
  72. if (IsWindow(hWnd))
  73. DestroyWindow(hWnd);
  74. //BU win98 sucks UnregisterClass(tag, Main::gethInstance());
  75. #else
  76. if (dc)
  77. {
  78. XFreeGC(Linux::getDisplay(), dc->gc);
  79. FREE(dc);
  80. }
  81. #endif
  82. }
  83. //----------------------------------------------------------------------
  84. BOOL CALLBACK invalidateChildren(HWND hwnd, LPARAM lParam)
  85. {
  86. InvalidateRect(hwnd, NULL, FALSE);
  87. return TRUE;
  88. }
  89. //----------------------------------------------------------------------
  90. BOOL CALLBACK invalidateAll(HWND hwnd, LPARAM lParam)
  91. {
  92. EnumChildWindows(hwnd, invalidateChildren, 0);
  93. InvalidateRect(hwnd, NULL, FALSE);
  94. return TRUE;
  95. }
  96. //----------------------------------------------------------------------
  97. int resizeClass::resizeWindow(ifc_window *wnd, int way)
  98. {
  99. // paintHookStart();
  100. wnd->getWindowRect(&originalRect);
  101. snapAdjust.left = 0;
  102. snapAdjust.top = 0;
  103. snapAdjust.right = 0;
  104. snapAdjust.bottom = 0;
  105. if (wnd->getInterface(layoutGuid))
  106. {
  107. static_cast<Layout *>(wnd)->getSnapAdjust(&snapAdjust);
  108. if (wnd->getRenderRatio() != 1.0)
  109. {
  110. double rr = wnd->getRenderRatio();
  111. snapAdjust.left = (int)((double)(snapAdjust.left) * rr);
  112. snapAdjust.top = (int)((double)(snapAdjust.top) * rr);
  113. snapAdjust.right = (int)((double)(snapAdjust.right) * rr);
  114. snapAdjust.bottom = (int)((double)(snapAdjust.bottom) * rr);
  115. }
  116. originalRect.left += snapAdjust.left;
  117. originalRect.top += snapAdjust.top;
  118. originalRect.right -= snapAdjust.right;
  119. originalRect.bottom -= snapAdjust.bottom;
  120. }
  121. curRect = originalRect;
  122. resizeWay = way;
  123. resizedWindow = wnd->gethWnd();
  124. resizedWindowR = wnd;
  125. POINT pt;
  126. Wasabi::Std::getMousePos(&pt);
  127. cX = pt.x;
  128. cY = pt.y;
  129. #ifdef WIN32
  130. SetCapture(hWnd);
  131. #endif
  132. SetTimer(hWnd, 1, 100, NULL); // this timer will make sure that we never get interlock
  133. drawFrame();
  134. MSG msg;
  135. cancelit = 1;
  136. while (GetCapture() == hWnd && GetMessage( &msg, hWnd, 0, 0 ))
  137. {
  138. TranslateMessage( &msg );
  139. #ifdef LINUX
  140. if ( msg.message == WM_LBUTTONUP || msg.message == WM_MOUSEMOVE )
  141. wndProc( msg.hwnd, msg.message, msg.wParam, msg.lParam );
  142. else
  143. #endif
  144. DispatchMessage( &msg );
  145. }
  146. drawFrame();
  147. // paintHookStop();
  148. if (GetCapture() == hWnd) ReleaseCapture();
  149. KillTimer(hWnd, 1);
  150. if (!cancelit)
  151. {
  152. curRect.left -= snapAdjust.left;
  153. curRect.top -= snapAdjust.top;
  154. curRect.right += snapAdjust.right;
  155. curRect.bottom += snapAdjust.bottom;
  156. }
  157. else
  158. {
  159. curRect = originalRect;
  160. // evil, but less evil than InvalidateRect(NULL, NULL, FALSE);
  161. EnumWindows(invalidateAll, 0);
  162. }
  163. return !cancelit;
  164. }
  165. //----------------------------------------------------------------------
  166. RECT resizeClass::getRect(void)
  167. {
  168. return curRect;
  169. }
  170. //#define nifty
  171. //----------------------------------------------------------------------
  172. void resizeClass::drawFrame(void)
  173. {
  174. RECT outRect;
  175. #ifdef WIN32
  176. if (!dc)
  177. {
  178. dc = GetDC(NULL);
  179. brush = CreateSolidBrush(0xFFFFFF);
  180. pen = CreatePen(PS_SOLID, 0, 0xFFFFFF);
  181. oldB = (HBRUSH)SelectObject(dc, brush);
  182. oldP = (HPEN)SelectObject(dc, pen);
  183. mix = SetROP2(dc, R2_XORPEN);
  184. }
  185. outRect = curRect;
  186. #ifndef nifty
  187. DrawFocusRect(dc, &outRect);
  188. #else
  189. RECT inRect;
  190. inRect = outRect;
  191. inRect.left += 10;
  192. inRect.right -= 10;
  193. inRect.top += 24;
  194. inRect.bottom -= 10;
  195. MoveToEx(dc, inRect.left, inRect.top, NULL);
  196. LineTo(dc, inRect.right, inRect.top);
  197. LineTo(dc, inRect.right, inRect.bottom);
  198. LineTo(dc, inRect.left, inRect.bottom);
  199. LineTo(dc, inRect.left, inRect.top);
  200. MoveToEx(dc, outRect.left, 0, NULL);
  201. LineTo(dc, outRect.left, screenHeight);
  202. MoveToEx(dc, outRect.right, 0, NULL);
  203. LineTo(dc, outRect.right, screenHeight);
  204. MoveToEx(dc, 0, outRect.top, NULL);
  205. LineTo(dc, screenWidth, outRect.top);
  206. MoveToEx(dc, 0, outRect.bottom, NULL);
  207. LineTo(dc, screenWidth, outRect.bottom);
  208. #endif
  209. #endif//WIN32
  210. #ifdef LINUX
  211. outRect = curRect;
  212. if ( ! dc )
  213. {
  214. dc = (HDC)MALLOC( sizeof( hdc_typ ) );
  215. XGCValues gcv;
  216. gcv.function = GXxor;
  217. gcv.subwindow_mode = IncludeInferiors;
  218. gcv.foreground = 0xffffff;
  219. gcv.line_style = LineOnOffDash;
  220. gcv.dashes = 1;
  221. dc->gc = XCreateGC( Linux::getDisplay(), Linux::RootWin(), GCFunction | GCForeground | GCSubwindowMode, &gcv );
  222. }
  223. XDrawRectangle( Linux::getDisplay(), Linux::RootWin(), dc->gc,
  224. outRect.left, outRect.top, outRect.right - outRect.left,
  225. outRect.bottom - outRect.top );
  226. #endif
  227. //PORTME
  228. }
  229. LRESULT resizeClass::wndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  230. {
  231. switch (uMsg)
  232. {
  233. case WM_LBUTTONUP:
  234. cancelit = 0;
  235. ReleaseCapture();
  236. return 0;
  237. case WM_MOUSEMOVE:
  238. {
  239. POINT pt;
  240. int iX, iY;
  241. Wasabi::Std::getMousePos(&pt);
  242. iX = pt.x - cX;
  243. iY = pt.y - cY;
  244. drawFrame();
  245. if (resizeWay & TOP)
  246. curRect.top = originalRect.top + iY;
  247. if (resizeWay & BOTTOM)
  248. curRect.bottom = originalRect.bottom + iY;
  249. if (resizeWay & LEFT)
  250. curRect.left = originalRect.left + iX;
  251. if (resizeWay & RIGHT)
  252. curRect.right = originalRect.right + iX;
  253. if (abs((curRect.right - curRect.left) - sugWinWidth) < 10)
  254. if (resizeWay & RIGHT)
  255. curRect.right = curRect.left + sugWinWidth;
  256. else if (resizeWay & LEFT)
  257. curRect.left = curRect.right - sugWinWidth;
  258. if (abs((curRect.bottom - curRect.top) - sugWinHeight) < 10)
  259. if (resizeWay & BOTTOM)
  260. curRect.bottom = curRect.top + sugWinHeight;
  261. else if (resizeWay & TOP)
  262. curRect.top = curRect.bottom - sugWinHeight;
  263. curRect.left -= snapAdjust.left;
  264. curRect.top -= snapAdjust.top;
  265. curRect.right += snapAdjust.right;
  266. curRect.bottom += snapAdjust.bottom;
  267. windowTracker->autoDock(resizedWindowR, &curRect, resizeWay);
  268. curRect.left += snapAdjust.left;
  269. curRect.top += snapAdjust.top;
  270. curRect.right -= snapAdjust.right;
  271. curRect.bottom -= snapAdjust.bottom;
  272. if ((curRect.right - curRect.left) < minWinWidth)
  273. if (resizeWay & RIGHT)
  274. curRect.right = curRect.left + minWinWidth;
  275. else if (resizeWay & LEFT)
  276. curRect.left = curRect.right - minWinWidth;
  277. if ((curRect.bottom - curRect.top) < minWinHeight)
  278. if (resizeWay & BOTTOM)
  279. curRect.bottom = curRect.top + minWinHeight;
  280. else if (resizeWay & TOP)
  281. curRect.top = curRect.bottom - minWinHeight;
  282. if (maxWinWidth != -1 && (curRect.right - curRect.left) > maxWinWidth)
  283. if (resizeWay & RIGHT)
  284. curRect.right = curRect.left + maxWinWidth;
  285. else if (resizeWay & LEFT)
  286. curRect.left = curRect.right - maxWinWidth;
  287. if (maxWinHeight != -1 && (curRect.bottom - curRect.top) > maxWinHeight)
  288. if (resizeWay & BOTTOM)
  289. curRect.bottom = curRect.top + maxWinHeight;
  290. else if (resizeWay & TOP)
  291. curRect.top = curRect.bottom - maxWinHeight;
  292. drawFrame();
  293. }
  294. return 0;
  295. }
  296. #ifdef WIN32
  297. return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  298. #else
  299. return 0;
  300. #endif
  301. }
  302. // Window Procedure
  303. //
  304. LRESULT CALLBACK resizeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  305. {
  306. #ifdef WIN32
  307. resizeClass *gThis = (resizeClass *)GetWindowLongPtrW(hwnd, GWLP_USERDATA);
  308. if (!gThis)
  309. return DefWindowProcW(hwnd, uMsg, wParam, lParam);
  310. else
  311. return gThis->wndProc(hwnd, uMsg, wParam, lParam);
  312. #else
  313. return 0;
  314. #endif
  315. }
  316. void resizeClass::setResizeCursor(int action)
  317. {}