slider.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705
  1. #include <precomp.h>
  2. #include "slider.h"
  3. #include <tataki/canvas/canvas.h>
  4. #include <api/wnd/notifmsg.h>
  5. #include <api/wnd/PaintCanvas.h>
  6. #define DEFAULT_THUMBWIDTH 16
  7. #define DEFAULT_THUMBHEIGHT 16
  8. SliderWnd::SliderWnd()
  9. {
  10. seeking = 0;
  11. enabled = 1;
  12. hilite = 0;
  13. pos = 0;
  14. oldpos = -1;
  15. thumbwidth = DEFAULT_THUMBWIDTH;
  16. captured = 0;
  17. xShift = 0;
  18. yShift = 0;
  19. base_texture = NULL;
  20. use_base_texture = 0;
  21. no_default_background = 0;
  22. drawOnBorders = 0;
  23. hotPosition = -1;
  24. origPos = 0;
  25. vertical = 0;
  26. thumbCentered = 1;
  27. thumbOffset = 0;
  28. thumbStretched = 0;
  29. hotposrange = -1;
  30. setLimits(START, END);
  31. }
  32. SliderWnd::~SliderWnd()
  33. {}
  34. int SliderWnd::onPaint(Canvas *canvas)
  35. {
  36. if (canvas == NULL)
  37. {
  38. PaintBltCanvas paintcanvas;
  39. if (!paintcanvas.beginPaint(this))
  40. return 0;
  41. SliderWnd::onPaint(&paintcanvas);
  42. }
  43. SLIDERWND_PARENT::onPaint(canvas);
  44. RECT r, origr;
  45. getClientRect(&r);
  46. origr = r;
  47. if (use_base_texture)
  48. {
  49. if (!base_texture)
  50. {
  51. renderBaseTexture(canvas, r);
  52. }
  53. else
  54. {
  55. RECT cr;
  56. cr.left = xShift;
  57. cr.top = yShift;
  58. cr.right = cr.left + (r.right - r.left);
  59. cr.bottom = cr.top + (r.bottom - r.top);
  60. base_texture->blitToRect(canvas, &cr, &r);
  61. }
  62. }
  63. if (vertical)
  64. {
  65. RECT br;
  66. br.left = r.left;
  67. br.right = r.right;
  68. if (left.getBitmap())
  69. {
  70. br.top = r.top;
  71. br.bottom = left.getHeight();
  72. left.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
  73. }
  74. if (right.getBitmap())
  75. {
  76. br.top = r.bottom - right.getHeight();
  77. br.bottom = r.bottom;
  78. right.stretchToRectAlpha(canvas, &br, getPaintingAlpha());
  79. }
  80. if (middle.getBitmap())
  81. {
  82. br.top = r.top + (left.getBitmap() ? left.getHeight() : 0);
  83. br.bottom = r.bottom - (right.getBitmap() ? right.getHeight() : 0);
  84. middle.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
  85. }
  86. }
  87. else
  88. {
  89. RECT br;
  90. br.top = r.top;
  91. br.bottom = r.bottom;
  92. if (left.getBitmap())
  93. {
  94. br.left = r.left;
  95. br.right = br.left + left.getWidth();
  96. left.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
  97. }
  98. if (right.getBitmap())
  99. {
  100. br.left = r.right - right.getWidth();
  101. br.right = r.right;
  102. right.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
  103. }
  104. if (middle.getBitmap())
  105. {
  106. br.left = r.left + (left.getBitmap() ? left.getWidth() : 0);
  107. br.right = r.right - (right.getBitmap() ? right.getWidth() : 0);
  108. middle.getBitmap()->stretchToRectAlpha(canvas, &br, getPaintingAlpha());
  109. }
  110. }
  111. if (vertical)
  112. {
  113. int w = (r.bottom - r.top) - thumbHeight();
  114. // ASSERT(w > 0); // if the control paints off the edge of the screen, this will needlessly assert.
  115. if (w < 0) w = 0;
  116. r.top += (pos * w) / length;
  117. r.bottom = r.top + thumbHeight();
  118. if (!thumbStretched)
  119. {
  120. if (!thumbCentered)
  121. {
  122. r.left = origr.left + thumbOffset;
  123. r.right = origr.left + thumbWidth() + thumbOffset;
  124. }
  125. else
  126. {
  127. int w = ((r.right - r.left) - thumbWidth()) / 2;
  128. r.left = origr.left + w + thumbOffset;
  129. r.right = origr.right - w + thumbOffset;
  130. }
  131. }
  132. else
  133. {
  134. r.left = origr.left;
  135. r.right = origr.right;
  136. }
  137. }
  138. else
  139. {
  140. // offset for left bitmap
  141. if (!drawOnBorders)
  142. {
  143. if (left.getBitmap() != NULL) r.left += left.getWidth();
  144. if (right.getBitmap() != NULL) r.right -= right.getWidth();
  145. }
  146. int w = (r.right - r.left) - thumbWidth();
  147. if (w < 0) w = 0;
  148. r.left += (pos * w) / length;
  149. r.right = r.left + thumbWidth();
  150. if (r.right > origr.right)
  151. {
  152. r.left -= r.right - origr.right;
  153. r.right = origr.right;
  154. }
  155. if (!thumbStretched)
  156. {
  157. int thumbh = thumb.getBitmap() ? thumb.getHeight() : DEFAULT_THUMBWIDTH;
  158. if (thumbCentered)
  159. {
  160. int h = ((r.bottom - r.top) - thumbh) / 2;
  161. r.top = origr.top + h;
  162. r.bottom = origr.bottom - h;
  163. }
  164. else
  165. {
  166. r.top = origr.top + thumbOffset;
  167. r.bottom = origr.top + thumbh + thumbOffset;
  168. }
  169. }
  170. else
  171. {
  172. r.top = origr.top;
  173. r.bottom = origr.bottom;
  174. }
  175. }
  176. SkinBitmap *sb = getSeekStatus() ? (thumbdown.getBitmap() ? thumbdown.getBitmap() : thumb.getBitmap()) : ((hilite && thumbhilite.getBitmap()) ? thumbhilite.getBitmap() : thumb.getBitmap());
  177. if (sb != NULL)
  178. sb->stretchToRectAlpha(canvas, &r, getPaintingAlpha());
  179. else
  180. canvas->fillRect(&r, RGB(255, 0, 0));
  181. return 1;
  182. }
  183. int SliderWnd::onInit()
  184. {
  185. SLIDERWND_PARENT::onInit();
  186. if (!no_default_background)
  187. {
  188. if (vertical)
  189. {
  190. // Please note that these bitmaps here do not yet exist.
  191. if (left.getBitmapName() == NULL) setLeftBmp(L"wasabi.slider.vertical.top");
  192. if (middle.getBitmapName() == NULL) setMiddleBmp(L"wasabi.slider.vertical.middle");
  193. if (right.getBitmapName() == NULL) setRightBmp(L"wasabi.slider.vertical.bottom");
  194. if (thumb.getBitmapName() == NULL) setThumbBmp(L"wasabi.slider.vertical.button");
  195. if (thumbdown.getBitmapName() == NULL) setThumbDownBmp(L"wasabi.slider.vertical.button.pressed");
  196. }
  197. else
  198. {
  199. if (left.getBitmapName() == NULL) setLeftBmp(L"wasabi.slider.horizontal.left");
  200. if (middle.getBitmapName() == NULL) setMiddleBmp(L"wasabi.slider.horizontal.middle");
  201. if (right.getBitmapName() == NULL) setRightBmp(L"wasabi.slider.horizontal.right");
  202. if (thumb.getBitmapName() == NULL) setThumbBmp(L"wasabi.slider.horizontal.button");
  203. if (thumbdown.getBitmapName() == NULL) setThumbDownBmp(L"wasabi.slider.horizontal.button.pressed");
  204. }
  205. }
  206. return 1;
  207. }
  208. int SliderWnd::onLeftButtonDown(int x, int y)
  209. {
  210. SLIDERWND_PARENT::onLeftButtonDown(x, y);
  211. if (!enabled) return 0;
  212. seeking = 1;
  213. origPos = 0;
  214. RECT r;
  215. getClientRect(&r);
  216. if (vertical)
  217. {
  218. int w = (r.bottom - r.top) - thumbHeight();
  219. if (w < 0) w = 0;
  220. r.top += (pos * w) / length;
  221. origPos = (y - r.top) - 1;
  222. /*if(origPos<0 || origPos>thumbHeight())*/ origPos = (thumbHeight() / 2) - 2;
  223. }
  224. else
  225. {
  226. if (!drawOnBorders)
  227. {
  228. if (left.getBitmap() != NULL) r.left += left.getWidth();
  229. if (right.getBitmap() != NULL) r.right -= right.getWidth();
  230. }
  231. int w = (r.right - r.left) - thumbWidth();
  232. if (w < 0) w = 0;
  233. r.left += (pos * w) / length;
  234. origPos = (x - r.left) - 1;
  235. if (origPos < 0 || origPos > thumbWidth()) origPos = (thumbWidth() / 2) - 2;
  236. }
  237. if (!captured)
  238. {
  239. captured = 1;
  240. beginCapture();
  241. }
  242. oldpos = pos;
  243. onMouseMove(x, y);
  244. return 1;
  245. }
  246. //FG>
  247. //removed cross-hierarchy deletion (crashs due to ancestor in common.dll trying to delete pointers in a different
  248. //heap scope than the one in which they were allocated)
  249. void SliderWnd::setBitmaps(const wchar_t *thumbbmp, const wchar_t *thumbdownbmp, const wchar_t *thumbhighbmp, const wchar_t *leftbmp, const wchar_t *middlebmp, const wchar_t *rightbmp)
  250. {
  251. setThumbBmp(thumbbmp);
  252. setThumbDownBmp(thumbdownbmp);
  253. setThumbHiliteBmp(thumbhighbmp);
  254. setLeftBmp(leftbmp);
  255. setRightBmp(rightbmp);
  256. setMiddleBmp(middlebmp);
  257. }
  258. void SliderWnd::setLeftBmp(const wchar_t *name)
  259. {
  260. left = name;
  261. invalidate();
  262. }
  263. void SliderWnd::setMiddleBmp(const wchar_t *name)
  264. {
  265. middle = name;
  266. invalidate();
  267. }
  268. void SliderWnd::setRightBmp(const wchar_t *name)
  269. {
  270. right = name;
  271. invalidate();
  272. }
  273. void SliderWnd::setThumbBmp(const wchar_t *name)
  274. {
  275. thumb = name;
  276. invalidate();
  277. }
  278. void SliderWnd::setThumbDownBmp(const wchar_t *name)
  279. {
  280. thumbdown = name;
  281. invalidate();
  282. }
  283. void SliderWnd::setThumbHiliteBmp(const wchar_t *name)
  284. {
  285. thumbhilite = name;
  286. invalidate();
  287. }
  288. SkinBitmap *SliderWnd::getLeftBitmap()
  289. {
  290. return left;
  291. }
  292. SkinBitmap *SliderWnd::getRightBitmap()
  293. {
  294. return right;
  295. }
  296. SkinBitmap *SliderWnd::getMiddleBitmap()
  297. {
  298. return middle;
  299. }
  300. SkinBitmap *SliderWnd::getThumbBitmap()
  301. {
  302. return thumb;
  303. }
  304. SkinBitmap *SliderWnd::getThumbDownBitmap()
  305. {
  306. return thumbdown;
  307. }
  308. SkinBitmap *SliderWnd::getThumbHiliteBitmap()
  309. {
  310. return thumbhilite;
  311. }
  312. int SliderWnd::getWidth()
  313. {
  314. if (vertical)
  315. return (getThumbBitmap() ? getThumbBitmap()->getWidth() : 0);
  316. else
  317. {
  318. return 64;
  319. }
  320. }
  321. int SliderWnd::getHeight()
  322. {
  323. if (!vertical)
  324. return (getThumbBitmap() ? getThumbBitmap()->getHeight() : 0);
  325. else
  326. {
  327. return 64;
  328. }
  329. }
  330. void SliderWnd::setEnable(int en)
  331. {
  332. if (enabled != en) invalidate();
  333. enabled = en;
  334. }
  335. int SliderWnd::getEnable(void)
  336. {
  337. return enabled;
  338. }
  339. void SliderWnd::setPosition(int newpos, int wantcb)
  340. {
  341. if (newpos < minlimit) newpos = minlimit;
  342. else if (newpos > maxlimit) newpos = maxlimit;
  343. if (vertical) pos = maxlimit - newpos;
  344. else /* horizontal */ pos = newpos - minlimit;
  345. if (wantcb)
  346. onSetPosition();
  347. invalidate();
  348. }
  349. int SliderWnd::onMouseMove(int x, int y)
  350. {
  351. int p, w, mouseover;
  352. SLIDERWND_PARENT::onMouseMove(x, y);
  353. POINT po = {x, y};
  354. clientToScreen(&po);
  355. mouseover = (WASABI_API_WND->rootWndFromPoint(&po) == this);
  356. if (mouseover && !seeking && !captured)
  357. {
  358. beginCapture();
  359. captured = 1;
  360. onEnterArea();
  361. }
  362. int lasthilite = hilite;
  363. hilite = enabled && mouseover;
  364. if (hilite != lasthilite)
  365. {
  366. if (!mouseover && !seeking && captured)
  367. {
  368. endCapture();
  369. captured = 0;
  370. onLeaveArea();
  371. invalidate();
  372. return 0;
  373. }
  374. invalidate();
  375. }
  376. if (!enabled) return 1;
  377. RECT r, origr;
  378. getClientRect(&r);
  379. x -= r.left;
  380. y -= r.top;
  381. origr = r;
  382. if (vertical)
  383. {
  384. w = (r.bottom - r.top) - thumbHeight();
  385. // p = (y - (r.top-origr.top)) - (thumbHeight()/2-2);
  386. p = (y - (r.top - origr.top)) - origPos;
  387. }
  388. else
  389. {
  390. if (!drawOnBorders)
  391. {
  392. if (left != NULL) r.left += left.getWidth();
  393. if (right != NULL) r.right -= right.getWidth();
  394. }
  395. w = (r.right - r.left) - thumbWidth();
  396. // p = (x - (r.left - origr.left)) - (thumbWidth()/2-2);
  397. p = (x - (r.left - origr.left)) - origPos;
  398. }
  399. if (seeking)
  400. {
  401. pos = (p * length) / w;
  402. if (pos < 0) pos = 0;
  403. else if (pos > length) pos = length;
  404. if (hotPosition != -1)
  405. {
  406. int a, c;
  407. if (vertical) a = r.bottom - r.top;
  408. else a = r.right - r.left;
  409. c = getHotPosRange();
  410. if (c == -1)
  411. {
  412. int b = (int)(a * 0.075);
  413. c = (b * length) / a;
  414. }
  415. /**
  416. EQBand: minlimit -127, maxlimit 127, hotpos 0
  417. PanBar: minlimit 0, maxlimit 225, hotpos 127
  418. VSliders pos starts from top by 0 (winamp behaviour reversed!)
  419. */
  420. if (vertical)
  421. {
  422. //if (pos > (hotPosition - c) && pos < (hotPosition + c)) pos = hotPosition;
  423. if ((maxlimit - pos) > (hotPosition - c) && (maxlimit - pos) < (hotPosition + c)) pos = hotPosition - minlimit; // Hehe, now it works ;)
  424. }
  425. else
  426. {
  427. if (pos > (hotPosition - c) && pos < (hotPosition + c)) pos = hotPosition;
  428. //if ((pos - maxlimit)> (hotPosition - c) && (pos - maxlimit) < (hotPosition + c)) pos = hotPosition - minlimit;
  429. }
  430. }
  431. onSetPosition();
  432. invalidate();
  433. }
  434. return 1;
  435. }
  436. void SliderWnd::onCancelCapture()
  437. {
  438. SLIDERWND_PARENT::onCancelCapture();
  439. if (seeking && captured)
  440. abort();
  441. }
  442. int SliderWnd::onLeftButtonUp(int x, int y)
  443. {
  444. SLIDERWND_PARENT::onLeftButtonUp(x, y);
  445. int wasseeking = seeking;
  446. seeking = 0;
  447. captured = 0;
  448. oldpos = -1;
  449. endCapture();
  450. if (wasseeking)
  451. onSetFinalPosition();
  452. invalidate();
  453. return 1;
  454. }
  455. int SliderWnd::onRightButtonDown(int x, int y)
  456. {
  457. SLIDERWND_PARENT::onRightButtonDown(x, y);
  458. if (seeking && captured)
  459. {
  460. abort();
  461. }
  462. return 1;
  463. }
  464. int SliderWnd::onChar(unsigned int c)
  465. {
  466. SLIDERWND_PARENT::onChar(c);
  467. if (seeking && captured && (c == 27))
  468. {
  469. abort();
  470. }
  471. return 1;
  472. }
  473. int SliderWnd::onSetPosition()
  474. {
  475. if (!isInited()) return 0;
  476. notifyParent(ChildNotify::SLIDER_INTERIM_POSITION, getSliderPosition());
  477. return 0;
  478. }
  479. int SliderWnd::onSetFinalPosition()
  480. {
  481. if (!isInited()) return 0;
  482. notifyParent(ChildNotify::SLIDER_FINAL_POSITION, getSliderPosition());
  483. return 0;
  484. }
  485. int SliderWnd::getSliderPosition()
  486. {
  487. if (vertical) return maxlimit -pos;
  488. else return pos + minlimit;
  489. }
  490. int SliderWnd::getSeekStatus()
  491. {
  492. return seeking;
  493. }
  494. int SliderWnd::thumbWidth()
  495. {
  496. if (thumb.getBitmap() == NULL) return DEFAULT_THUMBWIDTH;
  497. return thumb.getWidth();
  498. }
  499. int SliderWnd::thumbHeight()
  500. {
  501. if (thumb.getBitmap() == NULL) return DEFAULT_THUMBHEIGHT;
  502. return thumb.getHeight();
  503. }
  504. void SliderWnd::setUseBaseTexture(int useit)
  505. {
  506. use_base_texture = useit;
  507. invalidate();
  508. }
  509. void SliderWnd::setBaseTexture(SkinBitmap *bmp, int x, int y)
  510. {
  511. base_texture = bmp;
  512. use_base_texture = TRUE;
  513. xShift = x;
  514. yShift = y;
  515. invalidate();
  516. }
  517. void SliderWnd::setNoDefaultBackground(int no)
  518. {
  519. no_default_background = no;
  520. }
  521. void SliderWnd::setDrawOnBorders(int draw)
  522. {
  523. drawOnBorders = draw;
  524. }
  525. void SliderWnd::onEnterArea()
  526. {
  527. SLIDERWND_PARENT::onEnterArea();
  528. }
  529. void SliderWnd::onLeaveArea()
  530. {
  531. SLIDERWND_PARENT::onLeaveArea();
  532. }
  533. void SliderWnd::setOrientation(int o)
  534. {
  535. vertical = o;
  536. }
  537. void SliderWnd::setHotPosition(int h)
  538. {
  539. hotPosition = h;
  540. }
  541. void SliderWnd::setThumbCentered(int c)
  542. {
  543. thumbCentered = c;
  544. }
  545. void SliderWnd::setThumbStretched(int c)
  546. {
  547. thumbStretched = c;
  548. }
  549. void SliderWnd::setThumbOffset(int o)
  550. {
  551. thumbOffset = o;
  552. }
  553. void SliderWnd::abort()
  554. {
  555. if (oldpos != -1)
  556. {
  557. seeking = 0;
  558. captured = 0;
  559. endCapture();
  560. pos = oldpos;
  561. onSetPosition();
  562. invalidate();
  563. oldpos = -1;
  564. }
  565. return ;
  566. }
  567. void SliderWnd::setLimits(int pminlimit, int pmaxlimit)
  568. {
  569. minlimit = pminlimit;
  570. maxlimit = pmaxlimit;
  571. length = maxlimit - minlimit;
  572. }
  573. int SliderWnd::onKeyDown(int vkcode)
  574. {
  575. switch (vkcode)
  576. {
  577. case VK_LEFT: move_left(Std::keyModifier(STDKEY_CONTROL)); return 1;
  578. case VK_RIGHT: move_right(Std::keyModifier(STDKEY_CONTROL)); return 1;
  579. case VK_HOME: move_start(); return 1;
  580. case VK_END: move_end(); return 1;
  581. default: return SLIDERWND_PARENT::onKeyDown(vkcode);
  582. }
  583. }
  584. void SliderWnd::move_left(int bigstep)
  585. {
  586. int pos = getSliderPosition();
  587. if (!bigstep) pos--; else pos -= (ABS(maxlimit - minlimit) / 10);
  588. if (pos < minlimit) pos = minlimit;
  589. setPosition(pos);
  590. }
  591. void SliderWnd::move_right(int bigstep)
  592. {
  593. int pos = getSliderPosition();
  594. if (!bigstep)
  595. pos++;
  596. else
  597. pos += (ABS(maxlimit - minlimit) / 10);
  598. if (pos > maxlimit)
  599. pos = maxlimit;
  600. setPosition(pos);
  601. }
  602. void SliderWnd::move_start()
  603. {
  604. setPosition(minlimit);
  605. }
  606. void SliderWnd::move_end()
  607. {
  608. setPosition(maxlimit);
  609. }