caret.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * File : caret.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. * 2009-10-16 Bernard first version
  13. */
  14. #include <rtgui/dc.h>
  15. #include <rtgui/caret.h>
  16. #include <rtgui/rtgui_system.h>
  17. #define RTGUI_CARET_WIDTH 2
  18. #ifdef __WIN32__
  19. #define RTGUI_CARET_BLINK 300
  20. #else
  21. #define RTGUI_CARET_BLINK 30
  22. #endif
  23. static void rtgui_caret_blink(struct rtgui_timer* timer, void* parameter)
  24. {
  25. struct rtgui_caret* caret;
  26. rtgui_widget_t* widget;
  27. caret = (struct rtgui_caret*)parameter;
  28. RT_ASSERT(caret != RT_NULL);
  29. if (caret->owner == RT_NULL) return;
  30. /* caret's owner is visible? */
  31. widget = caret->owner;
  32. do
  33. {
  34. if (RTGUI_WIDGET_IS_HIDE(widget) == RT_TRUE) return;
  35. widget = widget->parent;
  36. } while (widget != RT_NULL);
  37. if (caret->is_show == RT_TRUE)
  38. {
  39. /* set to false */
  40. caret->is_show = RT_FALSE;
  41. /* update owner widget */
  42. if (caret->owner != RT_NULL)
  43. {
  44. rtgui_widget_update(caret->owner);
  45. }
  46. }
  47. else
  48. {
  49. /* set to true */
  50. caret->is_show = RT_TRUE;
  51. /* draw caret */
  52. rtgui_caret_draw(caret);
  53. }
  54. }
  55. struct rtgui_caret* rtgui_caret_create(struct rtgui_widget* owner)
  56. {
  57. struct rtgui_caret* caret;
  58. RT_ASSERT(owner != RT_NULL);
  59. caret = (struct rtgui_caret*)rtgui_malloc(sizeof(struct rtgui_caret));
  60. if (caret != RT_NULL)
  61. {
  62. caret->is_show = RT_FALSE;
  63. caret->extent.x1 = 0;
  64. caret->extent.y1 = 0;
  65. caret->extent.x2 = RTGUI_CARET_WIDTH;
  66. caret->extent.y2 = owner->gc.font->height;
  67. caret->owner = owner;
  68. caret->dc = (struct rtgui_dc*)rtgui_dc_buffer_create(RTGUI_CARET_WIDTH, caret->extent.y2);
  69. if (caret->dc == RT_NULL) goto __exit;
  70. rtgui_dc_set_color(caret->dc, black);
  71. rtgui_dc_fill_rect(caret->dc, &(caret->extent));
  72. caret->timer_period = RTGUI_CARET_BLINK;
  73. caret->timer = rtgui_timer_create(caret->timer_period,
  74. RT_TIMER_FLAG_PERIODIC,
  75. rtgui_caret_blink, caret);
  76. if (caret->timer == RT_NULL) goto __exit_dc;
  77. caret->show_point.x = 0;
  78. caret->show_point.y = 0;
  79. }
  80. return caret;
  81. __exit_dc:
  82. rtgui_dc_destory(caret->dc);
  83. __exit:
  84. rtgui_free(caret);
  85. return RT_NULL;
  86. }
  87. void rtgui_caret_destroy(struct rtgui_caret* caret)
  88. {
  89. RT_ASSERT(caret != RT_NULL);
  90. if (caret->is_show == RT_TRUE)
  91. {
  92. /* stop timer */
  93. rtgui_timer_stop(caret->timer);
  94. }
  95. caret->owner = RT_NULL;
  96. rtgui_dc_destory(caret->dc);
  97. rtgui_timer_destory(caret->timer);
  98. rtgui_free(caret);
  99. }
  100. /* show caret on owner widget logic position */
  101. void rtgui_caret_show(struct rtgui_caret* caret, rt_base_t x, rt_base_t y)
  102. {
  103. if (caret->is_show == RT_TRUE)
  104. {
  105. /* set show flag and stop blink timer */
  106. caret->is_show = RT_FALSE;
  107. rtgui_timer_stop(caret->timer);
  108. }
  109. /* set show x and y */
  110. caret->show_point.x = x;
  111. caret->show_point.y = y;
  112. /* set show flag and start blink timer */
  113. caret->is_show = RT_TRUE;
  114. /* draw caret */
  115. rtgui_caret_draw(caret);
  116. /* start blink timer */
  117. rtgui_timer_start(caret->timer);
  118. }
  119. void rtgui_caret_hide(struct rtgui_caret* caret)
  120. {
  121. RT_ASSERT(caret != RT_NULL);
  122. /* set show flag and stop blink timer */
  123. caret->is_show = RT_FALSE;
  124. rtgui_timer_stop(caret->timer);
  125. /* update owner widget */
  126. if (caret->owner != RT_NULL)
  127. {
  128. rtgui_widget_update(caret->owner);
  129. }
  130. }
  131. void rtgui_caret_set_point(struct rtgui_caret* caret, int x, int y)
  132. {
  133. RT_ASSERT(caret != RT_NULL);
  134. if (caret->is_show == RT_TRUE)
  135. {
  136. /* stop the old caret */
  137. rtgui_timer_stop(caret->timer);
  138. /* update owner widget */
  139. if (caret->owner != RT_NULL && caret->is_show)
  140. {
  141. rtgui_widget_update(caret->owner);
  142. }
  143. }
  144. caret->show_point.x = x;
  145. caret->show_point.y = y;
  146. /* draw caret */
  147. rtgui_caret_draw(caret);
  148. /* start blink timer */
  149. rtgui_timer_start(caret->timer);
  150. }
  151. void rtgui_caret_set_box(struct rtgui_caret* caret, int w, int h)
  152. {
  153. RT_ASSERT(caret != RT_NULL);
  154. caret->extent.x2 = caret->extent.x1 + w;
  155. caret->extent.y2 = caret->extent.y1 + h;
  156. }
  157. void rtgui_caret_draw(struct rtgui_caret* caret)
  158. {
  159. RT_ASSERT(caret != RT_NULL);
  160. if (caret->is_show == RT_TRUE && caret->owner->toplevel != RT_NULL)
  161. {
  162. struct rtgui_rect rect = caret->extent;
  163. struct rtgui_point point = {0, 0};
  164. struct rtgui_dc* hw_dc;
  165. rtgui_rect_moveto(&rect, caret->show_point.x, caret->show_point.y);
  166. hw_dc = rtgui_dc_begin_drawing(caret->owner);
  167. rtgui_dc_blit(caret->dc, &point, hw_dc, &rect);
  168. rtgui_dc_end_drawing(hw_dc);
  169. }
  170. }