window.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. /*
  2. * File : window.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.h>
  15. #include <rtgui/color.h>
  16. #include <rtgui/image.h>
  17. #include <rtgui/rtgui_system.h>
  18. #include <panel.h>
  19. #include <rtgui/widgets/window.h>
  20. #include <rtgui/widgets/button.h>
  21. #include <rtgui/rtgui_theme.h>
  22. static void _rtgui_win_constructor(rtgui_win_t *win)
  23. {
  24. /* init window attribute */
  25. win->title = RT_NULL;
  26. win->on_activate = RT_NULL;
  27. win->on_deactivate = RT_NULL;
  28. win->on_close = RT_NULL;
  29. win->modal_widget = RT_NULL;
  30. win->tid = RT_NULL;
  31. /* set window hide */
  32. RTGUI_WIDGET_HIDE(win);
  33. RTGUI_WIDGET_FLAG(win) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
  34. RTGUI_WIDGET_BACKGROUND(win) = default_background;
  35. /* set window status and style */
  36. win->status = 0;
  37. win->style = RTGUI_WIN_DEFAULT;
  38. rtgui_widget_set_event_handler(win, rtgui_win_event_handler);
  39. /* init user data */
  40. win->user_data = RT_NULL;
  41. }
  42. static void _rtgui_win_destructor(rtgui_win_t* win)
  43. {
  44. rtgui_event_win_t ewin;
  45. /* remove win from box */
  46. if(RTGUI_WIDGET_PARENT(win) != RT_NULL)
  47. {
  48. rtgui_container_t *box;
  49. box = RTGUI_CONTAINER(RTGUI_WIDGET_PARENT(win));
  50. rtgui_container_remove_child(box, win);
  51. }
  52. /* destroy in server */
  53. RTGUI_EVENT_WIN_DESTROY_INIT(&ewin);
  54. ewin.wid = win;
  55. if(rtgui_thread_send_sync(rtgui_thread_get_server(), RTGUI_EVENT(&ewin),sizeof(rtgui_event_win_t)) != RT_EOK)
  56. {
  57. return; /* destroy in server failed */
  58. }
  59. /* release field */
  60. rt_free(win->title);
  61. }
  62. rtgui_type_t *rtgui_win_type_get(void)
  63. {
  64. static rtgui_type_t *win_type = RT_NULL;
  65. if(!win_type)
  66. {
  67. win_type = rtgui_type_create("win", RTGUI_CONTAINER_TYPE,
  68. sizeof(rtgui_win_t),
  69. RTGUI_CONSTRUCTOR(_rtgui_win_constructor),
  70. RTGUI_DESTRUCTOR(_rtgui_win_destructor));
  71. }
  72. return win_type;
  73. }
  74. rtgui_win_t* rtgui_win_create(PVOID parent, const char* title, rtgui_rect_t *rect, rt_uint32_t style)
  75. {
  76. rtgui_win_t* win;
  77. //取得GUI服务器线程
  78. struct rt_thread* server = rtgui_thread_get_server();
  79. rtgui_thread_t* thread;
  80. if(parent == RT_NULL) parent = RTGUI_CONTAINER(rtgui_panel_get());
  81. RT_ASSERT(parent != RT_NULL);
  82. if(server == RT_NULL) return RT_NULL;
  83. win = rtgui_widget_create(RTGUI_WIN_TYPE);
  84. if(win != RT_NULL)
  85. {//根据样式,设置一些尺寸参数
  86. /* set window title */
  87. if(title != RT_NULL)
  88. win->title = rt_strdup(title);
  89. else
  90. win->title = RT_NULL;
  91. win->style = style;
  92. //设置默认的尺寸参数
  93. win->title_height = RTGUI_WIN_TITLE_HEIGHT;
  94. win->status_height= RTGUI_WIN_STATUS_HEIGHT;
  95. win->menu_height = RTGUI_WIN_MENU_HEIGHT;
  96. win->border_size = RTGUI_BORDER_DEFAULT_WIDTH;
  97. RTGUI_WIDGET(win)->toplevel = RTGUI_WIDGET(win); //窗口自身作为顶级控件
  98. /* set extent of win */
  99. rtgui_widget_set_rect(win, rect);
  100. rtgui_container_add_child(parent, win);
  101. thread = rtgui_thread_self();
  102. win->tid = thread->tid;//将窗口挂在当前线程下
  103. rtgui_thread_set_widget(RTGUI_WIDGET(win));/* 允许多个win共用一个thread */
  104. {//发送一个创建消息
  105. rtgui_event_win_t ewin;
  106. RTGUI_EVENT_WIN_CREATE_INIT(&ewin);
  107. ewin.wid = win;
  108. if(rtgui_thread_send_sync(server, RTGUI_EVENT(&ewin),sizeof(rtgui_event_win_t)) != RT_EOK)
  109. {
  110. rt_kprintf("create win: %s failed\n", win->title);
  111. return RT_FALSE;
  112. }
  113. }
  114. }
  115. return win;
  116. }
  117. void rtgui_win_destroy(rtgui_win_t* win)
  118. {
  119. if(RTGUI_WIN_IS_MODAL_MODE(win))
  120. {
  121. /* end modal */
  122. rtgui_win_end_modal(win);
  123. }
  124. rtgui_widget_destroy(win);
  125. }
  126. //获得控件的容器窗口
  127. rtgui_win_t* rtgui_win_get_win_by_widget(PVOID wdt)
  128. {
  129. rtgui_widget_t *parent=(rtgui_widget_t*)wdt;
  130. if(RTGUI_IS_WIN(parent))
  131. return (rtgui_win_t*)parent;
  132. while(parent->parent != RT_NULL)
  133. {
  134. if(RTGUI_IS_WIN(parent))break;
  135. parent = parent->parent;
  136. }
  137. if(RTGUI_IS_WIN(parent))
  138. return (rtgui_win_t*)parent;
  139. return RT_NULL;
  140. }
  141. //窗口关闭时的事件处理
  142. void rtgui_win_close(PVOID wdt, rtgui_event_t *event)
  143. {
  144. rtgui_win_t* win = RT_NULL;
  145. if(RTGUI_IS_WIN(wdt))
  146. win = RTGUI_WIN(wdt);
  147. else
  148. win = rtgui_win_get_win_by_widget(wdt);
  149. if(win != RT_NULL)
  150. {
  151. rtgui_panel_t *panel=rtgui_panel_get();
  152. //置窗口状态为关闭状态
  153. win->status |= RTGUI_WIN_STATUS_CLOSED;
  154. RTGUI_CONTAINER(panel)->focused = RT_NULL;
  155. rtgui_win_destroy(win);
  156. }
  157. }
  158. void rtgui_win_show(rtgui_win_t* win, rt_bool_t modal)
  159. {
  160. RT_ASSERT(win != RT_NULL);
  161. if(RTGUI_WIDGET_IS_HIDE(win))
  162. {
  163. /* send show message to server */
  164. rtgui_event_win_t ewin;
  165. RTGUI_EVENT_WIN_SHOW_INIT(&ewin);
  166. ewin.wid = win;
  167. if(rtgui_thread_send_sync(rtgui_thread_get_server(), RTGUI_EVENT(&ewin),sizeof(rtgui_event_win_t)) != RT_EOK)
  168. {
  169. return;
  170. }
  171. }
  172. else rtgui_widget_update(win);
  173. if(modal == RT_TRUE)
  174. {//以模式方式显示
  175. rtgui_widget_t *parent_widget = RTGUI_WIDGET_PARENT(win);
  176. if(parent_widget != RT_NULL)
  177. {
  178. /* set style */
  179. win->status |= RTGUI_WIN_STATUS_MODAL;
  180. //win->modal_widget = win;//这时没有指定模式控件,则指向自身
  181. if(RTGUI_IS_PANEL(parent_widget))
  182. {
  183. rtgui_panel_t* panel;
  184. panel = RTGUI_PANEL(parent_widget);
  185. panel->status |= RTGUI_PANEL_STATUS_MODAL;
  186. panel->modal_widget = win;
  187. }
  188. else if(RTGUI_IS_WIN(parent_widget))
  189. {
  190. rtgui_win_t* pwin;
  191. pwin = RTGUI_WIN(parent_widget);
  192. pwin->status |= RTGUI_WIN_STATUS_MODAL;
  193. pwin->modal_widget = win;
  194. }
  195. }
  196. else
  197. {
  198. /* which is a top window */
  199. win->status |= RTGUI_WIN_STATUS_MODAL;
  200. rtgui_win_event_loop(win);
  201. win->status &= ~RTGUI_WIN_STATUS_MODAL;
  202. }
  203. }
  204. }
  205. void rtgui_win_end_modal(rtgui_win_t* win)
  206. {
  207. rtgui_widget_t* parent_widget;
  208. RT_ASSERT(win != RT_NULL);
  209. parent_widget = RTGUI_WIDGET_PARENT(win);
  210. if(parent_widget != RT_NULL)
  211. {
  212. if(RTGUI_IS_PANEL(parent_widget))
  213. {
  214. rtgui_panel_t* panel;
  215. /* which is shown under workbench */
  216. panel = RTGUI_PANEL(parent_widget);
  217. panel->status &= ~RTGUI_PANEL_STATUS_MODAL;
  218. panel->modal_widget = RT_NULL;
  219. }
  220. else if(RTGUI_IS_WIN(parent_widget))
  221. {
  222. rtgui_win_t* pwin;
  223. /* which is shown under win */
  224. pwin = RTGUI_WIN(parent_widget);
  225. pwin->status &= ~RTGUI_WIN_STATUS_MODAL;
  226. pwin->modal_widget = RT_NULL;
  227. }
  228. }
  229. else
  230. {
  231. /* which is a stand alone window */
  232. }
  233. /* remove modal mode */
  234. win->status &= ~RTGUI_WIN_STATUS_MODAL;
  235. }
  236. void rtgui_win_hiden(rtgui_win_t* win)
  237. {
  238. RT_ASSERT(win != RT_NULL);
  239. if(!RTGUI_WIDGET_IS_HIDE(win) && rtgui_thread_get_server() != RT_NULL)
  240. {
  241. /* send hidden message to server */
  242. rtgui_event_win_t ewin;
  243. RTGUI_EVENT_WIN_HIDE_INIT(&ewin);
  244. ewin.wid = win;
  245. if(rtgui_thread_send_sync(rtgui_thread_get_server(), RTGUI_EVENT(&ewin),sizeof(rtgui_event_win_t)) != RT_EOK)
  246. {
  247. rt_kprintf("hide win: %s failed\n", win->title);
  248. return;
  249. }
  250. /* set window hide and deactivated */
  251. RTGUI_WIDGET_HIDE(win);
  252. win->status &= ~RTGUI_WIN_STATUS_ACTIVATE;
  253. }
  254. }
  255. rt_bool_t rtgui_win_is_activated(rtgui_win_t* win)
  256. {
  257. RT_ASSERT(win != RT_NULL);
  258. return win->status & RTGUI_WIN_STATUS_ACTIVATE;
  259. }
  260. void rtgui_win_move(rtgui_win_t* win, int x, int y)
  261. {
  262. rtgui_event_win_move_t emove;
  263. RTGUI_EVENT_WIN_MOVE_INIT(&emove);
  264. if (win == RT_NULL) return;
  265. /* set win hide firstly */
  266. // RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
  267. emove.wid = win;
  268. emove.x = x;
  269. emove.y = y;
  270. if (rtgui_thread_send_sync(rtgui_thread_get_server(), RTGUI_EVENT(&emove),
  271. sizeof(rtgui_event_win_move_t)) != RT_EOK)
  272. {
  273. return;
  274. }
  275. // /* move window to logic position */
  276. // rtgui_widget_move_to_logic(win,
  277. // x - RTGUI_WIDGET(win)->extent.x1,
  278. // y - RTGUI_WIDGET(win)->extent.y1);
  279. //
  280. // /* set window visible */
  281. // RTGUI_WIDGET_UNHIDE(win);
  282. return;
  283. }
  284. rt_bool_t rtgui_win_ondraw(rtgui_win_t* win)
  285. {
  286. rtgui_event_paint_t event;
  287. rtgui_theme_draw_win(win);
  288. /* paint each widget */
  289. RTGUI_EVENT_PAINT_INIT(&event);
  290. event.wid = RT_NULL;
  291. rtgui_container_dispatch_event(RTGUI_CONTAINER(win), (rtgui_event_t*)&event);
  292. return RT_FALSE;
  293. }
  294. rt_bool_t rtgui_win_event_handler(PVOID wdt, rtgui_event_t* event)
  295. {
  296. rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
  297. rtgui_win_t* win = (rtgui_win_t*)widget;
  298. RT_ASSERT((win != RT_NULL) && (event != RT_NULL));
  299. switch (event->type)
  300. {
  301. case RTGUI_EVENT_WIN_CLOSE:
  302. if(win->on_close != RT_NULL)
  303. {
  304. if(win->on_close(widget, event) == RT_FALSE) return RT_TRUE;
  305. }
  306. if(RTGUI_WIN_IS_MODAL_MODE(win))
  307. {
  308. rtgui_win_destroy(win);
  309. }
  310. else
  311. {
  312. rtgui_win_close(win,RT_NULL);
  313. }
  314. /* exit event loop */
  315. return RT_TRUE;
  316. case RTGUI_EVENT_WIN_MAX: //最大化窗口
  317. // TODO: Place code here.
  318. break;
  319. case RTGUI_EVENT_WIN_MIN: //最小化窗口,(隐藏窗口)
  320. // TODO: Place code here.
  321. break;
  322. case RTGUI_EVENT_WIN_MOVE:
  323. {
  324. rtgui_event_win_move_t* emove = (rtgui_event_win_move_t*)event;
  325. /* move window */
  326. rtgui_win_move(win, emove->x, emove->y);
  327. }
  328. break;
  329. case RTGUI_EVENT_WIN_ACTIVATE:
  330. if(RTGUI_WIDGET_IS_HIDE(win))
  331. {
  332. rt_kprintf("activate window, but window is hide!\n");
  333. }
  334. win->status |= RTGUI_WIN_STATUS_ACTIVATE;
  335. if(widget->on_draw != RT_NULL)
  336. widget->on_draw(widget, event);
  337. else
  338. rtgui_widget_update(win);
  339. if (win->on_activate != RT_NULL)
  340. {
  341. win->on_activate(widget, event);
  342. }
  343. break;
  344. case RTGUI_EVENT_WIN_DEACTIVATE:
  345. if(RTGUI_WIN_IS_MODAL_MODE(win))
  346. {
  347. /* do not deactivate a modal win, re-send win-show event */
  348. rtgui_event_win_t eshow;
  349. RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
  350. eshow.wid = win;
  351. rtgui_thread_send(rtgui_thread_get_server(), RTGUI_EVENT(&eshow),sizeof(rtgui_event_win_t));
  352. }
  353. else
  354. {
  355. win->status &= ~RTGUI_WIN_STATUS_ACTIVATE;
  356. if(widget->on_draw != RT_NULL)
  357. widget->on_draw(widget, event);
  358. else
  359. rtgui_win_ondraw(win);
  360. if (win->on_deactivate != RT_NULL)
  361. {
  362. win->on_deactivate(widget, event);
  363. }
  364. }
  365. break;
  366. case RTGUI_EVENT_PAINT:
  367. if(widget->on_draw != RT_NULL) widget->on_draw(widget, event);
  368. else
  369. rtgui_win_ondraw(win);
  370. break;
  371. case RTGUI_EVENT_MOUSE_BUTTON:
  372. if(RTGUI_WIN_IS_MODAL_MODE(win))
  373. {
  374. if(win->modal_widget != RT_NULL)
  375. return RTGUI_WIDGET_EVENT_CALL(win->modal_widget, event);
  376. }
  377. if(rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),(rtgui_event_mouse_t*)event) == RT_FALSE)
  378. {//派发消息
  379. if(widget->on_mouseclick != RT_NULL)
  380. {
  381. return widget->on_mouseclick(widget, event);
  382. }
  383. }
  384. break;
  385. case RTGUI_EVENT_MOUSE_MOTION:
  386. if (RTGUI_WIN_IS_MODAL_MODE(win))
  387. {
  388. if (win->modal_widget != RT_NULL)
  389. return RTGUI_WIDGET_EVENT_CALL(win->modal_widget, event);
  390. }
  391. rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),(rtgui_event_mouse_t*)event);
  392. break;
  393. case RTGUI_EVENT_KBD:
  394. if(RTGUI_WIN_IS_MODAL_MODE(win))
  395. {
  396. if(win->modal_widget != RT_NULL)
  397. return RTGUI_WIDGET_EVENT_CALL(win->modal_widget, event);
  398. }
  399. if(RTGUI_CONTAINER(win)->focused != widget)
  400. {
  401. RTGUI_WIDGET_EVENT_CALL(RTGUI_CONTAINER(win)->focused, event);
  402. }
  403. break;
  404. default:
  405. //call parent widget event
  406. return rtgui_container_event_handler(wdt,event);
  407. }
  408. return RT_FALSE;
  409. }
  410. /* windows event loop */
  411. void rtgui_win_event_loop(rtgui_win_t* win)
  412. {
  413. rt_err_t result;
  414. rtgui_thread_t* tid;
  415. rtgui_event_t* event;
  416. tid = rtgui_thread_self();
  417. RT_ASSERT(tid != RT_NULL);
  418. /* point to event buffer */
  419. event = (rtgui_event_t*)tid->event_buffer;
  420. if(RTGUI_WIN_IS_MODAL_MODE(win))
  421. {
  422. while(RTGUI_WIN_IS_MODAL_MODE(win))
  423. {
  424. if (tid->on_idle != RT_NULL)
  425. {
  426. result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
  427. if (result == RT_EOK)
  428. {
  429. /* perform event handler */
  430. RTGUI_WIDGET_EVENT_CALL(win, event);
  431. }
  432. else if (result == -RT_ETIMEOUT)
  433. {
  434. tid->on_idle(win, RT_NULL);
  435. }
  436. }
  437. else
  438. {
  439. result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
  440. if (result == RT_EOK)
  441. {
  442. /* perform event handler */
  443. RTGUI_WIDGET_EVENT_CALL(win, event);
  444. }
  445. }
  446. }
  447. }
  448. else
  449. {
  450. while(!(win->status & RTGUI_WIN_STATUS_CLOSED))
  451. {
  452. if (tid->on_idle != RT_NULL)
  453. {
  454. result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
  455. if (result == RT_EOK)
  456. {
  457. /* perform event handler */
  458. RTGUI_WIDGET_EVENT_CALL(win, event);
  459. }
  460. else if (result == -RT_ETIMEOUT)
  461. {
  462. tid->on_idle(win, RT_NULL);
  463. }
  464. }
  465. else
  466. {
  467. result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
  468. if (result == RT_EOK)
  469. {
  470. /* perform event handler */
  471. RTGUI_WIDGET_EVENT_CALL(win, event);
  472. }
  473. }
  474. }
  475. }
  476. }
  477. void rtgui_win_set_rect(rtgui_win_t* win, rtgui_rect_t* rect)
  478. {
  479. rtgui_event_win_resize_t event;
  480. if(win == RT_NULL || rect == RT_NULL) return;
  481. RTGUI_WIDGET(win)->extent = *rect;
  482. if(rtgui_thread_get_server() != RT_NULL)
  483. {
  484. /* set window resize event to server */
  485. RTGUI_EVENT_WIN_RESIZE_INIT(&event);
  486. event.wid = win;
  487. event.rect = *rect;
  488. rtgui_thread_send(rtgui_thread_get_server(), &(event.parent), sizeof(rtgui_event_win_resize_t));
  489. }
  490. }
  491. void rtgui_win_set_onactivate(rtgui_win_t* win, rtgui_event_handler_ptr handler)
  492. {
  493. if(win != RT_NULL)
  494. {
  495. win->on_activate = handler;
  496. }
  497. }
  498. void rtgui_win_set_ondeactivate(rtgui_win_t* win, rtgui_event_handler_ptr handler)
  499. {
  500. if(win != RT_NULL)
  501. {
  502. win->on_deactivate = handler;
  503. }
  504. }
  505. void rtgui_win_set_onclose(rtgui_win_t* win, rtgui_event_handler_ptr handler)
  506. {
  507. if(win != RT_NULL)
  508. {
  509. win->on_close = handler;
  510. }
  511. }
  512. void rtgui_win_set_title(rtgui_win_t* win, const char *title)
  513. {
  514. /* modify in local side */
  515. rt_free(win->title);
  516. if(title != RT_NULL)
  517. win->title = rt_strdup(title);
  518. else
  519. win->title = RT_NULL;
  520. }
  521. char* rtgui_win_get_title(rtgui_win_t* win)
  522. {
  523. RT_ASSERT(win != RT_NULL);
  524. return win->title;
  525. }
  526. rtgui_point_t rtgui_win_get_client_zero(rtgui_win_t *win)
  527. {
  528. rtgui_point_t p={0};
  529. rtgui_rect_t r1,r2;
  530. rtgui_win_get_client_rect(win, &r1);
  531. rtgui_widget_get_rect(win, &r2);
  532. p.x = r1.x1-r2.x1;
  533. p.y = r1.y1-r2.y1;
  534. return p;
  535. }
  536. //返回窗口客户区区域
  537. void rtgui_win_get_client_rect(rtgui_win_t *win, rtgui_rect_t *rect)
  538. {
  539. rtgui_widget_get_rect(win, rect);
  540. if(win->style & RTGUI_WIN_BORDER)
  541. rtgui_rect_inflate(rect, -win->border_size);
  542. if(win->style & RTGUI_WIN_TITLE)//有标题栏则减去标题栏的高度
  543. rect->y1 += win->title_height;
  544. if(win->style & RTGUI_WIN_MENU)
  545. rect->y1 += win->menu_height;
  546. if(win->style & RTGUI_WIN_STATUS)//有状态栏则减去状态栏的高度
  547. rect->y2 -= win->status_height;
  548. }
  549. //返回窗口的标题栏区域
  550. void rtgui_win_get_title_rect(rtgui_win_t *win, rtgui_rect_t *rect)
  551. {
  552. rtgui_widget_get_rect(win, rect);
  553. if(win->style & RTGUI_WIN_TITLE)
  554. {
  555. if(win->style & RTGUI_WIN_BORDER)
  556. {
  557. rtgui_rect_inflate(rect, -win->border_size);
  558. }
  559. rect->y2 = rect->y1 + win->title_height;
  560. }
  561. else
  562. {
  563. rect->x1=rect->x2=rect->y1=rect->y2 = 0;
  564. }
  565. }
  566. //返回窗口的关闭按钮区域
  567. void rtgui_win_get_closebox_rect(rtgui_win_t *win, rtgui_rect_t *rect)
  568. {
  569. rtgui_win_get_title_rect(win,rect);
  570. if(win->style & RTGUI_WIN_CLOSEBOX)
  571. {
  572. /* get close button rect (device value) */
  573. rect->x2 = rect->x2 - 2;
  574. rect->x1 = rect->x2 - RTGUI_WIN_CLOSEBOX_WIDTH;
  575. rect->y1 = rect->y1 + (rtgui_rect_height(*rect)-RTGUI_WIN_CLOSEBOX_HEIGHT)/2;
  576. rect->y2 = rect->y1 + RTGUI_WIN_CLOSEBOX_HEIGHT;
  577. }
  578. }
  579. //返回窗口的最大化按钮区域
  580. void rtgui_win_get_maxbox_rect(rtgui_win_t *win, rtgui_rect_t *rect)
  581. {
  582. rtgui_win_get_closebox_rect(win,rect);
  583. if(win->style & RTGUI_WIN_CLOSEBOX)
  584. {
  585. rtgui_rect_moveto(rect,-2-RTGUI_WIN_CLOSEBOX_WIDTH,0);
  586. }
  587. }
  588. //返回窗口的最小化按钮区域
  589. void rtgui_win_get_minbox_rect(rtgui_win_t *win, rtgui_rect_t *rect)
  590. {
  591. rtgui_win_get_closebox_rect(win,rect);
  592. if(win->style & RTGUI_WIN_CLOSEBOX)
  593. {
  594. rtgui_rect_moveto(rect,-2-RTGUI_WIN_CLOSEBOX_WIDTH,0);
  595. }
  596. if(win->style &RTGUI_WIN_MAXBOX)
  597. {
  598. rtgui_rect_moveto(rect,-2-RTGUI_WIN_CLOSEBOX_WIDTH,0);
  599. }
  600. }