1
0

scbkgwnd.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. #include <precomp.h>
  2. #include "scbkgwnd.h"
  3. #include <api/wnd/notifmsg.h>
  4. #include <bfc/wasabi_std_wnd.h>
  5. #include <api/wnd/PaintCanvas.h>
  6. #define SCROLLBAR_SEP 4
  7. #define TIMER_SMOOTHSCROLLY 8873
  8. #define TIMER_SMOOTHSCROLLX 8874
  9. #define SMOOTH_STEPS 5
  10. #define DEFAULT_BGCOLOR RGB(0,0,0)
  11. ScrlBkgWnd::ScrlBkgWnd()
  12. {
  13. inDestroy = FALSE;
  14. bmp = NULL;
  15. bgColor = DEFAULT_BGCOLOR;
  16. scrollX = 0;
  17. scrollY = 0;
  18. dbbuffer = 1;
  19. needSetSliders = FALSE;
  20. lineHeight = 16;
  21. wantsep = 0;
  22. wantTileBg = true;
  23. lastratio = 1.0;
  24. MEMSET(&smsqr, 0, sizeof(RECT));
  25. in_set_slider_position = 0;
  26. smoothScrollYInc = smoothScrollXInc = 0;
  27. smoothScrollYCur = smoothScrollXCur = 0;
  28. smoothScrollYTimerCount = smoothScrollXTimerCount = 0;
  29. smoothYTimer = smoothXTimer = 0;
  30. }
  31. ScrlBkgWnd::~ScrlBkgWnd()
  32. {
  33. inDestroy = TRUE;
  34. }
  35. int ScrlBkgWnd::onInit()
  36. {
  37. SCRLBKGWND_PARENT::onInit();
  38. scrollY = 0;
  39. scrollX = 0;
  40. hSep.setOrientation(SEP_HORIZONTAL);
  41. hScroll.setBitmaps(L"wasabi.scrollbar.horizontal.left",
  42. L"wasabi.scrollbar.horizontal.left.pressed",
  43. L"wasabi.scrollbar.horizontal.left.hover",
  44. L"wasabi.scrollbar.horizontal.right",
  45. L"wasabi.scrollbar.horizontal.right.pressed",
  46. L"wasabi.scrollbar.horizontal.right.hover",
  47. L"wasabi.scrollbar.horizontal.button",
  48. L"wasabi.scrollbar.horizontal.button.pressed",
  49. L"wasabi.scrollbar.horizontal.button.hover");
  50. hScroll.setBackgroundBitmaps(L"wasabi.scrollbar.horizontal.background.left",
  51. L"wasabi.scrollbar.horizontal.background.middle",
  52. L"wasabi.scrollbar.horizontal.background.right");
  53. vSep.setOrientation(SEP_VERTICAL);
  54. vScroll.setBitmaps(L"wasabi.scrollbar.vertical.left",
  55. L"wasabi.scrollbar.vertical.left.pressed",
  56. L"wasabi.scrollbar.vertical.left.hover",
  57. L"wasabi.scrollbar.vertical.right",
  58. L"wasabi.scrollbar.vertical.right.pressed",
  59. L"wasabi.scrollbar.vertical.right.hover",
  60. L"wasabi.scrollbar.vertical.button",
  61. L"wasabi.scrollbar.vertical.button.pressed",
  62. L"wasabi.scrollbar.vertical.button.hover");
  63. vScroll.setBackgroundBitmaps(L"wasabi.scrollbar.vertical.background.top",
  64. L"wasabi.scrollbar.vertical.background.middle",
  65. L"wasabi.scrollbar.vertical.background.bottom");
  66. // hScroll->setVertical(FALSE);
  67. vScroll.setVertical(TRUE);
  68. hScroll.setStartHidden(TRUE); // prevent showing window at creation
  69. vScroll.setStartHidden(TRUE);
  70. hSep.setStartHidden(TRUE);
  71. vSep.setStartHidden(TRUE);
  72. hScroll.setParent(this);
  73. vScroll.setParent(this);
  74. hSep.setParent(this);
  75. vSep.setParent(this);
  76. hScroll.init(getOsModuleHandle(), getOsWindowHandle());
  77. vScroll.init(getOsModuleHandle(), getOsWindowHandle());
  78. hSep.init(getOsModuleHandle(), getOsWindowHandle());
  79. vSep.init(getOsModuleHandle(), getOsWindowHandle());
  80. hScroll.setPosition(0);
  81. vScroll.setPosition(0);
  82. setSlidersPosition(); // position sliders and show them if needed
  83. return 1;
  84. }
  85. void ScrlBkgWnd::setBgBitmap(const wchar_t *b)
  86. {
  87. bmp = b;
  88. if (b) setBgColor(DEFAULT_BGCOLOR);
  89. }
  90. void ScrlBkgWnd::setBgColor(ARGB32 rgb)
  91. {
  92. bgColor = rgb;
  93. }
  94. SkinBitmap *ScrlBkgWnd::getBgBitmap(void)
  95. {
  96. return bmp;
  97. }
  98. ARGB32 ScrlBkgWnd::getBgColor(void)
  99. {
  100. return bgColor;
  101. }
  102. // Scroll to a specified Y-pixels
  103. void ScrlBkgWnd::scrollToY(int y, int signal)
  104. {
  105. WndCanvas *canvas = NULL;
  106. RECT r;
  107. int offset;
  108. int dor2 = 0;
  109. RECT r2 = {0, 0, 0, 0};
  110. int focused = gotFocus();
  111. if (isVirtual() || renderRatioActive())
  112. {
  113. scrollY = y;
  114. invalidateRect(&clientRect());
  115. onScrollY(y);
  116. return ;
  117. }
  118. if (!Wasabi::Std::Wnd::isValidWnd(getOsWindowHandle())) return ; // no need to paint
  119. if (y > scrollY)
  120. { // tree scrolling up, scroller going down. invalidating from the bottom. bitblting from bottom to top
  121. int lines = y - scrollY;
  122. offset = -lines;
  123. getClientRect(&r);
  124. canvas = new WndCanvas();
  125. canvas->attachToClient(this);
  126. RegionI reg;
  127. makeWindowOverlayMask(&reg);
  128. RegionI clip(&r);
  129. reg.offset(0, offset);
  130. clip.subtractRegion(&reg);
  131. canvas->selectClipRgn(&clip);
  132. int b = hScroll.isVisible() ? hScroll.getHeight() : 0;
  133. int c = vScroll.isVisible() ? vScroll.getWidth() : 0;
  134. int a = focused && (!b);
  135. if (r.bottom-r.top-lines > 0)
  136. canvas->blit(r.left, r.top+lines, canvas, r.left, r.top, r.right-r.left- c, r.bottom-r.top-lines-a - b);
  137. // int a = focused && (!hScroll->isVisible());
  138. //if (r.bottom - r.top - lines > 0)
  139. // canvas->blit(r.left, r.top + lines, canvas, r.left, r.top, r.right - r.left, r.bottom - r.top - lines - a);
  140. canvas->selectClipRgn(NULL);
  141. if (!clip.isEmpty())
  142. invalidateRgn(&clip);
  143. getClientRect(&r2);
  144. r2.bottom = r2.top + 1;
  145. dor2 = 1;
  146. r.top = r.bottom - lines - 1;
  147. }
  148. if (y < scrollY)
  149. { // tree scrolling down, scroller going up. invalidating from the top. bitblting from top to bottom
  150. int lines = scrollY - y;
  151. offset = lines;
  152. getClientRect(&r);
  153. canvas = new WndCanvas();
  154. canvas->attachToClient(this);
  155. RegionI reg;
  156. makeWindowOverlayMask(&reg);
  157. RegionI clip(&r);
  158. reg.offset(0, offset);
  159. clip.subtractRegion(&reg);
  160. canvas->selectClipRgn(&clip);
  161. int c = vScroll.isVisible() ? vScroll.getWidth() : 0;
  162. canvas->blit(r.left, r.top+focused, canvas, r.left, r.top+lines+focused, r.right-r.left-c, r.bottom-r.top-lines-focused);
  163. //canvas->blit(r.left, r.top + focused, canvas, r.left, r.top + lines + focused, r.right - r.left, r.bottom - r.top - lines - focused);
  164. canvas->selectClipRgn(NULL);
  165. if (!clip.isEmpty())
  166. invalidateRgn(&clip);
  167. getClientRect(&r2);
  168. r2.top = r2.bottom - 1;
  169. dor2 = 1;
  170. r.bottom = r.top + lines + 1;
  171. }
  172. if (canvas)
  173. {
  174. delete canvas;
  175. scrollY = y;
  176. // in case we have a virtualCanvas, we need to tell BaseWnd to call us to paint on it next time it's needed coz we blited directly to the screen
  177. RECT cr;
  178. getClientRect(&cr);
  179. cr.top -= getHeaderHeight();
  180. RECT screenblit;
  181. SubtractRect(&screenblit, &cr, &r);
  182. // invalidate what's needed
  183. if (dor2 && focused)
  184. cascadeRepaintRect(&r2, 0);
  185. cascadeRepaintRect(&r);
  186. deferedInvalidateRect(&screenblit);
  187. //dbbuffer = 1;
  188. //repaint();
  189. }
  190. if (signal)
  191. updateVScroll(y);
  192. onScrollY(y);
  193. }
  194. // Scroll to a specified X-pixel
  195. void ScrlBkgWnd::scrollToX(int x, int signal)
  196. {
  197. WndCanvas *canvas = NULL;
  198. RECT r;
  199. int offset;
  200. int dor2 = 0;
  201. RECT r2 = {0, 0, 0, 0};
  202. int focused = gotFocus();
  203. if (isVirtual() || ABS(getRenderRatio() - 1.0) > 0.01)
  204. {
  205. scrollX = x;
  206. getClientRect(&r);
  207. invalidateRect(&r);
  208. return ;
  209. }
  210. if (x > scrollX)
  211. { // tree scrolling left, scroller going right. invalidating from the right. bitblting from right to left
  212. int lines = x - scrollX;
  213. offset = -lines;
  214. getClientRect(&r);
  215. r.top -= getHeaderHeight();
  216. canvas = new WndCanvas();
  217. canvas->attachToClient(this);
  218. RegionI reg;
  219. makeWindowOverlayMask(&reg);
  220. RegionI clip(&r);
  221. reg.offset(offset, 0);
  222. clip.subtractRegion(&reg);
  223. canvas->selectClipRgn(&clip);
  224. int c = vScroll.isVisible() ? vScroll.getWidth() : 0;
  225. canvas->blit(r.left+lines, r.top, canvas, r.left, r.top, r.right-r.left-lines-focused-c, r.bottom-r.top);
  226. //canvas->blit(r.left + lines, r.top, canvas, r.left, r.top, r.right - r.left - lines - focused, r.bottom - r.top);
  227. canvas->selectClipRgn(NULL);
  228. if (!reg.isEmpty())
  229. invalidateRgn(&reg);
  230. getClientRect(&r2);
  231. r2.right = r2.left + 1;
  232. dor2 = 1;
  233. r.left = r.right - lines - 1;
  234. }
  235. if (x < scrollX)
  236. { // tree scrolling right, scroller going left. invalidating from the left. bitblting from left to right
  237. int lines = scrollX - x;
  238. offset = lines;
  239. getClientRect(&r);
  240. r.top -= getHeaderHeight();
  241. canvas = new WndCanvas();
  242. canvas->attachToClient(this);
  243. RegionI reg;
  244. makeWindowOverlayMask(&reg);
  245. RegionI clip(&r);
  246. reg.offset(offset, 0);
  247. clip.subtractRegion(&reg);
  248. canvas->selectClipRgn(&clip);
  249. int a = focused && (!vScroll.isVisible());
  250. int c = hScroll.isVisible() ? hScroll.getHeight()-focused : 0;
  251. canvas->blit(r.left+a, r.top, canvas, r.left+lines, r.top, r.right-r.left-lines-a, r.bottom-r.top-c);
  252. //int a = focused && (!vScroll->isVisible());
  253. // canvas->blit(r.left + a, r.top, canvas, r.left + lines, r.top, r.right - r.left - lines - a, r.bottom - r.top);
  254. canvas->selectClipRgn(NULL);
  255. if (!reg.isEmpty())
  256. invalidateRgn(&reg);
  257. getClientRect(&r2);
  258. r2.left = r2.right - 1;
  259. dor2 = 1;
  260. r.right = r.left + lines + 1;
  261. }
  262. if (canvas)
  263. {
  264. delete canvas;
  265. scrollX = x;
  266. // in case we have a virtualCanvas, we need to tell BaseWnd to call us to paint on it next time it's needed coz we blited directly to the screen
  267. RECT cr;
  268. getClientRect(&cr);
  269. cr.top -= getHeaderHeight();
  270. RECT screenblit;
  271. SubtractRect(&screenblit, &cr, &r);
  272. deferedInvalidateRect(&screenblit);
  273. if (dor2 && focused)
  274. cascadeRepaintRect(&r2, 0);
  275. // invalidate what's needed
  276. cascadeRepaintRect(&r);
  277. //dbbuffer = 1;
  278. //repaint();
  279. }
  280. if (signal)
  281. updateHScroll(x);
  282. }
  283. void ScrlBkgWnd::setSlidersPosition()
  284. {
  285. if (in_set_slider_position) return ;
  286. in_set_slider_position = 1;
  287. _setSlidersPosition();
  288. in_set_slider_position = 0;
  289. }
  290. void ScrlBkgWnd::_setSlidersPosition()
  291. {
  292. if (!isInited()) return ;
  293. RECT d;
  294. getClientRect(&d);
  295. if ((d.left >= d.right) || (d.top >= d.bottom))
  296. return ;
  297. RECT r;
  298. if (inDestroy) return ;
  299. if (!isVisible())
  300. {
  301. needSetSliders = TRUE;
  302. return ;
  303. }
  304. needSetSliders = FALSE;
  305. if (needHScroll())
  306. {
  307. SCRLBKGWND_PARENT::getClientRect(&r);
  308. r.top = r.bottom - getScrollbarWidth();
  309. if (needVScroll())
  310. r.right -= getScrollbarWidth() + (wantsep ? SCROLLBAR_SEP : 0);
  311. RECT z; hScroll.getClientRect(&z);
  312. if (!Wasabi::Std::rectEqual(r, z))
  313. { // assumes ScrollBars are virtual
  314. hScroll.resizeToRect(&r);
  315. RECT s = r;
  316. s.bottom = s.top;
  317. s.top -= (wantsep ? SCROLLBAR_SEP : 0);
  318. hSep.resizeToRect(&s);
  319. }
  320. if (!hScroll.isVisible())
  321. {
  322. hScroll.setVisible(TRUE);
  323. if (wantsep) hSep.setVisible(TRUE);
  324. onHScrollToggle(1);
  325. }
  326. hScroll.setNPages(((int)(getContentsWidth() / (r.right - r.left))) + 1);
  327. hScroll.setUpDownValue((int)(((float)lineHeight / (getContentsWidth() - (r.right - r.left)))*SCROLLBAR_FULL));
  328. hScroll.setPosition((int)((float)scrollX / getMaxScrollX() * SCROLLBAR_FULL));
  329. }
  330. else
  331. {
  332. if (hScroll.isVisible())
  333. {
  334. hScroll.setVisible(FALSE);
  335. if (wantsep) hSep.setVisible(FALSE);
  336. onHScrollToggle(0);
  337. }
  338. hScroll.setPosition(0);
  339. scrollToX(0);
  340. }
  341. if (needVScroll())
  342. {
  343. SCRLBKGWND_PARENT::getClientRect(&r);
  344. r.left = r.right - getScrollbarWidth();
  345. if (needHScroll())
  346. r.bottom -= getScrollbarWidth();
  347. RECT z; vScroll.getNonClientRect(&z);
  348. if (!Wasabi::Std::rectEqual(r, z))
  349. {
  350. vScroll.resizeToRect(&r);
  351. RECT s = r;
  352. s.right = s.left;
  353. s.left -= (wantsep ? SCROLLBAR_SEP : 0);
  354. vSep.resizeToRect(&s);
  355. }
  356. if (!vScroll.isVisible())
  357. {
  358. vScroll.setVisible(TRUE);
  359. if (wantsep) vSep.setVisible(TRUE);
  360. onVScrollToggle(1);
  361. }
  362. vScroll.setNPages(((int)(getContentsHeight() / (r.bottom - r.top))) + 1);
  363. vScroll.setUpDownValue((int)(((float)lineHeight / (getContentsHeight() - (r.bottom - r.top)))*SCROLLBAR_FULL));
  364. vScroll.setPosition((int)((float)scrollY / getMaxScrollY() * SCROLLBAR_FULL));
  365. }
  366. else
  367. {
  368. if (vScroll.isVisible())
  369. {
  370. vScroll.setVisible(FALSE);
  371. if (wantsep) vSep.setVisible(FALSE);
  372. onVScrollToggle(0);
  373. }
  374. vScroll.setPosition(0);
  375. scrollToY(0);
  376. }
  377. hSep.invalidate();
  378. vSep.invalidate();
  379. if (needHScroll() && needVScroll())
  380. {
  381. getNonClientRect(&smsqr);
  382. smsqr.left = smsqr.right - getScrollbarWidth();
  383. smsqr.top = smsqr.bottom - getScrollbarWidth();
  384. invalidateRect(&smsqr);
  385. }
  386. else
  387. ZERO(smsqr);
  388. }
  389. void ScrlBkgWnd::onHScrollToggle(int set)
  390. {}
  391. void ScrlBkgWnd::onVScrollToggle(int set)
  392. {}
  393. int ScrlBkgWnd::onPaint(Canvas *canvas)
  394. {
  395. RECT d;
  396. getClientRect(&d);
  397. if (d.right > d.left + 0xFFFF || d.bottom > d.top + 0xFFFF) return 1;
  398. if ((d.left >= d.right) || (d.top >= d.bottom))
  399. {
  400. return SCRLBKGWND_PARENT::onPaint(canvas);
  401. }
  402. if (needSetSliders) setSlidersPosition();
  403. // RECT z;
  404. // GetUpdateRect(gethWnd(), &z, FALSE);
  405. PaintCanvas paintcanvas;
  406. PaintBltCanvas paintbcanvas;
  407. if (canvas == NULL)
  408. {
  409. if (dbbuffer)
  410. {
  411. if (!paintbcanvas.beginPaintNC(this)) return 0;
  412. canvas = &paintbcanvas;
  413. }
  414. else
  415. {
  416. if (!paintcanvas.beginPaint(this)) return 0;
  417. canvas = &paintcanvas;
  418. }
  419. }
  420. //dbbuffer=1;
  421. SCRLBKGWND_PARENT::onPaint(canvas);
  422. RegionI *smsq = NULL;
  423. if (needHScroll() && needVScroll())
  424. {
  425. renderBaseTexture(canvas, smsqr);
  426. smsq = new RegionI(&smsqr);
  427. }
  428. RECT r;
  429. LabelWnd::getNonClientRect(&r);
  430. RECT c = {r.left, r.top, r.right, r.top + getLabelHeight()}; // create label rect
  431. RegionI *clip = new RegionI();
  432. if (canvas->getClipRgn(clip) == 0)
  433. {
  434. delete clip;
  435. clip = new RegionI(&r);
  436. if (smsq) clip->subtractRegion(smsq);
  437. canvas->selectClipRgn(clip);
  438. }
  439. else
  440. {
  441. RegionI reg(&c);
  442. clip->subtractRegion(&reg);
  443. if (smsq) clip->subtractRegion(smsq);
  444. canvas->selectClipRgn(clip);
  445. }
  446. delete smsq;
  447. drawBackground(canvas);
  448. delete clip;
  449. if (getRenderRatio() != lastratio) { invalidate(); lastratio = getRenderRatio(); } // todo: make that an event
  450. return 1;
  451. }
  452. int ScrlBkgWnd::needDoubleBuffer()
  453. {
  454. return dbbuffer;
  455. }
  456. int ScrlBkgWnd::onEraseBkgnd(HDC dc)
  457. {
  458. /* DCCanvas canvas;
  459. canvas.cloneDC(dc);
  460. drawBackground(&canvas);*/
  461. return 1;
  462. }
  463. // Draws tiled background
  464. void ScrlBkgWnd::drawBackground(Canvas *canvas)
  465. {
  466. RECT r(clientRect());
  467. RegionI reg(&r);
  468. RegionI old;
  469. canvas->getClipRgn(&old);
  470. reg.andRegion(&old);
  471. canvas->selectClipRgn(&reg);
  472. if (bmp.getBitmap() && bgColor == DEFAULT_BGCOLOR)
  473. {
  474. r.top -= scrollY % bmp.getBitmap()->getHeight();
  475. r.left -= scrollX % bmp.getBitmap()->getWidth();
  476. if (wantTileBg)
  477. bmp.getBitmap()->blitTile(canvas, &r);
  478. else
  479. bmp.getBitmap()->stretchToRect(canvas, &r);
  480. }
  481. else if (bgColor != DEFAULT_BGCOLOR)
  482. {
  483. canvas->fillRect(&r, bgColor);
  484. }
  485. canvas->selectClipRgn(&old);
  486. }
  487. bool ScrlBkgWnd::needHScroll()
  488. {
  489. if (!wantHScroll()) return FALSE;
  490. RECT r;
  491. getNonClientRect(&r);
  492. if (vScroll.isVisible())
  493. r.right -= getScrollbarWidth();
  494. return (getContentsWidth() > r.right - r.left);
  495. }
  496. bool ScrlBkgWnd::needVScroll()
  497. {
  498. if (!wantVScroll()) return FALSE;
  499. RECT r;
  500. getNonClientRect(&r);
  501. r.top += getHeaderHeight();
  502. if (hScroll.isVisible())
  503. r.bottom -= getScrollbarWidth();
  504. return (getContentsHeight() > r.bottom - r.top);
  505. }
  506. // Returns the current tree width in pixels
  507. int ScrlBkgWnd::getContentsWidth()
  508. {
  509. /*RECT r;
  510. ScrlBkgWnd::getClientRect(&r);
  511. return r.right-r.left;*/
  512. return 10000;
  513. }
  514. // Returns the current tree height in pixels
  515. int ScrlBkgWnd::getContentsHeight()
  516. {
  517. /*RECT r;
  518. ScrlBkgWnd::getClientRect(&r);
  519. return r.bottom-r.top;*/
  520. return 10000;
  521. }
  522. int ScrlBkgWnd::getMaxScrollY()
  523. {
  524. RECT r;
  525. getClientRect(&r);
  526. return MAX<int>(0, getContentsHeight() - (r.bottom - r.top));
  527. }
  528. int ScrlBkgWnd::getMaxScrollX()
  529. {
  530. RECT r;
  531. getClientRect(&r);
  532. return MAX<int>(0, getContentsWidth() - (r.right - r.left));
  533. }
  534. void ScrlBkgWnd::updateVScroll(int y)
  535. {
  536. if (getMaxScrollY() == 0) { vScroll.setPosition(0); return ; }
  537. int z = (int)((float)y / getMaxScrollY() * SCROLLBAR_FULL);
  538. vScroll.setPosition(z);
  539. }
  540. void ScrlBkgWnd::updateHScroll(int x)
  541. {
  542. if (getMaxScrollX() == 0) { hScroll.setPosition(0); return ; }
  543. int z = (int)((float)x / getMaxScrollX() * SCROLLBAR_FULL);
  544. hScroll.setPosition(z);
  545. }
  546. void ScrlBkgWnd::updateScrollY(bool smooth)
  547. {
  548. if (getMaxScrollY() == 0) { scrollToY(0); return ; }
  549. int y = (int)((float)(vScroll.getPosition()) / SCROLLBAR_FULL * getMaxScrollY());
  550. if (!smooth)
  551. scrollToY(y /*& ~3*/);
  552. else
  553. smoothScrollToY(y);
  554. }
  555. void ScrlBkgWnd::updateScrollX(bool smooth)
  556. {
  557. if (getMaxScrollX() == 0) { scrollToX(0); return ; }
  558. int x = (int)((float)(hScroll.getPosition()) / SCROLLBAR_FULL * getMaxScrollX());
  559. if (!smooth)
  560. scrollToX(x /*& ~3*/);
  561. else
  562. smoothScrollToX(x);
  563. }
  564. void ScrlBkgWnd::smoothScrollToX(int x)
  565. {
  566. killSmoothXTimer();
  567. smoothScrollXInc = -(float)(scrollX - x) / SMOOTH_STEPS;
  568. smoothScrollXCur = (float)scrollX;
  569. smoothScrollXTimerCount = 0;
  570. smoothXTimer = 1;
  571. setTimer(TIMER_SMOOTHSCROLLX, 25);
  572. }
  573. void ScrlBkgWnd::killSmoothYTimer()
  574. {
  575. if (smoothYTimer)
  576. {
  577. killTimer(TIMER_SMOOTHSCROLLY);
  578. smoothScrollYCur += smoothScrollYInc * (SMOOTH_STEPS - smoothScrollYTimerCount);
  579. scrollToY((int)smoothScrollYCur);
  580. smoothYTimer = 0;
  581. updateVScroll(scrollY);
  582. }
  583. }
  584. void ScrlBkgWnd::killSmoothXTimer()
  585. {
  586. if (smoothXTimer)
  587. {
  588. killTimer(TIMER_SMOOTHSCROLLX);
  589. smoothScrollXCur += smoothScrollXInc * (SMOOTH_STEPS - smoothScrollXTimerCount);
  590. scrollToX((int)smoothScrollXCur);
  591. smoothXTimer = 0;
  592. updateHScroll(scrollX);
  593. }
  594. }
  595. void ScrlBkgWnd::smoothScrollToY(int y)
  596. {
  597. killSmoothYTimer();
  598. smoothScrollYInc = -(float)(scrollY - y) / SMOOTH_STEPS;
  599. smoothScrollYCur = (float)scrollY;
  600. smoothScrollYTimerCount = 0;
  601. smoothYTimer = 1;
  602. setTimer(TIMER_SMOOTHSCROLLY, 25);
  603. }
  604. void ScrlBkgWnd::timerCallback(int id)
  605. {
  606. switch (id)
  607. {
  608. case TIMER_SMOOTHSCROLLY:
  609. smoothScrollYCur += smoothScrollYInc;
  610. scrollToY((int)smoothScrollYCur, FALSE);
  611. if (++smoothScrollYTimerCount == SMOOTH_STEPS)
  612. killSmoothYTimer();
  613. return ;
  614. case TIMER_SMOOTHSCROLLX:
  615. smoothScrollXCur += smoothScrollXInc;
  616. scrollToX((int)smoothScrollXCur, FALSE);
  617. if (++smoothScrollXTimerCount == SMOOTH_STEPS)
  618. killSmoothXTimer();
  619. return ;
  620. }
  621. SCRLBKGWND_PARENT::timerCallback(id);
  622. }
  623. // Gets notification from sliders
  624. int ScrlBkgWnd::childNotify(ifc_window *child, int msg, intptr_t param1, intptr_t param2)
  625. {
  626. switch (msg)
  627. {
  628. case ChildNotify::SCROLLBAR_SETPOSITION:
  629. if (child == &vScroll)
  630. {
  631. updateScrollY(!!param1);
  632. return 1;
  633. }
  634. if (child == &hScroll)
  635. {
  636. updateScrollX(!!param1);
  637. return 1;
  638. }
  639. break;
  640. }
  641. return SCRLBKGWND_PARENT::childNotify(child, msg, param1, param2);
  642. }
  643. int ScrlBkgWnd::onResize()
  644. {
  645. int rt = SCRLBKGWND_PARENT::onResize();
  646. if (!isInited()) return rt;
  647. invalidateRect(&smsqr);
  648. setSlidersPosition();
  649. return 1;
  650. }
  651. void ScrlBkgWnd::onSetVisible(int show)
  652. {
  653. SCRLBKGWND_PARENT::onSetVisible(show);
  654. if (show)
  655. setSlidersPosition();
  656. }
  657. void ScrlBkgWnd::getClientRect(RECT *r)
  658. {
  659. SCRLBKGWND_PARENT::getClientRect(r);
  660. if (vScroll.isVisible(1))
  661. r->right -= getScrollbarWidth() + (wantsep ? SCROLLBAR_SEP : 0);
  662. if (hScroll.isVisible(1))
  663. r->bottom -= getScrollbarWidth() + (wantsep ? SCROLLBAR_SEP : 0);
  664. r->top += getHeaderHeight();
  665. }
  666. /*void ScrlBkgWnd::getNonClientRect(RECT *r) {
  667. SCRLBKGWND_PARENT::getClientRect(r); // my non client rect is my parent's client rect
  668. return;
  669. }*/
  670. int ScrlBkgWnd::getHeaderHeight()
  671. {
  672. return 0;
  673. }
  674. void ScrlBkgWnd::setLineHeight(int h)
  675. {
  676. lineHeight = h;
  677. }
  678. int ScrlBkgWnd::getLinesPerPage()
  679. {
  680. RECT r;
  681. getClientRect(&r);
  682. int h = r.bottom - r.top;
  683. return h / lineHeight;
  684. }
  685. int ScrlBkgWnd::getScrollX()
  686. {
  687. return scrollX;
  688. }
  689. int ScrlBkgWnd::getScrollY()
  690. {
  691. return scrollY;
  692. }
  693. int ScrlBkgWnd::getScrollbarWidth()
  694. {
  695. // TODO: maybe do if (hScroll.isVisible())
  696. return hScroll.getWidth();
  697. return vScroll.getWidth();
  698. return 0;
  699. }
  700. /*void ScrlBkgWnd::clientToScreen(RECT *r) {
  701. POINT p;
  702. p.x = r->left;
  703. p.y = r->top;
  704. SCRLBKGWND_PARENT::clientToScreen((int *)&p.x, (int*)&p.y);
  705. r->left = p.x;
  706. r->top = p.y;
  707. p.x = r->right;
  708. p.y = r->bottom;
  709. SCRLBKGWND_PARENT::clientToScreen((int *)&p.x, (int*)&p.y);
  710. r->right = p.x;
  711. r->bottom = p.y;
  712. }
  713. void ScrlBkgWnd::clientToScreen(int *x, int *y) {
  714. SCRLBKGWND_PARENT::clientToScreen(x, y);
  715. }
  716. void ScrlBkgWnd::clientToScreen(POINT *p) {
  717. TREEWND_PARENT::clientToScreen((int *)&p->x, (int *)&p->y);
  718. }*/
  719. void ScrlBkgWnd::makeWindowOverlayMask(api_region *r)
  720. {
  721. return ;
  722. #ifdef WIN32
  723. // With this routine empty, I'm just nuking the code from x-plat builds < KP
  724. HDC dc = GetDC(getOsWindowHandle());
  725. //if (getRandomRgn)
  726. {
  727. RECT cr;
  728. getClientRect(&cr);
  729. RECT wr;
  730. getWindowRect(&wr);
  731. RegionI sr;
  732. Wasabi::Std::Wnd::getRandomRegion(dc, sr.getOSHandle());
  733. sr.offset( -wr.left, -wr.top);
  734. r->setRect(&cr);
  735. r->subtractRegion(&sr);
  736. }
  737. ReleaseDC(getOsWindowHandle(), dc);
  738. #endif
  739. }