toplevel.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*
  2. * File : toplevel.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/rtgui_system.h>
  15. #include <rtgui/widgets/toplevel.h>
  16. static void _rtgui_toplevel_constructor(rtgui_toplevel_t *toplevel)
  17. {
  18. /* set event handler */
  19. rtgui_widget_set_event_handler(RTGUI_WIDGET(toplevel), rtgui_toplevel_event_handler);
  20. /* set toplevel to self */
  21. RTGUI_WIDGET(toplevel)->toplevel = RTGUI_WIDGET(toplevel);
  22. /* init toplevel property */
  23. toplevel->drawing = 0;
  24. toplevel->external_clip_rect = RT_NULL;
  25. toplevel->external_clip_size = 0;
  26. /* hide toplevel default */
  27. RTGUI_WIDGET_HIDE(RTGUI_WIDGET(toplevel));
  28. /* set server as RT_NULL (no connected) */
  29. toplevel->server = RT_NULL;
  30. }
  31. static void _rtgui_toplevel_destructor(rtgui_toplevel_t* toplevel)
  32. {
  33. /* release external clip info */
  34. rtgui_free(toplevel->external_clip_rect);
  35. toplevel->drawing = 0;
  36. rtgui_free(toplevel->external_clip_rect);
  37. toplevel->external_clip_rect = RT_NULL;
  38. toplevel->external_clip_size = 0;
  39. }
  40. rtgui_type_t *rtgui_toplevel_type_get(void)
  41. {
  42. static rtgui_type_t *toplevel_type = RT_NULL;
  43. if (!toplevel_type)
  44. {
  45. toplevel_type = rtgui_type_create("toplevel", RTGUI_CONTAINER_TYPE,
  46. sizeof(rtgui_toplevel_t),
  47. RTGUI_CONSTRUCTOR(_rtgui_toplevel_constructor),
  48. RTGUI_DESTRUCTOR(_rtgui_toplevel_destructor));
  49. }
  50. return toplevel_type;
  51. }
  52. rt_bool_t rtgui_toplevel_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
  53. {
  54. rtgui_toplevel_t* toplevel = (rtgui_toplevel_t*)widget;
  55. switch (event->type)
  56. {
  57. case RTGUI_EVENT_KBD:
  58. if (RTGUI_CONTAINER(toplevel)->focused != RT_NULL)
  59. {
  60. RTGUI_CONTAINER(toplevel)->focused->event_handler(RTGUI_CONTAINER(toplevel)->focused, event);
  61. }
  62. break;
  63. case RTGUI_EVENT_CLIP_INFO:
  64. /* set toplevel external clip info */
  65. rtgui_toplevel_handle_clip(toplevel, (struct rtgui_event_clip_info*)event);
  66. /* update toplevel clip */
  67. rtgui_toplevel_update_clip(toplevel);
  68. break;
  69. case RTGUI_EVENT_TIMER:
  70. {
  71. struct rtgui_timer* timer;
  72. struct rtgui_event_timer* etimer = (struct rtgui_event_timer*) event;
  73. timer = etimer->timer;
  74. if (timer->timeout != RT_NULL)
  75. {
  76. /* call timeout function */
  77. timer->timeout(timer, timer->user_data);
  78. }
  79. }
  80. break;
  81. case RTGUI_EVENT_COMMAND:
  82. if (rtgui_container_dispatch_event(RTGUI_CONTAINER(widget), event) != RT_TRUE)
  83. {
  84. #ifndef RTGUI_USING_SMALL_SIZE
  85. if (widget->on_command != RT_NULL)
  86. {
  87. widget->on_command(widget, event);
  88. }
  89. #endif
  90. }
  91. else return RT_TRUE;
  92. break;
  93. default :
  94. return rtgui_container_event_handler(widget, event);
  95. }
  96. return RT_FALSE;
  97. }
  98. void rtgui_toplevel_handle_clip(struct rtgui_toplevel* top,
  99. struct rtgui_event_clip_info* info)
  100. {
  101. RT_ASSERT(top != RT_NULL);
  102. RT_ASSERT(info != RT_NULL);
  103. /* release old rect array */
  104. if (top->external_clip_size != 0)
  105. {
  106. rtgui_free(top->external_clip_rect);
  107. top->external_clip_rect = RT_NULL;
  108. top->external_clip_size = 0;
  109. }
  110. /* no rect info */
  111. if (info->num_rect == 0) return;
  112. top->external_clip_rect = (rtgui_rect_t*) rtgui_malloc(sizeof(rtgui_rect_t) *
  113. info->num_rect);
  114. top->external_clip_size = info->num_rect;
  115. #ifdef RTGUI_USING_SMALL_SIZE
  116. {
  117. extern void rtgui_topwin_get_clipinfo(struct rtgui_rect* list, rt_int32_t count);
  118. /* get rect list from topwin list */
  119. rtgui_topwin_get_clipinfo(top->external_clip_rect, top->external_clip_size);
  120. }
  121. #else
  122. /* copy rect array */
  123. rt_memcpy(top->external_clip_rect, (void*)(info + 1), sizeof(rtgui_rect_t) * info->num_rect);
  124. #endif
  125. }
  126. #include <rtgui/driver.h> /* to get screen rect */
  127. void rtgui_toplevel_update_clip(rtgui_toplevel_t* top)
  128. {
  129. rt_uint32_t idx;
  130. rtgui_container_t* container;
  131. struct rtgui_list_node* node;
  132. rtgui_rect_t screen_rect;
  133. if (top == RT_NULL) return;
  134. /* reset toplevel widget clip to extent */
  135. rtgui_region_reset(&(RTGUI_WIDGET(top)->clip), &(RTGUI_WIDGET(top)->extent));
  136. #ifndef RTGUI_USING_SMALL_SIZE
  137. RTGUI_WIDGET(top)->clip_sync ++;
  138. #endif
  139. /* subtract the screen rect */
  140. screen_rect.x1 = screen_rect.y1 = 0;
  141. screen_rect.x2 = rtgui_graphic_driver_get_default()->width;
  142. screen_rect.y2 = rtgui_graphic_driver_get_default()->height;
  143. rtgui_region_intersect_rect(&(RTGUI_WIDGET(top)->clip), &(RTGUI_WIDGET(top)->clip),
  144. &screen_rect);
  145. /* subtract the external rect */
  146. for (idx = 0; idx < top->external_clip_size; idx ++)
  147. {
  148. rtgui_region_subtract_rect(&(RTGUI_WIDGET(top)->clip), &(RTGUI_WIDGET(top)->clip),
  149. &(top->external_clip_rect[idx]));
  150. }
  151. /* update the clip info of each child */
  152. container = RTGUI_CONTAINER(top);
  153. rtgui_list_foreach(node, &(container->children))
  154. {
  155. rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
  156. rtgui_widget_update_clip(child);
  157. }
  158. }