slider.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #include <rtgui/dc.h>
  2. #include <rtgui/rtgui_theme.h>
  3. #include <rtgui/widgets/slider.h>
  4. #define RTGUI_SLIDER_DEFAULT_WIDTH 100
  5. #define RTGUI_SLIDER_DEFAULT_HEIGHT 20
  6. #define RTGUI_SLIDER_DEFAULT_MIN 0
  7. #define RTGUI_SLIDER_DEFAULT_MAX 100
  8. static void _rtgui_slider_constructor(rtgui_slider_t *slider)
  9. {
  10. rtgui_rect_t rect = {0, 0, RTGUI_SLIDER_DEFAULT_WIDTH, RTGUI_SLIDER_DEFAULT_HEIGHT};
  11. /* init widget and set event handler */
  12. RTGUI_WIDGET(slider)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
  13. rtgui_widget_set_rect(RTGUI_WIDGET(slider), &rect);
  14. rtgui_widget_set_event_handler(RTGUI_WIDGET(slider), rtgui_slider_event_handler);
  15. /* set proper of control */
  16. slider->min = RTGUI_SLIDER_DEFAULT_MIN;
  17. slider->max = RTGUI_SLIDER_DEFAULT_MAX;
  18. slider->value = RTGUI_SLIDER_DEFAULT_MIN;
  19. slider->orient = RTGUI_HORIZONTAL;
  20. slider->ticks = 10;
  21. slider->thumb_width = 8;
  22. }
  23. rtgui_type_t *rtgui_slider_type_get(void)
  24. {
  25. static rtgui_type_t *slider_type = RT_NULL;
  26. if (!slider_type)
  27. {
  28. slider_type = rtgui_type_create("slider", RTGUI_WIDGET_TYPE,
  29. sizeof(rtgui_slider_t), RTGUI_CONSTRUCTOR(_rtgui_slider_constructor), RT_NULL);
  30. }
  31. return slider_type;
  32. }
  33. static void rtgui_slider_onmouse(struct rtgui_slider* slider, struct rtgui_event_mouse* event)
  34. {
  35. RT_ASSERT(slider != RT_NULL);
  36. RT_ASSERT(event != RT_NULL);
  37. if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
  38. event->button & RTGUI_MOUSE_BUTTON_LEFT)
  39. {
  40. int sel;
  41. int range = slider->max - slider->min;
  42. int x0, xsize;
  43. int x;
  44. x0 = 1 + slider->thumb_width/2;
  45. if (slider->orient == RTGUI_VERTICAL)
  46. {
  47. x = event->y - RTGUI_WIDGET(slider)->extent.y1;
  48. x -= x0;
  49. xsize = rtgui_rect_height(RTGUI_WIDGET(slider)->extent) - 2 * x0;
  50. }
  51. else
  52. {
  53. x = event->x - RTGUI_WIDGET(slider)->extent.x1;
  54. x -= x0;
  55. xsize = rtgui_rect_width(RTGUI_WIDGET(slider)->extent) - 2 * x0;
  56. }
  57. if (x <= 0)
  58. {
  59. sel = slider->min;
  60. }
  61. else if (x >= xsize)
  62. {
  63. sel = slider->max;
  64. }
  65. else
  66. {
  67. sel = ((range * x) + xsize/2) / xsize;
  68. sel += slider->min;
  69. }
  70. rtgui_widget_focus(RTGUI_WIDGET(slider));
  71. rtgui_slider_set_value(slider, sel);
  72. }
  73. }
  74. static void rtgui_slider_onkey(struct rtgui_slider* slider, struct rtgui_event_kbd *event)
  75. {
  76. RT_ASSERT(slider != RT_NULL);
  77. RT_ASSERT(event != RT_NULL);
  78. if (!(RTGUI_KBD_IS_UP(event))) return;
  79. if (event->key == RTGUIK_LEFT)
  80. {
  81. if (slider->value > slider->min)
  82. slider->value ++;
  83. }
  84. if (event->key == RTGUIK_RIGHT)
  85. {
  86. if (slider->value < slider->max)
  87. slider->value --;
  88. }
  89. /* update widget */
  90. rtgui_widget_update(RTGUI_WIDGET(slider));
  91. }
  92. rt_bool_t rtgui_slider_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
  93. {
  94. struct rtgui_slider* slider = (struct rtgui_slider*)widget;
  95. switch (event->type)
  96. {
  97. case RTGUI_EVENT_PAINT:
  98. #ifndef RTGUI_USING_SMALL_SIZE
  99. if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
  100. else
  101. #endif
  102. {
  103. rtgui_theme_draw_slider(slider);
  104. }
  105. break;
  106. case RTGUI_EVENT_KBD:
  107. #ifndef RTGUI_USING_SMALL_SIZE
  108. if (widget->on_key != RT_NULL) widget->on_key(widget, event);
  109. else
  110. #endif
  111. {
  112. rtgui_slider_onkey(slider, (struct rtgui_event_kbd *)event);
  113. }
  114. break;
  115. case RTGUI_EVENT_MOUSE_BUTTON:
  116. #ifndef RTGUI_USING_SMALL_SIZE
  117. if (widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
  118. else
  119. #endif
  120. {
  121. rtgui_slider_onmouse(slider, (struct rtgui_event_mouse*)event);
  122. }
  123. break;
  124. }
  125. return RT_FALSE;
  126. }
  127. struct rtgui_slider* rtgui_slider_create(rt_size_t min, rt_size_t max, int orient)
  128. {
  129. struct rtgui_slider* slider;
  130. slider = (struct rtgui_slider*) rtgui_widget_create (RTGUI_SLIDER_TYPE);
  131. if (slider != RT_NULL)
  132. {
  133. /* set proper of control */
  134. slider->min = min;
  135. slider->max = max;
  136. slider->value = min;
  137. slider->ticks = 10;
  138. slider->thumb_width = 8;
  139. rtgui_slider_set_orientation(slider, orient);
  140. }
  141. return slider;
  142. }
  143. void rtgui_slider_set_range(struct rtgui_slider* slider, rt_size_t min, rt_size_t max)
  144. {
  145. RT_ASSERT(slider != RT_NULL);
  146. slider->max = max;
  147. slider->min = min;
  148. }
  149. void rtgui_slider_set_value(struct rtgui_slider* slider, rt_size_t value)
  150. {
  151. RT_ASSERT(slider != RT_NULL);
  152. if (value < slider->min) value = slider->min;
  153. if (value > slider->max) value = slider->max;
  154. if (slider->value != value)
  155. {
  156. slider->value = value;
  157. rtgui_theme_draw_slider(slider);
  158. }
  159. }
  160. void rtgui_slider_set_orientation(struct rtgui_slider* slider, int orientation)
  161. {
  162. RT_ASSERT(slider != RT_NULL);
  163. /* set orientation */
  164. slider->orient = orientation;
  165. #ifndef RTGUI_USING_SMALL_SIZE
  166. if (slider->orient == RTGUI_HORIZONTAL)
  167. {
  168. /* HORIZONTAL */
  169. rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
  170. rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
  171. }
  172. else
  173. {
  174. /* VERTICAL */
  175. rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
  176. rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
  177. }
  178. #endif
  179. }
  180. rt_size_t rtgui_slider_get_value(struct rtgui_slider* slider)
  181. {
  182. RT_ASSERT(slider != RT_NULL);
  183. return slider->value;
  184. }