1
0

slider.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. /*
  2. * File : slider.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2010, 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. * 2009-10-16 Bernard first version
  13. * 2010-09-10 Bernard fix hide issue
  14. */
  15. #include <rtgui/dc.h>
  16. #include <rtgui/rtgui_theme.h>
  17. #include <rtgui/widgets/slider.h>
  18. #define RTGUI_SLIDER_DEFAULT_WIDTH 100
  19. #define RTGUI_SLIDER_DEFAULT_HEIGHT 20
  20. #define RTGUI_SLIDER_DEFAULT_MIN 0
  21. #define RTGUI_SLIDER_DEFAULT_MAX 100
  22. static void _rtgui_slider_constructor(rtgui_slider_t *slider)
  23. {
  24. rtgui_rect_t rect = {0, 0, RTGUI_SLIDER_DEFAULT_WIDTH, RTGUI_SLIDER_DEFAULT_HEIGHT};
  25. /* init widget and set event handler */
  26. RTGUI_WIDGET(slider)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
  27. rtgui_widget_set_rect(RTGUI_WIDGET(slider), &rect);
  28. rtgui_object_set_event_handler(RTGUI_OBJECT(slider), rtgui_slider_event_handler);
  29. /* set proper of control */
  30. slider->min = RTGUI_SLIDER_DEFAULT_MIN;
  31. slider->max = RTGUI_SLIDER_DEFAULT_MAX;
  32. slider->value = RTGUI_SLIDER_DEFAULT_MIN;
  33. slider->orient = RTGUI_HORIZONTAL;
  34. slider->ticks = 10;
  35. slider->thumb_width = 8;
  36. slider->on_changed = RT_NULL;
  37. }
  38. DEFINE_CLASS_TYPE(slider, "slider",
  39. RTGUI_WIDGET_TYPE,
  40. _rtgui_slider_constructor,
  41. RT_NULL,
  42. sizeof(struct rtgui_slider));
  43. static void rtgui_slider_onmouse(struct rtgui_slider* slider, struct rtgui_event_mouse* event)
  44. {
  45. RT_ASSERT(slider != RT_NULL);
  46. RT_ASSERT(event != RT_NULL);
  47. if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
  48. event->button & RTGUI_MOUSE_BUTTON_LEFT)
  49. {
  50. int sel;
  51. int range = slider->max - slider->min;
  52. int x0, xsize;
  53. int x;
  54. x0 = 1 + slider->thumb_width/2;
  55. if (slider->orient == RTGUI_VERTICAL)
  56. {
  57. x = event->y - RTGUI_WIDGET(slider)->extent.y1;
  58. x -= x0;
  59. xsize = rtgui_rect_height(RTGUI_WIDGET(slider)->extent) - 2 * x0;
  60. }
  61. else
  62. {
  63. x = event->x - RTGUI_WIDGET(slider)->extent.x1;
  64. x -= x0;
  65. xsize = rtgui_rect_width(RTGUI_WIDGET(slider)->extent) - 2 * x0;
  66. }
  67. if (x <= 0)
  68. {
  69. sel = slider->min;
  70. }
  71. else if (x >= xsize)
  72. {
  73. sel = slider->max;
  74. }
  75. else
  76. {
  77. sel = ((range * x) + xsize/2) / xsize;
  78. sel += slider->min;
  79. }
  80. rtgui_widget_focus(RTGUI_WIDGET(slider));
  81. rtgui_slider_set_value(slider, sel);
  82. if (slider->on_changed != RT_NULL) /* invoke callback function */
  83. slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
  84. }
  85. }
  86. static rt_bool_t rtgui_slider_onkey(struct rtgui_slider* slider, struct rtgui_event_kbd *event)
  87. {
  88. RT_ASSERT(slider != RT_NULL);
  89. RT_ASSERT(event != RT_NULL);
  90. if (!(RTGUI_KBD_IS_UP(event)))
  91. return RT_TRUE;
  92. if (slider->orient == RTGUI_HORIZONTAL)
  93. {
  94. if (event->key == RTGUIK_RIGHT)
  95. {
  96. if (slider->value > slider->min)
  97. slider->value++;
  98. }
  99. else if (event->key == RTGUIK_LEFT)
  100. {
  101. if (slider->value < slider->max)
  102. slider->value--;
  103. }
  104. }
  105. else
  106. {
  107. if (event->key == RTGUIK_UP)
  108. {
  109. if (slider->value > slider->min)
  110. slider->value--;
  111. }
  112. else if (event->key == RTGUIK_DOWN)
  113. {
  114. if (slider->value < slider->max)
  115. slider->value++;
  116. }
  117. }
  118. /* update widget */
  119. rtgui_widget_update(RTGUI_WIDGET(slider));
  120. if (slider->on_changed != RT_NULL) /* invoke callback function */
  121. slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
  122. return RT_TRUE;
  123. }
  124. rt_bool_t rtgui_slider_event_handler(struct rtgui_object *object, struct rtgui_event *event)
  125. {
  126. struct rtgui_widget *widget;
  127. struct rtgui_slider* slider;
  128. RT_ASSERT(object != RT_NULL);
  129. RT_ASSERT(event != RT_NULL);
  130. widget = RTGUI_WIDGET(object);
  131. slider = RTGUI_SLIDER(object);
  132. switch (event->type)
  133. {
  134. case RTGUI_EVENT_PAINT:
  135. #ifndef RTGUI_USING_SMALL_SIZE
  136. if (widget->on_draw != RT_NULL)
  137. widget->on_draw(RTGUI_OBJECT(widget), event);
  138. else
  139. #endif
  140. {
  141. rtgui_theme_draw_slider(slider);
  142. }
  143. break;
  144. case RTGUI_EVENT_KBD:
  145. if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
  146. #ifndef RTGUI_USING_SMALL_SIZE
  147. if (widget->on_key != RT_NULL)
  148. return widget->on_key(RTGUI_OBJECT(widget), event);
  149. else
  150. #endif
  151. return rtgui_slider_onkey(slider, (struct rtgui_event_kbd *)event);
  152. case RTGUI_EVENT_MOUSE_BUTTON:
  153. if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
  154. #ifndef RTGUI_USING_SMALL_SIZE
  155. if (widget->on_mouseclick != RT_NULL)
  156. widget->on_mouseclick(RTGUI_OBJECT(widget), event);
  157. else
  158. #endif
  159. {
  160. rtgui_slider_onmouse(slider, (struct rtgui_event_mouse*)event);
  161. }
  162. break;
  163. default:
  164. return rtgui_widget_event_handler(object, event);
  165. }
  166. return RT_FALSE;
  167. }
  168. struct rtgui_slider* rtgui_slider_create(rt_size_t min, rt_size_t max, int orient)
  169. {
  170. struct rtgui_slider* slider;
  171. slider = (struct rtgui_slider*) rtgui_widget_create (RTGUI_SLIDER_TYPE);
  172. if (slider != RT_NULL)
  173. {
  174. /* set proper of control */
  175. slider->min = min;
  176. slider->max = max;
  177. slider->value = min;
  178. slider->ticks = 10;
  179. slider->thumb_width = 8;
  180. rtgui_slider_set_orientation(slider, orient);
  181. }
  182. return slider;
  183. }
  184. void rtgui_slider_set_range(struct rtgui_slider* slider, rt_size_t min, rt_size_t max)
  185. {
  186. RT_ASSERT(slider != RT_NULL);
  187. slider->max = max;
  188. slider->min = min;
  189. }
  190. void rtgui_slider_set_value(struct rtgui_slider* slider, rt_size_t value)
  191. {
  192. RT_ASSERT(slider != RT_NULL);
  193. if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(slider)))
  194. {
  195. if (value < slider->min) value = slider->min;
  196. if (value > slider->max) value = slider->max;
  197. if (slider->value != value)
  198. {
  199. slider->value = value;
  200. rtgui_theme_draw_slider(slider);
  201. }
  202. }
  203. }
  204. void rtgui_slider_set_orientation(struct rtgui_slider* slider, int orientation)
  205. {
  206. RT_ASSERT(slider != RT_NULL);
  207. /* set orientation */
  208. slider->orient = orientation;
  209. #ifndef RTGUI_USING_SMALL_SIZE
  210. if (slider->orient == RTGUI_HORIZONTAL)
  211. {
  212. /* HORIZONTAL */
  213. rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
  214. rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
  215. }
  216. else
  217. {
  218. /* VERTICAL */
  219. rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
  220. rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
  221. }
  222. #endif
  223. }
  224. rt_size_t rtgui_slider_get_value(struct rtgui_slider* slider)
  225. {
  226. RT_ASSERT(slider != RT_NULL);
  227. return slider->value;
  228. }