widget.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. /*
  2. * File : widget.c
  3. * This file is part of RTGUI in 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-04 Bernard first version
  13. */
  14. #include <rtgui/dc_client.h>
  15. #include <rtgui/widgets/widget.h>
  16. #include <rtgui/widgets/label.h>
  17. #include <rtgui/widgets/window.h>
  18. #include <rtgui/widgets/combobox.h>
  19. #include <rtgui/widgets/view.h>
  20. #include <rtgui/widgets/listbox.h>
  21. #include <panel.h>
  22. #include <rtgui/dc.h>
  23. #include <topwin.h>
  24. static void _rtgui_widget_constructor(PVOID wdt)
  25. {
  26. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  27. if(!widget) return;
  28. /* set default flag */
  29. widget->flag = RTGUI_WIDGET_FLAG_DEFAULT;
  30. /* init list */
  31. rtgui_list_init(&(widget->sibling));
  32. /* init gc */
  33. widget->gc.foreground = default_foreground;
  34. widget->gc.background = default_background;
  35. widget->gc.font = rtgui_font_default();
  36. widget->gc.textstyle = RTGUI_TEXTSTYLE_NORMAL;
  37. widget->gc.textalign = RTGUI_ALIGN_CENTER_HORIZONTAL|RTGUI_ALIGN_CENTER_VERTICAL;
  38. #ifndef RTGUI_USING_SMALL_SIZE
  39. widget->align = RTGUI_ALIGN_CENTER_VERTICAL;
  40. #endif
  41. rtgui_widget_set_style(widget,RTGUI_BORDER_SUNKEN);
  42. widget->tab_index = 0;
  43. widget->tab_stop = RT_FALSE;
  44. /* set parent and toplevel */
  45. widget->parent = RT_NULL;
  46. widget->toplevel = RT_NULL;
  47. /* some common event handler */
  48. widget->on_focus_in = RT_NULL;
  49. widget->on_focus_out = RT_NULL;
  50. widget->on_draw = RT_NULL;
  51. widget->on_mouseclick = RT_NULL;
  52. widget->on_key = RT_NULL;
  53. widget->on_size = RT_NULL;
  54. widget->on_command = RT_NULL;
  55. /* set default event handler */
  56. rtgui_widget_set_event_handler(widget,rtgui_widget_event_handler);
  57. /* init user data private to 0 */
  58. widget->user_data = 0;
  59. /* init clip information */
  60. rtgui_region_init(&(widget->clip));
  61. /* init hardware dc */
  62. rtgui_dc_client_init(widget);
  63. }
  64. /* Destroys the widget */
  65. static void _rtgui_widget_destructor(PVOID wdt)
  66. {
  67. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  68. if(widget == RT_NULL) return;
  69. if(widget->parent != RT_NULL)
  70. {
  71. /* remove widget from parent's child list */
  72. rtgui_list_remove(&(RTGUI_CONTAINER(widget->parent)->children), &(widget->sibling));
  73. widget->parent = RT_NULL;
  74. }
  75. /* fini clip region */
  76. rtgui_region_fini(&(widget->clip));
  77. }
  78. rtgui_type_t *rtgui_widget_type_get(void)
  79. {
  80. static rtgui_type_t *widget_type = RT_NULL;
  81. if(!widget_type)
  82. {
  83. widget_type = rtgui_type_create("rtgui_widget", RTGUI_OBJECT_TYPE,
  84. sizeof(rtgui_widget_t),
  85. RTGUI_CONSTRUCTOR(_rtgui_widget_constructor),
  86. RTGUI_DESTRUCTOR(_rtgui_widget_destructor));
  87. }
  88. return widget_type;
  89. }
  90. PVOID rtgui_widget_create(rtgui_type_t *widget_type)
  91. {
  92. PVOID widget;
  93. widget = rtgui_object_create(widget_type);
  94. return widget;
  95. }
  96. void rtgui_widget_destroy(PVOID wdt)
  97. {
  98. rtgui_object_destroy(RTGUI_OBJECT(wdt));
  99. }
  100. void rtgui_widget_set_rect(PVOID wht, rtgui_rect_t* rect)
  101. {
  102. rtgui_widget_t *widget = (rtgui_widget_t*)wht;
  103. if(widget == RT_NULL || rect == RT_NULL) return;
  104. widget->extent = *rect;
  105. /* it's not empty, fini it */
  106. if(rtgui_region_not_empty(&(widget->clip)))
  107. {
  108. rtgui_region_fini(&(widget->clip));
  109. }
  110. /* reset clip info */
  111. rtgui_region_init_with_extents(&(widget->clip), rect);
  112. if((widget->parent != RT_NULL) && (widget->toplevel != RT_NULL))
  113. {
  114. /* update widget clip */
  115. rtgui_widget_update_clip(widget->parent);
  116. }
  117. }
  118. //设置控件的外观样式
  119. void rtgui_widget_set_style(PVOID wdt, rt_uint32_t style)
  120. {
  121. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  122. RT_ASSERT(widget != RT_NULL);
  123. widget->border_style = style;
  124. switch(style)
  125. {
  126. case RTGUI_BORDER_NONE:
  127. widget->border = 0;
  128. break;
  129. case RTGUI_BORDER_STATIC:
  130. case RTGUI_BORDER_SIMPLE:
  131. case RTGUI_BORDER_UP:
  132. case RTGUI_BORDER_DOWN:
  133. widget->border = 1;
  134. break;
  135. case RTGUI_BORDER_RAISE:
  136. case RTGUI_BORDER_SUNKEN:
  137. case RTGUI_BORDER_BOX:
  138. case RTGUI_BORDER_EXTRA:
  139. widget->border = 2;
  140. break;
  141. default:
  142. widget->border = 2;
  143. break;
  144. }
  145. }
  146. /*
  147. * 这个函数移动控件和它的子控件到一个逻辑点
  148. */
  149. void rtgui_widget_move_to_logic(PVOID wdt, int dx, int dy)
  150. {
  151. rtgui_list_t* node;
  152. rtgui_widget_t* child;
  153. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  154. if(widget == RT_NULL) return;
  155. rtgui_rect_moveto(&(widget->extent), dx, dy);
  156. /* move each child */
  157. if(RTGUI_IS_CONTAINER(widget))
  158. {
  159. rtgui_list_foreach(node, &(RTGUI_CONTAINER(widget)->children))
  160. {
  161. child = rtgui_list_entry(node, rtgui_widget_t, sibling);
  162. rtgui_widget_move_to_logic(child, dx, dy);
  163. }
  164. }
  165. }
  166. void rtgui_widget_set_event_handler(PVOID wdt, rtgui_event_handler_ptr handler)
  167. {
  168. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  169. RT_ASSERT(widget != RT_NULL);
  170. RTGUI_WIDGET_EVENT_HANDLE(widget) = handler;
  171. }
  172. //返回绝对坐标的rect区域
  173. void rtgui_widget_get_rect(PVOID wdt, rtgui_rect_t *rect)
  174. {
  175. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  176. RT_ASSERT(widget != RT_NULL);
  177. if (rect != RT_NULL)
  178. {
  179. rect->x1 = rect->y1 = 0;
  180. rect->x2 = widget->extent.x2 - widget->extent.x1;
  181. rect->y2 = widget->extent.y2 - widget->extent.y1;
  182. }
  183. }
  184. void rtgui_widget_get_position(PVOID wdt, rtgui_point_t *p)
  185. {
  186. rtgui_rect_t rect,parent_rect;
  187. RT_ASSERT(wdt != RT_NULL && RTGUI_WIDGET_PARENT(wdt) != RT_NULL);
  188. rtgui_widget_get_rect(wdt, &rect);
  189. rtgui_widget_rect_to_device(wdt,&rect);
  190. rtgui_widget_get_rect(RTGUI_WIDGET_PARENT(wdt), &parent_rect);
  191. rtgui_widget_rect_to_device(RTGUI_WIDGET_PARENT(wdt),&parent_rect);
  192. p->x = rect.x1 - parent_rect.x1;
  193. p->y = rect.y1 - parent_rect.y1;
  194. }
  195. rt_uint16_t rtgui_widget_get_width(PVOID wdt)
  196. {
  197. rtgui_rect_t rect={0};
  198. RT_ASSERT(wdt != RT_NULL);
  199. rtgui_widget_get_rect(wdt, &rect);
  200. return rtgui_rect_width(rect);
  201. }
  202. rt_uint16_t rtgui_widget_get_height(PVOID wdt)
  203. {
  204. rtgui_rect_t rect={0};
  205. RT_ASSERT(wdt != RT_NULL);
  206. rtgui_widget_get_rect(wdt, &rect);
  207. return rtgui_rect_height(rect);
  208. }
  209. void rtgui_widget_set_onfocus(PVOID wdt, rtgui_event_handler_ptr handler)
  210. {
  211. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  212. RT_ASSERT(widget != RT_NULL);
  213. widget->on_focus_in = handler;
  214. }
  215. void rtgui_widget_set_onunfocus(PVOID wdt, rtgui_event_handler_ptr handler)
  216. {
  217. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  218. RT_ASSERT(widget != RT_NULL);
  219. widget->on_focus_out = handler;
  220. }
  221. void rtgui_widget_set_ondraw(PVOID wdt, rtgui_event_handler_ptr handler)
  222. {
  223. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  224. RT_ASSERT(widget != RT_NULL);
  225. widget->on_draw = handler;
  226. }
  227. void rtgui_widget_set_onmouseclick(PVOID wdt, rtgui_event_handler_ptr handler)
  228. {
  229. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  230. RT_ASSERT(widget != RT_NULL);
  231. widget->on_mouseclick = handler;
  232. }
  233. void rtgui_widget_set_onkey(PVOID wdt, rtgui_event_handler_ptr handler)
  234. {
  235. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  236. RT_ASSERT(widget != RT_NULL);
  237. widget->on_key = handler;
  238. }
  239. void rtgui_widget_set_onsize(PVOID wdt, rtgui_event_handler_ptr handler)
  240. {
  241. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  242. RT_ASSERT(widget != RT_NULL);
  243. widget->on_size = handler;
  244. }
  245. void rtgui_widget_set_oncommand(PVOID wdt, rtgui_event_handler_ptr handler)
  246. {
  247. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  248. RT_ASSERT(widget != RT_NULL);
  249. widget->on_command = handler;
  250. }
  251. /**
  252. * find wdt's toplevel widget and return toplevel focused
  253. */
  254. PVOID rtgui_widget_get_focus(PVOID wdt)
  255. {
  256. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  257. rtgui_widget_t *top;
  258. if(widget == RT_NULL)return RT_NULL;
  259. top = rtgui_widget_get_toplevel(widget);
  260. if(RTGUI_IS_CONTAINER(top))
  261. return RTGUI_CONTAINER(top)->focused;
  262. return RT_NULL;
  263. }
  264. /**
  265. * @brief Focuses the widget. The focused widget is the widget which can receive the keyboard events
  266. * @param widget a widget
  267. * @note The widget has to be attached to a top widget, otherwise it will have no effect
  268. */
  269. void rtgui_widget_focus(PVOID wdt)
  270. {
  271. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  272. rtgui_container_t *parent;
  273. if(widget == RT_NULL)return;
  274. if(!widget->parent || !widget->toplevel) return;
  275. if(!RTGUI_WIDGET_IS_FOCUSABLE(widget) || !RTGUI_WIDGET_IS_ENABLE(widget))
  276. return;
  277. /* set widget as focused */
  278. widget->flag |= RTGUI_WIDGET_FLAG_FOCUS;
  279. /* 取得旧的根控件和焦点控件 */
  280. parent = RTGUI_CONTAINER(widget->toplevel);
  281. if(parent->focused == widget) return; /* it's the same focused widget */
  282. /* unfocused the old widget */
  283. if((parent->focused != RT_NULL) && !RTGUI_IS_WIN(parent->focused))
  284. rtgui_widget_unfocus(parent->focused);
  285. /* set widget as focused widget in parent link */
  286. parent = RTGUI_CONTAINER(widget->parent);
  287. do
  288. {
  289. parent->focused = widget;
  290. parent = RTGUI_CONTAINER(RTGUI_WIDGET_PARENT(parent));
  291. } while((parent != RT_NULL) && !RTGUI_WIDGET_IS_HIDE(parent));
  292. /* invoke on focus in call back */
  293. if(widget->on_focus_in != RT_NULL)
  294. widget->on_focus_in(widget, RT_NULL);
  295. }
  296. /**
  297. * @brief Unfocused the widget
  298. * @param widget a widget
  299. */
  300. void rtgui_widget_unfocus(PVOID wdt)
  301. {
  302. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  303. if(widget == RT_NULL)return;
  304. if(!widget->toplevel || !RTGUI_WIDGET_IS_FOCUSED(widget))
  305. return;
  306. widget->flag &= ~RTGUI_WIDGET_FLAG_FOCUS;
  307. if(widget->on_focus_out != RT_NULL)
  308. widget->on_focus_out(widget, RT_NULL);
  309. if(RTGUI_IS_CONTAINER(widget))
  310. {
  311. rtgui_list_t *node;
  312. rtgui_list_foreach(node,&(RTGUI_CONTAINER(widget)->children))
  313. {
  314. rtgui_widget_t *child = rtgui_list_entry(node, rtgui_widget_t, sibling);
  315. if(RTGUI_WIDGET_IS_HIDE(child))continue;
  316. rtgui_widget_unfocus(child);
  317. }
  318. }
  319. /* refresh widget 刷新控件 */
  320. //rtgui_widget_update(widget);//要除去该句,避免重复刷新
  321. }
  322. void rtgui_widget_point_to_device(PVOID wdt, rtgui_point_t* point)
  323. {
  324. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  325. RT_ASSERT(widget != RT_NULL);
  326. if(point != RT_NULL)
  327. {
  328. point->x += widget->extent.x1;
  329. point->y += widget->extent.y1;
  330. }
  331. }
  332. void rtgui_widget_rect_to_device(PVOID wdt, rtgui_rect_t* rect)
  333. {
  334. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  335. RT_ASSERT(widget != RT_NULL);
  336. if(rect != RT_NULL)
  337. {
  338. rect->x1 += widget->extent.x1;
  339. rect->x2 += widget->extent.x1;
  340. rect->y1 += widget->extent.y1;
  341. rect->y2 += widget->extent.y1;
  342. }
  343. }
  344. void rtgui_widget_point_to_logic(PVOID wdt, rtgui_point_t* point)
  345. {
  346. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  347. RT_ASSERT(widget != RT_NULL);
  348. if(point != RT_NULL)
  349. {
  350. point->x -= widget->extent.x1;
  351. point->y -= widget->extent.y1;
  352. }
  353. }
  354. void rtgui_widget_rect_to_logic(PVOID wdt, rtgui_rect_t* rect)
  355. {
  356. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  357. RT_ASSERT(widget != RT_NULL);
  358. if(rect != RT_NULL)
  359. {
  360. rect->x1 -= widget->extent.x1;
  361. rect->x2 -= widget->extent.x1;
  362. rect->y1 -= widget->extent.y1;
  363. rect->y2 -= widget->extent.y1;
  364. }
  365. }
  366. PVOID rtgui_widget_get_toplevel(PVOID wdt)
  367. {
  368. rtgui_widget_t *top;
  369. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  370. RT_ASSERT(widget != RT_NULL);
  371. if(widget->toplevel)
  372. return (PVOID)(widget->toplevel);
  373. top = widget;
  374. /* get the top widget */
  375. while(top->parent != RT_NULL) top = top->parent;
  376. /* set top */
  377. widget->toplevel = top;
  378. return top;
  379. }
  380. rt_bool_t rtgui_widget_event_handler(PVOID wdt, rtgui_event_t* event)
  381. {
  382. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  383. switch (event->type)
  384. {
  385. case RTGUI_EVENT_PAINT:
  386. if(widget->on_draw != RT_NULL) return widget->on_draw(widget, event);
  387. break;
  388. case RTGUI_EVENT_KBD:
  389. if(widget->on_key != RT_NULL) return widget->on_key(widget, event);
  390. break;
  391. case RTGUI_EVENT_MOUSE_BUTTON:
  392. if(widget->on_mouseclick != RT_NULL) return widget->on_mouseclick(widget, event);
  393. break;
  394. case RTGUI_EVENT_COMMAND:
  395. if(widget->on_command != RT_NULL) return widget->on_command(widget, event);
  396. break;
  397. case RTGUI_EVENT_RESIZE:
  398. if(widget->on_size != RT_NULL) return widget->on_size(widget, event);
  399. break;
  400. }
  401. return RT_FALSE;
  402. }
  403. /*
  404. * This function updates the clip info of widget
  405. */
  406. void rtgui_widget_update_clip(PVOID wdt)
  407. {
  408. rtgui_list_t *node;
  409. rtgui_widget_t *parent;
  410. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  411. /* no widget or widget is hide, no update clip */
  412. if(widget == RT_NULL || RTGUI_WIDGET_IS_HIDE(widget)) return;
  413. parent = widget->parent;
  414. /* if there is no parent, do not update clip (please use toplevel widget API) */
  415. if(parent == RT_NULL)
  416. {
  417. rtgui_panel_t *panel = rtgui_panel_get();
  418. rtgui_panel_update_clip(panel);
  419. return;
  420. }
  421. /* reset clip to extent */
  422. rtgui_region_reset(&(widget->clip), &(widget->extent));
  423. /* limit widget extent in screen extent */
  424. //rtgui_region_intersect(&(widget->clip), &(widget->clip), &(parent->clip));
  425. {
  426. rtgui_rect_t screen_rect;
  427. rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),&screen_rect);
  428. //rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &(parent->clip.extents));
  429. rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &screen_rect);
  430. }
  431. /* get the no transparent parent */
  432. while (parent != RT_NULL && parent->flag & RTGUI_WIDGET_FLAG_TRANSPARENT)
  433. {
  434. parent = parent->parent;
  435. }
  436. if (parent != RT_NULL)
  437. {
  438. /* subtract widget clip in parent clip */
  439. if (!(widget->flag & RTGUI_WIDGET_FLAG_TRANSPARENT))
  440. {
  441. rtgui_region_subtract_rect(&(parent->clip), &(parent->clip),
  442. &(widget->extent));
  443. }
  444. }
  445. /*
  446. * note: since the layout widget introduction, the sibling widget will not
  447. * intersect.
  448. */
  449. /* if it's a container object, update the clip info of children */
  450. if (RTGUI_IS_CONTAINER(widget))
  451. {
  452. rtgui_widget_t* child;
  453. rtgui_list_foreach(node, &(RTGUI_CONTAINER(widget)->children))
  454. {
  455. child = rtgui_list_entry(node, rtgui_widget_t, sibling);
  456. if (RTGUI_WIDGET_IS_HIDE(child)) continue;
  457. rtgui_widget_update_clip(child);
  458. }
  459. }
  460. }
  461. /*
  462. * 更新多个控件重叠时的clip剪切情况,将子控件topwdt作为最顶端控件,
  463. * 它的兄弟控件则相应的剪切掉topwdt区域,使它们从位置上被topwdt覆盖
  464. * 调用该函数时,应该保证topwdt控件是wdt控件下的一个子控件.
  465. */
  466. void rtgui_widget_update_clip_pirate(PVOID wdt,PVOID topwdt)
  467. {
  468. rtgui_list_t *node;
  469. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  470. rtgui_rect_t wdt_rect;
  471. if(widget == RT_NULL || RTGUI_WIDGET_IS_HIDE(widget)) return;
  472. wdt_rect = widget->extent;
  473. if(wdt == topwdt)
  474. { /* the same as oneself */
  475. rtgui_widget_update_clip(widget);
  476. return;
  477. }
  478. else
  479. { /* different widget */
  480. if(rtgui_rect_is_intersect(&RTGUI_WIDGET_EXTENT(topwdt), &wdt_rect) == RT_EOK)
  481. {
  482. rtgui_rect_intersect(&RTGUI_WIDGET_EXTENT(topwdt), &wdt_rect);/* calculate overlap */
  483. rtgui_region_reset(&(widget->clip), &(widget->extent));
  484. rtgui_region_subtract_rect(&(widget->clip), &(widget->clip),&wdt_rect);/* subtract overlap area */
  485. }
  486. else
  487. {
  488. rtgui_region_reset(&(widget->clip), &(widget->extent));
  489. }
  490. }
  491. {
  492. rtgui_rect_t screen_rect;
  493. rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),&screen_rect);
  494. rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &screen_rect);
  495. }
  496. if(RTGUI_IS_CONTAINER(widget))
  497. { /* update all child widget */
  498. rtgui_list_foreach(node, &(RTGUI_CONTAINER(widget)->children))
  499. {
  500. rtgui_widget_t *child = rtgui_list_entry(node, rtgui_widget_t, sibling);
  501. if(RTGUI_WIDGET_IS_HIDE(child))continue;
  502. if(RTGUI_IS_WIN(child))continue; /* no dispose windows */
  503. rtgui_region_subtract_rect(&(widget->clip), &(widget->clip),&(child->extent));
  504. rtgui_widget_update_clip_pirate(child,topwdt);
  505. }
  506. }
  507. }
  508. void rtgui_widget_show(PVOID wdt)
  509. {
  510. /* there is no parent or the parent is hide, no show at all */
  511. if(RTGUI_WIDGET_PARENT(wdt) == RT_NULL ||RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET_PARENT(wdt))) return;
  512. /* update the clip info of widget */
  513. RTGUI_WIDGET_UNHIDE(wdt);
  514. rtgui_widget_update_clip(wdt);
  515. }
  516. void rtgui_widget_hide(PVOID wdt)
  517. {
  518. rtgui_rect_t rect;
  519. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  520. /* hide this widget */
  521. RTGUI_WIDGET_HIDE(widget);
  522. if (widget->parent != RT_NULL)
  523. {
  524. int index;
  525. rtgui_widget_t *parent;
  526. rect = widget->extent;
  527. parent = widget->parent;
  528. /* get the no transparent parent */
  529. while (parent != RT_NULL && parent->flag & RTGUI_WIDGET_FLAG_TRANSPARENT)
  530. {
  531. parent = parent->parent;
  532. }
  533. /* union widget rect */
  534. rtgui_region_union_rect(&(widget->parent->clip), &(widget->parent->clip), &rect);
  535. /* subtract the external rect */
  536. for (index = 0; index < external_clip_size; index ++)
  537. {
  538. rtgui_region_subtract_rect(&(widget->parent->clip), &(widget->parent->clip),
  539. &(external_clip_rect[index]));
  540. }
  541. }
  542. }
  543. rtgui_color_t rtgui_widget_get_parent_foreground(PVOID wdt)
  544. {
  545. rtgui_widget_t* parent;
  546. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  547. /* get parent widget */
  548. parent = widget->parent;
  549. while (parent->parent != RT_NULL && (RTGUI_WIDGET_FLAG(parent) & RTGUI_WIDGET_FLAG_TRANSPARENT))
  550. parent = parent->parent;
  551. /* get parent's color */
  552. if (parent != RT_NULL)
  553. return RTGUI_WIDGET_FOREGROUND(parent);
  554. return RTGUI_WIDGET_FOREGROUND(widget);
  555. }
  556. rtgui_color_t rtgui_widget_get_parent_background(PVOID wdt)
  557. {
  558. rtgui_widget_t* parent;
  559. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  560. /* get parent widget */
  561. parent = widget->parent;
  562. while (parent->parent != RT_NULL && (RTGUI_WIDGET_FLAG(parent) & RTGUI_WIDGET_FLAG_TRANSPARENT))
  563. parent = parent->parent;
  564. /* get parent's color */
  565. if (parent != RT_NULL)
  566. return RTGUI_WIDGET_BACKGROUND(parent);
  567. return RTGUI_WIDGET_BACKGROUND(widget);
  568. }
  569. void rtgui_widget_update(PVOID wdt)
  570. {
  571. rtgui_event_paint_t paint;
  572. if(RTGUI_WIDGET_IS_HIDE(wdt)) return;
  573. RTGUI_EVENT_PAINT_INIT(&paint);
  574. paint.wid = RT_NULL;
  575. RT_ASSERT(wdt != RT_NULL);
  576. if(RTGUI_WIDGET_EVENT_HANDLE(wdt) != RT_NULL)
  577. {
  578. RTGUI_WIDGET_EVENT_CALL(wdt, &paint.parent);
  579. }
  580. }
  581. //获得下一个兄弟控件
  582. rtgui_widget_t* rtgui_widget_get_next_sibling(PVOID wdt)
  583. {
  584. rtgui_widget_t* sibling = RT_NULL;
  585. rtgui_widget_t* widget = wdt;
  586. if(widget->sibling.next != RT_NULL)
  587. {
  588. sibling = rtgui_list_entry(widget->sibling.next, rtgui_widget_t, sibling);
  589. }
  590. return sibling;
  591. }
  592. //获得上一个兄弟控件
  593. rtgui_widget_t* rtgui_widget_get_prev_sibling(PVOID wdt)
  594. {
  595. rtgui_list_t* node;
  596. rtgui_widget_t *sibling, *parent;
  597. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  598. node = RT_NULL; sibling = RT_NULL;
  599. parent = widget->parent;
  600. if(parent != RT_NULL)
  601. {
  602. rtgui_list_foreach(node, &(RTGUI_CONTAINER(parent)->children))
  603. {
  604. if(node->next == &(widget->sibling))
  605. break;
  606. }
  607. }
  608. if(node != RT_NULL)
  609. sibling = rtgui_list_entry(node, rtgui_widget_t, sibling);
  610. return sibling;
  611. }