apps_list.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #include "apps_list.h"
  2. #include <rtgui/rtgui_app.h>
  3. #include <rtgui/widgets/listctrl.h>
  4. #include "xpm/exec.xpm"
  5. #include "xpm/close.xpm"
  6. /* application manager */
  7. struct rtgui_application_item
  8. {
  9. struct rtgui_app* app;
  10. };
  11. static struct rtgui_application_item *app_items = RT_NULL;
  12. static rt_uint16_t app_count = 0;
  13. static struct rtgui_listctrl* app_list;
  14. static struct rtgui_image* app_default_icon = RT_NULL;
  15. static struct rtgui_image* app_close = RT_NULL;
  16. static void _handle_app_create(struct rtgui_event_application* event)
  17. {
  18. rt_uint32_t index;
  19. rt_int32_t status;
  20. struct rtgui_app* app;
  21. status = RTGUI_STATUS_OK;
  22. for (index = 0; index < app_count; index ++)
  23. {
  24. app = (struct rtgui_app*)app_items[index].app;
  25. if (app == event->app)
  26. {
  27. /* application is created already */
  28. status = RTGUI_STATUS_ERROR;
  29. goto __exit;
  30. }
  31. }
  32. app_count += 1;
  33. if (app_items == RT_NULL)
  34. app_items = (struct rtgui_application_item*) rtgui_malloc(sizeof(struct rtgui_application_item));
  35. else
  36. app_items = (struct rtgui_application_item*) rtgui_realloc(app_items, sizeof(struct rtgui_application_item) * app_count);
  37. if (app_items == RT_NULL)
  38. {
  39. status = RTGUI_STATUS_ERROR;
  40. goto __exit;
  41. }
  42. app = event->app;
  43. app_items[app_count - 1].app = app;
  44. rtgui_listctrl_set_items(app_list, (rt_uint32_t)app_items, app_count);
  45. __exit:
  46. /* send ack to the application */
  47. rtgui_ack(RTGUI_EVENT(event), status);
  48. return;
  49. }
  50. static void _handle_app_destroy(struct rtgui_event_application* event)
  51. {
  52. rt_uint32_t index;
  53. struct rtgui_app* app;
  54. for (index = 0; index < app_count; index ++)
  55. {
  56. app = (struct rtgui_app*)app_items[index].app;
  57. if (app == event->app)
  58. {
  59. /* remove this application */
  60. app_count --;
  61. if (app_count == 0)
  62. {
  63. rtgui_free(app_items);
  64. app_items = RT_NULL;
  65. }
  66. else if (index == app_count)
  67. {
  68. app_items = rtgui_realloc(app_items, app_count * sizeof(struct rtgui_application_item));
  69. }
  70. else
  71. {
  72. rt_uint32_t j;
  73. for (j = index; j < app_count; j ++)
  74. {
  75. app_items[j] = app_items[j + 1];
  76. }
  77. app_items = rtgui_realloc(app_items, app_count * sizeof(struct rtgui_application_item));
  78. }
  79. rtgui_listctrl_set_items(app_list, (rt_uint32_t)app_items, app_count);
  80. rtgui_ack(RTGUI_EVENT(event), RTGUI_STATUS_OK);
  81. return ;
  82. }
  83. }
  84. /* send ack to the application */
  85. rtgui_ack(RTGUI_EVENT(event), RTGUI_STATUS_ERROR);
  86. return;
  87. }
  88. static rt_bool_t _handle_app_activate(struct rtgui_object* object, struct rtgui_event* event)
  89. {
  90. struct rtgui_application_item *item;
  91. if (app_list->current_item == -1) return RT_TRUE;
  92. item = &app_items[app_list->current_item];
  93. rtgui_app_activate(item->app);
  94. return RT_TRUE;
  95. }
  96. rt_bool_t apps_list_event_handler(struct rtgui_object* object, struct rtgui_event* event)
  97. {
  98. RT_ASSERT(object != RT_NULL);
  99. RT_ASSERT(event != RT_NULL);
  100. switch (event->type)
  101. {
  102. case RTGUI_EVENT_APP_CREATE:
  103. _handle_app_create((struct rtgui_event_application*) event);
  104. break;
  105. case RTGUI_EVENT_APP_DESTROY:
  106. _handle_app_destroy((struct rtgui_event_application*) event);
  107. break;
  108. }
  109. return RT_TRUE;
  110. }
  111. static rt_bool_t apps_listctrl_event_handler(struct rtgui_object* object, struct rtgui_event* event)
  112. {
  113. struct rtgui_listctrl* ctrl;
  114. ctrl = RTGUI_LISTCTRL(object);
  115. if (event->type == RTGUI_EVENT_MOUSE_BUTTON)
  116. {
  117. struct rtgui_rect rect, close_rect;
  118. struct rtgui_event_mouse* emouse;
  119. emouse = (struct rtgui_event_mouse*)event;
  120. if (emouse->button & RTGUI_MOUSE_BUTTON_UP)
  121. {
  122. /* get physical extent information */
  123. rtgui_widget_get_extent(RTGUI_WIDGET(ctrl), &rect);
  124. close_rect = rect;
  125. close_rect.x1 = close_rect.x2 - 50;
  126. if ((rtgui_rect_contains_point(&close_rect, emouse->x, emouse->y) == RT_EOK) &&
  127. (ctrl->items_count > 0))
  128. {
  129. rt_uint16_t index;
  130. index = (emouse->y - rect.y1) / (2 + ctrl->item_height);
  131. if ((index < ctrl->page_items) &&
  132. (ctrl->current_item/ctrl->page_items)* ctrl->page_items + index < ctrl->items_count)
  133. {
  134. rt_uint16_t cur_item;
  135. /* get current item */
  136. cur_item = (ctrl->current_item/ctrl->page_items) * ctrl->page_items + index;
  137. if (cur_item == ctrl->current_item)
  138. {
  139. rt_kprintf("close app\n");
  140. rtgui_app_close(app_items[ctrl->current_item].app);
  141. return RT_TRUE;
  142. }
  143. }
  144. }
  145. }
  146. }
  147. return rtgui_listctrl_event_handler(object, event);
  148. }
  149. static void _app_info_draw(struct rtgui_listctrl *list, struct rtgui_dc* dc, rtgui_rect_t* rect, rt_uint16_t index)
  150. {
  151. struct rtgui_image *image;
  152. rtgui_rect_t item_rect, image_rect;
  153. struct rtgui_application_item *item, *items;
  154. item_rect = *rect;
  155. item_rect.x1 += 5;
  156. /* draw item */
  157. items = (struct rtgui_application_item*)list->items;
  158. item = &items[index];
  159. /* draw image */
  160. if (item->app->icon != RT_NULL) image = item->app->icon;
  161. else image = app_default_icon;
  162. if (image != RT_NULL)
  163. {
  164. image_rect.x1 = image_rect.y1 = 0;
  165. image_rect.x2 = app_default_icon->w;
  166. image_rect.y2 = app_default_icon->h;
  167. rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
  168. rtgui_image_blit(image, dc, &image_rect);
  169. }
  170. item_rect.x1 += app_default_icon->w + RTGUI_WIDGET_DEFAULT_MARGIN;
  171. /* draw text */
  172. rtgui_dc_draw_text(dc, (const char*)item->app->name, &item_rect); item_rect.x1 += 60;
  173. if (list->current_item == index)
  174. {
  175. /* draw close button */
  176. image_rect.x1 = image_rect.y1 = 0;
  177. image_rect.x2 = app_close->w;
  178. image_rect.y2 = app_close->h;
  179. item_rect.x1 = item_rect.x2 - 50;
  180. rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
  181. rtgui_image_blit(app_close, dc, &image_rect);
  182. }
  183. }
  184. struct rtgui_panel* apps_list_create(struct rtgui_panel* panel)
  185. {
  186. struct rtgui_rect rect;
  187. RT_ASSERT(panel != RT_NULL);
  188. if (app_default_icon == RT_NULL)
  189. {
  190. app_default_icon = rtgui_image_create_from_mem("xpm", (const rt_uint8_t*)exec_xpm, sizeof(exec_xpm), RT_FALSE);
  191. }
  192. if (app_close == RT_NULL)
  193. {
  194. app_close = rtgui_image_create_from_mem("xpm", (const rt_uint8_t *)close_xpm, sizeof(close_xpm), RT_FALSE);
  195. }
  196. rtgui_widget_get_extent(RTGUI_WIDGET(panel), &rect);
  197. /* create application list */
  198. rtgui_rect_inflate(&rect, -15);
  199. app_list = rtgui_listctrl_create((rt_uint32_t)app_items, app_count, &rect, _app_info_draw);
  200. rtgui_listctrl_set_itemheight(app_list, app_default_icon->h + 2);
  201. rtgui_listctrl_set_onitem(app_list, _handle_app_activate);
  202. rtgui_object_set_event_handler(RTGUI_OBJECT(app_list), apps_listctrl_event_handler);
  203. rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(app_list));
  204. return RTGUI_PANEL(panel);
  205. }
  206. #ifdef RT_USING_FINSH
  207. #include <finsh.h>
  208. void list_apps(void)
  209. {
  210. rt_uint32_t index;
  211. struct rtgui_app* app;
  212. rt_kprintf("GUI Applications:\n");
  213. rt_kprintf("=================\n");
  214. for (index = 0; index < app_count; index ++)
  215. {
  216. app = (struct rtgui_app*) app_items[index].app;
  217. rt_kprintf("%s\n", app->name);
  218. }
  219. }
  220. FINSH_FUNCTION_EXPORT(list_apps,show the application list);
  221. #endif