rtgui_theme.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990
  1. /*
  2. * File : rtgui_theme.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/rtgui.h>
  15. #include <rtgui/dc.h>
  16. #include <rtgui/widgets/widget.h>
  17. #include <rtgui/widgets/button.h>
  18. #include <rtgui/widgets/label.h>
  19. #include <rtgui/widgets/textbox.h>
  20. #include <rtgui/widgets/iconbox.h>
  21. #include <rtgui/widgets/title.h>
  22. #include <rtgui/rtgui_theme.h>
  23. #include <rtgui/rtgui_server.h>
  24. #include <rtgui/rtgui_system.h>
  25. #define SELECTED_HEIGHT 25
  26. const rtgui_color_t default_foreground = RTGUI_RGB(0x00, 0x00, 0x00);
  27. const rtgui_color_t default_background = RTGUI_RGB(212, 208, 200);
  28. const rtgui_color_t selected_color = RTGUI_RGB(0xc0, 0xc0, 0xc0);
  29. const rtgui_color_t disable_foreground = RTGUI_RGB(0x80, 0x80, 0x80);
  30. extern struct rtgui_font rtgui_font_asc16;
  31. extern struct rtgui_font rtgui_font_arial16;
  32. extern struct rtgui_font rtgui_font_asc12;
  33. extern struct rtgui_font rtgui_font_arial12;
  34. /* init theme */
  35. void rtgui_system_theme_init()
  36. {
  37. #if RTGUI_DEFAULT_FONT_SIZE == 16
  38. rtgui_font_set_defaut(&rtgui_font_asc16);
  39. #elif RTGUI_DEFAULT_FONT_SIZE == 12
  40. rtgui_font_set_defaut(&rtgui_font_asc12);
  41. #else
  42. rtgui_font_set_defaut(&rtgui_font_asc12);
  43. #endif
  44. }
  45. static const rt_uint8_t close_byte[14] = {0x06, 0x18, 0x03, 0x30, 0x01, 0xE0, 0x00,
  46. 0xC0, 0x01, 0xE0, 0x03, 0x30, 0x06, 0x18
  47. };
  48. /* window drawing */
  49. void rtgui_theme_draw_win(struct rtgui_topwin* win)
  50. {
  51. struct rtgui_dc* dc;
  52. rtgui_rect_t rect;
  53. if (win->title == RT_NULL) return; /* no title and no board */
  54. /* begin drawing */
  55. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(win->title));
  56. if (dc == RT_NULL) return;
  57. /* get rect */
  58. rtgui_widget_get_rect(RTGUI_WIDGET(win->title), &rect);
  59. /* draw border */
  60. if (win->flag & WINTITLE_BORDER)
  61. {
  62. rect.x2 -= 1; rect.y2 -= 1;
  63. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = RTGUI_RGB(212, 208, 200);
  64. rtgui_dc_draw_hline(dc, rect.x1, rect.x2, rect.y1);
  65. rtgui_dc_draw_vline(dc, rect.x1, rect.y1, rect.y2);
  66. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = white;
  67. rtgui_dc_draw_hline(dc, rect.x1 + 1, rect.x2 - 1, rect.y1 + 1);
  68. rtgui_dc_draw_vline(dc, rect.x1 + 1, rect.y1 + 1, rect.y2 - 1);
  69. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = RTGUI_RGB(128, 128, 128);
  70. rtgui_dc_draw_hline(dc, rect.x1 + 1, rect.x2 - 1, rect.y2 - 1);
  71. rtgui_dc_draw_vline(dc, rect.x2 - 1, rect.y1 + 1, rect.y2);
  72. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = RTGUI_RGB(64, 64, 64);
  73. rtgui_dc_draw_hline(dc, rect.x1, rect.x2, rect.y2);
  74. rtgui_dc_draw_vline(dc, rect.x2, rect.y1, rect.y2 + 1);
  75. /* shrink border */
  76. rtgui_rect_inflate(&rect, -WINTITLE_BORDER_SIZE);
  77. }
  78. /* draw title */
  79. if (!(win->flag & WINTITLE_NO))
  80. {
  81. rt_uint32_t index;
  82. float r, g, b, delta;
  83. if (win->flag & WINTITLE_ACTIVATE)
  84. {
  85. r = 10; g = 36; b = 106;
  86. delta = 150 / (float)(rect.x2 - rect.x1);
  87. }
  88. else
  89. {
  90. r = 128; g = 128; b = 128;
  91. delta = 64 / (float)(rect.x2 - rect.x1);
  92. }
  93. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = RTGUI_RGB(r, g, b);
  94. for (index = rect.x1; index < rect.x2 + 1; index ++)
  95. {
  96. rtgui_dc_draw_vline(dc, index, rect.y1, rect.y2);
  97. r += delta; g += delta; b += delta;
  98. }
  99. if (win->flag & WINTITLE_ACTIVATE)
  100. {
  101. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = white;
  102. }
  103. else
  104. {
  105. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = RTGUI_RGB(212, 208, 200);
  106. }
  107. rect.x1 += 4;
  108. rect.y1 += 2; rect.y2 = rect.y1 + WINTITLE_CB_HEIGHT;
  109. rtgui_dc_draw_text(dc, rtgui_wintitle_get_title(win->title), &rect);
  110. if (win->flag & WINTITLE_CLOSEBOX)
  111. {
  112. /* get close button rect */
  113. rtgui_rect_t box_rect = {0, 0, WINTITLE_CB_WIDTH, WINTITLE_CB_HEIGHT};
  114. rtgui_rect_moveto_align(&rect, &box_rect, RTGUI_ALIGN_CENTER_VERTICAL | RTGUI_ALIGN_RIGHT);
  115. box_rect.x1 -= 3; box_rect.x2 -= 3;
  116. rtgui_dc_fill_rect(dc, &box_rect);
  117. /* draw close box */
  118. if (win->flag & WINTITLE_CB_PRESSED)
  119. {
  120. rtgui_dc_draw_border(dc, &box_rect, RTGUI_BORDER_SUNKEN);
  121. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = red;
  122. rtgui_dc_draw_word(dc, box_rect.x1, box_rect.y1 + 6, 7, close_byte);
  123. }
  124. else
  125. {
  126. rtgui_dc_draw_border(dc, &box_rect, RTGUI_BORDER_RAISE);
  127. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = black;
  128. rtgui_dc_draw_word(dc, box_rect.x1 - 1, box_rect.y1 + 5, 7, close_byte);
  129. }
  130. }
  131. }
  132. rtgui_dc_end_drawing(dc);
  133. }
  134. /* widget drawing */
  135. void rtgui_theme_draw_button(rtgui_button_t* btn)
  136. {
  137. /* draw button */
  138. struct rtgui_dc* dc;
  139. struct rtgui_rect rect;
  140. rtgui_color_t bc, fc;
  141. /* begin drawing */
  142. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(btn));
  143. if (dc == RT_NULL) return;
  144. /* get widget rect */
  145. rtgui_widget_get_rect(RTGUI_WIDGET(btn), &rect);
  146. /* get foreground color */
  147. bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(btn));
  148. fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(btn));
  149. if (btn->flag & RTGUI_BUTTON_FLAG_PRESS)
  150. {
  151. if (btn->pressed_image != RT_NULL)
  152. {
  153. rtgui_rect_t image_rect;
  154. image_rect.x1 = 0; image_rect.y1 = 0;
  155. image_rect.x2 = btn->unpressed_image->w;
  156. image_rect.y2 = btn->unpressed_image->h;
  157. rtgui_rect_moveto_align(&rect, &image_rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
  158. rtgui_image_blit(btn->pressed_image, dc, &image_rect);
  159. }
  160. else
  161. {
  162. /* fill button rect with background color */
  163. rtgui_dc_fill_rect(dc, &rect);
  164. rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN);
  165. }
  166. }
  167. else
  168. {
  169. if (btn->unpressed_image != RT_NULL)
  170. {
  171. rtgui_rect_t image_rect;
  172. image_rect.x1 = 0; image_rect.y1 = 0;
  173. image_rect.x2 = btn->unpressed_image->w;
  174. image_rect.y2 = btn->unpressed_image->h;
  175. rtgui_rect_moveto_align(&rect, &image_rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
  176. rtgui_image_blit(btn->unpressed_image, dc, &image_rect);
  177. }
  178. else
  179. {
  180. /* fill button rect with background color */
  181. rtgui_dc_fill_rect(dc, &rect);
  182. rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_RAISE);
  183. }
  184. }
  185. if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(btn)))
  186. {
  187. /* re-set foreground and get default rect */
  188. rtgui_widget_get_rect(RTGUI_WIDGET(btn), &rect);
  189. rtgui_rect_inflate(&rect, -2);
  190. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(btn)) = black;
  191. rtgui_dc_draw_focus_rect(dc, &rect);
  192. }
  193. /* set forecolor */
  194. RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(btn)) = bc;
  195. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(btn)) = fc;
  196. if (btn->pressed_image == RT_NULL)
  197. {
  198. /* re-set foreground and get default rect */
  199. rtgui_widget_get_rect(RTGUI_WIDGET(btn), &rect);
  200. /* remove border */
  201. rtgui_rect_inflate(&rect, -2);
  202. /* draw text */
  203. rtgui_dc_draw_text(dc, rtgui_label_get_text(RTGUI_LABEL(btn)), &rect);
  204. }
  205. /* end drawing */
  206. rtgui_dc_end_drawing(dc);
  207. }
  208. void rtgui_theme_draw_label(rtgui_label_t* label)
  209. {
  210. /* draw label */
  211. struct rtgui_dc* dc;
  212. struct rtgui_rect rect;
  213. /* begin drawing */
  214. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(label));
  215. if (dc == RT_NULL) return;
  216. rtgui_widget_get_rect(RTGUI_WIDGET(label), &rect);
  217. rtgui_dc_fill_rect(dc, &rect);
  218. /* default left and center draw */
  219. rtgui_dc_draw_text(dc, rtgui_label_get_text(label), &rect);
  220. /* end drawing */
  221. rtgui_dc_end_drawing(dc);
  222. }
  223. #define RTGUI_TEXTBOX_MARGIN 3
  224. void rtgui_theme_draw_textbox(rtgui_textbox_t* box)
  225. {
  226. /* draw button */
  227. struct rtgui_dc* dc;
  228. struct rtgui_rect rect;
  229. rtgui_color_t fc;
  230. /* begin drawing */
  231. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
  232. if (dc == RT_NULL) return;
  233. /* get widget rect */
  234. rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
  235. fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box));
  236. /* fill widget rect with white color */
  237. RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
  238. rtgui_dc_fill_rect(dc, &rect);
  239. /* draw border */
  240. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = RTGUI_RGB(123, 158, 189);
  241. rtgui_dc_draw_rect(dc, &rect);
  242. /* draw text */
  243. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = fc;
  244. if (box->text != RT_NULL)
  245. {
  246. rect.x1 += RTGUI_TEXTBOX_MARGIN;
  247. if (box->flag & RTGUI_TEXTBOX_MASK)
  248. {
  249. /* draw '*' */
  250. rt_size_t len = rt_strlen(box->text);
  251. if (len > 0)
  252. {
  253. char *text_mask = rtgui_malloc(len + 1);
  254. rt_memset(text_mask, '*', len + 1);
  255. text_mask[len] = 0;
  256. rtgui_dc_draw_text(dc, text_mask, &rect);
  257. rt_free(text_mask);
  258. }
  259. }
  260. else
  261. {
  262. rtgui_dc_draw_text(dc, box->text, &rect);
  263. }
  264. /* draw caret */
  265. if (box->flag & RTGUI_TEXTBOX_CARET_SHOW)
  266. {
  267. rect.x1 += box->position * box->font_width;
  268. rect.x2 = rect.x1 + box->font_width;
  269. rect.y2 -= 2;
  270. rect.y1 = rect.y2 - 3;
  271. RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = black;
  272. rtgui_dc_fill_rect(dc, &rect);
  273. }
  274. }
  275. /* end drawing */
  276. rtgui_dc_end_drawing(dc);
  277. }
  278. void rtgui_theme_draw_iconbox(rtgui_iconbox_t* iconbox)
  279. {
  280. struct rtgui_dc* dc;
  281. struct rtgui_rect rect;
  282. /* begin drawing */
  283. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(iconbox));
  284. if (dc == RT_NULL) return;
  285. /* get widget rect */
  286. rtgui_widget_get_rect(RTGUI_WIDGET(iconbox), &rect);
  287. /* draw icon */
  288. rtgui_image_blit(iconbox->image, dc, &rect);
  289. /* draw text */
  290. if (iconbox->text_position == RTGUI_ICONBOX_TEXT_BELOW && iconbox->text != RT_NULL)
  291. {
  292. rect.y1 = iconbox->image->h + RTGUI_WIDGET_DEFAULT_MARGIN;
  293. rtgui_dc_draw_text(dc, iconbox->text, &rect);
  294. }
  295. else if (iconbox->text_position == RTGUI_ICONBOX_TEXT_RIGHT && iconbox->text != RT_NULL)
  296. {
  297. rect.x1 = iconbox->image->w + RTGUI_WIDGET_DEFAULT_MARGIN;
  298. rtgui_dc_draw_text(dc, iconbox->text, &rect);
  299. }
  300. /* end drawing */
  301. rtgui_dc_end_drawing(dc);
  302. }
  303. static const rt_uint8_t checked_byte[7] = {0x02, 0x06, 0x8E, 0xDC, 0xF8, 0x70, 0x20};
  304. void rtgui_theme_draw_checkbox(struct rtgui_checkbox* checkbox)
  305. {
  306. struct rtgui_dc* dc;
  307. struct rtgui_rect rect, box_rect;
  308. rtgui_color_t bc, fc;
  309. fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(checkbox));
  310. bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(checkbox));
  311. /* begin drawing */
  312. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(checkbox));
  313. if (dc == RT_NULL) return;
  314. /* get rect */
  315. rtgui_widget_get_rect(RTGUI_WIDGET(checkbox), &rect);
  316. /* fill rect */
  317. rtgui_dc_fill_rect(dc, &rect);
  318. if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(checkbox)))
  319. {
  320. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(checkbox)) = black;
  321. /* draw focused border */
  322. rtgui_rect_inflate(&rect, -1);
  323. rtgui_dc_draw_focus_rect(dc, &rect);
  324. rtgui_rect_inflate(&rect, 1);
  325. }
  326. /* draw check box */
  327. box_rect.x1 = 0;
  328. box_rect.y1 = 0;
  329. box_rect.x2 = CHECK_BOX_W;
  330. box_rect.y2 = CHECK_BOX_H;
  331. rtgui_rect_moveto_align(&rect, &box_rect, RTGUI_ALIGN_CENTER_VERTICAL);
  332. box_rect.x1 += 2; box_rect.x2 += 2;
  333. rtgui_dc_draw_border(dc, &box_rect, RTGUI_BORDER_BOX);
  334. rtgui_rect_inflate(&box_rect, -1);
  335. RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(checkbox)) = RTGUI_RGB(247, 247, 246);
  336. rtgui_dc_fill_rect(dc, &box_rect);
  337. if (checkbox->status_down == RTGUI_CHECKBOX_STATUS_CHECKED)
  338. {
  339. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(checkbox)) = RTGUI_RGB(33, 161, 33);
  340. rtgui_dc_draw_byte(dc, box_rect.x1 + 2, box_rect.y1 + 2, 7, checked_byte);
  341. }
  342. /* restore saved color */
  343. RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(checkbox)) = bc;
  344. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(checkbox)) = fc;
  345. /* draw text */
  346. rect.x1 += rtgui_rect_height(rect) - 4 + 5;
  347. rtgui_dc_draw_text(dc, rtgui_label_get_text(RTGUI_LABEL(checkbox)), &rect);
  348. /* end drawing */
  349. rtgui_dc_end_drawing(dc);
  350. return;
  351. }
  352. static const rt_uint8_t radio_unchecked_byte[] =
  353. {
  354. 0x0f, 0x00, 0x30, 0xc0, 0x40, 0x20,
  355. 0x40, 0x20, 0x80, 0x10, 0x80, 0x10,
  356. 0x80, 0x10, 0x80, 0x10, 0x40, 0x20,
  357. 0x40, 0x20, 0x30, 0xc0, 0x0f, 0x00,
  358. };
  359. static const rt_uint8_t radio_checked_byte[] =
  360. {
  361. 0x0f, 0x00, 0x30, 0xc0, 0x40, 0x20,
  362. 0x40, 0x20, 0x86, 0x10, 0x8f, 0x10,
  363. 0x8f, 0x10, 0x86, 0x10, 0x40, 0x20,
  364. 0x40, 0x20, 0x30, 0xc0, 0x0f, 0x00,
  365. };
  366. void rtgui_theme_draw_radiobutton(struct rtgui_radiobox* radiobox, rt_uint16_t item)
  367. {
  368. struct rtgui_dc* dc;
  369. struct rtgui_rect rect, item_rect;
  370. int item_size, bord_size;
  371. /* begin drawing */
  372. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(radiobox));
  373. if (dc == RT_NULL) return;
  374. /* get widget rect */
  375. rtgui_widget_get_rect(RTGUI_WIDGET(radiobox), &rect);
  376. item_size = radiobox->item_size;
  377. /* get board size */
  378. if (radiobox->orient == RTGUI_VERTICAL)
  379. bord_size = item_size;
  380. else
  381. {
  382. rtgui_font_get_metrics(RTGUI_DC_FONT(dc), "H", &item_rect);
  383. bord_size = rtgui_rect_height(item_rect);
  384. }
  385. item_rect = rect;
  386. rtgui_rect_inflate(&item_rect, - bord_size);
  387. if (radiobox->orient == RTGUI_VERTICAL)
  388. {
  389. /* set the first text rect */
  390. item_rect.y1 += item * item_size;
  391. item_rect.y2 = item_rect.y1 + item_size;
  392. /* draw radio */
  393. if (radiobox->item_selection == item)
  394. {
  395. if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(radiobox)))
  396. rtgui_dc_draw_focus_rect(dc, &item_rect);
  397. rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1 + (item_size - RADIO_BOX_H) / 2,
  398. RADIO_BOX_H, radio_checked_byte);
  399. }
  400. else
  401. {
  402. item_rect.x2 += 1; item_rect.y2 += 1;
  403. rtgui_dc_fill_rect(dc, &item_rect);
  404. item_rect.x2 -= 1; item_rect.y2 -= 1;
  405. rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1 + (item_size - RADIO_BOX_H) / 2,
  406. RADIO_BOX_H, radio_unchecked_byte);
  407. }
  408. /* draw text */
  409. item_rect.x1 += item_size + 3;
  410. rtgui_dc_draw_text(dc, radiobox->items[item], &item_rect);
  411. }
  412. else
  413. {
  414. item_rect.x1 += item * item_size;
  415. /* set the first text rect */
  416. item_rect.x2 = item_rect.x1 + item_size - 1;
  417. item_rect.y2 = item_rect.y1 + bord_size;
  418. /* draw radio */
  419. if (radiobox->item_selection == item)
  420. {
  421. if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(radiobox)))
  422. rtgui_dc_draw_focus_rect(dc, &item_rect);
  423. rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1, RADIO_BOX_H, radio_checked_byte);
  424. }
  425. else
  426. {
  427. item_rect.x2 += 1; item_rect.y2 += 1;
  428. rtgui_dc_fill_rect(dc, &item_rect);
  429. item_rect.x2 -= 1; item_rect.y2 -= 1;
  430. rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1, RADIO_BOX_H, radio_unchecked_byte);
  431. }
  432. /* draw text */
  433. item_rect.x1 += bord_size + 3;
  434. rtgui_dc_draw_text(dc, radiobox->items[item], &item_rect);
  435. }
  436. /* end drawing */
  437. rtgui_dc_end_drawing(dc);
  438. }
  439. void rtgui_theme_draw_radiobox(struct rtgui_radiobox* radiobox)
  440. {
  441. struct rtgui_dc* dc;
  442. struct rtgui_rect rect, item_rect;
  443. int item_size, bord_size, index;
  444. rtgui_color_t fc;
  445. /* begin drawing */
  446. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(radiobox));
  447. if (dc == RT_NULL) return;
  448. /* get widget rect */
  449. rtgui_widget_get_rect(RTGUI_WIDGET(radiobox), &rect);
  450. rtgui_dc_fill_rect(dc, &rect);
  451. item_size = radiobox->item_size;
  452. /* get board size */
  453. if (radiobox->orient == RTGUI_VERTICAL)
  454. bord_size = item_size;
  455. else
  456. {
  457. rtgui_font_get_metrics(RTGUI_DC_FONT(dc), "H", &item_rect);
  458. bord_size = rtgui_rect_height(item_rect);
  459. }
  460. /* draw box */
  461. rtgui_rect_inflate(&rect, -bord_size/2);
  462. fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(radiobox));
  463. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(radiobox)) = white;
  464. rect.x1 ++; rect.y1 ++; rect.x2 ++; rect.y2 ++;
  465. rtgui_dc_draw_rect(dc, &rect);
  466. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(radiobox)) = RTGUI_RGB(128, 128, 128);
  467. rect.x1 --; rect.y1 --; rect.x2 --; rect.y2 --;
  468. rtgui_dc_draw_rect(dc, &rect);
  469. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(radiobox)) = fc;
  470. rtgui_rect_inflate(&rect, bord_size/2);
  471. if (radiobox->text != RT_NULL)
  472. {
  473. struct rtgui_rect text_rect;
  474. /* draw group text */
  475. rtgui_font_get_metrics(RTGUI_DC_FONT(dc), radiobox->text, &text_rect);
  476. rtgui_rect_moveto(&text_rect, rect.x1 + bord_size + 5, rect.y1);
  477. rect.x1 -= 5; rect.x2 += 5;
  478. rtgui_dc_fill_rect(dc, &text_rect);
  479. rect.x1 += 5; rect.x2 -= 5;
  480. rtgui_dc_draw_text(dc, radiobox->text, &text_rect);
  481. }
  482. /* set init item rect */
  483. item_rect = rect;
  484. rtgui_rect_inflate(&item_rect, - bord_size);
  485. if (radiobox->orient == RTGUI_VERTICAL)
  486. {
  487. rt_uint16_t offset;
  488. /* set the first text rect */
  489. item_rect.y2 = item_rect.y1 + item_size;
  490. offset = (item_size - RADIO_BOX_H) / 2;
  491. /* draw each radio button */
  492. for (index = 0; index < radiobox->item_count; index ++)
  493. {
  494. if (item_rect.y2 > rect.y2 - item_size) break;
  495. /* draw radio */
  496. if (radiobox->item_selection == index)
  497. {
  498. if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(radiobox)))
  499. rtgui_dc_draw_focus_rect(dc, &item_rect);
  500. rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1 + offset, RADIO_BOX_H, radio_checked_byte);
  501. }
  502. else
  503. {
  504. rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1 + offset, RADIO_BOX_H, radio_unchecked_byte);
  505. }
  506. /* draw text */
  507. item_rect.x1 += item_size + 3;
  508. rtgui_dc_draw_text(dc, radiobox->items[index], &item_rect);
  509. item_rect.x1 -= item_size + 3;
  510. item_rect.y1 += item_size;
  511. item_rect.y2 += item_size;
  512. }
  513. }
  514. else
  515. {
  516. /* set the first text rect */
  517. item_rect.x2 = item_rect.x1 + item_size;
  518. item_rect.y2 = item_rect.y1 + bord_size;
  519. /* draw each radio button */
  520. for (index = 0; index < radiobox->item_count; index ++)
  521. {
  522. if (item_rect.x2 > rect.x2 - item_size) break;
  523. /* draw radio */
  524. if (radiobox->item_selection == index)
  525. {
  526. if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(radiobox)))
  527. rtgui_dc_draw_focus_rect(dc, &item_rect);
  528. rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1, RADIO_BOX_H, radio_checked_byte);
  529. }
  530. else
  531. {
  532. rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1, RADIO_BOX_H, radio_unchecked_byte);
  533. }
  534. /* draw text */
  535. item_rect.x1 += bord_size + 3;
  536. rtgui_dc_draw_text(dc, radiobox->items[index], &item_rect);
  537. item_rect.x1 -= bord_size + 3;
  538. item_rect.x1 += item_size;
  539. item_rect.x2 += (item_size - 1);
  540. }
  541. }
  542. /* end drawing */
  543. rtgui_dc_end_drawing(dc);
  544. }
  545. void rtgui_theme_draw_slider(struct rtgui_slider* slider)
  546. {
  547. /* draw button */
  548. struct rtgui_dc* dc;
  549. int i, xsize, x0;
  550. rtgui_rect_t r, focus_rect, slider_rect, slot_rect;
  551. /* begin drawing */
  552. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(slider));
  553. if (dc == RT_NULL) return;
  554. /* get widget rect */
  555. rtgui_widget_get_rect(RTGUI_WIDGET(slider), &focus_rect);
  556. /* fill widget rect with background color */
  557. rtgui_dc_fill_rect(dc, &focus_rect);
  558. r = focus_rect;
  559. if (slider->orient == RTGUI_VERTICAL)
  560. {
  561. rtgui_rect_inflate(&r, -1);
  562. xsize = r.y2 - r.y1 + 1 - slider->thumb_width;
  563. x0 = r.y1 + slider->thumb_width / 2;
  564. /* calculate thumb position */
  565. slider_rect = r;
  566. slider_rect.x1 = 5;
  567. slider_rect.y1 = x0 + xsize * (slider->value - slider->min) / (slider->max - slider->min) - slider->thumb_width/2;
  568. slider_rect.y2 = slider_rect.y1 + slider->thumb_width;
  569. /* calculate slot position */
  570. slot_rect.y1 = x0;
  571. slot_rect.y2 = x0 + xsize;
  572. slot_rect.x1 = (slider_rect.x1 + slider_rect.x2) /2 -1;
  573. slot_rect.x2 = slot_rect.x1 +3;
  574. /* draw slot */
  575. rtgui_dc_draw_border(dc, &slot_rect, RTGUI_BORDER_RAISE);
  576. /* draw the ticks */
  577. for (i = 0; i <= slider->ticks; i++)
  578. {
  579. int x = x0 + xsize * i / slider->ticks;
  580. rtgui_dc_draw_hline(dc, 1, 3, x);
  581. }
  582. /* draw the thumb */
  583. rtgui_dc_fill_rect(dc, &slider_rect);
  584. rtgui_dc_draw_border(dc, &slider_rect, RTGUI_BORDER_RAISE);
  585. }
  586. else
  587. {
  588. rtgui_rect_inflate(&r, -1);
  589. xsize = r.x2 - r.x1 + 1 - slider->thumb_width;
  590. x0 = r.x1 + slider->thumb_width / 2;
  591. /* calculate thumb position */
  592. slider_rect = r;
  593. slider_rect.y1 = 5;
  594. slider_rect.x1 = x0 + xsize * (slider->value - slider->min) / (slider->max - slider->min) - slider->thumb_width/2;
  595. slider_rect.x2 = slider_rect.x1 + slider->thumb_width;
  596. /* calculate slot position */
  597. slot_rect.x1 = x0;
  598. slot_rect.x2 = x0 + xsize;
  599. slot_rect.y1 = (slider_rect.y1 + slider_rect.y2) /2 -1;
  600. slot_rect.y2 = slot_rect.y1 +3;
  601. /* draw slot */
  602. rtgui_dc_draw_border(dc, &slot_rect, RTGUI_BORDER_RAISE);
  603. /* draw the ticks */
  604. for (i = 0; i <= slider->ticks; i++)
  605. {
  606. int x = x0 + xsize * i / slider->ticks;
  607. rtgui_dc_draw_vline(dc, x, 1, 3);
  608. }
  609. /* draw the thumb */
  610. rtgui_dc_fill_rect(dc, &slider_rect);
  611. rtgui_dc_draw_border(dc, &slider_rect, RTGUI_BORDER_RAISE);
  612. }
  613. /* draw focus */
  614. if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(slider)))
  615. {
  616. rtgui_dc_draw_focus_rect(dc, &focus_rect);
  617. }
  618. /* end drawing */
  619. rtgui_dc_end_drawing(dc);
  620. return;
  621. }
  622. const static rt_uint8_t _up_arrow[] = {0x10, 0x38, 0x7C, 0xFE};
  623. const static rt_uint8_t _down_arrow[] = {0xFE,0x7C, 0x38, 0x10};
  624. const static rt_uint8_t _left_arrow[] = {0x10, 0x30, 0x70, 0xF0, 0x70, 0x30, 0x10};
  625. const static rt_uint8_t _right_arrow[] = {0x80, 0xC0, 0xE0, 0xF0, 0xE0, 0xC0, 0x80};
  626. void rtgui_theme_draw_scrollbar(struct rtgui_scrollbar* bar)
  627. {
  628. /* draw scroll bar */
  629. struct rtgui_dc* dc;
  630. rtgui_rect_t rect, btn_rect, thum_rect, arrow_rect;
  631. rtgui_color_t bc, fc;
  632. /* begin drawing */
  633. dc = rtgui_dc_begin_drawing(&(bar->parent));
  634. if (dc == RT_NULL) return;
  635. rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
  636. /* draw background */
  637. fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(bar));
  638. if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar)))
  639. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(128, 128, 128);
  640. bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar));
  641. RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)) = white;
  642. rtgui_dc_fill_rect(dc, &rect);
  643. RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)) = bc;
  644. if (bar->orient == RTGUI_VERTICAL)
  645. {
  646. btn_rect = rect;
  647. btn_rect.y2 = btn_rect.y1 + (rect.x2 - rect.x1);
  648. /* draw up button */
  649. rtgui_dc_fill_rect(dc, &btn_rect);
  650. if (bar->status & SBS_UPARROW) rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
  651. else rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
  652. /* draw arrow */
  653. arrow_rect.x1 = 0; arrow_rect.y1 = 0;
  654. arrow_rect.x2 = 7; arrow_rect.y2 = 4;
  655. rtgui_rect_moveto_align(&btn_rect, &arrow_rect,
  656. RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
  657. rtgui_dc_draw_byte(dc, arrow_rect.x1, arrow_rect.y1,
  658. rtgui_rect_height(arrow_rect), _up_arrow);
  659. /* draw thumb */
  660. if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar)))
  661. {
  662. rtgui_scrollbar_get_thumb_rect(bar, &thum_rect);
  663. rtgui_dc_fill_rect(dc, &thum_rect);
  664. rtgui_dc_draw_border(dc, &thum_rect, RTGUI_BORDER_RAISE);
  665. }
  666. /* draw down button */
  667. btn_rect.y1 = rect.y2 - (rect.x2 - rect.x1);
  668. btn_rect.y2 = rect.y2;
  669. rtgui_dc_fill_rect(dc, &btn_rect);
  670. if (bar->status & SBS_DOWNARROW) rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
  671. else rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
  672. arrow_rect.x1 = 0; arrow_rect.y1 = 0;
  673. arrow_rect.x2 = 7; arrow_rect.y2 = 4;
  674. rtgui_rect_moveto_align(&btn_rect, &arrow_rect,
  675. RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
  676. rtgui_dc_draw_byte(dc, arrow_rect.x1, arrow_rect.y1,
  677. rtgui_rect_height(arrow_rect), _down_arrow);
  678. }
  679. else
  680. {
  681. btn_rect.x1 = rect.x1;
  682. btn_rect.y1 = rect.y1;
  683. btn_rect.x2 = rect.y2;
  684. btn_rect.y2 = rect.y2;
  685. /* draw left button */
  686. rtgui_dc_fill_rect(dc, &btn_rect);
  687. if (bar->status & SBS_LEFTARROW) rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
  688. else rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
  689. arrow_rect.x1 = 0; arrow_rect.y1 = 0;
  690. arrow_rect.x2 = 4; arrow_rect.y2 = 7;
  691. rtgui_rect_moveto_align(&btn_rect, &arrow_rect,
  692. RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
  693. rtgui_dc_draw_byte(dc, arrow_rect.x1, arrow_rect.y1,
  694. rtgui_rect_height(arrow_rect), _left_arrow);
  695. /* draw thumb */
  696. if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar)))
  697. {
  698. rtgui_scrollbar_get_thumb_rect(bar, &thum_rect);
  699. rtgui_dc_fill_rect(dc, &thum_rect);
  700. rtgui_dc_draw_border(dc, &thum_rect, RTGUI_BORDER_RAISE);
  701. }
  702. btn_rect.x1 = rect.x2 - rect.y2;
  703. btn_rect.x2 = rect.x2;
  704. /* draw right button */
  705. rtgui_dc_fill_rect(dc, &btn_rect);
  706. if (bar->status & SBS_RIGHTARROW) rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
  707. else rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
  708. arrow_rect.x1 = 0; arrow_rect.y1 = 0;
  709. arrow_rect.x2 = 4; arrow_rect.y2 = 7;
  710. rtgui_rect_moveto_align(&btn_rect, &arrow_rect,
  711. RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
  712. rtgui_dc_draw_byte(dc, arrow_rect.x1, arrow_rect.y1,
  713. rtgui_rect_height(arrow_rect), _right_arrow);
  714. }
  715. /* end drawing */
  716. rtgui_dc_end_drawing(dc);
  717. RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(bar)) = fc;
  718. return;
  719. }
  720. void rtgui_theme_draw_progressbar(struct rtgui_progressbar* bar)
  721. {
  722. /* draw progress bar */
  723. struct rtgui_dc* dc;
  724. struct rtgui_rect rect;
  725. int max = bar->range;
  726. int pos = bar->position;
  727. int left;
  728. rtgui_color_t bc;
  729. /* begin drawing */
  730. dc = rtgui_dc_begin_drawing(&(bar->parent));
  731. if (dc == RT_NULL) return;
  732. bc = RTGUI_DC_BC(dc);
  733. rtgui_widget_get_rect(&(bar->parent), &rect);
  734. /* fill button rect with background color */
  735. RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(212, 208, 200);
  736. /* draw border */
  737. rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN);
  738. /* Nothing to draw */
  739. if (max == 0)
  740. {
  741. rtgui_dc_end_drawing(dc);
  742. return;
  743. }
  744. rect.x2 ++; rect.y2 ++;
  745. left = max - pos;
  746. rtgui_rect_inflate(&rect, -2);
  747. RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(0, 0, 255);
  748. rect.y2 --; rect.x2 --;
  749. if (bar->orient == RTGUI_VERTICAL)
  750. {
  751. /* Vertical bar grows from bottom to top */
  752. int dy = (rtgui_rect_height(rect) * left) / max;
  753. rect.y1 += dy;
  754. rtgui_dc_fill_rect(dc, &rect);
  755. RTGUI_DC_BC(dc) = bc;
  756. rect.y1 -= dy; rect.y2 = dy;
  757. rtgui_dc_fill_rect(dc, &rect);
  758. }
  759. else
  760. {
  761. /* Horizontal bar grows from left to right */
  762. int dx = (rtgui_rect_width(rect) * left) / max;
  763. rect.x2 -= dx;
  764. rtgui_dc_fill_rect(dc, &rect);
  765. RTGUI_DC_BC(dc) = bc;
  766. rect.x1 = rect.x2; rect.x2 += dx;
  767. rtgui_dc_fill_rect(dc, &rect);
  768. }
  769. /* end drawing */
  770. rtgui_dc_end_drawing(dc);
  771. return;
  772. }
  773. void rtgui_theme_draw_staticline(struct rtgui_staticline* staticline)
  774. {
  775. struct rtgui_dc* dc;
  776. struct rtgui_rect rect;
  777. /* begin drawing */
  778. dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(staticline));
  779. if (dc == RT_NULL) return ;
  780. rtgui_widget_get_rect(RTGUI_WIDGET(staticline), &rect);
  781. rtgui_dc_fill_rect(dc, &rect);
  782. if (staticline->orient == RTGUI_HORIZONTAL)
  783. {
  784. rtgui_dc_draw_horizontal_line(dc, rect.x1, rect.x2, rect.y1);
  785. }
  786. else
  787. {
  788. rtgui_dc_draw_vertical_line(dc, rect.x1, rect.y1, rect.y2);
  789. }
  790. rtgui_dc_end_drawing(dc);
  791. }
  792. rt_uint16_t rtgui_theme_get_selected_height()
  793. {
  794. return SELECTED_HEIGHT;
  795. }
  796. void rtgui_theme_draw_selected(struct rtgui_dc* dc, rtgui_rect_t *rect)
  797. {
  798. rtgui_color_t bc;
  799. rt_uint16_t index;
  800. bc = RTGUI_DC_FC(dc);
  801. RTGUI_DC_FC(dc) = selected_color;
  802. rtgui_dc_draw_hline(dc, rect->x1 + 3, rect->x2 - 2, rect->y1 + 1);
  803. rtgui_dc_draw_hline(dc, rect->x1 + 3, rect->x2 - 2, rect->y2 - 2);
  804. rtgui_dc_draw_vline(dc, rect->x1 + 2, rect->y1 + 2, rect->y2 - 2);
  805. rtgui_dc_draw_vline(dc, rect->x2 - 2, rect->y1 + 2, rect->y2 - 2);
  806. for (index = rect->y1 + 1; index < rect->y2 - 2; index ++)
  807. rtgui_dc_draw_hline(dc, rect->x1 + 3, rect->x2 - 2, index);
  808. RTGUI_DC_FC(dc) = bc;
  809. }
  810. /* get default background color */
  811. rtgui_color_t rtgui_theme_default_bc()
  812. {
  813. return default_background;
  814. }
  815. /* get default foreground color */
  816. rtgui_color_t rtgui_theme_default_fc()
  817. {
  818. return default_foreground;
  819. }