scrollbar.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. /*
  2. * File : scrollbar.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. *
  13. */
  14. #include <stdlib.h>
  15. #include <rtgui/dc.h>
  16. #include <rtgui/widgets/scrollbar.h>
  17. static void _rtgui_scrollbar_constructor(rtgui_scrollbar_t *bar)
  18. {
  19. /* set event handler */
  20. rtgui_object_set_event_handler(RTGUI_OBJECT(bar), rtgui_scrollbar_event_handler);
  21. bar->status = 0;
  22. bar->value = 0;
  23. bar->thumb_w = 16;
  24. bar->thumb_len = 16;
  25. bar->widget_link = RT_NULL;
  26. bar->on_scroll = RT_NULL;
  27. bar->orient = RTGUI_HORIZONTAL;
  28. /* set gc */
  29. RTGUI_WIDGET_TEXTALIGN(bar) = RTGUI_ALIGN_CENTER;
  30. }
  31. static void _rtgui_scrollbar_destructor(rtgui_scrollbar_t *bar)
  32. {
  33. }
  34. rt_uint32_t _rtgui_scrollbar_get_length(rtgui_scrollbar_t *bar)
  35. {
  36. rtgui_rect_t rect;
  37. rt_uint32_t result;
  38. rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
  39. if(bar->orient & RTGUI_VERTICAL)
  40. result = rtgui_rect_height(rect) - 2*rtgui_rect_width(rect) - bar->thumb_len;
  41. else
  42. result = rtgui_rect_width(rect) - 2*rtgui_rect_height(rect) - bar->thumb_len;
  43. return result;
  44. }
  45. rt_uint32_t get_scrollbar_pos(rtgui_scrollbar_t* bar)
  46. {
  47. double pos,ftmp;
  48. rt_uint32_t result;
  49. /* calculate thumb position */
  50. pos = bar->value;
  51. ftmp = _rtgui_scrollbar_get_length(bar);
  52. pos *= ftmp;
  53. ftmp = bar->count;
  54. pos /= ftmp;
  55. result = pos;
  56. return result;
  57. }
  58. DEFINE_CLASS_TYPE(scrollbar, "scrollbar",
  59. RTGUI_WIDGET_TYPE,
  60. _rtgui_scrollbar_constructor,
  61. _rtgui_scrollbar_destructor,
  62. sizeof(struct rtgui_scrollbar));
  63. rtgui_scrollbar_t* rtgui_scrollbar_create(rtgui_container_t *container,int left,int top,int w,int len,int orient)
  64. {
  65. rtgui_scrollbar_t* bar;
  66. RT_ASSERT(container != RT_NULL);
  67. bar = (rtgui_scrollbar_t *)rtgui_widget_create(RTGUI_SCROLLBAR_TYPE);
  68. if(bar != RT_NULL)
  69. {
  70. rtgui_rect_t rect;
  71. rtgui_widget_get_rect(RTGUI_WIDGET(container), &rect);
  72. rtgui_widget_rect_to_device(RTGUI_WIDGET(container),&rect);
  73. rect.x1 += left;
  74. rect.y1 += top;
  75. bar->thumb_w = w;
  76. if(orient == RTGUI_VERTICAL)
  77. {
  78. rect.x2 = rect.x1+w;
  79. rect.y2 = rect.y1+len;
  80. }
  81. else
  82. {
  83. rect.x2 = rect.x1+len;
  84. rect.y2 = rect.y1+w;
  85. }
  86. rtgui_widget_set_rect(RTGUI_WIDGET(bar), &rect);
  87. bar->orient = orient;
  88. rtgui_container_add_child(container, RTGUI_WIDGET(bar));
  89. }
  90. return bar;
  91. }
  92. void rtgui_scrollbar_destroy(rtgui_scrollbar_t* bar)
  93. {
  94. rtgui_widget_destroy(RTGUI_WIDGET(bar));
  95. }
  96. const static rt_uint8_t _up_arrow[] = {0x10, 0x38, 0x7C, 0xFE};
  97. const static rt_uint8_t _down_arrow[] = {0xFE,0x7C, 0x38, 0x10};
  98. const static rt_uint8_t _left_arrow[] = {0x10, 0x30, 0x70, 0xF0, 0x70, 0x30, 0x10};
  99. const static rt_uint8_t _right_arrow[] = {0x80, 0xC0, 0xE0, 0xF0, 0xE0, 0xC0, 0x80};
  100. void rtgui_scrollbar_ondraw(rtgui_scrollbar_t* bar)
  101. {
  102. /* draw scroll bar */
  103. rtgui_rect_t rect, btn_rect, thum_rect, arrow_rect;
  104. struct rtgui_dc* dc;
  105. rtgui_color_t bc;
  106. RT_ASSERT(bar != RT_NULL);
  107. /* begin drawing */
  108. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(bar));
  109. if(dc == RT_NULL)return;
  110. bc = RTGUI_DC_BC(dc);
  111. /* begin drawing */
  112. rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
  113. RTGUI_DC_BC(dc) = white;
  114. rtgui_dc_fill_rect(dc,&rect);
  115. RTGUI_DC_BC(dc) = bc;
  116. if(bar->orient == RTGUI_VERTICAL)
  117. {
  118. btn_rect = rect;
  119. btn_rect.y2 = btn_rect.y1 + (rect.x2 - rect.x1);
  120. rtgui_dc_fill_rect(dc,&btn_rect);
  121. /* draw up button */
  122. if(bar->status & SBS_UPARROW)
  123. rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
  124. else
  125. rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
  126. /* draw up arrow */
  127. arrow_rect.x1 = 0; arrow_rect.y1 = 0;
  128. arrow_rect.x2 = 7; arrow_rect.y2 = 4;
  129. rtgui_rect_moveto_align(&btn_rect, &arrow_rect, RTGUI_ALIGN_CENTER);
  130. rtgui_dc_draw_byte(dc, arrow_rect.x1, arrow_rect.y1, rtgui_rect_height(arrow_rect), _up_arrow);
  131. /* draw thumb */
  132. rtgui_scrollbar_get_thumb_rect(bar, &thum_rect);
  133. rtgui_dc_fill_rect(dc,&thum_rect);
  134. rtgui_dc_draw_border(dc, &thum_rect, RTGUI_BORDER_RAISE);
  135. /* draw down button */
  136. btn_rect.y1 = rect.y2 - (rect.x2 - rect.x1);
  137. btn_rect.y2 = rect.y2;
  138. rtgui_dc_fill_rect(dc,&btn_rect);
  139. if(bar->status & SBS_DOWNARROW)
  140. rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
  141. else
  142. rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
  143. /* draw down arrow */
  144. arrow_rect.x1 = 0;
  145. arrow_rect.y1 = 0;
  146. arrow_rect.x2 = 7;
  147. arrow_rect.y2 = 4;
  148. rtgui_rect_moveto_align(&btn_rect, &arrow_rect, RTGUI_ALIGN_CENTER);
  149. rtgui_dc_draw_byte(dc, arrow_rect.x1, arrow_rect.y1, rtgui_rect_height(arrow_rect), _down_arrow);
  150. }
  151. else
  152. {
  153. btn_rect = rect;
  154. btn_rect.x2 = btn_rect.x1 + (rect.y2 - rect.y1);
  155. rtgui_dc_fill_rect(dc,&btn_rect);
  156. /* draw left button */
  157. if(bar->status & SBS_LEFTARROW)
  158. rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
  159. else
  160. rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
  161. arrow_rect.x1 = 0;
  162. arrow_rect.y1 = 0;
  163. arrow_rect.x2 = 4;
  164. arrow_rect.y2 = 7;
  165. rtgui_rect_moveto_align(&btn_rect, &arrow_rect, RTGUI_ALIGN_CENTER);
  166. rtgui_dc_draw_byte(dc, arrow_rect.x1, arrow_rect.y1, rtgui_rect_height(arrow_rect), _left_arrow);
  167. /* draw thumb */
  168. if(RTGUI_WIDGET_IS_ENABLE(bar))
  169. {
  170. rtgui_scrollbar_get_thumb_rect(bar, &thum_rect);
  171. rtgui_dc_fill_rect(dc,&thum_rect);
  172. rtgui_dc_draw_border(dc, &thum_rect, RTGUI_BORDER_RAISE);
  173. }
  174. btn_rect.x1 = rect.x2 - (rect.y2-rect.y1);
  175. btn_rect.x2 = rect.x2;
  176. rtgui_dc_fill_rect(dc,&btn_rect);
  177. /* draw right button */
  178. if(bar->status & SBS_RIGHTARROW)
  179. rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
  180. else
  181. rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
  182. arrow_rect.x1 = 0;
  183. arrow_rect.y1 = 0;
  184. arrow_rect.x2 = 4;
  185. arrow_rect.y2 = 7;
  186. rtgui_rect_moveto_align(&btn_rect, &arrow_rect, RTGUI_ALIGN_CENTER);
  187. rtgui_dc_draw_byte(dc, arrow_rect.x1, arrow_rect.y1, rtgui_rect_height(arrow_rect), _right_arrow);
  188. }
  189. rtgui_dc_end_drawing(dc);
  190. }
  191. void rtgui_scrollbar_get_thumb_rect(rtgui_scrollbar_t *bar, rtgui_rect_t *erect)
  192. {
  193. rtgui_rect_t rect;
  194. rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
  195. if(bar->orient & RTGUI_VERTICAL)
  196. {
  197. /* vertical scroll bar */
  198. erect->x1 = rect.x1;
  199. erect->x2 = rect.x2;
  200. erect->y1 = rect.y1 + rtgui_rect_width(rect) + get_scrollbar_pos(bar);
  201. erect->y2 = erect->y1 + bar->thumb_len;
  202. }
  203. else
  204. {
  205. /* horizontal scroll bar */
  206. erect->x1 = rect.x1 + rtgui_rect_height(rect) + get_scrollbar_pos(bar);
  207. erect->x2 = erect->x1 + bar->thumb_len;
  208. erect->y1 = rect.y1;
  209. erect->y2 = rect.y2;
  210. }
  211. }
  212. static rtgui_point_t sbar_mouse_move_size;
  213. static void _rtgui_scrollbar_on_mouseclick(rtgui_scrollbar_t *bar, rtgui_event_t * event)
  214. {
  215. rtgui_rect_t btn_rect, bar_rect,rect;
  216. rt_uint32_t pos;
  217. struct rtgui_event_mouse *mouse = (struct rtgui_event_mouse*)event;
  218. RT_ASSERT(bar != RT_NULL);
  219. /* get value */
  220. pos = get_scrollbar_pos(bar);
  221. rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
  222. rtgui_widget_rect_to_device(RTGUI_WIDGET(bar),&rect);
  223. if(bar->orient == RTGUI_VERTICAL)
  224. {
  225. /* arrange vertical */
  226. /* get up arrow button rect */
  227. btn_rect.x1 = rect.x1;
  228. btn_rect.x2 = rect.x2;
  229. btn_rect.y1 = rect.y1;
  230. btn_rect.y2 = rect.y1 + rtgui_rect_width(rect);
  231. if(rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
  232. {
  233. if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
  234. {
  235. bar->status |= SBS_UPARROW;
  236. if(bar->value==0)
  237. {
  238. rtgui_scrollbar_ondraw(bar);
  239. return;
  240. }
  241. /* line step */
  242. bar->value -= bar->line_step;
  243. if(bar->value < 0) bar->value = 0;
  244. }
  245. else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
  246. {
  247. bar->status = 0;
  248. }
  249. goto __exit;
  250. }
  251. /* click on the thumb chunk, be going to dragging */
  252. rtgui_scrollbar_get_thumb_rect(bar, &bar_rect);
  253. rtgui_widget_rect_to_device(RTGUI_WIDGET(bar),&bar_rect);
  254. if(rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
  255. {
  256. /* on thumb */
  257. if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
  258. {
  259. /* changed status into drag */
  260. bar->status |= SBS_VERTTHUMB;
  261. sbar_mouse_move_size.x = mouse->x;
  262. sbar_mouse_move_size.y = mouse->y;
  263. }
  264. else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
  265. {
  266. bar->status = 0;
  267. }
  268. goto __exit;
  269. }
  270. else
  271. {
  272. /* click on space without thumb */
  273. /* get bar rect */
  274. bar_rect.y1 = rect.y1 + rtgui_rect_width(rect);
  275. bar_rect.y2 = rect.y2 - rtgui_rect_width(rect);
  276. if(rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
  277. {
  278. if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
  279. {
  280. /* page step */
  281. if(mouse->y < bar_rect.y1 + pos)
  282. {
  283. bar->status |= SBS_UPSPACE;
  284. bar->value -= bar->page_step;
  285. if(bar->value < 0) bar->value = 0;
  286. }
  287. else if(mouse->y > pos + bar->thumb_len)
  288. {
  289. bar->status |= SBS_DOWNSPACE;
  290. bar->value += bar->page_step;
  291. if(bar->value > bar->count) bar->value = bar->count;
  292. }
  293. }
  294. goto __exit;
  295. }
  296. }
  297. /* likewise foregoing */
  298. /* get down arrow button rect */
  299. bar_rect.x1 = rect.x1;
  300. bar_rect.x2 = rect.x2;
  301. btn_rect.y1 = rect.y2 - rtgui_rect_width(rect);
  302. btn_rect.y2 = rect.y2;
  303. if(rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
  304. {
  305. if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
  306. {
  307. bar->status |= SBS_DOWNARROW;
  308. if(bar->value==bar->count)
  309. {
  310. rtgui_scrollbar_ondraw(bar);
  311. return;
  312. }
  313. /* line step */
  314. bar->value += bar->line_step;
  315. if(bar->value > bar->count) bar->value = bar->count;
  316. }
  317. else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
  318. bar->status = 0;
  319. goto __exit;
  320. }
  321. }
  322. else
  323. {
  324. /* get left arrow button rect */
  325. btn_rect.x1 = rect.x1;
  326. btn_rect.x2 = rect.x1 + rtgui_rect_height(rect);
  327. btn_rect.y1 = rect.y1;
  328. btn_rect.y2 = rect.y2;
  329. if(rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
  330. {
  331. if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
  332. {
  333. bar->status |= SBS_LEFTARROW;
  334. if(bar->value==0)
  335. {
  336. rtgui_scrollbar_ondraw(bar);
  337. return;
  338. }
  339. /* line step */
  340. bar->value -= bar->line_step;
  341. if(bar->value < 0) bar->value = 0;
  342. }
  343. else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
  344. bar->status = 0;
  345. goto __exit;
  346. }
  347. rtgui_scrollbar_get_thumb_rect(bar, &bar_rect);
  348. rtgui_widget_rect_to_device(RTGUI_WIDGET(bar),&bar_rect);
  349. if(rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
  350. {
  351. /* on the thumb */
  352. if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
  353. {
  354. bar->status |= SBS_HORZTHUMB;
  355. sbar_mouse_move_size.x = mouse->x;
  356. sbar_mouse_move_size.y = mouse->y;
  357. }
  358. else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
  359. {
  360. bar->status = 0;
  361. }
  362. goto __exit;
  363. }
  364. else
  365. {
  366. /* get bar rect */
  367. bar_rect.x1 = rect.x1 + rtgui_rect_height(rect);
  368. bar_rect.x2 = rect.x2 - rtgui_rect_height(rect);
  369. bar_rect.y1 = rect.y1;
  370. bar_rect.y2 = rect.y2;
  371. if(rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
  372. {
  373. if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
  374. {
  375. /* page step */
  376. if(mouse->x < bar_rect.x1 + pos)
  377. {
  378. bar->status |= SBS_LEFTSPACE;
  379. bar->value -= bar->page_step;
  380. if(bar->value < 0) bar->value = 0;
  381. }
  382. else if(mouse->x > pos + bar->thumb_len)
  383. {
  384. bar->status |= SBS_RIGHTSPACE;
  385. bar->value += bar->page_step;
  386. if(bar->value > bar->count) bar->value = bar->count;
  387. }
  388. }
  389. else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
  390. {
  391. bar->status = 0;
  392. }
  393. goto __exit;
  394. }
  395. }
  396. /* get right arrow button rect */
  397. btn_rect.x1 = rect.x2 - rtgui_rect_height(rect);
  398. btn_rect.x2 = rect.x2;
  399. bar_rect.y1 = rect.y1;
  400. bar_rect.y2 = rect.y2;
  401. if(rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
  402. {
  403. if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
  404. {
  405. bar->status |= SBS_RIGHTARROW;
  406. if(bar->value==bar->count)
  407. {
  408. rtgui_scrollbar_ondraw(bar);
  409. return;
  410. }
  411. /* line step */
  412. bar->value += bar->line_step;
  413. if(bar->value > bar->count) bar->value = bar->count;
  414. }
  415. else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
  416. bar->status = 0;
  417. goto __exit;
  418. }
  419. }
  420. __exit:
  421. rtgui_scrollbar_ondraw(bar);
  422. if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
  423. {
  424. if(bar->widget_link != RT_NULL && bar->on_scroll != RT_NULL)
  425. {
  426. rtgui_widget_focus(bar->widget_link);
  427. bar->on_scroll(RTGUI_OBJECT(bar->widget_link), event);
  428. }
  429. }
  430. }
  431. /* thumb chunk activity */
  432. static void _rtgui_scrollbar_on_mousemotion(rtgui_scrollbar_t *bar, rtgui_event_t * event)
  433. {
  434. float tmppos;
  435. rt_uint32_t pos;
  436. struct rtgui_event_mouse *mouse = (struct rtgui_event_mouse*)event;
  437. rt_kprintf("sbar mouse motion.\n");
  438. tmppos = _rtgui_scrollbar_get_length(bar);
  439. tmppos /= bar->count;
  440. pos = (rt_uint32_t)tmppos;
  441. if(bar->orient == RTGUI_VERTICAL)
  442. {
  443. if(bar->status & SBS_VERTTHUMB)
  444. {
  445. /* from then on mouseclick */
  446. if((mouse->y-sbar_mouse_move_size.y) > 3)
  447. {
  448. bar->status |= SBS_DOWNTHUMB;
  449. }
  450. else if((mouse->y-sbar_mouse_move_size.y) < -3)
  451. {
  452. bar->status |= SBS_UPTHUMB;
  453. }
  454. else bar->status &= ~(SBS_UPTHUMB|SBS_DOWNTHUMB);
  455. if(abs(mouse->y-sbar_mouse_move_size.y) >= pos)
  456. {
  457. int step = abs(mouse->y-sbar_mouse_move_size.y)/pos;
  458. sbar_mouse_move_size.y = mouse->y;
  459. if(bar->status & SBS_UPTHUMB)
  460. {
  461. bar->value -= step;
  462. if(bar->value < 0) bar->value = 0;
  463. }
  464. else if(bar->status & SBS_DOWNTHUMB)
  465. {
  466. bar->value += step;
  467. if(bar->value > bar->count) bar->value = bar->count;
  468. }
  469. goto __exit;
  470. }
  471. }
  472. else if(bar->status & SBS_UPARROW)
  473. {
  474. /* on-going push down uparrow button */
  475. if(bar->value==0)return;
  476. bar->value -= bar->line_step;
  477. if(bar->value < 0) bar->value = 0;
  478. goto __exit;
  479. }
  480. else if(bar->status & SBS_DOWNARROW)
  481. {
  482. /* on-going push down downarrow button */
  483. if(bar->value==bar->count)return;
  484. bar->value += bar->line_step;
  485. if(bar->value > bar->count) bar->value = bar->count;
  486. goto __exit;
  487. }
  488. /*else if(bar->status & SBS_UPSPACE)
  489. {
  490. bar->value -= bar->page_step;
  491. if(bar->value < 0) bar->value = 0;
  492. goto __exit;
  493. }
  494. else if(bar->status & SBS_DOWNSPACE)
  495. {
  496. bar->value += bar->page_step;
  497. if(bar->value > bar->count) bar->value = bar->count;
  498. goto __exit;
  499. }*/
  500. return;
  501. }
  502. else
  503. {
  504. if(bar->status & SBS_HORZTHUMB)
  505. {rt_kprintf("HORZTHUMB, move event\n");
  506. if((mouse->x-sbar_mouse_move_size.x) > 5)
  507. {
  508. bar->status |= SBS_RIGHTTHUMB;
  509. }
  510. else if((mouse->x-sbar_mouse_move_size.x) < -5)
  511. {
  512. bar->status |= SBS_LEFTTHUMB;
  513. }
  514. if(abs(mouse->x-sbar_mouse_move_size.x) > pos)
  515. {
  516. int step = abs(mouse->x-sbar_mouse_move_size.x)/pos;
  517. sbar_mouse_move_size.x = mouse->x;
  518. if(bar->status & SBS_LEFTTHUMB)
  519. {
  520. bar->value -= step;
  521. if(bar->value < 0) bar->value = 0;
  522. }
  523. else if(bar->status & SBS_RIGHTTHUMB)
  524. {
  525. bar->value += step;
  526. if(bar->value > bar->count) bar->value = bar->count;
  527. }
  528. goto __exit;
  529. }
  530. }
  531. else if(bar->status & SBS_LEFTARROW)
  532. {
  533. if(bar->value==0)return;
  534. bar->value -= bar->line_step;
  535. if(bar->value < 0) bar->value = 0;
  536. goto __exit;
  537. }
  538. else if(bar->status & SBS_RIGHTARROW)
  539. {
  540. if(bar->value==bar->count)return;
  541. bar->value += bar->line_step;
  542. if(bar->value > bar->count) bar->value = bar->count;
  543. goto __exit;
  544. }
  545. /*else if(bar->status & SBS_LEFTSPACE)
  546. {
  547. bar->value -= bar->page_step;
  548. if(bar->value < bar->min) bar->value = bar->min;
  549. goto __exit;
  550. }
  551. else if(bar->status & SBS_RIGHTSPACE)
  552. {
  553. bar->value += bar->page_step;
  554. if(bar->value > bar->count-1) bar->value = bar->count-1;
  555. goto __exit;
  556. }*/
  557. return;
  558. }
  559. __exit:
  560. rtgui_scrollbar_ondraw(bar);
  561. if(bar->widget_link != RT_NULL && bar->on_scroll != RT_NULL)
  562. {
  563. rtgui_widget_focus(bar->widget_link);
  564. bar->on_scroll(RTGUI_OBJECT(bar->widget_link), event);
  565. }
  566. }
  567. rt_bool_t rtgui_scrollbar_event_handler(rtgui_object_t *object, rtgui_event_t *event)
  568. {
  569. rtgui_widget_t *widget = RTGUI_WIDGET(object);
  570. rtgui_scrollbar_t* bar = RTGUI_SCROLLBAR(object);
  571. switch(event->type)
  572. {
  573. case RTGUI_EVENT_PAINT:
  574. #ifndef RTGUI_USING_SMALL_SIZE
  575. if(widget->on_draw != RT_NULL)
  576. widget->on_draw(object, event);
  577. else
  578. #endif
  579. {
  580. if(!RTGUI_WIDGET_IS_HIDE(bar))
  581. rtgui_scrollbar_ondraw(bar);
  582. }
  583. break;
  584. case RTGUI_EVENT_MOUSE_BUTTON:
  585. if(RTGUI_WIDGET_IS_ENABLE(widget))
  586. {
  587. #ifndef RTGUI_USING_SMALL_SIZE
  588. if(widget->on_mouseclick != RT_NULL)
  589. {
  590. widget->on_mouseclick(object, event);
  591. }
  592. else
  593. #endif
  594. {
  595. _rtgui_scrollbar_on_mouseclick(bar, event);
  596. }
  597. }
  598. break;
  599. case RTGUI_EVENT_MOUSE_MOTION:
  600. if(RTGUI_WIDGET_IS_ENABLE(widget))
  601. {
  602. _rtgui_scrollbar_on_mousemotion(bar, event);
  603. }
  604. default:
  605. return rtgui_widget_event_handler(object, event);
  606. }
  607. return RT_FALSE;
  608. }
  609. void rtgui_scrollbar_set_orientation(rtgui_scrollbar_t* bar, int orient)
  610. {
  611. RT_ASSERT(bar != RT_NULL);
  612. bar->orient = orient;
  613. }
  614. /* get active area length */
  615. rt_uint32_t get_sbar_active_len(rtgui_scrollbar_t *bar)
  616. {
  617. rtgui_rect_t rect;
  618. rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
  619. if(bar->orient & RTGUI_VERTICAL)
  620. return rtgui_rect_height(rect) - 2*rtgui_rect_width(rect);
  621. else
  622. return rtgui_rect_width(rect) - 2*rtgui_rect_height(rect);
  623. }
  624. void rtgui_scrollbar_set_thumbbar_len(rtgui_scrollbar_t* bar)
  625. {
  626. double size=0;
  627. rt_uint32_t len,w;
  628. RT_ASSERT(bar != RT_NULL);
  629. /* Make sure called rtgui_scrollbar_set_range(),before you use under code. */
  630. size = bar->page_step;
  631. size /= bar->count+bar->page_step;
  632. size *= get_sbar_active_len(bar);
  633. len = (rt_uint32_t)size ;
  634. w = bar->thumb_w;
  635. if(len < w/2) len = w/2;
  636. bar->thumb_len = len;
  637. }
  638. /*
  639. * please use them with below step:
  640. * 1.SetLineStep();2.SetPageStep();3.SetRange();
  641. */
  642. void rtgui_scrollbar_set_line_step(rtgui_scrollbar_t* bar, int step)
  643. {
  644. RT_ASSERT(bar != RT_NULL);
  645. bar->line_step = step;
  646. }
  647. void rtgui_scrollbar_set_page_step(rtgui_scrollbar_t* bar, int step)
  648. {
  649. RT_ASSERT(bar != RT_NULL);
  650. bar->page_step = step;
  651. }
  652. void rtgui_scrollbar_set_range(rtgui_scrollbar_t* bar, int count)
  653. {
  654. RT_ASSERT(bar != RT_NULL);
  655. /* disable or enable scrollbar */
  656. if(bar->page_step >= count)
  657. {
  658. /* disable bar */
  659. RTGUI_WIDGET_DISABLE(bar);
  660. }
  661. else
  662. {
  663. /* enable bar */
  664. RTGUI_WIDGET_ENABLE(bar);
  665. }
  666. /* thumb step count = item_count-item_per_page */
  667. bar->count = (rt_int16_t)(count-bar->page_step);
  668. rtgui_scrollbar_set_thumbbar_len(bar);
  669. }
  670. /* use VALUE change be binding widget's frist item. */
  671. void rtgui_scrollbar_set_value(rtgui_scrollbar_t* bar, rt_int16_t value)
  672. {
  673. RT_ASSERT(bar != RT_NULL);
  674. bar->value = value;
  675. if(bar->value < 0) bar->value = 0;
  676. rtgui_widget_update(RTGUI_WIDGET(bar));
  677. }
  678. void rtgui_scrollbar_set_onscroll(rtgui_scrollbar_t* bar, rtgui_event_handler_ptr handler)
  679. {
  680. if(bar == RT_NULL || handler == RT_NULL) return;
  681. bar->on_scroll = handler;
  682. }
  683. void rtgui_scrollbar_hide(rtgui_scrollbar_t* bar)
  684. {
  685. rtgui_rect_t rect;
  686. struct rtgui_dc* dc;
  687. RT_ASSERT(bar != RT_NULL);
  688. /* begin drawing */
  689. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(bar));
  690. if(dc == RT_NULL)return;
  691. RTGUI_WIDGET_HIDE(bar);
  692. /* begin drawing */
  693. rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
  694. if((RTGUI_WIDGET(bar))->parent != RT_NULL)
  695. RTGUI_DC_BC(dc) = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)->parent);
  696. else
  697. RTGUI_DC_BC(dc) = RTGUI_RGB(225, 228, 220);
  698. rtgui_dc_fill_rect(dc,&rect);
  699. rtgui_dc_end_drawing(dc);
  700. }