virtualwnd.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672
  1. #include <precomp.h>
  2. #include "virtualwnd.h"
  3. #include <tataki/region/api_region.h>
  4. #include <api/wnd/usermsg.h>
  5. #include <api/wnd/accessible.h>
  6. VirtualWnd::VirtualWnd()
  7. {
  8. virtualX = virtualY = virtualH = virtualW = 0;
  9. bypassvirtual = 0;
  10. focus = 0;
  11. resizecount = 0;
  12. lastratio = 1;
  13. }
  14. VirtualWnd::~VirtualWnd()
  15. {}
  16. int VirtualWnd::init(ifc_window *parWnd, int nochild)
  17. {
  18. if (!bypassvirtual)
  19. setParent(parWnd);
  20. return (VIRTUALWND_PARENT::init(parWnd, nochild));
  21. }
  22. int VirtualWnd::init(OSMODULEHANDLE moduleHandle, OSWINDOWHANDLE parent, int nochild)
  23. {
  24. if (!bypassvirtual)
  25. {
  26. ASSERTPR(getParent() != NULL, "Virtual window created without specifying BaseWnd parent");
  27. if (getStartHidden())
  28. this_visible = 0;
  29. else
  30. this_visible = 1;
  31. onInit();
  32. onPostOnInit();
  33. if (isVisible())
  34. onSetVisible(1);
  35. return 1;
  36. }
  37. else
  38. return VIRTUALWND_PARENT::init(moduleHandle, parent, nochild);
  39. }
  40. OSWINDOWHANDLE VirtualWnd::getOsWindowHandle()
  41. {
  42. // ASSERTPR(getParent() != NULL, "Virtual window used as base parent !");
  43. if (!bypassvirtual)
  44. {
  45. if (!getParent())
  46. return INVALIDOSWINDOWHANDLE;
  47. return getParent()->getOsWindowHandle();
  48. }
  49. else
  50. {
  51. return VIRTUALWND_PARENT::getOsWindowHandle();
  52. }
  53. }
  54. OSMODULEHANDLE VirtualWnd::getOsModuleHandle()
  55. {
  56. if (!bypassvirtual)
  57. {
  58. if (!getParent())
  59. return INVALIDOSMODULEHANDLE;
  60. return getParent()->getOsModuleHandle();
  61. }
  62. else
  63. return VIRTUALWND_PARENT::getOsModuleHandle();
  64. }
  65. void VirtualWnd::resize(RECT *r, int wantcb)
  66. {
  67. if (!bypassvirtual)
  68. {
  69. resize(r->left, r->top, r->right - r->left, r->bottom - r->top, wantcb);
  70. }
  71. else
  72. {
  73. VIRTUALWND_PARENT::resize( r, wantcb );
  74. //virtualX = rx;
  75. //virtualY = ry;
  76. //virtualW = rwidth;
  77. //virtualH = rheight;
  78. }
  79. }
  80. // fg> the resizecount > 1 is a hack, it should be 0 but i need more time to fix this thing, at least this way we don't lose the optim
  81. void VirtualWnd::resize(int x, int y, int w, int h, int wantcb)
  82. {
  83. if (!bypassvirtual)
  84. {
  85. if (x == NOCHANGE)
  86. x = virtualX;
  87. if (y == NOCHANGE)
  88. y = virtualY;
  89. if (w == NOCHANGE)
  90. w = virtualW;
  91. if (h == NOCHANGE)
  92. h = virtualH;
  93. double thisratio = getRenderRatio();
  94. if (resizecount > 1 && virtualX == x && virtualY == y && virtualW == w && virtualH == h && lastratio == thisratio)
  95. return ;
  96. lastratio = thisratio;
  97. if (isVisible())
  98. {
  99. RECT r;
  100. getNonClientRect(&r);
  101. invalidateRect(&r);
  102. }
  103. virtualX = x;
  104. virtualY = y;
  105. virtualW = w;
  106. virtualH = h;
  107. if (isVisible())
  108. {
  109. RECT r;
  110. getNonClientRect(&r);
  111. invalidateRect(&r);
  112. }
  113. setRSize(x, y, w, h);
  114. if (wantcb && isPostOnInit())
  115. {
  116. resizecount = MIN(resizecount + 1, 2);
  117. onResize();
  118. }
  119. }
  120. else
  121. {
  122. VIRTUALWND_PARENT::resize( x, y, w, h, wantcb );
  123. //virtualX = rx;
  124. //virtualY = ry;
  125. //virtualW = rwidth;
  126. //virtualH = rheight;
  127. }
  128. }
  129. //CUTvoid VirtualWnd::resize(RECT *r) {
  130. //CUT resize(r->left, r->top, r->right-r->left, r->bottom-r->top);
  131. //CUT}
  132. void VirtualWnd::move(int x, int y)
  133. {
  134. //DebugStringW( L"VirtualWnd::move( x = %d, y = %d )\n", x, y );
  135. if (!bypassvirtual)
  136. {
  137. if (isVisible())
  138. {
  139. RECT r;
  140. getNonClientRect(&r);
  141. invalidateRect(&r);
  142. }
  143. virtualX = x;
  144. virtualY = y;
  145. if (isVisible())
  146. {
  147. RECT r;
  148. getNonClientRect(&r);
  149. invalidateRect(&r);
  150. }
  151. }
  152. else
  153. {
  154. VIRTUALWND_PARENT::move( x, y );
  155. //virtualX = x;
  156. //virtualY = y;
  157. }
  158. }
  159. void VirtualWnd::invalidate()
  160. {
  161. if (!bypassvirtual)
  162. {
  163. if (!getRootParent()) return ;
  164. RECT r(clientRect());
  165. getRootParent()->invalidateRectFrom(&r, this);
  166. // VIRTUALWND_PARENT::invalidate();
  167. }
  168. else
  169. VIRTUALWND_PARENT::invalidate();
  170. }
  171. void VirtualWnd::invalidateRect(RECT *r)
  172. {
  173. if (!bypassvirtual)
  174. {
  175. if (!getRootParent()) return ;
  176. getRootParent()->invalidateRectFrom(r, this);
  177. }
  178. else
  179. VIRTUALWND_PARENT::invalidateRect(r);
  180. }
  181. void VirtualWnd::invalidateRgn(api_region *reg)
  182. {
  183. if (!bypassvirtual)
  184. {
  185. if (!getRootParent()) return ;
  186. getRootParent()->invalidateRgnFrom(reg, this);
  187. }
  188. else
  189. VIRTUALWND_PARENT::invalidateRgn(reg);
  190. }
  191. void VirtualWnd::validate()
  192. {
  193. if (!bypassvirtual)
  194. {
  195. if (!getRootParent()) return ;
  196. RECT r;
  197. getClientRect(&r);
  198. getRootParent()->validateRect(&r);
  199. }
  200. else
  201. VIRTUALWND_PARENT::validate();
  202. }
  203. void VirtualWnd::validateRect(RECT *r)
  204. {
  205. if (!bypassvirtual)
  206. {
  207. if (!getRootParent())
  208. return ;
  209. getRootParent()->validateRect(r);
  210. }
  211. else
  212. VIRTUALWND_PARENT::validateRect( r );
  213. }
  214. void VirtualWnd::validateRgn(api_region *reg)
  215. {
  216. if (!bypassvirtual)
  217. {
  218. if (!getRootParent()) return ;
  219. getRootParent()->validateRgn(reg);
  220. }
  221. else
  222. VIRTUALWND_PARENT::validateRgn(reg);
  223. }
  224. void VirtualWnd::getClientRect(RECT *rect)
  225. {
  226. if (!bypassvirtual)
  227. {
  228. // CT:getClientRect behaves differently here for virtual windows
  229. // so we can use onPaint directly on the destination canvas
  230. // without using another temporary canvas.
  231. Wasabi::Std::setRect(rect, virtualX, virtualY, virtualX + virtualW, virtualY + virtualH);
  232. // rect->left=0; rect->right=virtualW;
  233. // rect->top=0; rect->bottom=virtualH;
  234. }
  235. else
  236. VIRTUALWND_PARENT::getClientRect(rect);
  237. }
  238. void VirtualWnd::getNonClientRect(RECT *rect)
  239. {
  240. VirtualWnd::getClientRect(rect);
  241. }
  242. void VirtualWnd::getWindowRect(RECT *rect)
  243. {
  244. if (!bypassvirtual)
  245. {
  246. RECT a;
  247. getRootParent()->getWindowRect(&a);
  248. int x = virtualX, y = virtualY, w = virtualW, h = virtualH;
  249. if (renderRatioActive())
  250. {
  251. multRatio(&x, &y);
  252. multRatio(&w, &h);
  253. }
  254. rect->left = a.left + x; rect->right = rect->left + w;
  255. rect->top = a.top + y; rect->bottom = rect->top + h;
  256. }
  257. else
  258. VIRTUALWND_PARENT::getWindowRect(rect);
  259. }
  260. int VirtualWnd::beginCapture()
  261. {
  262. if (!bypassvirtual)
  263. {
  264. disable_tooltip_til_recapture = 0;
  265. getRootParent()->setVirtualChildCapture(this);
  266. return 1;
  267. }
  268. else
  269. return VIRTUALWND_PARENT::beginCapture();
  270. }
  271. int VirtualWnd::endCapture()
  272. {
  273. if (!bypassvirtual)
  274. {
  275. if (getRootParent() == NULL) return 0;
  276. getRootParent()->setVirtualChildCapture(NULL);
  277. return 1;
  278. }
  279. else
  280. return VIRTUALWND_PARENT::endCapture();
  281. }
  282. int VirtualWnd::getCapture()
  283. {
  284. if (!bypassvirtual)
  285. {
  286. if (getRootParent() == NULL) return 0;
  287. return getRootParent()->getVirtualChildCapture() == this;
  288. }
  289. else
  290. return VIRTUALWND_PARENT::getCapture();
  291. }
  292. void VirtualWnd::setVirtualChildCapture(BaseWnd *child)
  293. {
  294. if (!bypassvirtual)
  295. {
  296. getParent()->setVirtualChildCapture(child);
  297. }
  298. else
  299. VIRTUALWND_PARENT::setVirtualChildCapture(child);
  300. }
  301. // eek
  302. void VirtualWnd::repaint()
  303. {
  304. if (!bypassvirtual)
  305. {
  306. if (!getParent()) return ;
  307. getParent()->repaint();
  308. }
  309. else
  310. VIRTUALWND_PARENT::repaint();
  311. }
  312. /*int VirtualWnd::focusNextSibbling(int dochild) {
  313. return 1;
  314. }
  315. int VirtualWnd::focusNextVirtualChild(BaseWnd *child) {
  316. return 1;
  317. }*/
  318. int VirtualWnd::cascadeRepaint(int pack)
  319. {
  320. if (!bypassvirtual)
  321. {
  322. if (getRootParent())
  323. {
  324. RECT r;
  325. VirtualWnd::getNonClientRect(&r);
  326. getRootParent()->cascadeRepaintRectFrom(&r, this, pack);
  327. }
  328. return 1;
  329. }
  330. else
  331. return VIRTUALWND_PARENT::cascadeRepaint(pack);
  332. }
  333. int VirtualWnd::cascadeRepaintRect(RECT *r, int pack)
  334. {
  335. if (!bypassvirtual)
  336. {
  337. if (getRootParent())
  338. {
  339. getRootParent()->cascadeRepaintRectFrom(r, this, pack);
  340. }
  341. return 1;
  342. }
  343. else
  344. return VIRTUALWND_PARENT::cascadeRepaintRect(r, pack);
  345. }
  346. int VirtualWnd::cascadeRepaintRgn(api_region *r, int pack)
  347. {
  348. if (!bypassvirtual)
  349. {
  350. if (getRootParent())
  351. {
  352. getRootParent()->cascadeRepaintRgnFrom(r, this, pack);
  353. }
  354. return 1;
  355. }
  356. else
  357. return VIRTUALWND_PARENT::cascadeRepaintRgn(r, pack);
  358. }
  359. /*api_window *VirtualWnd::getWindowBehindMyself(int x, int y) {
  360. RECT r;
  361. if (!bypassvirtual) {
  362. if (!getParent()) return NULL;
  363. int n = getParent()->getNumVirtuals();
  364. api_window *c = NULL;
  365. for (int i=n-1;i>=0;i++) {
  366. c = getParent()->getVirtualChild(i);
  367. if (c == this) break;
  368. }
  369. i--;
  370. if (i < 0) return getParent();
  371. for (;i>=0; i--) {
  372. c = getParent()->getVirtualChild(i);
  373. c->getNonClientRect(&r);
  374. if (x>=r.left&&x<=r.right&&y>=r.top&&y<=r.bottom)
  375. return c;
  376. }
  377. return getParent();
  378. } else
  379. return NULL;
  380. }*/
  381. ifc_window *VirtualWnd::rootWndFromPoint(POINT *pt)
  382. {
  383. if (!bypassvirtual)
  384. {
  385. if (!getParent()) return NULL;
  386. return getParent()->rootWndFromPoint(pt);
  387. }
  388. else
  389. return VIRTUALWND_PARENT::rootWndFromPoint(pt);
  390. }
  391. double VirtualWnd::getRenderRatio()
  392. {
  393. if (!bypassvirtual)
  394. {
  395. if (!getParent()) return 1.0;
  396. return getParent()->getRenderRatio();
  397. }
  398. else
  399. return VIRTUALWND_PARENT::getRenderRatio();
  400. }
  401. void VirtualWnd::bringToFront()
  402. {
  403. if (!bypassvirtual)
  404. {
  405. if (!getParent()) return ;
  406. //getParent()->bringVirtualToFront(this); TODO: FIX!!!
  407. }
  408. else
  409. VIRTUALWND_PARENT::bringToFront();
  410. }
  411. void VirtualWnd::bringToBack()
  412. {
  413. if (!bypassvirtual)
  414. {
  415. if (!getParent()) return ;
  416. //getParent()->bringVirtualToBack(this); TODO: FIX!!!
  417. }
  418. else
  419. VIRTUALWND_PARENT::bringToBack();
  420. }
  421. void VirtualWnd::bringAbove(BaseWnd *o)
  422. {
  423. if (!bypassvirtual)
  424. {
  425. if (!getParent()) return ;
  426. getParent()->bringVirtualAbove(this, o);
  427. } /* else
  428. VIRTUALWND_PARENT::bringAbove();*/
  429. }
  430. void VirtualWnd::bringBelow(BaseWnd *o)
  431. {
  432. if (!bypassvirtual)
  433. {
  434. if (!getParent()) return ;
  435. getParent()->bringVirtualBelow(this, o);
  436. } /* else
  437. VIRTUALWND_PARENT::bringBelow();*/
  438. }
  439. int VirtualWnd::reparent(ifc_window *newparent)
  440. {
  441. if (!bypassvirtual)
  442. {
  443. if (getParent())
  444. getParent()->unregisterRootWndChild(this);
  445. parentWnd = NULL;
  446. newparent->registerRootWndChild(this);
  447. onSetParent(newparent);
  448. newparent->invalidate();
  449. return 1;
  450. }
  451. else
  452. {
  453. return VIRTUALWND_PARENT::reparent(newparent);
  454. }
  455. }
  456. int VirtualWnd::setVirtual(int i)
  457. {
  458. // ASSERT(!isInited()); // cut
  459. if (isInited()) return 0;
  460. bypassvirtual = !i;
  461. return 1;
  462. }
  463. ifc_window *VirtualWnd::getRootParent()
  464. {
  465. if (!bypassvirtual)
  466. {
  467. if (!getParent()) return NULL;
  468. ifc_window *t = this;
  469. while (t->isVirtual())
  470. {
  471. if (!t->getParent()) return NULL;
  472. t = t->getParent();
  473. }
  474. return t;
  475. }
  476. else
  477. {
  478. return VIRTUALWND_PARENT::getRootParent();
  479. }
  480. }
  481. int VirtualWnd::gotFocus()
  482. {
  483. if (!bypassvirtual)
  484. return focus;
  485. else
  486. return VIRTUALWND_PARENT::gotFocus();
  487. }
  488. int VirtualWnd::onGetFocus()
  489. {
  490. if (!bypassvirtual)
  491. {
  492. focus = 1;
  493. getRootParent()->onSetRootFocus(this);
  494. invalidate();
  495. Accessible *a = getAccessibleObject();
  496. if (a != NULL)
  497. a->onGetFocus();
  498. }
  499. else
  500. return VIRTUALWND_PARENT::onGetFocus();
  501. return 1;
  502. }
  503. int VirtualWnd::onKillFocus()
  504. {
  505. if (!bypassvirtual)
  506. {
  507. focus = 0;
  508. invalidate();
  509. }
  510. else
  511. return VIRTUALWND_PARENT::onKillFocus();
  512. return 1;
  513. }
  514. void VirtualWnd::setFocus()
  515. {
  516. ifc_window *f = this;
  517. if (!f->wantFocus() && f->getParent())
  518. {
  519. while (f)
  520. {
  521. ifc_window *rp = f->getRootParent();
  522. if (rp == f) rp = f->getParent();
  523. f = rp;
  524. if (f && (!f->getParent() || f->wantFocus() || f == WASABI_API_WND->main_getRootWnd()))
  525. {
  526. f->setFocus();
  527. break;
  528. }
  529. }
  530. }
  531. else
  532. {
  533. if (!bypassvirtual)
  534. {
  535. if (getParent())
  536. {
  537. getParent()->setVirtualChildFocus(this);
  538. }
  539. }
  540. else
  541. VIRTUALWND_PARENT::setFocus();
  542. }
  543. }
  544. void VirtualWnd::setVirtualChildFocus(ifc_window *child)
  545. {
  546. if (!bypassvirtual)
  547. {
  548. getParent()->setVirtualChildFocus(child);
  549. }
  550. else
  551. VIRTUALWND_PARENT::setVirtualChildFocus(child);
  552. }
  553. int VirtualWnd::onActivate()
  554. {
  555. if (bypassvirtual)
  556. return VIRTUALWND_PARENT::onActivate();
  557. return 1;
  558. }
  559. int VirtualWnd::onDeactivate()
  560. {
  561. if (bypassvirtual)
  562. return VIRTUALWND_PARENT::onDeactivate();
  563. return 1;
  564. }
  565. void VirtualWnd::setAllowDeactivation(int allow)
  566. {
  567. ifc_window *w = getDesktopParent();
  568. if (w != NULL && w != this)
  569. w->setAllowDeactivation(allow);
  570. else VIRTUALWND_PARENT::setAllowDeactivation(allow);
  571. }
  572. int VirtualWnd::allowDeactivation()
  573. {
  574. ifc_window *w = getDesktopParent();
  575. if (w != NULL && w != this)
  576. return w->allowDeactivation();
  577. return VIRTUALWND_PARENT::allowDeactivation();
  578. }
  579. /* todo: setCursor
  580. + real childs going invisible should deferedInvalidate their rect on their parent window if it has a virtualCanvas
  581. */
  582. // No need for screenToClient/clientToScreen overrides since the virtual's origin is the same as it's parent