Browse Source

merge new RTGUI in to trunk

The full log is at https://github.com/RTGUI/RTGUI/commits/merge_1 and it's difficult to merge the new tree commit by commit. I also converted all the file into unix eol so there are many fake diff. Big changes are noted in rtgui/doc/road_map.txt and rtgui/doc/attention.txt. Keep an eye on them if you want to migrate your old code.

Note that the work is still in progress and the bsp is not prepared in trunk so far.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2092 bbd45198-f89e-11dd-88c7-29a3b14d5316
chaos.proton@gmail.com 13 years ago
parent
commit
db06460208
100 changed files with 13131 additions and 13805 deletions
  1. 81 83
      components/rtgui/SConscript
  2. 284 284
      components/rtgui/common/blit.c
  3. 20 19
      components/rtgui/common/dc_client.c
  4. 13 11
      components/rtgui/common/dc_hw.c
  5. 463 463
      components/rtgui/common/filerw.c
  6. 237 237
      components/rtgui/common/font_freetype.c
  7. 2 2
      components/rtgui/common/font_hz_bmp.c
  8. 2 2
      components/rtgui/common/font_hz_file.c
  9. 225 225
      components/rtgui/common/framebuffer_driver.c
  10. 15 15
      components/rtgui/common/image.c
  11. 645 645
      components/rtgui/common/image_bmp.c
  12. 445 445
      components/rtgui/common/image_container.c
  13. 154 154
      components/rtgui/common/pixel_driver.c
  14. 24 11
      components/rtgui/common/rtgui_object.c
  15. 2 465
      components/rtgui/common/rtgui_system.c
  16. 1 1
      components/rtgui/common/rtgui_xml.c
  17. 16 0
      components/rtgui/doc/attention.txt
  18. 70 0
      components/rtgui/doc/road_map.txt
  19. 9 9
      components/rtgui/include/rtgui/blit.h
  20. 114 114
      components/rtgui/include/rtgui/color.h
  21. 196 196
      components/rtgui/include/rtgui/dc.h
  22. 27 27
      components/rtgui/include/rtgui/dc_client.h
  23. 24 24
      components/rtgui/include/rtgui/dc_hw.h
  24. 119 0
      components/rtgui/include/rtgui/dlist.h
  25. 67 67
      components/rtgui/include/rtgui/driver.h
  26. 352 423
      components/rtgui/include/rtgui/event.h
  27. 47 47
      components/rtgui/include/rtgui/filerw.h
  28. 103 103
      components/rtgui/include/rtgui/font.h
  29. 10 10
      components/rtgui/include/rtgui/font_freetype.h
  30. 80 80
      components/rtgui/include/rtgui/image.h
  31. 293 293
      components/rtgui/include/rtgui/kbddef.h
  32. 66 66
      components/rtgui/include/rtgui/list.h
  33. 2 3
      components/rtgui/include/rtgui/rtgui.h
  34. 99 0
      components/rtgui/include/rtgui/rtgui_application.h
  35. 81 75
      components/rtgui/include/rtgui/rtgui_config.h
  36. 28 5
      components/rtgui/include/rtgui/rtgui_object.h
  37. 84 79
      components/rtgui/include/rtgui/rtgui_server.h
  38. 57 100
      components/rtgui/include/rtgui/rtgui_system.h
  39. 44 46
      components/rtgui/include/rtgui/widgets/about_view.h
  40. 58 58
      components/rtgui/include/rtgui/widgets/box.h
  41. 81 81
      components/rtgui/include/rtgui/widgets/button.h
  42. 43 43
      components/rtgui/include/rtgui/widgets/checkbox.h
  43. 49 49
      components/rtgui/include/rtgui/widgets/combobox.h
  44. 68 47
      components/rtgui/include/rtgui/widgets/container.h
  45. 58 57
      components/rtgui/include/rtgui/widgets/filelist_view.h
  46. 55 55
      components/rtgui/include/rtgui/widgets/iconbox.h
  47. 49 49
      components/rtgui/include/rtgui/widgets/label.h
  48. 76 78
      components/rtgui/include/rtgui/widgets/list_view.h
  49. 67 68
      components/rtgui/include/rtgui/widgets/listbox.h
  50. 63 66
      components/rtgui/include/rtgui/widgets/listctrl.h
  51. 78 80
      components/rtgui/include/rtgui/widgets/menu.h
  52. 49 53
      components/rtgui/include/rtgui/widgets/notebook.h
  53. 40 40
      components/rtgui/include/rtgui/widgets/progressbar.h
  54. 45 45
      components/rtgui/include/rtgui/widgets/radiobox.h
  55. 89 89
      components/rtgui/include/rtgui/widgets/scrollbar.h
  56. 53 53
      components/rtgui/include/rtgui/widgets/slider.h
  57. 35 35
      components/rtgui/include/rtgui/widgets/staticline.h
  58. 75 75
      components/rtgui/include/rtgui/widgets/textbox.h
  59. 67 67
      components/rtgui/include/rtgui/widgets/textview.h
  60. 44 44
      components/rtgui/include/rtgui/widgets/title.h
  61. 44 53
      components/rtgui/include/rtgui/widgets/toplevel.h
  62. 0 66
      components/rtgui/include/rtgui/widgets/view.h
  63. 25 18
      components/rtgui/include/rtgui/widgets/widget.h
  64. 160 107
      components/rtgui/include/rtgui/widgets/window.h
  65. 0 87
      components/rtgui/include/rtgui/widgets/workbench.h
  66. 1 1
      components/rtgui/server/mouse.c
  67. 0 315
      components/rtgui/server/panel.c
  68. 0 72
      components/rtgui/server/panel.h
  69. 673 0
      components/rtgui/server/rtgui_application.c
  70. 158 447
      components/rtgui/server/server.c
  71. 571 396
      components/rtgui/server/topwin.c
  72. 10 12
      components/rtgui/server/topwin.h
  73. 101 101
      components/rtgui/widgets/about_view.c
  74. 9 7
      components/rtgui/widgets/box.c
  75. 11 8
      components/rtgui/widgets/button.c
  76. 153 146
      components/rtgui/widgets/checkbox.c
  77. 276 259
      components/rtgui/widgets/combobox.c
  78. 117 42
      components/rtgui/widgets/container.c
  79. 827 846
      components/rtgui/widgets/filelist_view.c
  80. 8 3
      components/rtgui/widgets/iconbox.c
  81. 5 6
      components/rtgui/widgets/label.c
  82. 636 636
      components/rtgui/widgets/list_view.c
  83. 388 387
      components/rtgui/widgets/listbox.c
  84. 427 426
      components/rtgui/widgets/listctrl.c
  85. 287 275
      components/rtgui/widgets/menu.c
  86. 356 330
      components/rtgui/widgets/notebook.c
  87. 104 101
      components/rtgui/widgets/progressbar.c
  88. 246 244
      components/rtgui/widgets/radiobox.c
  89. 419 415
      components/rtgui/widgets/scrollbar.c
  90. 266 241
      components/rtgui/widgets/slider.c
  91. 80 80
      components/rtgui/widgets/staticline.c
  92. 16 10
      components/rtgui/widgets/textbox.c
  93. 351 352
      components/rtgui/widgets/textview.c
  94. 24 56
      components/rtgui/widgets/toplevel.c
  95. 0 214
      components/rtgui/widgets/view.c
  96. 88 64
      components/rtgui/widgets/widget.c
  97. 258 300
      components/rtgui/widgets/window.c
  98. 0 581
      components/rtgui/widgets/workbench.c
  99. 46 40
      examples/gui/SConscript
  100. 147 0
      examples/gui/demo_application.c

+ 81 - 83
components/rtgui/SConscript

@@ -1,83 +1,81 @@
-Import('RTT_ROOT')
-from building import *
-
-common_src = Split("""
-common/blit.c
-common/color.c
-common/region.c
-common/rtgui_object.c
-common/rtgui_system.c
-common/rtgui_theme.c
-common/rtgui_xml.c
-common/dc.c
-common/dc_hw.c
-common/dc_buffer.c
-common/dc_client.c
-common/filerw.c
-common/image.c
-common/image_xpm.c
-common/image_hdc.c
-common/image_bmp.c
-common/image_png.c
-common/image_jpg.c
-common/image_container.c
-common/font.c
-common/font_bmp.c
-common/font_hz_file.c
-common/font_hz_bmp.c
-common/asc12font.c
-common/asc16font.c
-common/hz12font.c
-common/hz16font.c
-common/framebuffer_driver.c
-common/pixel_driver.c
-""")
-
-server_src = Split("""
-server/driver.c
-server/mouse.c
-server/panel.c
-server/server.c
-server/topwin.c
-""")
-
-widgets_src = Split("""
-widgets/box.c
-widgets/button.c
-widgets/checkbox.c
-widgets/container.c
-widgets/combobox.c
-widgets/iconbox.c
-widgets/label.c
-widgets/textview.c
-widgets/listctrl.c
-widgets/menu.c
-widgets/progressbar.c
-widgets/radiobox.c
-widgets/slider.c
-widgets/scrollbar.c
-widgets/staticline.c
-widgets/textbox.c
-widgets/listbox.c
-widgets/title.c
-widgets/toplevel.c
-widgets/notebook.c
-widgets/view.c
-widgets/list_view.c
-widgets/about_view.c
-widgets/filelist_view.c
-widgets/widget.c
-widgets/window.c
-widgets/workbench.c
-""")
-
-# The set of source files associated with this SConscript file.
-src = common_src + server_src + widgets_src
-
-path = [RTT_ROOT + '/components/rtgui/include',
-	RTT_ROOT + '/components/rtgui/common', 
-	RTT_ROOT + '/components/rtgui/server', 
-	RTT_ROOT + '/components/rtgui/widgets']
-group = DefineGroup('RTGUI', src, depend = ['RT_USING_RTGUI'], CPPPATH = path)
-
-Return('group')
+Import('RTT_ROOT')
+from building import *
+
+common_src = Split("""
+common/blit.c
+common/color.c
+common/region.c
+common/rtgui_object.c
+common/rtgui_system.c
+common/rtgui_theme.c
+common/rtgui_xml.c
+common/dc.c
+common/dc_hw.c
+common/dc_buffer.c
+common/dc_client.c
+common/filerw.c
+common/image.c
+common/image_xpm.c
+common/image_hdc.c
+common/image_bmp.c
+common/image_png.c
+common/image_jpg.c
+common/image_container.c
+common/font.c
+common/font_bmp.c
+common/font_hz_file.c
+common/font_hz_bmp.c
+common/asc12font.c
+common/asc16font.c
+common/hz12font.c
+common/hz16font.c
+common/framebuffer_driver.c
+common/pixel_driver.c
+""")
+
+server_src = Split("""
+server/rtgui_application.c
+server/driver.c
+server/mouse.c
+server/server.c
+server/topwin.c
+""")
+
+widgets_src = Split("""
+widgets/box.c
+widgets/button.c
+widgets/checkbox.c
+widgets/combobox.c
+widgets/iconbox.c
+widgets/label.c
+widgets/textview.c
+widgets/listctrl.c
+widgets/menu.c
+widgets/progressbar.c
+widgets/radiobox.c
+widgets/slider.c
+widgets/scrollbar.c
+widgets/staticline.c
+widgets/textbox.c
+widgets/listbox.c
+widgets/title.c
+widgets/toplevel.c
+widgets/notebook.c
+widgets/container.c
+widgets/list_view.c
+widgets/about_view.c
+widgets/filelist_view.c
+widgets/widget.c
+widgets/window.c
+""")
+
+# The set of source files associated with this SConscript file.
+src = common_src + server_src + widgets_src
+
+path = [RTT_ROOT + '/components/rtgui/include',
+	RTT_ROOT + '/components/rtgui/common', 
+	RTT_ROOT + '/components/rtgui/server', 
+	RTT_ROOT + '/components/rtgui/widgets']
+group = DefineGroup('RTGUI', src, depend = ['RT_USING_RTGUI'], CPPPATH = path)
+
+Return('group')

+ 284 - 284
components/rtgui/common/blit.c

@@ -1,32 +1,32 @@
-#include <rtgui/rtgui.h>
-#include <rtgui/blit.h>
-
-/* 2 bpp to 1 bpp */
-static void rtgui_blit_line_2_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-	return;
-}
-
-/* 3 bpp to 1 bpp */
-static void rtgui_blit_line_3_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-	line = line / 3;
-	while (line)
-	{
-		*dst_ptr = (rt_uint8_t)(((*src_ptr & 0x00E00000)>>16)|
-			((*(src_ptr + 1) & 0x0000E000)>>11) |
-			((*(src_ptr + 2) & 0x000000C0)>>6));
-
-		src_ptr += 3;
-		dst_ptr ++;
-		line --;
-	}
-	return;
-}
-
-/* 4 bpp to 1 bpp */
-static void rtgui_blit_line_4_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
+#include <rtgui/rtgui.h>
+#include <rtgui/blit.h>
+
+/* 2 bpp to 1 bpp */
+static void rtgui_blit_line_2_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+	return;
+}
+
+/* 3 bpp to 1 bpp */
+static void rtgui_blit_line_3_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+	line = line / 3;
+	while (line)
+	{
+		*dst_ptr = (rt_uint8_t)(((*src_ptr & 0x00E00000)>>16)|
+			((*(src_ptr + 1) & 0x0000E000)>>11) |
+			((*(src_ptr + 2) & 0x000000C0)>>6));
+
+		src_ptr += 3;
+		dst_ptr ++;
+		line --;
+	}
+	return;
+}
+
+/* 4 bpp to 1 bpp */
+static void rtgui_blit_line_4_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
 	struct _color {rt_uint8_t r, g, b, a;} *c;
 	struct _color {rt_uint8_t r, g, b, a;} *c;
 
 
 	c = (struct _color*)src_ptr;
 	c = (struct _color*)src_ptr;
@@ -36,39 +36,39 @@ static void rtgui_blit_line_4_1(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int li
 
 
 		c ++;
 		c ++;
 		dst_ptr ++;
 		dst_ptr ++;
-	}
-}
-
-/* 1 bpp to 2 bpp */
-static void rtgui_blit_line_1_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-	return;
-}
-
-/* 3 bpp to 2 bpp */
-static void rtgui_blit_line_3_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-	rt_uint16_t* dst;
-
-	dst = (rt_uint16_t*)dst_ptr;
-	line = line / 3;
-	while (line)
-	{
-		*dst = (((*(src_ptr + 2) << 8) & 0x0000F800) | 
-			((*(src_ptr + 1) << 3) & 0x000007E0)     | 
-			((*src_ptr >> 3) & 0x0000001F)); 
-
-		src_ptr += 3;
-		dst ++;
-		line --;
-	}
-
-	return;
-}
-
-/* 4 bpp to 2 bpp */
-static void rtgui_blit_line_4_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
+	}
+}
+
+/* 1 bpp to 2 bpp */
+static void rtgui_blit_line_1_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+	return;
+}
+
+/* 3 bpp to 2 bpp */
+static void rtgui_blit_line_3_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+	rt_uint16_t* dst;
+
+	dst = (rt_uint16_t*)dst_ptr;
+	line = line / 3;
+	while (line)
+	{
+		*dst = (((*(src_ptr + 2) << 8) & 0x0000F800) | 
+			((*(src_ptr + 1) << 3) & 0x000007E0)     | 
+			((*src_ptr >> 3) & 0x0000001F)); 
+
+		src_ptr += 3;
+		dst ++;
+		line --;
+	}
+
+	return;
+}
+
+/* 4 bpp to 2 bpp */
+static void rtgui_blit_line_4_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
 	struct _color {rt_uint8_t r, g, b, a;} *c;
 	struct _color {rt_uint8_t r, g, b, a;} *c;
 	rt_uint16_t* ptr;
 	rt_uint16_t* ptr;
 
 
@@ -83,225 +83,225 @@ static void rtgui_blit_line_4_2(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int li
 		c ++;
 		c ++;
 		ptr ++;
 		ptr ++;
 	}
 	}
-}
-
-static void rtgui_blit_line_1_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-	return;
-}
-
-#define HI	1
-#define LO	0
-
-/* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
-static const rt_uint32_t RGB565_RGBA8888_LUT[512] =
-{
-	0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
-	0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
-	0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
-	0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
-	0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
-	0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
-	0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
-	0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
-	0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
-	0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
-	0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
-	0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
-	0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
-	0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
-	0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
-	0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
-	0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
-	0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
-	0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
-	0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
-	0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
-	0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
-	0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
-	0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
-	0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
-	0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
-	0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
-	0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
-	0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
-	0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
-	0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
-	0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
-	0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
-	0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
-	0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
-	0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
-	0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
-	0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
-	0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
-	0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
-	0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
-	0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
-	0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
-	0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
-	0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
-	0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
-	0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
-	0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
-	0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
-	0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
-	0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
-	0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
-	0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
-	0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
-	0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
-	0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
-	0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
-	0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
-	0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
-	0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
-	0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
-	0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
-	0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
-	0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
-	0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
-	0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
-	0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
-	0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
-	0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
-	0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
-	0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
-	0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
-	0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
-	0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
-	0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
-	0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
-	0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
-	0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
-	0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
-	0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
-	0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
-	0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
-	0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
-	0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
-	0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
-	0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
-	0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
-	0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
-	0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
-	0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
-	0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
-	0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
-	0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
-	0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
-	0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
-	0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
-	0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
-	0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
-	0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
-	0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
-	0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
-	0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
-	0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
-	0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
-	0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
-	0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
-	0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
-	0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
-	0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
-	0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
-	0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
-	0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
-	0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
-	0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
-	0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
-	0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
-	0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
-	0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
-	0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
-	0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
-	0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
-	0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
-	0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
-	0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
-	0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
-	0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
-	0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
-	0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
-};
-
-static void rtgui_blit_line_2_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-	rt_uint16_t *src;
-	rt_uint32_t *dst;
-
-	src = (rt_uint16_t*)src_ptr;
-	dst = (rt_uint32_t*)dst_ptr;
-
-	line = line / 2;
-	while (line)
-	{
-		*dst++ = RGB565_RGBA8888_LUT[src[LO]*2] + RGB565_RGBA8888_LUT[src[HI]*2+1];
-		line--;
-		src ++;
-	}
-}
-
-void rtgui_blit_line_direct(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-	rt_memcpy(dst_ptr, src_ptr, line);
-}
-
-/* convert 4bpp to 3bpp */
-static void rtgui_blit_line_4_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-	line = line / 4;
-	while (line)
-	{
-		*dst_ptr++ = *src_ptr++;
-		*dst_ptr++ = *src_ptr++;
-		*dst_ptr++ = *src_ptr++;
-		src_ptr ++;
-		line --;
-	}
-}
-
-static void rtgui_blit_line_1_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-}
-
-static void rtgui_blit_line_2_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-}
-
-/* convert 3bpp to 4bpp */
-static void rtgui_blit_line_3_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
-{
-	line = line / 4;
-	while (line)
-	{
-		*dst_ptr++ = *src_ptr++;
-		*dst_ptr++ = *src_ptr++;
-		*dst_ptr++ = *src_ptr++;
-		*dst_ptr++ = 0;
-		line --;
-	}
-}
-
-static const rtgui_blit_line_func _blit_table[5][5] = 
-{
-	/* 0_0, 1_0, 2_0, 3_0, 4_0 */
-	{RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL }, 
-	/* 0_1, 1_1, 2_1, 3_1, 4_1 */
-	{RT_NULL, rtgui_blit_line_direct, rtgui_blit_line_2_1, rtgui_blit_line_3_1, rtgui_blit_line_4_1 }, 
-	/* 0_2, 1_2, 2_2, 3_2, 4_2 */
-	{RT_NULL, rtgui_blit_line_1_2, rtgui_blit_line_direct, rtgui_blit_line_3_2, rtgui_blit_line_4_2 }, 
-	/* 0_3, 1_3, 2_3, 3_3, 4_3 */
-	{RT_NULL, rtgui_blit_line_1_3, rtgui_blit_line_2_3, rtgui_blit_line_direct, rtgui_blit_line_4_3 }, 
-	/* 0_4, 1_4, 2_4, 3_4, 4_4 */
-	{RT_NULL, rtgui_blit_line_1_4, rtgui_blit_line_2_4, rtgui_blit_line_3_4, rtgui_blit_line_direct }, 
-};
-
-rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp)
-{
-	RT_ASSERT(dst_bpp>0 && dst_bpp < 5);
-	RT_ASSERT(src_bpp>0 && src_bpp < 5);
-
-	return _blit_table[dst_bpp][src_bpp];
-}
+}
+
+static void rtgui_blit_line_1_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+	return;
+}
+
+#define HI	1
+#define LO	0
+
+/* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */
+static const rt_uint32_t RGB565_RGBA8888_LUT[512] =
+{
+	0x000000ff, 0x00000000, 0x000008ff, 0x00200000,
+	0x000010ff, 0x00400000, 0x000018ff, 0x00610000,
+	0x000020ff, 0x00810000, 0x000029ff, 0x00a10000,
+	0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000,
+	0x000041ff, 0x08000000, 0x00004aff, 0x08200000,
+	0x000052ff, 0x08400000, 0x00005aff, 0x08610000,
+	0x000062ff, 0x08810000, 0x00006aff, 0x08a10000,
+	0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000,
+	0x000083ff, 0x10000000, 0x00008bff, 0x10200000,
+	0x000094ff, 0x10400000, 0x00009cff, 0x10610000,
+	0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000,
+	0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000,
+	0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000,
+	0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000,
+	0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000,
+	0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000,
+	0x000400ff, 0x20000000, 0x000408ff, 0x20200000,
+	0x000410ff, 0x20400000, 0x000418ff, 0x20610000,
+	0x000420ff, 0x20810000, 0x000429ff, 0x20a10000,
+	0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000,
+	0x000441ff, 0x29000000, 0x00044aff, 0x29200000,
+	0x000452ff, 0x29400000, 0x00045aff, 0x29610000,
+	0x000462ff, 0x29810000, 0x00046aff, 0x29a10000,
+	0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000,
+	0x000483ff, 0x31000000, 0x00048bff, 0x31200000,
+	0x000494ff, 0x31400000, 0x00049cff, 0x31610000,
+	0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000,
+	0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000,
+	0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000,
+	0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000,
+	0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000,
+	0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000,
+	0x000800ff, 0x41000000, 0x000808ff, 0x41200000,
+	0x000810ff, 0x41400000, 0x000818ff, 0x41610000,
+	0x000820ff, 0x41810000, 0x000829ff, 0x41a10000,
+	0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000,
+	0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000,
+	0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000,
+	0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000,
+	0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000,
+	0x000883ff, 0x52000000, 0x00088bff, 0x52200000,
+	0x000894ff, 0x52400000, 0x00089cff, 0x52610000,
+	0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000,
+	0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000,
+	0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000,
+	0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000,
+	0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000,
+	0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000,
+	0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000,
+	0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000,
+	0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000,
+	0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000,
+	0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000,
+	0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000,
+	0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000,
+	0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000,
+	0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000,
+	0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000,
+	0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000,
+	0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000,
+	0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000,
+	0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000,
+	0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000,
+	0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000,
+	0x001000ff, 0x83000000, 0x001008ff, 0x83200000,
+	0x001010ff, 0x83400000, 0x001018ff, 0x83610000,
+	0x001020ff, 0x83810000, 0x001029ff, 0x83a10000,
+	0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000,
+	0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000,
+	0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000,
+	0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000,
+	0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000,
+	0x001083ff, 0x94000000, 0x00108bff, 0x94200000,
+	0x001094ff, 0x94400000, 0x00109cff, 0x94610000,
+	0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000,
+	0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000,
+	0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000,
+	0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000,
+	0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000,
+	0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000,
+	0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000,
+	0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000,
+	0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000,
+	0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000,
+	0x001441ff, 0xac000000, 0x00144aff, 0xac200000,
+	0x001452ff, 0xac400000, 0x00145aff, 0xac610000,
+	0x001462ff, 0xac810000, 0x00146aff, 0xaca10000,
+	0x001473ff, 0xacc20000, 0x00147bff, 0xace20000,
+	0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000,
+	0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000,
+	0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000,
+	0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000,
+	0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000,
+	0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000,
+	0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000,
+	0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000,
+	0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000,
+	0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000,
+	0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000,
+	0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000,
+	0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000,
+	0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000,
+	0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000,
+	0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000,
+	0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000,
+	0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000,
+	0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000,
+	0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000,
+	0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000,
+	0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000,
+	0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000,
+	0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000,
+	0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000,
+	0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000,
+	0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000,
+	0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000,
+	0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000,
+	0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000,
+	0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000,
+	0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000,
+	0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000,
+	0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000,
+	0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000,
+	0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000,
+	0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000,
+	0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000,
+	0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000,
+	0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000,
+};
+
+static void rtgui_blit_line_2_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+	rt_uint16_t *src;
+	rt_uint32_t *dst;
+
+	src = (rt_uint16_t*)src_ptr;
+	dst = (rt_uint32_t*)dst_ptr;
+
+	line = line / 2;
+	while (line)
+	{
+		*dst++ = RGB565_RGBA8888_LUT[src[LO]*2] + RGB565_RGBA8888_LUT[src[HI]*2+1];
+		line--;
+		src ++;
+	}
+}
+
+void rtgui_blit_line_direct(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+	rt_memcpy(dst_ptr, src_ptr, line);
+}
+
+/* convert 4bpp to 3bpp */
+static void rtgui_blit_line_4_3(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+	line = line / 4;
+	while (line)
+	{
+		*dst_ptr++ = *src_ptr++;
+		*dst_ptr++ = *src_ptr++;
+		*dst_ptr++ = *src_ptr++;
+		src_ptr ++;
+		line --;
+	}
+}
+
+static void rtgui_blit_line_1_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+}
+
+static void rtgui_blit_line_2_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+}
+
+/* convert 3bpp to 4bpp */
+static void rtgui_blit_line_3_4(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
+{
+	line = line / 4;
+	while (line)
+	{
+		*dst_ptr++ = *src_ptr++;
+		*dst_ptr++ = *src_ptr++;
+		*dst_ptr++ = *src_ptr++;
+		*dst_ptr++ = 0;
+		line --;
+	}
+}
+
+static const rtgui_blit_line_func _blit_table[5][5] = 
+{
+	/* 0_0, 1_0, 2_0, 3_0, 4_0 */
+	{RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL }, 
+	/* 0_1, 1_1, 2_1, 3_1, 4_1 */
+	{RT_NULL, rtgui_blit_line_direct, rtgui_blit_line_2_1, rtgui_blit_line_3_1, rtgui_blit_line_4_1 }, 
+	/* 0_2, 1_2, 2_2, 3_2, 4_2 */
+	{RT_NULL, rtgui_blit_line_1_2, rtgui_blit_line_direct, rtgui_blit_line_3_2, rtgui_blit_line_4_2 }, 
+	/* 0_3, 1_3, 2_3, 3_3, 4_3 */
+	{RT_NULL, rtgui_blit_line_1_3, rtgui_blit_line_2_3, rtgui_blit_line_direct, rtgui_blit_line_4_3 }, 
+	/* 0_4, 1_4, 2_4, 3_4, 4_4 */
+	{RT_NULL, rtgui_blit_line_1_4, rtgui_blit_line_2_4, rtgui_blit_line_3_4, rtgui_blit_line_direct }, 
+};
+
+rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp)
+{
+	RT_ASSERT(dst_bpp>0 && dst_bpp < 5);
+	RT_ASSERT(src_bpp>0 && src_bpp < 5);
+
+	return _blit_table[dst_bpp][src_bpp];
+}

+ 20 - 19
components/rtgui/common/dc_client.c

@@ -21,9 +21,10 @@
 
 
 #include <rtgui/driver.h>
 #include <rtgui/driver.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/view.h>
+#include <rtgui/rtgui_application.h>
+#include <rtgui/rtgui_server.h>
+#include <rtgui/widgets/container.h>
 #include <rtgui/widgets/window.h>
 #include <rtgui/widgets/window.h>
-#include <rtgui/widgets/workbench.h>
 #include <rtgui/widgets/title.h>
 #include <rtgui/widgets/title.h>
 
 
 static void rtgui_dc_client_draw_point(struct rtgui_dc* dc, int x, int y);
 static void rtgui_dc_client_draw_point(struct rtgui_dc* dc, int x, int y);
@@ -48,14 +49,11 @@ struct rtgui_dc* rtgui_dc_begin_drawing(rtgui_widget_t* owner)
 {
 {
 	RT_ASSERT(owner != RT_NULL);
 	RT_ASSERT(owner != RT_NULL);
 
 
-	if ((rtgui_region_is_flat(&owner->clip) == RT_EOK) && 
+	if ((rtgui_region_is_flat(&owner->clip) == RT_EOK) &&
 		rtgui_rect_is_equal(&(owner->extent), &(owner->clip.extents)) == RT_EOK)
 		rtgui_rect_is_equal(&(owner->extent), &(owner->clip.extents)) == RT_EOK)
-	{
-		/* use hardware DC */
 		return rtgui_dc_hw_create(owner);
 		return rtgui_dc_hw_create(owner);
-	}
-
-	return rtgui_dc_client_create(owner);
+	else
+		return rtgui_dc_client_create(owner);
 }
 }
 
 
 void rtgui_dc_end_drawing(struct rtgui_dc* dc)
 void rtgui_dc_end_drawing(struct rtgui_dc* dc)
@@ -63,7 +61,7 @@ void rtgui_dc_end_drawing(struct rtgui_dc* dc)
 	dc->engine->fini(dc);
 	dc->engine->fini(dc);
 }
 }
 
 
-const struct rtgui_dc_engine dc_client_engine = 
+const struct rtgui_dc_engine dc_client_engine =
 {
 {
 	rtgui_dc_client_draw_point,
 	rtgui_dc_client_draw_point,
 	rtgui_dc_client_draw_color_point,
 	rtgui_dc_client_draw_color_point,
@@ -116,7 +114,7 @@ struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner)
 		if (RTGUI_WIDGET_IS_HIDE(widget))
 		if (RTGUI_WIDGET_IS_HIDE(widget))
 		{
 		{
 			RTGUI_WIDGET_DC_SET_UNVISIBLE(owner);
 			RTGUI_WIDGET_DC_SET_UNVISIBLE(owner);
-			break;
+			return RT_NULL;
 		}
 		}
 
 
 		widget = widget->parent;
 		widget = widget->parent;
@@ -130,7 +128,7 @@ struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner)
 		if (top->drawing == 1)
 		if (top->drawing == 1)
 		{
 		{
 #ifdef RTGUI_USING_MOUSE_CURSOR
 #ifdef RTGUI_USING_MOUSE_CURSOR
-#ifdef __WIN32__
+#ifdef _WIN32
 			rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
 			rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
 			rt_kprintf("hide cursor\n");
 			rt_kprintf("hide cursor\n");
 			rtgui_mouse_hide_cursor();
 			rtgui_mouse_hide_cursor();
@@ -141,15 +139,18 @@ struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner)
 #endif
 #endif
 		}
 		}
 	}
 	}
-	else if (RTGUI_IS_WORKBENCH(owner->toplevel) ||
-		RTGUI_IS_WIN(owner->toplevel))
+	else if (RTGUI_IS_APPLICATION(owner->toplevel))
+	{
+		RT_ASSERT(0);
+	}
+	else if (RTGUI_IS_WIN(owner->toplevel))
 	{
 	{
 		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
 		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
 		top->drawing ++;
 		top->drawing ++;
 
 
 		if (top->drawing == 1)
 		if (top->drawing == 1)
 		{
 		{
-#ifdef __WIN32__
+#ifdef _WIN32
 #ifdef RTGUI_USING_MOUSE_CURSOR
 #ifdef RTGUI_USING_MOUSE_CURSOR
 			rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
 			rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
 			rt_kprintf("hide cursor\n");
 			rt_kprintf("hide cursor\n");
@@ -161,7 +162,7 @@ struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner)
 			RTGUI_EVENT_UPDATE_BEGIN_INIT(&(eupdate));
 			RTGUI_EVENT_UPDATE_BEGIN_INIT(&(eupdate));
 			eupdate.rect = RTGUI_WIDGET(top)->extent;
 			eupdate.rect = RTGUI_WIDGET(top)->extent;
 
 
-			rtgui_thread_send(top->server, (struct rtgui_event*)&eupdate, sizeof(eupdate));
+			rtgui_server_post_event((struct rtgui_event*)&eupdate, sizeof(eupdate));
 #endif
 #endif
 		}
 		}
 	}
 	}
@@ -186,7 +187,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc)
 		top->drawing --;
 		top->drawing --;
 		if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
 		if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
 		{
 		{
-#ifdef __WIN32__
+#ifdef _WIN32
 #ifdef RTGUI_USING_MOUSE_CURSOR
 #ifdef RTGUI_USING_MOUSE_CURSOR
 			rt_mutex_release(&cursor_mutex);
 			rt_mutex_release(&cursor_mutex);
 			/* show cursor */
 			/* show cursor */
@@ -206,7 +207,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc)
 #endif
 #endif
 		}
 		}
 	}
 	}
-	else if (RTGUI_IS_WORKBENCH(owner->toplevel) ||
+	else if (RTGUI_IS_APPLICATION(owner->toplevel) ||
 		RTGUI_IS_WIN(owner->toplevel))
 		RTGUI_IS_WIN(owner->toplevel))
 	{
 	{
 		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
 		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
@@ -214,7 +215,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc)
 
 
 		if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
 		if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
 		{
 		{
-#ifdef __WIN32__
+#ifdef _WIN32
 #ifdef RTGUI_USING_MOUSE_CURSOR
 #ifdef RTGUI_USING_MOUSE_CURSOR
 			rt_mutex_release(&cursor_mutex);
 			rt_mutex_release(&cursor_mutex);
 			/* show cursor */
 			/* show cursor */
@@ -229,7 +230,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc)
 			RTGUI_EVENT_UPDATE_END_INIT(&(eupdate));
 			RTGUI_EVENT_UPDATE_END_INIT(&(eupdate));
 			eupdate.rect = owner->extent;
 			eupdate.rect = owner->extent;
 
 
-			rtgui_thread_send(top->server, (struct rtgui_event*)&eupdate, sizeof(eupdate));
+			rtgui_server_post_event((struct rtgui_event*)&eupdate, sizeof(eupdate));
 #endif
 #endif
 		}
 		}
 	}
 	}

+ 13 - 11
components/rtgui/common/dc_hw.c

@@ -15,9 +15,11 @@
 #include <rtgui/dc_hw.h>
 #include <rtgui/dc_hw.h>
 #include <rtgui/driver.h>
 #include <rtgui/driver.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/view.h>
+#include <rtgui/rtgui_application.h>
+#include <rtgui/rtgui_server.h>
+
+#include <rtgui/widgets/container.h>
 #include <rtgui/widgets/window.h>
 #include <rtgui/widgets/window.h>
-#include <rtgui/widgets/workbench.h>
 #include <rtgui/widgets/title.h>
 #include <rtgui/widgets/title.h>
 
 
 static void rtgui_dc_hw_draw_point(struct rtgui_dc* dc, int x, int y);
 static void rtgui_dc_hw_draw_point(struct rtgui_dc* dc, int x, int y);
@@ -81,7 +83,7 @@ struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner)
 		if (RTGUI_WIDGET_IS_HIDE(widget))
 		if (RTGUI_WIDGET_IS_HIDE(widget))
 		{
 		{
 			RTGUI_WIDGET_DC_SET_UNVISIBLE(owner);
 			RTGUI_WIDGET_DC_SET_UNVISIBLE(owner);
-			break;
+			return RT_NULL;
 		}
 		}
 
 
 		widget = widget->parent;
 		widget = widget->parent;
@@ -104,7 +106,7 @@ struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner)
 		if (top->drawing == 1)
 		if (top->drawing == 1)
 		{
 		{
 #ifdef RTGUI_USING_MOUSE_CURSOR
 #ifdef RTGUI_USING_MOUSE_CURSOR
-#ifdef __WIN32__
+#ifdef _WIN32
 			rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
 			rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
 			rt_kprintf("hide cursor\n");
 			rt_kprintf("hide cursor\n");
 			rtgui_mouse_hide_cursor();
 			rtgui_mouse_hide_cursor();
@@ -115,7 +117,7 @@ struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner)
 #endif
 #endif
 		}
 		}
 	}
 	}
-	else if (RTGUI_IS_WORKBENCH(owner->toplevel) ||
+	else if (RTGUI_IS_APPLICATION(owner->toplevel) ||
 		RTGUI_IS_WIN(owner->toplevel))
 		RTGUI_IS_WIN(owner->toplevel))
 	{
 	{
 		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
 		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
@@ -123,7 +125,7 @@ struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner)
 
 
 		if (top->drawing == 1)
 		if (top->drawing == 1)
 		{
 		{
-#ifdef __WIN32__
+#ifdef _WIN32
 #ifdef RTGUI_USING_MOUSE_CURSOR
 #ifdef RTGUI_USING_MOUSE_CURSOR
 			rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
 			rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
 			rt_kprintf("hide cursor\n");
 			rt_kprintf("hide cursor\n");
@@ -135,7 +137,7 @@ struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner)
 			RTGUI_EVENT_UPDATE_BEGIN_INIT(&(eupdate));
 			RTGUI_EVENT_UPDATE_BEGIN_INIT(&(eupdate));
 			eupdate.rect = RTGUI_WIDGET(top)->extent;
 			eupdate.rect = RTGUI_WIDGET(top)->extent;
 
 
-			rtgui_thread_send(top->server, (struct rtgui_event*)&eupdate, sizeof(eupdate));
+			rtgui_server_post_event((struct rtgui_event*)&eupdate, sizeof(eupdate));
 #endif
 #endif
 		}
 		}
 	}
 	}
@@ -162,7 +164,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc)
 		top->drawing --;
 		top->drawing --;
 		if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
 		if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
 		{
 		{
-#ifdef __WIN32__
+#ifdef _WIN32
 #ifdef RTGUI_USING_MOUSE_CURSOR
 #ifdef RTGUI_USING_MOUSE_CURSOR
 			rt_mutex_release(&cursor_mutex);
 			rt_mutex_release(&cursor_mutex);
 			/* show cursor */
 			/* show cursor */
@@ -182,7 +184,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc)
 #endif
 #endif
 		}
 		}
 	}
 	}
-	else if (RTGUI_IS_WORKBENCH(owner->toplevel) ||
+	else if (RTGUI_IS_APPLICATION(owner->toplevel) ||
 		RTGUI_IS_WIN(owner->toplevel))
 		RTGUI_IS_WIN(owner->toplevel))
 	{
 	{
 		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
 		rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
@@ -190,7 +192,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc)
 
 
 		if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
 		if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
 		{
 		{
-#ifdef __WIN32__
+#ifdef _WIN32
 #ifdef RTGUI_USING_MOUSE_CURSOR
 #ifdef RTGUI_USING_MOUSE_CURSOR
 			rt_mutex_release(&cursor_mutex);
 			rt_mutex_release(&cursor_mutex);
 			/* show cursor */
 			/* show cursor */
@@ -205,7 +207,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc)
 			RTGUI_EVENT_UPDATE_END_INIT(&(eupdate));
 			RTGUI_EVENT_UPDATE_END_INIT(&(eupdate));
 			eupdate.rect = owner->extent;
 			eupdate.rect = owner->extent;
 
 
-			rtgui_thread_send(top->server, (struct rtgui_event*)&eupdate, sizeof(eupdate));
+			rtgui_server_post_event((struct rtgui_event*)&eupdate, sizeof(eupdate));
 #endif
 #endif
 		}
 		}
 	}
 	}

+ 463 - 463
components/rtgui/common/filerw.c

@@ -1,463 +1,463 @@
-/*
- * File      : filerw.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-
-#include <rtgui/filerw.h>
-#include <rtgui/rtgui_system.h>
-
-#ifdef RTGUI_USING_DFS_FILERW
-#include <dfs_posix.h>
-
-/* standard file read/write */
-struct rtgui_filerw_stdio
-{
-	/* inherit from rtgui_filerw */
-	struct rtgui_filerw parent;
-
-	int fd;
-	rt_bool_t eof;
-};
-
-static int stdio_seek(struct rtgui_filerw *context, rt_off_t offset, int whence)
-{
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-	int stdio_whence[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
-
-	if (whence < RTGUI_FILE_SEEK_SET || whence > RTGUI_FILE_SEEK_END)
-	{
-		return -1;
-	}
-
-	return lseek(stdio_filerw->fd, offset, stdio_whence[whence]);
-}
-
-static int stdio_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum)
-{
-	int result;
-	
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-
-	/* end of file */
-	if (stdio_filerw->eof == RT_TRUE) return -1;
-
-	result = read(stdio_filerw->fd, ptr, size * maxnum);
-	if (result == 0) stdio_filerw->eof = RT_TRUE;
-
-	return result;
-}
-
-static int stdio_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num)
-{
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-
-	return write(stdio_filerw->fd, (char*)ptr, size * num);
-}
-
-static int stdio_tell(struct rtgui_filerw* context)
-{
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-
-	return lseek(stdio_filerw->fd, 0, SEEK_CUR);
-}
-
-static int stdio_eof(struct rtgui_filerw* context)
-{
-	int result;
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-
-	if (stdio_filerw->eof == RT_TRUE) result = 1;
-	else result = -1;
-
-	return result;
-}
-
-static int stdio_close(struct rtgui_filerw *context)
-{
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-
-	if (stdio_filerw)
-	{
-		close(stdio_filerw->fd);
-		rtgui_free(stdio_filerw);
-
-		return 0;
-	}
-
-	return -1;
-}
-#elif defined(RTGUI_USING_STDIO_FILERW)
-#include <stdio.h>
-
-/* standard file read/write */
-struct rtgui_filerw_stdio
-{
-	/* inherit from rtgui_filerw */
-	struct rtgui_filerw parent;
-
-	FILE* fp;
-};
-
-static int stdio_seek(struct rtgui_filerw *context, rt_off_t offset, int whence)
-{
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-	int stdio_whence[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
-
-	if (whence < RTGUI_FILE_SEEK_SET || whence > RTGUI_FILE_SEEK_END)
-	{
-		return -1;
-	}
-
-	if (fseek(stdio_filerw->fp, offset, stdio_whence[whence]) == 0)
-	{
-		return ftell(stdio_filerw->fp);
-	}
-
-	return -1;
-}
-
-static int stdio_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum)
-{
-	size_t nread;
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-
-	nread = fread(ptr, size, maxnum, stdio_filerw->fp);
-	if (nread == 0 && ferror(stdio_filerw->fp))
-	{
-		return -1;
-	}
-
-	return nread;
-}
-
-static int stdio_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num)
-{
-	size_t nwrote;
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-
-	nwrote = fwrite(ptr, size, num, stdio_filerw->fp);
-
-	if ( nwrote == 0 && ferror(stdio_filerw->fp) )
-	{
-		return -1;
-	}
-
-	return nwrote;
-}
-
-static int stdio_tell(struct rtgui_filerw* context)
-{
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-
-	return ftell(stdio_filerw->fp);
-}
-
-static int stdio_eof(struct rtgui_filerw* context)
-{
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-
-	return feof(stdio_filerw->fp);
-}
-
-static int stdio_close(struct rtgui_filerw *context)
-{
-	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
-
-	if (stdio_filerw)
-	{
-		fclose(stdio_filerw->fp);
-		rtgui_free(stdio_filerw);
-
-		return 0;
-	}
-
-	return -1;
-}
-#endif
-
-/* memory file read/write */
-struct rtgui_filerw_mem
-{
-	/* inherit from rtgui_filerw */
-	struct rtgui_filerw parent;
-
-	const rt_uint8_t *mem_base, *mem_position, *mem_end;
-};
-
-static int mem_seek(struct rtgui_filerw *context, rt_off_t offset, int whence)
-{
-	const rt_uint8_t* newpos;
-	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
-
-	RT_ASSERT(mem != RT_NULL);
-
-	switch (whence) {
-	case RTGUI_FILE_SEEK_SET:
-		newpos = mem->mem_base + offset;
-		break;
-
-	case RTGUI_FILE_SEEK_CUR:
-		newpos = mem->mem_position + offset;
-		break;
-
-	case RTGUI_FILE_SEEK_END:
-		newpos = mem->mem_end + offset;
-		break;
-
-	default:
-		return -1;
-	}
-
-	if ( newpos < mem->mem_base )
-		newpos = mem->mem_base;
-
-	if ( newpos > mem->mem_end )
-		newpos = mem->mem_end;
-
-	mem->mem_position = newpos;
-	return mem->mem_position- mem->mem_base;
-}
-
-static int mem_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum)
-{
-	int total_bytes;
-	int mem_available;
-	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
-
-	total_bytes = (maxnum * size);
-	if ( (maxnum <= 0) || (size <= 0) || ((total_bytes / maxnum) != size) )
-	{
-		return -1;
-	}
-
-	mem_available = mem->mem_end - mem->mem_position;
-	if (total_bytes > mem_available)
-		total_bytes = mem_available;
-
-	rt_memcpy(ptr, mem->mem_position, total_bytes);
-	mem->mem_position += total_bytes;
-
-	return (total_bytes / size);
-}
-
-static int mem_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num)
-{
-#if 0
-	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
-
-	if ((mem->mem_position + (num * size)) > mem->mem_end)
-	{
-		num = (mem->mem_end - mem->mem_position)/size;
-	}
-
-	rt_memcpy(mem->mem_position, ptr, num*size);
-	mem->mem_position += num*size;
-
-	return num;
-#else
-	return 0; /* not support memory write */
-#endif
-}
-
-static int mem_tell(struct rtgui_filerw* context)
-{
-	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
-
-	return mem->mem_position - mem->mem_base;
-}
-
-static int mem_eof(struct rtgui_filerw* context)
-{
-	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
-
-	return mem->mem_position >= mem->mem_end;
-}
-
-static int mem_close(struct rtgui_filerw *context)
-{
-	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
-
-	if (mem != RT_NULL)
-	{
-		rtgui_free(mem);
-		return 0;
-	}
-
-	return -1;
-}
-
-const rt_uint8_t* rtgui_filerw_mem_getdata(struct rtgui_filerw* context)
-{
-	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
-
-	/* check whether it's a memory filerw */
-	if (mem->parent.read != mem_read) return RT_NULL;
-
-	return mem->mem_base;
-}
-
-/* file read/write public interface */
-#ifdef RTGUI_USING_DFS_FILERW
-static int parse_mode(const char *mode)
-{
-  int f=0;
- 
-  for (;;)
-  {
-    switch (*mode)
-	{
-    case 0: return f;
-    case 'b': break;
-    case 'r': f=O_RDONLY; break;
-    case 'w': f=O_WRONLY|O_CREAT|O_TRUNC; break;
-    case 'a': f=O_WRONLY|O_CREAT|O_APPEND; break;
-    case '+': f=(f&(~O_WRONLY))|O_RDWR; break;
-    }
-
-    ++mode;
-  }
-}
-
-struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode)
-{
-	int fd;
-	struct rtgui_filerw_stdio *rw;
-
-	RT_ASSERT(filename != RT_NULL);
-
-	rw = RT_NULL;
-	fd = open(filename, parse_mode(mode), 0);
-
-	if ( fd >= 0 )
-	{
-		rw = (struct rtgui_filerw_stdio*) rtgui_malloc(sizeof(struct rtgui_filerw_stdio));
-		if (rw != RT_NULL)
-		{
-			rw->parent.seek  = stdio_seek;
-			rw->parent.read  = stdio_read;
-			rw->parent.write = stdio_write;
-			rw->parent.tell  = stdio_tell;
-			rw->parent.close = stdio_close;
-			rw->parent.eof	 = stdio_eof;
-
-			rw->fd  = fd;
-			rw->eof = RT_FALSE;
-		}
-	}
-
-	return &(rw->parent);
-}
-#elif defined(RTGUI_USING_STDIO_FILERW)
-struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode)
-{
-	FILE *fp;
-	struct rtgui_filerw_stdio *rw;
-
-	RT_ASSERT(filename != RT_NULL);
-
-	rw = RT_NULL;
-	fp = fopen(filename, mode);
-
-	if ( fp != NULL )
-	{
-		rw = (struct rtgui_filerw_stdio*) rtgui_malloc(sizeof(struct rtgui_filerw_stdio));
-		if (rw != RT_NULL)
-		{
-			rw->parent.seek  = stdio_seek;
-			rw->parent.read  = stdio_read;
-			rw->parent.write = stdio_write;
-			rw->parent.tell  = stdio_tell;
-			rw->parent.close = stdio_close;
-			rw->parent.eof	 = stdio_eof;
-
-			rw->fp = fp;
-		}
-	}
-
-	return &(rw->parent);
-}
-#endif
-
-struct rtgui_filerw* rtgui_filerw_create_mem(const rt_uint8_t* mem, rt_size_t size)
-{
-	struct rtgui_filerw_mem* rw;
-	RT_ASSERT(mem != RT_NULL);
-
-	rw = (struct rtgui_filerw_mem*) rtgui_malloc(sizeof(struct rtgui_filerw_mem));
-	if (rw != RT_NULL)
-	{
-		rw->parent.seek  = mem_seek;
-		rw->parent.read  = mem_read;
-		rw->parent.write = mem_write;
-		rw->parent.tell  = mem_tell;
-		rw->parent.eof	 = mem_eof;
-		rw->parent.close = mem_close;
-
-		rw->mem_base = mem;
-		rw->mem_position = mem;
-		rw->mem_end = mem + size;
-	}
-
-	return &(rw->parent);
-}
-
-int rtgui_filerw_seek(struct rtgui_filerw* context, rt_off_t offset, int whence)
-{
-	RT_ASSERT(context != RT_NULL);
-
-	return context->seek(context, offset, whence);
-}
-
-int rtgui_filerw_read(struct rtgui_filerw* context, void* buffer, rt_size_t size, rt_size_t count)
-{
-	RT_ASSERT(context != RT_NULL);
-
-	return context->read(context, buffer, size, count);
-}
-
-int rtgui_filerw_write(struct rtgui_filerw* context, const void* buffer, rt_size_t size, rt_size_t count)
-{
-	RT_ASSERT(context != RT_NULL);
-
-	return context->write(context, buffer, size, count);
-}
-
-int rtgui_filerw_eof	(struct rtgui_filerw* context)
-{
-	RT_ASSERT(context != RT_NULL);
-
-	return context->eof(context);
-}
-
-int rtgui_filerw_tell(struct rtgui_filerw* context)
-{
-	RT_ASSERT(context != RT_NULL);
-
-	return context->tell(context);
-}
-
-int rtgui_filerw_close(struct rtgui_filerw* context)
-{
-	int result;
-
-	RT_ASSERT(context != RT_NULL);
-
-	/* close context */
-	result = context->close(context);
-	if (result != 0)
-	{
-		/* close file failed */
-		return -1;
-	}
-
-	return 0;
-}
+/*
+ * File      : filerw.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+
+#include <rtgui/filerw.h>
+#include <rtgui/rtgui_system.h>
+
+#ifdef RTGUI_USING_DFS_FILERW
+#include <dfs_posix.h>
+
+/* standard file read/write */
+struct rtgui_filerw_stdio
+{
+	/* inherit from rtgui_filerw */
+	struct rtgui_filerw parent;
+
+	int fd;
+	rt_bool_t eof;
+};
+
+static int stdio_seek(struct rtgui_filerw *context, rt_off_t offset, int whence)
+{
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+	int stdio_whence[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
+
+	if (whence < RTGUI_FILE_SEEK_SET || whence > RTGUI_FILE_SEEK_END)
+	{
+		return -1;
+	}
+
+	return lseek(stdio_filerw->fd, offset, stdio_whence[whence]);
+}
+
+static int stdio_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum)
+{
+	int result;
+	
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+
+	/* end of file */
+	if (stdio_filerw->eof == RT_TRUE) return -1;
+
+	result = read(stdio_filerw->fd, ptr, size * maxnum);
+	if (result == 0) stdio_filerw->eof = RT_TRUE;
+
+	return result;
+}
+
+static int stdio_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num)
+{
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+
+	return write(stdio_filerw->fd, (char*)ptr, size * num);
+}
+
+static int stdio_tell(struct rtgui_filerw* context)
+{
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+
+	return lseek(stdio_filerw->fd, 0, SEEK_CUR);
+}
+
+static int stdio_eof(struct rtgui_filerw* context)
+{
+	int result;
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+
+	if (stdio_filerw->eof == RT_TRUE) result = 1;
+	else result = -1;
+
+	return result;
+}
+
+static int stdio_close(struct rtgui_filerw *context)
+{
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+
+	if (stdio_filerw)
+	{
+		close(stdio_filerw->fd);
+		rtgui_free(stdio_filerw);
+
+		return 0;
+	}
+
+	return -1;
+}
+#elif defined(RTGUI_USING_STDIO_FILERW)
+#include <stdio.h>
+
+/* standard file read/write */
+struct rtgui_filerw_stdio
+{
+	/* inherit from rtgui_filerw */
+	struct rtgui_filerw parent;
+
+	FILE* fp;
+};
+
+static int stdio_seek(struct rtgui_filerw *context, rt_off_t offset, int whence)
+{
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+	int stdio_whence[3] = {SEEK_SET, SEEK_CUR, SEEK_END};
+
+	if (whence < RTGUI_FILE_SEEK_SET || whence > RTGUI_FILE_SEEK_END)
+	{
+		return -1;
+	}
+
+	if (fseek(stdio_filerw->fp, offset, stdio_whence[whence]) == 0)
+	{
+		return ftell(stdio_filerw->fp);
+	}
+
+	return -1;
+}
+
+static int stdio_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum)
+{
+	size_t nread;
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+
+	nread = fread(ptr, size, maxnum, stdio_filerw->fp);
+	if (nread == 0 && ferror(stdio_filerw->fp))
+	{
+		return -1;
+	}
+
+	return nread;
+}
+
+static int stdio_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num)
+{
+	size_t nwrote;
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+
+	nwrote = fwrite(ptr, size, num, stdio_filerw->fp);
+
+	if ( nwrote == 0 && ferror(stdio_filerw->fp) )
+	{
+		return -1;
+	}
+
+	return nwrote;
+}
+
+static int stdio_tell(struct rtgui_filerw* context)
+{
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+
+	return ftell(stdio_filerw->fp);
+}
+
+static int stdio_eof(struct rtgui_filerw* context)
+{
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+
+	return feof(stdio_filerw->fp);
+}
+
+static int stdio_close(struct rtgui_filerw *context)
+{
+	struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context;
+
+	if (stdio_filerw)
+	{
+		fclose(stdio_filerw->fp);
+		rtgui_free(stdio_filerw);
+
+		return 0;
+	}
+
+	return -1;
+}
+#endif
+
+/* memory file read/write */
+struct rtgui_filerw_mem
+{
+	/* inherit from rtgui_filerw */
+	struct rtgui_filerw parent;
+
+	const rt_uint8_t *mem_base, *mem_position, *mem_end;
+};
+
+static int mem_seek(struct rtgui_filerw *context, rt_off_t offset, int whence)
+{
+	const rt_uint8_t* newpos;
+	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
+
+	RT_ASSERT(mem != RT_NULL);
+
+	switch (whence) {
+	case RTGUI_FILE_SEEK_SET:
+		newpos = mem->mem_base + offset;
+		break;
+
+	case RTGUI_FILE_SEEK_CUR:
+		newpos = mem->mem_position + offset;
+		break;
+
+	case RTGUI_FILE_SEEK_END:
+		newpos = mem->mem_end + offset;
+		break;
+
+	default:
+		return -1;
+	}
+
+	if ( newpos < mem->mem_base )
+		newpos = mem->mem_base;
+
+	if ( newpos > mem->mem_end )
+		newpos = mem->mem_end;
+
+	mem->mem_position = newpos;
+	return mem->mem_position- mem->mem_base;
+}
+
+static int mem_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum)
+{
+	int total_bytes;
+	int mem_available;
+	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
+
+	total_bytes = (maxnum * size);
+	if ( (maxnum <= 0) || (size <= 0) || ((total_bytes / maxnum) != size) )
+	{
+		return -1;
+	}
+
+	mem_available = mem->mem_end - mem->mem_position;
+	if (total_bytes > mem_available)
+		total_bytes = mem_available;
+
+	rt_memcpy(ptr, mem->mem_position, total_bytes);
+	mem->mem_position += total_bytes;
+
+	return (total_bytes / size);
+}
+
+static int mem_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num)
+{
+#if 0
+	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
+
+	if ((mem->mem_position + (num * size)) > mem->mem_end)
+	{
+		num = (mem->mem_end - mem->mem_position)/size;
+	}
+
+	rt_memcpy(mem->mem_position, ptr, num*size);
+	mem->mem_position += num*size;
+
+	return num;
+#else
+	return 0; /* not support memory write */
+#endif
+}
+
+static int mem_tell(struct rtgui_filerw* context)
+{
+	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
+
+	return mem->mem_position - mem->mem_base;
+}
+
+static int mem_eof(struct rtgui_filerw* context)
+{
+	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
+
+	return mem->mem_position >= mem->mem_end;
+}
+
+static int mem_close(struct rtgui_filerw *context)
+{
+	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
+
+	if (mem != RT_NULL)
+	{
+		rtgui_free(mem);
+		return 0;
+	}
+
+	return -1;
+}
+
+const rt_uint8_t* rtgui_filerw_mem_getdata(struct rtgui_filerw* context)
+{
+	struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context;
+
+	/* check whether it's a memory filerw */
+	if (mem->parent.read != mem_read) return RT_NULL;
+
+	return mem->mem_base;
+}
+
+/* file read/write public interface */
+#ifdef RTGUI_USING_DFS_FILERW
+static int parse_mode(const char *mode)
+{
+  int f=0;
+ 
+  for (;;)
+  {
+    switch (*mode)
+	{
+    case 0: return f;
+    case 'b': break;
+    case 'r': f=O_RDONLY; break;
+    case 'w': f=O_WRONLY|O_CREAT|O_TRUNC; break;
+    case 'a': f=O_WRONLY|O_CREAT|O_APPEND; break;
+    case '+': f=(f&(~O_WRONLY))|O_RDWR; break;
+    }
+
+    ++mode;
+  }
+}
+
+struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode)
+{
+	int fd;
+	struct rtgui_filerw_stdio *rw;
+
+	RT_ASSERT(filename != RT_NULL);
+
+	rw = RT_NULL;
+	fd = open(filename, parse_mode(mode), 0);
+
+	if ( fd >= 0 )
+	{
+		rw = (struct rtgui_filerw_stdio*) rtgui_malloc(sizeof(struct rtgui_filerw_stdio));
+		if (rw != RT_NULL)
+		{
+			rw->parent.seek  = stdio_seek;
+			rw->parent.read  = stdio_read;
+			rw->parent.write = stdio_write;
+			rw->parent.tell  = stdio_tell;
+			rw->parent.close = stdio_close;
+			rw->parent.eof	 = stdio_eof;
+
+			rw->fd  = fd;
+			rw->eof = RT_FALSE;
+		}
+	}
+
+	return &(rw->parent);
+}
+#elif defined(RTGUI_USING_STDIO_FILERW)
+struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode)
+{
+	FILE *fp;
+	struct rtgui_filerw_stdio *rw;
+
+	RT_ASSERT(filename != RT_NULL);
+
+	rw = RT_NULL;
+	fp = fopen(filename, mode);
+
+	if ( fp != NULL )
+	{
+		rw = (struct rtgui_filerw_stdio*) rtgui_malloc(sizeof(struct rtgui_filerw_stdio));
+		if (rw != RT_NULL)
+		{
+			rw->parent.seek  = stdio_seek;
+			rw->parent.read  = stdio_read;
+			rw->parent.write = stdio_write;
+			rw->parent.tell  = stdio_tell;
+			rw->parent.close = stdio_close;
+			rw->parent.eof	 = stdio_eof;
+
+			rw->fp = fp;
+		}
+	}
+
+	return &(rw->parent);
+}
+#endif
+
+struct rtgui_filerw* rtgui_filerw_create_mem(const rt_uint8_t* mem, rt_size_t size)
+{
+	struct rtgui_filerw_mem* rw;
+	RT_ASSERT(mem != RT_NULL);
+
+	rw = (struct rtgui_filerw_mem*) rtgui_malloc(sizeof(struct rtgui_filerw_mem));
+	if (rw != RT_NULL)
+	{
+		rw->parent.seek  = mem_seek;
+		rw->parent.read  = mem_read;
+		rw->parent.write = mem_write;
+		rw->parent.tell  = mem_tell;
+		rw->parent.eof	 = mem_eof;
+		rw->parent.close = mem_close;
+
+		rw->mem_base = mem;
+		rw->mem_position = mem;
+		rw->mem_end = mem + size;
+	}
+
+	return &(rw->parent);
+}
+
+int rtgui_filerw_seek(struct rtgui_filerw* context, rt_off_t offset, int whence)
+{
+	RT_ASSERT(context != RT_NULL);
+
+	return context->seek(context, offset, whence);
+}
+
+int rtgui_filerw_read(struct rtgui_filerw* context, void* buffer, rt_size_t size, rt_size_t count)
+{
+	RT_ASSERT(context != RT_NULL);
+
+	return context->read(context, buffer, size, count);
+}
+
+int rtgui_filerw_write(struct rtgui_filerw* context, const void* buffer, rt_size_t size, rt_size_t count)
+{
+	RT_ASSERT(context != RT_NULL);
+
+	return context->write(context, buffer, size, count);
+}
+
+int rtgui_filerw_eof	(struct rtgui_filerw* context)
+{
+	RT_ASSERT(context != RT_NULL);
+
+	return context->eof(context);
+}
+
+int rtgui_filerw_tell(struct rtgui_filerw* context)
+{
+	RT_ASSERT(context != RT_NULL);
+
+	return context->tell(context);
+}
+
+int rtgui_filerw_close(struct rtgui_filerw* context)
+{
+	int result;
+
+	RT_ASSERT(context != RT_NULL);
+
+	/* close context */
+	result = context->close(context);
+	if (result != 0)
+	{
+		/* close file failed */
+		return -1;
+	}
+
+	return 0;
+}

+ 237 - 237
components/rtgui/common/font_freetype.c

@@ -1,237 +1,237 @@
-#include <rtgui/font_freetype.h>
-
-#ifdef RTGUI_USING_TTF
-#include <ft2build.h>
-#include <freetype/freetype.h>
-#include <freetype/ftglyph.h>
-
-static void rtgui_freetype_font_draw_text(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect);
-static void rtgui_freetype_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect);
-
-struct rtgui_font_engine freetype_font_engine =
-{
-	RT_NULL,
-	RT_NULL,
-	rtgui_freetype_font_draw_text,
-	rtgui_freetype_font_get_metrics
-};
-
-struct rtgui_freetype_font
-{
-	int bold;
-	int italic;
-
-	FT_Face     face;
-	FT_Library  library;
-};
-
-static void gbk_to_unicode(rt_uint16_t *unicode, const unsigned char *text, int len)
-{
-	int i;
-	unsigned short wch;
-	extern unsigned short ff_convert(unsigned short wch, int direction);
-
-	for (i = 0; i < len; )
-	{
-		if (*text < 0x80)
-		{
-			wch = *text;
-			*unicode = ff_convert(wch, 1);
-			text ++;
-			i ++;
-		}
-		else
-		{
-			wch = wch = *(text + 1) | (*text << 8);
-			*unicode = ff_convert(wch, 1);
-			text += 2;
-			i += 2;
-		}
-
-		unicode ++;
-	}
-
-	*unicode = '\0';
-}
-
-static void rtgui_freetype_font_draw_text(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect)
-{
-	int index = 0;
-	FT_Error err = 0;
-	rt_uint16_t *text_short, *text_ptr;
-	struct rtgui_freetype_font* freetype;
-
-	RT_ASSERT(font != RT_NULL);
-	freetype = (struct rtgui_freetype_font*) font->data;
-	RT_ASSERT(freetype != RT_NULL);
-
-	/* allocate unicode buffer */
-	text_short = (rt_uint16_t*)rtgui_malloc((len + 1)* 2);
-	if (text_short == RT_NULL) return ; /* out of memory */
-
-	/* convert gbk to unicode */
-	gbk_to_unicode(text_short, text, len);
-	text_ptr = text_short;
-
-	while (*text_ptr)
-	{
-		index = FT_Get_Char_Index(freetype->face, *text_ptr);
-		err = FT_Load_Glyph(freetype->face, index, FT_LOAD_DEFAULT|FT_LOAD_RENDER);
-		if (err == 0)
-		{
-			int rows, x;
-			rt_uint8_t* ptr;
-
-			/* render font */
-			ptr = (rt_uint8_t*)freetype->face->glyph->bitmap.buffer;
-			
-			for (rows = 0; rows < freetype->face->glyph->bitmap.rows; rows ++)
-				for (x = 0; x < freetype->face->glyph->bitmap.width; x++)
-				{
-					if (*ptr > 0)
-						rtgui_dc_draw_color_point(dc, rect->x1 + x, rect->y1 + rows, RTGUI_RGB(0xff - *ptr, 0xff - *ptr, 0xff - *ptr));
-					ptr ++;
-				}
-		}
-
-		text_ptr ++;
-		rect->x1 += freetype->face->glyph->bitmap.width;
-	}
-
-	/* release unicode buffer */
-	rtgui_free(text_short);
-}
-
-static void rtgui_freetype_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect)
-{
-	int index = 0, len;
-	FT_Error err = 0;
-	rt_uint16_t w = 0, h = 0;
-	rt_uint16_t *text_short, *text_ptr;
-	struct rtgui_freetype_font* freetype;
-	
-	RT_ASSERT(font != RT_NULL);
-	RT_ASSERT(rect != RT_NULL);
-	freetype = (struct rtgui_freetype_font*) font->data;
-	RT_ASSERT(freetype != RT_NULL);
-
-	len = strlen(text);
-	memset(rect, 0, sizeof(struct rtgui_rect));
-
-	/* allocate unicode buffer */
-	text_short = (rt_uint16_t*)rtgui_malloc((len + 1)* 2);
-	if (text_short == RT_NULL) return ; /* out of memory */
-
-	/* convert gbk to unicode */
-	gbk_to_unicode(text_short, text, len);
-	text_ptr = text_short;
-
-	while (*text_ptr)
-	{
-		index = FT_Get_Char_Index(freetype->face, *text_ptr);
-		err = FT_Load_Glyph(freetype->face, index, FT_LOAD_DEFAULT);
-
-		if (err == 0)
-		{
-			w += freetype->face->glyph->bitmap.width;
-			if (freetype->face->glyph->bitmap.rows > h)
-			{
-				h = freetype->face->glyph->bitmap.rows;
-			}
-		}
-
-		text_ptr ++;
-	}
-
-	rect->x1 = 0; rect->y1 = 0;
-	rect->x2 = w; rect->y2 = h;
-
-	/* release unicode buffer */
-	rtgui_free(text_short);
-}
-
-rtgui_font_t* rtgui_freetype_font_create(const char* filename, int bold, int italic, rt_size_t size)
-{
-	FT_Error err = 0;
-	struct rtgui_font* font;
-
-	font = (struct rtgui_font*) rtgui_malloc (sizeof(struct rtgui_font));
-	if (font != RT_NULL)
-	{
-		struct rtgui_freetype_font* freetype;
-
-		freetype = (struct rtgui_freetype_font*) rtgui_malloc (sizeof(struct rtgui_freetype_font));
-		if (freetype == RT_NULL)
-		{
-			rt_free(font);
-			font = RT_NULL;
-		}
-		else
-		{
-			err = FT_Init_FreeType(&freetype->library);
-			if((err = FT_New_Face(freetype->library, filename, 0, &freetype->face)))
-			{
-				FT_Done_FreeType(freetype->library);
-
-				rt_free(font);
-				font = RT_NULL;
-			}
-			else
-			{
-				err = FT_Select_Charmap(freetype->face, ft_encoding_unicode);
-				if(err)
-				{
-					err = FT_Select_Charmap(freetype->face, ft_encoding_latin_1 );
-				}
-
-				err = FT_Set_Pixel_Sizes(freetype->face, 0, size);
-				if (err != 0)
-				{
-					rtgui_free(font);
-					font = RT_NULL;
-
-					FT_Done_FreeType(freetype->library);
-					rtgui_free(freetype);
-
-					return RT_NULL;
-				}
-
-				freetype->bold = bold;
-				freetype->italic = italic;
-
-				rt_kprintf("fonfile:%s\n", filename);
-				rt_kprintf("font family_name:%s\n", freetype->face->family_name);
-				rt_kprintf("font style_name:%s\n", freetype->face->style_name);
-
-				/* set user data */
-				font->data = freetype;
-				font->family = rt_strdup(freetype->face->family_name);
-				font->height = (rt_uint16_t)size;
-				font->refer_count = 0;
-				font->engine = &freetype_font_engine;
-
-				/* add to system */
-				rtgui_font_system_add_font(font);
-			}
-		}
-	}
-
-	return font;
-}
-
-void rtgui_freetype_font_destroy(rtgui_font_t* font)
-{
-	struct rtgui_freetype_font* freetype;
-	
-	RT_ASSERT(font != RT_NULL);
-	freetype = (struct rtgui_freetype_font*) font->data;
-	RT_ASSERT(freetype != RT_NULL);
-
-	rtgui_font_system_remove_font(font);
-
-	FT_Done_Face    (freetype->face);
-	FT_Done_FreeType(freetype->library);
-	rtgui_free(freetype);
-	rtgui_free(font);
-}
-#endif
+#include <rtgui/font_freetype.h>
+
+#ifdef RTGUI_USING_TTF
+#include <ft2build.h>
+#include <freetype/freetype.h>
+#include <freetype/ftglyph.h>
+
+static void rtgui_freetype_font_draw_text(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect);
+static void rtgui_freetype_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect);
+
+struct rtgui_font_engine freetype_font_engine =
+{
+	RT_NULL,
+	RT_NULL,
+	rtgui_freetype_font_draw_text,
+	rtgui_freetype_font_get_metrics
+};
+
+struct rtgui_freetype_font
+{
+	int bold;
+	int italic;
+
+	FT_Face     face;
+	FT_Library  library;
+};
+
+static void gbk_to_unicode(rt_uint16_t *unicode, const unsigned char *text, int len)
+{
+	int i;
+	unsigned short wch;
+	extern unsigned short ff_convert(unsigned short wch, int direction);
+
+	for (i = 0; i < len; )
+	{
+		if (*text < 0x80)
+		{
+			wch = *text;
+			*unicode = ff_convert(wch, 1);
+			text ++;
+			i ++;
+		}
+		else
+		{
+			wch = wch = *(text + 1) | (*text << 8);
+			*unicode = ff_convert(wch, 1);
+			text += 2;
+			i += 2;
+		}
+
+		unicode ++;
+	}
+
+	*unicode = '\0';
+}
+
+static void rtgui_freetype_font_draw_text(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect)
+{
+	int index = 0;
+	FT_Error err = 0;
+	rt_uint16_t *text_short, *text_ptr;
+	struct rtgui_freetype_font* freetype;
+
+	RT_ASSERT(font != RT_NULL);
+	freetype = (struct rtgui_freetype_font*) font->data;
+	RT_ASSERT(freetype != RT_NULL);
+
+	/* allocate unicode buffer */
+	text_short = (rt_uint16_t*)rtgui_malloc((len + 1)* 2);
+	if (text_short == RT_NULL) return ; /* out of memory */
+
+	/* convert gbk to unicode */
+	gbk_to_unicode(text_short, text, len);
+	text_ptr = text_short;
+
+	while (*text_ptr)
+	{
+		index = FT_Get_Char_Index(freetype->face, *text_ptr);
+		err = FT_Load_Glyph(freetype->face, index, FT_LOAD_DEFAULT|FT_LOAD_RENDER);
+		if (err == 0)
+		{
+			int rows, x;
+			rt_uint8_t* ptr;
+
+			/* render font */
+			ptr = (rt_uint8_t*)freetype->face->glyph->bitmap.buffer;
+			
+			for (rows = 0; rows < freetype->face->glyph->bitmap.rows; rows ++)
+				for (x = 0; x < freetype->face->glyph->bitmap.width; x++)
+				{
+					if (*ptr > 0)
+						rtgui_dc_draw_color_point(dc, rect->x1 + x, rect->y1 + rows, RTGUI_RGB(0xff - *ptr, 0xff - *ptr, 0xff - *ptr));
+					ptr ++;
+				}
+		}
+
+		text_ptr ++;
+		rect->x1 += freetype->face->glyph->bitmap.width;
+	}
+
+	/* release unicode buffer */
+	rtgui_free(text_short);
+}
+
+static void rtgui_freetype_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect)
+{
+	int index = 0, len;
+	FT_Error err = 0;
+	rt_uint16_t w = 0, h = 0;
+	rt_uint16_t *text_short, *text_ptr;
+	struct rtgui_freetype_font* freetype;
+	
+	RT_ASSERT(font != RT_NULL);
+	RT_ASSERT(rect != RT_NULL);
+	freetype = (struct rtgui_freetype_font*) font->data;
+	RT_ASSERT(freetype != RT_NULL);
+
+	len = strlen(text);
+	memset(rect, 0, sizeof(struct rtgui_rect));
+
+	/* allocate unicode buffer */
+	text_short = (rt_uint16_t*)rtgui_malloc((len + 1)* 2);
+	if (text_short == RT_NULL) return ; /* out of memory */
+
+	/* convert gbk to unicode */
+	gbk_to_unicode(text_short, text, len);
+	text_ptr = text_short;
+
+	while (*text_ptr)
+	{
+		index = FT_Get_Char_Index(freetype->face, *text_ptr);
+		err = FT_Load_Glyph(freetype->face, index, FT_LOAD_DEFAULT);
+
+		if (err == 0)
+		{
+			w += freetype->face->glyph->bitmap.width;
+			if (freetype->face->glyph->bitmap.rows > h)
+			{
+				h = freetype->face->glyph->bitmap.rows;
+			}
+		}
+
+		text_ptr ++;
+	}
+
+	rect->x1 = 0; rect->y1 = 0;
+	rect->x2 = w; rect->y2 = h;
+
+	/* release unicode buffer */
+	rtgui_free(text_short);
+}
+
+rtgui_font_t* rtgui_freetype_font_create(const char* filename, int bold, int italic, rt_size_t size)
+{
+	FT_Error err = 0;
+	struct rtgui_font* font;
+
+	font = (struct rtgui_font*) rtgui_malloc (sizeof(struct rtgui_font));
+	if (font != RT_NULL)
+	{
+		struct rtgui_freetype_font* freetype;
+
+		freetype = (struct rtgui_freetype_font*) rtgui_malloc (sizeof(struct rtgui_freetype_font));
+		if (freetype == RT_NULL)
+		{
+			rt_free(font);
+			font = RT_NULL;
+		}
+		else
+		{
+			err = FT_Init_FreeType(&freetype->library);
+			if((err = FT_New_Face(freetype->library, filename, 0, &freetype->face)))
+			{
+				FT_Done_FreeType(freetype->library);
+
+				rt_free(font);
+				font = RT_NULL;
+			}
+			else
+			{
+				err = FT_Select_Charmap(freetype->face, ft_encoding_unicode);
+				if(err)
+				{
+					err = FT_Select_Charmap(freetype->face, ft_encoding_latin_1 );
+				}
+
+				err = FT_Set_Pixel_Sizes(freetype->face, 0, size);
+				if (err != 0)
+				{
+					rtgui_free(font);
+					font = RT_NULL;
+
+					FT_Done_FreeType(freetype->library);
+					rtgui_free(freetype);
+
+					return RT_NULL;
+				}
+
+				freetype->bold = bold;
+				freetype->italic = italic;
+
+				rt_kprintf("fonfile:%s\n", filename);
+				rt_kprintf("font family_name:%s\n", freetype->face->family_name);
+				rt_kprintf("font style_name:%s\n", freetype->face->style_name);
+
+				/* set user data */
+				font->data = freetype;
+				font->family = rt_strdup(freetype->face->family_name);
+				font->height = (rt_uint16_t)size;
+				font->refer_count = 0;
+				font->engine = &freetype_font_engine;
+
+				/* add to system */
+				rtgui_font_system_add_font(font);
+			}
+		}
+	}
+
+	return font;
+}
+
+void rtgui_freetype_font_destroy(rtgui_font_t* font)
+{
+	struct rtgui_freetype_font* freetype;
+	
+	RT_ASSERT(font != RT_NULL);
+	freetype = (struct rtgui_freetype_font*) font->data;
+	RT_ASSERT(freetype != RT_NULL);
+
+	rtgui_font_system_remove_font(font);
+
+	FT_Done_Face    (freetype->face);
+	FT_Done_FreeType(freetype->library);
+	rtgui_free(freetype);
+	rtgui_free(font);
+}
+#endif

+ 2 - 2
components/rtgui/common/font_hz_bmp.c

@@ -86,7 +86,7 @@ static void rtgui_hz_bitmap_font_draw_text (struct rtgui_font* font, struct rtgu
 	while (length > 0)
 	while (length > 0)
 	{
 	{
 		len = 0;
 		len = 0;
-		while (((rt_uint8_t)*(text + len)) < 0x80 && *(text + len)) len ++;
+		while (((rt_uint8_t)*(text + len)) < 0x80 && *(text + len) && len < length) len ++;
 		/* draw text with English font */
 		/* draw text with English font */
 		if (len > 0)
 		if (len > 0)
 		{
 		{
@@ -97,7 +97,7 @@ static void rtgui_hz_bitmap_font_draw_text (struct rtgui_font* font, struct rtgu
 		}
 		}
 
 
 		len = 0;
 		len = 0;
-		while (((rt_uint8_t)*(text + len)) >= 0x80) len ++;
+		while (((rt_uint8_t)*(text + len)) >= 0x80 && len < length) len ++;
 		if (len > 0)
 		if (len > 0)
 		{
 		{
 			_rtgui_hz_bitmap_font_draw_text(bmp_font, dc, text, len, rect);
 			_rtgui_hz_bitmap_font_draw_text(bmp_font, dc, text, len, rect);

+ 2 - 2
components/rtgui/common/font_hz_file.c

@@ -177,7 +177,7 @@ static void rtgui_hz_file_font_draw_text(struct rtgui_font* font, struct rtgui_d
 	while (length > 0)
 	while (length > 0)
 	{
 	{
 		len = 0;
 		len = 0;
-		while (((rt_uint8_t)*(text + len)) < 0x80 && *(text + len)) len ++;
+		while (((rt_uint8_t)*(text + len)) < 0x80 && *(text + len) && len < length) len ++;
 		/* draw text with English font */
 		/* draw text with English font */
 		if (len > 0)
 		if (len > 0)
 		{
 		{
@@ -188,7 +188,7 @@ static void rtgui_hz_file_font_draw_text(struct rtgui_font* font, struct rtgui_d
 		}
 		}
 
 
 		len = 0;
 		len = 0;
-		while (((rt_uint8_t)*(text + len)) >= 0x80) len ++;
+		while (((rt_uint8_t)*(text + len)) >= 0x80 && len < length) len ++;
 		if (len > 0)
 		if (len > 0)
 		{
 		{
 			_rtgui_hz_file_font_draw_text(hz_file_font, dc, text, len, rect);
 			_rtgui_hz_file_font_draw_text(hz_file_font, dc, text, len, rect);

+ 225 - 225
components/rtgui/common/framebuffer_driver.c

@@ -1,225 +1,225 @@
-#include <rtgui/rtgui_system.h>
-#include <rtgui/driver.h>
-
-#define GET_PIXEL(dst, x, y, type)	\
-	(type *)((rt_uint8_t*)((dst)->framebuffer) + (y) * (dst)->pitch + (x) * ((dst)->bits_per_pixel/8))
-
-static void _rgb565_set_pixel(rtgui_color_t *c, int x, int y)
-{
-	*GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t) = rtgui_color_to_565(*c);
-}
-
-static void _rgb565_get_pixel(rtgui_color_t *c, int x, int y)
-{
-	rt_uint16_t pixel;
-
-	pixel = *GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t);
-
-	/* get pixel from color */
-	*c = rtgui_color_from_565(pixel);
-}
-
-static void _rgb565_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
-{
-	rt_ubase_t index;
-	rt_uint16_t pixel;
-	rt_uint16_t *pixel_ptr;
-
-	/* get pixel from color */
-	pixel = rtgui_color_to_565(*c);
-
-	/* get pixel pointer in framebuffer */
-	pixel_ptr = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint16_t);
-	
-	for (index = x1; index < x2; index ++)
-	{
-		*pixel_ptr = pixel;
-		pixel_ptr ++;
-	}
-}
-
-static void _rgb565_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
-{
-	rt_uint8_t *dst;
-	rt_uint16_t pixel;
-	rt_ubase_t index;
-
-	pixel = rtgui_color_to_565(*c);
-	dst = GET_PIXEL(rtgui_graphic_get_device(), x, y1, rt_uint8_t);
-	for (index = y1; index < y2; index ++)
-	{
-		*(rt_uint16_t*)dst = pixel;
-		dst += rtgui_graphic_get_device()->pitch;
-	}
-}
-
-static void _rgb565p_set_pixel(rtgui_color_t *c, int x, int y)
-{
-	*GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t) = rtgui_color_to_565p(*c);
-}
-
-static void _rgb565p_get_pixel(rtgui_color_t *c, int x, int y)
-{
-	rt_uint16_t pixel;
-
-	pixel = *GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t);
-
-	/* get pixel from color */
-	*c = rtgui_color_from_565p(pixel);
-}
-
-static void _rgb565p_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
-{
-	rt_ubase_t index;
-	rt_uint16_t pixel;
-	rt_uint16_t *pixel_ptr;
-
-	/* get pixel from color */
-	pixel = rtgui_color_to_565p(*c);
-
-	/* get pixel pointer in framebuffer */
-	pixel_ptr = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint16_t);
-	
-	for (index = x1; index < x2; index ++)
-	{
-		*pixel_ptr = pixel;
-		pixel_ptr ++;
-	}
-}
-
-static void _rgb565p_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
-{
-	rt_uint8_t *dst;
-	rt_uint16_t pixel;
-	rt_ubase_t index;
-
-	pixel = rtgui_color_to_565p(*c);
-	dst = GET_PIXEL(rtgui_graphic_get_device(), x, y1, rt_uint8_t);
-	for (index = y1; index < y2; index ++)
-	{
-		*(rt_uint16_t*)dst = pixel;
-		dst += rtgui_graphic_get_device()->pitch;
-	}
-}
-
-/* draw raw hline */
-static void framebuffer_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
-{
-	rt_uint8_t *dst;
-
-	dst = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint8_t);
-	rt_memcpy(dst, pixels, (x2 - x1) * (rtgui_graphic_get_device()->bits_per_pixel/8));
-}
-
-const struct rtgui_graphic_driver_ops _framebuffer_rgb565_ops = 
-{
-	_rgb565_set_pixel,
-	_rgb565_get_pixel,
-	_rgb565_draw_hline,
-	_rgb565_draw_vline,
-	framebuffer_draw_raw_hline,
-};
-
-const struct rtgui_graphic_driver_ops _framebuffer_rgb565p_ops = 
-{
-	_rgb565p_set_pixel,
-	_rgb565p_get_pixel,
-	_rgb565p_draw_hline,
-	_rgb565p_draw_vline,
-	framebuffer_draw_raw_hline,
-};
-
-#define FRAMEBUFFER	(rtgui_graphic_get_device()->framebuffer)
-#define MONO_PIXEL(framebuffer, x, y) \
-	((rt_uint8_t**)(framebuffer))[y/8][x]
-
-static void _mono_set_pixel(rtgui_color_t *c, int x, int y)
-{
-	if (*c == white)
-		MONO_PIXEL(FRAMEBUFFER, x, y) &= ~(1 << (y%8));
-	else
-		MONO_PIXEL(FRAMEBUFFER, x, y) |= (1 << (y%8));
-}
-
-static void _mono_get_pixel(rtgui_color_t *c, int x, int y)
-{
-	if (MONO_PIXEL(FRAMEBUFFER, x, y) & (1 << (y%8)))
-		*c = black;
-	else
-		*c = white;
-}
-
-static void _mono_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
-{
-	rt_ubase_t index;
-	
-	if (*c == white)
-		for (index = x1; index < x2; index ++)
-		{
-			MONO_PIXEL(FRAMEBUFFER, index, y) &= ~(1 << (y%8));
-		}
-	else
-		for (index = x1; index < x2; index ++)
-		{
-			MONO_PIXEL(FRAMEBUFFER, index, y) |= (1 << (y%8));
-		}
-}
-
-static void _mono_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
-{
-	rt_ubase_t index;
-	
-	if (*c == white)
-		for (index = y1; index < y2; index ++)
-		{
-			MONO_PIXEL(FRAMEBUFFER, x, index) &= ~(1 << (index%8));
-		}
-	else
-		for (index = y1; index < y2; index ++)
-		{
-			MONO_PIXEL(FRAMEBUFFER, x, index) |=  (1 << (index%8));
-		}
-}
-
-/* draw raw hline */
-static void _mono_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
-{
-	rt_ubase_t index;
-
-	for (index = x1; index < x2; index ++)
-	{
-		if (pixels[index/8] && (1 << (index % 8)))
-			MONO_PIXEL(FRAMEBUFFER, index, y) |=  (1 << (y%8));
-		else
-			MONO_PIXEL(FRAMEBUFFER, index, y) &= ~(1 << (y%8));
-	}
-}
-
-const struct rtgui_graphic_driver_ops _framebuffer_mono_ops = 
-{
-	_mono_set_pixel,
-	_mono_get_pixel,
-	_mono_draw_hline,
-	_mono_draw_vline,
-	_mono_draw_raw_hline,
-};
-
-const struct rtgui_graphic_driver_ops *rtgui_framebuffer_get_ops(int pixel_format)
-{
-	switch (pixel_format)
-	{
-	case RTGRAPHIC_PIXEL_FORMAT_MONO:
-		return &_framebuffer_mono_ops;
-	case RTGRAPHIC_PIXEL_FORMAT_GRAY4:
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_GRAY16:
-		break;
-	case RTGRAPHIC_PIXEL_FORMAT_RGB565:
-		return &_framebuffer_rgb565_ops;
-	case RTGRAPHIC_PIXEL_FORMAT_RGB565P:
-		return &_framebuffer_rgb565p_ops;
-	}
-
-	return RT_NULL;
-}
-
+#include <rtgui/rtgui_system.h>
+#include <rtgui/driver.h>
+
+#define GET_PIXEL(dst, x, y, type)	\
+	(type *)((rt_uint8_t*)((dst)->framebuffer) + (y) * (dst)->pitch + (x) * ((dst)->bits_per_pixel/8))
+
+static void _rgb565_set_pixel(rtgui_color_t *c, int x, int y)
+{
+	*GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t) = rtgui_color_to_565(*c);
+}
+
+static void _rgb565_get_pixel(rtgui_color_t *c, int x, int y)
+{
+	rt_uint16_t pixel;
+
+	pixel = *GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t);
+
+	/* get pixel from color */
+	*c = rtgui_color_from_565(pixel);
+}
+
+static void _rgb565_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
+{
+	rt_ubase_t index;
+	rt_uint16_t pixel;
+	rt_uint16_t *pixel_ptr;
+
+	/* get pixel from color */
+	pixel = rtgui_color_to_565(*c);
+
+	/* get pixel pointer in framebuffer */
+	pixel_ptr = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint16_t);
+	
+	for (index = x1; index < x2; index ++)
+	{
+		*pixel_ptr = pixel;
+		pixel_ptr ++;
+	}
+}
+
+static void _rgb565_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
+{
+	rt_uint8_t *dst;
+	rt_uint16_t pixel;
+	rt_ubase_t index;
+
+	pixel = rtgui_color_to_565(*c);
+	dst = GET_PIXEL(rtgui_graphic_get_device(), x, y1, rt_uint8_t);
+	for (index = y1; index < y2; index ++)
+	{
+		*(rt_uint16_t*)dst = pixel;
+		dst += rtgui_graphic_get_device()->pitch;
+	}
+}
+
+static void _rgb565p_set_pixel(rtgui_color_t *c, int x, int y)
+{
+	*GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t) = rtgui_color_to_565p(*c);
+}
+
+static void _rgb565p_get_pixel(rtgui_color_t *c, int x, int y)
+{
+	rt_uint16_t pixel;
+
+	pixel = *GET_PIXEL(rtgui_graphic_get_device(), x, y, rt_uint16_t);
+
+	/* get pixel from color */
+	*c = rtgui_color_from_565p(pixel);
+}
+
+static void _rgb565p_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
+{
+	rt_ubase_t index;
+	rt_uint16_t pixel;
+	rt_uint16_t *pixel_ptr;
+
+	/* get pixel from color */
+	pixel = rtgui_color_to_565p(*c);
+
+	/* get pixel pointer in framebuffer */
+	pixel_ptr = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint16_t);
+	
+	for (index = x1; index < x2; index ++)
+	{
+		*pixel_ptr = pixel;
+		pixel_ptr ++;
+	}
+}
+
+static void _rgb565p_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
+{
+	rt_uint8_t *dst;
+	rt_uint16_t pixel;
+	rt_ubase_t index;
+
+	pixel = rtgui_color_to_565p(*c);
+	dst = GET_PIXEL(rtgui_graphic_get_device(), x, y1, rt_uint8_t);
+	for (index = y1; index < y2; index ++)
+	{
+		*(rt_uint16_t*)dst = pixel;
+		dst += rtgui_graphic_get_device()->pitch;
+	}
+}
+
+/* draw raw hline */
+static void framebuffer_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
+{
+	rt_uint8_t *dst;
+
+	dst = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint8_t);
+	rt_memcpy(dst, pixels, (x2 - x1) * (rtgui_graphic_get_device()->bits_per_pixel/8));
+}
+
+const struct rtgui_graphic_driver_ops _framebuffer_rgb565_ops = 
+{
+	_rgb565_set_pixel,
+	_rgb565_get_pixel,
+	_rgb565_draw_hline,
+	_rgb565_draw_vline,
+	framebuffer_draw_raw_hline,
+};
+
+const struct rtgui_graphic_driver_ops _framebuffer_rgb565p_ops = 
+{
+	_rgb565p_set_pixel,
+	_rgb565p_get_pixel,
+	_rgb565p_draw_hline,
+	_rgb565p_draw_vline,
+	framebuffer_draw_raw_hline,
+};
+
+#define FRAMEBUFFER	(rtgui_graphic_get_device()->framebuffer)
+#define MONO_PIXEL(framebuffer, x, y) \
+	((rt_uint8_t**)(framebuffer))[y/8][x]
+
+static void _mono_set_pixel(rtgui_color_t *c, int x, int y)
+{
+	if (*c == white)
+		MONO_PIXEL(FRAMEBUFFER, x, y) &= ~(1 << (y%8));
+	else
+		MONO_PIXEL(FRAMEBUFFER, x, y) |= (1 << (y%8));
+}
+
+static void _mono_get_pixel(rtgui_color_t *c, int x, int y)
+{
+	if (MONO_PIXEL(FRAMEBUFFER, x, y) & (1 << (y%8)))
+		*c = black;
+	else
+		*c = white;
+}
+
+static void _mono_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
+{
+	rt_ubase_t index;
+	
+	if (*c == white)
+		for (index = x1; index < x2; index ++)
+		{
+			MONO_PIXEL(FRAMEBUFFER, index, y) &= ~(1 << (y%8));
+		}
+	else
+		for (index = x1; index < x2; index ++)
+		{
+			MONO_PIXEL(FRAMEBUFFER, index, y) |= (1 << (y%8));
+		}
+}
+
+static void _mono_draw_vline(rtgui_color_t *c, int x , int y1, int y2)
+{
+	rt_ubase_t index;
+	
+	if (*c == white)
+		for (index = y1; index < y2; index ++)
+		{
+			MONO_PIXEL(FRAMEBUFFER, x, index) &= ~(1 << (index%8));
+		}
+	else
+		for (index = y1; index < y2; index ++)
+		{
+			MONO_PIXEL(FRAMEBUFFER, x, index) |=  (1 << (index%8));
+		}
+}
+
+/* draw raw hline */
+static void _mono_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
+{
+	rt_ubase_t index;
+
+	for (index = x1; index < x2; index ++)
+	{
+		if (pixels[index/8] && (1 << (index % 8)))
+			MONO_PIXEL(FRAMEBUFFER, index, y) |=  (1 << (y%8));
+		else
+			MONO_PIXEL(FRAMEBUFFER, index, y) &= ~(1 << (y%8));
+	}
+}
+
+const struct rtgui_graphic_driver_ops _framebuffer_mono_ops = 
+{
+	_mono_set_pixel,
+	_mono_get_pixel,
+	_mono_draw_hline,
+	_mono_draw_vline,
+	_mono_draw_raw_hline,
+};
+
+const struct rtgui_graphic_driver_ops *rtgui_framebuffer_get_ops(int pixel_format)
+{
+	switch (pixel_format)
+	{
+	case RTGRAPHIC_PIXEL_FORMAT_MONO:
+		return &_framebuffer_mono_ops;
+	case RTGRAPHIC_PIXEL_FORMAT_GRAY4:
+		break;
+	case RTGRAPHIC_PIXEL_FORMAT_GRAY16:
+		break;
+	case RTGRAPHIC_PIXEL_FORMAT_RGB565:
+		return &_framebuffer_rgb565_ops;
+	case RTGRAPHIC_PIXEL_FORMAT_RGB565P:
+		return &_framebuffer_rgb565p_ops;
+	}
+
+	return RT_NULL;
+}
+

+ 15 - 15
components/rtgui/common/image.c

@@ -64,47 +64,47 @@ void rtgui_system_image_init(void)
 #endif
 #endif
 }
 }
 
 
-static struct rtgui_image_engine* rtgui_image_get_engine(const char* type)
+static struct rtgui_image_engine* rtgui_image_get_engine_by_filename(const char* fn)
 {
 {
 	struct rtgui_list_node *node;
 	struct rtgui_list_node *node;
 	struct rtgui_image_engine *engine;
 	struct rtgui_image_engine *engine;
+	const char* ext;
+
+	ext = fn + rt_strlen(fn);
+	while (ext != fn)
+	{
+		if (*ext == '.') { ext ++; break; }
+		ext --;
+	}
+	if (ext == fn) return RT_NULL; /* no ext */
 
 
 	rtgui_list_foreach(node, &_rtgui_system_image_list)
 	rtgui_list_foreach(node, &_rtgui_system_image_list)
 	{
 	{
 		engine = rtgui_list_entry(node, struct rtgui_image_engine, list);
 		engine = rtgui_list_entry(node, struct rtgui_image_engine, list);
-
-		if (strncasecmp(engine->name, type, strlen(engine->name)) ==0)
+		if (strncasecmp(engine->name, ext, strlen(engine->name)) == 0)
 			return engine;
 			return engine;
 	}
 	}
 
 
 	return RT_NULL;
 	return RT_NULL;
 }
 }
 
 
-#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
-static struct rtgui_image_engine* rtgui_image_get_engine_by_filename(const char* fn)
+static struct rtgui_image_engine* rtgui_image_get_engine(const char* type)
 {
 {
 	struct rtgui_list_node *node;
 	struct rtgui_list_node *node;
 	struct rtgui_image_engine *engine;
 	struct rtgui_image_engine *engine;
-	const char* ext;
-
-	ext = fn + rt_strlen(fn);
-	while (ext != fn)
-	{
-		if (*ext == '.') { ext ++; break; }
-		ext --;
-	}
-	if (ext == fn) return RT_NULL; /* no ext */
 
 
 	rtgui_list_foreach(node, &_rtgui_system_image_list)
 	rtgui_list_foreach(node, &_rtgui_system_image_list)
 	{
 	{
 		engine = rtgui_list_entry(node, struct rtgui_image_engine, list);
 		engine = rtgui_list_entry(node, struct rtgui_image_engine, list);
-		if (strncasecmp(engine->name, ext, strlen(engine->name)) == 0)
+
+		if (strncasecmp(engine->name, type, strlen(engine->name)) ==0)
 			return engine;
 			return engine;
 	}
 	}
 
 
 	return RT_NULL;
 	return RT_NULL;
 }
 }
 
 
+#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
 struct rtgui_image* rtgui_image_create_from_file(const char* type, const char* filename, rt_bool_t load)
 struct rtgui_image* rtgui_image_create_from_file(const char* type, const char* filename, rt_bool_t load)
 {
 {
 	struct rtgui_filerw* filerw;
 	struct rtgui_filerw* filerw;

+ 645 - 645
components/rtgui/common/image_bmp.c

@@ -1,645 +1,645 @@
-#include <rtthread.h>
-#include <rtgui/dc_hw.h>
-#include <rtgui/image.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/image_bmp.h>
-#include <rtgui/blit.h>
-
-#ifdef RTGUI_IMAGE_BMP
-/* Compression encodings for BMP files */
-#ifndef BI_RGB
-#define BI_RGB			0
-#define BI_RLE8			1
-#define BI_RLE4			2
-#define BI_BITFIELDS	3
-#endif
-
-#define hw_driver				(rtgui_graphic_driver_get_default())
-
-struct rtgui_image_bmp
-{
-	rt_bool_t is_loaded;
-
-	rt_uint32_t Rmask;
-	rt_uint32_t Gmask;
-	rt_uint32_t Bmask;
-
-	rt_size_t   pixel_offset;
-
-	rt_uint8_t  byte_per_pixel;
-	rt_uint8_t  pad;
-	rt_uint8_t  ExpandBMP;
-
-	rt_uint8_t *pixels;
-	rt_uint8_t *line_pixels;
-	rt_uint32_t pitch;
-
-	struct rtgui_filerw* filerw;
-};
-
-struct rtgui_image_bmp_header
-{
-	/* The Win32 BMP file header (14 bytes) */
-	char   magic[2];
-	rt_uint32_t bfSize;
-	rt_uint16_t bfReserved1;
-	rt_uint16_t bfReserved2;
-	rt_uint32_t bfOffBits;
-
-	/* The Win32 BITMAPINFOHEADER struct (40 bytes) */
-	rt_uint32_t biSize;
-	rt_int32_t  biWidth;
-	rt_int32_t  biHeight;
-	rt_uint16_t biPlanes;
-	rt_uint16_t biBitCount;
-	rt_uint32_t biCompression;
-	rt_uint32_t biSizeImage;
-	rt_int32_t  biXPelsPerMeter;
-	rt_int32_t  biYPelsPerMeter;
-	rt_uint32_t biClrUsed;
-	rt_uint32_t biClrImportant;
-};
-
-static rt_bool_t rtgui_image_bmp_check(struct rtgui_filerw* file);
-static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_filerw* file, rt_bool_t load);
-static void rtgui_image_bmp_unload(struct rtgui_image* image);
-static void rtgui_image_bmp_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect);
-
-struct rtgui_image_engine rtgui_image_bmp_engine =
-{
-	"bmp",
-	{ RT_NULL },
-	rtgui_image_bmp_check,
-	rtgui_image_bmp_load,
-	rtgui_image_bmp_unload,
-	rtgui_image_bmp_blit
-};
-
-rt_inline rt_uint32_t rtgui_filerw_read32(struct rtgui_filerw* src)
-{
-	rt_uint32_t value;
-	rtgui_filerw_read(src, &value, (sizeof value), 1);
-	return value;
-}
-
-rt_inline rt_uint16_t rtgui_filerw_read16(struct rtgui_filerw* src)
-{
-	rt_uint16_t value;
-	rtgui_filerw_read(src, &value, (sizeof value), 1);
-	return value;
-
-}
-
-static rt_bool_t rtgui_image_bmp_check(struct rtgui_filerw* file)
-{
-	char magic[2];
-	rt_bool_t is_bmp;
-	rt_off_t start;
-
-	if ( !file ) return 0;
-
-	start = rtgui_filerw_tell(file);
-
-	/* move to the beginning of file */
-	rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET);
-
-	is_bmp = RT_FALSE;
-	if ( rtgui_filerw_read(file, magic, 1, sizeof(magic)) == sizeof(magic) )
-	{
-		if (magic[0] == 'B' &&
-				magic[1] == 'M')
-		{
-			is_bmp = RT_TRUE;
-		}
-	}
-
-	rtgui_filerw_seek(file, start, RTGUI_FILE_SEEK_SET);
-
-	return(is_bmp);
-}
-
-static struct rtgui_image_palette* rtgui_image_bmp_load_palette(struct rtgui_image_bmp_header* header, struct rtgui_filerw* src)
-{
-	/* Load the palette, if any */
-	rt_size_t i;
-	struct rtgui_image_palette* palette;
-
-	if (header->biClrUsed == 0)
-		header->biClrUsed = 1 << header->biBitCount;
-
-	palette = rtgui_image_palette_create(header->biClrUsed);
-	if (palette == RT_NULL) return RT_NULL;
-
-	if ( header->biSize == 12 )
-	{
-		rt_uint8_t r, g, b;
-		for ( i = 0; i < (int)header->biClrUsed; ++i )
-		{
-			rtgui_filerw_read(src, &b, 1, 1);
-			rtgui_filerw_read(src, &g, 1, 1);
-			rtgui_filerw_read(src, &r, 1, 1);
-			palette->colors[i] = RTGUI_RGB(r, g, b);
-		}
-	}
-	else
-	{
-		rt_uint8_t r, g, b, a;
-		for ( i = 0; i < (int)header->biClrUsed; ++i )
-		{
-			rtgui_filerw_read(src, &b, 1, 1);
-			rtgui_filerw_read(src, &g, 1, 1);
-			rtgui_filerw_read(src, &r, 1, 1);
-			rtgui_filerw_read(src, &a, 1, 1);
-			palette->colors[i] = RTGUI_ARGB(a, r, g, b);
-		}
-	}
-
-	return palette;
-}
-
-static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_filerw* src, rt_bool_t load)
-{
-	rt_uint32_t Rmask;
-	rt_uint32_t Gmask;
-	rt_uint32_t Bmask;
-	int ExpandBMP, bmpPitch;
-	struct rtgui_image_bmp* bmp;
-	struct rtgui_image_bmp_header* header;
-	struct rtgui_image_palette* palette;
-
-	bmp = RT_NULL;
-	header = RT_NULL;
-	palette = RT_NULL;
-	header = (struct rtgui_image_bmp_header*) rtgui_malloc(sizeof(struct rtgui_image_bmp_header));
-	if (header == RT_NULL) return RT_FALSE;
-
-	if ( rtgui_filerw_read(src, header->magic, 1, sizeof(header->magic)) ==
-		sizeof(sizeof(header->magic)) )
-	{
-		if (header->magic[0] != 'B' ||
-			header->magic[1] != 'M')
-		{
-			goto __exit;
-		}
-	}
-
-	header->bfSize		= rtgui_filerw_read32(src);
-	header->bfReserved1	= rtgui_filerw_read16(src);
-	header->bfReserved2	= rtgui_filerw_read16(src);
-	header->bfOffBits	= rtgui_filerw_read32(src);
-
-	/* Read the Win32 BITMAPINFOHEADER */
-	header->biSize		= rtgui_filerw_read32(src);
-	if ( header->biSize == 12 )
-	{
-		header->biWidth		= (rt_uint32_t)rtgui_filerw_read16(src);
-		header->biHeight	= (rt_uint32_t)rtgui_filerw_read16(src);
-		header->biPlanes	= rtgui_filerw_read16(src);
-		header->biBitCount	= rtgui_filerw_read16(src);
-		header->biCompression	= BI_RGB;
-		header->biSizeImage	= 0;
-		header->biXPelsPerMeter	= 0;
-		header->biYPelsPerMeter	= 0;
-		header->biClrUsed	= 0;
-
-		header->biClrImportant	= 0;
-
-	}
-	else
-	{
-		header->biWidth		= rtgui_filerw_read32(src);
-		header->biHeight	= rtgui_filerw_read32(src);
-		header->biPlanes	= rtgui_filerw_read16(src);
-		header->biBitCount	= rtgui_filerw_read16(src);
-		header->biCompression	= rtgui_filerw_read32(src);
-		header->biSizeImage	= rtgui_filerw_read32(src);
-		header->biXPelsPerMeter	= rtgui_filerw_read32(src);
-		header->biYPelsPerMeter	= rtgui_filerw_read32(src);
-		header->biClrUsed	= rtgui_filerw_read32(src);
-		header->biClrImportant	= rtgui_filerw_read32(src);
-
-	}
-
-	/* allocate palette and expand 1 and 4 bit bitmaps to 8 bits per pixel */
-	switch (header->biBitCount)
-	{
-	case 1:
-		ExpandBMP = header->biBitCount;
-		palette = rtgui_image_bmp_load_palette(header, src);
-		header->biBitCount = 8;
-		break;
-
-	case 4:
-		ExpandBMP = header->biBitCount;
-		palette = rtgui_image_bmp_load_palette(header, src);
-		header->biBitCount = 8;
-		break;
-
-	case 8:
-		palette = rtgui_image_bmp_load_palette(header, src);
-		ExpandBMP = 0;
-		break;
-
-	default:
-		ExpandBMP = 0;
-		break;
-	}
-
-	/* We don't support any BMP compression right now */
-	Rmask = Gmask = Bmask = 0;
-	switch (header->biCompression)
-	{
-	case BI_RGB:
-		/* If there are no masks, use the defaults */
-		if ( header->bfOffBits == (14 + header->biSize) )
-		{
-			/* Default values for the BMP format */
-			switch (header->biBitCount)
-			{
-			case 15:
-			case 16:
-				Rmask = 0x7C00;
-				Gmask = 0x03E0;
-				Bmask = 0x001F;
-				break;
-
-			case 24:
-			case 32:
-				Rmask = 0x00FF0000;
-				Gmask = 0x0000FF00;
-				Bmask = 0x000000FF;
-				break;
-
-			default:
-				break;
-			}
-			break;
-		}
-		/* Fall through -- read the RGB masks */
-
-	case BI_BITFIELDS:
-		switch (header->biBitCount)
-		{
-		case 15:
-		case 16:
-		case 32:
-			Rmask = rtgui_filerw_read32(src);
-			Gmask = rtgui_filerw_read32(src);
-			Bmask = rtgui_filerw_read32(src);
-			break;
-
-		default:
-			break;
-		}
-		break;
-
-	default:
-		rt_kprintf("Compressed BMP files not supported\n");
-		goto __exit;
-	}
-
-	bmp = (struct rtgui_image_bmp*) rtgui_malloc(sizeof(struct rtgui_image_bmp));
-	if (bmp == RT_NULL)
-		goto __exit;
-
-	/* set image information */
-	image->w = header->biWidth;
-	image->h = header->biHeight;
-	image->engine = &rtgui_image_bmp_engine;
-	image->data = bmp;
-	bmp->filerw = src;
-	bmp->byte_per_pixel = header->biBitCount/8;
-	bmp->pitch = image->w * bmp->byte_per_pixel;
-	bmp->pixel_offset = header->bfOffBits;
-	bmp->Rmask = Rmask; bmp->Gmask = Gmask; bmp->Bmask = Bmask;
-	bmp->ExpandBMP = ExpandBMP;
-	if (palette != RT_NULL) image->palette = palette;
-
-	/* get padding */
-	switch (ExpandBMP)
-	{
-	case 1:
-		bmpPitch = (header->biWidth + 7) >> 3;
-		bmp->pad  = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
-		break;
-
-	case 4:
-		bmpPitch = (header->biWidth + 1) >> 1;
-		bmp->pad  = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
-		break;
-
-	default:
-		bmp->pad  = ((bmp->pitch%4) ? (4-(bmp->pitch%4)) : 0);
-		break;
-	}
-
-	if (load == RT_TRUE)
-	{
-		rt_uint8_t *bits;
-		rt_uint32_t i;
-
-		/* load all pixels */
-		bmp->pixels = rtgui_malloc(image->h * bmp->pitch);
-		if (bmp->pixels == RT_NULL)
-			goto __exit;
-
-		/* Read the pixels.  Note that the bmp image is upside down */
-		if ( rtgui_filerw_seek(src, bmp->pixel_offset, RTGUI_FILE_SEEK_SET) < 0)
-			goto __exit;
-
-		bits = bmp->pixels + image->h * bmp->pitch;
-		while ( bits > bmp->pixels )
-		{
-			bits -= bmp->pitch;
-			switch (ExpandBMP)
-			{
-			case 1:
-			case 4:
-				{
-					rt_uint8_t pixel = 0;
-					int   shift = (8 - ExpandBMP);
-					for ( i=0; i < image->w; ++i )
-					{
-						if ( i % (8/ExpandBMP) == 0 )
-						{
-							if ( !rtgui_filerw_read(src, &pixel, 1, 1) )
-								goto __exit;
-
-						}
-						*(bits+i) = (pixel>>shift);
-						pixel <<= ExpandBMP;
-					}
-				}
-				break;
-
-			default:
-				if ( rtgui_filerw_read(src, bits, 1, bmp->pitch) != bmp->pitch ) goto __exit;
-				break;
-			}
-
-			/* Skip padding bytes  */
-			if ( bmp->pad )
-			{
-				rt_uint8_t padbyte;
-				for ( i=0; i < bmp->pad; ++i )
-				{
-					rtgui_filerw_read(src, &padbyte, 1, 1);
-				}
-			}
-		}
-
-		rtgui_filerw_close(bmp->filerw);
-		bmp->line_pixels = RT_NULL;
-		bmp->filerw = RT_NULL;
-		bmp->pixel_offset = 0;
-	}
-	else
-	{
-		bmp->pixels = RT_NULL;
-		bmp->line_pixels = rtgui_malloc(bmp->pitch);
-	}
-
-	return RT_TRUE;
-
-__exit:
-	rtgui_free(header);
-	if (palette != RT_NULL)
-	{
-		rtgui_free(palette);
-		image->palette = RT_NULL;
-	}
-
-	if (bmp != RT_NULL)
-		rtgui_free(bmp->pixels);
-	rtgui_free(bmp);
-	return RT_FALSE;
-}
-
-static void rtgui_image_bmp_unload(struct rtgui_image* image)
-{
-	struct rtgui_image_bmp* bmp;
-
-	if (image != RT_NULL)
-	{
-		bmp = (struct rtgui_image_bmp*) image->data;
-
-		if (bmp->pixels != RT_NULL) rtgui_free(bmp->pixels);
-		if (bmp->line_pixels != RT_NULL) rtgui_free(bmp->line_pixels);
-		if (bmp->filerw != RT_NULL)
-		{
-			rtgui_filerw_close(bmp->filerw);
-			bmp->filerw = RT_NULL;
-		}
-
-		/* release data */
-		rtgui_free(bmp);
-	}
-}
-
-static void rtgui_image_bmp_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* dst_rect)
-{
-	int y;
-	rt_uint16_t w, h;
-	struct rtgui_image_bmp* bmp;
-
-	RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL);
-
-	/* this dc is not visible */
-	if (rtgui_dc_get_visible(dc) != RT_TRUE) return;
-
-	bmp = (struct rtgui_image_bmp*) image->data;
-	RT_ASSERT(bmp != RT_NULL);
-
-	/* the minimum rect */
-	if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
-	else w = rtgui_rect_width(*dst_rect);
-	if (image->h < rtgui_rect_height(*dst_rect)) h = image->h;
-	else h = rtgui_rect_height(*dst_rect);
-
-	if (bmp->pixels != RT_NULL)
-	{
-		rt_uint8_t* ptr;
-
-		/* get pixel pointer */
-		ptr = bmp->pixels;
-		if (bmp->byte_per_pixel == hw_driver->bits_per_pixel/8)
-		{
-			for (y = 0; y < h; y ++)
-			{
-				dc->engine->blit_line(dc, 
-					dst_rect->x1, dst_rect->x1 + w,
-					dst_rect->y1 + y, 
-					ptr);
-				ptr += bmp->pitch;
-			}
-		}
-		else
-		{
-			rt_size_t pitch;
-			rt_uint8_t *line_ptr;
-
-			if (image->palette == RT_NULL)
-			{
-				rtgui_blit_line_func blit_line;
-				line_ptr = (rt_uint8_t*) rtgui_malloc((hw_driver->bits_per_pixel/8) * w);
-				blit_line = rtgui_blit_line_get(hw_driver->bits_per_pixel/8 , bmp->byte_per_pixel);
-				pitch = w * bmp->byte_per_pixel;
-				if (line_ptr != RT_NULL)
-				{
-					for (y = 0; y < h; y ++)
-					{
-						blit_line(line_ptr, ptr, pitch);
-						dc->engine->blit_line(dc,
-							dst_rect->x1, dst_rect->x1 + w,
-							dst_rect->y1 + y, 
-							line_ptr);
-						ptr += bmp->pitch;
-					}
-				}
-				rtgui_free(line_ptr);
-			}
-			else
-			{
-				int x;
-				rtgui_color_t color;
-
-				/* use palette */
-				for (y = 0; y < h; y ++)
-				{
-					ptr = bmp->pixels + (y * bmp->pitch);
-					for (x = 0; x < w; x ++)
-					{
-						color = image->palette->colors[*ptr]; ptr ++;
-						rtgui_dc_draw_color_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, color);
-					}
-				}
-			}
-		}
-	}
-	else
-	{
-		int offset;
-		rt_uint8_t *bits;
-
-		/* calculate offset */
-		switch (bmp->ExpandBMP)
-		{
-		case 1:
-			offset = (image->h - h) * (image->w/8) * bmp->byte_per_pixel;
-			break;
-
-		case 4:
-			offset = (image->h - h) * (image->w/2) * bmp->byte_per_pixel;
-			break;
-
-		default:
-			offset = (image->h - h) * image->w * bmp->byte_per_pixel;
-			break;
-		}
-		/* seek to the begin of pixel data */
-		rtgui_filerw_seek(bmp->filerw, bmp->pixel_offset + offset, RTGUI_FILE_SEEK_SET);
-
-		if (bmp->ExpandBMP == 1 || bmp->ExpandBMP == 4)
-		{
-			int x;
-			rtgui_color_t color;
-			/* 1, 4 bit per pixels */
-
-			/* draw each line */
-			for (y = h - 1; y >= 0; y --)
-			{
-				/* read pixel data */
-				rt_uint8_t pixel = 0;
-				int   shift = (8 - bmp->ExpandBMP);
-				int i;
-
-				bits = bmp->line_pixels;
-				for ( i=0; i < image->w; ++i )
-				{
-					if ( i % (8/bmp->ExpandBMP) == 0 )
-					{
-						if ( !rtgui_filerw_read(bmp->filerw, &pixel, 1, 1) )
-							return;
-					}
-					*(bits+i) = (pixel>>shift);
-					pixel <<= bmp->ExpandBMP;
-				}
-
-				/* Skip padding bytes  */
-				if (bmp->pad)
-				{
-					int i;
-					rt_uint8_t padbyte;
-					for ( i=0; i < bmp->pad; ++i )
-						rtgui_filerw_read(bmp->filerw, &padbyte, 1, 1);
-				}
-
-				/* use palette */
-				bits = bmp->line_pixels;
-				for (x = 0; x < w; x ++)
-				{
-					color = image->palette->colors[*bits]; bits ++;
-					rtgui_dc_draw_color_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, color);
-				}
-			}
-		}
-		else
-		{
-			rt_uint8_t *line_ptr = (rt_uint8_t*) rtgui_malloc((hw_driver->bits_per_pixel/8) * w);
-			if (line_ptr == RT_NULL) return;
-
-			/* draw each line */
-			for (y = h - 1; y >= 0; y --)
-			{
-				/* read line pixels */
-				rtgui_filerw_read(bmp->filerw, bmp->line_pixels, 1, bmp->pitch);
-
-				/* Skip padding bytes  */
-				if (bmp->pad)
-				{
-					int i;
-					rt_uint8_t padbyte;
-					for ( i=0; i < bmp->pad; ++i )
-						rtgui_filerw_read(bmp->filerw, &padbyte, 1, 1);
-				}
-
-				if (image->palette == RT_NULL)
-				{
-					int pitch;
-					rtgui_blit_line_func blit_line;
-					blit_line = rtgui_blit_line_get(hw_driver->bits_per_pixel/8 , bmp->byte_per_pixel);
-					pitch = w * bmp->byte_per_pixel;
-					if (line_ptr != RT_NULL)
-					{
-						blit_line(line_ptr, bmp->line_pixels, pitch);
-						dc->engine->blit_line(dc,
-							dst_rect->x1, dst_rect->x1 + w,
-							dst_rect->y1 + y, 
-							line_ptr);
-					}
-				}
-				else 
-				{
-					int x;
-					rtgui_color_t color;
-
-					/* use palette */
-					bits = bmp->line_pixels;
-					for (x = 0; x < w; x ++)
-					{
-						color = image->palette->colors[*bits]; bits ++;
-						rtgui_dc_draw_color_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, color);
-					}
-				}
-			}
-			if (line_ptr != RT_NULL) rtgui_free(line_ptr);
-		}
-	}
-}
-
-void rtgui_image_bmp_init()
-{
-	/* register bmp on image system */
-	rtgui_image_register_engine(&rtgui_image_bmp_engine);
-}
-#endif
+#include <rtthread.h>
+#include <rtgui/dc_hw.h>
+#include <rtgui/image.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/image_bmp.h>
+#include <rtgui/blit.h>
+
+#ifdef RTGUI_IMAGE_BMP
+/* Compression encodings for BMP files */
+#ifndef BI_RGB
+#define BI_RGB			0
+#define BI_RLE8			1
+#define BI_RLE4			2
+#define BI_BITFIELDS	3
+#endif
+
+#define hw_driver				(rtgui_graphic_driver_get_default())
+
+struct rtgui_image_bmp
+{
+	rt_bool_t is_loaded;
+
+	rt_uint32_t Rmask;
+	rt_uint32_t Gmask;
+	rt_uint32_t Bmask;
+
+	rt_size_t   pixel_offset;
+
+	rt_uint8_t  byte_per_pixel;
+	rt_uint8_t  pad;
+	rt_uint8_t  ExpandBMP;
+
+	rt_uint8_t *pixels;
+	rt_uint8_t *line_pixels;
+	rt_uint32_t pitch;
+
+	struct rtgui_filerw* filerw;
+};
+
+struct rtgui_image_bmp_header
+{
+	/* The Win32 BMP file header (14 bytes) */
+	char   magic[2];
+	rt_uint32_t bfSize;
+	rt_uint16_t bfReserved1;
+	rt_uint16_t bfReserved2;
+	rt_uint32_t bfOffBits;
+
+	/* The Win32 BITMAPINFOHEADER struct (40 bytes) */
+	rt_uint32_t biSize;
+	rt_int32_t  biWidth;
+	rt_int32_t  biHeight;
+	rt_uint16_t biPlanes;
+	rt_uint16_t biBitCount;
+	rt_uint32_t biCompression;
+	rt_uint32_t biSizeImage;
+	rt_int32_t  biXPelsPerMeter;
+	rt_int32_t  biYPelsPerMeter;
+	rt_uint32_t biClrUsed;
+	rt_uint32_t biClrImportant;
+};
+
+static rt_bool_t rtgui_image_bmp_check(struct rtgui_filerw* file);
+static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_filerw* file, rt_bool_t load);
+static void rtgui_image_bmp_unload(struct rtgui_image* image);
+static void rtgui_image_bmp_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect);
+
+struct rtgui_image_engine rtgui_image_bmp_engine =
+{
+	"bmp",
+	{ RT_NULL },
+	rtgui_image_bmp_check,
+	rtgui_image_bmp_load,
+	rtgui_image_bmp_unload,
+	rtgui_image_bmp_blit
+};
+
+rt_inline rt_uint32_t rtgui_filerw_read32(struct rtgui_filerw* src)
+{
+	rt_uint32_t value;
+	rtgui_filerw_read(src, &value, (sizeof value), 1);
+	return value;
+}
+
+rt_inline rt_uint16_t rtgui_filerw_read16(struct rtgui_filerw* src)
+{
+	rt_uint16_t value;
+	rtgui_filerw_read(src, &value, (sizeof value), 1);
+	return value;
+
+}
+
+static rt_bool_t rtgui_image_bmp_check(struct rtgui_filerw* file)
+{
+	char magic[2];
+	rt_bool_t is_bmp;
+	rt_off_t start;
+
+	if ( !file ) return 0;
+
+	start = rtgui_filerw_tell(file);
+
+	/* move to the beginning of file */
+	rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET);
+
+	is_bmp = RT_FALSE;
+	if ( rtgui_filerw_read(file, magic, 1, sizeof(magic)) == sizeof(magic) )
+	{
+		if (magic[0] == 'B' &&
+				magic[1] == 'M')
+		{
+			is_bmp = RT_TRUE;
+		}
+	}
+
+	rtgui_filerw_seek(file, start, RTGUI_FILE_SEEK_SET);
+
+	return(is_bmp);
+}
+
+static struct rtgui_image_palette* rtgui_image_bmp_load_palette(struct rtgui_image_bmp_header* header, struct rtgui_filerw* src)
+{
+	/* Load the palette, if any */
+	rt_size_t i;
+	struct rtgui_image_palette* palette;
+
+	if (header->biClrUsed == 0)
+		header->biClrUsed = 1 << header->biBitCount;
+
+	palette = rtgui_image_palette_create(header->biClrUsed);
+	if (palette == RT_NULL) return RT_NULL;
+
+	if ( header->biSize == 12 )
+	{
+		rt_uint8_t r, g, b;
+		for ( i = 0; i < (int)header->biClrUsed; ++i )
+		{
+			rtgui_filerw_read(src, &b, 1, 1);
+			rtgui_filerw_read(src, &g, 1, 1);
+			rtgui_filerw_read(src, &r, 1, 1);
+			palette->colors[i] = RTGUI_RGB(r, g, b);
+		}
+	}
+	else
+	{
+		rt_uint8_t r, g, b, a;
+		for ( i = 0; i < (int)header->biClrUsed; ++i )
+		{
+			rtgui_filerw_read(src, &b, 1, 1);
+			rtgui_filerw_read(src, &g, 1, 1);
+			rtgui_filerw_read(src, &r, 1, 1);
+			rtgui_filerw_read(src, &a, 1, 1);
+			palette->colors[i] = RTGUI_ARGB(a, r, g, b);
+		}
+	}
+
+	return palette;
+}
+
+static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_filerw* src, rt_bool_t load)
+{
+	rt_uint32_t Rmask;
+	rt_uint32_t Gmask;
+	rt_uint32_t Bmask;
+	int ExpandBMP, bmpPitch;
+	struct rtgui_image_bmp* bmp;
+	struct rtgui_image_bmp_header* header;
+	struct rtgui_image_palette* palette;
+
+	bmp = RT_NULL;
+	header = RT_NULL;
+	palette = RT_NULL;
+	header = (struct rtgui_image_bmp_header*) rtgui_malloc(sizeof(struct rtgui_image_bmp_header));
+	if (header == RT_NULL) return RT_FALSE;
+
+	if ( rtgui_filerw_read(src, header->magic, 1, sizeof(header->magic)) ==
+		sizeof(sizeof(header->magic)) )
+	{
+		if (header->magic[0] != 'B' ||
+			header->magic[1] != 'M')
+		{
+			goto __exit;
+		}
+	}
+
+	header->bfSize		= rtgui_filerw_read32(src);
+	header->bfReserved1	= rtgui_filerw_read16(src);
+	header->bfReserved2	= rtgui_filerw_read16(src);
+	header->bfOffBits	= rtgui_filerw_read32(src);
+
+	/* Read the Win32 BITMAPINFOHEADER */
+	header->biSize		= rtgui_filerw_read32(src);
+	if ( header->biSize == 12 )
+	{
+		header->biWidth		= (rt_uint32_t)rtgui_filerw_read16(src);
+		header->biHeight	= (rt_uint32_t)rtgui_filerw_read16(src);
+		header->biPlanes	= rtgui_filerw_read16(src);
+		header->biBitCount	= rtgui_filerw_read16(src);
+		header->biCompression	= BI_RGB;
+		header->biSizeImage	= 0;
+		header->biXPelsPerMeter	= 0;
+		header->biYPelsPerMeter	= 0;
+		header->biClrUsed	= 0;
+
+		header->biClrImportant	= 0;
+
+	}
+	else
+	{
+		header->biWidth		= rtgui_filerw_read32(src);
+		header->biHeight	= rtgui_filerw_read32(src);
+		header->biPlanes	= rtgui_filerw_read16(src);
+		header->biBitCount	= rtgui_filerw_read16(src);
+		header->biCompression	= rtgui_filerw_read32(src);
+		header->biSizeImage	= rtgui_filerw_read32(src);
+		header->biXPelsPerMeter	= rtgui_filerw_read32(src);
+		header->biYPelsPerMeter	= rtgui_filerw_read32(src);
+		header->biClrUsed	= rtgui_filerw_read32(src);
+		header->biClrImportant	= rtgui_filerw_read32(src);
+
+	}
+
+	/* allocate palette and expand 1 and 4 bit bitmaps to 8 bits per pixel */
+	switch (header->biBitCount)
+	{
+	case 1:
+		ExpandBMP = header->biBitCount;
+		palette = rtgui_image_bmp_load_palette(header, src);
+		header->biBitCount = 8;
+		break;
+
+	case 4:
+		ExpandBMP = header->biBitCount;
+		palette = rtgui_image_bmp_load_palette(header, src);
+		header->biBitCount = 8;
+		break;
+
+	case 8:
+		palette = rtgui_image_bmp_load_palette(header, src);
+		ExpandBMP = 0;
+		break;
+
+	default:
+		ExpandBMP = 0;
+		break;
+	}
+
+	/* We don't support any BMP compression right now */
+	Rmask = Gmask = Bmask = 0;
+	switch (header->biCompression)
+	{
+	case BI_RGB:
+		/* If there are no masks, use the defaults */
+		if ( header->bfOffBits == (14 + header->biSize) )
+		{
+			/* Default values for the BMP format */
+			switch (header->biBitCount)
+			{
+			case 15:
+			case 16:
+				Rmask = 0x7C00;
+				Gmask = 0x03E0;
+				Bmask = 0x001F;
+				break;
+
+			case 24:
+			case 32:
+				Rmask = 0x00FF0000;
+				Gmask = 0x0000FF00;
+				Bmask = 0x000000FF;
+				break;
+
+			default:
+				break;
+			}
+			break;
+		}
+		/* Fall through -- read the RGB masks */
+
+	case BI_BITFIELDS:
+		switch (header->biBitCount)
+		{
+		case 15:
+		case 16:
+		case 32:
+			Rmask = rtgui_filerw_read32(src);
+			Gmask = rtgui_filerw_read32(src);
+			Bmask = rtgui_filerw_read32(src);
+			break;
+
+		default:
+			break;
+		}
+		break;
+
+	default:
+		rt_kprintf("Compressed BMP files not supported\n");
+		goto __exit;
+	}
+
+	bmp = (struct rtgui_image_bmp*) rtgui_malloc(sizeof(struct rtgui_image_bmp));
+	if (bmp == RT_NULL)
+		goto __exit;
+
+	/* set image information */
+	image->w = header->biWidth;
+	image->h = header->biHeight;
+	image->engine = &rtgui_image_bmp_engine;
+	image->data = bmp;
+	bmp->filerw = src;
+	bmp->byte_per_pixel = header->biBitCount/8;
+	bmp->pitch = image->w * bmp->byte_per_pixel;
+	bmp->pixel_offset = header->bfOffBits;
+	bmp->Rmask = Rmask; bmp->Gmask = Gmask; bmp->Bmask = Bmask;
+	bmp->ExpandBMP = ExpandBMP;
+	if (palette != RT_NULL) image->palette = palette;
+
+	/* get padding */
+	switch (ExpandBMP)
+	{
+	case 1:
+		bmpPitch = (header->biWidth + 7) >> 3;
+		bmp->pad  = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
+		break;
+
+	case 4:
+		bmpPitch = (header->biWidth + 1) >> 1;
+		bmp->pad  = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0);
+		break;
+
+	default:
+		bmp->pad  = ((bmp->pitch%4) ? (4-(bmp->pitch%4)) : 0);
+		break;
+	}
+
+	if (load == RT_TRUE)
+	{
+		rt_uint8_t *bits;
+		rt_uint32_t i;
+
+		/* load all pixels */
+		bmp->pixels = rtgui_malloc(image->h * bmp->pitch);
+		if (bmp->pixels == RT_NULL)
+			goto __exit;
+
+		/* Read the pixels.  Note that the bmp image is upside down */
+		if ( rtgui_filerw_seek(src, bmp->pixel_offset, RTGUI_FILE_SEEK_SET) < 0)
+			goto __exit;
+
+		bits = bmp->pixels + image->h * bmp->pitch;
+		while ( bits > bmp->pixels )
+		{
+			bits -= bmp->pitch;
+			switch (ExpandBMP)
+			{
+			case 1:
+			case 4:
+				{
+					rt_uint8_t pixel = 0;
+					int   shift = (8 - ExpandBMP);
+					for ( i=0; i < image->w; ++i )
+					{
+						if ( i % (8/ExpandBMP) == 0 )
+						{
+							if ( !rtgui_filerw_read(src, &pixel, 1, 1) )
+								goto __exit;
+
+						}
+						*(bits+i) = (pixel>>shift);
+						pixel <<= ExpandBMP;
+					}
+				}
+				break;
+
+			default:
+				if ( rtgui_filerw_read(src, bits, 1, bmp->pitch) != bmp->pitch ) goto __exit;
+				break;
+			}
+
+			/* Skip padding bytes  */
+			if ( bmp->pad )
+			{
+				rt_uint8_t padbyte;
+				for ( i=0; i < bmp->pad; ++i )
+				{
+					rtgui_filerw_read(src, &padbyte, 1, 1);
+				}
+			}
+		}
+
+		rtgui_filerw_close(bmp->filerw);
+		bmp->line_pixels = RT_NULL;
+		bmp->filerw = RT_NULL;
+		bmp->pixel_offset = 0;
+	}
+	else
+	{
+		bmp->pixels = RT_NULL;
+		bmp->line_pixels = rtgui_malloc(bmp->pitch);
+	}
+
+	return RT_TRUE;
+
+__exit:
+	rtgui_free(header);
+	if (palette != RT_NULL)
+	{
+		rtgui_free(palette);
+		image->palette = RT_NULL;
+	}
+
+	if (bmp != RT_NULL)
+		rtgui_free(bmp->pixels);
+	rtgui_free(bmp);
+	return RT_FALSE;
+}
+
+static void rtgui_image_bmp_unload(struct rtgui_image* image)
+{
+	struct rtgui_image_bmp* bmp;
+
+	if (image != RT_NULL)
+	{
+		bmp = (struct rtgui_image_bmp*) image->data;
+
+		if (bmp->pixels != RT_NULL) rtgui_free(bmp->pixels);
+		if (bmp->line_pixels != RT_NULL) rtgui_free(bmp->line_pixels);
+		if (bmp->filerw != RT_NULL)
+		{
+			rtgui_filerw_close(bmp->filerw);
+			bmp->filerw = RT_NULL;
+		}
+
+		/* release data */
+		rtgui_free(bmp);
+	}
+}
+
+static void rtgui_image_bmp_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* dst_rect)
+{
+	int y;
+	rt_uint16_t w, h;
+	struct rtgui_image_bmp* bmp;
+
+	RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL);
+
+	/* this dc is not visible */
+	if (rtgui_dc_get_visible(dc) != RT_TRUE) return;
+
+	bmp = (struct rtgui_image_bmp*) image->data;
+	RT_ASSERT(bmp != RT_NULL);
+
+	/* the minimum rect */
+	if (image->w < rtgui_rect_width(*dst_rect)) w = image->w;
+	else w = rtgui_rect_width(*dst_rect);
+	if (image->h < rtgui_rect_height(*dst_rect)) h = image->h;
+	else h = rtgui_rect_height(*dst_rect);
+
+	if (bmp->pixels != RT_NULL)
+	{
+		rt_uint8_t* ptr;
+
+		/* get pixel pointer */
+		ptr = bmp->pixels;
+		if (bmp->byte_per_pixel == hw_driver->bits_per_pixel/8)
+		{
+			for (y = 0; y < h; y ++)
+			{
+				dc->engine->blit_line(dc, 
+					dst_rect->x1, dst_rect->x1 + w,
+					dst_rect->y1 + y, 
+					ptr);
+				ptr += bmp->pitch;
+			}
+		}
+		else
+		{
+			rt_size_t pitch;
+			rt_uint8_t *line_ptr;
+
+			if (image->palette == RT_NULL)
+			{
+				rtgui_blit_line_func blit_line;
+				line_ptr = (rt_uint8_t*) rtgui_malloc((hw_driver->bits_per_pixel/8) * w);
+				blit_line = rtgui_blit_line_get(hw_driver->bits_per_pixel/8 , bmp->byte_per_pixel);
+				pitch = w * bmp->byte_per_pixel;
+				if (line_ptr != RT_NULL)
+				{
+					for (y = 0; y < h; y ++)
+					{
+						blit_line(line_ptr, ptr, pitch);
+						dc->engine->blit_line(dc,
+							dst_rect->x1, dst_rect->x1 + w,
+							dst_rect->y1 + y, 
+							line_ptr);
+						ptr += bmp->pitch;
+					}
+				}
+				rtgui_free(line_ptr);
+			}
+			else
+			{
+				int x;
+				rtgui_color_t color;
+
+				/* use palette */
+				for (y = 0; y < h; y ++)
+				{
+					ptr = bmp->pixels + (y * bmp->pitch);
+					for (x = 0; x < w; x ++)
+					{
+						color = image->palette->colors[*ptr]; ptr ++;
+						rtgui_dc_draw_color_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, color);
+					}
+				}
+			}
+		}
+	}
+	else
+	{
+		int offset;
+		rt_uint8_t *bits;
+
+		/* calculate offset */
+		switch (bmp->ExpandBMP)
+		{
+		case 1:
+			offset = (image->h - h) * (image->w/8) * bmp->byte_per_pixel;
+			break;
+
+		case 4:
+			offset = (image->h - h) * (image->w/2) * bmp->byte_per_pixel;
+			break;
+
+		default:
+			offset = (image->h - h) * image->w * bmp->byte_per_pixel;
+			break;
+		}
+		/* seek to the begin of pixel data */
+		rtgui_filerw_seek(bmp->filerw, bmp->pixel_offset + offset, RTGUI_FILE_SEEK_SET);
+
+		if (bmp->ExpandBMP == 1 || bmp->ExpandBMP == 4)
+		{
+			int x;
+			rtgui_color_t color;
+			/* 1, 4 bit per pixels */
+
+			/* draw each line */
+			for (y = h - 1; y >= 0; y --)
+			{
+				/* read pixel data */
+				rt_uint8_t pixel = 0;
+				int   shift = (8 - bmp->ExpandBMP);
+				int i;
+
+				bits = bmp->line_pixels;
+				for ( i=0; i < image->w; ++i )
+				{
+					if ( i % (8/bmp->ExpandBMP) == 0 )
+					{
+						if ( !rtgui_filerw_read(bmp->filerw, &pixel, 1, 1) )
+							return;
+					}
+					*(bits+i) = (pixel>>shift);
+					pixel <<= bmp->ExpandBMP;
+				}
+
+				/* Skip padding bytes  */
+				if (bmp->pad)
+				{
+					int i;
+					rt_uint8_t padbyte;
+					for ( i=0; i < bmp->pad; ++i )
+						rtgui_filerw_read(bmp->filerw, &padbyte, 1, 1);
+				}
+
+				/* use palette */
+				bits = bmp->line_pixels;
+				for (x = 0; x < w; x ++)
+				{
+					color = image->palette->colors[*bits]; bits ++;
+					rtgui_dc_draw_color_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, color);
+				}
+			}
+		}
+		else
+		{
+			rt_uint8_t *line_ptr = (rt_uint8_t*) rtgui_malloc((hw_driver->bits_per_pixel/8) * w);
+			if (line_ptr == RT_NULL) return;
+
+			/* draw each line */
+			for (y = h - 1; y >= 0; y --)
+			{
+				/* read line pixels */
+				rtgui_filerw_read(bmp->filerw, bmp->line_pixels, 1, bmp->pitch);
+
+				/* Skip padding bytes  */
+				if (bmp->pad)
+				{
+					int i;
+					rt_uint8_t padbyte;
+					for ( i=0; i < bmp->pad; ++i )
+						rtgui_filerw_read(bmp->filerw, &padbyte, 1, 1);
+				}
+
+				if (image->palette == RT_NULL)
+				{
+					int pitch;
+					rtgui_blit_line_func blit_line;
+					blit_line = rtgui_blit_line_get(hw_driver->bits_per_pixel/8 , bmp->byte_per_pixel);
+					pitch = w * bmp->byte_per_pixel;
+					if (line_ptr != RT_NULL)
+					{
+						blit_line(line_ptr, bmp->line_pixels, pitch);
+						dc->engine->blit_line(dc,
+							dst_rect->x1, dst_rect->x1 + w,
+							dst_rect->y1 + y, 
+							line_ptr);
+					}
+				}
+				else 
+				{
+					int x;
+					rtgui_color_t color;
+
+					/* use palette */
+					bits = bmp->line_pixels;
+					for (x = 0; x < w; x ++)
+					{
+						color = image->palette->colors[*bits]; bits ++;
+						rtgui_dc_draw_color_point(dc, dst_rect->x1 + x, dst_rect->y1 + y, color);
+					}
+				}
+			}
+			if (line_ptr != RT_NULL) rtgui_free(line_ptr);
+		}
+	}
+}
+
+void rtgui_image_bmp_init()
+{
+	/* register bmp on image system */
+	rtgui_image_register_engine(&rtgui_image_bmp_engine);
+}
+#endif

+ 445 - 445
components/rtgui/common/image_container.c

@@ -1,445 +1,445 @@
-#include <rtgui/image_container.h>
-
-#ifdef RTGUI_IMAGE_CONTAINER
-typedef unsigned int (*rtgui_hash_func_t) (const void* key);
-typedef struct _rtgui_hash_table  rtgui_hash_table_t;
-typedef rt_bool_t (*rtgui_equal_func_t) (const void* a, const void* b);
-typedef void (*rtgui_user_func_t) (const void* value, const void* data);
-
-/*
- *Hash tables
- */
-rtgui_hash_table_t* hash_table_create(rtgui_hash_func_t hash_func, rtgui_equal_func_t key_equal_func);
-void hash_table_destroy (rtgui_hash_table_t* hash_table);
-
-void* hash_table_find (rtgui_hash_table_t* hash_table, void* key);
-void hash_table_insert (rtgui_hash_table_t* hash_table, void* key, void* value);
-rt_bool_t hash_table_remove (rtgui_hash_table_t* hash_table, void* key);
-
-void hash_table_foreach(rtgui_hash_table_t* hash_table, rtgui_user_func_t user_func, void* data);
-unsigned int hash_table_get_size (rtgui_hash_table_t* hash_table);
-
-/* Hash Functions
- */
-unsigned int direct_hash (void* v);
-
-#define HASH_TABLE_MIN_SIZE 11
-#define HASH_TABLE_MAX_SIZE 6247
-
-typedef struct _gui_hash_node rtgui_hash_node_t;
-struct _gui_hash_node
-{
-	void* key;
-	void* value;
-	rtgui_hash_node_t *next;
-};
-
-struct _rtgui_hash_table
-{
-	rt_uint16_t size;
-	rt_uint16_t nnodes;
-
-	rtgui_hash_node_t **nodes;
-	rtgui_hash_func_t hash_func;
-	rtgui_equal_func_t key_equal_func;
-};
-
-static const unsigned int primes[] =
-{
-	11,
-	19,
-	37,
-	73,
-	109,
-	163,
-	251,
-	367,
-	557,
-	823,
-	1237,
-	1861,
-	2777,
-	4177,
-	6247,
-/*
-	9371,
-	14057,
-	21089,
-	31627,
-	47431,
-	71143,
-	106721,
-	160073,
-	240101,
-	360163,
-	540217,
-	810343,
-	1215497,
-	1823231,
-	2734867,
-	4102283,
-	6153409,
-	9230113,
-	13845163,
-*/
-};
-
-static const unsigned int nprimes = sizeof (primes) / sizeof (primes[0]);
-
-static void hash_table_resize (rtgui_hash_table_t *hash_table);
-static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, void* key);
-static rtgui_hash_node_t* hash_node_create (void* key, void* value);
-static void hash_node_destroy (rtgui_hash_node_t *hash_node);
-static void hash_nodes_destroy (rtgui_hash_node_t *hash_node);
-static unsigned int primes_closest (unsigned int num);
-static void hash_table_needresize(rtgui_hash_table_t *hash_table);
-
-rt_inline unsigned int primes_closest (unsigned int num)
-{
-	int i;
-
-	for (i = 0; i < nprimes; i++)
-		if (primes[i] > num)
-			return primes[i];
-
-	return primes[nprimes - 1];
-}
-
-/* directly hash */
-unsigned int direct_hash (void* v)
-{
-	return (unsigned int)v;
-}
-
-rtgui_hash_table_t* hash_table_create(rtgui_hash_func_t hash_func, rtgui_equal_func_t key_equal_func)
-{
-	rtgui_hash_table_t *hash_table;
-
-	hash_table = (rtgui_hash_table_t*) rt_malloc (sizeof(rtgui_hash_table_t));
-	if (hash_table != RT_NULL)
-	{
-		hash_table->size               = HASH_TABLE_MIN_SIZE;
-		hash_table->nnodes             = 0;
-		hash_table->hash_func          = hash_func ? hash_func : direct_hash;
-		hash_table->key_equal_func     = key_equal_func;
-		hash_table->nodes              = (rtgui_hash_node_t **)rt_malloc ( sizeof(rtgui_hash_node_t*) * hash_table->size);
-		if (hash_table->nodes == RT_NULL)
-		{
-			/* no memory yet */
-			rt_free(hash_table);
-			return RT_NULL;
-		}
-
-		rt_memset(hash_table->nodes, 0, sizeof(rtgui_hash_node_t*) * hash_table->size);
-	}
-
-	return hash_table;
-}
-
-void hash_table_destroy (rtgui_hash_table_t *hash_table)
-{
-	unsigned int i;
-
-	RT_ASSERT(hash_table != RT_NULL);
-
-	for (i = 0; i < hash_table->size; i++)
-		hash_nodes_destroy (hash_table->nodes[i]);
-
-	rt_free (hash_table->nodes);
-	rt_free (hash_table);
-}
-
-static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, void* key)
-{
-	rtgui_hash_node_t **node;
-
-	node = &hash_table->nodes [(* hash_table->hash_func) (key) % hash_table->size];
-
-	if (hash_table->key_equal_func)
-		while (*node && !(*hash_table->key_equal_func) ((*node)->key, key))
-			node = &(*node)->next;
-	else
-		while (*node && (*node)->key != key)
-			node = &(*node)->next;
-
-	return node;
-}
-
-void* hash_table_find (rtgui_hash_table_t* hash_table, void* key)
-{
-	rtgui_hash_node_t *node;
-
-	RT_ASSERT(hash_table != RT_NULL);
-	RT_ASSERT(key != RT_NULL);
-
-	node = *hash_table_find_node (hash_table, key);
-
-	if (node) return node->value;
-	else return RT_NULL;
-}
-
-void hash_table_insert (rtgui_hash_table_t *hash_table, void* key, void* value)
-{
-	rtgui_hash_node_t **node;
-
-	if (hash_table == RT_NULL)return;
-
-	node = hash_table_find_node (hash_table, key);
-	if (*node)
-	{
-		(*node)->value = value;
-	}
-	else
-	{
-		*node = hash_node_create (key, value);
-		hash_table->nnodes++;
-		hash_table_needresize (hash_table);
-	}
-}
-
-rt_bool_t hash_table_remove (rtgui_hash_table_t *hash_table, void*  key)
-{
-	rtgui_hash_node_t **node, *dest;
-
-	if (hash_table == RT_NULL) return RT_FALSE;
-
-	node = hash_table_find_node (hash_table, key);
-	if (*node)
-	{
-		dest = *node;
-		(*node) = dest->next;
-		hash_node_destroy (dest);
-		hash_table->nnodes--;
-
-		hash_table_needresize (hash_table);
-
-		return RT_TRUE;
-	}
-
-	return RT_FALSE;
-}
-
-void hash_table_foreach(rtgui_hash_table_t *hash_table, rtgui_user_func_t user_func, void* data)
-{
-	rtgui_hash_node_t *node;
-	int i;
-
-	RT_ASSERT(hash_table != RT_NULL);
-	RT_ASSERT(user_func != RT_NULL);
-
-	for (i = 0; i < hash_table->size; i++)
-		for (node = hash_table->nodes[i]; node; node = node->next)
-			(* user_func) (node->value, data);
-}
-
-unsigned int hash_table_get_size (rtgui_hash_table_t *hash_table)
-{
-	if ( hash_table ==NULL ) return 0;
-
-	return hash_table->nnodes;
-}
-
-static void hash_table_needresize(rtgui_hash_table_t *hash_table)
-{
-	if ((hash_table->size >= 3*hash_table->nnodes && hash_table->size > HASH_TABLE_MIN_SIZE) ||
-	        (3 * hash_table->size <= hash_table->nnodes && hash_table->size < HASH_TABLE_MAX_SIZE))
-		hash_table_resize (hash_table);
-}
-
-static void hash_table_resize (rtgui_hash_table_t *hash_table)
-{
-	rtgui_hash_node_t **new_nodes;
-	rtgui_hash_node_t *node;
-	rtgui_hash_node_t *next;
-	unsigned int hash_val;
-	int new_size;
-	int i;
-
-	i = primes_closest(hash_table->nnodes);
-	new_size = i > HASH_TABLE_MAX_SIZE ? HASH_TABLE_MAX_SIZE : i < HASH_TABLE_MIN_SIZE ? HASH_TABLE_MIN_SIZE : i ;
-
-	new_nodes = (rtgui_hash_node_t **)rt_malloc ( sizeof(rtgui_hash_node_t*) * new_size);
-	if (new_nodes == RT_NULL) return; /* no memory yet */
-	rt_memset(new_nodes, 0, sizeof(rtgui_hash_node_t*) * new_size);
-
-	for (i = 0; i < hash_table->size; i++)
-	{
-		for (node = hash_table->nodes[i]; node; node = next)
-		{
-			next = node->next;
-
-			hash_val = (* hash_table->hash_func) (node->key) % new_size;
-
-			node->next = new_nodes[hash_val];
-			new_nodes[hash_val] = node;
-		}
-	}
-
-	rt_free (hash_table->nodes);
-	hash_table->nodes = new_nodes;
-	hash_table->size = new_size;
-}
-
-static rtgui_hash_node_t* hash_node_create (void* key, void* value)
-{
-	rtgui_hash_node_t *hash_node;
-
-	hash_node = (rtgui_hash_node_t*) rt_malloc ( sizeof(rtgui_hash_node_t) );
-	if (hash_node != RT_NULL)
-	{
-		/* set value and key */
-		hash_node->key = key;
-		hash_node->value = value;;
-
-		hash_node->next = RT_NULL;
-	}
-
-	return hash_node;
-}
-
-static void hash_node_destroy (rtgui_hash_node_t *hash_node)
-{
-	rt_free(hash_node);
-}
-
-static void hash_nodes_destroy (rtgui_hash_node_t *hash_node)
-{
-	if (hash_node)
-	{
-		rtgui_hash_node_t *node = hash_node;
-		rtgui_hash_node_t *temp;
-
-		while (node->next)
-		{
-			node->key = NULL;
-			node->value = NULL;
-
-			temp = node;
-			node = node->next;
-			rt_free(temp);
-		}
-
-		node->key = NULL;
-		node->value = NULL;
-		rt_free(node);
-	}
-}
-
-unsigned int string_hash_func(const void* self)
-{
-	const char *p;
-	int h=0, g;
-
-	for(p = self; *p != '\0'; p += 1)
-	{
-		h = ( h << 4 ) + *p;
-		if ( ( g = h & 0xf0000000 ) )
-		{
-			h = h ^ (g >> 24);
-			h = h ^ g;
-		}
-	}
-
-	return h ;
-}
-rt_bool_t string_equal_func(const void* a, const void* b)
-{
-	const char *str1, *str2;
-
-	str1 = (const char*)a;
-	str2 = (const char*)b;
-
-	if (strcmp(str1, str2) == 0) return RT_TRUE;
-	return RT_FALSE;
-}
-
-static rtgui_hash_table_t* image_hash_table;
-static rt_bool_t load_image = RT_FALSE;
-void rtgui_system_image_container_init(rt_bool_t load)
-{
-	/* create image hash table */
-	image_hash_table = hash_table_create(string_hash_func, string_equal_func);
-	RT_ASSERT(image_hash_table != RT_NULL);
-
-	/* set load type */
-	load_image = load;
-}
-
-rtgui_image_item_t* rtgui_image_container_get(const char* filename)
-{
-	struct rtgui_image_item* item;
-	
-	item = hash_table_find(image_hash_table, filename);
-	if (item == RT_NULL)
-	{
-		item = (struct rtgui_image_item*) rt_malloc (sizeof(struct rtgui_image_item));
-		if (item == RT_NULL) return RT_NULL;
-
-		/* create a image object */
-		item->image = rtgui_image_create(filename, load_image);
-		if (item->image == RT_NULL)
-		{
-			rt_free(item);
-			return RT_NULL; /* create image failed */
-		}
-
-		item->refcount = 1;
-		item->filename = rt_strdup(filename);
-		hash_table_insert(image_hash_table, item->filename, item);
-	}
-	else
-	{
-		item->refcount ++; /* increase refcount */
-	}
-
-	return item;
-}
-
-rtgui_image_item_t* rtgui_image_container_get_memref(const char* type, const rt_uint8_t* memory, rt_uint32_t length)
-{
-	char filename[32];
-	struct rtgui_image_item* item;
-
-	/* create filename for image identification */
-	rt_snprintf(filename, sizeof(filename), "0x%08x_%s", memory, type);
-
-	/* search in container */
-	item = hash_table_find(image_hash_table, filename);
-	if (item == RT_NULL)
-	{
-		item = (struct rtgui_image_item*) rt_malloc (sizeof(struct rtgui_image_item));
-		if (item == RT_NULL) return RT_NULL;
-
-		/* create image object */
-		item->image = rtgui_image_create_from_mem(type, memory, length, load_image);
-		if (item->image == RT_NULL)
-		{
-			rt_free(item);
-			return RT_NULL; /* create image failed */
-		}
-
-		item->refcount = 1;
-		item->filename = rt_strdup(filename);
-		hash_table_insert(image_hash_table, item->filename, item);
-	}
-	else item->refcount ++;
-
-	return item;
-}
-
-void rtgui_image_container_put(rtgui_image_item_t* item)
-{
-	item->refcount --;
-	if (item->refcount == 0)
-	{
-		/* remove item from container */
-		hash_table_remove(image_hash_table, item->filename);
-
-		/* destroy image and image item */
-		rt_free(item->filename);
-		rtgui_image_destroy(item->image);
-		rt_free(item);
-	}
-}
-
-#endif
+#include <rtgui/image_container.h>
+
+#ifdef RTGUI_IMAGE_CONTAINER
+typedef unsigned int (*rtgui_hash_func_t) (const void* key);
+typedef struct _rtgui_hash_table  rtgui_hash_table_t;
+typedef rt_bool_t (*rtgui_equal_func_t) (const void* a, const void* b);
+typedef void (*rtgui_user_func_t) (const void* value, const void* data);
+
+/*
+ *Hash tables
+ */
+rtgui_hash_table_t* hash_table_create(rtgui_hash_func_t hash_func, rtgui_equal_func_t key_equal_func);
+void hash_table_destroy (rtgui_hash_table_t* hash_table);
+
+void* hash_table_find (rtgui_hash_table_t* hash_table, void* key);
+void hash_table_insert (rtgui_hash_table_t* hash_table, void* key, void* value);
+rt_bool_t hash_table_remove (rtgui_hash_table_t* hash_table, void* key);
+
+void hash_table_foreach(rtgui_hash_table_t* hash_table, rtgui_user_func_t user_func, void* data);
+unsigned int hash_table_get_size (rtgui_hash_table_t* hash_table);
+
+/* Hash Functions
+ */
+unsigned int direct_hash (void* v);
+
+#define HASH_TABLE_MIN_SIZE 11
+#define HASH_TABLE_MAX_SIZE 6247
+
+typedef struct _gui_hash_node rtgui_hash_node_t;
+struct _gui_hash_node
+{
+	void* key;
+	void* value;
+	rtgui_hash_node_t *next;
+};
+
+struct _rtgui_hash_table
+{
+	rt_uint16_t size;
+	rt_uint16_t nnodes;
+
+	rtgui_hash_node_t **nodes;
+	rtgui_hash_func_t hash_func;
+	rtgui_equal_func_t key_equal_func;
+};
+
+static const unsigned int primes[] =
+{
+	11,
+	19,
+	37,
+	73,
+	109,
+	163,
+	251,
+	367,
+	557,
+	823,
+	1237,
+	1861,
+	2777,
+	4177,
+	6247,
+/*
+	9371,
+	14057,
+	21089,
+	31627,
+	47431,
+	71143,
+	106721,
+	160073,
+	240101,
+	360163,
+	540217,
+	810343,
+	1215497,
+	1823231,
+	2734867,
+	4102283,
+	6153409,
+	9230113,
+	13845163,
+*/
+};
+
+static const unsigned int nprimes = sizeof (primes) / sizeof (primes[0]);
+
+static void hash_table_resize (rtgui_hash_table_t *hash_table);
+static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, void* key);
+static rtgui_hash_node_t* hash_node_create (void* key, void* value);
+static void hash_node_destroy (rtgui_hash_node_t *hash_node);
+static void hash_nodes_destroy (rtgui_hash_node_t *hash_node);
+static unsigned int primes_closest (unsigned int num);
+static void hash_table_needresize(rtgui_hash_table_t *hash_table);
+
+rt_inline unsigned int primes_closest (unsigned int num)
+{
+	int i;
+
+	for (i = 0; i < nprimes; i++)
+		if (primes[i] > num)
+			return primes[i];
+
+	return primes[nprimes - 1];
+}
+
+/* directly hash */
+unsigned int direct_hash (void* v)
+{
+	return (unsigned int)v;
+}
+
+rtgui_hash_table_t* hash_table_create(rtgui_hash_func_t hash_func, rtgui_equal_func_t key_equal_func)
+{
+	rtgui_hash_table_t *hash_table;
+
+	hash_table = (rtgui_hash_table_t*) rt_malloc (sizeof(rtgui_hash_table_t));
+	if (hash_table != RT_NULL)
+	{
+		hash_table->size               = HASH_TABLE_MIN_SIZE;
+		hash_table->nnodes             = 0;
+		hash_table->hash_func          = hash_func ? hash_func : direct_hash;
+		hash_table->key_equal_func     = key_equal_func;
+		hash_table->nodes              = (rtgui_hash_node_t **)rt_malloc ( sizeof(rtgui_hash_node_t*) * hash_table->size);
+		if (hash_table->nodes == RT_NULL)
+		{
+			/* no memory yet */
+			rt_free(hash_table);
+			return RT_NULL;
+		}
+
+		rt_memset(hash_table->nodes, 0, sizeof(rtgui_hash_node_t*) * hash_table->size);
+	}
+
+	return hash_table;
+}
+
+void hash_table_destroy (rtgui_hash_table_t *hash_table)
+{
+	unsigned int i;
+
+	RT_ASSERT(hash_table != RT_NULL);
+
+	for (i = 0; i < hash_table->size; i++)
+		hash_nodes_destroy (hash_table->nodes[i]);
+
+	rt_free (hash_table->nodes);
+	rt_free (hash_table);
+}
+
+static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, void* key)
+{
+	rtgui_hash_node_t **node;
+
+	node = &hash_table->nodes [(* hash_table->hash_func) (key) % hash_table->size];
+
+	if (hash_table->key_equal_func)
+		while (*node && !(*hash_table->key_equal_func) ((*node)->key, key))
+			node = &(*node)->next;
+	else
+		while (*node && (*node)->key != key)
+			node = &(*node)->next;
+
+	return node;
+}
+
+void* hash_table_find (rtgui_hash_table_t* hash_table, void* key)
+{
+	rtgui_hash_node_t *node;
+
+	RT_ASSERT(hash_table != RT_NULL);
+	RT_ASSERT(key != RT_NULL);
+
+	node = *hash_table_find_node (hash_table, key);
+
+	if (node) return node->value;
+	else return RT_NULL;
+}
+
+void hash_table_insert (rtgui_hash_table_t *hash_table, void* key, void* value)
+{
+	rtgui_hash_node_t **node;
+
+	if (hash_table == RT_NULL)return;
+
+	node = hash_table_find_node (hash_table, key);
+	if (*node)
+	{
+		(*node)->value = value;
+	}
+	else
+	{
+		*node = hash_node_create (key, value);
+		hash_table->nnodes++;
+		hash_table_needresize (hash_table);
+	}
+}
+
+rt_bool_t hash_table_remove (rtgui_hash_table_t *hash_table, void*  key)
+{
+	rtgui_hash_node_t **node, *dest;
+
+	if (hash_table == RT_NULL) return RT_FALSE;
+
+	node = hash_table_find_node (hash_table, key);
+	if (*node)
+	{
+		dest = *node;
+		(*node) = dest->next;
+		hash_node_destroy (dest);
+		hash_table->nnodes--;
+
+		hash_table_needresize (hash_table);
+
+		return RT_TRUE;
+	}
+
+	return RT_FALSE;
+}
+
+void hash_table_foreach(rtgui_hash_table_t *hash_table, rtgui_user_func_t user_func, void* data)
+{
+	rtgui_hash_node_t *node;
+	int i;
+
+	RT_ASSERT(hash_table != RT_NULL);
+	RT_ASSERT(user_func != RT_NULL);
+
+	for (i = 0; i < hash_table->size; i++)
+		for (node = hash_table->nodes[i]; node; node = node->next)
+			(* user_func) (node->value, data);
+}
+
+unsigned int hash_table_get_size (rtgui_hash_table_t *hash_table)
+{
+	if ( hash_table ==NULL ) return 0;
+
+	return hash_table->nnodes;
+}
+
+static void hash_table_needresize(rtgui_hash_table_t *hash_table)
+{
+	if ((hash_table->size >= 3*hash_table->nnodes && hash_table->size > HASH_TABLE_MIN_SIZE) ||
+	        (3 * hash_table->size <= hash_table->nnodes && hash_table->size < HASH_TABLE_MAX_SIZE))
+		hash_table_resize (hash_table);
+}
+
+static void hash_table_resize (rtgui_hash_table_t *hash_table)
+{
+	rtgui_hash_node_t **new_nodes;
+	rtgui_hash_node_t *node;
+	rtgui_hash_node_t *next;
+	unsigned int hash_val;
+	int new_size;
+	int i;
+
+	i = primes_closest(hash_table->nnodes);
+	new_size = i > HASH_TABLE_MAX_SIZE ? HASH_TABLE_MAX_SIZE : i < HASH_TABLE_MIN_SIZE ? HASH_TABLE_MIN_SIZE : i ;
+
+	new_nodes = (rtgui_hash_node_t **)rt_malloc ( sizeof(rtgui_hash_node_t*) * new_size);
+	if (new_nodes == RT_NULL) return; /* no memory yet */
+	rt_memset(new_nodes, 0, sizeof(rtgui_hash_node_t*) * new_size);
+
+	for (i = 0; i < hash_table->size; i++)
+	{
+		for (node = hash_table->nodes[i]; node; node = next)
+		{
+			next = node->next;
+
+			hash_val = (* hash_table->hash_func) (node->key) % new_size;
+
+			node->next = new_nodes[hash_val];
+			new_nodes[hash_val] = node;
+		}
+	}
+
+	rt_free (hash_table->nodes);
+	hash_table->nodes = new_nodes;
+	hash_table->size = new_size;
+}
+
+static rtgui_hash_node_t* hash_node_create (void* key, void* value)
+{
+	rtgui_hash_node_t *hash_node;
+
+	hash_node = (rtgui_hash_node_t*) rt_malloc ( sizeof(rtgui_hash_node_t) );
+	if (hash_node != RT_NULL)
+	{
+		/* set value and key */
+		hash_node->key = key;
+		hash_node->value = value;;
+
+		hash_node->next = RT_NULL;
+	}
+
+	return hash_node;
+}
+
+static void hash_node_destroy (rtgui_hash_node_t *hash_node)
+{
+	rt_free(hash_node);
+}
+
+static void hash_nodes_destroy (rtgui_hash_node_t *hash_node)
+{
+	if (hash_node)
+	{
+		rtgui_hash_node_t *node = hash_node;
+		rtgui_hash_node_t *temp;
+
+		while (node->next)
+		{
+			node->key = NULL;
+			node->value = NULL;
+
+			temp = node;
+			node = node->next;
+			rt_free(temp);
+		}
+
+		node->key = NULL;
+		node->value = NULL;
+		rt_free(node);
+	}
+}
+
+unsigned int string_hash_func(const void* self)
+{
+	const char *p;
+	int h=0, g;
+
+	for(p = self; *p != '\0'; p += 1)
+	{
+		h = ( h << 4 ) + *p;
+		if ( ( g = h & 0xf0000000 ) )
+		{
+			h = h ^ (g >> 24);
+			h = h ^ g;
+		}
+	}
+
+	return h ;
+}
+rt_bool_t string_equal_func(const void* a, const void* b)
+{
+	const char *str1, *str2;
+
+	str1 = (const char*)a;
+	str2 = (const char*)b;
+
+	if (strcmp(str1, str2) == 0) return RT_TRUE;
+	return RT_FALSE;
+}
+
+static rtgui_hash_table_t* image_hash_table;
+static rt_bool_t load_image = RT_FALSE;
+void rtgui_system_image_container_init(rt_bool_t load)
+{
+	/* create image hash table */
+	image_hash_table = hash_table_create(string_hash_func, string_equal_func);
+	RT_ASSERT(image_hash_table != RT_NULL);
+
+	/* set load type */
+	load_image = load;
+}
+
+rtgui_image_item_t* rtgui_image_container_get(const char* filename)
+{
+	struct rtgui_image_item* item;
+	
+	item = hash_table_find(image_hash_table, filename);
+	if (item == RT_NULL)
+	{
+		item = (struct rtgui_image_item*) rt_malloc (sizeof(struct rtgui_image_item));
+		if (item == RT_NULL) return RT_NULL;
+
+		/* create a image object */
+		item->image = rtgui_image_create(filename, load_image);
+		if (item->image == RT_NULL)
+		{
+			rt_free(item);
+			return RT_NULL; /* create image failed */
+		}
+
+		item->refcount = 1;
+		item->filename = rt_strdup(filename);
+		hash_table_insert(image_hash_table, item->filename, item);
+	}
+	else
+	{
+		item->refcount ++; /* increase refcount */
+	}
+
+	return item;
+}
+
+rtgui_image_item_t* rtgui_image_container_get_memref(const char* type, const rt_uint8_t* memory, rt_uint32_t length)
+{
+	char filename[32];
+	struct rtgui_image_item* item;
+
+	/* create filename for image identification */
+	rt_snprintf(filename, sizeof(filename), "0x%08x_%s", memory, type);
+
+	/* search in container */
+	item = hash_table_find(image_hash_table, filename);
+	if (item == RT_NULL)
+	{
+		item = (struct rtgui_image_item*) rt_malloc (sizeof(struct rtgui_image_item));
+		if (item == RT_NULL) return RT_NULL;
+
+		/* create image object */
+		item->image = rtgui_image_create_from_mem(type, memory, length, load_image);
+		if (item->image == RT_NULL)
+		{
+			rt_free(item);
+			return RT_NULL; /* create image failed */
+		}
+
+		item->refcount = 1;
+		item->filename = rt_strdup(filename);
+		hash_table_insert(image_hash_table, item->filename, item);
+	}
+	else item->refcount ++;
+
+	return item;
+}
+
+void rtgui_image_container_put(rtgui_image_item_t* item)
+{
+	item->refcount --;
+	if (item->refcount == 0)
+	{
+		/* remove item from container */
+		hash_table_remove(image_hash_table, item->filename);
+
+		/* destroy image and image item */
+		rt_free(item->filename);
+		rtgui_image_destroy(item->image);
+		rt_free(item);
+	}
+}
+
+#endif

+ 154 - 154
components/rtgui/common/pixel_driver.c

@@ -1,154 +1,154 @@
-#include <rtgui/rtgui_system.h>
-#include <rtgui/driver.h>
-
-#define gfx_device		(rtgui_graphic_get_device()->device)
-#define gfx_device_ops 	rt_graphix_ops(gfx_device)
-
-static void _pixel_rgb565p_set_pixel(rtgui_color_t *c, int x, int y)
-{
-	rt_uint16_t pixel;
-
-	pixel = rtgui_color_to_565p(*c);
-	gfx_device_ops->set_pixel((char*)&pixel, x, y);
-}
-
-static void _pixel_rgb565_set_pixel(rtgui_color_t *c, int x, int y)
-{
-	rt_uint16_t pixel;
-
-	pixel = rtgui_color_to_565(*c);
-	gfx_device_ops->set_pixel((char*)&pixel, x, y);
-}
-
-static void _pixel_rgb888_set_pixel(rtgui_color_t *c, int x, int y)
-{
-	rt_uint32_t pixel;
-
-	pixel = rtgui_color_to_888(*c);
-	gfx_device_ops->set_pixel((char*)&pixel, x, y);
-}
-
-static void _pixel_rgb565p_get_pixel(rtgui_color_t *c, int x, int y)
-{
-	rt_uint16_t pixel;
-
-	gfx_device_ops->get_pixel((char*)&pixel, x, y);
-	*c = rtgui_color_from_565p(pixel);
-}
-
-static void _pixel_rgb565_get_pixel(rtgui_color_t *c, int x, int y)
-{
-	rt_uint16_t pixel;
-
-	gfx_device_ops->get_pixel((char*)&pixel, x, y);
-	*c = rtgui_color_from_565(pixel);
-}
-
-static void _pixel_rgb888_get_pixel(rtgui_color_t *c, int x, int y)
-{
-	rt_uint32_t pixel;
-
-	gfx_device_ops->get_pixel((char*)&pixel, x, y);
-	*c = rtgui_color_from_888(pixel);
-}
-
-static void _pixel_rgb565p_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
-{
-	rt_uint16_t pixel;
-
-	pixel = rtgui_color_to_565p(*c);
-	gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y);
-}
-
-static void _pixel_rgb565_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
-{
-	rt_uint16_t pixel;
-
-	pixel = rtgui_color_to_565(*c);
-	gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y);
-}
-
-static void _pixel_rgb888_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
-{
-	rt_uint32_t pixel;
-
-	pixel = rtgui_color_to_888(*c);
-	gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y);
-}
-
-static void _pixel_rgb565p_draw_vline(rtgui_color_t *c, int x, int y1, int y2)
-{
-	rt_uint16_t pixel;
-
-	pixel = rtgui_color_to_565p(*c);
-	gfx_device_ops->draw_vline((char*)&pixel, x, y1, y2);
-}
-
-static void _pixel_rgb565_draw_vline(rtgui_color_t *c, int x, int y1, int y2)
-{
-	rt_uint16_t pixel;
-
-	pixel = rtgui_color_to_565(*c);
-	gfx_device_ops->draw_vline((char*)&pixel, x, y1, y2);
-}
-
-static void _pixel_rgb888_draw_vline(rtgui_color_t *c, int x, int y1, int y2)
-{
-	rt_uint32_t pixel;
-
-	pixel = rtgui_color_to_888(*c);
-	gfx_device_ops->draw_vline((char*)&pixel, x, y1, y2);
-}
-
-static void _pixel_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
-{
-	if (x2 > x1)
-		gfx_device_ops->blit_line((char*)pixels, x1, y, (x2 - x1));
-	else
-		gfx_device_ops->blit_line((char*)pixels, x2, y, (x1 - x2));	
-}
-
-/* pixel device */
-const struct rtgui_graphic_driver_ops _pixel_rgb565p_ops = 
-{
-	_pixel_rgb565p_set_pixel,
-	_pixel_rgb565p_get_pixel,
-	_pixel_rgb565p_draw_hline,
-	_pixel_rgb565p_draw_vline,
-	_pixel_draw_raw_hline,
-};
-
-const struct rtgui_graphic_driver_ops _pixel_rgb565_ops = 
-{
-	_pixel_rgb565_set_pixel,
-	_pixel_rgb565_get_pixel,
-	_pixel_rgb565_draw_hline,
-	_pixel_rgb565_draw_vline,
-	_pixel_draw_raw_hline,
-};
-
-const struct rtgui_graphic_driver_ops _pixel_rgb888_ops = 
-{
-	_pixel_rgb888_set_pixel,
-	_pixel_rgb888_get_pixel,
-	_pixel_rgb888_draw_hline,
-	_pixel_rgb888_draw_vline,
-	_pixel_draw_raw_hline,
-};
-
-const struct rtgui_graphic_driver_ops *rtgui_pixel_device_get_ops(int pixel_format)
-{
-	switch (pixel_format)
-	{
-	case RTGRAPHIC_PIXEL_FORMAT_RGB565:
-		return &_pixel_rgb565_ops;
-		
-	case RTGRAPHIC_PIXEL_FORMAT_RGB565P:
-		return &_pixel_rgb565p_ops;
-		
-	case RTGRAPHIC_PIXEL_FORMAT_RGB888:
-		return &_pixel_rgb888_ops;
-	}
-
-	return RT_NULL;
-}
+#include <rtgui/rtgui_system.h>
+#include <rtgui/driver.h>
+
+#define gfx_device		(rtgui_graphic_get_device()->device)
+#define gfx_device_ops 	rt_graphix_ops(gfx_device)
+
+static void _pixel_rgb565p_set_pixel(rtgui_color_t *c, int x, int y)
+{
+	rt_uint16_t pixel;
+
+	pixel = rtgui_color_to_565p(*c);
+	gfx_device_ops->set_pixel((char*)&pixel, x, y);
+}
+
+static void _pixel_rgb565_set_pixel(rtgui_color_t *c, int x, int y)
+{
+	rt_uint16_t pixel;
+
+	pixel = rtgui_color_to_565(*c);
+	gfx_device_ops->set_pixel((char*)&pixel, x, y);
+}
+
+static void _pixel_rgb888_set_pixel(rtgui_color_t *c, int x, int y)
+{
+	rt_uint32_t pixel;
+
+	pixel = rtgui_color_to_888(*c);
+	gfx_device_ops->set_pixel((char*)&pixel, x, y);
+}
+
+static void _pixel_rgb565p_get_pixel(rtgui_color_t *c, int x, int y)
+{
+	rt_uint16_t pixel;
+
+	gfx_device_ops->get_pixel((char*)&pixel, x, y);
+	*c = rtgui_color_from_565p(pixel);
+}
+
+static void _pixel_rgb565_get_pixel(rtgui_color_t *c, int x, int y)
+{
+	rt_uint16_t pixel;
+
+	gfx_device_ops->get_pixel((char*)&pixel, x, y);
+	*c = rtgui_color_from_565(pixel);
+}
+
+static void _pixel_rgb888_get_pixel(rtgui_color_t *c, int x, int y)
+{
+	rt_uint32_t pixel;
+
+	gfx_device_ops->get_pixel((char*)&pixel, x, y);
+	*c = rtgui_color_from_888(pixel);
+}
+
+static void _pixel_rgb565p_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
+{
+	rt_uint16_t pixel;
+
+	pixel = rtgui_color_to_565p(*c);
+	gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y);
+}
+
+static void _pixel_rgb565_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
+{
+	rt_uint16_t pixel;
+
+	pixel = rtgui_color_to_565(*c);
+	gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y);
+}
+
+static void _pixel_rgb888_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
+{
+	rt_uint32_t pixel;
+
+	pixel = rtgui_color_to_888(*c);
+	gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y);
+}
+
+static void _pixel_rgb565p_draw_vline(rtgui_color_t *c, int x, int y1, int y2)
+{
+	rt_uint16_t pixel;
+
+	pixel = rtgui_color_to_565p(*c);
+	gfx_device_ops->draw_vline((char*)&pixel, x, y1, y2);
+}
+
+static void _pixel_rgb565_draw_vline(rtgui_color_t *c, int x, int y1, int y2)
+{
+	rt_uint16_t pixel;
+
+	pixel = rtgui_color_to_565(*c);
+	gfx_device_ops->draw_vline((char*)&pixel, x, y1, y2);
+}
+
+static void _pixel_rgb888_draw_vline(rtgui_color_t *c, int x, int y1, int y2)
+{
+	rt_uint32_t pixel;
+
+	pixel = rtgui_color_to_888(*c);
+	gfx_device_ops->draw_vline((char*)&pixel, x, y1, y2);
+}
+
+static void _pixel_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
+{
+	if (x2 > x1)
+		gfx_device_ops->blit_line((char*)pixels, x1, y, (x2 - x1));
+	else
+		gfx_device_ops->blit_line((char*)pixels, x2, y, (x1 - x2));	
+}
+
+/* pixel device */
+const struct rtgui_graphic_driver_ops _pixel_rgb565p_ops = 
+{
+	_pixel_rgb565p_set_pixel,
+	_pixel_rgb565p_get_pixel,
+	_pixel_rgb565p_draw_hline,
+	_pixel_rgb565p_draw_vline,
+	_pixel_draw_raw_hline,
+};
+
+const struct rtgui_graphic_driver_ops _pixel_rgb565_ops = 
+{
+	_pixel_rgb565_set_pixel,
+	_pixel_rgb565_get_pixel,
+	_pixel_rgb565_draw_hline,
+	_pixel_rgb565_draw_vline,
+	_pixel_draw_raw_hline,
+};
+
+const struct rtgui_graphic_driver_ops _pixel_rgb888_ops = 
+{
+	_pixel_rgb888_set_pixel,
+	_pixel_rgb888_get_pixel,
+	_pixel_rgb888_draw_hline,
+	_pixel_rgb888_draw_vline,
+	_pixel_draw_raw_hline,
+};
+
+const struct rtgui_graphic_driver_ops *rtgui_pixel_device_get_ops(int pixel_format)
+{
+	switch (pixel_format)
+	{
+	case RTGRAPHIC_PIXEL_FORMAT_RGB565:
+		return &_pixel_rgb565_ops;
+		
+	case RTGRAPHIC_PIXEL_FORMAT_RGB565P:
+		return &_pixel_rgb565p_ops;
+		
+	case RTGRAPHIC_PIXEL_FORMAT_RGB888:
+		return &_pixel_rgb888_ops;
+	}
+
+	return RT_NULL;
+}

+ 24 - 11
components/rtgui/common/rtgui_object.c

@@ -17,9 +17,10 @@
 
 
 static void _rtgui_object_constructor(rtgui_object_t *object)
 static void _rtgui_object_constructor(rtgui_object_t *object)
 {
 {
-   if (!object) return;
+   if (!object)
+       return;
 
 
-   object->is_static = RT_FALSE;
+   object->flag = RTGUI_OBJECT_FLAG_NONE;
 }
 }
 
 
 /* Destroys the object */
 /* Destroys the object */
@@ -28,7 +29,7 @@ static void _rtgui_object_destructor(rtgui_object_t *object)
 	/* nothing */
 	/* nothing */
 }
 }
 
 
-DEFINE_CLASS_TYPE(type, "object", 
+DEFINE_CLASS_TYPE(type, "object",
 	RT_NULL,
 	RT_NULL,
 	_rtgui_object_constructor,
 	_rtgui_object_constructor,
 	_rtgui_object_destructor,
 	_rtgui_object_destructor,
@@ -44,9 +45,9 @@ void rtgui_type_object_construct(const rtgui_type_t *type, rtgui_object_t *objec
 }
 }
 
 
 void rtgui_type_destructors_call(const rtgui_type_t *type, rtgui_object_t *object)
 void rtgui_type_destructors_call(const rtgui_type_t *type, rtgui_object_t *object)
-{
-	const rtgui_type_t *t;
-	
+{
+	const rtgui_type_t *t;
+	
 	t = type;
 	t = type;
 	while (t)
 	while (t)
 	{
 	{
@@ -56,9 +57,9 @@ void rtgui_type_destructors_call(const rtgui_type_t *type, rtgui_object_t *objec
 }
 }
 
 
 rt_bool_t rtgui_type_inherits_from(const rtgui_type_t *type, const rtgui_type_t *parent)
 rt_bool_t rtgui_type_inherits_from(const rtgui_type_t *type, const rtgui_type_t *parent)
-{
-	const rtgui_type_t *t;
-	
+{
+	const rtgui_type_t *t;
+	
 	t = type;
 	t = type;
 	while (t)
 	while (t)
 	{
 	{
@@ -115,7 +116,6 @@ rtgui_object_t *rtgui_object_create(rtgui_type_t *object_type)
 #endif
 #endif
 
 
 	new_object->type = object_type;
 	new_object->type = object_type;
-	new_object->is_static = RT_FALSE;
 
 
 	rtgui_type_object_construct(object_type, new_object);
 	rtgui_type_object_construct(object_type, new_object);
 
 
@@ -131,7 +131,8 @@ rtgui_object_t *rtgui_object_create(rtgui_type_t *object_type)
  */
  */
 void rtgui_object_destroy(rtgui_object_t *object)
 void rtgui_object_destroy(rtgui_object_t *object)
 {
 {
-	if (!object || object->is_static == RT_TRUE) return;
+	if (!object || object->flag & RTGUI_OBJECT_FLAG_STATIC)
+        return;
 
 
 #ifdef RTGUI_OBJECT_TRACE
 #ifdef RTGUI_OBJECT_TRACE
 	obj_info.objs_number --;
 	obj_info.objs_number --;
@@ -178,3 +179,15 @@ const rtgui_type_t *rtgui_object_object_type_get(rtgui_object_t *object)
 	return object->type;
 	return object->type;
 }
 }
 
 
+void rtgui_object_set_event_handler(struct rtgui_object *object, rtgui_event_handler_ptr handler)
+{
+	RT_ASSERT(object != RT_NULL);
+
+	object->event_handler = handler;
+}
+
+rt_bool_t rtgui_object_event_handler(struct rtgui_object *object, struct rtgui_event* event)
+{
+	return RT_FALSE;
+}
+

+ 2 - 465
components/rtgui/common/rtgui_system.c

@@ -16,15 +16,13 @@
 #include <rtgui/image.h>
 #include <rtgui/image.h>
 #include <rtgui/font.h>
 #include <rtgui/font.h>
 #include <rtgui/event.h>
 #include <rtgui/event.h>
+#include <rtgui/rtgui_application.h>
 #include <rtgui/rtgui_server.h>
 #include <rtgui/rtgui_server.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/widgets/window.h>
 #include <rtgui/widgets/window.h>
 #include <rtgui/rtgui_theme.h>
 #include <rtgui/rtgui_theme.h>
 
 
-#define RTGUI_EVENT_DEBUG
-
 #ifdef _WIN32
 #ifdef _WIN32
-#define RTGUI_EVENT_DEBUG
 #define RTGUI_MEM_TRACE
 #define RTGUI_MEM_TRACE
 #endif
 #endif
 
 
@@ -43,467 +41,6 @@ void rtgui_system_server_init()
 	rtgui_system_theme_init();
 	rtgui_system_theme_init();
 }
 }
 
 
-/************************************************************************/
-/* RTGUI Thread Wrapper                                                 */
-/************************************************************************/
-#ifdef RTGUI_EVENT_DEBUG
-const char *event_string[] =
-{
-	/* panel event */
-	"PANEL_ATTACH",			/* attach to a panel	*/
-	"PANEL_DETACH",			/* detach from a panel	*/
-	"PANEL_SHOW",			/* show in a panel		*/
-	"PANEL_HIDE",			/* hide from a panel	*/
-	"PANEL_INFO",			/* panel information 	*/
-	"PANEL_RESIZE",			/* resize panel 		*/
-	"PANEL_FULLSCREEN",		/* to full screen 		*/
-	"PANEL_NORMAL",			/* to normal screen 	*/
-
-	/* window event */
-	"WIN_CREATE",			/* create a window 	*/
-	"WIN_DESTROY",			/* destroy a window 	*/
-	"WIN_SHOW",				/* show a window 		*/
-	"WIN_HIDE",				/* hide a window 		*/
-	"WIN_ACTIVATE", 		/* activate a window 	*/
-	"WIN_DEACTIVATE",		/* deactivate a window 	*/
-	"WIN_CLOSE",			/* close a window 		*/
-	"WIN_MOVE",				/* move a window 		*/
-	"WIN_RESIZE", 			/* resize a window 		*/
-
-	"SET_WM", 				/* set window manager	*/
-
-	"UPDATE_BEGIN",			/* begin of update rect */
-	"UPDATE_END",			/* end of update rect	*/
-	"MONITOR_ADD",			/* add a monitor rect 	*/
-	"MONITOR_REMOVE", 		/* remove a monitor rect*/
-	"PAINT",				/* paint on screen 		*/
-	"TIMER",				/* timer 				*/
-
-	/* clip rect information */
-	"CLIP_INFO",			/* clip rect info		*/
-
-	/* mouse and keyboard event */
-	"MOUSE_MOTION",			/* mouse motion */
-	"MOUSE_BUTTON",			/* mouse button info 	*/
-	"KBD",					/* keyboard info		*/
-
-	/* user command event */
-	"COMMAND",				/* user command 		*/
-
-	/* request's status event */
-	"STATUS",				/* request result 		*/
-	"SCROLLED",           	/* scroll bar scrolled  */
-	"RESIZE",				/* widget resize 		*/
-};
-
-#define DBG_MSG(x)	rt_kprintf x
-
-static void rtgui_event_dump(rt_thread_t tid, rtgui_event_t* event)
-{
-	char* sender = "(unknown)";
-
-	if (event->sender != RT_NULL) sender = event->sender->name;
-
-	if ((event->type == RTGUI_EVENT_TIMER) ||
-		(event->type == RTGUI_EVENT_UPDATE_BEGIN) ||
-		(event->type == RTGUI_EVENT_UPDATE_END))
-	{
-		/* don't dump timer event */
-		return ;
-	}
-
-	rt_kprintf("%s -- %s --> %s ", sender, event_string[event->type], tid->name);
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-		{
-			struct rtgui_event_paint *paint = (struct rtgui_event_paint *)event;
-
-			if(paint->wid != RT_NULL)
-				rt_kprintf("win: %s", paint->wid->title);
-		}
-		break;
-
-	case RTGUI_EVENT_KBD:
-		{
-			struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd*) event;
-			if (ekbd->wid != RT_NULL)
-				rt_kprintf("win: %s", ekbd->wid->title);
-			if (RTGUI_KBD_IS_UP(ekbd)) rt_kprintf(", up");
-			else rt_kprintf(", down");
-		}
-		break;
-
-	case RTGUI_EVENT_CLIP_INFO:
-		{
-			struct rtgui_event_clip_info *info = (struct rtgui_event_clip_info *)event;
-
-			if(info->wid != RT_NULL)
-				rt_kprintf("win: %s", info->wid->title);
-		}
-		break;
-
-	case RTGUI_EVENT_WIN_CREATE:
-		{
-			struct rtgui_event_win_create *create = (struct rtgui_event_win_create*)event;
-
-			rt_kprintf(" win: %s at (x1:%d, y1:%d, x2:%d, y2:%d)",
-#ifdef RTGUI_USING_SMALL_SIZE
-				create->wid->title,
-				RTGUI_WIDGET(create->wid)->extent.x1,
-				RTGUI_WIDGET(create->wid)->extent.y1,
-				RTGUI_WIDGET(create->wid)->extent.x2,
-				RTGUI_WIDGET(create->wid)->extent.y2);
-#else
-				create->title,
-				create->extent.x1,
-				create->extent.y1,
-				create->extent.x2,
-				create->extent.y2);
-#endif
-		}
-		break;
-
-	case RTGUI_EVENT_UPDATE_END:
-		{
-			struct rtgui_event_update_end* update_end = (struct rtgui_event_update_end*)event;
-			rt_kprintf("(x:%d, y1:%d, x2:%d, y2:%d)", update_end->rect.x1,
-				update_end->rect.y1,
-				update_end->rect.x2,
-				update_end->rect.y2);
-		}
-		break;
-
-	case RTGUI_EVENT_WIN_ACTIVATE:
-	case RTGUI_EVENT_WIN_DEACTIVATE:
-	case RTGUI_EVENT_WIN_SHOW:
-		{
-			struct rtgui_event_win *win = (struct rtgui_event_win *)event;
-
-			if(win->wid != RT_NULL)
-				rt_kprintf("win: %s", win->wid->title);
-		}
-		break;
-
-	case RTGUI_EVENT_WIN_MOVE:
-		{
-			struct rtgui_event_win_move *win = (struct rtgui_event_win_move *)event;
-
-			if(win->wid != RT_NULL)
-			{
-				rt_kprintf("win: %s", win->wid->title);
-				rt_kprintf(" to (x:%d, y:%d)", win->x, win->y);
-			}
-		}
-		break;
-
-	case RTGUI_EVENT_WIN_RESIZE:
-		{
-			struct rtgui_event_win_resize* win = (struct rtgui_event_win_resize *)event;
-
-			if (win->wid != RT_NULL)
-			{
-				rt_kprintf("win: %s, rect(x1:%d, y1:%d, x2:%d, y2:%d)", win->wid->title,
-					RTGUI_WIDGET(win->wid)->extent.x1,
-					RTGUI_WIDGET(win->wid)->extent.y1,
-					RTGUI_WIDGET(win->wid)->extent.x2,
-					RTGUI_WIDGET(win->wid)->extent.y2);
-			}
-		}
-		break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-	case RTGUI_EVENT_MOUSE_MOTION:
-		{
-			struct rtgui_event_mouse *mouse = (struct rtgui_event_mouse*)event;
-
-			if (mouse->button & RTGUI_MOUSE_BUTTON_LEFT) rt_kprintf("left ");
-			else rt_kprintf("right ");
-
-			if (mouse->button & RTGUI_MOUSE_BUTTON_DOWN) rt_kprintf("down ");
-			else rt_kprintf("up ");
-
-			if (mouse->wid != RT_NULL)
-				rt_kprintf("win: %s at (%d, %d)", mouse->wid->title,
-				mouse->x, mouse->y);
-			else
-				rt_kprintf("(%d, %d)", mouse->x, mouse->y);
-		}
-		break;
-
-	case RTGUI_EVENT_MONITOR_ADD:
-		{
-			struct rtgui_event_monitor *monitor = (struct rtgui_event_monitor*)event;
-			if (monitor->panel != RT_NULL)
-			{
-				rt_kprintf("the rect is:(%d, %d) - (%d, %d)",
-					monitor->rect.x1, monitor->rect.y1,
-					monitor->rect.x2, monitor->rect.y2);
-			}
-			else if (monitor->wid != RT_NULL)
-			{
-				rt_kprintf("win: %s, the rect is:(%d, %d) - (%d, %d)", monitor->wid->title,
-					monitor->rect.x1, monitor->rect.y1,
-					monitor->rect.x2, monitor->rect.y2);
-			}
-		}
-		break;
-	}
-
-	rt_kprintf("\n");
-}
-#else
-#define DBG_MSG(x)
-#define rtgui_event_dump(tid, event)
-#endif
-
-rtgui_thread_t* rtgui_thread_register(rt_thread_t tid, rt_mq_t mq)
-{
-	rtgui_thread_t* thread = rtgui_malloc(sizeof(rtgui_thread_t));
-
-	if (thread != RT_NULL)
-	{
-		DBG_MSG(("register a rtgui thread: %s, tid: 0x%p\n", tid->name, tid));
-
-		/* set tid and mq */
-		thread->tid			= tid;
-		thread->mq			= mq;
-		thread->widget		= RT_NULL;
-		thread->on_idle     = RT_NULL;
-
-		/* set user thread */
-		tid->user_data = (rt_uint32_t)thread;
-	}
-
-	return thread;
-}
-
-void rtgui_thread_deregister(rt_thread_t tid)
-{
-	rtgui_thread_t* thread;
-
-	/* find rtgui_thread_t */
-	thread = (rtgui_thread_t*) (tid->user_data);
-
-	if (thread != RT_NULL)
-	{
-		/* remove rtgui_thread_t */
-		tid->user_data = 0;
-
-		/* free rtgui_thread_t */
-		rtgui_free(thread);
-	}
-}
-
-/* get current gui thread */
-rtgui_thread_t* rtgui_thread_self()
-{
-	rtgui_thread_t* thread;
-	rt_thread_t self;
-
-	/* get current thread */
-	self = rt_thread_self();
-	thread = (rtgui_thread_t*)(self->user_data);
-
-	return thread;
-}
-
-void rtgui_thread_set_onidle(rtgui_idle_func onidle)
-{
-	rtgui_thread_t* thread;
-
-	thread = rtgui_thread_self();
-	RT_ASSERT(thread != RT_NULL);
-
-	thread->on_idle = onidle;
-}
-
-rtgui_idle_func rtgui_thread_get_onidle()
-{
-	rtgui_thread_t* thread;
-
-	thread = rtgui_thread_self();
-	RT_ASSERT(thread != RT_NULL);
-
-	return thread->on_idle;
-}
-
-extern rt_thread_t rt_thread_find(char* name);
-rt_thread_t rtgui_thread_get_server()
-{
-	return rt_thread_find("rtgui");
-}
-
-void rtgui_thread_set_widget(rtgui_widget_t* widget)
-{
-	rtgui_thread_t* thread;
-
-	/* get rtgui_thread */
-	thread = (rtgui_thread_t*) (rt_thread_self()->user_data);
-
-	if (thread != RT_NULL) thread->widget = widget;
-}
-
-rtgui_widget_t* rtgui_thread_get_widget()
-{
-	rtgui_thread_t* thread;
-
-	/* get rtgui_thread_t */
-	thread = (rtgui_thread_t*) (rt_thread_self()->user_data);
-
-	return thread == RT_NULL? RT_NULL : thread->widget;
-}
-
-rt_err_t rtgui_thread_send(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
-{
-	rt_err_t result;
-	rtgui_thread_t* thread;
-
-	rtgui_event_dump(tid, event);
-
-	/* find rtgui_thread_t */
-	thread = (rtgui_thread_t*) (tid->user_data);
-	if (thread == RT_NULL) return -RT_ERROR;
-
-	result = rt_mq_send(thread->mq, event, event_size);
-	if (result != RT_EOK)
-	{
-		if (event->type != RTGUI_EVENT_TIMER)
-			rt_kprintf("send event to %s failed\n", thread->tid->name);
-	}
-
-	return result;
-}
-
-rt_err_t rtgui_thread_send_urgent(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
-{
-	rt_err_t result;
-	rtgui_thread_t* thread;
-
-	rtgui_event_dump(tid, event);
-
-	/* find rtgui_thread_t */
-	thread = (rtgui_thread_t*) (tid->user_data);
-	if (thread == RT_NULL) return -RT_ERROR;
-
-	result = rt_mq_urgent(thread->mq, event, event_size);
-	if (result != RT_EOK)
-		rt_kprintf("send ergent event failed\n");
-
-	return result;
-}
-
-rt_err_t rtgui_thread_send_sync(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
-{
-	rt_err_t r;
-	rtgui_thread_t* thread;
-	rt_int32_t ack_buffer, ack_status;
-	struct rt_mailbox ack_mb;
-
-	rtgui_event_dump(tid, event);
-
-	/* init ack mailbox */
-	r = rt_mb_init(&ack_mb, "ack", &ack_buffer, 1, 0);
-	if (r!= RT_EOK) goto __return;
-
-	/* find rtgui_thread_t */
-	thread = (rtgui_thread_t*) (tid->user_data);
-	if (thread == RT_NULL)
-	{
-		r = -RT_ERROR;
-		goto __return;
-	}
-
-	event->ack = &ack_mb;
-	r = rt_mq_send(thread->mq, event, event_size);
-	if (r != RT_EOK)
-	{
-		rt_kprintf("send sync event failed\n");
-		goto __return;
-	}
-
-	r = rt_mb_recv(&ack_mb, (rt_uint32_t*)&ack_status, RT_WAITING_FOREVER);
-	if (r!= RT_EOK) goto __return;
-
-	if (ack_status != RTGUI_STATUS_OK)
-		r = -RT_ERROR;
-	else
-		r = RT_EOK;
-
-__return:
-	/* fini ack mailbox */
-	rt_mb_detach(&ack_mb);
-
-	return r;
-}
-
-rt_err_t rtgui_thread_ack(rtgui_event_t* event, rt_int32_t status)
-{
-	if (event != RT_NULL &&
-		event->ack != RT_NULL)
-	{
-		rt_mb_send(event->ack, status);
-	}
-
-	return RT_EOK;
-}
-
-rt_err_t rtgui_thread_recv(rtgui_event_t* event, rt_size_t event_size)
-{
-	rtgui_thread_t* thread;
-	rt_err_t r;
-
-	/* find rtgui_thread_t */
-	thread = (rtgui_thread_t*) (rt_thread_self()->user_data);
-	if (thread == RT_NULL) return -RT_ERROR;
-
-	r = rt_mq_recv(thread->mq, event, event_size, RT_WAITING_FOREVER);
-
-	return r;
-}
-
-rt_err_t rtgui_thread_recv_nosuspend(rtgui_event_t* event, rt_size_t event_size)
-{
-	rtgui_thread_t* thread;
-	rt_err_t r;
-
-	/* find rtgui_thread */
-	thread = (rtgui_thread_t*) (rt_thread_self()->user_data);
-	if (thread == RT_NULL) return -RT_ERROR;
-
-	r = rt_mq_recv(thread->mq, event, event_size, 0);
-
-	return r;
-}
-
-rt_err_t rtgui_thread_recv_filter(rt_uint32_t type, rtgui_event_t* event, rt_size_t event_size)
-{
-	rtgui_thread_t* thread;
-
-	/* find rtgui_thread_t */
-	thread = (rtgui_thread_t*) (rt_thread_self()->user_data);
-	if (thread == RT_NULL) return -RT_ERROR;
-
-	while (rt_mq_recv(thread->mq, event, event_size, RT_WAITING_FOREVER) == RT_EOK)
-	{
-		if (event->type == type)
-		{
-			return RT_EOK;
-		}
-		else
-		{
-			/* let widget to handle event */
-			if (thread->widget != RT_NULL &&
-				thread->widget->event_handler != RT_NULL)
-			{
-				thread->widget->event_handler(thread->widget, event);
-			}
-		}
-	}
-
-	return -RT_ERROR;
-}
-
 /************************************************************************/
 /************************************************************************/
 /* RTGUI Timer                                                          */
 /* RTGUI Timer                                                          */
 /************************************************************************/
 /************************************************************************/
@@ -522,7 +59,7 @@ static void rtgui_time_out(void* parameter)
 
 
 	event.timer = timer;
 	event.timer = timer;
 
 
-	rtgui_thread_send(timer->tid, &(event.parent), sizeof(rtgui_event_timer_t));
+	rtgui_application_send(timer->tid, &(event.parent), sizeof(rtgui_event_timer_t));
 }
 }
 
 
 rtgui_timer_t* rtgui_timer_create(rt_int32_t time, rt_int32_t flag, rtgui_timeout_func timeout, void* parameter)
 rtgui_timer_t* rtgui_timer_create(rt_int32_t time, rt_int32_t flag, rtgui_timeout_func timeout, void* parameter)

+ 1 - 1
components/rtgui/common/rtgui_xml.c

@@ -1,5 +1,5 @@
 #include <rtgui/rtgui_xml.h>
 #include <rtgui/rtgui_xml.h>
-#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_system.h>
 
 
 /* Internal states that the parser can be in at any given time. */
 /* Internal states that the parser can be in at any given time. */
 enum {
 enum {

+ 16 - 0
components/rtgui/doc/attention.txt

@@ -0,0 +1,16 @@
+1, 对同一 window 销毁两次会引起 segfault。同时,如果在创建时设置了
+RTGUI_WIN_STYLE_DESTROY_ON_CLOSE,close 窗口之后不要再去销毁窗口。
+
+2, 所有的 window 由 topwin 进行管理,用户不要在指定创建具有父窗口的子窗口之后在
+把这个窗口加为父窗口的 child。这可能会导致子窗口无法显示。
+
+3, command 事件添加了 wid 参数,用于指定此事件需要传递的目标窗口。
+
+4, 在 widget 中添加了 on_show 和 on_hide 事件回调函数。他们会在控件显示/隐藏的
+时候被调用。
+
+5, slider 控件改为左键减小数值,右键增加数值。横向的 slider 处理左右键,纵向的
+slider 处理上下键,上面的值小,下面的值大。
+
+6, view 不再提供 show 方法。如果想单独显示控件,请用 window 包含之。
+

+ 70 - 0
components/rtgui/doc/road_map.txt

@@ -0,0 +1,70 @@
+RTGUI for 1.1 路线图(排名不分先后)
+1, 把 rtgui_thread 给去掉,变成 rtgui_application ,消除原来的 rtgui_thread +
+mq 的模式。rtgui_application 记录当前依附的 panel,和 panel 的 extent。(Done)
+   1.1, rtgui_application_run 运行主事件循环(Done)
+   1.2, rtgui_application 作为事件的接收者_和_事件派发者。(Done)
+
+2, workbench,window并成一个,其事件主循环并合并到rtgui_application中。
+   2.1, window 作为有标题栏的 workbench(Done)
+   2.2, 将其事件主循环移至 application 中。(Done)
+   2.3, 将 window 的父类 toplevel 合并进 window 中。所有直接与服务器打交道的从
+   window 继承。(或者将 toplevel 合并进 application 中,因为只有 application 才
+   会和服务器打交道。)
+   2.4 在创建 window 的时候需要指定 parent,如果为 RT_NULL,则此 window 为 root
+   窗口,parent 为当前 rtgui_application。每一个 application 必须有且只有一个根
+   窗口。(Done)
+   2.5 添加一个 FULL_PANEL 的 STYLE。指定此 STYLE 之后会自动填满整个 panel。其
+   与 NO_TITLE 之类的合用可以达到之前 workbench 的效果。(Deprecated)
+   2.6 event_loop 可以设定顶层控件,只会把事件传递给顶层控件。这样可以方便的实
+   现模态窗口。event_loop 靠 object 的一个标志位来判断是否要退出当前循环。(Done)
+
+3, 将 view 合并进 container,所有容器类继承 container。[note1](Done)
+
+4, 事件循环完成后不主动销毁控件,销毁任务交由用户完成。但是有些自动销毁是必要的
+,比如 container 自动销毁其包含的控件(Done)
+   4.1 对于 window 的 onclose事件,保证在其回调函数中可以(但不是必须)安全销毁窗
+   口。这个功能不保证能够实现。(onclose 是在将要关闭窗口的时候触发的,调用它之
+   后 RTGUI 还要进行其他的设置和清理工作,所以不能在 onclose 里销毁窗口)(Cannot
+   Implement)
+   4.2 对 window 添加 RTGUI_WIN_STYLE_DESTROY_ON_CLOSE 。使得其在被关闭时自动销
+   毁。注意:对同一 window 销毁两次会引起 segfault。同时,如果在创建时设置了
+   RTGUI_WIN_STYLE_DESTROY_ON_CLOSE,close 窗口之后不要再去销毁窗口。
+
+5, API 清理。更详细的文档。
+
+6, 使 panel 退化为无窗口标题的 window,这样 server 就只记录 window 一种东西的位
+置。(Done, 删除了 panel,使得整体以 window 为主)
+
+7, 指定名称的时候不再自己拷贝一份。(我觉得 90% 的情况下名称都是静态的字符串,这
+时用 strdup其实并没有必要。)(Deprecated)
+
+8, 添加一些工业控制当中用到的波形、仪表之类的控件。
+
+9, 在 window 中记录焦点控件,键盘事件由 window 直接投送。各个控件不记录焦点控件
+。(Done)
+
+10, 在 widget 中添加 on_show 和 on_hide 事件回调函数。(Done)
+
+11, 添加 EVENT_WIN_MODAL_ENTER 和 EVENT_WIN_MODAL_EXIT 事件,用来通知窗口管理器
+(topwin)一个窗口进入模态。窗口管理器根据这个进行相应的设置。
+
+12, rtgui_filelist_view 不必继承自 container。
+
+13, 添加 desktop window 支持。(Done)
+    概念与名词:
+		13.1 desktop window:最底层的桌面窗口。它会在所有窗口下面显示,并且不会被它
+			上面的窗口模态掉。它的子窗口是 root window。(继承关系由 RTGUI 管理,不
+			用用户管理)它只有在启用 RTGUI_USING_DESKTOP_WINDOW 时才有此特性。
+		13.2 root window:创建时父窗口为 RT_NULL 的窗口。是用户空间窗口继承树的根。
+		13.3 normal window:创建时父窗口不为 RT_NULL 的窗口。它始终会在父窗口之上显
+			示(它会 clip 父窗口)。normal windows 和 root window 组成一个窗口树。
+		13.4 模态:当一个 normal window 模态显示时会会模态自己所在树的同级窗口
+			和所有父级窗口,但不会影响别的窗口树。被模态的窗口不会接受到用户事
+			件(按键,触摸等)
+
+----
+[note1] 我们至少需要一种容器控件来盛放其他的控件,并且能把上层事件传递给被包含
+的控件。实现这样的功能有一个就好,container 可以担当这个责任。其他需要放多个控
+件的控件则可以继承/包含这个控件。然后多个容器控件轮换的,notebook 可以来做。
+notebook可以是有标签和无标签的,有标签的对应一般的 tab 控件,无标签的对应 rtgui
+for RTT 1.0 的 workbench+view。

+ 9 - 9
components/rtgui/include/rtgui/blit.h

@@ -1,9 +1,9 @@
-#ifndef __RTGUI_BLIT_H__
-#define __RTGUI_BLIT_H__
-
-#include <rtgui/rtgui.h>
-
-typedef void (*rtgui_blit_line_func)(rt_uint8_t* dst, rt_uint8_t* src, int line);
-rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp);
-
-#endif
+#ifndef __RTGUI_BLIT_H__
+#define __RTGUI_BLIT_H__
+
+#include <rtgui/rtgui.h>
+
+typedef void (*rtgui_blit_line_func)(rt_uint8_t* dst, rt_uint8_t* src, int line);
+rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp);
+
+#endif

+ 114 - 114
components/rtgui/include/rtgui/color.h

@@ -1,114 +1,114 @@
-/*
- * File      : color.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_COLOR_H__
-#define __RTGUI_COLOR_H__
-
-#include <rtgui/rtgui.h>
-
-#define RTGUI_ARGB(a, r, g, b)	\
-		((rtgui_color_t)(((rt_uint8_t)(r)|\
-		(((unsigned)(rt_uint8_t)(g))<<8))|\
-		(((unsigned long)(rt_uint8_t)(b))<<16)|\
-		(((unsigned long)(rt_uint8_t)(a))<<24)))
-#define RTGUI_RGB(r, g, b)	RTGUI_ARGB(255, (r), (g), (b))
-
-#define RTGUI_RGB_R(c)	((c) & 0xff)
-#define RTGUI_RGB_G(c)	(((c) >> 8)  & 0xff)
-#define RTGUI_RGB_B(c)	(((c) >> 16) & 0xff)
-#define RTGUI_RGB_A(c)	(((c) >> 24) & 0xff)
-
-extern const rtgui_color_t default_foreground;
-extern const rtgui_color_t default_background;
-
-extern const rtgui_color_t red;
-extern const rtgui_color_t green;
-extern const rtgui_color_t blue;
-extern const rtgui_color_t black;
-extern const rtgui_color_t white;
-extern const rtgui_color_t high_light;
-extern const rtgui_color_t dark_grey;
-extern const rtgui_color_t light_grey;
-
-/*
- * RTGUI default color format
- * BBBB BBBB GGGG GGGG RRRR RRRR
- */
-
-/* convert rtgui color to BBBBBGGGGGGRRRRR */
-rt_inline rt_uint16_t rtgui_color_to_565(rtgui_color_t c)
-{
-	rt_uint16_t pixel;
-
-	pixel = (rt_uint16_t)(((RTGUI_RGB_B(c)>> 3) << 11) | ((RTGUI_RGB_G(c) >> 2) << 5) | (RTGUI_RGB_R(c) >> 3));
-
-	return pixel;
-}
-
-rt_inline rtgui_color_t rtgui_color_from_565(rt_uint16_t pixel)
-{
-	rt_uint16_t r, g, b;
-	rtgui_color_t color;
-
-	r = pixel & 0x1f;
-	g = (pixel >> 5) & 0x3f;
-	b = (pixel >> 11) & 0x1f;
-
-	color = r * 8225 / 1024 + ((g * 4047 / 1024) << 8) + ((b * 8225 / 1024) << 16);
-
-	return color;
-}
-
-/* convert rtgui color to RRRRRGGGGGGBBBBB */
-rt_inline rt_uint16_t rtgui_color_to_565p(rtgui_color_t c)
-{
-	rt_uint16_t pixel;
-
-	pixel = (rt_uint16_t)(((RTGUI_RGB_R(c) >> 3) << 11) | ((RTGUI_RGB_G(c) >> 2) << 5) | (RTGUI_RGB_B(c)>> 3));
-	return pixel;
-}
-
-rt_inline rtgui_color_t rtgui_color_from_565p(rt_uint16_t pixel)
-{
-	rt_uint8_t r, g, b;
-	rtgui_color_t color;
-
-	r = (pixel >> 11) & 0x1f;
-	g = (pixel >> 5)  & 0x3f;
-	b = pixel & 0x1f;
-
-	color = r * 8225 / 1024 + ((g * 4047 / 1024) << 8) + ((b * 8225 / 1024) << 16);
-
-	return color;
-}
-
-/* convert rtgui color to RGB */
-rt_inline rt_uint32_t rtgui_color_to_888(rtgui_color_t c)
-{
-	rt_uint32_t pixel;
-
-	pixel = RTGUI_RGB_R(c) << 16 | RTGUI_RGB_G(c) << 8 | RTGUI_RGB_B(c);
-	return pixel;
-}
-
-rt_inline rtgui_color_t rtgui_color_from_888(rt_uint32_t pixel)
-{
-	rtgui_color_t color;
-
-	color = RTGUI_RGB(((pixel >> 16) & 0xff), ((pixel >> 8) & 0xff), pixel & 0xff);
-
-	return color;
-}
-
-#endif
-
+/*
+ * File      : color.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_COLOR_H__
+#define __RTGUI_COLOR_H__
+
+#include <rtgui/rtgui.h>
+
+#define RTGUI_ARGB(a, r, g, b)	\
+		((rtgui_color_t)(((rt_uint8_t)(r)|\
+		(((unsigned)(rt_uint8_t)(g))<<8))|\
+		(((unsigned long)(rt_uint8_t)(b))<<16)|\
+		(((unsigned long)(rt_uint8_t)(a))<<24)))
+#define RTGUI_RGB(r, g, b)	RTGUI_ARGB(255, (r), (g), (b))
+
+#define RTGUI_RGB_R(c)	((c) & 0xff)
+#define RTGUI_RGB_G(c)	(((c) >> 8)  & 0xff)
+#define RTGUI_RGB_B(c)	(((c) >> 16) & 0xff)
+#define RTGUI_RGB_A(c)	(((c) >> 24) & 0xff)
+
+extern const rtgui_color_t default_foreground;
+extern const rtgui_color_t default_background;
+
+extern const rtgui_color_t red;
+extern const rtgui_color_t green;
+extern const rtgui_color_t blue;
+extern const rtgui_color_t black;
+extern const rtgui_color_t white;
+extern const rtgui_color_t high_light;
+extern const rtgui_color_t dark_grey;
+extern const rtgui_color_t light_grey;
+
+/*
+ * RTGUI default color format
+ * BBBB BBBB GGGG GGGG RRRR RRRR
+ */
+
+/* convert rtgui color to BBBBBGGGGGGRRRRR */
+rt_inline rt_uint16_t rtgui_color_to_565(rtgui_color_t c)
+{
+	rt_uint16_t pixel;
+
+	pixel = (rt_uint16_t)(((RTGUI_RGB_B(c)>> 3) << 11) | ((RTGUI_RGB_G(c) >> 2) << 5) | (RTGUI_RGB_R(c) >> 3));
+
+	return pixel;
+}
+
+rt_inline rtgui_color_t rtgui_color_from_565(rt_uint16_t pixel)
+{
+	rt_uint16_t r, g, b;
+	rtgui_color_t color;
+
+	r = pixel & 0x1f;
+	g = (pixel >> 5) & 0x3f;
+	b = (pixel >> 11) & 0x1f;
+
+	color = r * 8225 / 1024 + ((g * 4047 / 1024) << 8) + ((b * 8225 / 1024) << 16);
+
+	return color;
+}
+
+/* convert rtgui color to RRRRRGGGGGGBBBBB */
+rt_inline rt_uint16_t rtgui_color_to_565p(rtgui_color_t c)
+{
+	rt_uint16_t pixel;
+
+	pixel = (rt_uint16_t)(((RTGUI_RGB_R(c) >> 3) << 11) | ((RTGUI_RGB_G(c) >> 2) << 5) | (RTGUI_RGB_B(c)>> 3));
+	return pixel;
+}
+
+rt_inline rtgui_color_t rtgui_color_from_565p(rt_uint16_t pixel)
+{
+	rt_uint8_t r, g, b;
+	rtgui_color_t color;
+
+	r = (pixel >> 11) & 0x1f;
+	g = (pixel >> 5)  & 0x3f;
+	b = pixel & 0x1f;
+
+	color = r * 8225 / 1024 + ((g * 4047 / 1024) << 8) + ((b * 8225 / 1024) << 16);
+
+	return color;
+}
+
+/* convert rtgui color to RGB */
+rt_inline rt_uint32_t rtgui_color_to_888(rtgui_color_t c)
+{
+	rt_uint32_t pixel;
+
+	pixel = RTGUI_RGB_R(c) << 16 | RTGUI_RGB_G(c) << 8 | RTGUI_RGB_B(c);
+	return pixel;
+}
+
+rt_inline rtgui_color_t rtgui_color_from_888(rt_uint32_t pixel)
+{
+	rtgui_color_t color;
+
+	color = RTGUI_RGB(((pixel >> 16) & 0xff), ((pixel >> 8) & 0xff), pixel & 0xff);
+
+	return color;
+}
+
+#endif
+

+ 196 - 196
components/rtgui/include/rtgui/dc.h

@@ -1,196 +1,196 @@
-/*
- * File      : dc.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_DC_H__
-#define __RTGUI_DC_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/font.h>
-#include <rtgui/driver.h>
-#include <rtgui/widgets/widget.h>
-
-enum rtgui_dc_type
-{
-	RTGUI_DC_HW,
-	RTGUI_DC_CLIENT,
-	RTGUI_DC_BUFFER,
-};
-
-struct rtgui_dc_engine
-{
-	/* interface */
-	void (*draw_point)(struct rtgui_dc* dc, int x, int y);
-	void (*draw_color_point)(struct rtgui_dc* dc, int x, int y, rtgui_color_t color);
-	void (*draw_vline)(struct rtgui_dc* dc, int x, int y1, int y2);
-	void (*draw_hline)(struct rtgui_dc* dc, int x1, int x2, int y);
-	void (*fill_rect )(struct rtgui_dc* dc, rtgui_rect_t* rect);
-	void (*blit_line) (struct rtgui_dc* dc, int x1, int x2, int y, rt_uint8_t* line_data);
-	void (*blit		 )(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
-
-	/* set and get graphic context */
-	void (*set_gc)(struct rtgui_dc* dc, struct rtgui_gc *gc);
-	struct rtgui_gc* (*get_gc)(struct rtgui_dc* dc);
-
-	/* get dc visible */
-	rt_bool_t (*get_visible)(struct rtgui_dc* dc);
-
-	/* get dc rect */
-	void (*get_rect  )(struct rtgui_dc* dc, rtgui_rect_t* rect);
-
-	rt_bool_t (*fini )(struct rtgui_dc* dc);
-};
-
-/* the abstract device context */
-struct rtgui_dc
-{
-	/* type of device context */
-	rt_uint32_t type;
-
-	/* dc engine */
-	const struct rtgui_dc_engine* engine;
-};
-
-#define RTGUI_DC_FC(dc)			(rtgui_dc_get_gc(dc)->foreground)
-#define RTGUI_DC_BC(dc)			(rtgui_dc_get_gc(dc)->background)
-#define RTGUI_DC_FONT(dc)		(rtgui_dc_get_gc(dc)->font)
-#define RTGUI_DC_TEXTALIGN(dc)	(rtgui_dc_get_gc(dc)->textalign)
-
-/* create a buffer dc */
-struct rtgui_dc* rtgui_dc_buffer_create(int width, int height);
-rt_uint8_t* rtgui_dc_buffer_get_pixel(struct rtgui_dc* dc);
-
-/* begin and end a drawing */
-struct rtgui_dc* rtgui_dc_begin_drawing(rtgui_widget_t* owner);
-void rtgui_dc_end_drawing(struct rtgui_dc* dc);
-
-/* destroy a dc */
-void rtgui_dc_destory(struct rtgui_dc* dc);
-
-void rtgui_dc_draw_line (struct rtgui_dc* dc, int x1, int y1, int x2, int y2);
-void rtgui_dc_draw_rect (struct rtgui_dc* dc, struct rtgui_rect* rect);
-void rtgui_dc_fill_rect_forecolor(struct rtgui_dc* dc, struct rtgui_rect* rect);
-void rtgui_dc_draw_round_rect(struct rtgui_dc* dc, struct rtgui_rect* rect, int r);
-void rtgui_dc_fill_round_rect(struct rtgui_dc* dc, struct rtgui_rect* rect, int r);
-void rtgui_dc_draw_annulus(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r1, rt_int16_t r2, rt_int16_t start, rt_int16_t end);
-void rtgui_dc_draw_sector(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r, rt_int16_t start, rt_int16_t end);
-void rtgui_dc_fill_sector(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r, rt_int16_t start, rt_int16_t end);
-
-void rtgui_dc_draw_text (struct rtgui_dc* dc, const char* text, struct rtgui_rect* rect);
-
-void rtgui_dc_draw_mono_bmp(struct rtgui_dc* dc, int x, int y, int w, int h, const rt_uint8_t* data);
-void rtgui_dc_draw_byte(struct rtgui_dc*dc, int x, int y, int h, const rt_uint8_t* data);
-void rtgui_dc_draw_word(struct rtgui_dc*dc, int x, int y, int h, const rt_uint8_t* data);
-
-void rtgui_dc_draw_border(struct rtgui_dc* dc, rtgui_rect_t* rect, int flag);
-void rtgui_dc_draw_horizontal_line(struct rtgui_dc* dc, int x1, int x2, int y);
-void rtgui_dc_draw_vertical_line(struct rtgui_dc* dc, int x, int y1, int y2);
-void rtgui_dc_draw_focus_rect(struct rtgui_dc* dc, rtgui_rect_t* rect);
-
-void rtgui_dc_draw_polygon(struct rtgui_dc* dc, const int *vx, const int *vy, int count);
-void rtgui_dc_fill_polygon(struct rtgui_dc* dc, const int* vx, const int* vy, int count);
-
-void rtgui_dc_draw_circle(struct rtgui_dc* dc, int x, int y, int r);
-void rtgui_dc_fill_circle(struct rtgui_dc* dc, rt_int16_t x, rt_int16_t y, rt_int16_t r);
-void rtgui_dc_draw_arc(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r, rt_int16_t start, rt_int16_t end);
-
-void rtgui_dc_draw_ellipse(struct rtgui_dc* dc, rt_int16_t x, rt_int16_t y, rt_int16_t rx, rt_int16_t ry);
-void rtgui_dc_fill_ellipse(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t rx, rt_int16_t ry);
-
-/*
- * dc inline function
- *
- * Note:
- * In order to improve drawing speed, put most of common function of dc to inline
- */
-
-/*
- * draw a point on dc
- */
-rt_inline void rtgui_dc_draw_point(struct rtgui_dc* dc, int x, int y)
-{
-	dc->engine->draw_point(dc, x, y);
-}
-
-/*
- * draw a color point on dc
- */
-rt_inline void rtgui_dc_draw_color_point(struct rtgui_dc* dc, int x, int y, rtgui_color_t color)
-{
-	dc->engine->draw_color_point(dc, x, y, color);
-}
-
-/*
- * draw a vertical line on dc
- */
-rt_inline void rtgui_dc_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2)
-{
-	dc->engine->draw_vline(dc, x, y1, y2);
-}
-
-/*
- * draw a horizontal line on dc
- */
-rt_inline void rtgui_dc_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y)
-{
-	dc->engine->draw_hline(dc, x1, x2, y);
-}
-
-/*
- * fill a rect with background color 
- */
-rt_inline void rtgui_dc_fill_rect (struct rtgui_dc* dc, struct rtgui_rect* rect)
-{
-	dc->engine->fill_rect(dc, rect);
-}
-
-/*
- * blit a dc on hardware dc
- */
-rt_inline void rtgui_dc_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
-{
-	dc->engine->blit(dc, dc_point, dest, rect);
-}
-
-/*
- * set gc of dc
- */
-rt_inline void rtgui_dc_set_gc(struct rtgui_dc* dc, rtgui_gc_t* gc)
-{
-	dc->engine->set_gc(dc, gc);
-}
-
-/*
- * get gc of dc
- */
-rt_inline rtgui_gc_t *rtgui_dc_get_gc(struct rtgui_dc* dc)
-{
-	return dc->engine->get_gc(dc);
-}
-
-/*
- * get visible status of dc 
- */
-rt_inline rt_bool_t rtgui_dc_get_visible(struct rtgui_dc* dc)
-{
-	return dc->engine->get_visible(dc);
-}
-
-/*
- * get rect of dc
- */
-rt_inline void rtgui_dc_get_rect(struct rtgui_dc*dc, rtgui_rect_t* rect)
-{
-	dc->engine->get_rect(dc, rect);
-}
-
-#endif
+/*
+ * File      : dc.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_DC_H__
+#define __RTGUI_DC_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/font.h>
+#include <rtgui/driver.h>
+#include <rtgui/widgets/widget.h>
+
+enum rtgui_dc_type
+{
+	RTGUI_DC_HW,
+	RTGUI_DC_CLIENT,
+	RTGUI_DC_BUFFER,
+};
+
+struct rtgui_dc_engine
+{
+	/* interface */
+	void (*draw_point)(struct rtgui_dc* dc, int x, int y);
+	void (*draw_color_point)(struct rtgui_dc* dc, int x, int y, rtgui_color_t color);
+	void (*draw_vline)(struct rtgui_dc* dc, int x, int y1, int y2);
+	void (*draw_hline)(struct rtgui_dc* dc, int x1, int x2, int y);
+	void (*fill_rect )(struct rtgui_dc* dc, rtgui_rect_t* rect);
+	void (*blit_line) (struct rtgui_dc* dc, int x1, int x2, int y, rt_uint8_t* line_data);
+	void (*blit		 )(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect);
+
+	/* set and get graphic context */
+	void (*set_gc)(struct rtgui_dc* dc, struct rtgui_gc *gc);
+	struct rtgui_gc* (*get_gc)(struct rtgui_dc* dc);
+
+	/* get dc visible */
+	rt_bool_t (*get_visible)(struct rtgui_dc* dc);
+
+	/* get dc rect */
+	void (*get_rect  )(struct rtgui_dc* dc, rtgui_rect_t* rect);
+
+	rt_bool_t (*fini )(struct rtgui_dc* dc);
+};
+
+/* the abstract device context */
+struct rtgui_dc
+{
+	/* type of device context */
+	rt_uint32_t type;
+
+	/* dc engine */
+	const struct rtgui_dc_engine* engine;
+};
+
+#define RTGUI_DC_FC(dc)			(rtgui_dc_get_gc(dc)->foreground)
+#define RTGUI_DC_BC(dc)			(rtgui_dc_get_gc(dc)->background)
+#define RTGUI_DC_FONT(dc)		(rtgui_dc_get_gc(dc)->font)
+#define RTGUI_DC_TEXTALIGN(dc)	(rtgui_dc_get_gc(dc)->textalign)
+
+/* create a buffer dc */
+struct rtgui_dc* rtgui_dc_buffer_create(int width, int height);
+rt_uint8_t* rtgui_dc_buffer_get_pixel(struct rtgui_dc* dc);
+
+/* begin and end a drawing */
+struct rtgui_dc* rtgui_dc_begin_drawing(rtgui_widget_t* owner);
+void rtgui_dc_end_drawing(struct rtgui_dc* dc);
+
+/* destroy a dc */
+void rtgui_dc_destory(struct rtgui_dc* dc);
+
+void rtgui_dc_draw_line (struct rtgui_dc* dc, int x1, int y1, int x2, int y2);
+void rtgui_dc_draw_rect (struct rtgui_dc* dc, struct rtgui_rect* rect);
+void rtgui_dc_fill_rect_forecolor(struct rtgui_dc* dc, struct rtgui_rect* rect);
+void rtgui_dc_draw_round_rect(struct rtgui_dc* dc, struct rtgui_rect* rect, int r);
+void rtgui_dc_fill_round_rect(struct rtgui_dc* dc, struct rtgui_rect* rect, int r);
+void rtgui_dc_draw_annulus(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r1, rt_int16_t r2, rt_int16_t start, rt_int16_t end);
+void rtgui_dc_draw_sector(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r, rt_int16_t start, rt_int16_t end);
+void rtgui_dc_fill_sector(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r, rt_int16_t start, rt_int16_t end);
+
+void rtgui_dc_draw_text (struct rtgui_dc* dc, const char* text, struct rtgui_rect* rect);
+
+void rtgui_dc_draw_mono_bmp(struct rtgui_dc* dc, int x, int y, int w, int h, const rt_uint8_t* data);
+void rtgui_dc_draw_byte(struct rtgui_dc*dc, int x, int y, int h, const rt_uint8_t* data);
+void rtgui_dc_draw_word(struct rtgui_dc*dc, int x, int y, int h, const rt_uint8_t* data);
+
+void rtgui_dc_draw_border(struct rtgui_dc* dc, rtgui_rect_t* rect, int flag);
+void rtgui_dc_draw_horizontal_line(struct rtgui_dc* dc, int x1, int x2, int y);
+void rtgui_dc_draw_vertical_line(struct rtgui_dc* dc, int x, int y1, int y2);
+void rtgui_dc_draw_focus_rect(struct rtgui_dc* dc, rtgui_rect_t* rect);
+
+void rtgui_dc_draw_polygon(struct rtgui_dc* dc, const int *vx, const int *vy, int count);
+void rtgui_dc_fill_polygon(struct rtgui_dc* dc, const int* vx, const int* vy, int count);
+
+void rtgui_dc_draw_circle(struct rtgui_dc* dc, int x, int y, int r);
+void rtgui_dc_fill_circle(struct rtgui_dc* dc, rt_int16_t x, rt_int16_t y, rt_int16_t r);
+void rtgui_dc_draw_arc(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r, rt_int16_t start, rt_int16_t end);
+
+void rtgui_dc_draw_ellipse(struct rtgui_dc* dc, rt_int16_t x, rt_int16_t y, rt_int16_t rx, rt_int16_t ry);
+void rtgui_dc_fill_ellipse(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t rx, rt_int16_t ry);
+
+/*
+ * dc inline function
+ *
+ * Note:
+ * In order to improve drawing speed, put most of common function of dc to inline
+ */
+
+/*
+ * draw a point on dc
+ */
+rt_inline void rtgui_dc_draw_point(struct rtgui_dc* dc, int x, int y)
+{
+	dc->engine->draw_point(dc, x, y);
+}
+
+/*
+ * draw a color point on dc
+ */
+rt_inline void rtgui_dc_draw_color_point(struct rtgui_dc* dc, int x, int y, rtgui_color_t color)
+{
+	dc->engine->draw_color_point(dc, x, y, color);
+}
+
+/*
+ * draw a vertical line on dc
+ */
+rt_inline void rtgui_dc_draw_vline(struct rtgui_dc* dc, int x, int y1, int y2)
+{
+	dc->engine->draw_vline(dc, x, y1, y2);
+}
+
+/*
+ * draw a horizontal line on dc
+ */
+rt_inline void rtgui_dc_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y)
+{
+	dc->engine->draw_hline(dc, x1, x2, y);
+}
+
+/*
+ * fill a rect with background color 
+ */
+rt_inline void rtgui_dc_fill_rect (struct rtgui_dc* dc, struct rtgui_rect* rect)
+{
+	dc->engine->fill_rect(dc, rect);
+}
+
+/*
+ * blit a dc on hardware dc
+ */
+rt_inline void rtgui_dc_blit(struct rtgui_dc* dc, struct rtgui_point* dc_point, struct rtgui_dc* dest, rtgui_rect_t* rect)
+{
+	dc->engine->blit(dc, dc_point, dest, rect);
+}
+
+/*
+ * set gc of dc
+ */
+rt_inline void rtgui_dc_set_gc(struct rtgui_dc* dc, rtgui_gc_t* gc)
+{
+	dc->engine->set_gc(dc, gc);
+}
+
+/*
+ * get gc of dc
+ */
+rt_inline rtgui_gc_t *rtgui_dc_get_gc(struct rtgui_dc* dc)
+{
+	return dc->engine->get_gc(dc);
+}
+
+/*
+ * get visible status of dc 
+ */
+rt_inline rt_bool_t rtgui_dc_get_visible(struct rtgui_dc* dc)
+{
+	return dc->engine->get_visible(dc);
+}
+
+/*
+ * get rect of dc
+ */
+rt_inline void rtgui_dc_get_rect(struct rtgui_dc*dc, rtgui_rect_t* rect)
+{
+	dc->engine->get_rect(dc, rect);
+}
+
+#endif

+ 27 - 27
components/rtgui/include/rtgui/dc_client.h

@@ -1,27 +1,27 @@
-/*
- * File      : dc_buffer.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-04-10     Bernard      first version
- * 2010-06-14     Bernard      embedded hardware dc to each widget
- * 2010-08-09     Bernard      rename hardware dc to client dc
- */
-
-#ifndef __RTGUI_DC_CLIENT_H__
-#define __RTGUI_DC_CLIENT_H__
-
-#include <rtgui/dc.h>
-
-/* create a hardware dc */
-struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner);
-void rtgui_dc_client_init(rtgui_widget_t* owner);
-
-#endif
-
+/*
+ * File      : dc_buffer.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-04-10     Bernard      first version
+ * 2010-06-14     Bernard      embedded hardware dc to each widget
+ * 2010-08-09     Bernard      rename hardware dc to client dc
+ */
+
+#ifndef __RTGUI_DC_CLIENT_H__
+#define __RTGUI_DC_CLIENT_H__
+
+#include <rtgui/dc.h>
+
+/* create a hardware dc */
+struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner);
+void rtgui_dc_client_init(rtgui_widget_t* owner);
+
+#endif
+

+ 24 - 24
components/rtgui/include/rtgui/dc_hw.h

@@ -1,24 +1,24 @@
-/*
- * File      : dc_buffer.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-04-10     Bernard      first version
- * 2010-06-14     Bernard      embedded hardware dc to each widget
- */
-#ifndef __RTGUI_DC_HW_H__
-#define __RTGUI_DC_HW_H__
-
-#include <rtgui/dc.h>
-
-/* create a hardware dc */
-struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner);
-
-#endif
-
+/*
+ * File      : dc_buffer.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-04-10     Bernard      first version
+ * 2010-06-14     Bernard      embedded hardware dc to each widget
+ */
+#ifndef __RTGUI_DC_HW_H__
+#define __RTGUI_DC_HW_H__
+
+#include <rtgui/dc.h>
+
+/* create a hardware dc */
+struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner);
+
+#endif
+

+ 119 - 0
components/rtgui/include/rtgui/dlist.h

@@ -0,0 +1,119 @@
+/*
+ * File      : dlist.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2006-03-16     Bernard      the first version
+ * 2006-09-07     Bernard      move the kservice APIs to rtthread.h
+ * 2007-06-27     Bernard      fix the rt_list_remove bug
+ * 2012-02-25     Grissiom     move to rtgui/include/rtgui and some misc changes
+ */
+
+#ifndef __RTGUI_DLIST_H__
+#define __RTGUI_DLIST_H__
+
+/* This file is copied from kservice.h in RTT kernel. There are some differences:
+ *     1, naming. Use rtgui_dlist_ prefix instead of rt_list.
+ *     2, add rtgui_dlist_foreach for convenience.
+ *     3, move the definition of list node into this file.
+ *
+ * Please keep both of the files synchronized when fixing bugs.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct rtgui_dlist_node
+{
+	struct rtgui_dlist_node *next;	/* point to next node. */
+	struct rtgui_dlist_node *prev;	/* point to prev node. */
+};
+
+/**
+ * @brief initialize a list
+ *
+ * @param l list to be initialized
+ */
+rt_inline void rtgui_dlist_init(struct rtgui_dlist_node *l)
+{
+	l->next = l->prev = l;
+}
+
+/**
+ * @brief insert a node after a list
+ *
+ * @param l list to insert it
+ * @param n new node to be inserted
+ */
+rt_inline void rtgui_dlist_insert_after(struct rtgui_dlist_node *l, struct rtgui_dlist_node *n)
+{
+	l->next->prev = n;
+	n->next = l->next;
+
+	l->next = n;
+	n->prev = l;
+}
+
+/**
+ * @brief insert a node before a list
+ *
+ * @param n new node to be inserted
+ * @param l list to insert it
+ */
+rt_inline void rtgui_dlist_insert_before(struct rtgui_dlist_node *l, struct rtgui_dlist_node *n)
+{
+	l->prev->next = n;
+	n->prev = l->prev;
+
+	l->prev = n;
+	n->next = l;
+}
+
+/**
+ * @brief remove node from list.
+ * @param n the node to remove from the list.
+ */
+rt_inline void rtgui_dlist_remove(struct rtgui_dlist_node *n)
+{
+	n->next->prev = n->prev;
+	n->prev->next = n->next;
+
+	rtgui_dlist_init(n);
+}
+
+/**
+ * @brief tests whether a list is empty
+ * @param l the list to test.
+ */
+rt_inline int rtgui_dlist_isempty(const struct rtgui_dlist_node *l)
+{
+	return l->next == l;
+}
+
+/**
+ * @brief get the struct for this entry
+ * @param node the entry point
+ * @param type the type of structure
+ * @param member the name of list in structure
+ */
+#define rtgui_dlist_entry(node, type, member) \
+    ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
+
+/* the direction can only be next or prev. If you want to iterate the list in
+ * normal order, use next. If you want to iterate the list with reverse order,
+ * use prev.*/
+#define rtgui_dlist_foreach(node, list, direction)	\
+	for ((node) = (list)->direction; (node) != list; (node) = (node)->direction)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 67 - 67
components/rtgui/include/rtgui/driver.h

@@ -1,67 +1,67 @@
-/*
- * File      : driver.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-04     Bernard      first version
- */
-#ifndef __RTGUI_DRIVER_H__
-#define __RTGUI_DRIVER_H__
-
-#include <rtgui/list.h>
-#include <rtgui/color.h>
-
-struct rtgui_graphic_driver_ops
-{
-	/* set and get pixel in (x, y) */
-	void (*set_pixel) (rtgui_color_t *c, int x, int y);
-	void (*get_pixel) (rtgui_color_t *c, int x, int y);
-
-	void (*draw_hline)(rtgui_color_t *c, int x1, int x2, int y);
-	void (*draw_vline)(rtgui_color_t *c, int x , int y1, int y2);
-
-	/* draw raw hline */
-	void (*draw_raw_hline)(rt_uint8_t *pixels, int x1, int x2, int y);
-};
-
-struct rtgui_graphic_driver
-{
-	/* pixel format and byte per pixel */
-	rt_uint8_t pixel_format;
-	rt_uint8_t bits_per_pixel;
-	rt_uint16_t pitch;
-
-	/* screen width and height */
-	rt_uint16_t width;
-	rt_uint16_t height;
-
-	/* framebuffer address and ops */
-	volatile rt_uint8_t *framebuffer;
-	rt_device_t device;
-	const struct rtgui_graphic_driver_ops *ops;
-};
-
-void rtgui_graphic_driver_add(const struct rtgui_graphic_driver* driver);
-
-struct rtgui_graphic_driver* rtgui_graphic_driver_get_default(void);
-
-void rtgui_graphic_driver_get_rect(const struct rtgui_graphic_driver *driver, rtgui_rect_t *rect);
-void rtgui_graphic_driver_screen_update(const struct rtgui_graphic_driver* driver, rtgui_rect_t *rect);
-rt_uint8_t* rtgui_graphic_driver_get_framebuffer(const struct rtgui_graphic_driver* driver);
-
-rt_err_t rtgui_graphic_set_device(rt_device_t device);
-
-rt_inline struct rtgui_graphic_driver* rtgui_graphic_get_device()
-{
-	extern struct rtgui_graphic_driver _driver;
-	return &_driver;
-}
-
-#endif
-
+/*
+ * File      : driver.h
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-04     Bernard      first version
+ */
+#ifndef __RTGUI_DRIVER_H__
+#define __RTGUI_DRIVER_H__
+
+#include <rtgui/list.h>
+#include <rtgui/color.h>
+
+struct rtgui_graphic_driver_ops
+{
+	/* set and get pixel in (x, y) */
+	void (*set_pixel) (rtgui_color_t *c, int x, int y);
+	void (*get_pixel) (rtgui_color_t *c, int x, int y);
+
+	void (*draw_hline)(rtgui_color_t *c, int x1, int x2, int y);
+	void (*draw_vline)(rtgui_color_t *c, int x , int y1, int y2);
+
+	/* draw raw hline */
+	void (*draw_raw_hline)(rt_uint8_t *pixels, int x1, int x2, int y);
+};
+
+struct rtgui_graphic_driver
+{
+	/* pixel format and byte per pixel */
+	rt_uint8_t pixel_format;
+	rt_uint8_t bits_per_pixel;
+	rt_uint16_t pitch;
+
+	/* screen width and height */
+	rt_uint16_t width;
+	rt_uint16_t height;
+
+	/* framebuffer address and ops */
+	volatile rt_uint8_t *framebuffer;
+	rt_device_t device;
+	const struct rtgui_graphic_driver_ops *ops;
+};
+
+void rtgui_graphic_driver_add(const struct rtgui_graphic_driver* driver);
+
+struct rtgui_graphic_driver* rtgui_graphic_driver_get_default(void);
+
+void rtgui_graphic_driver_get_rect(const struct rtgui_graphic_driver *driver, rtgui_rect_t *rect);
+void rtgui_graphic_driver_screen_update(const struct rtgui_graphic_driver* driver, rtgui_rect_t *rect);
+rt_uint8_t* rtgui_graphic_driver_get_framebuffer(const struct rtgui_graphic_driver* driver);
+
+rt_err_t rtgui_graphic_set_device(rt_device_t device);
+
+rt_inline struct rtgui_graphic_driver* rtgui_graphic_get_device()
+{
+	extern struct rtgui_graphic_driver _driver;
+	return &_driver;
+}
+
+#endif
+

+ 352 - 423
components/rtgui/include/rtgui/event.h

@@ -1,423 +1,352 @@
-/*
- * File      : event.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-04     Bernard      first version
- */
-#ifndef __RTGUI_EVENT_H__
-#define __RTGUI_EVENT_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/kbddef.h>
-
-enum _rtgui_event_type
-{
-	/* panel event */
-	RTGUI_EVENT_PANEL_ATTACH = 0,	/* attach to a panel	*/
-	RTGUI_EVENT_PANEL_DETACH,		/* detach from a panel	*/
-	RTGUI_EVENT_PANEL_SHOW,			/* show in a panel		*/
-	RTGUI_EVENT_PANEL_HIDE,			/* hide from a panel	*/
-	RTGUI_EVENT_PANEL_INFO,			/* panel information 	*/
-	RTGUI_EVENT_PANEL_RESIZE,		/* resize panel 		*/
-	RTGUI_EVENT_PANEL_FULLSCREEN,	/* to full screen 		*/
-	RTGUI_EVENT_PANEL_NORMAL,		/* to normal screen 	*/
-
-	/* window event */
-	RTGUI_EVENT_WIN_CREATE,			/* create a window 		*/
-	RTGUI_EVENT_WIN_DESTROY,		/* destroy a window 	*/
-	RTGUI_EVENT_WIN_SHOW,			/* show a window 		*/
-	RTGUI_EVENT_WIN_HIDE,			/* hide a window 		*/
-	RTGUI_EVENT_WIN_ACTIVATE, 		/* activate a window 	*/
-	RTGUI_EVENT_WIN_DEACTIVATE,		/* deactivate a window 	*/
-	RTGUI_EVENT_WIN_CLOSE,			/* close a window 		*/
-	RTGUI_EVENT_WIN_MOVE,			/* move a window 		*/
-	RTGUI_EVENT_WIN_RESIZE, 		/* resize a window 		*/
-
-	/* WM event */
-	RTGUI_EVENT_SET_WM,				/* set window manager   */
-
-	RTGUI_EVENT_UPDATE_BEGIN,		/* update a rect 		*/
-	RTGUI_EVENT_UPDATE_END,			/* update a rect 		*/
-	RTGUI_EVENT_MONITOR_ADD,		/* add a monitor rect 	*/
-	RTGUI_EVENT_MONITOR_REMOVE,		/* remove a monitor rect*/
-	RTGUI_EVENT_PAINT,				/* paint on screen 		*/
-	RTGUI_EVENT_TIMER,				/* timer 				*/
-
-	/* clip rect information */
-	RTGUI_EVENT_CLIP_INFO,			/* clip rect info		*/
-
-	/* mouse and keyboard event */
-	RTGUI_EVENT_MOUSE_MOTION,		/* mouse motion */
-	RTGUI_EVENT_MOUSE_BUTTON,		/* mouse button info 	*/
-	RTGUI_EVENT_KBD,				/* keyboard info		*/
-
-	/* user command event */
-	RTGUI_EVENT_COMMAND,			/* user command 		*/
-
-	/* widget event */
-	RTGUI_EVENT_FOCUSED,			/* widget focused       */
-	RTGUI_EVENT_SCROLLED,           /* scroll bar scrolled  */
-	RTGUI_EVENT_RESIZE,				/* widget resize 		*/
-};
-typedef enum _rtgui_event_type rtgui_event_type;
-
-enum {
-	RTGUI_STATUS_OK = 0,		/* status ok 		*/
-	RTGUI_STATUS_ERROR,			/* generic error 	*/
-	RTGUI_STATUS_NRC,			/* no resource 		*/
-};
-
-struct rtgui_event
-{
-	/* the event type */
-	rt_uint16_t type;
-	/* user field of event */
-	rt_uint16_t user;
-
-	/* the event sender */
-	rt_thread_t sender;
-
-	/* mailbox to acknowledge request */
-	rt_mailbox_t ack;
-};
-typedef struct rtgui_event rtgui_event_t;
-#define RTGUI_EVENT(e)	((struct rtgui_event*)(e))
-
-#define RTGUI_EVENT_INIT(e, t)	do		\
-{										\
-	(e)->type = (t);					\
-	(e)->user = 0;						\
-	(e)->sender = rt_thread_self();		\
-	(e)->ack = RT_NULL;					\
-} while (0)
-
-/*
- * RTGUI Panel Event
- */
-struct rtgui_event_panel_attach
-{
-	struct rtgui_event parent;
-
-	/* the panel name to be attached */
-	char panel_name[RTGUI_NAME_MAX];
-
-	/* workbench, wm field */
-	rtgui_workbench_t* workbench;
-};
-
-struct rtgui_event_panel_detach
-{
-	struct rtgui_event parent;
-
-	/* the panel which thread belong to */
-	rtgui_panel_t* panel;
-
-	/* workbench, wm field */
-	rtgui_workbench_t* workbench;
-};
-
-struct rtgui_event_panel_show
-{
-	struct rtgui_event parent;
-
-	/* the panel which thread belong to */
-	rtgui_panel_t* panel;
-
-	/* workbench, wm field */
-	rtgui_workbench_t* workbench;
-};
-
-struct rtgui_event_panel_hide
-{
-	struct rtgui_event parent;
-
-	/* the panel which thread belong to */
-	rtgui_panel_t* panel;
-
-	/* workbench, wm field */
-	rtgui_workbench_t* workbench;
-};
-
-struct rtgui_event_panel_info
-{
-	struct rtgui_event parent;
-
-	/* panel info */
-	rtgui_panel_t* panel;
-	rtgui_rect_t extent;
-};
-
-#define RTGUI_EVENT_PANEL_ATTACH_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_PANEL_ATTACH)
-#define RTGUI_EVENT_PANEL_DETACH_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_PANEL_DETACH)
-#define RTGUI_EVENT_PANEL_SHOW_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_PANEL_SHOW)
-#define RTGUI_EVENT_PANEL_HIDE_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_PANEL_HIDE)
-#define RTGUI_EVENT_PANEL_INFO_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_PANEL_INFO)
-
-/*
- * RTGUI Window Event
- */
-struct rtgui_event_win
-{
-	struct rtgui_event parent;
-
-	/* the window id */
-	rtgui_win_t* wid;
-};
-
-struct rtgui_event_win_create
-{
-	struct rtgui_event parent;
-
-#ifndef RTGUI_USING_SMALL_SIZE
-	/* the window title */
-	rt_uint8_t title[RTGUI_NAME_MAX];
-	/* the window extent */
-	struct rtgui_rect extent;
-#endif
-
-	/* the window id */
-	rtgui_win_t* wid;
-};
-
-struct rtgui_event_win_move
-{
-	struct rtgui_event parent;
-
-	/* the window id */
-	rtgui_win_t* wid;
-
-	rt_int16_t x, y;
-};
-
-struct rtgui_event_win_resize
-{
-	struct rtgui_event parent;
-
-	/* the window id */
-	rtgui_win_t* wid;
-
-	rtgui_rect_t rect;
-};
-
-#define	rtgui_event_win_destroy 	rtgui_event_win
-#define	rtgui_event_win_show 		rtgui_event_win
-#define	rtgui_event_win_hide 		rtgui_event_win
-#define	rtgui_event_win_activate	rtgui_event_win
-#define rtgui_event_win_deactivate 	rtgui_event_win
-#define rtgui_event_win_close 		rtgui_event_win
-
-/* window event init */
-#define RTGUI_EVENT_WIN_CREATE_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_CREATE)
-#define RTGUI_EVENT_WIN_DESTROY_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_DESTROY)
-#define RTGUI_EVENT_WIN_SHOW_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_SHOW)
-#define RTGUI_EVENT_WIN_HIDE_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_HIDE)
-#define RTGUI_EVENT_WIN_ACTIVATE_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_ACTIVATE)
-#define RTGUI_EVENT_WIN_DEACTIVATE_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_DEACTIVATE)
-#define RTGUI_EVENT_WIN_CLOSE_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_CLOSE)
-#define RTGUI_EVENT_WIN_MOVE_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_MOVE)
-#define RTGUI_EVENT_WIN_RESIZE_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_RESIZE)
-
-/*
- * RTGUI Workbench Manager Event
- */
-struct rtgui_event_set_wm
-{
-	struct rtgui_event parent;
-
-	/* the panel name to be managed */
-	char panel_name[RTGUI_NAME_MAX];
-};
-/* window event init */
-#define RTGUI_EVENT_SET_WM_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_SET_WM)
-
-/*
- * RTGUI Other Event
- */
-struct rtgui_event_update_begin
-{
-	struct rtgui_event parent;
-
-	/* the update rect */
-	rtgui_rect_t rect;
-};
-
-struct rtgui_event_update_end
-{
-	struct rtgui_event parent;
-
-	/* the update rect */
-	rtgui_rect_t rect;
-};
-
-struct rtgui_event_monitor
-{
-	struct rtgui_event parent;
-
-	/* the monitor rect */
-	rtgui_rect_t rect;
-
-	/* under panel */
-	rtgui_panel_t* panel;
-
-	/* or under window */
-	rtgui_win_t* wid;
-};
-
-struct rtgui_event_paint
-{
-	struct rtgui_event parent;
-
-	rtgui_win_t* wid;		/* destination window */
-	rtgui_rect_t rect;		/* rect to be updated */
-};
-
-struct rtgui_timer;
-struct rtgui_event_timer
-{
-	struct rtgui_event parent;
-
-	struct rtgui_timer *timer;
-};
-typedef struct rtgui_event_timer rtgui_event_timer_t;
-
-
-struct rtgui_event_clip_info
-{
-	struct rtgui_event parent;
-
-	/* destination window */
-	rtgui_win_t* wid;
-
-	/* the number of rects */
-	rt_uint32_t num_rect;
-
-	/* rtgui_rect_t *rects */
-};
-#define RTGUI_EVENT_GET_RECT(e, i)			&(((rtgui_rect_t*)(e + 1))[i])
-
-#define RTGUI_EVENT_UPDATE_BEGIN_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_UPDATE_BEGIN)
-#define RTGUI_EVENT_UPDATE_END_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_UPDATE_END)
-#define RTGUI_EVENT_MONITOR_ADD_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_MONITOR_ADD)
-#define RTGUI_EVENT_MONITOR_REMOVE_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_MONITOR_REMOVE)
-#define RTGUI_EVENT_CLIP_INFO_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_CLIP_INFO)
-#define RTGUI_EVENT_PAINT_INIT(e)			RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_PAINT)
-#define RTGUI_EVENT_TIMER_INIT(e)			RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_TIMER)
-
-/*
- * RTGUI Mouse and Keyboard Event
- */
-struct rtgui_event_mouse
-{
-	struct rtgui_event parent;
-
-	rtgui_win_t* wid;		/* destination window */
-
-	rt_uint16_t x, y;
-	rt_uint16_t button;
-};
-#define RTGUI_MOUSE_BUTTON_LEFT			0x01
-#define RTGUI_MOUSE_BUTTON_RIGHT		0x02
-#define RTGUI_MOUSE_BUTTON_MIDDLE		0x03
-#define RTGUI_MOUSE_BUTTON_WHEELUP		0x04
-#define RTGUI_MOUSE_BUTTON_WHEELDOWN	0x08
-
-#define RTGUI_MOUSE_BUTTON_DOWN			0x10
-#define RTGUI_MOUSE_BUTTON_UP			0x20
-
-struct rtgui_event_kbd
-{
-	struct rtgui_event parent;
-
-	rtgui_win_t* wid;		/* destination window */
-
-	rt_uint16_t type;		/* key down or up */
-	rt_uint16_t key;		/* current key */
-	rt_uint16_t mod;		/* current key modifiers */
-	rt_uint16_t unicode;	/* translated character */
-};
-#define RTGUI_KBD_IS_SET_CTRL(e)	((e)->mod & (RTGUI_KMOD_LCTRL | RTGUI_KMOD_RCTRL)))
-#define RTGUI_KBD_IS_SET_ALT(e)		((e)->mod & (RTGUI_KMOD_LALT  | RTGUI_KMOD_RALT))
-#define RTGUI_KBD_IS_SET_SHIFT(e)	((e)->mod & (RTGUI_KMOD_LSHIFT| RTGUI_KMOD_RSHIFT))
-#define RTGUI_KBD_IS_UP(e)			((e)->type == RTGUI_KEYUP)
-#define RTGUI_KBD_IS_DOWN(e)		((e)->type == RTGUI_KEYDOWN)
-
-#define RTGUI_EVENT_MOUSE_MOTION_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_MOUSE_MOTION)
-#define RTGUI_EVENT_MOUSE_BUTTON_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_MOUSE_BUTTON)
-#define RTGUI_EVENT_KBD_INIT(e)				RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_KBD)
-
-struct rtgui_event_command
-{
-	struct rtgui_event parent;
-
-	/* command type */
-	rt_int32_t type;
-
-	/* command id */
-	rt_int32_t command_id;
-
-	/* command string */
-	char command_string[RTGUI_NAME_MAX];
-};
-#define RTGUI_EVENT_COMMAND_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_COMMAND)
-
-#define RTGUI_CMD_UNKNOWN		0x00
-#define RTGUI_CMD_WM_CLOSE		0x10
-
-#define RTGUI_CMD_USER_INT		0x20
-#define RTGUI_CMD_USER_STRING	0x21
-
-/************************************************************************/
-/* Widget Event                                                         */
-/************************************************************************/
-#define RTGUI_WIDGET_EVENT_INIT(e, t)	do		\
-{										\
-	(e)->type = (t);					\
-	(e)->sender = RT_NULL;				\
-	(e)->ack = RT_NULL;					\
-} while (0)
-
-/*
- * RTGUI Scrollbar Event
- */
-struct rtgui_event_scrollbar
-{
-    struct rtgui_event parent;
-
-    rt_uint8_t event;
-};
-#define RTGUI_SCROLL_LINEUP             0x01
-#define RTGUI_SCROLL_LINEDOWN           0x02
-#define RTGUI_SCROLL_PAGEUP             0x03
-#define RTGUI_SCROLL_PAGEDOWN           0x04
-#define RTGUI_EVENT_SCROLLED_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_SCROLLED)
-
-/*
- * RTGUI Widget Focused Event
- */
-struct rtgui_event_focused
-{
-    struct rtgui_event parent;
-
-	struct rtgui_widget* widget;
-};
-#define RTGUI_EVENT_FOCUSED_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_FOCUSED)
-
-/*
- * RTGUI Widget Resize Event
- */
-struct rtgui_event_resize
-{
-	struct rtgui_event parent;
-	rt_int16_t x, y;
-	rt_int16_t w, h;
-};
-#define RTGUI_EVENT_RESIZE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_RESIZE)
-
-#endif
+/*
+ * File      : event.h
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-04     Bernard      first version
+ */
+#ifndef __RTGUI_EVENT_H__
+#define __RTGUI_EVENT_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/kbddef.h>
+
+/* NOTE: if you create a new event type, remember to add it into the union
+ * rtgui_event_generic */
+enum _rtgui_event_type
+{
+	/* window event */
+	RTGUI_EVENT_WIN_CREATE,            /* create a window       */
+	RTGUI_EVENT_WIN_DESTROY,           /* destroy a window      */
+	RTGUI_EVENT_WIN_SHOW,              /* show a window         */
+	RTGUI_EVENT_WIN_HIDE,              /* hide a window         */
+	RTGUI_EVENT_WIN_ACTIVATE,          /* activate a window     */
+	RTGUI_EVENT_WIN_DEACTIVATE,        /* deactivate a window   */
+	RTGUI_EVENT_WIN_CLOSE,             /* close a window        */
+	RTGUI_EVENT_WIN_MOVE,              /* move a window         */
+	RTGUI_EVENT_WIN_RESIZE,            /* resize a window       */
+	RTGUI_EVENT_WIN_MODAL_ENTER,       /* the window is entering modal mode.
+										  This event should be sent after the
+										  window got setup and before the
+										  application got setup. */
+
+	/* WM event */
+	RTGUI_EVENT_SET_WM,                /* set window manager    */
+
+	RTGUI_EVENT_UPDATE_BEGIN,          /* update a rect         */
+	RTGUI_EVENT_UPDATE_END,            /* update a rect         */
+	RTGUI_EVENT_MONITOR_ADD,           /* add a monitor rect    */
+	RTGUI_EVENT_MONITOR_REMOVE,        /* remove a monitor rect */
+	RTGUI_EVENT_PAINT,                 /* paint on screen       */
+	RTGUI_EVENT_TIMER,                 /* timer                 */
+
+	/* clip rect information */
+	RTGUI_EVENT_CLIP_INFO,             /* clip rect info        */
+
+	/* mouse and keyboard event */
+	RTGUI_EVENT_MOUSE_MOTION,          /* mouse motion          */
+	RTGUI_EVENT_MOUSE_BUTTON,          /* mouse button info     */
+	RTGUI_EVENT_KBD,                   /* keyboard info         */
+
+	/* user command event */
+	RTGUI_EVENT_COMMAND,               /* user command          */
+
+	/* widget event */
+	RTGUI_EVENT_FOCUSED,               /* widget focused        */
+	RTGUI_EVENT_SCROLLED,              /* scroll bar scrolled   */
+	RTGUI_EVENT_RESIZE,                /* widget resize         */
+};
+typedef enum _rtgui_event_type rtgui_event_type;
+
+enum {
+	RTGUI_STATUS_OK = 0,        /* status ok         */
+	RTGUI_STATUS_ERROR,         /* generic error     */
+	RTGUI_STATUS_NRC,           /* no resource       */
+};
+
+struct rtgui_event
+{
+	/* the event type */
+	rt_uint16_t type;
+	/* user field of event */
+	rt_uint16_t user;
+
+	/* the event sender */
+	rt_thread_t sender;
+
+	/* mailbox to acknowledge request */
+	rt_mailbox_t ack;
+};
+typedef struct rtgui_event rtgui_event_t;
+#define RTGUI_EVENT(e)	((struct rtgui_event*)(e))
+
+#define RTGUI_EVENT_INIT(e, t)	do		\
+{										\
+	(e)->type = (t);					\
+	(e)->user = 0;						\
+	(e)->sender = rt_thread_self();		\
+	(e)->ack = RT_NULL;					\
+} while (0)
+
+#define _RTGUI_EVENT_WIN_ELEMENTS \
+	struct rtgui_event parent; \
+	struct rtgui_win *wid;
+
+/*
+ * RTGUI Window Event
+ */
+struct rtgui_event_win
+{
+	_RTGUI_EVENT_WIN_ELEMENTS
+};
+
+struct rtgui_event_win_create
+{
+	_RTGUI_EVENT_WIN_ELEMENTS
+	struct rtgui_win *parent_window;
+#ifndef RTGUI_USING_SMALL_SIZE
+	/* the window title */
+	rt_uint8_t title[RTGUI_NAME_MAX];
+	/* the window extent */
+	struct rtgui_rect extent;
+#endif
+};
+
+struct rtgui_event_win_move
+{
+	_RTGUI_EVENT_WIN_ELEMENTS
+	rt_int16_t x, y;
+};
+
+struct rtgui_event_win_resize
+{
+	_RTGUI_EVENT_WIN_ELEMENTS
+
+	rtgui_rect_t rect;
+};
+
+#define rtgui_event_win_destroy      rtgui_event_win
+#define rtgui_event_win_show         rtgui_event_win
+#define rtgui_event_win_hide         rtgui_event_win
+#define rtgui_event_win_activate     rtgui_event_win
+#define rtgui_event_win_deactivate   rtgui_event_win
+#define rtgui_event_win_close        rtgui_event_win
+#define rtgui_event_win_modal_enter  rtgui_event_win
+
+/* window event init */
+#define RTGUI_EVENT_WIN_CREATE_INIT(e)      RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_CREATE)
+#define RTGUI_EVENT_WIN_DESTROY_INIT(e)     RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_DESTROY)
+#define RTGUI_EVENT_WIN_SHOW_INIT(e)        RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_SHOW)
+#define RTGUI_EVENT_WIN_HIDE_INIT(e)        RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_HIDE)
+#define RTGUI_EVENT_WIN_ACTIVATE_INIT(e)    RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_ACTIVATE)
+#define RTGUI_EVENT_WIN_DEACTIVATE_INIT(e)  RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_DEACTIVATE)
+#define RTGUI_EVENT_WIN_CLOSE_INIT(e)       RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_CLOSE)
+#define RTGUI_EVENT_WIN_MOVE_INIT(e)        RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_MOVE)
+#define RTGUI_EVENT_WIN_RESIZE_INIT(e)      RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_RESIZE)
+#define RTGUI_EVENT_WIN_MODAL_ENTER_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_MODAL_ENTER)
+
+/*
+ * RTGUI Other Event
+ */
+struct rtgui_event_update_begin
+{
+	struct rtgui_event parent;
+
+	/* the update rect */
+	rtgui_rect_t rect;
+};
+
+struct rtgui_event_update_end
+{
+	struct rtgui_event parent;
+
+	/* the update rect */
+	rtgui_rect_t rect;
+};
+
+struct rtgui_event_monitor
+{
+	_RTGUI_EVENT_WIN_ELEMENTS
+
+	/* the monitor rect */
+	rtgui_rect_t rect;
+};
+
+struct rtgui_event_paint
+{
+	_RTGUI_EVENT_WIN_ELEMENTS
+
+	rtgui_rect_t rect;		/* rect to be updated */
+};
+
+struct rtgui_timer;
+struct rtgui_event_timer
+{
+	struct rtgui_event parent;
+
+	struct rtgui_timer *timer;
+};
+typedef struct rtgui_event_timer rtgui_event_timer_t;
+
+
+struct rtgui_event_clip_info
+{
+	_RTGUI_EVENT_WIN_ELEMENTS
+
+	/* the number of rects */
+	//rt_uint32_t num_rect;
+
+	/* rtgui_rect_t *rects */
+};
+#define RTGUI_EVENT_GET_RECT(e, i)			&(((rtgui_rect_t*)(e + 1))[i])
+
+#define RTGUI_EVENT_UPDATE_BEGIN_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_UPDATE_BEGIN)
+#define RTGUI_EVENT_UPDATE_END_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_UPDATE_END)
+#define RTGUI_EVENT_MONITOR_ADD_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_MONITOR_ADD)
+#define RTGUI_EVENT_MONITOR_REMOVE_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_MONITOR_REMOVE)
+#define RTGUI_EVENT_CLIP_INFO_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_CLIP_INFO)
+#define RTGUI_EVENT_PAINT_INIT(e)			RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_PAINT)
+#define RTGUI_EVENT_TIMER_INIT(e)			RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_TIMER)
+
+/*
+ * RTGUI Mouse and Keyboard Event
+ */
+struct rtgui_event_mouse
+{
+	_RTGUI_EVENT_WIN_ELEMENTS
+
+	rt_uint16_t x, y;
+	rt_uint16_t button;
+};
+#define RTGUI_MOUSE_BUTTON_LEFT			0x01
+#define RTGUI_MOUSE_BUTTON_RIGHT		0x02
+#define RTGUI_MOUSE_BUTTON_MIDDLE		0x03
+#define RTGUI_MOUSE_BUTTON_WHEELUP		0x04
+#define RTGUI_MOUSE_BUTTON_WHEELDOWN	0x08
+
+#define RTGUI_MOUSE_BUTTON_DOWN			0x10
+#define RTGUI_MOUSE_BUTTON_UP			0x20
+
+struct rtgui_event_kbd
+{
+	_RTGUI_EVENT_WIN_ELEMENTS
+
+	rt_uint16_t type;		/* key down or up */
+	rt_uint16_t key;		/* current key */
+	rt_uint16_t mod;		/* current key modifiers */
+	rt_uint16_t unicode;	/* translated character */
+};
+#define RTGUI_KBD_IS_SET_CTRL(e)	((e)->mod & (RTGUI_KMOD_LCTRL | RTGUI_KMOD_RCTRL)))
+#define RTGUI_KBD_IS_SET_ALT(e)		((e)->mod & (RTGUI_KMOD_LALT  | RTGUI_KMOD_RALT))
+#define RTGUI_KBD_IS_SET_SHIFT(e)	((e)->mod & (RTGUI_KMOD_LSHIFT| RTGUI_KMOD_RSHIFT))
+#define RTGUI_KBD_IS_UP(e)			((e)->type == RTGUI_KEYUP)
+#define RTGUI_KBD_IS_DOWN(e)		((e)->type == RTGUI_KEYDOWN)
+
+#define RTGUI_EVENT_MOUSE_MOTION_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_MOUSE_MOTION)
+#define RTGUI_EVENT_MOUSE_BUTTON_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_MOUSE_BUTTON)
+#define RTGUI_EVENT_KBD_INIT(e)				RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_KBD)
+
+struct rtgui_event_command
+{
+        _RTGUI_EVENT_WIN_ELEMENTS
+
+	/* command type */
+	rt_int32_t type;
+
+	/* command id */
+	rt_int32_t command_id;
+
+	/* command string */
+	char command_string[RTGUI_NAME_MAX];
+};
+#define RTGUI_EVENT_COMMAND_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_COMMAND)
+
+#define RTGUI_CMD_UNKNOWN		0x00
+#define RTGUI_CMD_WM_CLOSE		0x10
+
+#define RTGUI_CMD_USER_INT		0x20
+#define RTGUI_CMD_USER_STRING	0x21
+
+/************************************************************************/
+/* Widget Event                                                         */
+/************************************************************************/
+#define RTGUI_WIDGET_EVENT_INIT(e, t)	do		\
+{										\
+	(e)->type = (t);					\
+	(e)->sender = RT_NULL;				\
+	(e)->ack = RT_NULL;					\
+} while (0)
+
+/*
+ * RTGUI Scrollbar Event
+ */
+struct rtgui_event_scrollbar
+{
+    struct rtgui_event parent;
+
+    rt_uint8_t event;
+};
+#define RTGUI_SCROLL_LINEUP             0x01
+#define RTGUI_SCROLL_LINEDOWN           0x02
+#define RTGUI_SCROLL_PAGEUP             0x03
+#define RTGUI_SCROLL_PAGEDOWN           0x04
+#define RTGUI_EVENT_SCROLLED_INIT(e)	RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_SCROLLED)
+
+/*
+ * RTGUI Widget Focused Event
+ */
+struct rtgui_event_focused
+{
+    struct rtgui_event parent;
+
+	struct rtgui_widget* widget;
+};
+#define RTGUI_EVENT_FOCUSED_INIT(e)		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_FOCUSED)
+
+/*
+ * RTGUI Widget Resize Event
+ */
+struct rtgui_event_resize
+{
+	struct rtgui_event parent;
+	rt_int16_t x, y;
+	rt_int16_t w, h;
+};
+#define RTGUI_EVENT_RESIZE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_RESIZE)
+
+#undef _RTGUI_EVENT_WIN_ELEMENTS
+
+union rtgui_event_generic
+{
+	struct rtgui_event base;
+	struct rtgui_event_win win_base;
+	struct rtgui_event_win_create win_create;
+	struct rtgui_event_win_move win_move;
+	struct rtgui_event_win_resize win_resize;
+	struct rtgui_event_win_destroy win_destroy;
+	struct rtgui_event_win_show win_show;
+	struct rtgui_event_win_hide win_hide;
+	struct rtgui_event_win_activate win_activate;
+	struct rtgui_event_win_deactivate win_deactivate;
+	struct rtgui_event_win_close win_close;
+	struct rtgui_event_win_modal_enter win_modal_enter;
+	struct rtgui_event_update_begin update_begin;
+	struct rtgui_event_update_end update_end;
+	struct rtgui_event_monitor monitor;
+	struct rtgui_event_paint paint;
+	struct rtgui_event_timer timer;
+	struct rtgui_event_clip_info clip_info;
+	struct rtgui_event_mouse mouse;
+	struct rtgui_event_kbd kbd;
+	struct rtgui_event_command command;
+	struct rtgui_event_scrollbar scrollbar;
+	struct rtgui_event_focused focused;
+	struct rtgui_event_resize resize;
+};
+#endif

+ 47 - 47
components/rtgui/include/rtgui/filerw.h

@@ -1,47 +1,47 @@
-/*
- * File      : filerw.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_FILERW_H__
-#define __RTGUI_FILERW_H__
-
-#include <rtgui/rtgui.h>
-
-#define RTGUI_FILE_SEEK_SET	0
-#define RTGUI_FILE_SEEK_CUR	1
-#define RTGUI_FILE_SEEK_END	2
-
-struct rtgui_filerw
-{
-	int (*seek) (struct rtgui_filerw *context, rt_off_t offset, int whence);
-	int (*read) (struct rtgui_filerw *context, void *buffer, rt_size_t size, rt_size_t count);
-	int (*write)(struct rtgui_filerw *context, const void *buffer, rt_size_t size, rt_size_t count);
-	int (*tell) (struct rtgui_filerw *context);
-	int (*eof)	(struct rtgui_filerw *context);
-	int (*close)(struct rtgui_filerw *context);
-};
-typedef struct rtgui_filerw rtgui_filerw_t;
-
-struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode);
-struct rtgui_filerw* rtgui_filerw_create_mem(const rt_uint8_t* mem, rt_size_t size);
-
-int rtgui_filerw_seek (struct rtgui_filerw* context, rt_off_t offset, int whence);
-int rtgui_filerw_read (struct rtgui_filerw* context, void* buffer, rt_size_t size, rt_size_t count);
-int rtgui_filerw_write(struct rtgui_filerw* context, const void* buffer, rt_size_t size, rt_size_t count);
-int rtgui_filerw_tell (struct rtgui_filerw* context);
-int rtgui_filerw_eof  (struct rtgui_filerw* context);
-int rtgui_filerw_close(struct rtgui_filerw* context);
-
-/* get memory data from filerw memory object */
-const rt_uint8_t* rtgui_filerw_mem_getdata(struct rtgui_filerw* context);
-
-#endif
+/*
+ * File      : filerw.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_FILERW_H__
+#define __RTGUI_FILERW_H__
+
+#include <rtgui/rtgui.h>
+
+#define RTGUI_FILE_SEEK_SET	0
+#define RTGUI_FILE_SEEK_CUR	1
+#define RTGUI_FILE_SEEK_END	2
+
+struct rtgui_filerw
+{
+	int (*seek) (struct rtgui_filerw *context, rt_off_t offset, int whence);
+	int (*read) (struct rtgui_filerw *context, void *buffer, rt_size_t size, rt_size_t count);
+	int (*write)(struct rtgui_filerw *context, const void *buffer, rt_size_t size, rt_size_t count);
+	int (*tell) (struct rtgui_filerw *context);
+	int (*eof)	(struct rtgui_filerw *context);
+	int (*close)(struct rtgui_filerw *context);
+};
+typedef struct rtgui_filerw rtgui_filerw_t;
+
+struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode);
+struct rtgui_filerw* rtgui_filerw_create_mem(const rt_uint8_t* mem, rt_size_t size);
+
+int rtgui_filerw_seek (struct rtgui_filerw* context, rt_off_t offset, int whence);
+int rtgui_filerw_read (struct rtgui_filerw* context, void* buffer, rt_size_t size, rt_size_t count);
+int rtgui_filerw_write(struct rtgui_filerw* context, const void* buffer, rt_size_t size, rt_size_t count);
+int rtgui_filerw_tell (struct rtgui_filerw* context);
+int rtgui_filerw_eof  (struct rtgui_filerw* context);
+int rtgui_filerw_close(struct rtgui_filerw* context);
+
+/* get memory data from filerw memory object */
+const rt_uint8_t* rtgui_filerw_mem_getdata(struct rtgui_filerw* context);
+
+#endif

+ 103 - 103
components/rtgui/include/rtgui/font.h

@@ -1,40 +1,40 @@
-/*
- * File      : font.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_FONT_H__
-#define __RTGUI_FONT_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/list.h>
-
-struct rtgui_font;
-struct rtgui_dc;
-struct rtgui_rect;
-
-struct rtgui_font_engine
-{
-	/* font engine function */
-	void (*font_init)(struct rtgui_font* font);
-	void (*font_load)(struct rtgui_font* font);
-
-	void (*font_draw_text)(struct rtgui_font* font, struct rtgui_dc* dc, const char* text,
-		rt_ubase_t len, struct rtgui_rect* rect);
-	void (*font_get_metrics)(struct rtgui_font* font, const char* text, struct rtgui_rect* rect);
-};
-
-/*
- * bitmap font engine
- */
+/*
+ * File      : font.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_FONT_H__
+#define __RTGUI_FONT_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/list.h>
+
+struct rtgui_font;
+struct rtgui_dc;
+struct rtgui_rect;
+
+struct rtgui_font_engine
+{
+	/* font engine function */
+	void (*font_init)(struct rtgui_font* font);
+	void (*font_load)(struct rtgui_font* font);
+
+	void (*font_draw_text)(struct rtgui_font* font, struct rtgui_dc* dc, const char* text,
+		rt_ubase_t len, struct rtgui_rect* rect);
+	void (*font_get_metrics)(struct rtgui_font* font, const char* text, struct rtgui_rect* rect);
+};
+
+/*
+ * bitmap font engine
+ */
 struct rtgui_font_bitmap
 struct rtgui_font_bitmap
 {
 {
 	const rt_uint8_t*  bmp;			/* bitmap font data */
 	const rt_uint8_t*  bmp;			/* bitmap font data */
@@ -46,69 +46,69 @@ struct rtgui_font_bitmap
 
 
 	rt_uint8_t first_char;
 	rt_uint8_t first_char;
 	rt_uint8_t last_char;
 	rt_uint8_t last_char;
-};
-extern const struct rtgui_font_engine bmp_font_engine;
-
-#include <rtgui/tree.h>
-SPLAY_HEAD(cache_tree, hz_cache);
-struct hz_cache
-{
-    SPLAY_ENTRY(hz_cache) hz_node;
-
-    rt_uint16_t hz_id;
-};
-
-struct rtgui_hz_file_font
-{
-    struct cache_tree cache_root;
-    rt_uint16_t cache_size;
-
-    /* font size */
-    rt_uint16_t font_size;
-	rt_uint16_t font_data_size;
-
-    /* file descriptor */
-    int fd;
-
-    /* font file name */
-    const char* font_fn;
-};
-extern const struct rtgui_font_engine rtgui_hz_file_font_engine;
-
-struct rtgui_font
-{
-	/* font name */
-	char* family;
-
-	/* font height */
-	rt_uint16_t height;
-
-	/* refer count */
-	rt_uint32_t refer_count;
-
-	/* font engine */
-	const struct rtgui_font_engine* engine;
-
-	/* font private data */
-	void* data;
-
-	/* the font list */
-	rtgui_list_t list;
-};
-typedef struct rtgui_font rtgui_font_t;
-
-void rtgui_font_system_init(void);
-void rtgui_font_system_add_font(struct rtgui_font* font);
-void rtgui_font_system_remove_font(struct rtgui_font* font);
-struct rtgui_font* rtgui_font_default(void);
-void rtgui_font_set_defaut(struct rtgui_font* font);
-
-struct rtgui_font* rtgui_font_refer(const rt_uint8_t* family, rt_uint16_t height);
-void rtgui_font_derefer(struct rtgui_font* font);
-
-/* draw a text */
-void rtgui_font_draw(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect);
-int  rtgui_font_get_string_width(struct rtgui_font* font, const char* text);
-void rtgui_font_get_metrics(struct rtgui_font* font, const char* text, struct rtgui_rect* rect);
-
-#endif
+};
+extern const struct rtgui_font_engine bmp_font_engine;
+
+#include <rtgui/tree.h>
+SPLAY_HEAD(cache_tree, hz_cache);
+struct hz_cache
+{
+    SPLAY_ENTRY(hz_cache) hz_node;
+
+    rt_uint16_t hz_id;
+};
+
+struct rtgui_hz_file_font
+{
+    struct cache_tree cache_root;
+    rt_uint16_t cache_size;
+
+    /* font size */
+    rt_uint16_t font_size;
+	rt_uint16_t font_data_size;
+
+    /* file descriptor */
+    int fd;
+
+    /* font file name */
+    const char* font_fn;
+};
+extern const struct rtgui_font_engine rtgui_hz_file_font_engine;
+
+struct rtgui_font
+{
+	/* font name */
+	char* family;
+
+	/* font height */
+	rt_uint16_t height;
+
+	/* refer count */
+	rt_uint32_t refer_count;
+
+	/* font engine */
+	const struct rtgui_font_engine* engine;
+
+	/* font private data */
+	void* data;
+
+	/* the font list */
+	rtgui_list_t list;
+};
+typedef struct rtgui_font rtgui_font_t;
+
+void rtgui_font_system_init(void);
+void rtgui_font_system_add_font(struct rtgui_font* font);
+void rtgui_font_system_remove_font(struct rtgui_font* font);
+struct rtgui_font* rtgui_font_default(void);
+void rtgui_font_set_defaut(struct rtgui_font* font);
+
+struct rtgui_font* rtgui_font_refer(const rt_uint8_t* family, rt_uint16_t height);
+void rtgui_font_derefer(struct rtgui_font* font);
+
+/* draw a text */
+void rtgui_font_draw(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect);
+int  rtgui_font_get_string_width(struct rtgui_font* font, const char* text);
+void rtgui_font_get_metrics(struct rtgui_font* font, const char* text, struct rtgui_rect* rect);
+
+#endif

+ 10 - 10
components/rtgui/include/rtgui/font_freetype.h

@@ -1,10 +1,10 @@
-#ifndef __RTGUI_FONT_TTF_H__
-#define __RTGUI_FONT_TTF_H__
-
-#include <rtgui/dc.h>
-#include <rtgui/font.h>
-
-rtgui_font_t* rtgui_freetype_font_create(const char* filename, int bold, int italic, rt_size_t size);
-void rtgui_freetype_font_destroy(rtgui_font_t* font);
-
-#endif
+#ifndef __RTGUI_FONT_TTF_H__
+#define __RTGUI_FONT_TTF_H__
+
+#include <rtgui/dc.h>
+#include <rtgui/font.h>
+
+rtgui_font_t* rtgui_freetype_font_create(const char* filename, int bold, int italic, rt_size_t size);
+void rtgui_freetype_font_destroy(rtgui_font_t* font);
+
+#endif

+ 80 - 80
components/rtgui/include/rtgui/image.h

@@ -1,80 +1,80 @@
-/*
- * File      : image.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_IMAGE_H__
-#define __RTGUI_IMAGE_H__
-
-#include <rtgui/dc.h>
-#include <rtgui/filerw.h>
-#include <rtgui/region.h>
-
-struct rtgui_image;
-struct rtgui_image_engine
-{
-	const char* name;
-	struct rtgui_list_node list;
-
-	/* image engine function */
-	rt_bool_t (*image_check)(struct rtgui_filerw* file);
-
-	rt_bool_t (*image_load)(struct rtgui_image* image, struct rtgui_filerw* file, rt_bool_t load);
-	void (*image_unload)(struct rtgui_image* image);
-
-	void (*image_blit)(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect);
-};
-
-struct rtgui_image_palette
-{
-	rtgui_color_t* colors;
-	rt_uint32_t ncolors;
-};
-typedef struct rtgui_image_palette rtgui_image_palette_t;
-
-struct rtgui_image
-{
-	/* image metrics */
-	rt_uint16_t w, h;
-
-	/* image engine */
-	const struct rtgui_image_engine* engine;
-
-	/* image palette */
-	rtgui_image_palette_t* palette;
-
-	/* image private data */
-	void* data;
-};
-typedef struct rtgui_image rtgui_image_t;
-
-/* init rtgui image system */
-void rtgui_system_image_init(void);
-
-#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
-struct rtgui_image* rtgui_image_create_from_file(const char* type, const char* filename, rt_bool_t load);
-struct rtgui_image* rtgui_image_create(const char* filename, rt_bool_t load);
-#endif
-struct rtgui_image* rtgui_image_create_from_mem(const char* type, const rt_uint8_t* data, rt_size_t length, rt_bool_t load);
-void rtgui_image_destroy(struct rtgui_image* image);
-
-/* get image's rect */
-void rtgui_image_get_rect(struct rtgui_image* image, struct rtgui_rect* rect);
-
-/* register an image engine */
-void rtgui_image_register_engine(struct rtgui_image_engine* engine);
-
-/* blit an image on DC */
-void rtgui_image_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect);
-struct rtgui_image_palette* rtgui_image_palette_create(rt_uint32_t ncolors);
-
-#endif
-
+/*
+ * File      : image.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_IMAGE_H__
+#define __RTGUI_IMAGE_H__
+
+#include <rtgui/dc.h>
+#include <rtgui/filerw.h>
+#include <rtgui/region.h>
+
+struct rtgui_image;
+struct rtgui_image_engine
+{
+	const char* name;
+	struct rtgui_list_node list;
+
+	/* image engine function */
+	rt_bool_t (*image_check)(struct rtgui_filerw* file);
+
+	rt_bool_t (*image_load)(struct rtgui_image* image, struct rtgui_filerw* file, rt_bool_t load);
+	void (*image_unload)(struct rtgui_image* image);
+
+	void (*image_blit)(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect);
+};
+
+struct rtgui_image_palette
+{
+	rtgui_color_t* colors;
+	rt_uint32_t ncolors;
+};
+typedef struct rtgui_image_palette rtgui_image_palette_t;
+
+struct rtgui_image
+{
+	/* image metrics */
+	rt_uint16_t w, h;
+
+	/* image engine */
+	const struct rtgui_image_engine* engine;
+
+	/* image palette */
+	rtgui_image_palette_t* palette;
+
+	/* image private data */
+	void* data;
+};
+typedef struct rtgui_image rtgui_image_t;
+
+/* init rtgui image system */
+void rtgui_system_image_init(void);
+
+#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
+struct rtgui_image* rtgui_image_create_from_file(const char* type, const char* filename, rt_bool_t load);
+struct rtgui_image* rtgui_image_create(const char* filename, rt_bool_t load);
+#endif
+struct rtgui_image* rtgui_image_create_from_mem(const char* type, const rt_uint8_t* data, rt_size_t length, rt_bool_t load);
+void rtgui_image_destroy(struct rtgui_image* image);
+
+/* get image's rect */
+void rtgui_image_get_rect(struct rtgui_image* image, struct rtgui_rect* rect);
+
+/* register an image engine */
+void rtgui_image_register_engine(struct rtgui_image_engine* engine);
+
+/* blit an image on DC */
+void rtgui_image_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect);
+struct rtgui_image_palette* rtgui_image_palette_create(rt_uint32_t ncolors);
+
+#endif
+

+ 293 - 293
components/rtgui/include/rtgui/kbddef.h

@@ -1,293 +1,293 @@
-/*
- * File      : kbddef.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __KBD_DEF_H__
-#define __KBD_DEF_H__
-
-/* The keyboard key have been cleverly chosen to map to ASCII */
-typedef enum
-{
-	RTGUIK_UNKNOWN		= 0,
-	RTGUIK_FIRST		= 0,
-	RTGUIK_BACKSPACE	= 8,
-	RTGUIK_TAB			= 9,
-	RTGUIK_CLEAR		= 12,
-	RTGUIK_RETURN		= 13,
-	RTGUIK_PAUSE		= 19,
-	RTGUIK_ESCAPE		= 27,
-	RTGUIK_SPACE		= 32,
-	RTGUIK_EXCLAIM		= 33,
-	RTGUIK_QUOTEDBL		= 34,
-	RTGUIK_HASH			= 35,
-	RTGUIK_DOLLAR		= 36,
-	RTGUIK_AMPERSAND	= 38,
-	RTGUIK_QUOTE		= 39,
-	RTGUIK_LEFTPAREN	= 40,
-	RTGUIK_RIGHTPAREN	= 41,
-	RTGUIK_ASTERISK		= 42,
-	RTGUIK_PLUS			= 43,
-	RTGUIK_COMMA		= 44,
-	RTGUIK_MINUS		= 45,
-	RTGUIK_PERIOD		= 46,
-	RTGUIK_SLASH		= 47,
-	RTGUIK_0			= 48,
-	RTGUIK_1			= 49,
-	RTGUIK_2			= 50,
-	RTGUIK_3			= 51,
-	RTGUIK_4			= 52,
-	RTGUIK_5			= 53,
-	RTGUIK_6			= 54,
-	RTGUIK_7			= 55,
-	RTGUIK_8			= 56,
-	RTGUIK_9			= 57,
-	RTGUIK_COLON		= 58,
-	RTGUIK_SEMICOLON	= 59,
-	RTGUIK_LESS			= 60,
-	RTGUIK_EQUALS		= 61,
-	RTGUIK_GREATER		= 62,
-	RTGUIK_QUESTION		= 63,
-	RTGUIK_AT			= 64,
-
-	/*
-	   Skip uppercase letters
-	 */
-	RTGUIK_LEFTBRACKET	= 91,
-	RTGUIK_BACKSLASH	= 92,
-	RTGUIK_RIGHTBRACKET	= 93,
-	RTGUIK_CARET		= 94,
-	RTGUIK_UNDERSCORE	= 95,
-	RTGUIK_BACKQUOTE	= 96,
-	RTGUIK_a			= 97,
-	RTGUIK_b			= 98,
-	RTGUIK_c			= 99,
-	RTGUIK_d			= 100,
-	RTGUIK_e			= 101,
-	RTGUIK_f			= 102,
-	RTGUIK_g			= 103,
-	RTGUIK_h			= 104,
-	RTGUIK_i			= 105,
-	RTGUIK_j			= 106,
-	RTGUIK_k			= 107,
-	RTGUIK_l			= 108,
-	RTGUIK_m			= 109,
-	RTGUIK_n			= 110,
-	RTGUIK_o			= 111,
-	RTGUIK_p			= 112,
-	RTGUIK_q			= 113,
-	RTGUIK_r			= 114,
-	RTGUIK_s			= 115,
-	RTGUIK_t			= 116,
-	RTGUIK_u			= 117,
-	RTGUIK_v			= 118,
-	RTGUIK_w			= 119,
-	RTGUIK_x			= 120,
-	RTGUIK_y			= 121,
-	RTGUIK_z			= 122,
-	RTGUIK_DELETE		= 127,
-
-	/* International keyboard */
-	RTGUIK_WORLD_0		= 160,		/* 0xA0 */
-	RTGUIK_WORLD_1		= 161,
-	RTGUIK_WORLD_2		= 162,
-	RTGUIK_WORLD_3		= 163,
-	RTGUIK_WORLD_4		= 164,
-	RTGUIK_WORLD_5		= 165,
-	RTGUIK_WORLD_6		= 166,
-	RTGUIK_WORLD_7		= 167,
-	RTGUIK_WORLD_8		= 168,
-	RTGUIK_WORLD_9		= 169,
-	RTGUIK_WORLD_10		= 170,
-	RTGUIK_WORLD_11		= 171,
-	RTGUIK_WORLD_12		= 172,
-	RTGUIK_WORLD_13		= 173,
-	RTGUIK_WORLD_14		= 174,
-	RTGUIK_WORLD_15		= 175,
-	RTGUIK_WORLD_16		= 176,
-	RTGUIK_WORLD_17		= 177,
-	RTGUIK_WORLD_18		= 178,
-	RTGUIK_WORLD_19		= 179,
-	RTGUIK_WORLD_20		= 180,
-	RTGUIK_WORLD_21		= 181,
-	RTGUIK_WORLD_22		= 182,
-	RTGUIK_WORLD_23		= 183,
-	RTGUIK_WORLD_24		= 184,
-	RTGUIK_WORLD_25		= 185,
-	RTGUIK_WORLD_26		= 186,
-	RTGUIK_WORLD_27		= 187,
-	RTGUIK_WORLD_28		= 188,
-	RTGUIK_WORLD_29		= 189,
-	RTGUIK_WORLD_30		= 190,
-	RTGUIK_WORLD_31		= 191,
-	RTGUIK_WORLD_32		= 192,
-	RTGUIK_WORLD_33		= 193,
-	RTGUIK_WORLD_34		= 194,
-	RTGUIK_WORLD_35		= 195,
-	RTGUIK_WORLD_36		= 196,
-	RTGUIK_WORLD_37		= 197,
-	RTGUIK_WORLD_38		= 198,
-	RTGUIK_WORLD_39		= 199,
-	RTGUIK_WORLD_40		= 200,
-	RTGUIK_WORLD_41		= 201,
-	RTGUIK_WORLD_42		= 202,
-	RTGUIK_WORLD_43		= 203,
-	RTGUIK_WORLD_44		= 204,
-	RTGUIK_WORLD_45		= 205,
-	RTGUIK_WORLD_46		= 206,
-	RTGUIK_WORLD_47		= 207,
-	RTGUIK_WORLD_48		= 208,
-	RTGUIK_WORLD_49		= 209,
-	RTGUIK_WORLD_50		= 210,
-	RTGUIK_WORLD_51		= 211,
-	RTGUIK_WORLD_52		= 212,
-	RTGUIK_WORLD_53		= 213,
-	RTGUIK_WORLD_54		= 214,
-	RTGUIK_WORLD_55		= 215,
-	RTGUIK_WORLD_56		= 216,
-	RTGUIK_WORLD_57		= 217,
-	RTGUIK_WORLD_58		= 218,
-	RTGUIK_WORLD_59		= 219,
-	RTGUIK_WORLD_60		= 220,
-	RTGUIK_WORLD_61		= 221,
-	RTGUIK_WORLD_62		= 222,
-	RTGUIK_WORLD_63		= 223,
-	RTGUIK_WORLD_64		= 224,
-	RTGUIK_WORLD_65		= 225,
-	RTGUIK_WORLD_66		= 226,
-	RTGUIK_WORLD_67		= 227,
-	RTGUIK_WORLD_68		= 228,
-	RTGUIK_WORLD_69		= 229,
-	RTGUIK_WORLD_70		= 230,
-	RTGUIK_WORLD_71		= 231,
-	RTGUIK_WORLD_72		= 232,
-	RTGUIK_WORLD_73		= 233,
-	RTGUIK_WORLD_74		= 234,
-	RTGUIK_WORLD_75		= 235,
-	RTGUIK_WORLD_76		= 236,
-	RTGUIK_WORLD_77		= 237,
-	RTGUIK_WORLD_78		= 238,
-	RTGUIK_WORLD_79		= 239,
-	RTGUIK_WORLD_80		= 240,
-	RTGUIK_WORLD_81		= 241,
-	RTGUIK_WORLD_82		= 242,
-	RTGUIK_WORLD_83		= 243,
-	RTGUIK_WORLD_84		= 244,
-	RTGUIK_WORLD_85		= 245,
-	RTGUIK_WORLD_86		= 246,
-	RTGUIK_WORLD_87		= 247,
-	RTGUIK_WORLD_88		= 248,
-	RTGUIK_WORLD_89		= 249,
-	RTGUIK_WORLD_90		= 250,
-	RTGUIK_WORLD_91		= 251,
-	RTGUIK_WORLD_92		= 252,
-	RTGUIK_WORLD_93		= 253,
-	RTGUIK_WORLD_94		= 254,
-	RTGUIK_WORLD_95		= 255,		/* 0xFF */
-
-	/* Numeric keypad */
-	RTGUIK_KP0			= 256,
-	RTGUIK_KP1			= 257,
-	RTGUIK_KP2			= 258,
-	RTGUIK_KP3			= 259,
-	RTGUIK_KP4			= 260,
-	RTGUIK_KP5			= 261,
-	RTGUIK_KP6			= 262,
-	RTGUIK_KP7			= 263,
-	RTGUIK_KP8			= 264,
-	RTGUIK_KP9			= 265,
-	RTGUIK_KP_PERIOD	= 266,
-	RTGUIK_KP_DIVIDE	= 267,
-	RTGUIK_KP_MULTIPLY	= 268,
-	RTGUIK_KP_MINUS		= 269,
-	RTGUIK_KP_PLUS		= 270,
-	RTGUIK_KP_ENTER		= 271,
-	RTGUIK_KP_EQUALS	= 272,
-
-	/* Arrows + Home/End pad */
-	RTGUIK_UP			= 273,
-	RTGUIK_DOWN			= 274,
-	RTGUIK_RIGHT		= 275,
-	RTGUIK_LEFT			= 276,
-	RTGUIK_INSERT		= 277,
-	RTGUIK_HOME			= 278,
-	RTGUIK_END			= 279,
-	RTGUIK_PAGEUP		= 280,
-	RTGUIK_PAGEDOWN		= 281,
-
-	/* Function keys */
-	RTGUIK_F1			= 282,
-	RTGUIK_F2			= 283,
-	RTGUIK_F3			= 284,
-	RTGUIK_F4			= 285,
-	RTGUIK_F5			= 286,
-	RTGUIK_F6			= 287,
-	RTGUIK_F7			= 288,
-	RTGUIK_F8			= 289,
-	RTGUIK_F9			= 290,
-	RTGUIK_F10			= 291,
-	RTGUIK_F11			= 292,
-	RTGUIK_F12			= 293,
-	RTGUIK_F13			= 294,
-	RTGUIK_F14			= 295,
-	RTGUIK_F15			= 296,
-
-	/* Key state modifier keys */
-	RTGUIK_NUMLOCK		= 300,
-	RTGUIK_CAPSLOCK		= 301,
-	RTGUIK_SCROLLOCK	= 302,
-	RTGUIK_RSHIFT		= 303,
-	RTGUIK_LSHIFT		= 304,
-	RTGUIK_RCTRL		= 305,
-	RTGUIK_LCTRL		= 306,
-	RTGUIK_RALT			= 307,
-	RTGUIK_LALT			= 308,
-	RTGUIK_RMETA		= 309,
-	RTGUIK_LMETA		= 310,
-	RTGUIK_LSUPER		= 311,		/* Left "Windows" key */
-	RTGUIK_RSUPER		= 312,		/* Right "Windows" key */
-	RTGUIK_MODE			= 313,		/* "Alt Gr" key */
-	RTGUIK_COMPOSE		= 314,		/* Multi-key compose key */
-
-	/* Miscellaneous function keys */
-	RTGUIK_HELP			= 315,
-	RTGUIK_PRINT		= 316,
-	RTGUIK_SYSREQ		= 317,
-	RTGUIK_BREAK		= 318,
-	RTGUIK_MENU			= 319,
-	RTGUIK_POWER		= 320,		/* Power key */
-
-	RTGUIK_LAST
-} RTGUI_KBD_KEY;
-
-/* Enumeration of valid key mods (possibly OR'd together) */
-typedef enum {
-	RTGUI_KMOD_NONE		= 0x0000,
-	RTGUI_KMOD_LSHIFT	= 0x0001,
-	RTGUI_KMOD_RSHIFT	= 0x0002,
-	RTGUI_KMOD_LCTRL	= 0x0040,
-	RTGUI_KMOD_RCTRL	= 0x0080,
-	RTGUI_KMOD_LALT		= 0x0100,
-	RTGUI_KMOD_RALT		= 0x0200,
-	RTGUI_KMOD_LMETA	= 0x0400,
-	RTGUI_KMOD_RMETA	= 0x0800,
-	RTGUI_KMOD_NUM		= 0x1000,
-	RTGUI_KMOD_CAPS		= 0x2000,
-	RTGUI_KMOD_MODE		= 0x4000,
-	RTGUI_KMOD_RESERVED = 0x8000
-} RTGUI_KBD_MOD;
-
-typedef enum {
-	RTGUI_KEYDOWN,			/* Keys pressed */
-	RTGUI_KEYUP,			/* Keys released */
-} RTGUI_KBD_TYPE;
-
-#endif
+/*
+ * File      : kbddef.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __KBD_DEF_H__
+#define __KBD_DEF_H__
+
+/* The keyboard key have been cleverly chosen to map to ASCII */
+typedef enum
+{
+	RTGUIK_UNKNOWN		= 0,
+	RTGUIK_FIRST		= 0,
+	RTGUIK_BACKSPACE	= 8,
+	RTGUIK_TAB			= 9,
+	RTGUIK_CLEAR		= 12,
+	RTGUIK_RETURN		= 13,
+	RTGUIK_PAUSE		= 19,
+	RTGUIK_ESCAPE		= 27,
+	RTGUIK_SPACE		= 32,
+	RTGUIK_EXCLAIM		= 33,
+	RTGUIK_QUOTEDBL		= 34,
+	RTGUIK_HASH			= 35,
+	RTGUIK_DOLLAR		= 36,
+	RTGUIK_AMPERSAND	= 38,
+	RTGUIK_QUOTE		= 39,
+	RTGUIK_LEFTPAREN	= 40,
+	RTGUIK_RIGHTPAREN	= 41,
+	RTGUIK_ASTERISK		= 42,
+	RTGUIK_PLUS			= 43,
+	RTGUIK_COMMA		= 44,
+	RTGUIK_MINUS		= 45,
+	RTGUIK_PERIOD		= 46,
+	RTGUIK_SLASH		= 47,
+	RTGUIK_0			= 48,
+	RTGUIK_1			= 49,
+	RTGUIK_2			= 50,
+	RTGUIK_3			= 51,
+	RTGUIK_4			= 52,
+	RTGUIK_5			= 53,
+	RTGUIK_6			= 54,
+	RTGUIK_7			= 55,
+	RTGUIK_8			= 56,
+	RTGUIK_9			= 57,
+	RTGUIK_COLON		= 58,
+	RTGUIK_SEMICOLON	= 59,
+	RTGUIK_LESS			= 60,
+	RTGUIK_EQUALS		= 61,
+	RTGUIK_GREATER		= 62,
+	RTGUIK_QUESTION		= 63,
+	RTGUIK_AT			= 64,
+
+	/*
+	   Skip uppercase letters
+	 */
+	RTGUIK_LEFTBRACKET	= 91,
+	RTGUIK_BACKSLASH	= 92,
+	RTGUIK_RIGHTBRACKET	= 93,
+	RTGUIK_CARET		= 94,
+	RTGUIK_UNDERSCORE	= 95,
+	RTGUIK_BACKQUOTE	= 96,
+	RTGUIK_a			= 97,
+	RTGUIK_b			= 98,
+	RTGUIK_c			= 99,
+	RTGUIK_d			= 100,
+	RTGUIK_e			= 101,
+	RTGUIK_f			= 102,
+	RTGUIK_g			= 103,
+	RTGUIK_h			= 104,
+	RTGUIK_i			= 105,
+	RTGUIK_j			= 106,
+	RTGUIK_k			= 107,
+	RTGUIK_l			= 108,
+	RTGUIK_m			= 109,
+	RTGUIK_n			= 110,
+	RTGUIK_o			= 111,
+	RTGUIK_p			= 112,
+	RTGUIK_q			= 113,
+	RTGUIK_r			= 114,
+	RTGUIK_s			= 115,
+	RTGUIK_t			= 116,
+	RTGUIK_u			= 117,
+	RTGUIK_v			= 118,
+	RTGUIK_w			= 119,
+	RTGUIK_x			= 120,
+	RTGUIK_y			= 121,
+	RTGUIK_z			= 122,
+	RTGUIK_DELETE		= 127,
+
+	/* International keyboard */
+	RTGUIK_WORLD_0		= 160,		/* 0xA0 */
+	RTGUIK_WORLD_1		= 161,
+	RTGUIK_WORLD_2		= 162,
+	RTGUIK_WORLD_3		= 163,
+	RTGUIK_WORLD_4		= 164,
+	RTGUIK_WORLD_5		= 165,
+	RTGUIK_WORLD_6		= 166,
+	RTGUIK_WORLD_7		= 167,
+	RTGUIK_WORLD_8		= 168,
+	RTGUIK_WORLD_9		= 169,
+	RTGUIK_WORLD_10		= 170,
+	RTGUIK_WORLD_11		= 171,
+	RTGUIK_WORLD_12		= 172,
+	RTGUIK_WORLD_13		= 173,
+	RTGUIK_WORLD_14		= 174,
+	RTGUIK_WORLD_15		= 175,
+	RTGUIK_WORLD_16		= 176,
+	RTGUIK_WORLD_17		= 177,
+	RTGUIK_WORLD_18		= 178,
+	RTGUIK_WORLD_19		= 179,
+	RTGUIK_WORLD_20		= 180,
+	RTGUIK_WORLD_21		= 181,
+	RTGUIK_WORLD_22		= 182,
+	RTGUIK_WORLD_23		= 183,
+	RTGUIK_WORLD_24		= 184,
+	RTGUIK_WORLD_25		= 185,
+	RTGUIK_WORLD_26		= 186,
+	RTGUIK_WORLD_27		= 187,
+	RTGUIK_WORLD_28		= 188,
+	RTGUIK_WORLD_29		= 189,
+	RTGUIK_WORLD_30		= 190,
+	RTGUIK_WORLD_31		= 191,
+	RTGUIK_WORLD_32		= 192,
+	RTGUIK_WORLD_33		= 193,
+	RTGUIK_WORLD_34		= 194,
+	RTGUIK_WORLD_35		= 195,
+	RTGUIK_WORLD_36		= 196,
+	RTGUIK_WORLD_37		= 197,
+	RTGUIK_WORLD_38		= 198,
+	RTGUIK_WORLD_39		= 199,
+	RTGUIK_WORLD_40		= 200,
+	RTGUIK_WORLD_41		= 201,
+	RTGUIK_WORLD_42		= 202,
+	RTGUIK_WORLD_43		= 203,
+	RTGUIK_WORLD_44		= 204,
+	RTGUIK_WORLD_45		= 205,
+	RTGUIK_WORLD_46		= 206,
+	RTGUIK_WORLD_47		= 207,
+	RTGUIK_WORLD_48		= 208,
+	RTGUIK_WORLD_49		= 209,
+	RTGUIK_WORLD_50		= 210,
+	RTGUIK_WORLD_51		= 211,
+	RTGUIK_WORLD_52		= 212,
+	RTGUIK_WORLD_53		= 213,
+	RTGUIK_WORLD_54		= 214,
+	RTGUIK_WORLD_55		= 215,
+	RTGUIK_WORLD_56		= 216,
+	RTGUIK_WORLD_57		= 217,
+	RTGUIK_WORLD_58		= 218,
+	RTGUIK_WORLD_59		= 219,
+	RTGUIK_WORLD_60		= 220,
+	RTGUIK_WORLD_61		= 221,
+	RTGUIK_WORLD_62		= 222,
+	RTGUIK_WORLD_63		= 223,
+	RTGUIK_WORLD_64		= 224,
+	RTGUIK_WORLD_65		= 225,
+	RTGUIK_WORLD_66		= 226,
+	RTGUIK_WORLD_67		= 227,
+	RTGUIK_WORLD_68		= 228,
+	RTGUIK_WORLD_69		= 229,
+	RTGUIK_WORLD_70		= 230,
+	RTGUIK_WORLD_71		= 231,
+	RTGUIK_WORLD_72		= 232,
+	RTGUIK_WORLD_73		= 233,
+	RTGUIK_WORLD_74		= 234,
+	RTGUIK_WORLD_75		= 235,
+	RTGUIK_WORLD_76		= 236,
+	RTGUIK_WORLD_77		= 237,
+	RTGUIK_WORLD_78		= 238,
+	RTGUIK_WORLD_79		= 239,
+	RTGUIK_WORLD_80		= 240,
+	RTGUIK_WORLD_81		= 241,
+	RTGUIK_WORLD_82		= 242,
+	RTGUIK_WORLD_83		= 243,
+	RTGUIK_WORLD_84		= 244,
+	RTGUIK_WORLD_85		= 245,
+	RTGUIK_WORLD_86		= 246,
+	RTGUIK_WORLD_87		= 247,
+	RTGUIK_WORLD_88		= 248,
+	RTGUIK_WORLD_89		= 249,
+	RTGUIK_WORLD_90		= 250,
+	RTGUIK_WORLD_91		= 251,
+	RTGUIK_WORLD_92		= 252,
+	RTGUIK_WORLD_93		= 253,
+	RTGUIK_WORLD_94		= 254,
+	RTGUIK_WORLD_95		= 255,		/* 0xFF */
+
+	/* Numeric keypad */
+	RTGUIK_KP0			= 256,
+	RTGUIK_KP1			= 257,
+	RTGUIK_KP2			= 258,
+	RTGUIK_KP3			= 259,
+	RTGUIK_KP4			= 260,
+	RTGUIK_KP5			= 261,
+	RTGUIK_KP6			= 262,
+	RTGUIK_KP7			= 263,
+	RTGUIK_KP8			= 264,
+	RTGUIK_KP9			= 265,
+	RTGUIK_KP_PERIOD	= 266,
+	RTGUIK_KP_DIVIDE	= 267,
+	RTGUIK_KP_MULTIPLY	= 268,
+	RTGUIK_KP_MINUS		= 269,
+	RTGUIK_KP_PLUS		= 270,
+	RTGUIK_KP_ENTER		= 271,
+	RTGUIK_KP_EQUALS	= 272,
+
+	/* Arrows + Home/End pad */
+	RTGUIK_UP			= 273,
+	RTGUIK_DOWN			= 274,
+	RTGUIK_RIGHT		= 275,
+	RTGUIK_LEFT			= 276,
+	RTGUIK_INSERT		= 277,
+	RTGUIK_HOME			= 278,
+	RTGUIK_END			= 279,
+	RTGUIK_PAGEUP		= 280,
+	RTGUIK_PAGEDOWN		= 281,
+
+	/* Function keys */
+	RTGUIK_F1			= 282,
+	RTGUIK_F2			= 283,
+	RTGUIK_F3			= 284,
+	RTGUIK_F4			= 285,
+	RTGUIK_F5			= 286,
+	RTGUIK_F6			= 287,
+	RTGUIK_F7			= 288,
+	RTGUIK_F8			= 289,
+	RTGUIK_F9			= 290,
+	RTGUIK_F10			= 291,
+	RTGUIK_F11			= 292,
+	RTGUIK_F12			= 293,
+	RTGUIK_F13			= 294,
+	RTGUIK_F14			= 295,
+	RTGUIK_F15			= 296,
+
+	/* Key state modifier keys */
+	RTGUIK_NUMLOCK		= 300,
+	RTGUIK_CAPSLOCK		= 301,
+	RTGUIK_SCROLLOCK	= 302,
+	RTGUIK_RSHIFT		= 303,
+	RTGUIK_LSHIFT		= 304,
+	RTGUIK_RCTRL		= 305,
+	RTGUIK_LCTRL		= 306,
+	RTGUIK_RALT			= 307,
+	RTGUIK_LALT			= 308,
+	RTGUIK_RMETA		= 309,
+	RTGUIK_LMETA		= 310,
+	RTGUIK_LSUPER		= 311,		/* Left "Windows" key */
+	RTGUIK_RSUPER		= 312,		/* Right "Windows" key */
+	RTGUIK_MODE			= 313,		/* "Alt Gr" key */
+	RTGUIK_COMPOSE		= 314,		/* Multi-key compose key */
+
+	/* Miscellaneous function keys */
+	RTGUIK_HELP			= 315,
+	RTGUIK_PRINT		= 316,
+	RTGUIK_SYSREQ		= 317,
+	RTGUIK_BREAK		= 318,
+	RTGUIK_MENU			= 319,
+	RTGUIK_POWER		= 320,		/* Power key */
+
+	RTGUIK_LAST
+} RTGUI_KBD_KEY;
+
+/* Enumeration of valid key mods (possibly OR'd together) */
+typedef enum {
+	RTGUI_KMOD_NONE		= 0x0000,
+	RTGUI_KMOD_LSHIFT	= 0x0001,
+	RTGUI_KMOD_RSHIFT	= 0x0002,
+	RTGUI_KMOD_LCTRL	= 0x0040,
+	RTGUI_KMOD_RCTRL	= 0x0080,
+	RTGUI_KMOD_LALT		= 0x0100,
+	RTGUI_KMOD_RALT		= 0x0200,
+	RTGUI_KMOD_LMETA	= 0x0400,
+	RTGUI_KMOD_RMETA	= 0x0800,
+	RTGUI_KMOD_NUM		= 0x1000,
+	RTGUI_KMOD_CAPS		= 0x2000,
+	RTGUI_KMOD_MODE		= 0x4000,
+	RTGUI_KMOD_RESERVED = 0x8000
+} RTGUI_KBD_MOD;
+
+typedef enum {
+	RTGUI_KEYDOWN,			/* Keys pressed */
+	RTGUI_KEYUP,			/* Keys released */
+} RTGUI_KBD_TYPE;
+
+#endif

+ 66 - 66
components/rtgui/include/rtgui/list.h

@@ -1,66 +1,66 @@
-/*
- * File      : list.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_LIST_H__
-#define __RTGUI_LIST_H__
-
-#include <rtgui/rtgui.h>
-
-struct rtgui_list_node
-{
-	struct rtgui_list_node* next;
-};
-typedef struct rtgui_list_node rtgui_list_t;
-
-rt_inline void rtgui_list_init(rtgui_list_t *l)
-{
-	l->next = (struct rtgui_list_node *)0;
-}
-
-rt_inline void rtgui_list_append(rtgui_list_t *l, rtgui_list_t *n)
-{
-	struct rtgui_list_node* node;
-
-	node = l;
-	while (node->next) node = node->next;
-
-	/* append the node to the tail */
-	node->next = n;
-	n->next = (struct rtgui_list_node*) 0;
-}
-
-rt_inline void rtgui_list_insert(rtgui_list_t *l, rtgui_list_t *n)
-{
-	n->next = l->next;
-	l->next = n;
-}
-
-rt_inline rtgui_list_t* rtgui_list_remove(rtgui_list_t *l, rtgui_list_t *n)
-{
-	/* remove slist head */
-	struct rtgui_list_node* node = l;
-	while (node->next && node->next != n) node = node->next;
-
-	/* remove node */
-	if (node->next != (rtgui_list_t *)0) node->next = node->next->next;
-
-	return l;
-}
-
-#define rtgui_list_entry(node, type, member)	\
-	((type *)((char*)(node)-(unsigned long)(&((type *)0)->member)))
-
-#define rtgui_list_foreach(node, list)	\
-	for ((node) = (list)->next; (node) != RT_NULL; (node) = (node)->next)
-
-#endif
+/*
+ * File      : list.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_LIST_H__
+#define __RTGUI_LIST_H__
+
+#include <rtgui/rtgui.h>
+
+struct rtgui_list_node
+{
+	struct rtgui_list_node* next;
+};
+typedef struct rtgui_list_node rtgui_list_t;
+
+rt_inline void rtgui_list_init(rtgui_list_t *l)
+{
+	l->next = (struct rtgui_list_node *)0;
+}
+
+rt_inline void rtgui_list_append(rtgui_list_t *l, rtgui_list_t *n)
+{
+	struct rtgui_list_node* node;
+
+	node = l;
+	while (node->next) node = node->next;
+
+	/* append the node to the tail */
+	node->next = n;
+	n->next = (struct rtgui_list_node*) 0;
+}
+
+rt_inline void rtgui_list_insert(rtgui_list_t *l, rtgui_list_t *n)
+{
+	n->next = l->next;
+	l->next = n;
+}
+
+rt_inline rtgui_list_t* rtgui_list_remove(rtgui_list_t *l, rtgui_list_t *n)
+{
+	/* remove slist head */
+	struct rtgui_list_node* node = l;
+	while (node->next && node->next != n) node = node->next;
+
+	/* remove node */
+	if (node->next != (rtgui_list_t *)0) node->next = node->next->next;
+
+	return l;
+}
+
+#define rtgui_list_entry(node, type, member)	\
+	((type *)((char*)(node)-(unsigned long)(&((type *)0)->member)))
+
+#define rtgui_list_foreach(node, list)	\
+	for ((node) = (list)->next; (node) != RT_NULL; (node) = (node)->next)
+
+#endif

+ 2 - 3
components/rtgui/include/rtgui/rtgui.h

@@ -21,17 +21,16 @@
 #define RT_INT16_MIN		(-RT_INT16_MAX-1)
 #define RT_INT16_MIN		(-RT_INT16_MAX-1)
 #define RTGUI_NOT_FOUND		(-1)
 #define RTGUI_NOT_FOUND		(-1)
 
 
-struct rtgui_panel;
 struct rtgui_event;
 struct rtgui_event;
 
 
+struct rtgui_object;
 struct rtgui_widget;
 struct rtgui_widget;
 struct rtgui_win;
 struct rtgui_win;
 struct rtgui_font;
 struct rtgui_font;
 
 
-typedef struct rtgui_panel rtgui_panel_t;
 typedef struct rtgui_win rtgui_win_t;
 typedef struct rtgui_win rtgui_win_t;
 typedef struct rtgui_workbench rtgui_workbench_t;
 typedef struct rtgui_workbench rtgui_workbench_t;
-typedef rt_bool_t (*rtgui_event_handler_ptr)(struct rtgui_widget* widget, struct rtgui_event* event);
+typedef rt_bool_t (*rtgui_event_handler_ptr)(struct rtgui_object* widget, struct rtgui_event* event);
 typedef void (*rtgui_onbutton_func_t)(struct rtgui_widget* widget, struct rtgui_event* event);
 typedef void (*rtgui_onbutton_func_t)(struct rtgui_widget* widget, struct rtgui_event* event);
 
 
 struct rtgui_point
 struct rtgui_point

+ 99 - 0
components/rtgui/include/rtgui/rtgui_application.h

@@ -0,0 +1,99 @@
+/*
+ * File      : rtgui_application.h
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-01-13     Grissiom     first version
+ */
+#ifndef __RTGUI_APPLICATION_H__
+#define __RTGUI_APPLICATION_H__
+
+#include <rtthread.h>
+#include <rtgui/rtgui.h>
+#include <rtgui/event.h>
+#include <rtgui/rtgui_system.h>
+
+DECLARE_CLASS_TYPE(application);
+
+/** Gets the type of a application */
+#define RTGUI_APPLICATION_TYPE       (RTGUI_TYPE(application))
+/** Casts the object to an rtgui_workbench */
+#define RTGUI_APPLICATION(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_APPLICATION_TYPE, struct rtgui_application))
+/** Checks if the object is an rtgui_workbench */
+#define RTGUI_IS_APPLICATION(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_APPLICATION_TYPE))
+
+enum rtgui_application_flag
+{
+	RTGUI_APPLICATION_FLAG_EXITED  = 0x04,
+	RTGUI_APPLICATION_FLAG_SHOWN   = 0x08
+};
+
+typedef void (*rtgui_idle_func)(struct rtgui_object* obj, struct rtgui_event *event);
+
+struct rtgui_application
+{
+	struct rtgui_object parent;
+
+	/* application name */
+	unsigned char *name;
+
+	enum rtgui_application_flag state_flag;
+
+	rt_uint16_t ref_count;
+	rt_uint16_t exit_code;
+
+	/* the thread id */
+	rt_thread_t tid;
+    rt_thread_t server;
+
+	/* the message queue of thread */
+	rt_mq_t mq;
+	/* event buffer */
+	rt_uint8_t event_buffer[sizeof(union rtgui_event_generic)];
+
+	/* if not RT_NULL, the application is modaled by modal_object. If is
+	 * RT_NULL, nothing modals. */
+	struct rtgui_object *modal_object;
+
+	/* on idle event handler */
+	rtgui_idle_func on_idle;
+};
+
+/**
+ * create an application named @myname on thread @param tid
+ */
+struct rtgui_application* rtgui_application_create(
+        rt_thread_t tid,
+        const char *myname);
+void rtgui_application_destroy(struct rtgui_application *app);
+rt_err_t rtgui_application_show(struct rtgui_application *app);
+rt_err_t rtgui_application_hide(struct rtgui_application *app);
+
+rt_base_t rtgui_application_run(struct rtgui_application *app);
+void rtgui_application_exit(struct rtgui_application *app, rt_uint16_t code);
+
+void rtgui_application_set_onidle(rtgui_idle_func onidle);
+rtgui_idle_func rtgui_application_get_onidle(void);
+struct rtgui_application* rtgui_application_self(void);
+
+rt_thread_t rtgui_application_get_server(void);
+
+void rtgui_application_set_root_object(struct rtgui_object* object);
+struct rtgui_object* rtgui_application_get_root_object(void);
+
+struct rtgui_event;
+rt_err_t rtgui_application_send(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
+rt_err_t rtgui_application_send_urgent(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
+rt_err_t rtgui_application_send_sync(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
+rt_err_t rtgui_application_ack(struct rtgui_event* event, rt_int32_t status);
+rt_err_t rtgui_application_recv(struct rtgui_event* event, rt_size_t event_size);
+rt_err_t rtgui_application_recv_nosuspend(struct rtgui_event* event, rt_size_t event_size);
+rt_err_t rtgui_application_recv_filter(rt_uint32_t type, struct rtgui_event* event, rt_size_t event_size);
+
+#endif /* end of include guard: RTGUI_APPLICATION_H */

+ 81 - 75
components/rtgui/include/rtgui/rtgui_config.h

@@ -1,75 +1,81 @@
-/*
- * File      : rtgui_config.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- * 2010-02-08     Bernard      move some RTGUI options to bsp
- */
-
-#ifndef __RTGUI_CONFIG_H__
-#define __RTGUI_CONFIG_H__
-
-/* RTGUI options */
-
-#ifdef _WIN32
-	/* name length of RTGUI object */
-	#define RTGUI_NAME_MAX		12
-	/* support 16 weight font */
-	#define RTGUI_USING_FONT16
-	/* support Chinese font */
-	#define RTGUI_USING_FONTHZ
-	/* support FreeType TTF font */
-	// #define RTGUI_USING_TTF
-	/* use small size in RTGUI */
-	#define RTGUI_USING_SMALL_SIZE
-	/* use mouse cursor */
-	/* #define RTGUI_USING_MOUSE_CURSOR */
-	/* default font size in RTGUI */
-	#define RTGUI_DEFAULT_FONT_SIZE	12
-
-	#define RTGUI_USING_STDIO_FILERW
-	#define RTGUI_IMAGE_CONTAINER
-	#define RTGUI_IMAGE_XPM
-	#define RTGUI_IMAGE_BMP
-	#define RTGUI_IMAGE_PNG
-	#define RTGUI_IMAGE_JPEG
-	#define RTGUI_USING_FONT12
-	#define RTGUI_USING_HZ_BMP
-	#define RTGUI_MEM_TRACE
-	#define RTGUI_USING_WINMOVE
-#else
-	/* native running under RT-Thread */
-	#ifndef RT_USING_DFS
-		#undef RTGUI_USING_DFS_FILERW
-		#undef RTGUI_USING_HZ_FILE
-	#endif
-#endif
-
-#if RTGUI_DEFAULT_FONT_SIZE == 0
-#define RTGUI_DEFAULT_FONT_SIZE 12
-#endif
-
-#define RTGUI_SVR_THREAD_PRIORITY		15
-#define RTGUI_SVR_THREAD_TIMESLICE		5
-#ifdef RTGUI_USING_SMALL_SIZE
-#define RTGUI_SVR_THREAD_STACK_SIZE		1024
-#else
-#define RTGUI_SVR_THREAD_STACK_SIZE		2048
-#endif
-
-#define RTGUI_APP_THREAD_PRIORITY		25
-#define RTGUI_APP_THREAD_TIMESLICE		5
-#ifdef RTGUI_USING_SMALL_SIZE
-#define RTGUI_APP_THREAD_STACK_SIZE		1024
-#else
-#define RTGUI_APP_THREAD_STACK_SIZE		2048
-#endif
-
-#endif
+/*
+ * File      : rtgui_config.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ * 2010-02-08     Bernard      move some RTGUI options to bsp
+ */
+
+#ifndef __RTGUI_CONFIG_H__
+#define __RTGUI_CONFIG_H__
+
+/* RTGUI options */
+
+#ifdef _WIN32
+	/* name length of RTGUI object */
+	#define RTGUI_NAME_MAX		12
+	/* support 16 weight font */
+	#define RTGUI_USING_FONT16
+	/* support Chinese font */
+	#define RTGUI_USING_FONTHZ
+	/* support FreeType TTF font */
+	//#define RTGUI_USING_TTF
+	/* use small size in RTGUI */
+	#define RTGUI_USING_SMALL_SIZE
+	/* use mouse cursor */
+	/* #define RTGUI_USING_MOUSE_CURSOR */
+	/* default font size in RTGUI */
+	#define RTGUI_DEFAULT_FONT_SIZE	12
+
+	#define RTGUI_USING_STDIO_FILERW
+	#define RTGUI_IMAGE_CONTAINER
+	#define RTGUI_IMAGE_XPM
+	#define RTGUI_IMAGE_BMP
+	#define RTGUI_IMAGE_PNG
+	#define RTGUI_IMAGE_JPEG
+	#define RTGUI_USING_FONT12
+	#define RTGUI_USING_HZ_BMP
+	#define RTGUI_MEM_TRACE
+	#define RTGUI_USING_WINMOVE
+#else
+	/* native running under RT-Thread */
+	#ifndef RT_USING_DFS
+		#undef RTGUI_USING_DFS_FILERW
+		#undef RTGUI_USING_HZ_FILE
+	#endif
+#endif
+
+#if RTGUI_DEFAULT_FONT_SIZE == 0
+#define RTGUI_DEFAULT_FONT_SIZE 12
+#endif
+
+#define RTGUI_SVR_THREAD_PRIORITY		15
+#define RTGUI_SVR_THREAD_TIMESLICE		5
+#ifdef RTGUI_USING_SMALL_SIZE
+#define RTGUI_SVR_THREAD_STACK_SIZE		1024
+#else
+#define RTGUI_SVR_THREAD_STACK_SIZE		2048
+#endif
+
+#define RTGUI_APP_THREAD_PRIORITY		25
+#define RTGUI_APP_THREAD_TIMESLICE		5
+#ifdef RTGUI_USING_SMALL_SIZE
+#define RTGUI_APP_THREAD_STACK_SIZE		1024
+#else
+#define RTGUI_APP_THREAD_STACK_SIZE		2048
+#endif
+
+#define RTGUI_USING_CAST_CHECK
+
+//#define RTGUI_USING_DESKTOP_WINDOW
+
+#define  RTGUI_EVENT_DEBUG
+
+#endif

+ 28 - 5
components/rtgui/include/rtgui/rtgui_object.h

@@ -16,6 +16,7 @@
 
 
 
 
 #include <rtthread.h>
 #include <rtthread.h>
+#include <rtgui/rtgui.h>
 
 
 #ifdef __cplusplus
 #ifdef __cplusplus
 extern "C" {
 extern "C" {
@@ -85,25 +86,47 @@ DECLARE_CLASS_TYPE(type);
 /** Gets the type of an object */
 /** Gets the type of an object */
 #define RTGUI_OBJECT_TYPE       RTGUI_TYPE(type)
 #define RTGUI_OBJECT_TYPE       RTGUI_TYPE(type)
 /** Casts the object to an rtgui_object_t */
 /** Casts the object to an rtgui_object_t */
-#define RTGUI_OBJECT(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_OBJECT_TYPE, rtgui_object_t))
+#define RTGUI_OBJECT(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_OBJECT_TYPE, struct rtgui_object))
 /** Checks if the object is an rtgui_Object */
 /** Checks if the object is an rtgui_Object */
 #define RTGUI_IS_OBJECT(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_OBJECT_TYPE))
 #define RTGUI_IS_OBJECT(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_OBJECT_TYPE))
 
 
+enum rtgui_object_flag
+{
+    RTGUI_OBJECT_FLAG_NONE     = 0x00,
+    RTGUI_OBJECT_FLAG_STATIC   = 0x01,
+    RTGUI_OBJECT_FLAG_DISABLED = 0x02
+};
+
 /* rtgui base object */
 /* rtgui base object */
 struct rtgui_object
 struct rtgui_object
 {
 {
 	/* object type */
 	/* object type */
 	const rtgui_type_t* type;
 	const rtgui_type_t* type;
 
 
-	rt_bool_t is_static;
+	/* the event handler */
+	rtgui_event_handler_ptr event_handler;
+
+	enum rtgui_object_flag flag;
 };
 };
-rtgui_type_t *rtgui_object_type_get(void);
 
 
 rtgui_object_t *rtgui_object_create(rtgui_type_t *object_type);
 rtgui_object_t *rtgui_object_create(rtgui_type_t *object_type);
 void         rtgui_object_destroy(rtgui_object_t *object);
 void         rtgui_object_destroy(rtgui_object_t *object);
 
 
-void         rtgui_object_name_set(rtgui_object_t *object, const char *name);
-const char   *rtgui_object_name_get(rtgui_object_t *object);
+/* set the event handler of object */
+void rtgui_object_set_event_handler(struct rtgui_object *object, rtgui_event_handler_ptr handler);
+/* object default event handler */
+rt_bool_t rtgui_object_event_handler(struct rtgui_object *object, struct rtgui_event* event);
+/* helper micro. widget event handlers could use this. */
+#define RTGUI_WIDGET_EVENT_HANDLER_PREPARE \
+	struct rtgui_widget *widget;  \
+	RT_ASSERT(object != RT_NULL); \
+	RT_ASSERT(event != RT_NULL);  \
+	widget = RTGUI_WIDGET(object); \
+	/* supress compiler warning */ \
+	widget = widget;
+
+void       rtgui_object_name_set(rtgui_object_t *object, const char *name);
+const char *rtgui_object_name_get(rtgui_object_t *object);
 
 
 rtgui_object_t *rtgui_object_check_cast(rtgui_object_t *object, rtgui_type_t *type);
 rtgui_object_t *rtgui_object_check_cast(rtgui_object_t *object, rtgui_type_t *type);
 rtgui_type_t   *rtk_object_object_type_get(rtgui_object_t *object);
 rtgui_type_t   *rtk_object_object_type_get(rtgui_object_t *object);

+ 84 - 79
components/rtgui/include/rtgui/rtgui_server.h

@@ -1,79 +1,84 @@
-/*
- * File      : rtgui_server.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-04     Bernard      first version
- */
-#ifndef __RTGUI_SERVER_H__
-#define __RTGUI_SERVER_H__
-
-#include <rtgui/list.h>
-
-/* RTGUI server definitions */
-
-/* top window definitions in server */
-enum
-{
-	WINTITLE_NO			= 0x01,
-	WINTITLE_BORDER		= 0x02,
-	WINTITLE_ACTIVATE	= 0x04,
-	WINTITLE_CLOSEBOX	= 0x08,
-	WINTITLE_MOVE		= 0x0C,
-	WINTITLE_CB_PRESSED	= 0x10,
-	WINTITLE_NOFOCUS	= 0x20
-};
-
-#define WINTITLE_HEIGHT			20
-#define WINTITLE_CB_WIDTH		16
-#define WINTITLE_CB_HEIGHT		16
-#define WINTITLE_BORDER_SIZE	2
-
-struct rtgui_topwin
-{
-	/* the window flag */
-	rt_uint32_t flag;
-	/* event mask */
-	rt_uint32_t mask;
-
-	struct rtgui_wintitle* title;
-
-	/* the window id */
-	struct rtgui_win* wid;
-
-	/* the thread id */
-	rt_thread_t tid;
-
-	/* the extent information */
-	rtgui_rect_t extent;
-
-	/* the top window list */
-	rtgui_list_t list;
-
-	/* the monitor rect list */
-	rtgui_list_t monitor_list;
-};
-typedef struct rtgui_topwin rtgui_topwin_t;
-
-/* top win manager init */
-void rtgui_topwin_init(void);
-void rtgui_server_init(void);
-
-/* post an event to server */
-void rtgui_server_post_event(struct rtgui_event* event, rt_size_t size);
-
-/* register or deregister panel in server */
-void rtgui_panel_register(char* name, rtgui_rect_t* extent);
-void rtgui_panel_deregister(char* name);
-
-void rtgui_panel_set_default_focused(char* name);
-void rtgui_panel_set_nofocused(char* name);
-
-#endif
-
+/*
+ * File      : rtgui_server.h
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-04     Bernard      first version
+ */
+#ifndef __RTGUI_SERVER_H__
+#define __RTGUI_SERVER_H__
+
+#include <rtgui/list.h>
+#include <rtgui/dlist.h>
+
+/* RTGUI server definitions */
+
+/* top window definitions in server */
+enum
+{
+	WINTITLE_NO         =  0x01,
+	WINTITLE_BORDER     =  0x02,
+	WINTITLE_ACTIVATE   =  0x04,
+	WINTITLE_CLOSEBOX   =  0x08,
+	WINTITLE_MOVE       =  0x0C,
+	WINTITLE_CB_PRESSED =  0x10,
+	WINTITLE_NOFOCUS    =  0x20,
+	/* window is hidden by default */
+	WINTITLE_SHOWN      =  0x40,
+	/* window is modaled by other window */
+	WINTITLE_MODALED    =  0x80,
+	/* window is modaling other window */
+	WINTITLE_MODALING   = 0x100
+};
+
+#define WINTITLE_HEIGHT         20
+#define WINTITLE_CB_WIDTH       16
+#define WINTITLE_CB_HEIGHT      16
+#define WINTITLE_BORDER_SIZE    2
+
+struct rtgui_topwin
+{
+	/* the window flag */
+	rt_uint32_t flag;
+	/* event mask */
+	rt_uint32_t mask;
+
+	struct rtgui_wintitle* title;
+
+	/* the window id */
+	struct rtgui_win* wid;
+
+	/* the thread id */
+	rt_thread_t tid;
+
+	/* the extent information */
+	rtgui_rect_t extent;
+
+	struct rtgui_topwin *parent;
+
+	/* we need to iterate the topwin list with usual order(get target window)
+	 * or reversely(painting). So it's better to use a double linked list */
+	struct rtgui_dlist_node list;
+	struct rtgui_dlist_node child_list;
+
+	/* the monitor rect list */
+	rtgui_list_t monitor_list;
+};
+typedef struct rtgui_topwin rtgui_topwin_t;
+
+/* top win manager init */
+void rtgui_topwin_init(void);
+void rtgui_server_init(void);
+
+/* post an event to server */
+void rtgui_server_post_event(struct rtgui_event* event, rt_size_t size);
+rt_err_t rtgui_server_post_event_sync(struct rtgui_event* event, rt_size_t size);
+
+#endif
+

+ 57 - 100
components/rtgui/include/rtgui/rtgui_system.h

@@ -1,100 +1,57 @@
-/*
- * File      : rtgui_system.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-04     Bernard      first version
- */
-#ifndef __RTGUI_SYSTEM_H__
-#define __RTGUI_SYSTEM_H__
-
-#include <rtthread.h>
-#include <rtgui/rtgui.h>
-
-struct rtgui_dc;
-struct rtgui_event;
-struct rtgui_widget;
-
-#ifdef RTGUI_USING_SMALL_SIZE
-#define RTGUI_EVENT_BUFFER_SIZE	64
-#else
-#define RTGUI_EVENT_BUFFER_SIZE	256
-#endif
-
-struct rtgui_thread
-{
-	/* the thread id */
-	rt_thread_t tid;
-
-	/* the message queue of thread */
-	rt_mq_t mq;
-
-	/* the owner of thread */
-	struct rtgui_widget* widget;
-	/* event buffer */
-	rt_uint8_t event_buffer[RTGUI_EVENT_BUFFER_SIZE];
-
-	/* on idle event handler */
-	void (*on_idle)(struct rtgui_widget* widget, struct rtgui_event *event);
-};
-typedef struct rtgui_thread rtgui_thread_t;
-struct rtgui_timer;
-typedef void (*rtgui_timeout_func)(struct rtgui_timer* timer, void* parameter);
-typedef void (*rtgui_idle_func)(struct rtgui_widget* widget, struct rtgui_event *event);
-
-struct rtgui_timer
-{
-	/* context thread id */
-	rt_thread_t tid;
-	/* rt timer */
-	struct rt_timer timer;
-
-	/* timeout function and user data */
-	rtgui_timeout_func timeout;
-	void* user_data;
-};
-typedef struct rtgui_timer rtgui_timer_t;
-
-rtgui_timer_t* rtgui_timer_create(rt_int32_t time, rt_base_t flag, rtgui_timeout_func timeout, void* parameter);
-void rtgui_timer_destory(rtgui_timer_t* timer);
-
-void rtgui_timer_start(rtgui_timer_t* timer);
-void rtgui_timer_stop (rtgui_timer_t* timer);
-
-rtgui_thread_t* rtgui_thread_register(rt_thread_t tid, rt_mq_t mq);
-void rtgui_thread_deregister(rt_thread_t tid);
-void rtgui_thread_set_onidle(rtgui_idle_func onidle);
-rtgui_idle_func rtgui_thread_get_onidle(void);
-rtgui_thread_t* rtgui_thread_self(void);
-
-rt_thread_t rtgui_thread_get_server(void);
-
-void rtgui_thread_set_widget(struct rtgui_widget* widget);
-struct rtgui_widget* rtgui_thread_get_widget(void);
-
-rt_err_t rtgui_thread_send(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
-rt_err_t rtgui_thread_send_urgent(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
-rt_err_t rtgui_thread_send_sync(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
-rt_err_t rtgui_thread_recv(struct rtgui_event* event, rt_size_t event_size);
-rt_err_t rtgui_thread_recv_nosuspend(struct rtgui_event* event, rt_size_t event_size);
-rt_err_t rtgui_thread_recv_filter(rt_uint32_t type, struct rtgui_event* event, rt_size_t event_size);
-rt_err_t rtgui_thread_ack(struct rtgui_event* event, rt_int32_t status);
-
-/* rtgui system initialization function */
-void rtgui_system_server_init(void);
-
-void* rtgui_malloc(rt_size_t size);
-void rtgui_free(void* ptr);
-void* rtgui_realloc(void* ptr, rt_size_t size);
-
-#define rtgui_enter_critical	rt_enter_critical
-#define rtgui_exit_critical		rt_exit_critical
-
-#endif
-
+/*
+ * File      : rtgui_system.h
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-04     Bernard      first version
+ */
+#ifndef __RTGUI_SYSTEM_H__
+#define __RTGUI_SYSTEM_H__
+
+#include <rtthread.h>
+#include <rtgui/rtgui.h>
+
+struct rtgui_dc;
+struct rtgui_event;
+struct rtgui_widget;
+
+struct rtgui_timer;
+typedef void (*rtgui_timeout_func)(struct rtgui_timer* timer, void* parameter);
+
+struct rtgui_timer
+{
+	/* context thread id */
+	rt_thread_t tid;
+	/* rt timer */
+	struct rt_timer timer;
+
+	/* timeout function and user data */
+	rtgui_timeout_func timeout;
+	void* user_data;
+};
+typedef struct rtgui_timer rtgui_timer_t;
+
+rtgui_timer_t* rtgui_timer_create(rt_int32_t time, rt_base_t flag, rtgui_timeout_func timeout, void* parameter);
+void rtgui_timer_destory(rtgui_timer_t* timer);
+
+void rtgui_timer_start(rtgui_timer_t* timer);
+void rtgui_timer_stop (rtgui_timer_t* timer);
+
+/* rtgui system initialization function */
+void rtgui_system_server_init(void);
+
+void* rtgui_malloc(rt_size_t size);
+void rtgui_free(void* ptr);
+void* rtgui_realloc(void* ptr, rt_size_t size);
+
+#define rtgui_enter_critical	rt_enter_critical
+#define rtgui_exit_critical		rt_exit_critical
+
+#endif
+

+ 44 - 46
components/rtgui/include/rtgui/widgets/about_view.h

@@ -1,46 +1,44 @@
-/*
- * File      : list_view.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-01-06     Bernard      first version
- */
-
-#ifndef __RTGUI_ABOUT_VIEW_H__
-#define __RTGUI_ABOUT_VIEW_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/image.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/view.h>
-
-DECLARE_CLASS_TYPE(aboutview);
-/** Gets the type of a about view */
-#define RTGUI_ABOUT_VIEW_TYPE       (RTGUI_TYPE(aboutview))
-/** Casts the object to a about view */
-#define RTGUI_ABOUT_VIEW(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_ABOUT_VIEW_TYPE, rtgui_about_view_t))
-/** Checks if the object is a about view */
-#define RTGUI_IS_ABOUT_VIEW(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_ABOUT_VIEW_TYPE))
-
-struct rtgui_about_view
-{
-	struct rtgui_view parent;
-
-	/* widget private data */
-	rtgui_image_t* logo;
-	const char* description;
-};
-typedef struct rtgui_about_view rtgui_about_view_t;
-
-rtgui_type_t *rtgui_about_view_type_get(void);
-
-rtgui_about_view_t* rtgui_about_view_create(rtgui_image_t *logo, const char* description);
-rt_bool_t rtgui_about_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-#endif
+/*
+ * File      : list_view.h
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-01-06     Bernard      first version
+ */
+
+#ifndef __RTGUI_ABOUT_VIEW_H__
+#define __RTGUI_ABOUT_VIEW_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/image.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/container.h>
+
+DECLARE_CLASS_TYPE(aboutview);
+/** Gets the type of a about view */
+#define RTGUI_ABOUT_VIEW_TYPE       (RTGUI_TYPE(aboutview))
+/** Casts the object to a about view */
+#define RTGUI_ABOUT_VIEW(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_ABOUT_VIEW_TYPE, rtgui_about_view_t))
+/** Checks if the object is a about view */
+#define RTGUI_IS_ABOUT_VIEW(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_ABOUT_VIEW_TYPE))
+
+struct rtgui_about_view
+{
+	struct rtgui_container parent;
+
+	/* widget private data */
+	rtgui_image_t* logo;
+	const char* description;
+};
+typedef struct rtgui_about_view rtgui_about_view_t;
+
+rtgui_about_view_t* rtgui_about_view_create(rtgui_image_t *logo, const char* description);
+rt_bool_t rtgui_about_view_event_handler(struct rtgui_object* widget, struct rtgui_event* event);
+
+#endif

+ 58 - 58
components/rtgui/include/rtgui/widgets/box.h

@@ -1,58 +1,58 @@
-/*
- * File      : box.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_BOX_H__
-#define __RTGUI_BOX_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/widgets/widget.h>
-#include <rtgui/widgets/container.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-DECLARE_CLASS_TYPE(box);
-
-/** Gets the type of a box */
-#define RTGUI_BOX_TYPE       (RTGUI_TYPE(box))
-/** Casts the object to an rtgui_box */
-#define RTGUI_BOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_BOX_TYPE, rtgui_box_t))
-/** Checks if the object is an rtgui_box */
-#define RTGUI_IS_BOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_BOX_TYPE))
-
-struct rtgui_box
-{
-	struct rtgui_container parent;
-
-	rt_uint16_t orient;
-	rt_uint16_t border_size;
-};
-typedef struct rtgui_box rtgui_box_t;
-
-struct rtgui_box* rtgui_box_create(int orientation, rtgui_rect_t* rect);
-void rtgui_box_destroy(struct rtgui_box* box);
-
-rt_bool_t rtgui_box_event_handler(rtgui_widget_t* widget, rtgui_event_t* event);
-
-void rtgui_box_append(rtgui_box_t* box, rtgui_widget_t* widget);
-void rtgui_box_layout(rtgui_box_t* box);
-
-rt_uint32_t rtgui_box_get_width(rtgui_box_t* box);
-rt_uint32_t rtgui_box_get_height(rtgui_box_t* box);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * File      : box.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_BOX_H__
+#define __RTGUI_BOX_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+#include <rtgui/widgets/container.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+DECLARE_CLASS_TYPE(box);
+
+/** Gets the type of a box */
+#define RTGUI_BOX_TYPE       (RTGUI_TYPE(box))
+/** Casts the object to an rtgui_box */
+#define RTGUI_BOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_BOX_TYPE, rtgui_box_t))
+/** Checks if the object is an rtgui_box */
+#define RTGUI_IS_BOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_BOX_TYPE))
+
+struct rtgui_box
+{
+	struct rtgui_container parent;
+
+	rt_uint16_t orient;
+	rt_uint16_t border_size;
+};
+typedef struct rtgui_box rtgui_box_t;
+
+struct rtgui_box* rtgui_box_create(int orientation, rtgui_rect_t* rect);
+void rtgui_box_destroy(struct rtgui_box* box);
+
+rt_bool_t rtgui_box_event_handler(rtgui_widget_t* widget, rtgui_event_t* event);
+
+void rtgui_box_append(rtgui_box_t* box, rtgui_widget_t* widget);
+void rtgui_box_layout(rtgui_box_t* box);
+
+rt_uint32_t rtgui_box_get_width(rtgui_box_t* box);
+rt_uint32_t rtgui_box_get_height(rtgui_box_t* box);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 81 - 81
components/rtgui/include/rtgui/widgets/button.h

@@ -1,81 +1,81 @@
-/*
- * File      : button.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_BUTTON_H__
-#define __RTGUI_BUTTON_H__
-
-#include <rtgui/image.h>
-#include <rtgui/widgets/widget.h>
-#include <rtgui/widgets/label.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup rtgui_button
- * @{
- */
-
-DECLARE_CLASS_TYPE(button);
-
-/** Gets the type of a button */
-#define RTGUI_BUTTON_TYPE       (RTGUI_TYPE(button))
-/** Casts the object to an rtgui_button */
-#define RTGUI_BUTTON(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_BUTTON_TYPE, rtgui_button_t))
-/** Checks if the object is an rtgui_button */
-#define RTGUI_IS_BUTTON(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_BUTTON_TYPE))
-
-#define RTGUI_BUTTON_FLAG_PRESS		0x01
-#define RTGUI_BUTTON_FLAG_DEFAULT	0x02
-
-#define RTGUI_BUTTON_TYPE_NORMAL	0x00
-#define RTGUI_BUTTON_TYPE_PUSH		0x10
-
-/*
- * the button widget
- */
-struct rtgui_button
-{
-	/* inherit from label */
-	struct rtgui_label parent;
-
-	/* button flag */
-	rt_base_t flag;
-
-	/* pressed and unpressed image */
-	rtgui_image_t *pressed_image, *unpressed_image;
-
-	/* click button event handler */
-	void (*on_button)(struct rtgui_widget* widget, rtgui_event_t *event);
-};
-typedef struct rtgui_button rtgui_button_t;
-
-rtgui_button_t* rtgui_button_create(const char* text);
-rtgui_button_t* rtgui_pushbutton_create(const char* text);
-void rtgui_button_destroy(rtgui_button_t* btn);
-
-void rtgui_button_set_pressed_image(rtgui_button_t* btn, rtgui_image_t* image);
-void rtgui_button_set_unpressed_image(rtgui_button_t* btn, rtgui_image_t* image);
-
-void rtgui_button_set_onbutton(rtgui_button_t* btn, rtgui_onbutton_func_t func);
-
-rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-/** @} */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * File      : button.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_BUTTON_H__
+#define __RTGUI_BUTTON_H__
+
+#include <rtgui/image.h>
+#include <rtgui/widgets/widget.h>
+#include <rtgui/widgets/label.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup rtgui_button
+ * @{
+ */
+
+DECLARE_CLASS_TYPE(button);
+
+/** Gets the type of a button */
+#define RTGUI_BUTTON_TYPE       (RTGUI_TYPE(button))
+/** Casts the object to an rtgui_button */
+#define RTGUI_BUTTON(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_BUTTON_TYPE, rtgui_button_t))
+/** Checks if the object is an rtgui_button */
+#define RTGUI_IS_BUTTON(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_BUTTON_TYPE))
+
+#define RTGUI_BUTTON_FLAG_PRESS		0x01
+#define RTGUI_BUTTON_FLAG_DEFAULT	0x02
+
+#define RTGUI_BUTTON_TYPE_NORMAL	0x00
+#define RTGUI_BUTTON_TYPE_PUSH		0x10
+
+/*
+ * the button widget
+ */
+struct rtgui_button
+{
+	/* inherit from label */
+	struct rtgui_label parent;
+
+	/* button flag */
+	rt_base_t flag;
+
+	/* pressed and unpressed image */
+	rtgui_image_t *pressed_image, *unpressed_image;
+
+	/* click button event handler */
+	void (*on_button)(struct rtgui_widget* widget, rtgui_event_t *event);
+};
+typedef struct rtgui_button rtgui_button_t;
+
+rtgui_button_t* rtgui_button_create(const char* text);
+rtgui_button_t* rtgui_pushbutton_create(const char* text);
+void rtgui_button_destroy(rtgui_button_t* btn);
+
+void rtgui_button_set_pressed_image(rtgui_button_t* btn, rtgui_image_t* image);
+void rtgui_button_set_unpressed_image(rtgui_button_t* btn, rtgui_image_t* image);
+
+void rtgui_button_set_onbutton(rtgui_button_t* btn, rtgui_onbutton_func_t func);
+
+rt_bool_t rtgui_button_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 43 - 43
components/rtgui/include/rtgui/widgets/checkbox.h

@@ -1,43 +1,43 @@
-#ifndef __RTGUI_CHECKBOX_H__
-#define __RTGUI_CHECKBOX_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/widgets/widget.h>
-#include <rtgui/widgets/label.h>
-
-DECLARE_CLASS_TYPE(checkbox);
-
-/** Gets the type of a checkbox */
-#define RTGUI_CHECKBOX_TYPE       (RTGUI_TYPE(checkbox))
-/** Casts the object to an rtgui_button */
-#define RTGUI_CHECKBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_CHECKBOX_TYPE, rtgui_checkbox))
-/** Checks if the object is an rtgui_button */
-#define RTGUI_IS_CHECKBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_CHECKBOX_TYPE))
-
-#define RTGUI_CHECKBOX_STATUS_CHECKED		0
-#define RTGUI_CHECKBOX_STATUS_UNCHECKED		1
-
-struct rtgui_checkbox
-{
-	/* inherit from label */
-	struct rtgui_label parent;
-
-	/* check box status */
-	rt_uint8_t status_down;
-
-	/* click button event handler */
-	void (*on_button)(struct rtgui_widget* widget, rtgui_event_t *event);
-};
-typedef struct rtgui_checkbox rtgui_checkbox_t;
-
-rtgui_checkbox_t* rtgui_checkbox_create(const char* text, rt_bool_t checked);
-void rtgui_checkbox_destroy(rtgui_checkbox_t* checkbox);
-
-void rtgui_checkbox_set_checked(rtgui_checkbox_t* checkbox, rt_bool_t checked);
-rt_bool_t rtgui_checkbox_get_checked(rtgui_checkbox_t* checkbox);
-
-void rtgui_checkbox_set_onbutton(rtgui_checkbox_t* checkbox, rtgui_onbutton_func_t func);
-
-rt_bool_t rtgui_checkbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-#endif
+#ifndef __RTGUI_CHECKBOX_H__
+#define __RTGUI_CHECKBOX_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+#include <rtgui/widgets/label.h>
+
+DECLARE_CLASS_TYPE(checkbox);
+
+/** Gets the type of a checkbox */
+#define RTGUI_CHECKBOX_TYPE       (RTGUI_TYPE(checkbox))
+/** Casts the object to an rtgui_button */
+#define RTGUI_CHECKBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_CHECKBOX_TYPE, struct rtgui_checkbox))
+/** Checks if the object is an rtgui_button */
+#define RTGUI_IS_CHECKBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_CHECKBOX_TYPE))
+
+#define RTGUI_CHECKBOX_STATUS_CHECKED		0
+#define RTGUI_CHECKBOX_STATUS_UNCHECKED		1
+
+struct rtgui_checkbox
+{
+	/* inherit from label */
+	struct rtgui_label parent;
+
+	/* check box status */
+	rt_uint8_t status_down;
+
+	/* click button event handler */
+	void (*on_button)(struct rtgui_widget* widget, rtgui_event_t *event);
+};
+typedef struct rtgui_checkbox rtgui_checkbox_t;
+
+rtgui_checkbox_t* rtgui_checkbox_create(const char* text, rt_bool_t checked);
+void rtgui_checkbox_destroy(rtgui_checkbox_t* checkbox);
+
+void rtgui_checkbox_set_checked(rtgui_checkbox_t* checkbox, rt_bool_t checked);
+rt_bool_t rtgui_checkbox_get_checked(rtgui_checkbox_t* checkbox);
+
+void rtgui_checkbox_set_onbutton(rtgui_checkbox_t* checkbox, rtgui_onbutton_func_t func);
+
+rt_bool_t rtgui_checkbox_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+
+#endif

+ 49 - 49
components/rtgui/include/rtgui/widgets/combobox.h

@@ -1,49 +1,49 @@
-#ifndef __RTGUI_COMBOBOX_H__
-#define __RTGUI_COMBOBOX_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/image.h>
-#include <rtgui/widgets/window.h>
-#include <rtgui/widgets/listbox.h>
-
-DECLARE_CLASS_TYPE(combobox);
-/** Gets the type of a combobox */
-#define RTGUI_COMBOBOX_TYPE       (RTGUI_TYPE(combobox))
-/** Casts the object to a rtgui_combobox */
-#define RTGUI_COMBOBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_COMBOBOX_TYPE, rtgui_combobox_t))
-/** Checks if the object is a rtgui_combobox */
-#define RTGUI_IS_COMBOBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_COMBOBOX_TYPE))
-
-#define RTGUI_COMBOBOX_WIDTH		75
-#define RTGUI_COMBOBOX_HEIGHT		20
-#define RTGUI_COMBOBOX_BUTTON_WIDTH	18
-
-struct rtgui_combobox
-{
-	struct rtgui_widget parent;
-
-	/* widget private data */
-
-	/* pull down window */
-	struct rtgui_win* pd_win;
-	rt_bool_t pd_pressed;
-
-	/* combobox items */
-	struct rtgui_listbox_item* items;
-	rt_uint16_t items_count;
-	rt_uint16_t current_item;
-
-	/* call back */
-	void (*on_selected) (struct rtgui_widget* widget, struct rtgui_event* event);
-};
-typedef struct rtgui_combobox rtgui_combobox_t;
-
-rtgui_combobox_t *rtgui_combobox_create(struct rtgui_listbox_item* items, rt_uint16_t counter, struct rtgui_rect* rect);
-void rtgui_combobox_destroy(rtgui_combobox_t* box);
-
-rt_bool_t rtgui_combobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-struct rtgui_listbox_item* rtgui_combox_get_select(struct rtgui_combobox* box);
-
-void rtgui_combobox_set_onselected(struct rtgui_combobox* box, rtgui_onitem_func_t func);
-
-#endif
+#ifndef __RTGUI_COMBOBOX_H__
+#define __RTGUI_COMBOBOX_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/image.h>
+#include <rtgui/widgets/window.h>
+#include <rtgui/widgets/listbox.h>
+
+DECLARE_CLASS_TYPE(combobox);
+/** Gets the type of a combobox */
+#define RTGUI_COMBOBOX_TYPE       (RTGUI_TYPE(combobox))
+/** Casts the object to a rtgui_combobox */
+#define RTGUI_COMBOBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_COMBOBOX_TYPE, rtgui_combobox_t))
+/** Checks if the object is a rtgui_combobox */
+#define RTGUI_IS_COMBOBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_COMBOBOX_TYPE))
+
+#define RTGUI_COMBOBOX_WIDTH		75
+#define RTGUI_COMBOBOX_HEIGHT		20
+#define RTGUI_COMBOBOX_BUTTON_WIDTH	18
+
+struct rtgui_combobox
+{
+	struct rtgui_widget parent;
+
+	/* widget private data */
+
+	/* pull down window */
+	struct rtgui_win* pd_win;
+	rt_bool_t pd_pressed;
+
+	/* combobox items */
+	struct rtgui_listbox_item* items;
+	rt_uint16_t items_count;
+	rt_uint16_t current_item;
+
+	/* call back */
+	rtgui_event_handler_ptr on_selected;
+};
+typedef struct rtgui_combobox rtgui_combobox_t;
+
+rtgui_combobox_t *rtgui_combobox_create(struct rtgui_listbox_item* items, rt_uint16_t counter, struct rtgui_rect* rect);
+void rtgui_combobox_destroy(rtgui_combobox_t* box);
+
+rt_bool_t rtgui_combobox_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+struct rtgui_listbox_item* rtgui_combox_get_select(struct rtgui_combobox* box);
+
+void rtgui_combobox_set_onselected(struct rtgui_combobox* box, rtgui_event_handler_ptr func);
+
+#endif

+ 68 - 47
components/rtgui/include/rtgui/widgets/container.h

@@ -1,47 +1,68 @@
-/*
- * File      : container.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_CONTAINER_H__
-#define __RTGUI_CONTAINER_H__
-
-#include <rtgui/widgets/widget.h>
-
-DECLARE_CLASS_TYPE(container);
-/** Gets the type of a container */
-#define RTGUI_CONTAINER_TYPE       (RTGUI_TYPE(container))
-/** Casts the object to a rtgui_container */
-#define RTGUI_CONTAINER(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_CONTAINER_TYPE, rtgui_container_t))
-/** Checks if the object is a rtgui_container */
-#define RTGUI_IS_CONTAINER(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_CONTAINER_TYPE))
-
-struct rtgui_container
-{
-	/* inherit from widget */
-	struct rtgui_widget parent;
-
-	struct rtgui_widget* focused;
-	rtgui_list_t children;
-};
-typedef struct rtgui_container rtgui_container_t;
-
-void rtgui_container_add_child(rtgui_container_t *container, rtgui_widget_t* child);
-void rtgui_container_remove_child(rtgui_container_t *container, rtgui_widget_t* child);
-void rtgui_container_destroy_children(rtgui_container_t *container);
-rtgui_widget_t* rtgui_container_get_first_child(rtgui_container_t* container);
-
-rt_bool_t rtgui_container_event_handler(rtgui_widget_t* widget, rtgui_event_t* event);
-
-rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_event_t* event);
-rt_bool_t rtgui_container_dispatch_mouse_event(rtgui_container_t *container, struct rtgui_event_mouse* event);
-
-#endif
+/*
+ * File      : container.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_CONTAINER_H__
+#define __RTGUI_CONTAINER_H__
+
+#include <rtgui/widgets/widget.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+DECLARE_CLASS_TYPE(container);
+/** Gets the type of a container */
+#define RTGUI_CONTAINER_TYPE       (RTGUI_TYPE(container))
+/** Casts the object to an rtgui_container */
+#define RTGUI_CONTAINER(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_CONTAINER_TYPE, rtgui_container_t))
+/** Checks if the object is an rtgui_container */
+#define RTGUI_IS_CONTAINER(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_CONTAINER_TYPE))
+
+/*
+ * the container widget
+ */
+struct rtgui_container
+{
+	struct rtgui_widget parent;
+
+	rtgui_list_t children;
+};
+typedef struct rtgui_container rtgui_container_t;
+
+rtgui_container_t* rtgui_container_create(void);
+void rtgui_container_destroy(rtgui_container_t* container);
+
+rt_bool_t rtgui_container_event_handler(struct rtgui_object* widget, struct rtgui_event* event);
+
+#ifndef RTGUI_USING_SMALL_SIZE
+struct rtgui_box;
+void rtgui_container_set_box(struct rtgui_container* container, struct rtgui_box* box);
+#endif
+
+void rtgui_container_hide(rtgui_container_t* container);
+
+void rtgui_container_add_child(rtgui_container_t *container, rtgui_widget_t* child);
+void rtgui_container_remove_child(rtgui_container_t *container, rtgui_widget_t* child);
+void rtgui_container_destroy_children(rtgui_container_t *container);
+rtgui_widget_t* rtgui_container_get_first_child(rtgui_container_t* container);
+
+rt_bool_t rtgui_container_event_handler(struct rtgui_object* widget, rtgui_event_t* event);
+
+rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_event_t* event);
+rt_bool_t rtgui_container_dispatch_mouse_event(rtgui_container_t *container, struct rtgui_event_mouse* event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 58 - 57
components/rtgui/include/rtgui/widgets/filelist_view.h

@@ -1,57 +1,58 @@
-#ifndef __RTGUI_FILELIST_VIEW_H__
-#define __RTGUI_FILELIST_VIEW_H__
-
-#include <rtgui/widgets/view.h>
-
-#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
-#define RTGUI_FITEM_FILE      0x0
-#define RTGUI_FITEM_DIR       0x1
-struct rtgui_file_item
-{
-	char* name;
-
-	rt_uint32_t type;
-	rt_uint32_t size;
-};
-
-DECLARE_CLASS_TYPE(filelist);
-/** Gets the type of a filelist view */
-#define RTGUI_FILELIST_VIEW_TYPE       (RTGUI_TYPE(filelist))
-/** Casts the object to a filelist */
-#define RTGUI_FILELIST_VIEW(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_FILELIST_VIEW_TYPE, rtgui_filelist_view_t))
-/** Checks if the object is a filelist view */
-#define RTGUI_IS_FILELIST_VIEW(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_FILELIST_VIEW_TYPE))
-
-struct rtgui_filelist_view
-{
-	struct rtgui_view parent;
-
-	/* widget private data */
-
-    /* current directory */
-    char* current_directory;
-    char* pattern;
-
-    /* the number of item in a page */
-    rt_uint16_t page_items;
-	rt_uint16_t items_count;
-
-	/* the selected item */
-	rt_uint16_t current_item;
-
-	/* items array */
-	struct rtgui_file_item *items;
-};
-typedef struct rtgui_filelist_view rtgui_filelist_view_t;
-
-rtgui_filelist_view_t* rtgui_filelist_view_create(rtgui_workbench_t* workbench, 
-	const char* directory, const char* pattern, const rtgui_rect_t* rect);
-void rtgui_filelist_view_destroy(rtgui_filelist_view_t* view);
-
-rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-void rtgui_filelist_view_set_directory(rtgui_filelist_view_t* view, const char* directory);
-
-void rtgui_filelist_view_get_fullpath(rtgui_filelist_view_t* view, char* path, rt_size_t len);
-#endif
-
-#endif
+#ifndef __RTGUI_FILELIST_VIEW_H__
+#define __RTGUI_FILELIST_VIEW_H__
+
+#include <rtgui/widgets/container.h>
+
+#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
+#define RTGUI_FITEM_FILE      0x0
+#define RTGUI_FITEM_DIR       0x1
+struct rtgui_file_item
+{
+	char* name;
+
+	rt_uint32_t type;
+	rt_uint32_t size;
+};
+
+DECLARE_CLASS_TYPE(filelist);
+/** Gets the type of a filelist view */
+#define RTGUI_FILELIST_VIEW_TYPE       (RTGUI_TYPE(filelist))
+/** Casts the object to a filelist */
+#define RTGUI_FILELIST_VIEW(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_FILELIST_VIEW_TYPE, rtgui_filelist_view_t))
+/** Checks if the object is a filelist view */
+#define RTGUI_IS_FILELIST_VIEW(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_FILELIST_VIEW_TYPE))
+
+struct rtgui_filelist_view
+{
+	struct rtgui_container parent;
+
+	/* widget private data */
+
+    /* current directory */
+    char* current_directory;
+    char* pattern;
+
+    /* the number of item in a page */
+    rt_uint16_t page_items;
+	rt_uint16_t items_count;
+
+	/* the selected item */
+	rt_uint16_t current_item;
+
+	/* items array */
+	struct rtgui_file_item *items;
+};
+typedef struct rtgui_filelist_view rtgui_filelist_view_t;
+
+rtgui_filelist_view_t* rtgui_filelist_view_create(const char* directory,
+												  const char* pattern,
+												  const rtgui_rect_t* rect);
+void rtgui_filelist_view_destroy(rtgui_filelist_view_t* view);
+
+rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
+void rtgui_filelist_view_set_directory(rtgui_filelist_view_t* view, const char* directory);
+
+void rtgui_filelist_view_get_fullpath(rtgui_filelist_view_t* view, char* path, rt_size_t len);
+#endif
+
+#endif

+ 55 - 55
components/rtgui/include/rtgui/widgets/iconbox.h

@@ -1,55 +1,55 @@
-/*
- * File      : iconbox.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_ICONBOX_H__
-#define __RTGUI_ICONBOX_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/image.h>
-#include <rtgui/widgets/widget.h>
-
-DECLARE_CLASS_TYPE(iconbox);
-/** Gets the type of a iconbox */
-#define RTGUI_ICONBOX_TYPE       (RTGUI_TYPE(iconbox))
-/** Casts the object to a rtgui_iconbox */
-#define RTGUI_ICONBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_ICONBOX_TYPE, rtgui_iconbox_t))
-/** Checks if the object is a rtgui_iconbox */
-#define RTGUI_IS_ICONBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_ICONBOX_TYPE))
-
-#define RTGUI_ICONBOX_NOTEXT		0x00
-#define RTGUI_ICONBOX_TEXT_RIGHT	0x01
-#define RTGUI_ICONBOX_TEXT_BELOW	0x02
-
-struct rtgui_iconbox
-{
-	/* inherit from widget */
-	struct rtgui_widget parent;
-
-	/* widget private data */
-	struct rtgui_image* image;
-
-	char *text;
-	rt_ubase_t text_position;
-
-	rt_bool_t selected;
-};
-typedef struct rtgui_iconbox rtgui_iconbox_t;
-
-struct rtgui_iconbox* rtgui_iconbox_create(struct rtgui_image* image, const char* text, int position);
-void rtgui_iconbox_destroy(struct rtgui_iconbox* iconbox);
-
-rt_bool_t rtgui_iconbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-void rtgui_iconbox_set_text_position(struct rtgui_iconbox* iconbox, int position);
-
-#endif
+/*
+ * File      : iconbox.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_ICONBOX_H__
+#define __RTGUI_ICONBOX_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/image.h>
+#include <rtgui/widgets/widget.h>
+
+DECLARE_CLASS_TYPE(iconbox);
+/** Gets the type of a iconbox */
+#define RTGUI_ICONBOX_TYPE       (RTGUI_TYPE(iconbox))
+/** Casts the object to a rtgui_iconbox */
+#define RTGUI_ICONBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_ICONBOX_TYPE, rtgui_iconbox_t))
+/** Checks if the object is a rtgui_iconbox */
+#define RTGUI_IS_ICONBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_ICONBOX_TYPE))
+
+#define RTGUI_ICONBOX_NOTEXT		0x00
+#define RTGUI_ICONBOX_TEXT_RIGHT	0x01
+#define RTGUI_ICONBOX_TEXT_BELOW	0x02
+
+struct rtgui_iconbox
+{
+	/* inherit from widget */
+	struct rtgui_widget parent;
+
+	/* widget private data */
+	struct rtgui_image* image;
+
+	char *text;
+	rt_ubase_t text_position;
+
+	rt_bool_t selected;
+};
+typedef struct rtgui_iconbox rtgui_iconbox_t;
+
+struct rtgui_iconbox* rtgui_iconbox_create(struct rtgui_image* image, const char* text, int position);
+void rtgui_iconbox_destroy(struct rtgui_iconbox* iconbox);
+
+rt_bool_t rtgui_iconbox_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+
+void rtgui_iconbox_set_text_position(struct rtgui_iconbox* iconbox, int position);
+
+#endif

+ 49 - 49
components/rtgui/include/rtgui/widgets/label.h

@@ -1,49 +1,49 @@
-/*
- * File      : label.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_LABEL_H__
-#define __RTGUI_LABEL_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/widgets/widget.h>
-
-DECLARE_CLASS_TYPE(label);
-
-/** Gets the type of a button */
-#define RTGUI_LABEL_TYPE       (RTGUI_TYPE(label))
-/** Casts the object to an rtgui_button */
-#define RTGUI_LABEL(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_LABEL_TYPE, rtgui_label_t))
-/** Checks if the object is an rtgui_button */
-#define RTGUI_IS_LABEL(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_LABEL_TYPE))
-
-/*
- * the label widget
- */
-struct rtgui_label
-{
-	struct rtgui_widget parent;
-
-	/* label */
-	char* text;
-};
-typedef struct rtgui_label rtgui_label_t;
-
-rtgui_label_t* rtgui_label_create(const char* text);
-void rtgui_label_destroy(rtgui_label_t* label);
-
-rt_bool_t rtgui_label_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-void rtgui_label_set_text(rtgui_label_t* label, const char* text);
-char* rtgui_label_get_text(rtgui_label_t* label);
-
-#endif
+/*
+ * File      : label.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_LABEL_H__
+#define __RTGUI_LABEL_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+
+DECLARE_CLASS_TYPE(label);
+
+/** Gets the type of a button */
+#define RTGUI_LABEL_TYPE       (RTGUI_TYPE(label))
+/** Casts the object to an rtgui_button */
+#define RTGUI_LABEL(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_LABEL_TYPE, rtgui_label_t))
+/** Checks if the object is an rtgui_button */
+#define RTGUI_IS_LABEL(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_LABEL_TYPE))
+
+/*
+ * the label widget
+ */
+struct rtgui_label
+{
+	struct rtgui_widget parent;
+
+	/* label */
+	char* text;
+};
+typedef struct rtgui_label rtgui_label_t;
+
+rtgui_label_t* rtgui_label_create(const char* text);
+void rtgui_label_destroy(rtgui_label_t* label);
+
+rt_bool_t rtgui_label_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+
+void rtgui_label_set_text(rtgui_label_t* label, const char* text);
+char* rtgui_label_get_text(rtgui_label_t* label);
+
+#endif

+ 76 - 78
components/rtgui/include/rtgui/widgets/list_view.h

@@ -1,78 +1,76 @@
-/*
- * File      : list_view.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-01-06     Bernard      first version
- */
-
-#ifndef __RTGUI_LIST_VIEW_H__
-#define __RTGUI_LIST_VIEW_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/image.h>
-#include <rtgui/rtgui_system.h>
-
-#include <rtgui/widgets/view.h>
-
-typedef void (*item_action)(struct rtgui_widget* widget, void* parameter);
-struct rtgui_list_item
-{
-    char* name;
-	rtgui_image_t *image;
-
-    item_action action;
-    void *parameter;
-};
-
-DECLARE_CLASS_TYPE(listview);
-/** Gets the type of a list view */
-#define RTGUI_LIST_VIEW_TYPE       (RTGUI_TYPE(listview))
-/** Casts the object to a filelist */
-#define RTGUI_LIST_VIEW(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_LIST_VIEW_TYPE, rtgui_list_view_t))
-/** Checks if the object is a filelist view */
-#define RTGUI_IS_LIST_VIEW(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_LIST_VIEW_TYPE))
-
-#define RTGUI_LIST_VIEW_LIST		0x00
-#define RTGUI_LIST_VIEW_ICON		0x01
-#define RTGUI_LIST_VIEW_REPORT		0x02
-
-struct rtgui_list_view
-{
-	struct rtgui_view parent;
-
-	/* widget private data */
-	/* list item */
-    const struct rtgui_list_item* items;
-
-	/* layout flag */
-	rt_uint16_t flag;
-
-	/* total number of items */
-	rt_uint16_t items_count;
-    /* the number of item in a page */
-    rt_uint16_t page_items;
-	/* current item */
-    rt_int16_t current_item;
-
-	/* icon layout */
-	rt_uint8_t row_items, col_items;
-};
-typedef struct rtgui_list_view rtgui_list_view_t;
-
-rtgui_type_t *rtgui_list_view_type_get(void);
-
-rtgui_list_view_t* rtgui_list_view_create(const struct rtgui_list_item* items, rt_uint16_t count,
-    rtgui_rect_t *rect, rt_uint16_t flag);
-void rtgui_list_view_destroy(rtgui_list_view_t* view);
-
-rt_bool_t rtgui_list_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-#endif
-
+/*
+ * File      : list_view.h
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-01-06     Bernard      first version
+ */
+
+#ifndef __RTGUI_LIST_VIEW_H__
+#define __RTGUI_LIST_VIEW_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/image.h>
+#include <rtgui/rtgui_system.h>
+
+#include <rtgui/widgets/container.h>
+
+typedef void (*item_action)(struct rtgui_widget* widget, void* parameter);
+struct rtgui_list_item
+{
+    char* name;
+	rtgui_image_t *image;
+
+    item_action action;
+    void *parameter;
+};
+
+DECLARE_CLASS_TYPE(listview);
+/** Gets the type of a list view */
+#define RTGUI_LIST_VIEW_TYPE       (RTGUI_TYPE(listview))
+/** Casts the object to a filelist */
+#define RTGUI_LIST_VIEW(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_LIST_VIEW_TYPE, rtgui_list_view_t))
+/** Checks if the object is a filelist view */
+#define RTGUI_IS_LIST_VIEW(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_LIST_VIEW_TYPE))
+
+#define RTGUI_LIST_VIEW_LIST		0x00
+#define RTGUI_LIST_VIEW_ICON		0x01
+#define RTGUI_LIST_VIEW_REPORT		0x02
+
+struct rtgui_list_view
+{
+	struct rtgui_container parent;
+
+	/* widget private data */
+	/* list item */
+    const struct rtgui_list_item* items;
+
+	/* layout flag */
+	rt_uint16_t flag;
+
+	/* total number of items */
+	rt_uint16_t items_count;
+    /* the number of item in a page */
+    rt_uint16_t page_items;
+	/* current item */
+    rt_uint16_t current_item;
+
+	/* icon layout */
+	rt_uint8_t row_items, col_items;
+};
+typedef struct rtgui_list_view rtgui_list_view_t;
+
+rtgui_list_view_t* rtgui_list_view_create(const struct rtgui_list_item* items, rt_uint16_t count,
+    rtgui_rect_t *rect, rt_uint16_t flag);
+void rtgui_list_view_destroy(rtgui_list_view_t* view);
+
+rt_bool_t rtgui_list_view_event_handler(struct rtgui_object* widget, struct rtgui_event* event);
+
+#endif
+

+ 67 - 68
components/rtgui/include/rtgui/widgets/listbox.h

@@ -1,68 +1,67 @@
-/*
- * File      : listbox.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-01-06     Bernard      first version
- */
-
-#ifndef __RTGUI_LISTBOX_H__
-#define __RTGUI_LISTBOX_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/image.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/widget.h>
-
-struct rtgui_listbox_item
-{
-    char* name;
-	rtgui_image_t *image;
-};
-
-DECLARE_CLASS_TYPE(listbox);
-/** Gets the type of a list box */
-#define RTGUI_LISTBOX_TYPE		(RTGUI_TYPE(listbox))
-/** Casts the object to a filelist */
-#define RTGUI_LISTBOX(obj)		(RTGUI_OBJECT_CAST((obj), RTGUI_LISTBOX_TYPE, rtgui_listbox_t))
-/** Checks if the object is a filelist box */
-#define RTGUI_IS_LISTBOX(obj)	(RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_LISTBOX_TYPE))
-
-struct rtgui_listbox
-{
-	struct rtgui_widget parent;
-
-	/* widget private data */
-	/* listbox item */
-    const struct rtgui_listbox_item* items;
-
-	/* item event handler */
-	void (*on_item)(rtgui_widget_t *widgets, struct rtgui_event* event);
-
-	/* total number of items */
-	rt_uint16_t items_count;
-    /* the number of item in a page */
-    rt_uint16_t page_items;
-    /* current item */
-    rt_int16_t current_item;
-};
-typedef struct rtgui_listbox rtgui_listbox_t;
-typedef void (*rtgui_onitem_func_t)(struct rtgui_widget* widget, rtgui_event_t *event);
-
-rtgui_listbox_t* rtgui_listbox_create(const struct rtgui_listbox_item* items, rt_uint16_t count,
-    rtgui_rect_t *rect);
-void rtgui_listbox_destroy(rtgui_listbox_t* box);
-
-rt_bool_t rtgui_listbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-void rtgui_listbox_set_onitem(rtgui_listbox_t* box, rtgui_onitem_func_t func);
-void rtgui_listbox_set_items(rtgui_listbox_t* box, struct rtgui_listbox_item* items, rt_uint16_t count);
-void rtgui_listbox_set_current_item(rtgui_listbox_t* box, int index);
-
-#endif
-
+/*
+ * File      : listbox.h
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-01-06     Bernard      first version
+ */
+
+#ifndef __RTGUI_LISTBOX_H__
+#define __RTGUI_LISTBOX_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/image.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/widget.h>
+
+struct rtgui_listbox_item
+{
+    char* name;
+	rtgui_image_t *image;
+};
+
+DECLARE_CLASS_TYPE(listbox);
+/** Gets the type of a list box */
+#define RTGUI_LISTBOX_TYPE		(RTGUI_TYPE(listbox))
+/** Casts the object to a filelist */
+#define RTGUI_LISTBOX(obj)		(RTGUI_OBJECT_CAST((obj), RTGUI_LISTBOX_TYPE, rtgui_listbox_t))
+/** Checks if the object is a filelist box */
+#define RTGUI_IS_LISTBOX(obj)	(RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_LISTBOX_TYPE))
+
+struct rtgui_listbox
+{
+	struct rtgui_widget parent;
+
+	/* widget private data */
+	/* listbox item */
+    const struct rtgui_listbox_item* items;
+
+	/* item event handler */
+	rtgui_event_handler_ptr on_item;
+
+	/* total number of items */
+	rt_uint16_t items_count;
+    /* the number of item in a page */
+    rt_uint16_t page_items;
+    /* current item */
+    rt_int16_t current_item;
+};
+typedef struct rtgui_listbox rtgui_listbox_t;
+
+rtgui_listbox_t* rtgui_listbox_create(const struct rtgui_listbox_item* items, rt_uint16_t count,
+    rtgui_rect_t *rect);
+void rtgui_listbox_destroy(rtgui_listbox_t* box);
+
+rt_bool_t rtgui_listbox_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+void rtgui_listbox_set_onitem(rtgui_listbox_t* box, rtgui_event_handler_ptr func);
+void rtgui_listbox_set_items(rtgui_listbox_t* box, struct rtgui_listbox_item* items, rt_uint16_t count);
+void rtgui_listbox_set_current_item(rtgui_listbox_t* box, int index);
+
+#endif
+

+ 63 - 66
components/rtgui/include/rtgui/widgets/listctrl.h

@@ -1,66 +1,63 @@
-/*
- * File      : listctrl.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-12-06     Bernard      first version
- */
-
-#ifndef __RTGUI_LISTCTRL_H__
-#define __RTGUI_LISTCTRL_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/image.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/widget.h>
-
-DECLARE_CLASS_TYPE(listctrl);
-/** Gets the type of a listctrl */
-#define RTGUI_LISTCTRL_TYPE		(RTGUI_TYPE(listctrl))
-/** Casts the object to a listctrl */
-#define RTGUI_LISTCTRL(obj)		(RTGUI_OBJECT_CAST((obj), RTGUI_LISTCTRL_TYPE, rtgui_listctrl_t))
-/** Checks if the object is a listctrl */
-#define RTGUI_IS_LISTCTRL(obj)	(RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_LISTCTRL_TYPE))
-
-struct rtgui_listctrl
-{
-	struct rtgui_widget parent;
-
-	/* widget private data */
-	/* listctrl items */
-    rt_uint32_t items;
-
-	/* total number of items */
-	rt_uint16_t items_count;
-    /* the number of item in a page */
-    rt_uint16_t page_items;
-    /* current item */
-    rt_int16_t current_item;
-
-	/* item event handler */
-	void (*on_item)(rtgui_widget_t *widget, struct rtgui_event* event);
-	void (*on_item_draw)(struct rtgui_listctrl *list, struct rtgui_dc* dc, rtgui_rect_t* rect, rt_uint16_t index);
-};
-typedef struct rtgui_listctrl rtgui_listctrl_t;
-
-typedef void (*rtgui_onitem_func_t)(struct rtgui_widget* widget, rtgui_event_t *event);
-typedef void (*rtgui_onitem_draw_t)(struct rtgui_listctrl *list, struct rtgui_dc* dc, rtgui_rect_t* rect, rt_uint16_t index);
-
-rtgui_type_t *rtgui_listctrl_type_get(void);
-
-rtgui_listctrl_t* rtgui_listctrl_create(rt_uint32_t items, rt_uint16_t count,
-    rtgui_rect_t *rect, rtgui_onitem_draw_t ondraw);
-void rtgui_listctrl_destroy(rtgui_listctrl_t* ctrl);
-
-rt_bool_t rtgui_listctrl_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-void rtgui_listctrl_set_onitem(rtgui_listctrl_t* ctrl, rtgui_onitem_func_t func);
-void rtgui_listctrl_set_items(rtgui_listctrl_t* ctrl, rt_uint32_t items, rt_uint16_t count);
-rt_bool_t rtgui_listctrl_get_item_rect(rtgui_listctrl_t* ctrl, rt_uint16_t item, rtgui_rect_t* item_rect);
-
-#endif
+/*
+ * File      : listctrl.h
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-12-06     Bernard      first version
+ */
+
+#ifndef __RTGUI_LISTCTRL_H__
+#define __RTGUI_LISTCTRL_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/image.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/widget.h>
+
+DECLARE_CLASS_TYPE(listctrl);
+/** Gets the type of a listctrl */
+#define RTGUI_LISTCTRL_TYPE		(RTGUI_TYPE(listctrl))
+/** Casts the object to a listctrl */
+#define RTGUI_LISTCTRL(obj)		(RTGUI_OBJECT_CAST((obj), RTGUI_LISTCTRL_TYPE, rtgui_listctrl_t))
+/** Checks if the object is a listctrl */
+#define RTGUI_IS_LISTCTRL(obj)	(RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_LISTCTRL_TYPE))
+
+struct rtgui_listctrl
+{
+	struct rtgui_widget parent;
+
+	/* widget private data */
+	/* listctrl items */
+    rt_uint32_t items;
+
+	/* total number of items */
+	rt_uint16_t items_count;
+    /* the number of item in a page */
+    rt_uint16_t page_items;
+    /* current item */
+    rt_int16_t current_item;
+
+	/* item event handler */
+	rtgui_event_handler_ptr on_item;
+	void (*on_item_draw)(struct rtgui_listctrl *list, struct rtgui_dc* dc, rtgui_rect_t* rect, rt_uint16_t index);
+};
+typedef struct rtgui_listctrl rtgui_listctrl_t;
+
+typedef void (*rtgui_onitem_draw_t)(struct rtgui_listctrl *list, struct rtgui_dc* dc, rtgui_rect_t* rect, rt_uint16_t index);
+
+rtgui_listctrl_t* rtgui_listctrl_create(rt_uint32_t items, rt_uint16_t count,
+    rtgui_rect_t *rect, rtgui_onitem_draw_t ondraw);
+void rtgui_listctrl_destroy(rtgui_listctrl_t* ctrl);
+
+rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+void rtgui_listctrl_set_onitem(rtgui_listctrl_t* ctrl, rtgui_event_handler_ptr func);
+void rtgui_listctrl_set_items(rtgui_listctrl_t* ctrl, rt_uint32_t items, rt_uint16_t count);
+rt_bool_t rtgui_listctrl_get_item_rect(rtgui_listctrl_t* ctrl, rt_uint16_t item, rtgui_rect_t* item_rect);
+
+#endif

+ 78 - 80
components/rtgui/include/rtgui/widgets/menu.h

@@ -1,80 +1,78 @@
-#ifndef __RTGUI_MENU_H__
-#define __RTGUI_MENU_H__
-
-#include <rtgui/image.h>
-#include <rtgui/widgets/window.h>
-#include <rtgui/widgets/listctrl.h>
-
-/* rtgui menu item */
-enum rtgui_menu_item_type
-{
-	RTGUI_ITEM_NORMAL,
-	RTGUI_ITEM_CHECK,
-	RTGUI_ITEM_SUBMENU,
-	RTGUI_ITEM_SEPARATOR
-};
-typedef enum rtgui_menu_item_type rtgui_menu_item_type_t;
-
-struct rtgui_menu_item
-{
-	rtgui_menu_item_type_t type;
-
-	/* menu text label */
-	const char* label;
-	/* menu image */
-	rtgui_image_t *image;
-
-	/* sub-menu item */
-	const struct rtgui_menu_item_t *submenu;
-	rt_uint16_t submenu_count;
-
-	/* menu action */
-	rt_bool_t (*on_menuaction)(rtgui_widget_t* widget, rtgui_event_t* event);
-};
-typedef struct rtgui_menu_item rtgui_menu_item_t;
-
-DECLARE_CLASS_TYPE(menu);
-/** Gets the type of a menu */
-#define RTGUI_MENU_TYPE       (RTGUI_TYPE(menu))
-/** Casts the object to an rtgui_menu */
-#define RTGUI_MENU(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_MENU_TYPE, rtgui_menu_t))
-/** Checks if the object is an rtgui_menu */
-#define RTGUI_IS_MENU(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_MENU_TYPE))
-
-#define RTGUI_MENU_DEFAULT_WIDTH	100
-struct rtgui_menu
-{
-	/* inherited from window */
-	struct rtgui_win parent;
-
-	/* menu items */
-	const struct rtgui_menu_item *items;
-	rt_uint16_t items_count;
-
-	/* parent menu */
-	struct rtgui_menu *parent_menu;
-	struct rtgui_menu *sub_menu;
-
-	/* menu item list control */
-	struct rtgui_listctrl *items_list;
-
-	/* pop event handle */
-	rt_bool_t (*on_menupop)(rtgui_widget_t* widget, rtgui_event_t* event);
-	rt_bool_t (*on_menuhide)(rtgui_widget_t* widget, rtgui_event_t* event);
-};
-typedef struct rtgui_menu rtgui_menu_t;
-
-rtgui_type_t *rtgui_menu_type_get(void);
-
-struct rtgui_menu* rtgui_menu_create(const char* title, struct rtgui_menu* parent_menu,
-	const struct rtgui_menu_item* items, rt_uint16_t count);
-void rtgui_menu_destroy(struct rtgui_menu* menu);
-
-void rtgui_menu_set_onmenupop(struct rtgui_menu* menu, rtgui_event_handler_ptr handler);
-void rtgui_menu_set_onmenuhide(struct rtgui_menu* menu, rtgui_event_handler_ptr handler);
-
-void rtgui_menu_pop(struct rtgui_menu* menu, int x, int y);
-void rtgui_menu_hiden(struct rtgui_menu* menu);
-
-#endif
-
+#ifndef __RTGUI_MENU_H__
+#define __RTGUI_MENU_H__
+
+#include <rtgui/image.h>
+#include <rtgui/widgets/window.h>
+#include <rtgui/widgets/listctrl.h>
+
+/* rtgui menu item */
+enum rtgui_menu_item_type
+{
+	RTGUI_ITEM_NORMAL,
+	RTGUI_ITEM_CHECK,
+	RTGUI_ITEM_SUBMENU,
+	RTGUI_ITEM_SEPARATOR
+};
+typedef enum rtgui_menu_item_type rtgui_menu_item_type_t;
+
+struct rtgui_menu_item
+{
+	rtgui_menu_item_type_t type;
+
+	/* menu text label */
+	const char* label;
+	/* menu image */
+	rtgui_image_t *image;
+
+	/* sub-menu item */
+	const struct rtgui_menu_item_t *submenu;
+	rt_uint16_t submenu_count;
+
+	/* menu action */
+	rt_bool_t (*on_menuaction)(rtgui_widget_t* widget, rtgui_event_t* event);
+};
+typedef struct rtgui_menu_item rtgui_menu_item_t;
+
+DECLARE_CLASS_TYPE(menu);
+/** Gets the type of a menu */
+#define RTGUI_MENU_TYPE       (RTGUI_TYPE(menu))
+/** Casts the object to an rtgui_menu */
+#define RTGUI_MENU(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_MENU_TYPE, rtgui_menu_t))
+/** Checks if the object is an rtgui_menu */
+#define RTGUI_IS_MENU(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_MENU_TYPE))
+
+#define RTGUI_MENU_DEFAULT_WIDTH	100
+struct rtgui_menu
+{
+	/* inherited from window */
+	struct rtgui_win parent;
+
+	/* menu items */
+	const struct rtgui_menu_item *items;
+	rt_uint16_t items_count;
+
+	/* parent menu */
+	struct rtgui_menu *parent_menu;
+	struct rtgui_menu *sub_menu;
+
+	/* menu item list control */
+	struct rtgui_listctrl *items_list;
+
+	/* pop event handle */
+	rtgui_event_handler_ptr on_menupop;
+	rtgui_event_handler_ptr on_menuhide;
+};
+typedef struct rtgui_menu rtgui_menu_t;
+
+struct rtgui_menu* rtgui_menu_create(const char* title, struct rtgui_menu* parent_menu,
+	const struct rtgui_menu_item* items, rt_uint16_t count);
+void rtgui_menu_destroy(struct rtgui_menu* menu);
+
+void rtgui_menu_set_onmenupop(struct rtgui_menu* menu, rtgui_event_handler_ptr handler);
+void rtgui_menu_set_onmenuhide(struct rtgui_menu* menu, rtgui_event_handler_ptr handler);
+
+void rtgui_menu_pop(struct rtgui_menu* menu, int x, int y);
+void rtgui_menu_hiden(struct rtgui_menu* menu);
+
+#endif
+

+ 49 - 53
components/rtgui/include/rtgui/widgets/notebook.h

@@ -1,53 +1,49 @@
-#ifndef __RTGUI_NOTEBOOK_H__
-#define __RTGUI_NOTEBOOK_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/widgets/container.h>
-
-DECLARE_CLASS_TYPE(notebook);
-/** Gets the type of a notebook */
-#define RTGUI_NOTEBOOK_TYPE       (RTGUI_TYPE(notebook))
-/** Casts the object to a notebook control */
-#define RTGUI_NOTEBOOK(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_NOTEBOOK_TYPE, rtgui_notebook_t))
-/** Checks if the object is a notebook control */
-#define RTGUI_IS_NOTEBOOK(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_NOTEBOOK_TYPE))
-
-#define RTGUI_NOTEBOOK_TOP			0x00
-#define RTGUI_NOTEBOOK_BOTTOM		0x01
-#define RTGUI_NOTEBOOK_NOTAB		0x02
-
-struct rtgui_notebook_tab
-{
-	char* title;
-	struct rtgui_widget* widget;
-};
-typedef struct rtgui_notebook_tab rtgui_notebook_tab_t;
-
-struct rtgui_notebook
-{
-	struct rtgui_container parent;
-
-	rt_uint8_t flag;
-
-	/* widget private data */
-	rtgui_notebook_tab_t* childs;
-	rt_uint16_t count;
-	rt_int16_t current;
-};
-typedef struct rtgui_notebook rtgui_notebook_t;
-
-rtgui_type_t *rtgui_notebook_type_get(void);
-
-rtgui_notebook_t* rtgui_notebook_create(const rtgui_rect_t* rect, rt_uint8_t style);
-void rtgui_notebook_destroy(rtgui_notebook_t* notebook);
-
-void rtgui_notebook_add(rtgui_notebook_t* notebook, const char* label, rtgui_widget_t* child);
-int rtgui_notebook_get_count(rtgui_notebook_t* notebook);
-rtgui_widget_t* rtgui_notebook_get_current(rtgui_notebook_t* notebook);
-void rtgui_notebook_set_current(rtgui_notebook_t* notebook, rtgui_widget_t* widget);
-void rtgui_notebook_set_current_by_index(rtgui_notebook_t* notebook, rt_uint16_t index);
-rtgui_widget_t* rtgui_notebook_get_index(rtgui_notebook_t* notebook, rt_uint16_t index);
-
-rt_bool_t rtgui_notebook_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-#endif
+#ifndef __RTGUI_NOTEBOOK_H__
+#define __RTGUI_NOTEBOOK_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+
+DECLARE_CLASS_TYPE(notebook);
+/** Gets the type of a notebook */
+#define RTGUI_NOTEBOOK_TYPE       (RTGUI_TYPE(notebook))
+/** Casts the object to a notebook control */
+#define RTGUI_NOTEBOOK(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_NOTEBOOK_TYPE, struct rtgui_notebook))
+/** Checks if the object is a notebook control */
+#define RTGUI_IS_NOTEBOOK(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_NOTEBOOK_TYPE))
+
+#define RTGUI_NOTEBOOK_TOP			0x00
+#define RTGUI_NOTEBOOK_BOTTOM		0x01
+#define RTGUI_NOTEBOOK_NOTAB		0x02
+
+struct rtgui_notebook_tab;
+
+struct rtgui_notebook
+{
+	struct rtgui_widget parent;
+
+	rt_uint8_t flag;
+
+	/* widget private data */
+	struct rtgui_notebook_tab *childs;
+	rt_uint16_t count;
+	rt_int16_t current;
+};
+
+struct rtgui_notebook* rtgui_notebook_create(const rtgui_rect_t* rect, rt_uint8_t style);
+void rtgui_notebook_destroy(struct rtgui_notebook* notebook);
+
+void rtgui_notebook_add(struct rtgui_notebook* notebook, const char* label, struct rtgui_widget* child);
+struct rtgui_widget* rtgui_notebook_get_current(struct rtgui_notebook* notebook);
+rt_int16_t rtgui_notebook_get_current_index(struct rtgui_notebook* notebook);
+
+int rtgui_notebook_get_count(struct rtgui_notebook* notebook);
+
+void rtgui_notebook_set_current(struct rtgui_notebook* notebook, struct rtgui_widget* child);
+void rtgui_notebook_set_current_by_index(struct rtgui_notebook* notebook, rt_uint16_t index);
+
+struct rtgui_widget* rtgui_notebook_get_widget_at(struct rtgui_notebook* notebook, rt_uint16_t index);
+
+rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* widget, struct rtgui_event* event);
+
+#endif

+ 40 - 40
components/rtgui/include/rtgui/widgets/progressbar.h

@@ -1,40 +1,40 @@
-#ifndef __RTGUI_PROGRESSBAR_H__
-#define __RTGUI_PROGRESSBAR_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/widgets/widget.h>
-
-DECLARE_CLASS_TYPE(progressbar);
-/** Gets the type of a progressbar */
-#define RTGUI_PROGRESSBAR_TYPE       (RTGUI_TYPE(progressbar))
-/** Casts the object to a rtgui_progressbar */
-#define RTGUI_PROGRESSBAR(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_PROGRESSBAR_TYPE, rtgui_progressbar_t))
-/** Checks if the object is a rtgui_progressbar */
-#define RTGUI_IS_PROGRESSBAR(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_PROGRESSBAR_TYPE))
-
-#define DEFAULT_WIDTH           100
-#define DEFAULT_HEIGHT          20
-
-struct rtgui_progressbar
-{
-	struct rtgui_widget parent;
-
-	int orient;
-
-    int range;
-    int position;
-};
-typedef struct rtgui_progressbar rtgui_progressbar_t;
-
-struct rtgui_progressbar* rtgui_progressbar_create(int orientation, int range, rtgui_rect_t* r);
-void rtgui_progressbar_destroy(struct rtgui_progressbar* p_bar);
-
-rt_bool_t rtgui_progressbar_event_handler(struct rtgui_widget* widget,
-                                            struct rtgui_event* event);
-
-void rtgui_progressbar_set_value(struct rtgui_progressbar *p_bar, int value);
-int rtgui_progressbar_get_value(struct rtgui_progressbar *p_bar);
-void rtgui_progressbar_set_range(struct rtgui_progressbar *p_bar, int range);
-int rtgui_progressbar_get_range(struct rtgui_progressbar *p_bar);
-
-#endif
+#ifndef __RTGUI_PROGRESSBAR_H__
+#define __RTGUI_PROGRESSBAR_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+
+DECLARE_CLASS_TYPE(progressbar);
+/** Gets the type of a progressbar */
+#define RTGUI_PROGRESSBAR_TYPE       (RTGUI_TYPE(progressbar))
+/** Casts the object to a rtgui_progressbar */
+#define RTGUI_PROGRESSBAR(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_PROGRESSBAR_TYPE, rtgui_progressbar_t))
+/** Checks if the object is a rtgui_progressbar */
+#define RTGUI_IS_PROGRESSBAR(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_PROGRESSBAR_TYPE))
+
+#define DEFAULT_WIDTH           100
+#define DEFAULT_HEIGHT          20
+
+struct rtgui_progressbar
+{
+	struct rtgui_widget parent;
+
+	int orient;
+
+    int range;
+    int position;
+};
+typedef struct rtgui_progressbar rtgui_progressbar_t;
+
+struct rtgui_progressbar* rtgui_progressbar_create(int orientation, int range, rtgui_rect_t* r);
+void rtgui_progressbar_destroy(struct rtgui_progressbar* p_bar);
+
+rt_bool_t rtgui_progressbar_event_handler(struct rtgui_object* object,
+                                            struct rtgui_event* event);
+
+void rtgui_progressbar_set_value(struct rtgui_progressbar *p_bar, int value);
+int rtgui_progressbar_get_value(struct rtgui_progressbar *p_bar);
+void rtgui_progressbar_set_range(struct rtgui_progressbar *p_bar, int range);
+int rtgui_progressbar_get_range(struct rtgui_progressbar *p_bar);
+
+#endif

+ 45 - 45
components/rtgui/include/rtgui/widgets/radiobox.h

@@ -1,45 +1,45 @@
-#ifndef __RTGUI_RADIOBOX_H__
-#define __RTGUI_RADIOBOX_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/widgets/widget.h>
-
-DECLARE_CLASS_TYPE(radiobox);
-/** Gets the type of a radiobox */
-#define RTGUI_RADIOBOX_TYPE       (RTGUI_TYPE(radiobox))
-/** Casts the object to an rtgui_radiobox */
-#define RTGUI_RADIOBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_RADIOBOX_TYPE, rtgui_radiobox_t))
-/** Checks if the object is an rtgui_radiobox */
-#define RTGUI_IS_RADIOBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_RADIOBOX_TYPE))
-
-struct rtgui_radiobox
-{
-	struct rtgui_widget parent;
-
-	/* widget private data */
-	char* text; /* radio box label */
-
-	/* box orient */
-	rt_uint8_t orient;
-
-	/* item size */
-	rt_uint8_t item_size;
-
-	char** items;
-	rt_uint16_t item_count;
-	rt_int16_t  item_selection;
-};
-typedef struct rtgui_radiobox rtgui_radiobox_t;
-
-struct rtgui_radiobox* rtgui_radiobox_create(const char* label, int orient, char** radio_items, int number);
-void rtgui_radiobox_destroy(struct rtgui_radiobox* radiobox);
-
-void rtgui_radiobox_set_selection(struct rtgui_radiobox* radiobox, int selection);
-int rtgui_radiobox_get_selection(struct rtgui_radiobox* radiobox);
-
-rt_bool_t rtgui_radiobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-void rtgui_radiobox_set_orientation(struct rtgui_radiobox* radiobox, int orientation);
-
-#endif
-
+#ifndef __RTGUI_RADIOBOX_H__
+#define __RTGUI_RADIOBOX_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+
+DECLARE_CLASS_TYPE(radiobox);
+/** Gets the type of a radiobox */
+#define RTGUI_RADIOBOX_TYPE       (RTGUI_TYPE(radiobox))
+/** Casts the object to an rtgui_radiobox */
+#define RTGUI_RADIOBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_RADIOBOX_TYPE, rtgui_radiobox_t))
+/** Checks if the object is an rtgui_radiobox */
+#define RTGUI_IS_RADIOBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_RADIOBOX_TYPE))
+
+struct rtgui_radiobox
+{
+	struct rtgui_widget parent;
+
+	/* widget private data */
+	char* text; /* radio box label */
+
+	/* box orient */
+	rt_uint8_t orient;
+
+	/* item size */
+	rt_uint8_t item_size;
+
+	char** items;
+	rt_uint16_t item_count;
+	rt_int16_t  item_selection;
+};
+typedef struct rtgui_radiobox rtgui_radiobox_t;
+
+struct rtgui_radiobox* rtgui_radiobox_create(const char* label, int orient, char** radio_items, int number);
+void rtgui_radiobox_destroy(struct rtgui_radiobox* radiobox);
+
+void rtgui_radiobox_set_selection(struct rtgui_radiobox* radiobox, int selection);
+int rtgui_radiobox_get_selection(struct rtgui_radiobox* radiobox);
+
+rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+
+void rtgui_radiobox_set_orientation(struct rtgui_radiobox* radiobox, int orientation);
+
+#endif
+

+ 89 - 89
components/rtgui/include/rtgui/widgets/scrollbar.h

@@ -1,89 +1,89 @@
-/*
- * File      : scrollbar.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-08-09     Bernard      first version
- */
-#ifndef __RTGUI_SCROLLBAR_H__
-#define __RTGUI_SCROLLBAR_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/widgets/widget.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-DECLARE_CLASS_TYPE(scrollbar);
-/** Gets the type of a scrollbar */
-#define RTGUI_SCROLLBAR_TYPE       (RTGUI_TYPE(scrollbar))
-/** Casts the object to an rtgui_scrollbar */
-#define RTGUI_SCROLLBAR(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_SCROLLBAR_TYPE, rtgui_scrollbar_t))
-/** Checks if the object is an rtgui_scrollbar */
-#define RTGUI_IS_SCROLLBAR(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_SCROLLBAR_TYPE))
-
-#define RTGUI_DEFAULT_SB_WIDTH				100
-#define RTGUI_DEFAULT_SB_HEIGHT				16
-
-/* scrollbar status/positions*/
-#define SBS_UNKNOWN         0x0000
-#define SBS_LEFTARROW       0x0001
-#define SBS_RIGHTARROW      0x0002
-#define SBS_LEFTSPACE       0x0004
-#define SBS_RIGHTSPACE      0x0008
-#define SBS_HORZTHUMB       0x0010
-#define SBS_UPARROW         0x0020
-#define SBS_DOWNARROW       0x0040
-#define SBS_UPSPACE         0x0080
-#define SBS_DOWNSPACE       0x0100
-#define SBS_VERTTHUMB       0x0200
-
-struct rtgui_scrollbar
-{
-	/* inherit from widget */
-	struct rtgui_widget parent;
-
-	rt_uint8_t orient;
-	rt_uint8_t status;
-
-	/* page_step = width of scrollbar */
-	/* thumb size = line_step * page_step / (page_step - (button width * 2)) */
-	rt_int16_t line_step, page_step;
-
-	rt_int16_t thumb_position, thumb_size;
-
-	/* position 1:1 width of scrollbar */
-	rt_int16_t min_position, max_position;
-
-	rt_bool_t (*on_scroll) (struct rtgui_widget* widget, struct rtgui_event* event);
-};
-typedef struct rtgui_scrollbar rtgui_scrollbar_t;
-
-struct rtgui_scrollbar* rtgui_scrollbar_create(int orient, rtgui_rect_t* r);
-void rtgui_scrollbar_destroy(struct rtgui_scrollbar* bar);
-
-void rtgui_scrollbar_get_thumb_rect(rtgui_scrollbar_t *bar, rtgui_rect_t *rect);
-
-void rtgui_scrollbar_set_range(struct rtgui_scrollbar* bar, int min, int max);
-rt_int16_t rtgui_scrollbar_get_value(struct rtgui_scrollbar* bar);
-void rtgui_scrollbar_set_value(struct rtgui_scrollbar* bar, rt_int16_t position);
-
-void rtgui_scrollbar_set_onscroll(struct rtgui_scrollbar* bar, rtgui_event_handler_ptr handler);
-void rtgui_scrollbar_set_orientation(struct rtgui_scrollbar* bar, int orientation);
-void rtgui_scrollbar_set_page_step(struct rtgui_scrollbar* bar, int step);
-void rtgui_scrollbar_set_line_step(struct rtgui_scrollbar* bar, int step);
-
-rt_bool_t rtgui_scrollbar_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * File      : scrollbar.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-08-09     Bernard      first version
+ */
+#ifndef __RTGUI_SCROLLBAR_H__
+#define __RTGUI_SCROLLBAR_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+DECLARE_CLASS_TYPE(scrollbar);
+/** Gets the type of a scrollbar */
+#define RTGUI_SCROLLBAR_TYPE       (RTGUI_TYPE(scrollbar))
+/** Casts the object to an rtgui_scrollbar */
+#define RTGUI_SCROLLBAR(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_SCROLLBAR_TYPE, rtgui_scrollbar_t))
+/** Checks if the object is an rtgui_scrollbar */
+#define RTGUI_IS_SCROLLBAR(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_SCROLLBAR_TYPE))
+
+#define RTGUI_DEFAULT_SB_WIDTH				100
+#define RTGUI_DEFAULT_SB_HEIGHT				16
+
+/* scrollbar status/positions*/
+#define SBS_UNKNOWN         0x0000
+#define SBS_LEFTARROW       0x0001
+#define SBS_RIGHTARROW      0x0002
+#define SBS_LEFTSPACE       0x0004
+#define SBS_RIGHTSPACE      0x0008
+#define SBS_HORZTHUMB       0x0010
+#define SBS_UPARROW         0x0020
+#define SBS_DOWNARROW       0x0040
+#define SBS_UPSPACE         0x0080
+#define SBS_DOWNSPACE       0x0100
+#define SBS_VERTTHUMB       0x0200
+
+struct rtgui_scrollbar
+{
+	/* inherit from widget */
+	struct rtgui_widget parent;
+
+	rt_uint8_t orient;
+	rt_uint8_t status;
+
+	/* page_step = width of scrollbar */
+	/* thumb size = line_step * page_step / (page_step - (button width * 2)) */
+	rt_int16_t line_step, page_step;
+
+	rt_int16_t thumb_position, thumb_size;
+
+	/* position 1:1 width of scrollbar */
+	rt_int16_t min_position, max_position;
+
+	rtgui_event_handler_ptr on_scroll;
+};
+typedef struct rtgui_scrollbar rtgui_scrollbar_t;
+
+struct rtgui_scrollbar* rtgui_scrollbar_create(int orient, rtgui_rect_t* r);
+void rtgui_scrollbar_destroy(struct rtgui_scrollbar* bar);
+
+void rtgui_scrollbar_get_thumb_rect(rtgui_scrollbar_t *bar, rtgui_rect_t *rect);
+
+void rtgui_scrollbar_set_range(struct rtgui_scrollbar* bar, int min, int max);
+rt_int16_t rtgui_scrollbar_get_value(struct rtgui_scrollbar* bar);
+void rtgui_scrollbar_set_value(struct rtgui_scrollbar* bar, rt_int16_t position);
+
+void rtgui_scrollbar_set_onscroll(struct rtgui_scrollbar* bar, rtgui_event_handler_ptr handler);
+void rtgui_scrollbar_set_orientation(struct rtgui_scrollbar* bar, int orientation);
+void rtgui_scrollbar_set_page_step(struct rtgui_scrollbar* bar, int step);
+void rtgui_scrollbar_set_line_step(struct rtgui_scrollbar* bar, int step);
+
+rt_bool_t rtgui_scrollbar_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 53 - 53
components/rtgui/include/rtgui/widgets/slider.h

@@ -1,53 +1,53 @@
-/*
- * File      : slider.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_SLIDER_H__
-#define __RTGUI_SLIDER_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/widgets/widget.h>
-
-DECLARE_CLASS_TYPE(slider);
-/** Gets the type of a slider */
-#define RTGUI_SLIDER_TYPE       (RTGUI_TYPE(slider))
-/** Casts the object to an rtgui_slider */
-#define RTGUI_SLIDER(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_SLIDER_TYPE, rtgui_slider_t))
-/** Checks if the object is an rtgui_slider */
-#define RTGUI_IS_SLIDER(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_SLIDER_TYPE))
-
-struct rtgui_slider
-{
-	struct rtgui_widget parent;
-
-	/* widget private data */
-	rt_size_t min, max, value, ticks;
-	rt_size_t thumb_width;
-
-	int orient;
-
-	void (*on_changed)(struct rtgui_widget* widget, struct rtgui_event *event);
-};
-typedef struct rtgui_slider rtgui_slider_t;
-
-struct rtgui_slider* rtgui_slider_create(rt_size_t min, rt_size_t max, int orient);
-void rtgui_slider_destroy(struct rtgui_slider* slider);
-
-rt_bool_t rtgui_slider_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-void rtgui_slider_set_range(struct rtgui_slider* slider, rt_size_t min, rt_size_t max);
-void rtgui_slider_set_value(struct rtgui_slider* slider, rt_size_t value);
-void rtgui_slider_set_orientation(struct rtgui_slider* slider, int orientation);
-
-rt_size_t rtgui_slider_get_value(struct rtgui_slider* slider);
-
-#endif
+/*
+ * File      : slider.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_SLIDER_H__
+#define __RTGUI_SLIDER_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+
+DECLARE_CLASS_TYPE(slider);
+/** Gets the type of a slider */
+#define RTGUI_SLIDER_TYPE       (RTGUI_TYPE(slider))
+/** Casts the object to an rtgui_slider */
+#define RTGUI_SLIDER(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_SLIDER_TYPE, rtgui_slider_t))
+/** Checks if the object is an rtgui_slider */
+#define RTGUI_IS_SLIDER(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_SLIDER_TYPE))
+
+struct rtgui_slider
+{
+	struct rtgui_widget parent;
+
+	/* widget private data */
+	rt_size_t min, max, value, ticks;
+	rt_size_t thumb_width;
+
+	int orient;
+
+	void (*on_changed)(struct rtgui_widget* widget, struct rtgui_event *event);
+};
+typedef struct rtgui_slider rtgui_slider_t;
+
+struct rtgui_slider* rtgui_slider_create(rt_size_t min, rt_size_t max, int orient);
+void rtgui_slider_destroy(struct rtgui_slider* slider);
+
+rt_bool_t rtgui_slider_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+
+void rtgui_slider_set_range(struct rtgui_slider* slider, rt_size_t min, rt_size_t max);
+void rtgui_slider_set_value(struct rtgui_slider* slider, rt_size_t value);
+void rtgui_slider_set_orientation(struct rtgui_slider* slider, int orientation);
+
+rt_size_t rtgui_slider_get_value(struct rtgui_slider* slider);
+
+#endif

+ 35 - 35
components/rtgui/include/rtgui/widgets/staticline.h

@@ -1,35 +1,35 @@
-#ifndef __RTGUI_STATICLINE__H__
-#define __RTGUI_STATICLINE__H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/widgets/widget.h>
-
-/*
- * the static line widget
- */
-
-DECLARE_CLASS_TYPE(staticline);
-/** Gets the type of a staticline */
-#define RTGUI_STATICLINE_TYPE       (RTGUI_TYPE(staticline))
-/** Casts the object to an rtgui_staticline */
-#define RTGUI_STATICLINE(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_STATICLINE_TYPE, rtgui_staticline_t))
-/** Checks if the object is an rtgui_staticline */
-#define RTGUI_IS_STATICLINE(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_STATICLINE_TYPE))
-
-struct rtgui_staticline
-{
-	/* inherit from widget */
-	struct rtgui_widget parent;
-
-	int orient;
-};
-typedef struct rtgui_staticline rtgui_staticline_t;
-
-rtgui_staticline_t *rtgui_staticline_create(int orientation);
-void rtgui_staticline_destroy(rtgui_staticline_t* staticline);
-
-rt_bool_t rtgui_staticline_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-void rtgui_staticline_set_orientation(rtgui_staticline_t* staticline, int orientation);
-
-#endif
-
+#ifndef __RTGUI_STATICLINE__H__
+#define __RTGUI_STATICLINE__H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+
+/*
+ * the static line widget
+ */
+
+DECLARE_CLASS_TYPE(staticline);
+/** Gets the type of a staticline */
+#define RTGUI_STATICLINE_TYPE       (RTGUI_TYPE(staticline))
+/** Casts the object to an rtgui_staticline */
+#define RTGUI_STATICLINE(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_STATICLINE_TYPE, rtgui_staticline_t))
+/** Checks if the object is an rtgui_staticline */
+#define RTGUI_IS_STATICLINE(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_STATICLINE_TYPE))
+
+struct rtgui_staticline
+{
+	/* inherit from widget */
+	struct rtgui_widget parent;
+
+	int orient;
+};
+typedef struct rtgui_staticline rtgui_staticline_t;
+
+rtgui_staticline_t *rtgui_staticline_create(int orientation);
+void rtgui_staticline_destroy(rtgui_staticline_t* staticline);
+
+rt_bool_t rtgui_staticline_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+void rtgui_staticline_set_orientation(rtgui_staticline_t* staticline, int orientation);
+
+#endif
+

+ 75 - 75
components/rtgui/include/rtgui/widgets/textbox.h

@@ -1,75 +1,75 @@
-/*
- * File      : textbox.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_TEXTBOX_H__
-#define __RTGUI_TEXTBOX_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/widgets/widget.h>
-
-DECLARE_CLASS_TYPE(textbox);
-/** Gets the type of a textbox */
-#define RTGUI_TEXTBOX_TYPE       (RTGUI_TYPE(textbox))
-/** Casts the object to a rtgui_textbox */
-#define RTGUI_TEXTBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_TEXTBOX_TYPE, rtgui_textbox_t))
-/** Checks if the object is a rtgui_textbox */
-#define RTGUI_IS_TEXTBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_TEXTBOX_TYPE))
-
-#define RTGUI_TEXTBOX_DEFAULT_WIDTH		80
-#define RTGUI_TEXTBOX_DEFAULT_HEIGHT	20
-
-#define RTGUI_TEXTBOX_SINGLE			0x00
-#define RTGUI_TEXTBOX_MULTI				0x01
-#define RTGUI_TEXTBOX_MASK				0x02
-#define RTGUI_TEXTBOX_CARET_SHOW		0x10
-#define RTGUI_TEXTBOX_CARET_HIDE		0x00
-
-struct rtgui_textbox_line
-{
-	char* line_text;
-
-	struct rtgui_textbox_line *prev, *next;
-};
-
-struct rtgui_textbox
-{
-	/* inherit from widget */
-	struct rtgui_widget parent;
-
-	/* text box flag */
-	rt_uint8_t flag;
-
-	/* current line and position */
-	rt_uint16_t line, line_begin, position, line_length;
-
-	char* text;
-	rt_size_t font_width;
-
-	struct rtgui_timer* caret_timer;
-
-	/* widget private data */
-	rt_bool_t (*on_enter) 	(struct rtgui_widget* widget, struct rtgui_event* event);
-};
-typedef struct rtgui_textbox rtgui_textbox_t;
-
-struct rtgui_textbox* rtgui_textbox_create(const char* text, rt_uint8_t flag);
-void rtgui_textbox_destroy(struct rtgui_textbox* box);
-
-rt_bool_t rtgui_textbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-void rtgui_textbox_set_value(struct rtgui_textbox* box, const char* text);
-const char* rtgui_textbox_get_value(struct rtgui_textbox* box);
-
-void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length);
-
-#endif
+/*
+ * File      : textbox.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_TEXTBOX_H__
+#define __RTGUI_TEXTBOX_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+
+DECLARE_CLASS_TYPE(textbox);
+/** Gets the type of a textbox */
+#define RTGUI_TEXTBOX_TYPE       (RTGUI_TYPE(textbox))
+/** Casts the object to a rtgui_textbox */
+#define RTGUI_TEXTBOX(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_TEXTBOX_TYPE, rtgui_textbox_t))
+/** Checks if the object is a rtgui_textbox */
+#define RTGUI_IS_TEXTBOX(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_TEXTBOX_TYPE))
+
+#define RTGUI_TEXTBOX_DEFAULT_WIDTH		80
+#define RTGUI_TEXTBOX_DEFAULT_HEIGHT	20
+
+#define RTGUI_TEXTBOX_SINGLE			0x00
+#define RTGUI_TEXTBOX_MULTI				0x01
+#define RTGUI_TEXTBOX_MASK				0x02
+#define RTGUI_TEXTBOX_CARET_SHOW		0x10
+#define RTGUI_TEXTBOX_CARET_HIDE		0x00
+
+struct rtgui_textbox_line
+{
+	char* line_text;
+
+	struct rtgui_textbox_line *prev, *next;
+};
+
+struct rtgui_textbox
+{
+	/* inherit from widget */
+	struct rtgui_widget parent;
+
+	/* text box flag */
+	rt_uint8_t flag;
+
+	/* current line and position */
+	rt_uint16_t line, line_begin, position, line_length;
+
+	char* text;
+	rt_size_t font_width;
+
+	struct rtgui_timer* caret_timer;
+
+	/* widget private data */
+	rt_bool_t (*on_enter) 	(struct rtgui_widget* widget, struct rtgui_event* event);
+};
+typedef struct rtgui_textbox rtgui_textbox_t;
+
+struct rtgui_textbox* rtgui_textbox_create(const char* text, rt_uint8_t flag);
+void rtgui_textbox_destroy(struct rtgui_textbox* box);
+
+rt_bool_t rtgui_textbox_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+
+void rtgui_textbox_set_value(struct rtgui_textbox* box, const char* text);
+const char* rtgui_textbox_get_value(struct rtgui_textbox* box);
+
+void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length);
+
+#endif

+ 67 - 67
components/rtgui/include/rtgui/widgets/textview.h

@@ -1,67 +1,67 @@
-/*
- * File      : textview.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2011-03-05     Bernard      first version
- */
-#ifndef __RTGUI_TEXTVIEW_H__
-#define __RTGUI_TEXTVIEW_H__
-
-#include <rtgui/widgets/widget.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @defgroup rtgui_textview
- * @{
- */
-
-DECLARE_CLASS_TYPE(textview);
-
-/** Gets the type of a textview */
-#define RTGUI_TEXTVIEW_TYPE       (RTGUI_TYPE(textview))
-/** Casts the object to an rtgui_textview */
-#define RTGUI_TEXTVIEW(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_TEXTVIEW_TYPE, rtgui_textview_t))
-/** Checks if the object is an rtgui_textview */
-#define RTGUI_IS_TEXTVIEW(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_TEXTVIEW_TYPE))
-
-/*
- * the textview widget
- */
-struct rtgui_textview
-{
-	/* inherit from widget */
-	struct rtgui_widget parent;
-
-	rt_uint16_t line_width;
-	rt_uint16_t line_count;
-
-	char* lines;
-
-	rt_int16_t line_current;
-	rt_uint16_t line_page_count;
-};
-typedef struct rtgui_textview rtgui_textview_t;
-
-rtgui_textview_t* rtgui_textview_create(const char* text, const rtgui_rect_t *rect);
-void rtgui_textview_destroy(rtgui_textview_t* textview);
-
-rt_bool_t rtgui_textview_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-void rtgui_textview_set_text(rtgui_textview_t* textview, const char* text);
-
-/** @} */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * File      : textview.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-03-05     Bernard      first version
+ */
+#ifndef __RTGUI_TEXTVIEW_H__
+#define __RTGUI_TEXTVIEW_H__
+
+#include <rtgui/widgets/widget.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup rtgui_textview
+ * @{
+ */
+
+DECLARE_CLASS_TYPE(textview);
+
+/** Gets the type of a textview */
+#define RTGUI_TEXTVIEW_TYPE       (RTGUI_TYPE(textview))
+/** Casts the object to an rtgui_textview */
+#define RTGUI_TEXTVIEW(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_TEXTVIEW_TYPE, rtgui_textview_t))
+/** Checks if the object is an rtgui_textview */
+#define RTGUI_IS_TEXTVIEW(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_TEXTVIEW_TYPE))
+
+/*
+ * the textview widget
+ */
+struct rtgui_textview
+{
+	/* inherit from widget */
+	struct rtgui_widget parent;
+
+	rt_uint16_t line_width;
+	rt_uint16_t line_count;
+
+	char* lines;
+
+	rt_int16_t line_current;
+	rt_uint16_t line_page_count;
+};
+typedef struct rtgui_textview rtgui_textview_t;
+
+rtgui_textview_t* rtgui_textview_create(const char* text, const rtgui_rect_t *rect);
+void rtgui_textview_destroy(rtgui_textview_t* textview);
+
+rt_bool_t rtgui_textview_event_handler(struct rtgui_object* object, struct rtgui_event* event);
+void rtgui_textview_set_text(rtgui_textview_t* textview, const char* text);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 44 - 44
components/rtgui/include/rtgui/widgets/title.h

@@ -1,44 +1,44 @@
-/*
- * File      : title.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_TITLE__
-#define __RTGUI_TITLE__
-
-#include <rtgui/widgets/toplevel.h>
-
-DECLARE_CLASS_TYPE(wintitle);
-/** Gets the type of a title */
-#define RTGUI_WINTITLE_TYPE       (RTGUI_TYPE(wintitle))
-/** Casts the object to an rtgui_wintitle */
-#define RTGUI_WINTITLE(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_WINTITLE_TYPE, rtgui_wintitle_t))
-/** Checks if the object is an rtgui_wintitle */
-#define RTGUI_IS_WINTITLE(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_WINTITLE_TYPE))
-
-struct rtgui_wintitle
-{
-	struct rtgui_toplevel parent;
-
-	/* title */
-	char* title;
-};
-typedef struct rtgui_wintitle rtgui_wintitle_t;
-
-rtgui_wintitle_t* rtgui_wintitle_create(const char* title);
-void rtgui_wintitle_destroy(rtgui_wintitle_t* wintitle);
-
-rt_bool_t rtgui_wintile_event_handler(rtgui_widget_t* widget, rtgui_event_t* event);
-
-void rtgui_wintitle_set_title(rtgui_wintitle_t* wintitle, const char* title);
-char *rtgui_wintitle_get_title(rtgui_wintitle_t* wintitle);
-
-#endif
+/*
+ * File      : title.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_TITLE__
+#define __RTGUI_TITLE__
+
+#include <rtgui/widgets/toplevel.h>
+
+DECLARE_CLASS_TYPE(wintitle);
+/** Gets the type of a title */
+#define RTGUI_WINTITLE_TYPE       (RTGUI_TYPE(wintitle))
+/** Casts the object to an rtgui_wintitle */
+#define RTGUI_WINTITLE(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_WINTITLE_TYPE, rtgui_wintitle_t))
+/** Checks if the object is an rtgui_wintitle */
+#define RTGUI_IS_WINTITLE(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_WINTITLE_TYPE))
+
+struct rtgui_wintitle
+{
+	struct rtgui_toplevel parent;
+
+	/* title */
+	char* title;
+};
+typedef struct rtgui_wintitle rtgui_wintitle_t;
+
+rtgui_wintitle_t* rtgui_wintitle_create(const char* title);
+void rtgui_wintitle_destroy(rtgui_wintitle_t* wintitle);
+
+rt_bool_t rtgui_wintile_event_handler(rtgui_widget_t* widget, rtgui_event_t* event);
+
+void rtgui_wintitle_set_title(rtgui_wintitle_t* wintitle, const char* title);
+char *rtgui_wintitle_get_title(rtgui_wintitle_t* wintitle);
+
+#endif

+ 44 - 53
components/rtgui/include/rtgui/widgets/toplevel.h

@@ -1,53 +1,44 @@
-/*
- * File      : toplevel.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_TOPLEVEL_H__
-#define __RTGUI_TOPLEVEL_H__
-
-#include <rtgui/widgets/container.h>
-
-DECLARE_CLASS_TYPE(toplevel);
-/** Gets the type of a toplevel */
-#define RTGUI_TOPLEVEL_TYPE       (RTGUI_TYPE(toplevel))
-/** Casts the object to an rtgui_toplevel */
-#define RTGUI_TOPLEVEL(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_TOPLEVEL_TYPE, rtgui_toplevel_t))
-/** Checks if the object is an rtgui_toplevel */
-#define RTGUI_IS_TOPLEVEL(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_TOPLEVEL_TYPE))
-
-/* last mouse event handled widget */
-#define RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(obj)	(RTGUI_TOPLEVEL(obj)->last_mevent_widget)
-
-struct rtgui_toplevel
-{
-	/* inherit from container */
-	rtgui_container_t parent;
-
-	/* drawing count */
-	rt_base_t drawing;
-
-	/* external clip info */
-	rtgui_rect_t*	external_clip_rect;
-	rt_uint32_t		external_clip_size;
-
-	/* server thread id */
-	rt_thread_t server;
-
-	/* last mouse event handled widget */
-	rtgui_widget_t* last_mevent_widget;
-};
-typedef struct rtgui_toplevel rtgui_toplevel_t;
-
-rt_bool_t rtgui_toplevel_event_handler(rtgui_widget_t* widget, rtgui_event_t* event);
-void rtgui_toplevel_update_clip(rtgui_toplevel_t* top);
-
-#endif
+/*
+ * File      : toplevel.h
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ */
+#ifndef __RTGUI_TOPLEVEL_H__
+#define __RTGUI_TOPLEVEL_H__
+
+#include <rtgui/widgets/container.h>
+
+DECLARE_CLASS_TYPE(toplevel);
+/** Gets the type of a toplevel */
+#define RTGUI_TOPLEVEL_TYPE       (RTGUI_TYPE(toplevel))
+/** Casts the object to an rtgui_toplevel */
+#define RTGUI_TOPLEVEL(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_TOPLEVEL_TYPE, rtgui_toplevel_t))
+/** Checks if the object is an rtgui_toplevel */
+#define RTGUI_IS_TOPLEVEL(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_TOPLEVEL_TYPE))
+
+struct rtgui_toplevel
+{
+	/* inherit from view */
+	rtgui_container_t parent;
+
+	/* drawing count */
+	rt_base_t drawing;
+
+	/* external clip info */
+	rtgui_rect_t*	external_clip_rect;
+	rt_uint32_t		external_clip_size;
+};
+typedef struct rtgui_toplevel rtgui_toplevel_t;
+
+rt_bool_t rtgui_toplevel_event_handler(struct rtgui_object* widget, struct rtgui_event* event);
+void rtgui_toplevel_update_clip(rtgui_toplevel_t* top);
+
+#endif

+ 0 - 66
components/rtgui/include/rtgui/widgets/view.h

@@ -1,66 +0,0 @@
-/*
- * File      : view.h
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- */
-#ifndef __RTGUI_VIEW_H__
-#define __RTGUI_VIEW_H__
-
-#include <rtgui/widgets/box.h>
-#include <rtgui/widgets/container.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-DECLARE_CLASS_TYPE(view);
-/** Gets the type of a view */
-#define RTGUI_VIEW_TYPE       (RTGUI_TYPE(view))
-/** Casts the object to an rtgui_view */
-#define RTGUI_VIEW(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_VIEW_TYPE, rtgui_view_t))
-/** Checks if the object is an rtgui_view */
-#define RTGUI_IS_VIEW(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_VIEW_TYPE))
-
-/*
- * the view widget
- */
-struct rtgui_view
-{
-	/* inherit from container */
-	struct rtgui_container parent;
-
-	/* private field */
-	char* title;
-	rt_bool_t modal_show;
-};
-typedef struct rtgui_view rtgui_view_t;
-
-rtgui_view_t* rtgui_view_create(const char* title);
-void rtgui_view_destroy(rtgui_view_t* view);
-
-rt_bool_t rtgui_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
-
-#ifndef RTGUI_USING_SMALL_SIZE
-void rtgui_view_set_box(rtgui_view_t* view, rtgui_box_t* box);
-#endif
-
-rtgui_modal_code_t rtgui_view_show(rtgui_view_t* view, rt_bool_t is_modal);
-void rtgui_view_hide(rtgui_view_t* view);
-void rtgui_view_end_modal(rtgui_view_t* view, rtgui_modal_code_t modal_code);
-
-char* rtgui_view_get_title(rtgui_view_t* view);
-void rtgui_view_set_title(rtgui_view_t* view, const char* title);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 25 - 18
components/rtgui/include/rtgui/widgets/widget.h

@@ -76,8 +76,10 @@ struct rtgui_widget
    /* inherit from rtgui_object */
    /* inherit from rtgui_object */
 	struct rtgui_object object;
 	struct rtgui_object object;
 
 
-	/* the parent and root widget */
-	struct rtgui_widget *parent, *toplevel;
+	/* the widget that contains this widget */
+	struct rtgui_widget *parent;
+	/* the window that contains this widget */
+	struct rtgui_win *toplevel;
 	/* the widget children and sibling */
 	/* the widget children and sibling */
 	rtgui_list_t sibling;
 	rtgui_list_t sibling;
 
 
@@ -106,18 +108,25 @@ struct rtgui_widget
 	/* the rect clip */
 	/* the rect clip */
 	rtgui_region_t clip;
 	rtgui_region_t clip;
 
 
-	/* the event handler */
-	rt_bool_t (*event_handler)	(struct rtgui_widget* widget, struct rtgui_event* event);
-
 	/* call back */
 	/* call back */
-	rt_bool_t (*on_focus_in)	(struct rtgui_widget* widget, struct rtgui_event* event);
-	rt_bool_t (*on_focus_out)	(struct rtgui_widget* widget, struct rtgui_event* event);
+	rt_bool_t (*on_focus_in)	(struct rtgui_object* widget, struct rtgui_event* event);
+	rt_bool_t (*on_focus_out)	(struct rtgui_object* widget, struct rtgui_event* event);
+	/* will be called just before the widget is shown. You can setup your
+	 * widget in this call back. It's return value is ignored. The @param event
+	 * will always be RT_NULL
+	 */
+	rt_bool_t (*on_show)        (struct rtgui_object* widget, struct rtgui_event* event);
+	/* will be called just before the widget is hiden. You can setup your
+	 * widget in this call back. It's return value is ignored. The @param event
+	 * will always be RT_NULL
+	 */
+	rt_bool_t (*on_hide)        (struct rtgui_object* widget, struct rtgui_event* event);
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
-	rt_bool_t (*on_draw)		(struct rtgui_widget* widget, struct rtgui_event* event);
-	rt_bool_t (*on_mouseclick)	(struct rtgui_widget* widget, struct rtgui_event* event);
-	rt_bool_t (*on_key)			(struct rtgui_widget* widget, struct rtgui_event* event);
-	rt_bool_t (*on_size)		(struct rtgui_widget* widget, struct rtgui_event* event);
-	rt_bool_t (*on_command)		(struct rtgui_widget* widget, struct rtgui_event* event);
+	rt_bool_t (*on_draw)		(struct rtgui_object* widget, struct rtgui_event* event);
+	rt_bool_t (*on_mouseclick)	(struct rtgui_object* widget, struct rtgui_event* event);
+	rt_bool_t (*on_key)			(struct rtgui_object* widget, struct rtgui_event* event);
+	rt_bool_t (*on_size)		(struct rtgui_object* widget, struct rtgui_event* event);
+	rt_bool_t (*on_command)		(struct rtgui_object* widget, struct rtgui_event* event);
 #endif
 #endif
 
 
 	/* user private data */
 	/* user private data */
@@ -125,14 +134,10 @@ struct rtgui_widget
 };
 };
 typedef struct rtgui_widget rtgui_widget_t;
 typedef struct rtgui_widget rtgui_widget_t;
 
 
-rtgui_type_t *rtgui_widget_type_get(void);
 rtgui_widget_t *rtgui_widget_create(rtgui_type_t *widget_type);
 rtgui_widget_t *rtgui_widget_create(rtgui_type_t *widget_type);
 void rtgui_widget_destroy(rtgui_widget_t* widget);
 void rtgui_widget_destroy(rtgui_widget_t* widget);
 
 
-/* set the event handler of widget */
-void rtgui_widget_set_event_handler(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
-/* widget default event handler */
-rt_bool_t rtgui_widget_event_handler(rtgui_widget_t* widget, rtgui_event_t* event);
+rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* event);
 
 
 /* focus and unfocus */
 /* focus and unfocus */
 void rtgui_widget_focus(rtgui_widget_t * widget);
 void rtgui_widget_focus(rtgui_widget_t * widget);
@@ -141,6 +146,8 @@ void rtgui_widget_unfocus(rtgui_widget_t *widget);
 /* event handler for each command */
 /* event handler for each command */
 void rtgui_widget_set_onfocus(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
 void rtgui_widget_set_onfocus(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
 void rtgui_widget_set_onunfocus(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
 void rtgui_widget_set_onunfocus(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
+void rtgui_widget_set_onshow(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
+void rtgui_widget_set_onhide(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
 void rtgui_widget_set_ondraw(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
 void rtgui_widget_set_ondraw(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
 void rtgui_widget_set_onmouseclick(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
 void rtgui_widget_set_onmouseclick(rtgui_widget_t* widget, rtgui_event_handler_ptr handler);
@@ -179,7 +186,7 @@ void rtgui_widget_move_to_logic(rtgui_widget_t* widget, int dx, int dy);
 void rtgui_widget_update_clip(rtgui_widget_t* widget);
 void rtgui_widget_update_clip(rtgui_widget_t* widget);
 
 
 /* get the toplevel widget of widget */
 /* get the toplevel widget of widget */
-rtgui_widget_t* rtgui_widget_get_toplevel(rtgui_widget_t* widget);
+struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget);
 
 
 void rtgui_widget_show(rtgui_widget_t* widget);
 void rtgui_widget_show(rtgui_widget_t* widget);
 void rtgui_widget_hide(rtgui_widget_t* widget);
 void rtgui_widget_hide(rtgui_widget_t* widget);

+ 160 - 107
components/rtgui/include/rtgui/widgets/window.h

@@ -1,107 +1,160 @@
-/*
- * File      : window.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-04     Bernard      first version
- * 2010-05-03     Bernard      add win close function
- */
-#ifndef __RTGUI_WINDOW_H__
-#define __RTGUI_WINDOW_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/list.h>
-#include <rtgui/widgets/widget.h>
-#include <rtgui/widgets/toplevel.h>
-#include <rtgui/widgets/box.h>
-
-DECLARE_CLASS_TYPE(win);
-/** Gets the type of a win */
-#define RTGUI_WIN_TYPE       (RTGUI_TYPE(win))
-/** Casts the object to an rtgui_win */
-#define RTGUI_WIN(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_WIN_TYPE, rtgui_win_t))
-/** Checks if the object is an rtgui_win */
-#define RTGUI_IS_WIN(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_WIN_TYPE))
-
-#define RTGUI_WIN_STYLE_MODAL		0x001	/* modal mode window			*/
-#define RTGUI_WIN_STYLE_CLOSED		0x002	/* window is closed				*/
-#define RTGUI_WIN_STYLE_ACTIVATE	0x004	/* window is activated			*/
-#define RTGUI_WIN_STYLE_NO_FOCUS	0x008	/* non-focused window			*/
-
-#define RTGUI_WIN_STYLE_NO_TITLE	0x010	/* no title window				*/
-#define RTGUI_WIN_STYLE_NO_BORDER	0x020	/* no border window				*/
-#define RTGUI_WIN_STYLE_CLOSEBOX	0x040	/* window has the close button	*/
-#define RTGUI_WIN_STYLE_MINIBOX		0x080	/* window has the mini button	*/
-
-#define RTGUI_WIN_STYLE_UNDER_MODAL	0x100    /* window is under modal show (show 
-											 * sub-win as modal window) */
-
-#define RTGUI_WIN_STYLE_DEFAULT		(RTGUI_WIN_STYLE_CLOSEBOX | RTGUI_WIN_STYLE_MINIBOX)
-
-struct rtgui_win_title;
-struct rtgui_win_area;
-
-struct rtgui_win
-{
-	/* inherit from toplevel */
-	struct rtgui_toplevel parent;
-
-	/* parent toplevel */
-	rtgui_toplevel_t* parent_toplevel;
-
-	/* top window style */
-	rt_uint16_t style;
-
-	rtgui_modal_code_t modal_code;
-	rtgui_widget_t* modal_widget;
-
-	/* window title */
-	char* title;
-
-	/* call back */
-	rt_bool_t (*on_activate)	(struct rtgui_widget* widget, struct rtgui_event* event);
-	rt_bool_t (*on_deactivate)	(struct rtgui_widget* widget, struct rtgui_event* event);
-	rt_bool_t (*on_close)		(struct rtgui_widget* widget, struct rtgui_event* event);
-
-	/* reserved user data */
-	rt_uint32_t user_data;
-};
-
-rtgui_win_t* rtgui_win_create(rtgui_toplevel_t* parent_toplevel, const char* title, 
-	rtgui_rect_t *rect, rt_uint8_t flag);
-void rtgui_win_destroy(rtgui_win_t* win);
-void rtgui_win_close(struct rtgui_win* win);
-
-rtgui_modal_code_t rtgui_win_show(rtgui_win_t* win, rt_bool_t is_modal);
-void rtgui_win_hiden(rtgui_win_t* win);
-void rtgui_win_end_modal(rtgui_win_t* win, rtgui_modal_code_t modal_code);
-
-rt_bool_t rtgui_win_is_activated(struct rtgui_win* win);
-
-void rtgui_win_move(struct rtgui_win* win, int x, int y);
-
-/* reset extent of window */
-void rtgui_win_set_rect(rtgui_win_t* win, rtgui_rect_t* rect);
-
-#ifndef RTGUI_USING_SMALL_SIZE
-void rtgui_win_set_box(rtgui_win_t* win, rtgui_box_t* box);
-#endif
-
-void rtgui_win_set_onactivate(rtgui_win_t* win, rtgui_event_handler_ptr handler);
-void rtgui_win_set_ondeactivate(rtgui_win_t* win, rtgui_event_handler_ptr handler);
-void rtgui_win_set_onclose(rtgui_win_t* win, rtgui_event_handler_ptr handler);
-
-rt_bool_t rtgui_win_event_handler(rtgui_widget_t* win, struct rtgui_event* event);
-
-void rtgui_win_event_loop(rtgui_win_t* wnd);
-
-void rtgui_win_set_title(rtgui_win_t* win, const char *title);
-char* rtgui_win_get_title(rtgui_win_t* win);
-
-#endif
+/*
+ * File      : window.h
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-04     Bernard      first version
+ * 2010-05-03     Bernard      add win close function
+ */
+#ifndef __RTGUI_WINDOW_H__
+#define __RTGUI_WINDOW_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/list.h>
+#include <rtgui/widgets/widget.h>
+#include <rtgui/widgets/toplevel.h>
+#include <rtgui/widgets/box.h>
+
+DECLARE_CLASS_TYPE(win);
+/** Gets the type of a win */
+#define RTGUI_WIN_TYPE       (RTGUI_TYPE(win))
+/** Casts the object to an rtgui_win */
+#define RTGUI_WIN(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_WIN_TYPE, rtgui_win_t))
+/** Checks if the object is an rtgui_win */
+#define RTGUI_IS_WIN(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_WIN_TYPE))
+
+#define RTGUI_WIN_STYLE_NO_FOCUS	        0x001	/* non-focused window			*/
+
+#define RTGUI_WIN_STYLE_NO_TITLE	        0x002	/* no title window				*/
+#define RTGUI_WIN_STYLE_NO_BORDER	        0x004	/* no border window				*/
+#define RTGUI_WIN_STYLE_CLOSEBOX	        0x008	/* window has the close button	*/
+#define RTGUI_WIN_STYLE_MINIBOX		        0x010	/* window has the mini button	*/
+
+#define RTGUI_WIN_STYLE_DESTROY_ON_CLOSE	0x020   /* window is destroyed when closed */
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+/* A desktop window is a full screen window which will beneath all other windows.
+ * There will be only one desktop window in a system. And this window should be
+ * created _before_ any other windows.
+ */
+#define RTGUI_WIN_STYLE_DESKTOP		        0x8000
+#define RTGUI_WIN_STYLE_DESKTOP_DEFAULT     RTGUI_WIN_STYLE_DESKTOP |\
+                                            RTGUI_WIN_STYLE_NO_BORDER |\
+                                            RTGUI_WIN_STYLE_NO_TITLE
+#endif
+
+#define RTGUI_WIN_STYLE_DEFAULT		(RTGUI_WIN_STYLE_CLOSEBOX | RTGUI_WIN_STYLE_MINIBOX)
+
+enum rtgui_win_flag
+{
+	RTGUI_WIN_FLAG_INIT        = 0x00,  /* init state              */
+	RTGUI_WIN_FLAG_MODAL	   = 0x01,	/* modal mode window	   */
+	RTGUI_WIN_FLAG_CLOSED	   = 0x02,	/* window is closed		   */
+	RTGUI_WIN_FLAG_ACTIVATE	   = 0x04,	/* window is activated	   */
+	RTGUI_WIN_FLAG_UNDER_MODAL = 0x08,  /* window is under modal
+										   show(modaled by other)  */
+	RTGUI_WIN_FLAG_CONNECTED   = 0x10,  /* connected to server */
+	/* window is event_key dispatcher(dispatch it to the focused widget in
+	 * current window) _and_ a key handler(it should be able to handle keys
+	 * such as ESC). Both of dispatching and handling are in the same
+	 * function(rtgui_win_event_handler). So we have to distinguish between the
+	 * two modes.
+	 *
+	 * If this flag is set, we are in key-handling mode.
+	 */
+	RTGUI_WIN_FLAG_HANDLE_KEY  = 0x20
+};
+
+struct rtgui_win_title;
+struct rtgui_win_area;
+
+struct rtgui_win
+{
+	/* inherit from toplevel */
+	struct rtgui_toplevel parent;
+
+    /* parent window. RT_NULL if the window is a top level window */
+	struct rtgui_win *parent_window;
+
+	/* the widget that will grab the focus in current window */
+	struct rtgui_widget *focused_widget;
+
+	/* top window style */
+	rt_uint16_t style;
+
+	/* window state flag */
+	enum rtgui_win_flag flag;
+
+	rtgui_modal_code_t modal_code;
+
+	/* last mouse event handled widget */
+	rtgui_widget_t* last_mevent_widget;
+
+	/* window title */
+	char* title;
+
+	/* call back */
+	rt_bool_t (*on_activate)	(struct rtgui_object* widget, struct rtgui_event* event);
+	rt_bool_t (*on_deactivate)	(struct rtgui_object* widget, struct rtgui_event* event);
+	rt_bool_t (*on_close)		(struct rtgui_object* widget, struct rtgui_event* event);
+	/* the key is sent to the focused widget by default. If the focused widget
+	 * and all of it's parents didn't handle the key event, it will be handled
+	 * by @func on_key
+	 *
+	 * If you want to handle key event on your own, it's better to overload
+	 * this function other than handle EVENT_KBD in event_handler.
+	 */
+	rt_bool_t (*on_key)		    (struct rtgui_object* widget, struct rtgui_event* event);
+
+	/* reserved user data */
+	rt_uint32_t user_data;
+};
+
+rtgui_win_t* rtgui_win_create(struct rtgui_win *parent_window, const char* title,
+							  rtgui_rect_t *rect, rt_uint16_t style);
+void rtgui_win_destroy(rtgui_win_t* win);
+
+/** Close window.
+ *
+ * @param win the window you want to close
+ *
+ * @return RT_TRUE if the window is closed. RT_FALSE if not. If the onclose
+ * callback returns RT_FALSE, the window won't be closed.
+ *
+ * \sa rtgui_win_set_onclose .
+ */
+rt_bool_t rtgui_win_close(struct rtgui_win* win);
+
+rt_base_t rtgui_win_show(struct rtgui_win *win, rt_bool_t is_modal);
+void rtgui_win_hiden(rtgui_win_t* win);
+void rtgui_win_end_modal(rtgui_win_t* win, rtgui_modal_code_t modal_code);
+
+rt_bool_t rtgui_win_is_activated(struct rtgui_win* win);
+
+void rtgui_win_move(struct rtgui_win* win, int x, int y);
+
+/* reset extent of window */
+void rtgui_win_set_rect(rtgui_win_t* win, rtgui_rect_t* rect);
+
+#ifndef RTGUI_USING_SMALL_SIZE
+void rtgui_win_set_box(rtgui_win_t* win, rtgui_box_t* box);
+#endif
+
+void rtgui_win_set_onactivate(rtgui_win_t* win, rtgui_event_handler_ptr handler);
+void rtgui_win_set_ondeactivate(rtgui_win_t* win, rtgui_event_handler_ptr handler);
+void rtgui_win_set_onclose(rtgui_win_t* win, rtgui_event_handler_ptr handler);
+void rtgui_win_set_onkey(rtgui_win_t* win, rtgui_event_handler_ptr handler);
+
+rt_bool_t rtgui_win_event_handler(struct rtgui_object* win, struct rtgui_event* event);
+
+void rtgui_win_event_loop(rtgui_win_t* wnd);
+
+void rtgui_win_set_title(rtgui_win_t* win, const char *title);
+char* rtgui_win_get_title(rtgui_win_t* win);
+
+#endif

+ 0 - 87
components/rtgui/include/rtgui/widgets/workbench.h

@@ -1,87 +0,0 @@
-/*
- * File      : workbench.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-04     Bernard      first version
- */
-#ifndef __RTGUI_WORKBENCH_H__
-#define __RTGUI_WORKBENCH_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/list.h>
-#include <rtgui/region.h>
-#include <rtgui/dc.h>
-
-#include <rtgui/widgets/view.h>
-#include <rtgui/widgets/toplevel.h>
-
-#define RTGUI_WORKBENCH_FLAG_VISIBLE	0x00	/* workbench is visible */
-#define RTGUI_WORKBENCH_FLAG_INVISIBLE	0x01	/* workbench is invisible */
-#define RTGUI_WORKBENCH_FLAG_FULLSCREEN	0x02	/* workbench is full screen */
-#define RTGUI_WORKBENCH_FLAG_MODAL_MODE	0x04	/* workbench is modal mode showing */
-
-#define RTGUI_WORKBENCH_FLAG_CLOSEBLE	0x00
-#define RTGUI_WORKBENCH_FLAG_UNCLOSEBLE	0x10
-#define RTGUI_WORKBENCH_FLAG_CLOSED		0x20
-
-#define RTGUI_WORKBENCH_FLAG_DEFAULT	RTGUI_WORKBENCH_FLAG_VISIBLE | RTGUI_WORKBENCH_FLAG_CLOSEBLE
-
-#define RTGUI_WORKBENCH_IS_MODAL_MODE(w) ((w)->flag & RTGUI_WORKBENCH_FLAG_MODAL_MODE)
-
-DECLARE_CLASS_TYPE(workbench);
-
-/** Gets the type of a workbench */
-#define RTGUI_WORKBENCH_TYPE       (RTGUI_TYPE(workbench))
-/** Casts the object to an rtgui_workbench */
-#define RTGUI_WORKBENCH(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_WORKBENCH_TYPE, rtgui_workbench_t))
-/** Checks if the object is an rtgui_workbench */
-#define RTGUI_IS_WORKBENCH(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_WORKBENCH_TYPE))
-
-struct rtgui_workbench
-{
-	/* inherit from toplevel */
-	struct rtgui_toplevel parent;
-
-	/* panel id */
-	rtgui_panel_t* panel;
-
-	/* workbench flag */
-	rt_uint8_t flag;
-	rtgui_modal_code_t modal_code;
-	rtgui_widget_t *modal_widget;
-
-	/* workbench title */
-	unsigned char* title;
-	rtgui_view_t* current_view;
-};
-
-rtgui_type_t* rtgui_workbench_type_get(void);
-
-rtgui_workbench_t *rtgui_workbench_create(const char* panel_name, const unsigned char* title);
-void rtgui_workbench_destroy(rtgui_workbench_t* workbench);
-void rtgui_workbench_close(rtgui_workbench_t* workbench);
-
-rt_bool_t rtgui_workbench_event_handler(rtgui_widget_t* widget, rtgui_event_t* event);
-
-void rtgui_workbench_set_flag(rtgui_workbench_t* workbench, rt_uint8_t flag);
-
-rt_bool_t rtgui_workbench_event_loop(rtgui_workbench_t* workbench);
-
-rt_err_t rtgui_workbench_show (rtgui_workbench_t* workbench);
-rt_err_t rtgui_workbench_hide (rtgui_workbench_t* workbench);
-
-void rtgui_workbench_add_view(rtgui_workbench_t* workbench, rtgui_view_t* view);
-void rtgui_workbench_remove_view(rtgui_workbench_t* workbench, rtgui_view_t* view);
-void rtgui_workbench_show_view(rtgui_workbench_t* workbench, rtgui_view_t* view);
-void rtgui_workbench_hide_view(rtgui_workbench_t* workbench, rtgui_view_t* view);
-
-rtgui_view_t *rtgui_workbench_get_current_view(rtgui_workbench_t * workbench);
-
-#endif

+ 1 - 1
components/rtgui/server/mouse.c

@@ -432,7 +432,7 @@ static void rtgui_winrect_show()
 	rt_uint16_t x, y;
 	rt_uint16_t x, y;
 	rtgui_color_t c;
 	rtgui_color_t c;
 	rtgui_rect_t screen_rect, win_rect, win_rect_inner;
 	rtgui_rect_t screen_rect, win_rect, win_rect_inner;
-	void (*set_pixel) (rtgui_color_t *c, rt_base_t x, rt_base_t y);
+	void (*set_pixel) (rtgui_color_t *c, int x, int y);
 
 
 	c = black;
 	c = black;
 	set_pixel = rtgui_graphic_driver_get_default()->ops->set_pixel;
 	set_pixel = rtgui_graphic_driver_get_default()->ops->set_pixel;

+ 0 - 315
components/rtgui/server/panel.c

@@ -1,315 +0,0 @@
-/*
- * File      : panel.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-04     Bernard      first version
- */
-
-#include "panel.h"
-#include "mouse.h"
-
-#include <rtgui/rtgui_system.h>
-
-/* the global parameter */
-struct rtgui_list_node _rtgui_panel_list = {RT_NULL};
-
-void rtgui_panel_register(char* name, rtgui_rect_t* extent)
-{
-	register rt_base_t temp;
-	struct rtgui_panel* panel;
-
-	panel = rtgui_panel_find(name);
-	if (panel != RT_NULL )
-	{
-		/* there are already a same named panel exist. */
-		return;
-	}
-
-	panel = rtgui_malloc(sizeof(struct rtgui_panel));
-	if (panel == RT_NULL)
-	{
-		/* can't alloc memory */
-		return;
-	}
-
-	/* copy name */
-	for (temp = 0; temp < RTGUI_NAME_MAX; temp ++)
-	{
-		panel->name[temp] = name[temp];
-	}
-
-	/* copy extent */
-	panel->extent = *extent;
-
-	panel->wm_thread = RT_NULL;
-	panel->is_focusable = RT_TRUE;
-
-	/* init list */
-	rtgui_list_init(&(panel->sibling));
-	rtgui_list_init(&(panel->thread_list));
-
-	/* add panel to panel list */
-	rtgui_list_insert(&_rtgui_panel_list, &(panel->sibling));
-}
-
-void rtgui_panel_deregister(char* name)
-{
-	struct rtgui_panel* panel;
-
-	panel = rtgui_panel_find(name);
-	if (panel != RT_NULL)
-	{
-		rtgui_list_remove(&_rtgui_panel_list, &(panel->sibling));
-
-		/* free pane node */
-		rtgui_free(panel);
-	}
-}
-
-/* set default focused panel, please use it after registered panel */
-void rtgui_panel_set_default_focused(char* name)
-{
-	extern struct rtgui_panel* rtgui_server_focus_panel;
-	struct rtgui_panel* panel;
-	
-	panel = rtgui_panel_find(name);
-	if (panel != RT_NULL)
-	{
-		rtgui_server_focus_panel = panel;
-	}
-}
-
-void rtgui_panel_set_nofocused(char* name)
-{
-	extern struct rtgui_panel* rtgui_server_focus_panel;
-	struct rtgui_panel* panel;
-	
-	panel = rtgui_panel_find(name);
-	if (panel != RT_NULL)
-	{
-		panel->is_focusable = RT_FALSE;
-	}
-}
-
-struct rtgui_panel* rtgui_panel_find(char* name)
-{
-	struct rtgui_list_node* node;
-	struct rtgui_panel* panel;
-
-	rtgui_list_foreach(node, &_rtgui_panel_list)
-	{
-		panel = rtgui_list_entry(node, struct rtgui_panel, sibling);
-
-		if (rt_strncmp(panel->name, name, RTGUI_NAME_MAX) == 0)
-		{
-			return panel;
-		}
-	}
-
-	return RT_NULL;
-}
-
-struct rtgui_panel* rtgui_panel_thread_add(char* name, rt_thread_t tid)
-{
-	struct rtgui_panel* panel;
-
-	panel = rtgui_panel_find(name);
-	if (panel != RT_NULL )
-	{
-		struct rtgui_panel_thread* thread;
-
-		/* allocate panel thread node */
-		thread = rtgui_malloc(sizeof(struct rtgui_panel_thread));
-		if (thread == RT_NULL)
-		{
-			return RT_NULL;
-		}
-
-		/* construct panel thread node */
-		thread->tid = tid;
-
-		/* init list */
-		rtgui_list_init(&(thread->list));
-		rtgui_list_init(&(thread->monitor_list));
-
-		/* append thread to the list */
-		rtgui_list_append(&(panel->thread_list), &(thread->list));
-	}
-
-	return panel;
-}
-
-void rtgui_panel_thread_remove(rtgui_panel_t* panel, rt_thread_t tid)
-{
-	if (panel != RT_NULL )
-	{
-		struct rtgui_list_node* node;
-		struct rtgui_panel_thread* thread;
-
-		rtgui_list_foreach(node, &(panel->thread_list))
-		{
-			thread = rtgui_list_entry(node, struct rtgui_panel_thread, list);
-			if (thread->tid == tid)
-			{
-				/* remove node from list */
-				rtgui_list_remove(&(panel->thread_list), &(thread->list));
-
-				/* free the panel thread node */
-				rtgui_free(thread);
-				return;
-			}
-		}
-	}
-}
-
-rt_thread_t rtgui_panel_get_active_thread(rtgui_panel_t* panel)
-{
-	if (panel != RT_NULL)
-	{
-		if (panel->thread_list.next != RT_NULL)
-		{
-			struct rtgui_panel_thread* thread;
-			thread = rtgui_list_entry(panel->thread_list.next, struct rtgui_panel_thread, list);
-
-			return thread->tid;
-		}
-	}
-
-	return RT_NULL;
-}
-
-void rtgui_panel_set_active_thread(rtgui_panel_t* panel, rt_thread_t tid)
-{
-	/* get old active thread */
-	rt_thread_t prev_actived = rtgui_panel_get_active_thread(panel);
-	if (prev_actived != tid)
-	{
-		/* de-active old active workbench */
-		struct rtgui_event_panel_hide ehide;
-		RTGUI_EVENT_PANEL_HIDE_INIT(&ehide);
-
-		ehide.panel = panel;
-		ehide.workbench = RT_NULL;
-		rtgui_thread_send_urgent(prev_actived, &(ehide.parent), sizeof (ehide));
-	}
-
-	if (panel != RT_NULL )
-	{
-		struct rtgui_list_node* node;
-		struct rtgui_panel_thread* thread;
-
-		rtgui_list_foreach(node, &(panel->thread_list))
-		{
-			thread = rtgui_list_entry(node, struct rtgui_panel_thread, list);
-			if (thread->tid == tid)
-			{
-				/* remove node from list */
-				rtgui_list_remove(&(panel->thread_list), &(thread->list));
-
-				/* insert node to the header */
-				rtgui_list_insert(&(panel->thread_list), &(thread->list));
-				return;
-			}
-		}
-	}
-}
-
-/* deactivate current activated thread -- move it to the end of list */
-void rtgui_panel_deactive_thread(rtgui_panel_t* panel)
-{
-	RT_ASSERT(panel == RT_NULL);
-
-	if (panel->thread_list.next != RT_NULL)
-	{
-		struct rtgui_panel_thread* thread;
-		thread = rtgui_list_entry(panel->thread_list.next, struct rtgui_panel_thread, list);
-
-		/* remove it */
-		panel->thread_list.next = thread->list.next;
-
-		/* append to the tail of thread list */
-		rtgui_list_append(&(panel->thread_list), &(thread->list));
-	}
-}
-
-/**
- * get the panel which contains a point(x, y)
- */
-rtgui_panel_t* rtgui_panel_get_contain(int x, int y)
-{
-	struct rtgui_list_node* node;
-	struct rtgui_panel* panel;
-
-	rtgui_list_foreach(node, &(_rtgui_panel_list))
-	{
-		panel = rtgui_list_entry(node, struct rtgui_panel, sibling);
-		if (rtgui_rect_contains_point(&(panel->extent), x, y) == RT_EOK)
-		{
-			return panel;
-		}
-	}
-
-	return RT_NULL;
-}
-
-/**
- * append a rect to panel mouse monitor rect list
- */
-void rtgui_panel_append_monitor_rect(rtgui_panel_t* panel, rt_thread_t tid, rtgui_rect_t* rect)
-{
-	if (panel != RT_NULL )
-	{
-		struct rtgui_list_node* node;
-		struct rtgui_panel_thread* thread;
-
-		rtgui_list_foreach(node, &(panel->thread_list))
-		{
-			thread = rtgui_list_entry(node, struct rtgui_panel_thread, list);
-			if (thread->tid == tid)
-			{
-				/* add the monitor rect to list */
-				rtgui_mouse_monitor_append(&(thread->monitor_list), rect);
-				return;
-			}
-		}
-	}
-}
-
-/**
- * remove a rect from panel mouse monitor rect list
- */
-void rtgui_panel_remove_monitor_rect(rtgui_panel_t* panel, rt_thread_t tid, rtgui_rect_t* rect)
-{
-	if (panel != RT_NULL )
-	{
-		struct rtgui_list_node* node;
-		struct rtgui_panel_thread* thread;
-
-		rtgui_list_foreach(node, &(panel->thread_list))
-		{
-			thread = rtgui_list_entry(node, struct rtgui_panel_thread, list);
-			if (thread->tid == tid)
-			{
-				/* remove the monitor rect from list */
-				rtgui_mouse_monitor_remove(&(thread->monitor_list), rect);
-				return;
-			}
-		}
-	}
-}
-
-void rtgui_panel_set_wm(rtgui_panel_t* panel, rt_thread_t wm)
-{
-	RT_ASSERT(wm != RT_NULL);
-	RT_ASSERT(panel != RT_NULL);
-
-	panel->wm_thread = wm;
-}
-

+ 0 - 72
components/rtgui/server/panel.h

@@ -1,72 +0,0 @@
-/*
- * File      : panel.h
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-04     Bernard      first version
- */
-
-#ifndef __RT_PANEL_H__
-#define __RT_PANEL_H__
-
-#include <rtgui/rtgui.h>
-#include <rtgui/list.h>
-#include <rtgui/region.h>
-
-struct rtgui_panel_thread
-{
-	/* thread id */
-	rt_thread_t tid;
-
-	/* the list of thread */
-	rtgui_list_t list;
-
-	/* monitor rect list */
-	rtgui_list_t monitor_list;
-};
-typedef struct rtgui_panel_thread rtgui_panel_thread_list_t;
-
-struct rtgui_panel
-{
-	char name[RTGUI_NAME_MAX];
-
-	/* the extent of panel */
-	rtgui_rect_t extent;
-
-	/* the list of panel */
-	rtgui_list_t sibling;
-
-	/* the thread list in this panel */
-	rtgui_list_t thread_list;
-
-	/* the workbench manager thread */
-	rt_thread_t wm_thread;
-
-	/* is focusable */
-	rt_bool_t is_focusable;
-};
-
-/* find panel by name */
-struct rtgui_panel* rtgui_panel_find(char* name);
-
-/* add or remove application thread from specified panel */
-rtgui_panel_t* rtgui_panel_thread_add(char* name, rt_thread_t tid);
-void rtgui_panel_thread_remove(rtgui_panel_t* panel, rt_thread_t tid);
-
-rt_thread_t rtgui_panel_get_active_thread(rtgui_panel_t* panel);
-void rtgui_panel_set_active_thread(rtgui_panel_t* panel, rt_thread_t tid);
-
-rtgui_panel_t* rtgui_panel_get_contain(int x, int y);
-void rtgui_panel_set_wm(rtgui_panel_t* panel, rt_thread_t wm);
-
-void rtgui_panel_append_monitor_rect(rtgui_panel_t* panel, rt_thread_t tid, rtgui_rect_t* rect);
-void rtgui_panel_remove_monitor_rect(rtgui_panel_t* panel, rt_thread_t tid, rtgui_rect_t* rect);
-
-#endif
-

+ 673 - 0
components/rtgui/server/rtgui_application.c

@@ -0,0 +1,673 @@
+/*
+ * File      : rtgui_application.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2012, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2012-01-13     Grissiom     first version(just a prototype of application API)
+ */
+
+#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_application.h>
+#include <rtgui/widgets/window.h>
+
+#ifdef _WIN32
+#define RTGUI_EVENT_DEBUG
+#endif
+
+#ifdef RTGUI_EVENT_DEBUG
+const char *event_string[] =
+{
+	/* window event */
+	"WIN_CREATE",			/* create a window 	*/
+	"WIN_DESTROY",			/* destroy a window 	*/
+	"WIN_SHOW",				/* show a window 		*/
+	"WIN_HIDE",				/* hide a window 		*/
+	"WIN_ACTIVATE", 		/* activate a window 	*/
+	"WIN_DEACTIVATE",		/* deactivate a window 	*/
+	"WIN_CLOSE",			/* close a window 		*/
+	"WIN_MOVE",				/* move a window 		*/
+	"WIN_RESIZE", 			/* resize a window 		*/
+	"WIN_MODAL_ENTER", 			/* a window modals		*/
+
+	"SET_WM", 				/* set window manager	*/
+
+	"UPDATE_BEGIN",			/* begin of update rect */
+	"UPDATE_END",			/* end of update rect	*/
+	"MONITOR_ADD",			/* add a monitor rect 	*/
+	"MONITOR_REMOVE", 		/* remove a monitor rect*/
+	"PAINT",				/* paint on screen 		*/
+	"TIMER",				/* timer 				*/
+
+	/* clip rect information */
+	"CLIP_INFO",			/* clip rect info		*/
+
+	/* mouse and keyboard event */
+	"MOUSE_MOTION",			/* mouse motion */
+	"MOUSE_BUTTON",			/* mouse button info 	*/
+	"KBD",					/* keyboard info		*/
+
+	/* user command event */
+	"COMMAND",				/* user command 		*/
+
+	/* request's status event */
+	"STATUS",				/* request result 		*/
+	"SCROLLED",           	/* scroll bar scrolled  */
+	"RESIZE",				/* widget resize 		*/
+};
+
+#define DBG_MSG(x)	rt_kprintf x
+
+static void rtgui_event_dump(rt_thread_t tid, rtgui_event_t* event)
+{
+	char* sender = "(unknown)";
+
+	if ((event->type == RTGUI_EVENT_TIMER) ||
+		(event->type == RTGUI_EVENT_UPDATE_BEGIN) ||
+		(event->type == RTGUI_EVENT_MOUSE_MOTION) ||
+		(event->type == RTGUI_EVENT_UPDATE_END))
+	{
+		/* don't dump timer event */
+		return ;
+	}
+
+	if (event->sender != RT_NULL)
+		sender = event->sender->name;
+
+	rt_kprintf("%s -- %s --> %s ", sender, event_string[event->type], tid->name);
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+		{
+			struct rtgui_event_paint *paint = (struct rtgui_event_paint *)event;
+
+			if(paint->wid != RT_NULL)
+				rt_kprintf("win: %s", paint->wid->title);
+		}
+		break;
+
+	case RTGUI_EVENT_KBD:
+		{
+			struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd*) event;
+			if (ekbd->wid != RT_NULL)
+				rt_kprintf("win: %s", ekbd->wid->title);
+			if (RTGUI_KBD_IS_UP(ekbd)) rt_kprintf(", up");
+			else rt_kprintf(", down");
+		}
+		break;
+
+	case RTGUI_EVENT_CLIP_INFO:
+		{
+			struct rtgui_event_clip_info *info = (struct rtgui_event_clip_info *)event;
+
+			if(info->wid != RT_NULL)
+				rt_kprintf("win: %s", info->wid->title);
+		}
+		break;
+
+	case RTGUI_EVENT_WIN_CREATE:
+		{
+			struct rtgui_event_win_create *create = (struct rtgui_event_win_create*)event;
+
+			rt_kprintf(" win: %s at (x1:%d, y1:%d, x2:%d, y2:%d), addr: %p",
+#ifdef RTGUI_USING_SMALL_SIZE
+				create->wid->title,
+				RTGUI_WIDGET(create->wid)->extent.x1,
+				RTGUI_WIDGET(create->wid)->extent.y1,
+				RTGUI_WIDGET(create->wid)->extent.x2,
+				RTGUI_WIDGET(create->wid)->extent.y2,
+#else
+				create->title,
+				create->extent.x1,
+				create->extent.y1,
+				create->extent.x2,
+				create->extent.y2,
+#endif
+				create->wid
+                );
+		}
+		break;
+
+	case RTGUI_EVENT_UPDATE_END:
+		{
+			struct rtgui_event_update_end* update_end = (struct rtgui_event_update_end*)event;
+			rt_kprintf("(x:%d, y1:%d, x2:%d, y2:%d)", update_end->rect.x1,
+				update_end->rect.y1,
+				update_end->rect.x2,
+				update_end->rect.y2);
+		}
+		break;
+
+	case RTGUI_EVENT_WIN_ACTIVATE:
+	case RTGUI_EVENT_WIN_DEACTIVATE:
+	case RTGUI_EVENT_WIN_SHOW:
+	case RTGUI_EVENT_WIN_MODAL_ENTER:
+		{
+			struct rtgui_event_win *win = (struct rtgui_event_win *)event;
+
+			if(win->wid != RT_NULL)
+				rt_kprintf("win: %s", win->wid->title);
+		}
+		break;
+
+	case RTGUI_EVENT_WIN_MOVE:
+		{
+			struct rtgui_event_win_move *win = (struct rtgui_event_win_move *)event;
+
+			if(win->wid != RT_NULL)
+			{
+				rt_kprintf("win: %s", win->wid->title);
+				rt_kprintf(" to (x:%d, y:%d)", win->x, win->y);
+			}
+		}
+		break;
+
+	case RTGUI_EVENT_WIN_RESIZE:
+		{
+			struct rtgui_event_win_resize* win = (struct rtgui_event_win_resize *)event;
+
+			if (win->wid != RT_NULL)
+			{
+				rt_kprintf("win: %s, rect(x1:%d, y1:%d, x2:%d, y2:%d)", win->wid->title,
+					RTGUI_WIDGET(win->wid)->extent.x1,
+					RTGUI_WIDGET(win->wid)->extent.y1,
+					RTGUI_WIDGET(win->wid)->extent.x2,
+					RTGUI_WIDGET(win->wid)->extent.y2);
+			}
+		}
+		break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+	case RTGUI_EVENT_MOUSE_MOTION:
+		{
+			struct rtgui_event_mouse *mouse = (struct rtgui_event_mouse*)event;
+
+			if (mouse->button & RTGUI_MOUSE_BUTTON_LEFT) rt_kprintf("left ");
+			else rt_kprintf("right ");
+
+			if (mouse->button & RTGUI_MOUSE_BUTTON_DOWN) rt_kprintf("down ");
+			else rt_kprintf("up ");
+
+			if (mouse->wid != RT_NULL)
+				rt_kprintf("win: %s at (%d, %d)", mouse->wid->title,
+				mouse->x, mouse->y);
+			else
+				rt_kprintf("(%d, %d)", mouse->x, mouse->y);
+		}
+		break;
+
+	case RTGUI_EVENT_MONITOR_ADD:
+		{
+			struct rtgui_event_monitor *monitor = (struct rtgui_event_monitor*)event;
+			if (monitor->wid != RT_NULL)
+			{
+				rt_kprintf("win: %s, the rect is:(%d, %d) - (%d, %d)", monitor->wid->title,
+					monitor->rect.x1, monitor->rect.y1,
+					monitor->rect.x2, monitor->rect.y2);
+			}
+		}
+		break;
+	}
+
+	rt_kprintf("\n");
+}
+#else
+#define DBG_MSG(x)
+#define rtgui_event_dump(tid, event)
+#endif
+
+rt_bool_t rtgui_application_event_handler(struct rtgui_object* obj, rtgui_event_t* event);
+
+static void _rtgui_application_constructor(struct rtgui_application *app)
+{
+	/* set event handler */
+	rtgui_object_set_event_handler(RTGUI_OBJECT(app),
+			                       rtgui_application_event_handler);
+
+	app->name           = RT_NULL;
+	/* set EXITED so we can destroy an application that just created */
+	app->state_flag     = RTGUI_APPLICATION_FLAG_EXITED;
+	app->ref_count      = 0;
+	app->exit_code      = 0;
+	app->tid            = RT_NULL;
+	app->server         = RT_NULL;
+	app->mq             = RT_NULL;
+	app->modal_object   = RT_NULL;
+	app->on_idle        = RT_NULL;
+}
+
+static void _rtgui_application_destructor(struct rtgui_application *app)
+{
+	RT_ASSERT(app != RT_NULL);
+
+	rt_free(app->name);
+	app->name = RT_NULL;
+}
+
+DEFINE_CLASS_TYPE(application, "application",
+	RTGUI_OBJECT_TYPE,
+	_rtgui_application_constructor,
+	_rtgui_application_destructor,
+	sizeof(struct rtgui_application));
+
+struct rtgui_application* rtgui_application_create(
+        rt_thread_t tid,
+        const char *myname)
+{
+	struct rtgui_application *app;
+
+	RT_ASSERT(tid != RT_NULL);
+	RT_ASSERT(myname != RT_NULL);
+
+	/* create application */
+	app = RTGUI_APPLICATION(rtgui_object_create(RTGUI_APPLICATION_TYPE));
+	if (app == RT_NULL)
+		return RT_NULL;
+
+	DBG_MSG(("register a rtgui application(%s) on thread %s\n", myname, tid->name));
+
+	app->tid     = tid;
+	/* set user thread */
+	tid->user_data = (rt_uint32_t)app;
+
+	app->mq = rt_mq_create("rtgui", sizeof(union rtgui_event_generic), 32, RT_IPC_FLAG_FIFO);
+	if (app->mq == RT_NULL)
+	{
+		rt_kprintf("mq err\n");
+		goto __mq_err;
+	}
+
+	/* set application title */
+	app->name = (unsigned char*)rt_strdup((char*)myname);
+	if (app->name != RT_NULL)
+		return app;
+
+__mq_err:
+	rtgui_object_destroy(RTGUI_OBJECT(app));
+	tid->user_data = 0;
+	return RT_NULL;
+}
+
+#define _rtgui_application_check(app) \
+do { \
+    RT_ASSERT(app != RT_NULL); \
+    RT_ASSERT(app->tid != RT_NULL); \
+    RT_ASSERT(app->tid->user_data != 0); \
+    RT_ASSERT(app->mq != RT_NULL); \
+} while (0)
+
+void rtgui_application_destroy(struct rtgui_application *app)
+{
+    _rtgui_application_check(app);
+
+	if (!(app->state_flag & RTGUI_APPLICATION_FLAG_EXITED))
+	{
+		rt_kprintf("cannot destroy a running application: %s.\n",
+				   app->name);
+		return;
+	}
+
+	app->tid->user_data = 0;
+	rt_mq_delete(app->mq);
+	rtgui_object_destroy(RTGUI_OBJECT(app));
+}
+
+struct rtgui_application* rtgui_application_self(void)
+{
+	struct rtgui_application *app;
+	rt_thread_t self;
+
+	/* get current thread */
+	self = rt_thread_self();
+	app = (struct rtgui_application*)(self->user_data);
+
+	return app;
+}
+
+void rtgui_application_set_onidle(rtgui_idle_func onidle)
+{
+	struct rtgui_application *app;
+
+	app = rtgui_application_self();
+	if (app != RT_NULL)
+		app->on_idle = onidle;
+}
+
+rtgui_idle_func rtgui_application_get_onidle(void)
+{
+	struct rtgui_application *app;
+
+	app = rtgui_application_self();
+	if (app != RT_NULL)
+		return app->on_idle;
+	else
+		return RT_NULL;
+}
+
+extern rt_thread_t rt_thread_find(char* name);
+rt_thread_t rtgui_application_get_server(void)
+{
+	return rt_thread_find("rtgui");
+}
+
+rt_err_t rtgui_application_send(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
+{
+	rt_err_t result;
+	struct rtgui_application *app;
+
+	RT_ASSERT(tid != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+	RT_ASSERT(event_size != 0);
+
+	rtgui_event_dump(tid, event);
+
+	/* find struct rtgui_application */
+	app = (struct rtgui_application*) (tid->user_data);
+	if (app == RT_NULL)
+		return -RT_ERROR;
+
+	result = rt_mq_send(app->mq, event, event_size);
+	if (result != RT_EOK)
+	{
+		if (event->type != RTGUI_EVENT_TIMER)
+			rt_kprintf("send event to %s failed\n", app->tid->name);
+	}
+
+	return result;
+}
+
+rt_err_t rtgui_application_send_urgent(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
+{
+	rt_err_t result;
+	struct rtgui_application *app;
+
+	RT_ASSERT(tid != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+	RT_ASSERT(event_size != 0);
+
+	rtgui_event_dump(tid, event);
+
+	/* find rtgui_application */
+	app = (struct rtgui_application*) (tid->user_data);
+	if (app == RT_NULL)
+		return -RT_ERROR;
+
+	result = rt_mq_urgent(app->mq, event, event_size);
+	if (result != RT_EOK)
+		rt_kprintf("send ergent event failed\n");
+
+	return result;
+}
+
+rt_err_t rtgui_application_send_sync(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
+{
+	rt_err_t r;
+	struct rtgui_application *app;
+	rt_int32_t ack_buffer, ack_status;
+	struct rt_mailbox ack_mb;
+
+	RT_ASSERT(tid != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+	RT_ASSERT(event_size != 0);
+
+	rtgui_event_dump(tid, event);
+
+	/* init ack mailbox */
+	r = rt_mb_init(&ack_mb, "ack", &ack_buffer, 1, 0);
+	if (r!= RT_EOK)
+		goto __return;
+
+	app = (struct rtgui_application*) (tid->user_data);
+	if (app == RT_NULL)
+	{
+		r = -RT_ERROR;
+		goto __return;
+	}
+
+	event->ack = &ack_mb;
+	r = rt_mq_send(app->mq, event, event_size);
+	if (r != RT_EOK)
+	{
+		rt_kprintf("send sync event failed\n");
+		goto __return;
+	}
+
+	r = rt_mb_recv(&ack_mb, (rt_uint32_t*)&ack_status, RT_WAITING_FOREVER);
+	if (r!= RT_EOK)
+		goto __return;
+
+	if (ack_status != RTGUI_STATUS_OK)
+		r = -RT_ERROR;
+	else
+		r = RT_EOK;
+
+__return:
+	/* fini ack mailbox */
+	rt_mb_detach(&ack_mb);
+	return r;
+}
+
+rt_err_t rtgui_application_ack(rtgui_event_t* event, rt_int32_t status)
+{
+	RT_ASSERT(event != RT_NULL);
+	RT_ASSERT(event->ack != RT_NULL);
+
+	rt_mb_send(event->ack, status);
+
+	return RT_EOK;
+}
+
+rt_err_t rtgui_application_recv(rtgui_event_t* event, rt_size_t event_size)
+{
+	struct rtgui_application* app;
+	rt_err_t r;
+
+	RT_ASSERT(event != RT_NULL);
+	RT_ASSERT(event_size != 0);
+
+	app = (struct rtgui_application*) (rt_thread_self()->user_data);
+	if (app == RT_NULL)
+		return -RT_ERROR;
+
+	r = rt_mq_recv(app->mq, event, event_size, RT_WAITING_FOREVER);
+
+	return r;
+}
+
+rt_err_t rtgui_application_recv_nosuspend(rtgui_event_t* event, rt_size_t event_size)
+{
+	struct rtgui_application *app;
+	rt_err_t r;
+
+	RT_ASSERT(event != RT_NULL);
+	RT_ASSERT(event != 0);
+
+	app = (struct rtgui_application*) (rt_thread_self()->user_data);
+	if (app == RT_NULL)
+		return -RT_ERROR;
+
+	r = rt_mq_recv(app->mq, event, event_size, 0);
+
+	return r;
+}
+
+rt_err_t rtgui_application_recv_filter(rt_uint32_t type, rtgui_event_t* event, rt_size_t event_size)
+{
+	struct rtgui_application *app;
+
+	RT_ASSERT(event != RT_NULL);
+	RT_ASSERT(event_size != 0);
+
+	app = (struct rtgui_application*) (rt_thread_self()->user_data);
+	if (app == RT_NULL)
+		return -RT_ERROR;
+
+	while (rt_mq_recv(app->mq, event, event_size, RT_WAITING_FOREVER) == RT_EOK)
+	{
+		if (event->type == type)
+		{
+			return RT_EOK;
+		}
+		else
+		{
+			if (RTGUI_OBJECT(app)->event_handler != RT_NULL)
+			{
+				RTGUI_OBJECT(app)->event_handler(RTGUI_OBJECT(app), event);
+			}
+		}
+	}
+
+	return -RT_ERROR;
+}
+
+rt_inline rt_bool_t _rtgui_application_dest_handle(
+		struct rtgui_application *app,
+		struct rtgui_event *event)
+{
+	struct rtgui_event_win* wevent = (struct rtgui_event_win*)event;
+
+	struct rtgui_object* dest_object = RTGUI_OBJECT(wevent->wid);
+
+	if (dest_object != RT_NULL)
+	{
+		if (dest_object->event_handler != RT_NULL)
+			return dest_object->event_handler(RTGUI_OBJECT(dest_object), event);
+		else
+			return RT_FALSE;
+	}
+	else
+	{
+		rt_kprintf("RTGUI ERROR:server sent a event(%d) without wid\n", event->type);
+		return RT_FALSE;
+	}
+}
+
+rt_bool_t rtgui_application_event_handler(struct rtgui_object* object, rtgui_event_t* event)
+{
+	struct rtgui_application* app;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	app = RTGUI_APPLICATION(object);
+
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+	case RTGUI_EVENT_CLIP_INFO:
+	case RTGUI_EVENT_WIN_ACTIVATE:
+	case RTGUI_EVENT_WIN_DEACTIVATE:
+	case RTGUI_EVENT_WIN_CLOSE:
+	case RTGUI_EVENT_WIN_MOVE:
+	case RTGUI_EVENT_KBD:
+		_rtgui_application_dest_handle(app, event);
+		break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+	case RTGUI_EVENT_MOUSE_MOTION:
+		{
+			struct rtgui_event_win* wevent = (struct rtgui_event_win*)event;
+			struct rtgui_object* dest_object = RTGUI_OBJECT(wevent->wid);
+
+			// FIXME: let application determine the dest_wiget but not in sever
+			// so we can combine this handler with above one
+			if (app->modal_object != RT_NULL &&
+				dest_object != app->modal_object)
+			{
+//				rt_kprintf("discard event %s that is not sent to modal object\n",
+//						   event_string[event->type]);
+			}
+			else
+			{
+				_rtgui_application_dest_handle(app, event);
+			}
+		}
+		break;
+
+	case RTGUI_EVENT_TIMER:
+		{
+			struct rtgui_timer* timer;
+			struct rtgui_event_timer* etimer = (struct rtgui_event_timer*) event;
+
+			timer = etimer->timer;
+			if (timer->timeout != RT_NULL)
+			{
+				/* call timeout function */
+				timer->timeout(timer, timer->user_data);
+			}
+		}
+		break;
+
+        case RTGUI_EVENT_COMMAND:
+                {
+                        struct rtgui_event_command *ecmd = (struct rtgui_event_command*)event;
+
+                        if (ecmd->wid != RT_NULL)
+                                return _rtgui_application_dest_handle(app, event);
+                }
+
+	default:
+		return rtgui_object_event_handler(object, event);
+	}
+
+	return RT_TRUE;
+}
+
+rt_inline void _rtgui_application_event_loop(struct rtgui_application *app)
+{
+	rt_err_t result;
+	rt_uint16_t current_ref;
+	struct rtgui_event *event;
+
+	_rtgui_application_check(app);
+
+	/* point to event buffer */
+	event = (struct rtgui_event*)app->event_buffer;
+
+	current_ref = ++app->ref_count;
+
+	while (current_ref <= app->ref_count)
+	{
+		RT_ASSERT(current_ref == app->ref_count);
+
+		if (app->on_idle != RT_NULL)
+		{
+			result = rtgui_application_recv_nosuspend(event, sizeof(union rtgui_event_generic));
+			if (result == RT_EOK)
+				RTGUI_OBJECT(app)->event_handler(RTGUI_OBJECT(app), event);
+			else if (result == -RT_ETIMEOUT)
+				app->on_idle(RTGUI_OBJECT(app), RT_NULL);
+		}
+		else
+		{
+			result = rtgui_application_recv(event, sizeof(union rtgui_event_generic));
+			if (result == RT_EOK)
+				RTGUI_OBJECT(app)->event_handler(RTGUI_OBJECT(app), event);
+		}
+	}
+}
+
+rt_base_t rtgui_application_run(struct rtgui_application *app)
+{
+	_rtgui_application_check(app);
+
+	app->state_flag &= ~RTGUI_APPLICATION_FLAG_EXITED;
+
+	_rtgui_application_event_loop(app);
+
+	if (app->ref_count == 0)
+		app->state_flag |= RTGUI_APPLICATION_FLAG_EXITED;
+
+	return app->exit_code;
+}
+
+void rtgui_application_exit(struct rtgui_application* app, rt_uint16_t code)
+{
+	--app->ref_count;
+	app->exit_code = code;
+}

+ 158 - 447
components/rtgui/server/server.c

@@ -15,176 +15,15 @@
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui.h>
 #include <rtgui/event.h>
 #include <rtgui/event.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_object.h>
+#include <rtgui/rtgui_application.h>
 #include <rtgui/driver.h>
 #include <rtgui/driver.h>
 
 
 #include "mouse.h"
 #include "mouse.h"
-#include "panel.h"
 #include "topwin.h"
 #include "topwin.h"
 
 
 static struct rt_thread *rtgui_server_tid;
 static struct rt_thread *rtgui_server_tid;
-static struct rt_messagequeue *rtgui_server_mq;
-
-extern struct rtgui_topwin* rtgui_server_focus_topwin;
-struct rtgui_panel* rtgui_server_focus_panel = RT_NULL;
-
-void rtgui_server_create_application(struct rtgui_event_panel_attach* event)
-{
-	struct rtgui_panel* panel = rtgui_panel_find(event->panel_name);
-
-	if (panel != RT_NULL)
-	{
-		struct rtgui_event_panel_info ep;
-		RTGUI_EVENT_PANEL_INFO_INIT(&ep);
-
-		if (panel->wm_thread != RT_NULL)
-		{
-			/* notify to workbench */
-			rtgui_thread_send(panel->wm_thread, &(event->parent), sizeof(struct rtgui_event_panel_attach));
-		}
-
-		/* send the responses - ok */
-		rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_OK);
-
-		/* send the panel info */
-		ep.panel = panel;
-		ep.extent = panel->extent;
-		rtgui_thread_send(event->parent.sender, (struct rtgui_event*)&ep, sizeof(ep));
-
-		rtgui_panel_thread_add(event->panel_name, event->parent.sender);
-	}
-	else
-	{
-		/* send the responses - failure */
-		rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_NRC);
-	}
-}
-
-void rtgui_server_destroy_application(struct rtgui_event_panel_detach* event)
-{
-	struct rtgui_panel* panel = event->panel;
-
-	if (panel != RT_NULL)
-	{
-		if (panel->wm_thread != RT_NULL)
-		{
-			/* notify to workbench */
-			rtgui_thread_send(panel->wm_thread, &(event->parent), sizeof(struct rtgui_event_panel_detach));
-		}
-
-		/* send the responses */
-		rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_OK);
-
-		rtgui_panel_thread_remove(panel, event->parent.sender);
-
-		{
-			/* get next thread and active it */
-			rt_thread_t tid = rtgui_panel_get_active_thread(panel);
-			if (tid != RT_NULL)
-			{
-				/* let this thread repaint */
-				struct rtgui_event_paint epaint;
-				RTGUI_EVENT_PAINT_INIT(&epaint);
-				epaint.wid = RT_NULL;
-				rtgui_thread_send(tid, (struct rtgui_event*)&epaint, sizeof(epaint));
-			}
-		}
-	}
-	else
-	{
-		/* send the responses - failure */
-		rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_NRC);
-	}
-}
-
-void rtgui_server_thread_panel_show(struct rtgui_event_panel_show* event)
-{
-	struct rtgui_panel* panel = event->panel;
-
-	if (panel != RT_NULL)
-	{
-		struct rtgui_event_paint epaint;
-
-		/* send the responses */
-		rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_OK);
-
-		if (panel->wm_thread != RT_NULL)
-		{
-			/* notify to workbench */
-			rtgui_thread_send(panel->wm_thread, &(event->parent), sizeof(struct rtgui_event_panel_show));
-		}
-
-		rtgui_panel_set_active_thread(panel, event->parent.sender);
-
-		/* send all topwin clip info */
-		rtgui_topwin_update_clip_to_panel(panel);
-
-		/* send paint event */
-		RTGUI_EVENT_PAINT_INIT(&epaint);
-		epaint.wid = RT_NULL;
-		rtgui_thread_send(event->parent.sender, (struct rtgui_event*)&epaint,
-			sizeof(epaint));
-	}
-	else
-	{
-		/* send failed */
-		rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_ERROR);
-	}
-}
-
-void rtgui_server_thread_panel_hide(struct rtgui_event_panel_hide* event)
-{
-	struct rtgui_panel* panel = event->panel;
-
-	if (panel != RT_NULL)
-	{
-		rt_thread_t tid;
-
-		/* send the responses */
-		rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_OK);
-
-		if (panel->thread_list.next != RT_NULL)
-		{
-			struct rtgui_panel_thread* thread;
-			thread = rtgui_list_entry(panel->thread_list.next, struct rtgui_panel_thread, list);
-
-			/* remove it */
-			panel->thread_list.next = thread->list.next;
-
-			/* append to the tail of thread list */
-			rtgui_list_append(&(panel->thread_list), &(thread->list));
-		}
-
-		/* send all topwin clip info */
-		rtgui_topwin_update_clip_to_panel(panel);
-
-		/* get new active thread */
-		tid = rtgui_panel_get_active_thread(panel);
-		if (tid != RT_NULL)
-		{
-			struct rtgui_event_paint epaint;
-
-			/* send paint event */
-			RTGUI_EVENT_PAINT_INIT(&epaint);
-			epaint.wid = RT_NULL;
-			rtgui_thread_send(tid, (struct rtgui_event*)&epaint, sizeof(epaint));
-		}
-	}
-	else
-	{
-		/* send failed */
-		rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_ERROR);
-	}
-}
-
-void rtgui_server_handle_set_wm(struct rtgui_event_set_wm *event)
-{
-	struct rtgui_panel* panel = rtgui_panel_find(event->panel_name);
-
-	if (panel != RT_NULL)
-	{
-		rtgui_panel_set_wm(panel, event->parent.sender);
-	}
-}
+static struct rtgui_application *rtgui_server_application;
 
 
 void rtgui_server_handle_update(struct rtgui_event_update_end* event)
 void rtgui_server_handle_update(struct rtgui_event_update_end* event)
 {
 {
@@ -199,36 +38,19 @@ void rtgui_server_handle_update(struct rtgui_event_update_end* event)
 
 
 void rtgui_server_handle_monitor_add(struct rtgui_event_monitor* event)
 void rtgui_server_handle_monitor_add(struct rtgui_event_monitor* event)
 {
 {
-	if (event->panel != RT_NULL)
-	{
-		/* append monitor rect to panel list */
-		rtgui_panel_append_monitor_rect(event->panel, event->parent.sender, &(event->rect));
-	}
-	else
-	{
-		/* add monitor rect to top window list */
-		rtgui_topwin_append_monitor_rect(event->wid, &(event->rect));
-	}
+	/* add monitor rect to top window list */
+	rtgui_topwin_append_monitor_rect(event->wid, &(event->rect));
 }
 }
 
 
 void rtgui_server_handle_monitor_remove(struct rtgui_event_monitor* event)
 void rtgui_server_handle_monitor_remove(struct rtgui_event_monitor* event)
 {
 {
-	if (event->panel != RT_NULL)
-	{
-		/* add monitor rect to panel list */
-		rtgui_panel_remove_monitor_rect(event->panel, event->parent.sender, &(event->rect));
-	}
-	else
-	{
-		/* add monitor rect to top window list */
-		rtgui_topwin_remove_monitor_rect(event->wid, &(event->rect));
-	}
+	/* add monitor rect to top window list */
+	rtgui_topwin_remove_monitor_rect(event->wid, &(event->rect));
 }
 }
 
 
 void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
 void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
 {
 {
 	struct rtgui_topwin* wnd;
 	struct rtgui_topwin* wnd;
-	struct rtgui_panel* panel;
 
 
 	/* re-init to server thread */
 	/* re-init to server thread */
 	RTGUI_EVENT_MOUSE_BUTTON_INIT(event);
 	RTGUI_EVENT_MOUSE_BUTTON_INIT(event);
@@ -263,7 +85,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
 			}
 			}
 
 
 			/* send to client thread */
 			/* send to client thread */
-			rtgui_thread_send(topwin->tid, &(ewin.parent), sizeof(ewin));
+			rtgui_application_send(topwin->tid, &(ewin.parent), sizeof(ewin));
 
 
 			return;
 			return;
 		}
 		}
@@ -271,16 +93,15 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
 #endif
 #endif
 
 
 	/* get the wnd which contains the mouse */
 	/* get the wnd which contains the mouse */
-	wnd = rtgui_topwin_get_wnd(event->x, event->y);
+	wnd = rtgui_topwin_get_wnd_no_modaled(event->x, event->y);
 	if (wnd != RT_NULL)
 	if (wnd != RT_NULL)
 	{
 	{
 		event->wid = wnd->wid;
 		event->wid = wnd->wid;
 
 
-		if (rtgui_server_focus_topwin != wnd)
+		if (rtgui_topwin_get_focus() != wnd)
 		{
 		{
 			/* raise this window */
 			/* raise this window */
 			rtgui_topwin_activate_win(wnd);
 			rtgui_topwin_activate_win(wnd);
-			rtgui_server_focus_panel = RT_NULL;
 		}
 		}
 
 
 		if (wnd->title != RT_NULL &&
 		if (wnd->title != RT_NULL &&
@@ -291,137 +112,39 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
 		else
 		else
 		{
 		{
 			/* send mouse event to thread */
 			/* send mouse event to thread */
-			rtgui_thread_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_mouse));
+			rtgui_application_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_mouse));
 		}
 		}
 		return ;
 		return ;
 	}
 	}
-
-	/* get the panel which contains the mouse */
-	panel = rtgui_panel_get_contain(event->x, event->y);
-	if ((panel != RT_NULL) && (panel->is_focusable == RT_TRUE))
-	{
-		/* deactivate old window */
-		if (rtgui_server_focus_topwin != RT_NULL)
-		{
-			rtgui_topwin_deactivate_win(rtgui_server_focus_topwin);
-		}
-
-		rtgui_server_focus_panel = panel;
-		rtgui_server_focus_topwin = RT_NULL;
-
-		/* set destination window to null */
-		event->wid = RT_NULL;
-
-		/* send mouse event to thread */
-		if (rtgui_panel_get_active_thread(panel) != RT_NULL)
-		{
-			rtgui_thread_send(rtgui_panel_get_active_thread(panel),
-				(struct rtgui_event*)event,
-				sizeof(struct rtgui_event_mouse));
-		}
-	}
 }
 }
 
 
-static struct rtgui_panel* last_monitor_panel = RT_NULL;
 static struct rtgui_topwin* last_monitor_topwin = RT_NULL;
 static struct rtgui_topwin* last_monitor_topwin = RT_NULL;
 
 
 void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse* event)
 void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse* event)
 {
 {
 	/* the topwin contains current mouse */
 	/* the topwin contains current mouse */
 	struct rtgui_topwin* win 	= RT_NULL;
 	struct rtgui_topwin* win 	= RT_NULL;
-	struct rtgui_panel* panel 	= RT_NULL;
 
 
 	/* re-init mouse event */
 	/* re-init mouse event */
 	RTGUI_EVENT_MOUSE_MOTION_INIT(event);
 	RTGUI_EVENT_MOUSE_MOTION_INIT(event);
 
 
-	/* find the panel or topwin which monitor the mouse motion */
-	win = rtgui_topwin_get_wnd(event->x, event->y);
-	if (win == RT_NULL)
-	{
-		/* try to find monitor on the panel */
-		panel = rtgui_panel_get_contain(event->x, event->y);
-
-		if (panel != RT_NULL)
-		{
-			struct rtgui_panel_thread* thread;
-
-			/* get active panel thread */
-			if (panel->thread_list.next != RT_NULL)
-			{
-				thread = rtgui_list_entry(panel->thread_list.next, struct rtgui_panel_thread, list);
-				if (!rtgui_mouse_monitor_contains_point(&(thread->monitor_list),
-					event->x, event->y) == RT_TRUE)
-				{
-					/* no monitor in this panel */
-					panel = RT_NULL;
-				}
-			}
-		}
-	}
-	else if (win->monitor_list.next != RT_NULL)
+	win = rtgui_topwin_get_wnd_no_modaled(event->x, event->y);
+	if (win != RT_NULL && win->monitor_list.next != RT_NULL)
 	{
 	{
+		// FIXME:
 		/* check whether the monitor exist */
 		/* check whether the monitor exist */
-		if (rtgui_mouse_monitor_contains_point(&(win->monitor_list), event->x, event->y) != RT_TRUE)
+		if (rtgui_mouse_monitor_contains_point(&(win->monitor_list),
+											   event->x, event->y) != RT_TRUE)
 		{
 		{
 			win = RT_NULL;
 			win = RT_NULL;
-
-			/* try to find monitor on the panel */
-			panel = rtgui_panel_get_contain(event->x, event->y);
-			if (panel != RT_NULL)
-			{
-				struct rtgui_panel_thread* thread;
-
-				/* get active panel thread */
-				if (panel->thread_list.next != RT_NULL)
-				{
-					thread = rtgui_list_entry(panel->thread_list.next, struct rtgui_panel_thread, list);
-					if (!rtgui_mouse_monitor_contains_point(&(thread->monitor_list),
-						event->x, event->y) == RT_TRUE)
-					{
-						/* no monitor in this panel */
-						panel = RT_NULL;
-					}
-				}
-			}
 		}
 		}
 	}
 	}
-	else
-	{
-		win = RT_NULL;
-	}
 
 
-	/* check old panel or window */
-	if (last_monitor_panel != RT_NULL)
-	{
-		rt_thread_t tid = rtgui_panel_get_active_thread(last_monitor_panel);
-
-		/* send mouse motion event */
-		if (tid != RT_NULL)
-		{
-			event->wid = RT_NULL;
-			rtgui_thread_send(tid, &(event->parent), sizeof(struct rtgui_event_mouse));
-		}
-	}
-	else if (last_monitor_topwin != RT_NULL)
+	if (last_monitor_topwin != RT_NULL)
 	{
 	{
 		event->wid = last_monitor_topwin->wid;
 		event->wid = last_monitor_topwin->wid;
-
 		/* send mouse motion event */
 		/* send mouse motion event */
-		rtgui_thread_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse));
-	}
-
-	if (last_monitor_panel != panel)
-	{
-		last_monitor_panel = panel;
-		if (last_monitor_panel != RT_NULL)
-		{
-			rt_thread_t tid = rtgui_panel_get_active_thread(last_monitor_panel);
-			event->wid = RT_NULL;
-
-			/* send mouse motion event */
-			if (tid != RT_NULL)
-				rtgui_thread_send(tid, &(event->parent), sizeof(struct rtgui_event_mouse));
-		}
+		rtgui_application_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse));
 	}
 	}
 
 
 	if (last_monitor_topwin != win)
 	if (last_monitor_topwin != win)
@@ -432,7 +155,7 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse* event)
 			event->wid = last_monitor_topwin->wid;
 			event->wid = last_monitor_topwin->wid;
 
 
 			/* send mouse motion event */
 			/* send mouse motion event */
-			rtgui_thread_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse));
+			rtgui_application_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse));
 		}
 		}
 	}
 	}
 
 
@@ -443,203 +166,191 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse* event)
 void rtgui_server_handle_kbd(struct rtgui_event_kbd* event)
 void rtgui_server_handle_kbd(struct rtgui_event_kbd* event)
 {
 {
 	struct rtgui_topwin* wnd;
 	struct rtgui_topwin* wnd;
-	struct rtgui_panel* panel;
 
 
 	/* re-init to server thread */
 	/* re-init to server thread */
 	RTGUI_EVENT_KBD_INIT(event);
 	RTGUI_EVENT_KBD_INIT(event);
 
 
 	/* todo: handle input method and global shortcut */
 	/* todo: handle input method and global shortcut */
 
 
-	/* send to focus window or focus panel */
-	wnd = rtgui_server_focus_topwin;
-	if (wnd != RT_NULL && wnd->flag & WINTITLE_ACTIVATE)
+	wnd = rtgui_topwin_get_focus();
+	if (wnd != RT_NULL)
 	{
 	{
+		RT_ASSERT(wnd->flag & WINTITLE_ACTIVATE)
+
 		/* send to focus window */
 		/* send to focus window */
 		event->wid = wnd->wid;
 		event->wid = wnd->wid;
 
 
 		/* send keyboard event to thread */
 		/* send keyboard event to thread */
-		rtgui_thread_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_kbd));
+		rtgui_application_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_kbd));
 
 
 		return;
 		return;
 	}
 	}
+}
 
 
-	panel = rtgui_server_focus_panel;
-	if (panel != RT_NULL)
-	{
-		rt_thread_t tid;
+#ifdef _WIN32
+#include <windows.h>
+#endif
 
 
-		/* get active thread in this panel */
-		tid = rtgui_panel_get_active_thread(panel);
-		if (tid != RT_NULL)
-		{
-			/* send to focus panel */
-			event->wid = RT_NULL;
+static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
+                                            struct rtgui_event *event)
+{
+    RT_ASSERT(object != RT_NULL);
+    RT_ASSERT(event != RT_NULL);
+
+    /* dispatch event */
+    switch (event->type)
+    {
+		/* window event */
+    case RTGUI_EVENT_WIN_CREATE:
+        if (rtgui_topwin_add((struct rtgui_event_win_create*)event) == RT_EOK)
+			rtgui_application_ack(event, RTGUI_STATUS_OK);
+		else
+			rtgui_application_ack(event, RTGUI_STATUS_ERROR);
+        break;
+
+    case RTGUI_EVENT_WIN_DESTROY:
+		if (last_monitor_topwin != RT_NULL &&
+			last_monitor_topwin->wid == ((struct rtgui_event_win*)event)->wid)
+				last_monitor_topwin = RT_NULL;
+        if (rtgui_topwin_remove(((struct rtgui_event_win*)event)->wid) == RT_EOK)
+            rtgui_application_ack(event, RTGUI_STATUS_OK);
+        else
+            rtgui_application_ack(event, RTGUI_STATUS_ERROR);
+        break;
+
+    case RTGUI_EVENT_WIN_SHOW:
+        if (rtgui_topwin_show((struct rtgui_event_win*)event) == RT_EOK)
+            rtgui_application_ack(event, RTGUI_STATUS_OK);
+        else
+            rtgui_application_ack(event, RTGUI_STATUS_ERROR);
+        break;
+
+    case RTGUI_EVENT_WIN_HIDE:
+        if (rtgui_topwin_hide((struct rtgui_event_win*)event) == RT_EOK)
+            rtgui_application_ack(event, RTGUI_STATUS_OK);
+        else
+            rtgui_application_ack(event, RTGUI_STATUS_ERROR);
+        break;
+
+    case RTGUI_EVENT_WIN_MOVE:
+        if (rtgui_topwin_move((struct rtgui_event_win_move*)event) == RT_EOK)
+            rtgui_application_ack(event, RTGUI_STATUS_OK);
+        else
+            rtgui_application_ack(event, RTGUI_STATUS_ERROR);
+        break;
+
+	case RTGUI_EVENT_WIN_MODAL_ENTER:
+		if (rtgui_topwin_modal_enter((struct rtgui_event_win_modal_enter*)event) == RT_EOK)
+			rtgui_application_ack(event, RTGUI_STATUS_OK);
+		else
+			rtgui_application_ack(event, RTGUI_STATUS_ERROR);
+		break;
 
 
-			/* send keyboard event to thread */
-			rtgui_thread_send(tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_kbd));
-		}
-	}
-}
+    case RTGUI_EVENT_WIN_RESIZE:
+        rtgui_topwin_resize(((struct rtgui_event_win_resize*)event)->wid,
+                &(((struct rtgui_event_win_resize*)event)->rect));
+        break;
 
 
-#ifdef __WIN32__
-#include <windows.h>
+        /* other event */
+    case RTGUI_EVENT_UPDATE_BEGIN:
+#ifdef RTGUI_USING_MOUSE_CURSOR
+        /* hide cursor */
+        rtgui_mouse_hide_cursor();
 #endif
 #endif
+        break;
+
+    case RTGUI_EVENT_UPDATE_END:
+        /* handle screen update */
+        rtgui_server_handle_update((struct rtgui_event_update_end*)event);
+#ifdef RTGUI_USING_MOUSE_CURSOR
+        /* show cursor */
+        rtgui_mouse_show_cursor();
+#endif
+        break;
+
+    case RTGUI_EVENT_MONITOR_ADD:
+        /* handle mouse monitor */
+        rtgui_server_handle_monitor_add((struct rtgui_event_monitor*)event);
+        break;
+
+        /* mouse and keyboard event */
+    case RTGUI_EVENT_MOUSE_MOTION:
+        /* handle mouse motion event */
+        rtgui_server_handle_mouse_motion((struct rtgui_event_mouse*)event);
+        break;
+
+    case RTGUI_EVENT_MOUSE_BUTTON:
+        /* handle mouse button */
+        rtgui_server_handle_mouse_btn((struct rtgui_event_mouse*)event);
+        break;
+
+    case RTGUI_EVENT_KBD:
+        /* handle keyboard event */
+        rtgui_server_handle_kbd((struct rtgui_event_kbd*)event);
+        break;
+
+    case RTGUI_EVENT_COMMAND:
+        break;
+    }
+
+	return RT_TRUE;
+}
 
 
 /**
 /**
  * rtgui server thread's entry
  * rtgui server thread's entry
  */
  */
 static void rtgui_server_entry(void* parameter)
 static void rtgui_server_entry(void* parameter)
 {
 {
-#ifdef __WIN32__
+#ifdef _WIN32
 	/* set the server thread to highest */
 	/* set the server thread to highest */
 	HANDLE hCurrentThread = GetCurrentThread();
 	HANDLE hCurrentThread = GetCurrentThread();
 	SetThreadPriority(hCurrentThread, THREAD_PRIORITY_HIGHEST);
 	SetThreadPriority(hCurrentThread, THREAD_PRIORITY_HIGHEST);
 #endif
 #endif
 
 
-#ifdef RTGUI_USING_SMALL_SIZE
-	/* create rtgui server msgq */
-	rtgui_server_mq = rt_mq_create("rtgui",
-		32, 16, RT_IPC_FLAG_FIFO);
-#else
-	/* create rtgui server msgq */
-	rtgui_server_mq = rt_mq_create("rtgui",
-		256, 8, RT_IPC_FLAG_FIFO);
-#endif
 	/* register rtgui server thread */
 	/* register rtgui server thread */
-	rtgui_thread_register(rtgui_server_tid, rtgui_server_mq);
+	rtgui_server_application = rtgui_application_create(rtgui_server_tid,
+                                                        "rtgui");
+    if (rtgui_server_application == RT_NULL)
+        return;
 
 
+    rtgui_object_set_event_handler(RTGUI_OBJECT(rtgui_server_application),
+                                   rtgui_server_event_handler);
 	/* init mouse and show */
 	/* init mouse and show */
 	rtgui_mouse_init();
 	rtgui_mouse_init();
 #ifdef RTGUI_USING_MOUSE_CURSOR
 #ifdef RTGUI_USING_MOUSE_CURSOR
 	rtgui_mouse_show_cursor();
 	rtgui_mouse_show_cursor();
 #endif
 #endif
 
 
-	while (1)
-	{
-		/* the buffer uses to receive event */
-#ifdef RTGUI_USING_SMALL_SIZE
-		char event_buf[64];
-#else
-		char event_buf[256];
-#endif
-		struct rtgui_event* event = (struct rtgui_event*)&(event_buf[0]);
+    rtgui_application_run(rtgui_server_application);
 
 
-		if (rtgui_thread_recv(event, sizeof(event_buf)) == RT_EOK)
-		{
-			/* dispatch event */
-			switch (event->type)
-			{
-			/* panel event */
-			case RTGUI_EVENT_PANEL_ATTACH:
-				/* register an application in panel */
-				rtgui_server_create_application((struct rtgui_event_panel_attach*)event);
-				break;
-
-			case RTGUI_EVENT_PANEL_DETACH:
-				/* unregister an application */
-				rtgui_server_destroy_application((struct rtgui_event_panel_detach*)event);
-				break;
-
-			case RTGUI_EVENT_PANEL_SHOW:
-				/* handle raise an application */
-				rtgui_server_thread_panel_show((struct rtgui_event_panel_show*)event);
-				break;
-
-			case RTGUI_EVENT_PANEL_HIDE:
-				/* handle hide an application */
-				rtgui_server_thread_panel_hide((struct rtgui_event_panel_hide*)event);
-				break;
-
-			case RTGUI_EVENT_SET_WM:
-				/* handle set workbench manager event */
-				rtgui_server_handle_set_wm((struct rtgui_event_set_wm*)event);
-				break;
-
-			/* window event */
-			case RTGUI_EVENT_WIN_CREATE:
-				rtgui_thread_ack(event, RTGUI_STATUS_OK);
-				rtgui_topwin_add((struct rtgui_event_win_create*)event);
-				break;
-
-			case RTGUI_EVENT_WIN_DESTROY:
-				if (rtgui_topwin_remove(((struct rtgui_event_win*)event)->wid) == RT_EOK)
-					rtgui_thread_ack(event, RTGUI_STATUS_OK);
-				else
-					rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
-				break;
-
-			case RTGUI_EVENT_WIN_SHOW:
-				rtgui_topwin_show((struct rtgui_event_win*)event);
-				break;
-
-			case RTGUI_EVENT_WIN_HIDE:
-				rtgui_topwin_hide((struct rtgui_event_win*)event);
-				break;
-
-			case RTGUI_EVENT_WIN_MOVE:
-				rtgui_topwin_move((struct rtgui_event_win_move*)event);
-				break;
-
-			case RTGUI_EVENT_WIN_RESIZE:
-				rtgui_topwin_resize(((struct rtgui_event_win_resize*)event)->wid,
-					&(((struct rtgui_event_win_resize*)event)->rect));
-				break;
-
-			/* other event */
-			case RTGUI_EVENT_UPDATE_BEGIN:
-#ifdef RTGUI_USING_MOUSE_CURSOR
-				/* hide cursor */
-				rtgui_mouse_hide_cursor();
-#endif
-				break;
-
-			case RTGUI_EVENT_UPDATE_END:
-				/* handle screen update */
-				rtgui_server_handle_update((struct rtgui_event_update_end*)event);
-#ifdef RTGUI_USING_MOUSE_CURSOR
-				/* show cursor */
-				rtgui_mouse_show_cursor();
-#endif
-				break;
-
-			case RTGUI_EVENT_MONITOR_ADD:
-				/* handle mouse monitor */
-				rtgui_server_handle_monitor_add((struct rtgui_event_monitor*)event);
-				break;
-
-			/* mouse and keyboard event */
-			case RTGUI_EVENT_MOUSE_MOTION:
-				/* handle mouse motion event */
-				rtgui_server_handle_mouse_motion((struct rtgui_event_mouse*)event);
-				break;
-
-			case RTGUI_EVENT_MOUSE_BUTTON:
-				/* handle mouse button */
-				rtgui_server_handle_mouse_btn((struct rtgui_event_mouse*)event);
-				break;
-
-			case RTGUI_EVENT_KBD:
-				/* handle keyboard event */
-				rtgui_server_handle_kbd((struct rtgui_event_kbd*)event);
-				break;
-
-			case RTGUI_EVENT_COMMAND:
-				break;
-			}
-		}
-	}
-
-	/* unregister in rtgui thread */
-	// rtgui_thread_deregister(rt_thread_self());
+    rtgui_application_destroy(rtgui_server_application);
+    rtgui_server_application = RT_NULL;
 }
 }
 
 
 void rtgui_server_post_event(struct rtgui_event* event, rt_size_t size)
 void rtgui_server_post_event(struct rtgui_event* event, rt_size_t size)
 {
 {
-	rt_mq_send(rtgui_server_mq, event, size);
+	if (rtgui_server_tid != RT_NULL)
+		rtgui_application_send(rtgui_server_tid, event, size);
+	else
+		rt_kprintf("post when server is not running\n");
+}
+
+rt_err_t rtgui_server_post_event_sync(struct rtgui_event* event, rt_size_t size)
+{
+	if (rtgui_server_tid != RT_NULL)
+		return rtgui_application_send_sync(rtgui_server_tid, event, size);
+	else
+	{
+		rt_kprintf("post when server is not running\n");
+		return -RT_ENOSYS;
+	}
 }
 }
 
 
-void rtgui_server_init()
+void rtgui_server_init(void)
 {
 {
+    if (rtgui_server_tid != RT_NULL)
+        return;
+
 	rtgui_server_tid = rt_thread_create("rtgui",
 	rtgui_server_tid = rt_thread_create("rtgui",
 		rtgui_server_entry, RT_NULL,
 		rtgui_server_entry, RT_NULL,
 		RTGUI_SVR_THREAD_STACK_SIZE,
 		RTGUI_SVR_THREAD_STACK_SIZE,

File diff suppressed because it is too large
+ 571 - 396
components/rtgui/server/topwin.c


+ 10 - 12
components/rtgui/server/topwin.h

@@ -15,7 +15,6 @@
 #define __RTGUI_TOPWIN_H__
 #define __RTGUI_TOPWIN_H__
 
 
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui.h>
-#include <rtgui/list.h>
 #include <rtgui/region.h>
 #include <rtgui/region.h>
 #include <rtgui/event.h>
 #include <rtgui/event.h>
 #include <rtgui/widgets/title.h>
 #include <rtgui/widgets/title.h>
@@ -25,25 +24,24 @@
 rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event);
 rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event);
 rt_err_t rtgui_topwin_remove(struct rtgui_win* wid);
 rt_err_t rtgui_topwin_remove(struct rtgui_win* wid);
 
 
-/* raise window to front */
-void rtgui_topwin_raise(struct rtgui_win* wid, rt_thread_t sender);
-/* update clip info to a panel */
-void rtgui_topwin_update_clip_to_panel(struct rtgui_panel* panel);
+void rtgui_topwin_activate_win(struct rtgui_topwin* win);
 
 
 /* show a window */
 /* show a window */
-void rtgui_topwin_show(struct rtgui_event_win* event);
+rt_err_t rtgui_topwin_show(struct rtgui_event_win* event);
 /* hide a window */
 /* hide a window */
-void rtgui_topwin_hide(struct rtgui_event_win* event);
+rt_err_t rtgui_topwin_hide(struct rtgui_event_win* event);
 /* move a window */
 /* move a window */
-void rtgui_topwin_move(struct rtgui_event_win_move* event);
+rt_err_t rtgui_topwin_move(struct rtgui_event_win_move* event);
 /* resize a window */
 /* resize a window */
 void rtgui_topwin_resize(struct rtgui_win* wid, rtgui_rect_t* r);
 void rtgui_topwin_resize(struct rtgui_win* wid, rtgui_rect_t* r);
+/* a window is entering modal mode */
+rt_err_t rtgui_topwin_modal_enter(struct rtgui_event_win_modal_enter* event);
 
 
 /* get window at (x, y) */
 /* get window at (x, y) */
 struct rtgui_topwin* rtgui_topwin_get_wnd(int x, int y);
 struct rtgui_topwin* rtgui_topwin_get_wnd(int x, int y);
+struct rtgui_topwin* rtgui_topwin_get_wnd_no_modaled(int x, int y);
 
 
-void rtgui_topwin_activate_win(struct rtgui_topwin* win);
-void rtgui_topwin_deactivate_win(struct rtgui_topwin* win);
+//void rtgui_topwin_deactivate_win(struct rtgui_topwin* win);
 
 
 /* window title */
 /* window title */
 void rtgui_topwin_title_ondraw(struct rtgui_topwin* win);
 void rtgui_topwin_title_ondraw(struct rtgui_topwin* win);
@@ -53,7 +51,7 @@ void rtgui_topwin_title_onmouse(struct rtgui_topwin* win, struct rtgui_event_mou
 void rtgui_topwin_append_monitor_rect(struct rtgui_win* wid, rtgui_rect_t* rect);
 void rtgui_topwin_append_monitor_rect(struct rtgui_win* wid, rtgui_rect_t* rect);
 void rtgui_topwin_remove_monitor_rect(struct rtgui_win* wid, rtgui_rect_t* rect);
 void rtgui_topwin_remove_monitor_rect(struct rtgui_win* wid, rtgui_rect_t* rect);
 
 
-void rtgui_topwin_do_clip(rtgui_widget_t* widget);
-
+/* get the topwin that is currently focused */
+struct rtgui_topwin* rtgui_topwin_get_focus(void);
 #endif
 #endif
 
 

+ 101 - 101
components/rtgui/widgets/about_view.c

@@ -1,101 +1,101 @@
-/*
- * File      : about_view.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-01-06     Bernard      first version
- */
-
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/about_view.h>
-
-static void _rtgui_about_view_constructor(struct rtgui_about_view *view)
-{
-	/* default rect */
-	struct rtgui_rect rect = {0, 0, 200, 200};
-
-	/* set default widget rect and set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(view),rtgui_about_view_event_handler);
-	rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
-
-	RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
-	view->logo = RT_NULL;
-	view->description = RT_NULL;
-
-	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(aboutview, "aboutview", 
-	RTGUI_VIEW_TYPE,
-	_rtgui_about_view_constructor,
-	RT_NULL,
-	sizeof(struct rtgui_about_view));
-
-void rtgui_about_view_ondraw(struct rtgui_about_view* view)
-{
-	struct rtgui_rect rect;
-	struct rtgui_dc* dc;
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
-	if (dc == RT_NULL) return;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-	rtgui_dc_fill_rect(dc, &rect);
-
-	if (view->logo != RT_NULL)
-		rtgui_image_blit(view->logo, dc, &rect);
-
-	rect.y1 += view->logo->h + 5;
-	if (view->description != RT_NULL)
-		rtgui_dc_draw_text(dc, view->description, &rect);
-
-	rect.y1 += rtgui_dc_get_gc(dc)->font->height;
-	rtgui_dc_draw_hline(dc, rect.x1 + 3, rect.x2 - 3, rect.y1);
-	RTGUI_DC_FC(dc) = white;
-	rtgui_dc_draw_hline(dc, rect.x1 + 4, rect.x2 - 2, rect.y1 + 1);
-
-	rtgui_dc_end_drawing(dc);
-}
-
-rt_bool_t rtgui_about_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_about_view* view = RT_NULL;
-
-	view = RTGUI_ABOUT_VIEW(widget);
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-		rtgui_about_view_ondraw(view);
-		return RT_FALSE;
-	}
-
-    /* use view event handler */
-    return rtgui_view_event_handler(widget, event);
-}
-
-rtgui_about_view_t* rtgui_about_view_create(rtgui_image_t *logo, const char* description)
-{
-	struct rtgui_about_view* view = RT_NULL;
-
-	view = (struct rtgui_about_view*) rtgui_widget_create(RTGUI_ABOUT_VIEW_TYPE);
-	if (view != RT_NULL)
-	{
-	    view->logo = logo;
-	    view->description = description;
-	}
-
-	return view;
-}
-
-void rtgui_about_view_destroy(rtgui_about_view_t* view)
-{
-    /* destroy view */
-	rtgui_widget_destroy(RTGUI_WIDGET(view));
-}
+/*
+ * File      : about_view.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-01-06     Bernard      first version
+ */
+
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/about_view.h>
+
+static void _rtgui_about_view_constructor(struct rtgui_about_view *view)
+{
+	/* default rect */
+	struct rtgui_rect rect = {0, 0, 200, 200};
+
+	/* set default widget rect and set event handler */
+	rtgui_object_set_event_handler(RTGUI_OBJECT(view),rtgui_about_view_event_handler);
+	rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
+
+	RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+	view->logo = RT_NULL;
+	view->description = RT_NULL;
+
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(aboutview, "aboutview", 
+	RTGUI_CONTAINER_TYPE,
+	_rtgui_about_view_constructor,
+	RT_NULL,
+	sizeof(struct rtgui_about_view));
+
+void rtgui_about_view_ondraw(struct rtgui_about_view* view)
+{
+	struct rtgui_rect rect;
+	struct rtgui_dc* dc;
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+	if (dc == RT_NULL) return;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+	rtgui_dc_fill_rect(dc, &rect);
+
+	if (view->logo != RT_NULL)
+		rtgui_image_blit(view->logo, dc, &rect);
+
+	rect.y1 += view->logo->h + 5;
+	if (view->description != RT_NULL)
+		rtgui_dc_draw_text(dc, view->description, &rect);
+
+	rect.y1 += rtgui_dc_get_gc(dc)->font->height;
+	rtgui_dc_draw_hline(dc, rect.x1 + 3, rect.x2 - 3, rect.y1);
+	RTGUI_DC_FC(dc) = white;
+	rtgui_dc_draw_hline(dc, rect.x1 + 4, rect.x2 - 2, rect.y1 + 1);
+
+	rtgui_dc_end_drawing(dc);
+}
+
+rt_bool_t rtgui_about_view_event_handler(struct rtgui_object* widget, struct rtgui_event* event)
+{
+	struct rtgui_about_view* view = RT_NULL;
+
+	view = RTGUI_ABOUT_VIEW(widget);
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+		rtgui_about_view_ondraw(view);
+		return RT_FALSE;
+	}
+
+    /* use view event handler */
+    return rtgui_container_event_handler(widget, event);
+}
+
+rtgui_about_view_t* rtgui_about_view_create(rtgui_image_t *logo, const char* description)
+{
+	struct rtgui_about_view* view = RT_NULL;
+
+	view = (struct rtgui_about_view*) rtgui_widget_create(RTGUI_ABOUT_VIEW_TYPE);
+	if (view != RT_NULL)
+	{
+	    view->logo = logo;
+	    view->description = description;
+	}
+
+	return view;
+}
+
+void rtgui_about_view_destroy(rtgui_about_view_t* view)
+{
+    /* destroy view */
+	rtgui_widget_destroy(RTGUI_WIDGET(view));
+}

+ 9 - 7
components/rtgui/widgets/box.c

@@ -18,23 +18,23 @@
 static void _rtgui_box_constructor(rtgui_box_t *box)
 static void _rtgui_box_constructor(rtgui_box_t *box)
 {
 {
 	/* init widget and set event handler */
 	/* init widget and set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_box_event_handler);
+	rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_box_event_handler);
 
 
 	RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_TRANSPARENT;
 	RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_TRANSPARENT;
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_box_event_handler);
+	rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_box_event_handler);
 
 
 	/* set proper of control */
 	/* set proper of control */
 	box->orient = RTGUI_HORIZONTAL;
 	box->orient = RTGUI_HORIZONTAL;
 	box->border_size = RTGUI_BORDER_DEFAULT_WIDTH;
 	box->border_size = RTGUI_BORDER_DEFAULT_WIDTH;
 }
 }
 
 
-DEFINE_CLASS_TYPE(box, "box", 
+DEFINE_CLASS_TYPE(box, "box",
 	RTGUI_CONTAINER_TYPE,
 	RTGUI_CONTAINER_TYPE,
 	_rtgui_box_constructor,
 	_rtgui_box_constructor,
 	RT_NULL,
 	RT_NULL,
 	sizeof(struct rtgui_box));
 	sizeof(struct rtgui_box));
 
 
-rt_bool_t rtgui_box_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
+rt_bool_t rtgui_box_event_handler(struct rtgui_object *widget, rtgui_event_t *event)
 {
 {
 	struct rtgui_box* box = (struct rtgui_box*)widget;
 	struct rtgui_box* box = (struct rtgui_box*)widget;
 
 
@@ -48,7 +48,7 @@ rt_bool_t rtgui_box_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
 		break;
 		break;
 
 
 	default:
 	default:
-		return rtgui_container_event_handler(RTGUI_WIDGET(box), event);
+		return rtgui_container_event_handler(RTGUI_OBJECT(box), event);
 	}
 	}
 
 
 	return RT_FALSE;
 	return RT_FALSE;
@@ -166,7 +166,8 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box)
 		size_event.y = rect->y1;
 		size_event.y = rect->y1;
 		size_event.w = rect->x2 - rect->x1;
 		size_event.w = rect->x2 - rect->x1;
 		size_event.h = rect->y2 - rect->y1;
 		size_event.h = rect->y2 - rect->y1;
-		widget->event_handler(widget, &size_event.parent);
+		RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget),
+											&size_event.parent);
 
 
 		/* point to next height */
 		/* point to next height */
 		next_y = rect->y2;
 		next_y = rect->y2;
@@ -258,7 +259,8 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box)
 		size_event.y = rect->y1;
 		size_event.y = rect->y1;
 		size_event.w = rect->x2 - rect->x1;
 		size_event.w = rect->x2 - rect->x1;
 		size_event.h = rect->y2 - rect->y1;
 		size_event.h = rect->y2 - rect->y1;
-		widget->event_handler(widget, &size_event.parent);
+		RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget),
+											&size_event.parent);
 
 
 		/* point to next width */
 		/* point to next width */
 		next_x = rect->x2;
 		next_x = rect->x2;

+ 11 - 8
components/rtgui/widgets/button.c

@@ -14,13 +14,13 @@
 #include <rtgui/dc.h>
 #include <rtgui/dc.h>
 #include <rtgui/rtgui_theme.h>
 #include <rtgui/rtgui_theme.h>
 #include <rtgui/widgets/button.h>
 #include <rtgui/widgets/button.h>
-#include <rtgui/widgets/toplevel.h>
+#include <rtgui/widgets/window.h>
 
 
 static void _rtgui_button_constructor(rtgui_button_t *button)
 static void _rtgui_button_constructor(rtgui_button_t *button)
 {
 {
 	/* init widget and set event handler */
 	/* init widget and set event handler */
 	RTGUI_WIDGET(button)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
 	RTGUI_WIDGET(button)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(button), rtgui_button_event_handler);
+	rtgui_object_set_event_handler(RTGUI_OBJECT(button), rtgui_button_event_handler);
 
 
 	/* un-press button */
 	/* un-press button */
 	button->flag = 0;
 	button->flag = 0;
@@ -57,13 +57,16 @@ DEFINE_CLASS_TYPE(button, "button",
 	_rtgui_button_destructor,
 	_rtgui_button_destructor,
 	sizeof(struct rtgui_button));
 	sizeof(struct rtgui_button));
 
 
-rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+rt_bool_t rtgui_button_event_handler(struct rtgui_object* object, struct rtgui_event* event)
 {
 {
-	struct rtgui_button* btn;
+	struct rtgui_widget *widget;
+	struct rtgui_button *btn;
 
 
 	RT_ASSERT(widget != RT_NULL);
 	RT_ASSERT(widget != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
 
 
-	btn = (struct rtgui_button*) widget;
+	widget = RTGUI_WIDGET(object);
+	btn = RTGUI_BUTTON(widget);
 	switch (event->type)
 	switch (event->type)
 	{
 	{
 	case RTGUI_EVENT_PAINT:
 	case RTGUI_EVENT_PAINT:
@@ -150,10 +153,10 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_e
 				if (emouse->button & RTGUI_MOUSE_BUTTON_LEFT)
 				if (emouse->button & RTGUI_MOUSE_BUTTON_LEFT)
 				{
 				{
 					/* set the last mouse event handled widget */
 					/* set the last mouse event handled widget */
-					rtgui_toplevel_t* toplevel;
+					struct rtgui_win* win;
 
 
-					toplevel = RTGUI_TOPLEVEL(RTGUI_WIDGET(btn)->toplevel);
-					toplevel->last_mevent_widget = RTGUI_WIDGET(btn);
+					win = RTGUI_WIN(RTGUI_WIDGET(btn)->toplevel);
+					win->last_mevent_widget = RTGUI_WIDGET(btn);
 
 
 					/* it's a normal button */
 					/* it's a normal button */
 					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
 					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)

+ 153 - 146
components/rtgui/widgets/checkbox.c

@@ -1,146 +1,153 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/checkbox.h>
-
-static void _rtgui_checkbox_constructor(rtgui_checkbox_t *box)
-{
-	/* init widget and set event handler */
-	RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_checkbox_event_handler);
-
-	/* set status */
-	box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
-	box->on_button = RT_NULL;
-
-	/* set default gc */
-	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(checkbox, "checkbox", 
-	RTGUI_LABEL_TYPE,
-	_rtgui_checkbox_constructor,
-	RT_NULL,
-	sizeof(struct rtgui_checkbox));
-
-void rtgui_checkbox_set_onbutton(rtgui_checkbox_t* checkbox, rtgui_onbutton_func_t func)
-{
-	RT_ASSERT(checkbox != RT_NULL);
-
-	checkbox->on_button = func;
-}
-
-rt_bool_t rtgui_checkbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_checkbox* box = (struct rtgui_checkbox*)widget;
-
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-#ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_draw != RT_NULL)
-		{
-			return widget->on_draw(widget, event);
-		}
-		else
-#endif
-			rtgui_theme_draw_checkbox(box);
-		break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-		{
-			if (RTGUI_WIDGET_IS_ENABLE(widget) && !RTGUI_WIDGET_IS_HIDE(widget))
-			{
-				struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;
-				if (emouse->button & RTGUI_MOUSE_BUTTON_LEFT &&
-					emouse->button & RTGUI_MOUSE_BUTTON_UP)
-				{
-					/* set focus */
-					rtgui_widget_focus(widget);
-
-					if (box->status_down & RTGUI_CHECKBOX_STATUS_UNCHECKED)
-					{
-						/* check it */
-						box->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
-					}
-					else
-					{
-						/* un-check it */
-						box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
-					}
-				}
-
-				/* draw checkbox */
-				rtgui_theme_draw_checkbox(box);
-
-#ifndef RTGUI_USING_SMALL_SIZE
-				/* call user callback */
-				if (widget->on_mouseclick != RT_NULL)
-				{
-					return widget->on_mouseclick(widget, event);
-				}
-#endif
-				if (box->on_button != RT_NULL)
-				{
-					box->on_button(widget, event);
-					return RT_TRUE;
-				}
-			}
-
-			return RT_TRUE;
-		}
-	}
-
-	return RT_FALSE;
-}
-
-struct rtgui_checkbox* rtgui_checkbox_create(const char* text, rt_bool_t checked)
-{
-    struct rtgui_checkbox* box;
-
-    box = (struct rtgui_checkbox*) rtgui_widget_create (RTGUI_CHECKBOX_TYPE);
-    if (box != RT_NULL)
-    {
-		rtgui_rect_t rect;
-
-		/* set default rect */
-		rtgui_font_get_metrics(rtgui_font_default(), text, &rect);
-		rect.x2 += RTGUI_BORDER_DEFAULT_WIDTH + 5 + (RTGUI_BORDER_DEFAULT_WIDTH << 1);
-		rect.y2 += (RTGUI_BORDER_DEFAULT_WIDTH << 1);
-
-		rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
-		rtgui_label_set_text(RTGUI_LABEL(box), text);
-		
-		if (checked == RT_TRUE)
-			box->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
-		else
-			box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
-	}
-
-	return box;
-}
-
-void rtgui_checkbox_destroy(rtgui_checkbox_t* box)
-{
-	rtgui_widget_destroy(RTGUI_WIDGET(box));
-}
-
-void rtgui_checkbox_set_checked(rtgui_checkbox_t* checkbox, rt_bool_t checked)
-{
-	RT_ASSERT(checkbox != RT_NULL);
-	if (checked == RT_TRUE)
-		checkbox->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
-	else
-		checkbox->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
-		
-}
-
-rt_bool_t rtgui_checkbox_get_checked(rtgui_checkbox_t* checkbox)
-{
-	RT_ASSERT(checkbox != RT_NULL);
-
-	if (checkbox->status_down == RTGUI_CHECKBOX_STATUS_CHECKED)
-		return RT_TRUE;
-
-	return RT_FALSE;
-}
-
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/checkbox.h>
+
+static void _rtgui_checkbox_constructor(rtgui_checkbox_t *box)
+{
+	/* init widget and set event handler */
+	RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+	rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_checkbox_event_handler);
+
+	/* set status */
+	box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
+	box->on_button = RT_NULL;
+
+	/* set default gc */
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(checkbox, "checkbox", 
+	RTGUI_LABEL_TYPE,
+	_rtgui_checkbox_constructor,
+	RT_NULL,
+	sizeof(struct rtgui_checkbox));
+
+void rtgui_checkbox_set_onbutton(rtgui_checkbox_t* checkbox, rtgui_onbutton_func_t func)
+{
+	RT_ASSERT(checkbox != RT_NULL);
+
+	checkbox->on_button = func;
+}
+
+rt_bool_t rtgui_checkbox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_widget *widget;
+	struct rtgui_checkbox *box = (struct rtgui_checkbox*)widget;
+
+	RT_ASSERT(widget != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	widget = RTGUI_WIDGET(object);
+	box = RTGUI_CHECKBOX(object);
+
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+#ifndef RTGUI_USING_SMALL_SIZE
+		if (widget->on_draw != RT_NULL)
+		{
+			return widget->on_draw(widget, event);
+		}
+		else
+#endif
+			rtgui_theme_draw_checkbox(box);
+		break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+		{
+			if (RTGUI_WIDGET_IS_ENABLE(widget) && !RTGUI_WIDGET_IS_HIDE(widget))
+			{
+				struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;
+				if (emouse->button & RTGUI_MOUSE_BUTTON_LEFT &&
+					emouse->button & RTGUI_MOUSE_BUTTON_UP)
+				{
+					/* set focus */
+					rtgui_widget_focus(widget);
+
+					if (box->status_down & RTGUI_CHECKBOX_STATUS_UNCHECKED)
+					{
+						/* check it */
+						box->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
+					}
+					else
+					{
+						/* un-check it */
+						box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
+					}
+				}
+
+				/* draw checkbox */
+				rtgui_theme_draw_checkbox(box);
+
+#ifndef RTGUI_USING_SMALL_SIZE
+				/* call user callback */
+				if (widget->on_mouseclick != RT_NULL)
+				{
+					return widget->on_mouseclick(widget, event);
+				}
+#endif
+				if (box->on_button != RT_NULL)
+				{
+					box->on_button(widget, event);
+					return RT_TRUE;
+				}
+			}
+
+			return RT_TRUE;
+		}
+	}
+
+	return RT_FALSE;
+}
+
+struct rtgui_checkbox* rtgui_checkbox_create(const char* text, rt_bool_t checked)
+{
+    struct rtgui_checkbox* box;
+
+    box = (struct rtgui_checkbox*) rtgui_widget_create (RTGUI_CHECKBOX_TYPE);
+    if (box != RT_NULL)
+    {
+		rtgui_rect_t rect;
+
+		/* set default rect */
+		rtgui_font_get_metrics(rtgui_font_default(), text, &rect);
+		rect.x2 += RTGUI_BORDER_DEFAULT_WIDTH + 5 + (RTGUI_BORDER_DEFAULT_WIDTH << 1);
+		rect.y2 += (RTGUI_BORDER_DEFAULT_WIDTH << 1);
+
+		rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
+		rtgui_label_set_text(RTGUI_LABEL(box), text);
+		
+		if (checked == RT_TRUE)
+			box->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
+		else
+			box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
+	}
+
+	return box;
+}
+
+void rtgui_checkbox_destroy(rtgui_checkbox_t* box)
+{
+	rtgui_widget_destroy(RTGUI_WIDGET(box));
+}
+
+void rtgui_checkbox_set_checked(rtgui_checkbox_t* checkbox, rt_bool_t checked)
+{
+	RT_ASSERT(checkbox != RT_NULL);
+	if (checked == RT_TRUE)
+		checkbox->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
+	else
+		checkbox->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
+		
+}
+
+rt_bool_t rtgui_checkbox_get_checked(rtgui_checkbox_t* checkbox)
+{
+	RT_ASSERT(checkbox != RT_NULL);
+
+	if (checkbox->status_down == RTGUI_CHECKBOX_STATUS_CHECKED)
+		return RT_TRUE;
+
+	return RT_FALSE;
+}
+

+ 276 - 259
components/rtgui/widgets/combobox.c

@@ -1,259 +1,276 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/combobox.h>
-
-static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_widget* widget, struct rtgui_event* event);
-const static rt_uint8_t down_arrow[]  = {0xff, 0x7e, 0x3c, 0x18};
-
-static void _rtgui_combobox_constructor(rtgui_combobox_t *box)
-{
-	rtgui_rect_t rect = {0, 0, RTGUI_COMBOBOX_WIDTH, RTGUI_COMBOBOX_HEIGHT};
-
-	/* init widget and set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_combobox_event_handler);
-	rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
-
-	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL;
-
-	box->pd_pressed = RT_FALSE;
-	box->current_item = 0;
-	box->on_selected = RT_NULL;
-	box->pd_win    = RT_NULL;
-}
-
-static void _rtgui_combobox_destructor(rtgui_combobox_t *box)
-{
-	/* destroy pull down window */
-	rtgui_win_destroy(box->pd_win);
-
-	/* reset box field */
-	box->pd_win    = RT_NULL;
-}
-
-void rtgui_combobox_pdwin_onitem(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	rtgui_win_t* pd_win;
-	rtgui_combobox_t* combo;
-	rtgui_listbox_t* list;
-
-	list = RTGUI_LISTBOX(widget);
-	pd_win = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
-	combo = RTGUI_COMBOBOX(pd_win->user_data);
-	combo->current_item = list->current_item;
-
-	if (combo->on_selected != RT_NULL)
-		combo->on_selected(RTGUI_WIDGET(combo), RT_NULL);
-
-	rtgui_win_hiden(pd_win);
-	rtgui_widget_update(RTGUI_WIDGET(combo));
-
-	return ;
-}
-
-rt_bool_t rtgui_combobox_pdwin_ondeactive(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	rtgui_win_hiden(RTGUI_WIN(widget));
-	return RT_TRUE;
-}
-
-DEFINE_CLASS_TYPE(combobox, "combobox", 
-	RTGUI_WIDGET_TYPE,
-	_rtgui_combobox_constructor,
-	_rtgui_combobox_destructor,
-	sizeof(struct rtgui_combobox));
-
-rtgui_combobox_t *rtgui_combobox_create(struct rtgui_listbox_item* items, rt_uint16_t count, struct rtgui_rect* rect)
-{
-	rtgui_combobox_t *box;
-
-	box = (rtgui_combobox_t*)rtgui_widget_create(RTGUI_COMBOBOX_TYPE);
-	box->items_count = count;
-	box->items = items;
-	rtgui_widget_set_rect(RTGUI_WIDGET(box), rect);
-	
-	box->pd_win = RT_NULL;
-
-	return box;
-}
-
-void rtgui_combobox_destroy(rtgui_combobox_t* box)
-{
-	rtgui_widget_destroy(RTGUI_WIDGET(box));
-}
-
-static void rtgui_combobox_ondraw(struct rtgui_combobox* box)
-{
-	/* draw button */
-	rtgui_color_t bc;
-	struct rtgui_dc* dc;
-	struct rtgui_rect rect, r;
-
-	/* begin drawing */
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
-	if (dc == RT_NULL) return;
-
-	bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box));
-
-	/* get widget rect */
-	rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
-	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
-
-	/* fill widget rect with background color */
-	rtgui_dc_fill_rect(dc, &rect);
-	rtgui_dc_draw_rect(dc, &rect);
-
-	/* draw current item */
-	if (box->current_item < box->items_count)
-	{
-		rect.x1 += 5;
-		rtgui_dc_draw_text(dc, box->items[box->current_item].name, &rect);
-	}
-
-	/* restore background color */
-	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = bc;
-
-	/* draw pull down button */
-	rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH;
-	rtgui_rect_inflate(&rect, -1);
-	rtgui_dc_fill_rect(dc, &rect);
-	if (box->pd_pressed == RT_TRUE) rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN);
-	else rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_RAISE);
-
-	r.x1 = 0; r.y1 = 0; r.x2 = 8; r.y2 = 4;
-	rtgui_rect_moveto_align(&rect, &r, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
-	rtgui_dc_draw_byte(dc, r.x1, r.y1, 4, down_arrow);
-
-	/* end drawing */
-	rtgui_dc_end_drawing(dc);
-	return;
-}
-
-static rt_bool_t rtgui_combobox_onmouse_button(struct rtgui_combobox* box, struct rtgui_event_mouse* event)
-{
-	struct rtgui_rect rect;
-
-	/* get widget rect */
-	rect = RTGUI_WIDGET(box)->extent;
-
-	/* move to the pull down button */
-	rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH;
-	if (rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
-	{
-		/* handle mouse button on pull down button */
-		if (event->button & RTGUI_MOUSE_BUTTON_LEFT &&
-			event->button & RTGUI_MOUSE_BUTTON_DOWN)
-		{
-			box->pd_pressed = RT_TRUE;
-			rtgui_widget_update(RTGUI_WIDGET(box));
-		}
-		else if (event->button & RTGUI_MOUSE_BUTTON_LEFT &&
-			event->button & RTGUI_MOUSE_BUTTON_UP)
-		{
-			box->pd_pressed = RT_FALSE;
-			rtgui_widget_update(RTGUI_WIDGET(box));
-
-			/* pop pull down window */
-			if (box->pd_win == RT_NULL)
-			{
-				rtgui_listbox_t  *list;
-
-				/* create pull down window */
-				rect = RTGUI_WIDGET(box)->extent;
-				rect.y1 = rect.y2;
-				rect.y2 = rect.y1 + 5 * (2 + rtgui_theme_get_selected_height());
-				box->pd_win = rtgui_win_create(RT_NULL, "combo", &rect, RTGUI_WIN_STYLE_NO_TITLE);
-				rtgui_win_set_ondeactivate(RTGUI_WIN(box->pd_win), rtgui_combobox_pulldown_hide);
-				/* set user data to parent combobox */
-				box->pd_win->user_data = (rt_uint32_t)box;
-
-				/* create list box */
-				rtgui_rect_inflate(&rect, -1);
-				list = rtgui_listbox_create(box->items, box->items_count, &rect);
-				rtgui_container_add_child(RTGUI_CONTAINER(box->pd_win), RTGUI_WIDGET(list));
-				rtgui_widget_focus(RTGUI_WIDGET(list));
-
-				rtgui_listbox_set_onitem(list, rtgui_combobox_pdwin_onitem);
-				rtgui_win_set_ondeactivate(box->pd_win, rtgui_combobox_pdwin_ondeactive);
-			}
-
-			/* show combo box pull down window */
-			rtgui_win_show(RTGUI_WIN(box->pd_win), RT_FALSE);
-		}
-
-		return RT_TRUE;
-	}
-
-	return RT_FALSE;
-}
-
-rt_bool_t rtgui_combobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_combobox* box = (struct rtgui_combobox*)widget;
-
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-#ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
-		else
-#endif
-			rtgui_combobox_ondraw(box);
-
-		break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-		return rtgui_combobox_onmouse_button(box, (struct rtgui_event_mouse*)event);
-
-	case RTGUI_EVENT_FOCUSED:
-		{
-			/* item focused */
-			struct rtgui_event_focused* focused;
-
-			focused = (struct rtgui_event_focused*) event;
-
-			if (focused->widget != RT_NULL)
-			{
-				/* hide pull down window */
-				rtgui_win_hiden(RTGUI_WIN(box->pd_win));
-				rtgui_combobox_ondraw(box);
-			}
-		}
-		break;
-	}
-
-	return RT_FALSE;
-}
-
-static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_combobox* box;
-
-	if (widget == RT_NULL) return RT_TRUE;
-
-	box = (struct rtgui_combobox*) (((struct rtgui_win*)widget)->user_data);
-	if (box == RT_NULL) return RT_TRUE;
-
-	/* hide pull down window */
-	rtgui_win_hiden(RTGUI_WIN(box->pd_win));
-
-	/* clear pull down button state */
-	box->pd_pressed = RT_FALSE;
-	rtgui_widget_update(RTGUI_WIDGET(box));
-
-	return RT_TRUE;
-}
-
-struct rtgui_listbox_item* rtgui_combox_get_select(struct rtgui_combobox* box)
-{
-	if ((box != RT_NULL) && (box->current_item < box->items_count))
-	{
-		return &(box->items[box->current_item]);
-	}
-
-	return RT_NULL;
-}
-
-void rtgui_combobox_set_onselected(struct rtgui_combobox* box, rtgui_onitem_func_t func)
-{
-	box->on_selected = func;
-}
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/combobox.h>
+
+static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_object* object, struct rtgui_event* event);
+const static rt_uint8_t down_arrow[]  = {0xff, 0x7e, 0x3c, 0x18};
+
+static void _rtgui_combobox_constructor(rtgui_combobox_t *box)
+{
+	rtgui_rect_t rect = {0, 0, RTGUI_COMBOBOX_WIDTH, RTGUI_COMBOBOX_HEIGHT};
+
+	/* init widget and set event handler */
+	rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_combobox_event_handler);
+	rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
+
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL;
+
+	box->pd_pressed = RT_FALSE;
+	box->current_item = 0;
+	box->on_selected = RT_NULL;
+	box->pd_win    = RT_NULL;
+}
+
+static void _rtgui_combobox_destructor(rtgui_combobox_t *box)
+{
+	/* destroy pull down window */
+	rtgui_win_destroy(box->pd_win);
+
+	/* reset box field */
+	box->pd_win    = RT_NULL;
+}
+
+rt_bool_t rtgui_combobox_pdwin_onitem(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_widget *widget;
+	rtgui_win_t* pd_win;
+	rtgui_combobox_t* combo;
+	rtgui_listbox_t* list;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	widget = RTGUI_WIDGET(object);
+	list = RTGUI_LISTBOX(widget);
+	pd_win = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
+	combo = RTGUI_COMBOBOX(pd_win->user_data);
+	combo->current_item = list->current_item;
+
+	if (combo->on_selected != RT_NULL)
+		combo->on_selected(RTGUI_OBJECT(combo), RT_NULL);
+
+	rtgui_win_hiden(pd_win);
+	rtgui_widget_update(RTGUI_WIDGET(combo));
+
+	return RT_FALSE;
+}
+
+rt_bool_t rtgui_combobox_pdwin_ondeactive(struct rtgui_object* object, struct rtgui_event* event)
+{
+	rtgui_win_hiden(RTGUI_WIN(object));
+	return RT_TRUE;
+}
+
+DEFINE_CLASS_TYPE(combobox, "combobox", 
+	RTGUI_WIDGET_TYPE,
+	_rtgui_combobox_constructor,
+	_rtgui_combobox_destructor,
+	sizeof(struct rtgui_combobox));
+
+rtgui_combobox_t *rtgui_combobox_create(struct rtgui_listbox_item* items, rt_uint16_t count, struct rtgui_rect* rect)
+{
+	rtgui_combobox_t *box;
+
+	box = (rtgui_combobox_t*)rtgui_widget_create(RTGUI_COMBOBOX_TYPE);
+	box->items_count = count;
+	box->items = items;
+	rtgui_widget_set_rect(RTGUI_WIDGET(box), rect);
+	
+	box->pd_win = RT_NULL;
+
+	return box;
+}
+
+void rtgui_combobox_destroy(rtgui_combobox_t* box)
+{
+	rtgui_widget_destroy(RTGUI_WIDGET(box));
+}
+
+static void rtgui_combobox_ondraw(struct rtgui_combobox* box)
+{
+	/* draw button */
+	rtgui_color_t bc;
+	struct rtgui_dc* dc;
+	struct rtgui_rect rect, r;
+
+	/* begin drawing */
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
+	if (dc == RT_NULL) return;
+
+	bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box));
+
+	/* get widget rect */
+	rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
+	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
+
+	/* fill widget rect with background color */
+	rtgui_dc_fill_rect(dc, &rect);
+	rtgui_dc_draw_rect(dc, &rect);
+
+	/* draw current item */
+	if (box->current_item < box->items_count)
+	{
+		rect.x1 += 5;
+		rtgui_dc_draw_text(dc, box->items[box->current_item].name, &rect);
+	}
+
+	/* restore background color */
+	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = bc;
+
+	/* draw pull down button */
+	rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH;
+	rtgui_rect_inflate(&rect, -1);
+	rtgui_dc_fill_rect(dc, &rect);
+	if (box->pd_pressed == RT_TRUE) rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN);
+	else rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_RAISE);
+
+	r.x1 = 0; r.y1 = 0; r.x2 = 8; r.y2 = 4;
+	rtgui_rect_moveto_align(&rect, &r, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
+	rtgui_dc_draw_byte(dc, r.x1, r.y1, 4, down_arrow);
+
+	/* end drawing */
+	rtgui_dc_end_drawing(dc);
+	return;
+}
+
+static rt_bool_t rtgui_combobox_onmouse_button(struct rtgui_combobox* box, struct rtgui_event_mouse* event)
+{
+	struct rtgui_rect rect;
+
+	/* get widget rect */
+	rect = RTGUI_WIDGET(box)->extent;
+
+	/* move to the pull down button */
+	rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH;
+	if (rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
+	{
+		/* handle mouse button on pull down button */
+		if (event->button & RTGUI_MOUSE_BUTTON_LEFT &&
+			event->button & RTGUI_MOUSE_BUTTON_DOWN)
+		{
+			box->pd_pressed = RT_TRUE;
+			rtgui_widget_update(RTGUI_WIDGET(box));
+		}
+		else if (event->button & RTGUI_MOUSE_BUTTON_LEFT &&
+			event->button & RTGUI_MOUSE_BUTTON_UP)
+		{
+			box->pd_pressed = RT_FALSE;
+			rtgui_widget_update(RTGUI_WIDGET(box));
+
+			/* pop pull down window */
+			if (box->pd_win == RT_NULL)
+			{
+				rtgui_listbox_t  *list;
+
+				/* create pull down window */
+				rect = RTGUI_WIDGET(box)->extent;
+				rect.y1 = rect.y2;
+				rect.y2 = rect.y1 + 5 * (2 + rtgui_theme_get_selected_height());
+				box->pd_win = rtgui_win_create(RT_NULL, "combo", &rect, RTGUI_WIN_STYLE_NO_TITLE);
+				rtgui_win_set_ondeactivate(RTGUI_WIN(box->pd_win), rtgui_combobox_pulldown_hide);
+				/* set user data to parent combobox */
+				box->pd_win->user_data = (rt_uint32_t)box;
+
+				/* create list box */
+				rtgui_rect_inflate(&rect, -1);
+				list = rtgui_listbox_create(box->items, box->items_count, &rect);
+				rtgui_container_add_child(RTGUI_CONTAINER(box->pd_win), RTGUI_WIDGET(list));
+				rtgui_widget_focus(RTGUI_WIDGET(list));
+
+				rtgui_listbox_set_onitem(list, rtgui_combobox_pdwin_onitem);
+				rtgui_win_set_ondeactivate(box->pd_win, rtgui_combobox_pdwin_ondeactive);
+			}
+
+			/* show combo box pull down window */
+			rtgui_win_show(RTGUI_WIN(box->pd_win), RT_FALSE);
+		}
+
+		return RT_TRUE;
+	}
+
+	return RT_FALSE;
+}
+
+rt_bool_t rtgui_combobox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_combobox *box;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	box = RTGUI_COMBOBOX(object);
+
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+#ifndef RTGUI_USING_SMALL_SIZE
+		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+		else
+#endif
+			rtgui_combobox_ondraw(box);
+
+		break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+		return rtgui_combobox_onmouse_button(box, (struct rtgui_event_mouse*)event);
+
+	case RTGUI_EVENT_FOCUSED:
+		{
+			/* item focused */
+			struct rtgui_event_focused* focused;
+
+			focused = (struct rtgui_event_focused*) event;
+
+			if (focused->widget != RT_NULL)
+			{
+				/* hide pull down window */
+				rtgui_win_hiden(RTGUI_WIN(box->pd_win));
+				rtgui_combobox_ondraw(box);
+			}
+		}
+		break;
+	}
+
+	return RT_FALSE;
+}
+
+static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_widget *widget;
+	struct rtgui_combobox *box;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	widget = RTGUI_WIDGET(object);
+	box = RTGUI_COMBOBOX(object);
+
+	if (widget == RT_NULL) return RT_TRUE;
+
+	box = (struct rtgui_combobox*) (((struct rtgui_win*)widget)->user_data);
+	if (box == RT_NULL) return RT_TRUE;
+
+	/* hide pull down window */
+	rtgui_win_hiden(RTGUI_WIN(box->pd_win));
+
+	/* clear pull down button state */
+	box->pd_pressed = RT_FALSE;
+	rtgui_widget_update(RTGUI_WIDGET(box));
+
+	return RT_TRUE;
+}
+
+struct rtgui_listbox_item* rtgui_combox_get_select(struct rtgui_combobox* box)
+{
+	if ((box != RT_NULL) && (box->current_item < box->items_count))
+	{
+		return &(box->items[box->current_item]);
+	}
+
+	return RT_NULL;
+}
+
+void rtgui_combobox_set_onselected(struct rtgui_combobox* box, rtgui_event_handler_ptr func)
+{
+	box->on_selected = func;
+}

+ 117 - 42
components/rtgui/widgets/container.c

@@ -10,37 +10,55 @@
  * Change Logs:
  * Change Logs:
  * Date           Author       Notes
  * Date           Author       Notes
  * 2009-10-16     Bernard      first version
  * 2009-10-16     Bernard      first version
+ * 2010-09-24     Bernard      fix container destroy issue
  */
  */
-#include <rtgui/widgets/toplevel.h>
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_application.h>
 #include <rtgui/widgets/container.h>
 #include <rtgui/widgets/container.h>
+#include <rtgui/widgets/window.h>
 
 
 static void _rtgui_container_constructor(rtgui_container_t *container)
 static void _rtgui_container_constructor(rtgui_container_t *container)
 {
 {
-	/* set event handler and init field */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(container), rtgui_container_event_handler);
+	/* init container */
+	rtgui_object_set_event_handler(RTGUI_OBJECT(container),
+		rtgui_container_event_handler);
+
 	rtgui_list_init(&(container->children));
 	rtgui_list_init(&(container->children));
-	
-	/* set focused widget to itself */
-	container->focused = RTGUI_WIDGET(container);
-	/* set container as focusable widget */
-	RTGUI_WIDGET(container)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+	/* container is used to 'contain'(show) widgets and dispatch events to
+	 * them, not interact with user. So no need to grab focus. If we did it,
+	 * some widget inherited from container(e.g. notebook) will grab the focus
+	 * annoyingly.
+	 *
+	 * For example, a focusable notebook N has a widget W. When the user press
+	 * W, N will gain the focus and W will lose it at first. Then N will set
+	 * focus to W because it is W that eventually interact with people. N will
+	 * yield focus and W will gain the focus again. This loop will make W
+	 * repaint twice every time user press it.
+	 *
+	 * Just eliminate it.
+	 */
+	RTGUI_WIDGET(container)->flag &= ~RTGUI_WIDGET_FLAG_FOCUSABLE;
 }
 }
 
 
 static void _rtgui_container_destructor(rtgui_container_t *container)
 static void _rtgui_container_destructor(rtgui_container_t *container)
 {
 {
-	/* destroy children of container */
 	rtgui_container_destroy_children(container);
 	rtgui_container_destroy_children(container);
 }
 }
 
 
 static void _rtgui_container_update_toplevel(rtgui_container_t* container)
 static void _rtgui_container_update_toplevel(rtgui_container_t* container)
 {
 {
+	struct rtgui_win *window;
 	struct rtgui_list_node* node;
 	struct rtgui_list_node* node;
 
 
+	window = rtgui_widget_get_toplevel(RTGUI_WIDGET(container));
+
 	rtgui_list_foreach(node, &(container->children))
 	rtgui_list_foreach(node, &(container->children))
 	{
 	{
 		rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
 		rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
 		/* set child toplevel */
 		/* set child toplevel */
-		child->toplevel = rtgui_widget_get_toplevel(RTGUI_WIDGET(container));
+		child->toplevel = window;
 
 
 		if (RTGUI_IS_CONTAINER(child))
 		if (RTGUI_IS_CONTAINER(child))
 		{
 		{
@@ -49,7 +67,7 @@ static void _rtgui_container_update_toplevel(rtgui_container_t* container)
 	}
 	}
 }
 }
 
 
-DEFINE_CLASS_TYPE(container, "container", 
+DEFINE_CLASS_TYPE(container, "container",
 	RTGUI_WIDGET_TYPE,
 	RTGUI_WIDGET_TYPE,
 	_rtgui_container_constructor,
 	_rtgui_container_constructor,
 	_rtgui_container_destructor,
 	_rtgui_container_destructor,
@@ -65,7 +83,8 @@ rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_eve
 		struct rtgui_widget* w;
 		struct rtgui_widget* w;
 		w = rtgui_list_entry(node, struct rtgui_widget, sibling);
 		w = rtgui_list_entry(node, struct rtgui_widget, sibling);
 
 
-		if (w->event_handler(w, event) == RT_TRUE) return RT_TRUE;
+		if (RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w), event) == RT_TRUE)
+			return RT_TRUE;
 	}
 	}
 
 
 	return RT_FALSE;
 	return RT_FALSE;
@@ -75,64 +94,106 @@ rt_bool_t rtgui_container_dispatch_mouse_event(rtgui_container_t *container, str
 {
 {
 	/* handle in child widget */
 	/* handle in child widget */
 	struct rtgui_list_node* node;
 	struct rtgui_list_node* node;
-	rtgui_widget_t *focus;
+	struct rtgui_widget *old_focus;
+
+	old_focus = RTGUI_WIDGET(container)->toplevel->focused_widget;
 
 
-	/* get focus widget on toplevel */
-	focus = RTGUI_CONTAINER(RTGUI_WIDGET(container)->toplevel)->focused;
 	rtgui_list_foreach(node, &(container->children))
 	rtgui_list_foreach(node, &(container->children))
 	{
 	{
 		struct rtgui_widget* w;
 		struct rtgui_widget* w;
 		w = rtgui_list_entry(node, struct rtgui_widget, sibling);
 		w = rtgui_list_entry(node, struct rtgui_widget, sibling);
-		if (rtgui_rect_contains_point(&(w->extent), event->x, event->y) == RT_EOK)
+		if (rtgui_rect_contains_point(&(w->extent),
+					                  event->x, event->y) == RT_EOK)
 		{
 		{
-			if ((focus != w) && RTGUI_WIDGET_IS_FOCUSABLE(w))
+			if ((old_focus != w) && RTGUI_WIDGET_IS_FOCUSABLE(w))
 				rtgui_widget_focus(w);
 				rtgui_widget_focus(w);
-			if (w->event_handler(w, (rtgui_event_t*)event) == RT_TRUE) return RT_TRUE;
+			if (RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w),
+											   (rtgui_event_t*)event) == RT_TRUE)
+				return RT_TRUE;
 		}
 		}
 	}
 	}
 
 
 	return RT_FALSE;
 	return RT_FALSE;
 }
 }
 
 
-rt_bool_t rtgui_container_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
+rt_bool_t rtgui_container_event_handler(struct rtgui_object* object, struct rtgui_event* event)
 {
 {
-	rtgui_container_t *container = RTGUI_CONTAINER(widget);
+	struct rtgui_container *container;
+	struct rtgui_widget    *widget;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	container = RTGUI_CONTAINER(object);
+	widget    = RTGUI_WIDGET(object);
 
 
 	switch (event->type)
 	switch (event->type)
 	{
 	{
 	case RTGUI_EVENT_PAINT:
 	case RTGUI_EVENT_PAINT:
-	case RTGUI_EVENT_COMMAND:
-	case RTGUI_EVENT_RESIZE:
-		rtgui_container_dispatch_event(container, event);
+		{
+			struct rtgui_dc* dc;
+			struct rtgui_rect rect;
+
+			dc = rtgui_dc_begin_drawing(widget);
+			if (dc == RT_NULL)
+				return RT_FALSE;
+			rtgui_widget_get_rect(widget, &rect);
+
+			/* fill container with background */
+			rtgui_dc_fill_rect(dc, &rect);
+
+			/* paint on each child */
+			rtgui_container_dispatch_event(container, event);
+
+			rtgui_dc_end_drawing(dc);
+		}
 		break;
 		break;
 
 
 	case RTGUI_EVENT_KBD:
 	case RTGUI_EVENT_KBD:
+		/* let parent to handle keyboard event */
+		if (widget->parent != RT_NULL &&
+			widget->parent != RTGUI_WIDGET(widget->toplevel))
 		{
 		{
-			/* let parent to handle keyboard event */
-			if (widget->parent != RT_NULL && widget->parent != widget->toplevel)
-			{
-				return widget->parent->event_handler(widget->parent, event);
-			}
+			return RTGUI_OBJECT(widget->parent)->event_handler(
+					RTGUI_OBJECT(widget->parent),
+					event);
 		}
 		}
 		break;
 		break;
 
 
 	case RTGUI_EVENT_MOUSE_BUTTON:
 	case RTGUI_EVENT_MOUSE_BUTTON:
+	case RTGUI_EVENT_MOUSE_MOTION:
 		/* handle in child widget */
 		/* handle in child widget */
 		return rtgui_container_dispatch_mouse_event(container,
 		return rtgui_container_dispatch_mouse_event(container,
 			(struct rtgui_event_mouse*)event);
 			(struct rtgui_event_mouse*)event);
 
 
-	case RTGUI_EVENT_MOUSE_MOTION:
-		return rtgui_container_dispatch_mouse_event(container,
-			(struct rtgui_event_mouse*)event);
+	case RTGUI_EVENT_COMMAND:
+	case RTGUI_EVENT_RESIZE:
+		rtgui_container_dispatch_event(container, event);
+		break;
 
 
 	default:
 	default:
 		/* call parent widget event handler */
 		/* call parent widget event handler */
-		return rtgui_widget_event_handler(widget, event);
+		return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event);
 	}
 	}
 
 
 	return RT_FALSE;
 	return RT_FALSE;
 }
 }
 
 
+rtgui_container_t* rtgui_container_create(void)
+{
+	struct rtgui_container* container;
+
+	/* allocate container */
+	container = (struct rtgui_container*) rtgui_widget_create (RTGUI_CONTAINER_TYPE);
+	return container;
+}
+
+void rtgui_container_destroy(rtgui_container_t* container)
+{
+	rtgui_container_hide(container);
+	rtgui_widget_destroy(RTGUI_WIDGET(container));
+}
+
 /*
 /*
  * This function will add a child to a container widget
  * This function will add a child to a container widget
  * Note: this function will not change the widget layout
  * Note: this function will not change the widget layout
@@ -168,13 +229,7 @@ void rtgui_container_remove_child(rtgui_container_t *container, rtgui_widget_t*
 	RT_ASSERT(container != RT_NULL);
 	RT_ASSERT(container != RT_NULL);
 	RT_ASSERT(child != RT_NULL);
 	RT_ASSERT(child != RT_NULL);
 
 
-	if (child == container->focused)
-	{
-		/* set focused to itself */
-		container->focused = RTGUI_WIDGET(container);
-
-		rtgui_widget_focus(RTGUI_WIDGET(container));
-	}
+	rtgui_widget_unfocus(child);
 
 
 	/* remove widget from parent's children list */
 	/* remove widget from parent's children list */
 	rtgui_list_remove(&(container->children), &(child->sibling));
 	rtgui_list_remove(&(container->children), &(child->sibling));
@@ -218,9 +273,6 @@ void rtgui_container_destroy_children(rtgui_container_t *container)
 	}
 	}
 
 
 	container->children.next = RT_NULL;
 	container->children.next = RT_NULL;
-	container->focused = RTGUI_WIDGET(container);
-	if (RTGUI_WIDGET(container)->parent != RT_NULL)
-		rtgui_widget_focus(RTGUI_WIDGET(container));
 
 
 	/* update widget clip */
 	/* update widget clip */
 	rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(RTGUI_WIDGET(container)->toplevel));
 	rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(RTGUI_WIDGET(container)->toplevel));
@@ -237,3 +289,26 @@ rtgui_widget_t* rtgui_container_get_first_child(rtgui_container_t* container)
 
 
 	return child;
 	return child;
 }
 }
+
+#ifndef RTGUI_USING_SMALL_SIZE
+void rtgui_container_set_box(rtgui_container_t* container, struct rtgui_box* box)
+{
+	if (container == RT_NULL || box  == RT_NULL)
+        return;
+
+	rtgui_container_add_child(RTGUI_CONTAINER(container), RTGUI_WIDGET(box));
+	rtgui_widget_set_rect(RTGUI_WIDGET(box), &(RTGUI_WIDGET(container)->extent));
+}
+#endif
+
+void rtgui_container_hide(rtgui_container_t* container)
+{
+	if (container == RT_NULL) return;
+
+	if (RTGUI_WIDGET(container)->parent == RT_NULL)
+	{
+		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(container));
+		return;
+	}
+}
+

+ 827 - 846
components/rtgui/widgets/filelist_view.c

@@ -1,846 +1,827 @@
-/*
- * File      : filelist_view.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-01-06     Bernard      first version
- */
-
-#include <rtgui/rtgui_object.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/rtgui_theme.h>
-
-#include <rtgui/list.h>
-#include <rtgui/image.h>
-#include <rtgui/widgets/view.h>
-#include <rtgui/widgets/workbench.h>
-#include <rtgui/widgets/filelist_view.h>
-#include <rtgui/widgets/listbox.h>
-#include <rtgui/widgets/window.h>
-
-#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
-#ifdef _WIN32
-#include <io.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#define PATH_SEPARATOR		'\\'
-#else
-#include <dfs_posix.h>
-#define PATH_SEPARATOR		'/'
-#endif
-
-#include <string.h>
-
-#define RTGUI_FILELIST_MARGIN		5
-
-const static char * file_xpm[] = {
-"16 16 21 1",
-" 	c None",
-".	c #999999",
-"+	c #818181",
-"@	c #FFFFFF",
-"#	c #ECECEC",
-"$	c #EAEAEA",
-"%	c #EBEBEB",
-"&	c #EDEDED",
-"*	c #F0F0F0",
-"=	c #C4C4C4",
-"-	c #C5C5C5",
-";	c #C6C6C6",
-">	c #C7C7C7",
-",	c #EEEEEE",
-"'	c #EDEDE5",
-")	c #EDEDE6",
-"!	c #EFEFEF",
-"~	c #C8C8C8",
-"{	c #F1F1F1",
-"]	c #F2F2F2",
-"^	c #959595",
-".++++++++++++   ",
-"+@@@@@@@@@@@@+  ",
-"+@#$$%%%##&*@+  ",
-"+@$=--;;;;>*@+  ",
-"+@$%%###&&,*@+  ",
-"+@%-;;;;;;>*@+  ",
-"+@%%##&&'#,*@+  ",
-"+@%;;;;,,),*@+  ",
-"+@##&&,,!!!*@+  ",
-"+@#;;;>>~~~*@+  ",
-"+@#&,,!!*{{{@+  ",
-"+@&;>>~~~{{]@+  ",
-"+@&&,!!**{]]@+  ",
-"+@@@@@@@@@@@@+  ",
-"^++++++++++++^  ",
-"                "};
-
-const static char * folder_xpm[] = {
-"16 16 121 2",
-"  	c None",
-". 	c #D9B434",
-"+ 	c #E1C25E",
-"@ 	c #E2C360",
-"# 	c #E2C35F",
-"$ 	c #DBB63C",
-"% 	c #DAB336",
-"& 	c #FEFEFD",
-"* 	c #FFFFFE",
-"= 	c #FFFEFE",
-"- 	c #FFFEFD",
-"; 	c #FBF7EA",
-"> 	c #E4C76B",
-", 	c #E3C76B",
-"' 	c #E6CD79",
-") 	c #E5CA74",
-"! 	c #DAAF35",
-"~ 	c #FEFCF7",
-"{ 	c #F8E48E",
-"] 	c #F5DE91",
-"^ 	c #F5E09F",
-"/ 	c #F6E1AC",
-"( 	c #FEFBEF",
-"_ 	c #FEFDF4",
-": 	c #FEFCF3",
-"< 	c #FEFCF1",
-"[ 	c #FEFBEE",
-"} 	c #FFFDFA",
-"| 	c #DAAF36",
-"1 	c #DAAA36",
-"2 	c #FDFAF1",
-"3 	c #F5DE94",
-"4 	c #F4DC93",
-"5 	c #F2D581",
-"6 	c #EDCA6A",
-"7 	c #EACB6C",
-"8 	c #EFD385",
-"9 	c #EFD280",
-"0 	c #EFD07A",
-"a 	c #EECF76",
-"b 	c #EECF72",
-"c 	c #FBF7E9",
-"d 	c #DAAE34",
-"e 	c #DAAB35",
-"f 	c #FBF6E8",
-"g 	c #EFD494",
-"h 	c #EECE88",
-"i 	c #E9C173",
-"j 	c #F6E9C9",
-"k 	c #FEFCF2",
-"l 	c #FEFCF0",
-"m 	c #DAAB36",
-"n 	c #DAA637",
-"o 	c #FFFDF8",
-"p 	c #FFFDF6",
-"q 	c #FFFCF5",
-"r 	c #FCF6D8",
-"s 	c #F8E694",
-"t 	c #F7E385",
-"u 	c #F6DF76",
-"v 	c #F5DB68",
-"w 	c #F4D85C",
-"x 	c #FCF4D7",
-"y 	c #DAA435",
-"z 	c #DAA136",
-"A 	c #FEFCF6",
-"B 	c #FCF2C8",
-"C 	c #FBEFB9",
-"D 	c #FAECAC",
-"E 	c #F9E89C",
-"F 	c #F7E38B",
-"G 	c #F6E07C",
-"H 	c #F6DC6C",
-"I 	c #F5D95D",
-"J 	c #F4D64F",
-"K 	c #F3D344",
-"L 	c #FCF3D0",
-"M 	c #DA9F35",
-"N 	c #DA9A36",
-"O 	c #FDFAF2",
-"P 	c #FAEDB3",
-"Q 	c #F9E9A4",
-"R 	c #F8E695",
-"S 	c #F7E285",
-"T 	c #F6DE76",
-"U 	c #F5DB65",
-"V 	c #F4D757",
-"W 	c #F3D449",
-"X 	c #F2D13B",
-"Y 	c #F1CE30",
-"Z 	c #FBF2CC",
-"` 	c #DA9835",
-" .	c #DA9435",
-"..	c #FEFAEF",
-"+.	c #F9E9A1",
-"@.	c #F8E591",
-"#.	c #F7E181",
-"$.	c #F6DE72",
-"%.	c #F5DA63",
-"&.	c #F4D754",
-"*.	c #F3D347",
-"=.	c #F2D039",
-"-.	c #F1CD2E",
-";.	c #F0CB26",
-">.	c #FBF2CA",
-",.	c #D98E33",
-"'.	c #FAF0DC",
-").	c #F4DDA7",
-"!.	c #F4DB9E",
-"~.	c #F3DA96",
-"{.	c #F3D88E",
-"].	c #F3D786",
-"^.	c #F2D47F",
-"/.	c #F2D379",
-"(.	c #F1D272",
-"_.	c #F1D06C",
-":.	c #F1CF69",
-"<.	c #F8EAC2",
-"[.	c #D8882D",
-"}.	c #D8872D",
-"|.	c #D8862C",
-"                                ",
-"                                ",
-"                                ",
-"  . + @ @ @ # $                 ",
-"  % & * = - * ; > , , , ' )     ",
-"  ! ~ { ] ^ / ( _ : < ( [ } |   ",
-"  1 2 3 4 5 6 7 8 9 0 a b c d   ",
-"  e f g h i j k : k l ( [ * m   ",
-"  n * o p q : r s t u v w x y   ",
-"  z A B C D E F G H I J K L M   ",
-"  N O P Q R S T U V W X Y Z `   ",
-"   ...+.@.#.$.%.&.*.=.-.;.>. .  ",
-"  ,.'.).!.~.{.].^./.(._.:.<.,.  ",
-"    [.}.[.[.[.[.[.[.[.[.}.[.|.  ",
-"                                ",
-"                                "};
-
-/* image for file and folder */
-static rtgui_image_t *file_image, *folder_image;
-static struct rtgui_listbox_item items[] = 
-{
-#ifdef RTGUI_USING_FONTHZ
-	{"打开文件夹", RT_NULL},
-	{"选择文件夹", RT_NULL},
-	{"退出", RT_NULL}
-#else
-	{"Open folder", RT_NULL},
-	{"Select folder", RT_NULL},
-	{"Cancel", RT_NULL}
-#endif
-};
-static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view);
-
-static void rtgui_filelist_view_on_folder_item(rtgui_widget_t* widget, struct rtgui_event* event)
-{
-	rtgui_win_t *menu;
-	rtgui_listbox_t *listbox;
-	rtgui_filelist_view_t *view;
-
-	listbox = RTGUI_LISTBOX(widget);
-	menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
-	view = RTGUI_FILELIST_VIEW(menu->user_data);
-
-	/* hide window */
-	rtgui_win_hiden(menu);
-
-	switch (listbox->current_item)
-	{
-	case 0:
-		{
-			char* dir_ptr;
-
-			/* destroy menu window */
-			rtgui_win_destroy(menu);
-
-			dir_ptr = (char*) rtgui_malloc (256);
-			rtgui_filelist_view_get_fullpath(view, dir_ptr, 256);
-			rtgui_filelist_view_set_directory(view, dir_ptr);
-			rt_free(dir_ptr);
-		}
-		break;
-	case 1:
-		/* destroy menu window */
-		rtgui_win_destroy(menu);
-		if (RTGUI_VIEW(view)->modal_show == RT_TRUE)
-		{
-			rtgui_view_end_modal(RTGUI_VIEW(view), RTGUI_MODAL_OK);
-		}
-		break;
-
-	default:
-		/* destroy menu window */
-		rtgui_win_destroy(menu);
-		break;
-	}
-}
-
-static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_widget_t* widget, struct rtgui_event* event)
-{
-	rtgui_win_t *menu;
-	menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
-
-	/* destroy menu window */
-	rtgui_win_destroy(menu);
-
-	return RT_TRUE;
-}
-
-static void rtgui_filelist_view_menu_pop(rtgui_widget_t *parent)
-{
-	rtgui_win_t *menu;
-	rtgui_listbox_t *listbox;
-	rtgui_rect_t screen, rect = {0, 0, 140, 85};
-
-	rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &screen);
-	rtgui_rect_moveto_align(&screen, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
-
-	menu = rtgui_win_create(RTGUI_TOPLEVEL(rtgui_widget_get_toplevel(parent)), 
-		"Folder Menu", &rect, RTGUI_WIN_STYLE_DEFAULT);
-	if (menu != RT_NULL)
-	{
-		/* set user data on menu window */
-		menu->user_data = (rt_uint32_t)parent;
-
-		rtgui_win_set_ondeactivate(menu, rtgui_filelist_view_on_menu_deactivate);
-
-		listbox = rtgui_listbox_create(items, sizeof(items)/sizeof(items[0]), &rect);
-		rtgui_listbox_set_onitem(listbox, rtgui_filelist_view_on_folder_item);
-		rtgui_container_add_child(RTGUI_CONTAINER(menu), RTGUI_WIDGET(listbox));
-		rtgui_win_show(menu, RT_FALSE);
-		rtgui_widget_focus(RTGUI_WIDGET(listbox));
-		rtgui_listbox_set_current_item(listbox, 0);
-	}
-}
-
-static void _rtgui_filelist_view_constructor(struct rtgui_filelist_view *view)
-{
-	/* default rect */
-	struct rtgui_rect rect = {0, 0, 200, 200};
-
-	/* set default widget rect and set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(view), rtgui_filelist_view_event_handler);
-	rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
-
-	RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
-	view->current_item = 0;
-	view->items_count = 0;
-	view->page_items = 0;
-
-	view->current_directory = RT_NULL;
-	view->pattern = RT_NULL;
-	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white;
-	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
-
-	file_image = rtgui_image_create_from_mem("xpm",
-		(rt_uint8_t*)file_xpm, sizeof(file_xpm), RT_TRUE);
-	folder_image = rtgui_image_create_from_mem("xpm",
-		(rt_uint8_t*)folder_xpm, sizeof(folder_xpm), RT_TRUE);
-}
-
-static void _rtgui_filelist_view_destructor(struct rtgui_filelist_view *view)
-{
-    /* delete all file items */
-    rtgui_filelist_view_clear(view);
-	/* delete current directory and pattern */
-	rtgui_free(view->current_directory); view->current_directory = RT_NULL;
-	rtgui_free(view->pattern); view->pattern = RT_NULL;
-
-	/* delete image */
-	rtgui_image_destroy(file_image);
-	rtgui_image_destroy(folder_image);
-}
-
-DEFINE_CLASS_TYPE(filelist, "filelist", 
-	RTGUI_VIEW_TYPE,
-	_rtgui_filelist_view_constructor,
-	_rtgui_filelist_view_destructor,
-	sizeof(struct rtgui_filelist_view));
-
-void rtgui_filelist_view_ondraw(struct rtgui_filelist_view* view)
-{
-	struct rtgui_dc* dc;
-	rt_uint16_t page_index, index;
-	struct rtgui_file_item* item;
-	struct rtgui_rect rect, item_rect, image_rect;
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
-	if (dc == RT_NULL) return;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-	rtgui_dc_fill_rect(dc, &rect);
-
-	/* get item base rect */
-	item_rect = rect;
-	item_rect.y1 += 1;	
-	item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
-
-	/* get image base rect */
-	image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
-	image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
-	rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-
-	/* get current page */
-	page_index = (view->current_item / view->page_items) * view->page_items;
-	for (index = 0; index < view->page_items; index ++)
-	{
-		if (page_index + index >= view->items_count) break;
-
-		item = &(view->items[page_index + index]);
-
-		if (page_index + index == view->current_item)
-		{
-			rtgui_theme_draw_selected(dc, &item_rect);
-		}
-		else
-		{
-			/* draw background */
-			rtgui_dc_fill_rect(dc, &item_rect);
-		}
-		
-		/* draw item */
-		
-		if (item->type == RTGUI_FITEM_FILE)
-			rtgui_image_blit(file_image, dc, &image_rect);
-		else
-			rtgui_image_blit(folder_image, dc, &image_rect);
-
-        /* draw text */
-		item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
-		rtgui_dc_draw_text(dc, item->name, &item_rect);
-		item_rect.x1 -= RTGUI_FILELIST_MARGIN + file_image->w + 2;
-
-        /* move to next item position */
-		item_rect.y1 += (rtgui_theme_get_selected_height() + 1);
-		item_rect.y2 += (rtgui_theme_get_selected_height() + 1);
-
-		image_rect.y1 += (rtgui_theme_get_selected_height() + 1);
-		image_rect.y2 += (rtgui_theme_get_selected_height() + 1);
-	}
-
-	rtgui_dc_end_drawing(dc);
-}
-
-void rtgui_filelist_view_update_current(struct rtgui_filelist_view* view, rt_uint16_t old_item)
-{
-	struct rtgui_dc* dc;
-	struct rtgui_file_item* item;
-	rtgui_rect_t rect, item_rect, image_rect;
-
-	if (old_item/view->page_items != view->current_item/view->page_items)
-	{
-		/* it's not a same page, update all */
-		rtgui_widget_update(RTGUI_WIDGET(view));
-		return;
-	}
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
-	if (dc == RT_NULL) return;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-
-	/* get old item rect */
-	item_rect = rect;
-	item_rect.y1 += 1;	
-	item_rect.y1 += (old_item % view->page_items) * (1 + rtgui_theme_get_selected_height());
-	item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
-
-	/* get image rect */
-	image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
-	image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
-	rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-	
-	/* draw old item */
-	rtgui_dc_fill_rect(dc, &item_rect);
-
-	item = &(view->items[old_item]);
-	if (item->type == RTGUI_FITEM_FILE) /* draw item image */
-		rtgui_image_blit(file_image, dc, &image_rect);
-	else
-		rtgui_image_blit(folder_image, dc, &image_rect);
-
-	item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
-	rtgui_dc_draw_text(dc, item->name, &item_rect);
-
-	/* draw current item */
-	item_rect = rect;
-	item_rect.y1 += 1;
-	item_rect.y1 += (view->current_item % view->page_items) * (1 + rtgui_theme_get_selected_height());
-	item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
-
-	rtgui_theme_draw_selected(dc, &item_rect);
-
-	/* get image base rect */
-	image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
-	image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
-	rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-
-	item = &(view->items[view->current_item]);
-	if (item->type == RTGUI_FITEM_FILE) /* draw item image */
-		rtgui_image_blit(file_image, dc, &image_rect);
-	else
-		rtgui_image_blit(folder_image, dc, &image_rect);
-
-	item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
-	rtgui_dc_draw_text(dc, item->name, &item_rect);
-
-	rtgui_dc_end_drawing(dc);
-}
-
-static void rtgui_filelist_view_onenturn(struct rtgui_filelist_view* view)
-{
-	if (view->items[view->current_item].type == RTGUI_FITEM_DIR)
-	{
-		char new_path[64];
-
-		if (strcmp(view->items[view->current_item].name, ".") == 0) return ;
-		if (strcmp(view->items[view->current_item].name, "..") == 0)
-		{
-			char *ptr;
-			ptr = strrchr(view->current_directory, PATH_SEPARATOR);
-
-			if (ptr == RT_NULL) return ;
-			if (ptr == &(view->current_directory[0]))
-			{
-				/* it's root directory */
-				new_path[0] = PATH_SEPARATOR;
-				new_path[1] = '\0';
-			}
-			else
-			{
-				strncpy(new_path, view->current_directory, ptr - view->current_directory + 1);
-				new_path[ptr - view->current_directory] = '\0';
-			}
-		}
-		else if (view->current_item == 0 && 
-#ifdef _WIN32
-			(view->current_directory[1] == ':') && (view->current_directory[2] == '\\'))
-#else
-			(view->current_directory[0] == '/') && (view->current_directory[1] == '\0'))
-#endif
-		{
-			if (RTGUI_VIEW(view)->modal_show == RT_TRUE)
-			{
-				rtgui_view_end_modal(RTGUI_VIEW(view), RTGUI_MODAL_CANCEL);
-			}
-			else
-			{
-				rtgui_filelist_view_destroy(view);
-			}
-
-			return ;
-		}
-		else
-		{
-			rtgui_filelist_view_menu_pop(RTGUI_WIDGET(view));
-			return ;
-		}
-		rtgui_filelist_view_set_directory(view, new_path);
-	}
-	else
-	{
-		if (RTGUI_VIEW(view)->modal_show == RT_TRUE)
-		{
-			rtgui_view_end_modal(RTGUI_VIEW(view), RTGUI_MODAL_OK);
-		}
-	}
-}
-
-rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_filelist_view* view = RT_NULL;
-
-	view = RTGUI_FILELIST_VIEW(widget);
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-		rtgui_filelist_view_ondraw(view);
-		return RT_FALSE;
-
-    case RTGUI_EVENT_RESIZE:
-        {
-			struct rtgui_event_resize* resize;
-
-			resize = (struct rtgui_event_resize*)event;
-
-            /* recalculate page items */
-			if (file_image != RT_NULL)
-				view->page_items = resize->h  / (1 + rtgui_theme_get_selected_height());
-			else
-				view->page_items = resize->h / (2 + 14);
-        }
-        break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-		{
-			rtgui_rect_t rect;
-			struct rtgui_event_mouse* emouse;
-
-			emouse = (struct rtgui_event_mouse*)event;
-
-			/* calculate selected item */
-
-			/* get physical extent information */
-			rtgui_widget_get_rect(widget, &rect);
-			rtgui_widget_rect_to_device(widget, &rect);
-
-			if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
-			{
-				rt_uint16_t index;
-				rt_uint16_t current_page;
-				rt_uint16_t old_item;
-
-				index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
-				
-				/* get current page */
-				current_page = view->current_item/view->page_items;
-				old_item = view->current_item;
-
-				if (index + current_page * view->page_items < view->items_count)
-				{
-					/* set selected item */
-					view->current_item = index + current_page * view->page_items;
-					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
-					{
-						rtgui_filelist_view_update_current(view, old_item);
-					}
-					else
-					{
-						/* up event */
-						rtgui_filelist_view_onenturn(view);
-					}
-				}
-
-				return RT_TRUE;
-			}
-		}
-		break;
-
-    case RTGUI_EVENT_KBD:
-        {
-            struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
-            if (ekbd->type == RTGUI_KEYDOWN)
-            {
-				rt_uint16_t old_item;
-
-				old_item = view->current_item;
-                switch (ekbd->key)
-                {
-                case RTGUIK_UP:
-					if (view->current_item > 0)
-						view->current_item --;
-					rtgui_filelist_view_update_current(view, old_item);
-					return RT_TRUE;
-
-                case RTGUIK_DOWN:
-					if (view->current_item < view->items_count - 1)
-						view->current_item ++;
-					rtgui_filelist_view_update_current(view, old_item);
-					return RT_TRUE;
-
-				case RTGUIK_LEFT:
-					if (view->current_item - view->page_items >= 0)
-						view->current_item -= view->page_items;
-					rtgui_filelist_view_update_current(view, old_item);
-					return RT_TRUE;
-
-				case RTGUIK_RIGHT:
-					if (view->current_item + view->page_items < view->items_count - 1)
-						view->current_item += view->page_items;
-					rtgui_filelist_view_update_current(view, old_item);
-					return RT_TRUE;
-
-				case RTGUIK_RETURN:
-					rtgui_filelist_view_onenturn(view);
-					return RT_TRUE;
-
-                default:
-                    break;
-                }
-            }
-        }
-		return RT_FALSE;
-	}
-
-    /* use view event handler */
-    return rtgui_view_event_handler(widget, event);
-}
-
-rtgui_filelist_view_t* rtgui_filelist_view_create(rtgui_workbench_t* workbench, 
-	const char* directory, const char* pattern, const rtgui_rect_t* rect)
-{
-	struct rtgui_filelist_view* view = RT_NULL;
-
-	/* create a new view */
-	view = (struct rtgui_filelist_view*) rtgui_widget_create(RTGUI_FILELIST_VIEW_TYPE);
-	if (view != RT_NULL)
-	{
-		view->items = RT_NULL;
-		view->pattern = rt_strdup(pattern);
-		view->page_items = rtgui_rect_height(*rect) / (1 + rtgui_theme_get_selected_height());
-		rtgui_filelist_view_set_directory(view, directory);
-		
-		rtgui_workbench_add_view(workbench, RTGUI_VIEW(view));
-	}
-
-	return view;
-}
-
-void rtgui_filelist_view_destroy(rtgui_filelist_view_t* view)
-{
-    /* destroy view */
-	rtgui_widget_destroy(RTGUI_WIDGET(view));
-}
-
-/* clear all file items */
-static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view)
-{
-	rt_uint32_t index;
-    struct rtgui_file_item* item;
-
-	for (index = 0; index < view->items_count; index ++)
-	{
-		item = &(view->items[index]);
-
-		/* release item name */
-		rt_free(item->name);
-		item->name = RT_NULL;
-	}
-
-	/* release items */
-	rtgui_free(view->items);
-	view->items = RT_NULL;
-
-	view->items_count = 0;
-	view->current_item = 0;
-}
-
-void rtgui_filelist_view_set_directory(rtgui_filelist_view_t* view, const char* directory)
-{
-    struct rtgui_file_item *item;
-
-    RT_ASSERT(view != RT_NULL);
-
-    /* clear file items firstly */
-    rtgui_filelist_view_clear(view);
-    if (directory != RT_NULL)
-    {
-		DIR* dir;
-		struct stat s;
-		char* fullpath;
-		rt_uint32_t index;
-		struct dirent* dirent;
-
-		view->items_count = 0;
-        dir = opendir(directory);
-		if (dir == RT_NULL)  goto __return;
-
-		/* current directory exists, set it */
-		if (view->current_directory != RT_NULL) rt_free(view->current_directory);
-		view->current_directory = rt_strdup(directory);
-
-		do 
-		{
-			dirent = readdir(dir);
-			if (dirent == RT_NULL) break;
-
-			if (strcmp(dirent->d_name, ".") == 0) continue;
-			if (strcmp(dirent->d_name, "..") == 0) continue;
-			
-			view->items_count ++;
-		} while (dirent != RT_NULL);
-		closedir(dir);
-
-		view->items_count ++; /* root directory for [x] exit, others for .. */
-
-		view->items = (struct rtgui_file_item*) rtgui_malloc(sizeof(struct rtgui_file_item) * view->items_count);
-		if (view->items == RT_NULL) return; /* no memory */
-
-		index = 0;
-		if (directory[0] == '/' && directory[1] != '\0')
-		{
-			item = &(view->items[0]);
-
-			/* add .. directory */
-			item->name = rt_strdup("..");
-			item->type = RTGUI_FITEM_DIR;
-			item->size = 0;
-			
-			index ++;
-		}
-		else
-		{
-			item = &(view->items[0]);
-
-			/* add .. directory */
-			item->name = rt_strdup("退出文件浏览");
-			item->type = RTGUI_FITEM_DIR;
-			item->size = 0;
-			
-			index ++;
-		}
-
-		/* reopen directory */
-		dir = opendir(directory);
-		fullpath = rtgui_malloc(256);
-		while (index < view->items_count)
-		{
-			dirent = readdir(dir);
-			if (dirent == RT_NULL) break;
-
-			if (strcmp(dirent->d_name, ".") == 0) continue;
-			if (strcmp(dirent->d_name, "..") == 0) continue;
-
-			item = &(view->items[index]);
-			item->name = rt_strdup(dirent->d_name);
-
-			rt_memset(&s, 0, sizeof(struct stat));
-
-			/* build full path for the file */
-			if (directory[strlen(directory) - 1] != PATH_SEPARATOR)
-				rt_snprintf(fullpath, 256, "%s%c%s", directory, PATH_SEPARATOR, dirent->d_name);
-			else
-				rt_snprintf(fullpath, 256, "%s%s", directory, dirent->d_name);
-
-			stat(fullpath, &s);
-			if ( s.st_mode & S_IFDIR )
-			{
-				item->type = RTGUI_FITEM_DIR;
-				item->size = 0;
-			}
-			else
-			{
-				item->type = RTGUI_FITEM_FILE;
-				item->size = s.st_size;
-			}
-
-			index ++;
-		}
-		rtgui_free(fullpath);
-		closedir(dir);
-    }
-
-	view->current_item = 0;
-
-__return:
-    /* update view */
-    rtgui_widget_update(RTGUI_WIDGET(view));
-}
-
-void rtgui_filelist_view_get_fullpath(rtgui_filelist_view_t* view, char* path, rt_size_t len)
-{
-	RT_ASSERT(view != RT_NULL);
-
-	if (view->current_directory[strlen(view->current_directory) - 1] != PATH_SEPARATOR)
-		rt_snprintf(path, len, "%s%c%s",view->current_directory, PATH_SEPARATOR,
-			view->items[view->current_item].name);
-	else
-		rt_snprintf(path, len, "%s%s",view->current_directory, 
-			view->items[view->current_item].name);
-}
-#endif
+/*
+ * File      : filelist_view.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-01-06     Bernard      first version
+ */
+
+#include <rtgui/rtgui_object.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/rtgui_application.h>
+
+#include <rtgui/list.h>
+#include <rtgui/image.h>
+#include <rtgui/widgets/container.h>
+#include <rtgui/widgets/filelist_view.h>
+#include <rtgui/widgets/listbox.h>
+#include <rtgui/widgets/window.h>
+
+#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
+#ifdef _WIN32
+#include <io.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#define PATH_SEPARATOR		'\\'
+#else
+#include <dfs_posix.h>
+#define PATH_SEPARATOR		'/'
+#endif
+
+#include <string.h>
+
+#define RTGUI_FILELIST_MARGIN		5
+
+const static char * file_xpm[] = {
+"16 16 21 1",
+" 	c None",
+".	c #999999",
+"+	c #818181",
+"@	c #FFFFFF",
+"#	c #ECECEC",
+"$	c #EAEAEA",
+"%	c #EBEBEB",
+"&	c #EDEDED",
+"*	c #F0F0F0",
+"=	c #C4C4C4",
+"-	c #C5C5C5",
+";	c #C6C6C6",
+">	c #C7C7C7",
+",	c #EEEEEE",
+"'	c #EDEDE5",
+")	c #EDEDE6",
+"!	c #EFEFEF",
+"~	c #C8C8C8",
+"{	c #F1F1F1",
+"]	c #F2F2F2",
+"^	c #959595",
+".++++++++++++   ",
+"+@@@@@@@@@@@@+  ",
+"+@#$$%%%##&*@+  ",
+"+@$=--;;;;>*@+  ",
+"+@$%%###&&,*@+  ",
+"+@%-;;;;;;>*@+  ",
+"+@%%##&&'#,*@+  ",
+"+@%;;;;,,),*@+  ",
+"+@##&&,,!!!*@+  ",
+"+@#;;;>>~~~*@+  ",
+"+@#&,,!!*{{{@+  ",
+"+@&;>>~~~{{]@+  ",
+"+@&&,!!**{]]@+  ",
+"+@@@@@@@@@@@@+  ",
+"^++++++++++++^  ",
+"                "};
+
+const static char * folder_xpm[] = {
+"16 16 121 2",
+"  	c None",
+". 	c #D9B434",
+"+ 	c #E1C25E",
+"@ 	c #E2C360",
+"# 	c #E2C35F",
+"$ 	c #DBB63C",
+"% 	c #DAB336",
+"& 	c #FEFEFD",
+"* 	c #FFFFFE",
+"= 	c #FFFEFE",
+"- 	c #FFFEFD",
+"; 	c #FBF7EA",
+"> 	c #E4C76B",
+", 	c #E3C76B",
+"' 	c #E6CD79",
+") 	c #E5CA74",
+"! 	c #DAAF35",
+"~ 	c #FEFCF7",
+"{ 	c #F8E48E",
+"] 	c #F5DE91",
+"^ 	c #F5E09F",
+"/ 	c #F6E1AC",
+"( 	c #FEFBEF",
+"_ 	c #FEFDF4",
+": 	c #FEFCF3",
+"< 	c #FEFCF1",
+"[ 	c #FEFBEE",
+"} 	c #FFFDFA",
+"| 	c #DAAF36",
+"1 	c #DAAA36",
+"2 	c #FDFAF1",
+"3 	c #F5DE94",
+"4 	c #F4DC93",
+"5 	c #F2D581",
+"6 	c #EDCA6A",
+"7 	c #EACB6C",
+"8 	c #EFD385",
+"9 	c #EFD280",
+"0 	c #EFD07A",
+"a 	c #EECF76",
+"b 	c #EECF72",
+"c 	c #FBF7E9",
+"d 	c #DAAE34",
+"e 	c #DAAB35",
+"f 	c #FBF6E8",
+"g 	c #EFD494",
+"h 	c #EECE88",
+"i 	c #E9C173",
+"j 	c #F6E9C9",
+"k 	c #FEFCF2",
+"l 	c #FEFCF0",
+"m 	c #DAAB36",
+"n 	c #DAA637",
+"o 	c #FFFDF8",
+"p 	c #FFFDF6",
+"q 	c #FFFCF5",
+"r 	c #FCF6D8",
+"s 	c #F8E694",
+"t 	c #F7E385",
+"u 	c #F6DF76",
+"v 	c #F5DB68",
+"w 	c #F4D85C",
+"x 	c #FCF4D7",
+"y 	c #DAA435",
+"z 	c #DAA136",
+"A 	c #FEFCF6",
+"B 	c #FCF2C8",
+"C 	c #FBEFB9",
+"D 	c #FAECAC",
+"E 	c #F9E89C",
+"F 	c #F7E38B",
+"G 	c #F6E07C",
+"H 	c #F6DC6C",
+"I 	c #F5D95D",
+"J 	c #F4D64F",
+"K 	c #F3D344",
+"L 	c #FCF3D0",
+"M 	c #DA9F35",
+"N 	c #DA9A36",
+"O 	c #FDFAF2",
+"P 	c #FAEDB3",
+"Q 	c #F9E9A4",
+"R 	c #F8E695",
+"S 	c #F7E285",
+"T 	c #F6DE76",
+"U 	c #F5DB65",
+"V 	c #F4D757",
+"W 	c #F3D449",
+"X 	c #F2D13B",
+"Y 	c #F1CE30",
+"Z 	c #FBF2CC",
+"` 	c #DA9835",
+" .	c #DA9435",
+"..	c #FEFAEF",
+"+.	c #F9E9A1",
+"@.	c #F8E591",
+"#.	c #F7E181",
+"$.	c #F6DE72",
+"%.	c #F5DA63",
+"&.	c #F4D754",
+"*.	c #F3D347",
+"=.	c #F2D039",
+"-.	c #F1CD2E",
+";.	c #F0CB26",
+">.	c #FBF2CA",
+",.	c #D98E33",
+"'.	c #FAF0DC",
+").	c #F4DDA7",
+"!.	c #F4DB9E",
+"~.	c #F3DA96",
+"{.	c #F3D88E",
+"].	c #F3D786",
+"^.	c #F2D47F",
+"/.	c #F2D379",
+"(.	c #F1D272",
+"_.	c #F1D06C",
+":.	c #F1CF69",
+"<.	c #F8EAC2",
+"[.	c #D8882D",
+"}.	c #D8872D",
+"|.	c #D8862C",
+"                                ",
+"                                ",
+"                                ",
+"  . + @ @ @ # $                 ",
+"  % & * = - * ; > , , , ' )     ",
+"  ! ~ { ] ^ / ( _ : < ( [ } |   ",
+"  1 2 3 4 5 6 7 8 9 0 a b c d   ",
+"  e f g h i j k : k l ( [ * m   ",
+"  n * o p q : r s t u v w x y   ",
+"  z A B C D E F G H I J K L M   ",
+"  N O P Q R S T U V W X Y Z `   ",
+"   ...+.@.#.$.%.&.*.=.-.;.>. .  ",
+"  ,.'.).!.~.{.].^./.(._.:.<.,.  ",
+"    [.}.[.[.[.[.[.[.[.[.}.[.|.  ",
+"                                ",
+"                                "};
+
+/* image for file and folder */
+static rtgui_image_t *file_image, *folder_image;
+static struct rtgui_listbox_item items[] =
+{
+#ifdef RTGUI_USING_FONTHZ
+	{"湖羲恅璃標", RT_NULL},
+	{"恁寁恅璃標", RT_NULL},
+	{"豖堤", RT_NULL}
+#else
+	{"Open folder", RT_NULL},
+	{"Select folder", RT_NULL},
+	{"Cancel", RT_NULL}
+#endif
+};
+static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view);
+
+static void rtgui_filelist_view_on_folder_item(rtgui_widget_t* widget, struct rtgui_event* event)
+{
+	rtgui_win_t *menu;
+	rtgui_listbox_t *listbox;
+	rtgui_filelist_view_t *view;
+
+	listbox = RTGUI_LISTBOX(widget);
+	menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
+	view = RTGUI_FILELIST_VIEW(menu->user_data);
+
+	/* hide window */
+	rtgui_win_hiden(menu);
+
+	switch (listbox->current_item)
+	{
+	case 0:
+		{
+			char* dir_ptr;
+
+			/* destroy menu window */
+			rtgui_win_destroy(menu);
+
+			dir_ptr = (char*) rtgui_malloc (256);
+			rtgui_filelist_view_get_fullpath(view, dir_ptr, 256);
+			rtgui_filelist_view_set_directory(view, dir_ptr);
+			rt_free(dir_ptr);
+		}
+		break;
+	case 1:
+		/* destroy menu window */
+		rtgui_win_destroy(menu);
+		break;
+
+	default:
+		/* destroy menu window */
+		rtgui_win_destroy(menu);
+		break;
+	}
+}
+
+static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_widget_t* widget, struct rtgui_event* event)
+{
+	rtgui_win_t *menu;
+	menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
+
+	/* destroy menu window */
+	rtgui_win_destroy(menu);
+
+	return RT_TRUE;
+}
+
+static void rtgui_filelist_view_menu_pop(rtgui_widget_t *parent)
+{
+	rtgui_win_t *menu;
+	rtgui_listbox_t *listbox;
+	rtgui_rect_t screen, rect = {0, 0, 140, 85};
+
+	rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &screen);
+	rtgui_rect_moveto_align(&screen, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
+
+	menu = rtgui_win_create(RTGUI_TOPLEVEL(rtgui_widget_get_toplevel(parent)),
+							"Folder Menu", &rect, RTGUI_WIN_STYLE_DEFAULT);
+	if (menu != RT_NULL)
+	{
+		/* set user data on menu window */
+		menu->user_data = (rt_uint32_t)parent;
+
+		rtgui_win_set_ondeactivate(menu, rtgui_filelist_view_on_menu_deactivate);
+
+		listbox = rtgui_listbox_create(items, sizeof(items)/sizeof(items[0]), &rect);
+		rtgui_listbox_set_onitem(listbox, rtgui_filelist_view_on_folder_item);
+		rtgui_container_add_child(RTGUI_CONTAINER(menu), RTGUI_WIDGET(listbox));
+		rtgui_win_show(menu, RT_FALSE);
+		rtgui_widget_focus(RTGUI_WIDGET(listbox));
+		rtgui_listbox_set_current_item(listbox, 0);
+	}
+}
+
+static void _rtgui_filelist_view_constructor(struct rtgui_filelist_view *view)
+{
+	/* default rect */
+	struct rtgui_rect rect = {0, 0, 200, 200};
+
+	/* set default widget rect and set event handler */
+	rtgui_object_set_event_handler(RTGUI_WIDGET(view), rtgui_filelist_view_event_handler);
+	rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
+
+	RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+	view->current_item = 0;
+	view->items_count = 0;
+	view->page_items = 0;
+
+	view->current_directory = RT_NULL;
+	view->pattern = RT_NULL;
+	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white;
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
+
+	file_image = rtgui_image_create_from_mem("xpm",
+		(rt_uint8_t*)file_xpm, sizeof(file_xpm), RT_TRUE);
+	folder_image = rtgui_image_create_from_mem("xpm",
+		(rt_uint8_t*)folder_xpm, sizeof(folder_xpm), RT_TRUE);
+}
+
+static void _rtgui_filelist_view_destructor(struct rtgui_filelist_view *view)
+{
+    /* delete all file items */
+    rtgui_filelist_view_clear(view);
+	/* delete current directory and pattern */
+	rtgui_free(view->current_directory); view->current_directory = RT_NULL;
+	rtgui_free(view->pattern); view->pattern = RT_NULL;
+
+	/* delete image */
+	rtgui_image_destroy(file_image);
+	rtgui_image_destroy(folder_image);
+}
+
+DEFINE_CLASS_TYPE(filelist, "filelist",
+	RTGUI_CONTAINER_TYPE,
+	_rtgui_filelist_view_constructor,
+	_rtgui_filelist_view_destructor,
+	sizeof(struct rtgui_filelist_view));
+
+void rtgui_filelist_view_ondraw(struct rtgui_filelist_view* view)
+{
+	struct rtgui_dc* dc;
+	rt_uint16_t page_index, index;
+	struct rtgui_file_item* item;
+	struct rtgui_rect rect, item_rect, image_rect;
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+	if (dc == RT_NULL) return;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+	rtgui_dc_fill_rect(dc, &rect);
+
+	/* get item base rect */
+	item_rect = rect;
+	item_rect.y1 += 1;
+	item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
+
+	/* get image base rect */
+	image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
+	image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
+	rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+	/* get current page */
+	page_index = (view->current_item / view->page_items) * view->page_items;
+	for (index = 0; index < view->page_items; index ++)
+	{
+		if (page_index + index >= view->items_count) break;
+
+		item = &(view->items[page_index + index]);
+
+		if (page_index + index == view->current_item)
+		{
+			rtgui_theme_draw_selected(dc, &item_rect);
+		}
+		else
+		{
+			/* draw background */
+			rtgui_dc_fill_rect(dc, &item_rect);
+		}
+
+		/* draw item */
+		if (item->type == RTGUI_FITEM_FILE)
+			rtgui_image_blit(file_image, dc, &image_rect);
+		else
+			rtgui_image_blit(folder_image, dc, &image_rect);
+
+        /* draw text */
+		item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
+		rtgui_dc_draw_text(dc, item->name, &item_rect);
+		item_rect.x1 -= RTGUI_FILELIST_MARGIN + file_image->w + 2;
+
+        /* move to next item position */
+		item_rect.y1 += (rtgui_theme_get_selected_height() + 1);
+		item_rect.y2 += (rtgui_theme_get_selected_height() + 1);
+
+		image_rect.y1 += (rtgui_theme_get_selected_height() + 1);
+		image_rect.y2 += (rtgui_theme_get_selected_height() + 1);
+	}
+
+	rtgui_dc_end_drawing(dc);
+}
+
+void rtgui_filelist_view_update_current(struct rtgui_filelist_view* view, rt_uint16_t old_item)
+{
+	struct rtgui_dc* dc;
+	struct rtgui_file_item* item;
+	rtgui_rect_t rect, item_rect, image_rect;
+
+	if (old_item/view->page_items != view->current_item/view->page_items)
+	{
+		/* it's not a same page, update all */
+		rtgui_widget_update(RTGUI_WIDGET(view));
+		return;
+	}
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+	if (dc == RT_NULL) return;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+
+	/* get old item rect */
+	item_rect = rect;
+	item_rect.y1 += 1;
+	item_rect.y1 += (old_item % view->page_items) * (1 + rtgui_theme_get_selected_height());
+	item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
+
+	/* get image rect */
+	image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
+	image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
+	rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+	/* draw old item */
+	rtgui_dc_fill_rect(dc, &item_rect);
+
+	item = &(view->items[old_item]);
+	if (item->type == RTGUI_FITEM_FILE) /* draw item image */
+		rtgui_image_blit(file_image, dc, &image_rect);
+	else
+		rtgui_image_blit(folder_image, dc, &image_rect);
+
+	item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
+	rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+	/* draw current item */
+	item_rect = rect;
+	item_rect.y1 += 1;
+	item_rect.y1 += (view->current_item % view->page_items) * (1 + rtgui_theme_get_selected_height());
+	item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
+
+	rtgui_theme_draw_selected(dc, &item_rect);
+
+	/* get image base rect */
+	image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
+	image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
+	rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+	item = &(view->items[view->current_item]);
+	if (item->type == RTGUI_FITEM_FILE) /* draw item image */
+		rtgui_image_blit(file_image, dc, &image_rect);
+	else
+		rtgui_image_blit(folder_image, dc, &image_rect);
+
+	item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
+	rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+	rtgui_dc_end_drawing(dc);
+}
+
+static void rtgui_filelist_view_onenturn(struct rtgui_filelist_view* view)
+{
+	if (view->items[view->current_item].type == RTGUI_FITEM_DIR)
+	{
+		char new_path[64];
+
+		if (strcmp(view->items[view->current_item].name, ".") == 0) return ;
+		if (strcmp(view->items[view->current_item].name, "..") == 0)
+		{
+			char *ptr;
+			ptr = strrchr(view->current_directory, PATH_SEPARATOR);
+
+			if (ptr == RT_NULL) return ;
+			if (ptr == &(view->current_directory[0]))
+			{
+				/* it's root directory */
+				new_path[0] = PATH_SEPARATOR;
+				new_path[1] = '\0';
+			}
+			else
+			{
+				strncpy(new_path, view->current_directory, ptr - view->current_directory + 1);
+				new_path[ptr - view->current_directory] = '\0';
+			}
+		}
+		else if (view->current_item == 0 &&
+#ifdef _WIN32
+			(view->current_directory[1] == ':') && (view->current_directory[2] == '\\')
+#else
+			(view->current_directory[0] == '/') && (view->current_directory[1] == '\0')
+#endif
+			)
+		{
+			rtgui_filelist_view_destroy(view);
+
+			return ;
+		}
+		else
+		{
+			rtgui_filelist_view_menu_pop(RTGUI_WIDGET(view));
+			return ;
+		}
+		rtgui_filelist_view_set_directory(view, new_path);
+	}
+}
+
+rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+{
+	struct rtgui_filelist_view* view = RT_NULL;
+
+	view = RTGUI_FILELIST_VIEW(widget);
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+		rtgui_filelist_view_ondraw(view);
+		return RT_FALSE;
+
+    case RTGUI_EVENT_RESIZE:
+        {
+			struct rtgui_event_resize* resize;
+
+			resize = (struct rtgui_event_resize*)event;
+
+            /* recalculate page items */
+			if (file_image != RT_NULL)
+				view->page_items = resize->h  / (1 + rtgui_theme_get_selected_height());
+			else
+				view->page_items = resize->h / (2 + 14);
+        }
+        break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+		{
+			rtgui_rect_t rect;
+			struct rtgui_event_mouse* emouse;
+
+			emouse = (struct rtgui_event_mouse*)event;
+
+			/* calculate selected item */
+
+			/* get physical extent information */
+			rtgui_widget_get_rect(widget, &rect);
+			rtgui_widget_rect_to_device(widget, &rect);
+
+			if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
+			{
+				rt_uint16_t index;
+				rt_uint16_t current_page;
+				rt_uint16_t old_item;
+
+				index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
+
+				/* get current page */
+				current_page = view->current_item/view->page_items;
+				old_item = view->current_item;
+
+				if (index + current_page * view->page_items < view->items_count)
+				{
+					/* set selected item */
+					view->current_item = index + current_page * view->page_items;
+					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+					{
+						rtgui_filelist_view_update_current(view, old_item);
+					}
+					else
+					{
+						/* up event */
+						rtgui_filelist_view_onenturn(view);
+					}
+				}
+
+				return RT_TRUE;
+			}
+		}
+		break;
+
+    case RTGUI_EVENT_KBD:
+        {
+            struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+            if (ekbd->type == RTGUI_KEYDOWN)
+            {
+				rt_uint16_t old_item;
+
+				old_item = view->current_item;
+                switch (ekbd->key)
+                {
+                case RTGUIK_UP:
+					if (view->current_item > 0)
+						view->current_item --;
+					rtgui_filelist_view_update_current(view, old_item);
+					return RT_TRUE;
+
+                case RTGUIK_DOWN:
+					if (view->current_item < view->items_count - 1)
+						view->current_item ++;
+					rtgui_filelist_view_update_current(view, old_item);
+					return RT_TRUE;
+
+				case RTGUIK_LEFT:
+					if (view->current_item - view->page_items >= 0)
+						view->current_item -= view->page_items;
+					rtgui_filelist_view_update_current(view, old_item);
+					return RT_TRUE;
+
+				case RTGUIK_RIGHT:
+					if (view->current_item + view->page_items < view->items_count - 1)
+						view->current_item += view->page_items;
+					rtgui_filelist_view_update_current(view, old_item);
+					return RT_TRUE;
+
+				case RTGUIK_RETURN:
+					rtgui_filelist_view_onenturn(view);
+					return RT_TRUE;
+
+                default:
+                    break;
+                }
+            }
+        }
+		return RT_FALSE;
+	}
+
+    /* use view event handler */
+    return rtgui_container_event_handler(widget, event);
+}
+
+rtgui_filelist_view_t* rtgui_filelist_view_create(const char* directory,
+												  const char* pattern,
+												  const rtgui_rect_t* rect)
+{
+	struct rtgui_filelist_view* view = RT_NULL;
+
+	/* create a new view */
+	view = (struct rtgui_filelist_view*) rtgui_widget_create(RTGUI_FILELIST_VIEW_TYPE);
+	if (view != RT_NULL)
+	{
+		view->items = RT_NULL;
+		view->pattern = rt_strdup(pattern);
+		view->page_items = rtgui_rect_height(*rect) / (1 + rtgui_theme_get_selected_height());
+		rtgui_filelist_view_set_directory(view, directory);
+	}
+
+	return view;
+}
+
+void rtgui_filelist_view_destroy(rtgui_filelist_view_t* view)
+{
+    /* destroy view */
+	rtgui_widget_destroy(RTGUI_WIDGET(view));
+}
+
+/* clear all file items */
+static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view)
+{
+	rt_uint32_t index;
+    struct rtgui_file_item* item;
+
+	for (index = 0; index < view->items_count; index ++)
+	{
+		item = &(view->items[index]);
+
+		/* release item name */
+		rt_free(item->name);
+		item->name = RT_NULL;
+	}
+
+	/* release items */
+	rtgui_free(view->items);
+	view->items = RT_NULL;
+
+	view->items_count = 0;
+	view->current_item = 0;
+}
+
+void rtgui_filelist_view_set_directory(rtgui_filelist_view_t* view, const char* directory)
+{
+    struct rtgui_file_item *item;
+
+    RT_ASSERT(view != RT_NULL);
+
+    /* clear file items firstly */
+    rtgui_filelist_view_clear(view);
+    if (directory != RT_NULL)
+    {
+		DIR* dir;
+		struct stat s;
+		char* fullpath;
+		rt_uint32_t index;
+		struct dirent* dirent;
+
+		view->items_count = 0;
+        dir = opendir(directory);
+		if (dir == RT_NULL)  goto __return;
+
+		/* current directory exists, set it */
+		if (view->current_directory != RT_NULL) rt_free(view->current_directory);
+		view->current_directory = rt_strdup(directory);
+
+		do
+		{
+			dirent = readdir(dir);
+			if (dirent == RT_NULL) break;
+
+			if (strcmp(dirent->d_name, ".") == 0) continue;
+			if (strcmp(dirent->d_name, "..") == 0) continue;
+
+			view->items_count ++;
+		} while (dirent != RT_NULL);
+		closedir(dir);
+
+		view->items_count ++; /* root directory for [x] exit, others for .. */
+
+		view->items = (struct rtgui_file_item*) rtgui_malloc(sizeof(struct rtgui_file_item) * view->items_count);
+		if (view->items == RT_NULL) return; /* no memory */
+
+		index = 0;
+		if (directory[0] == '/' && directory[1] != '\0')
+		{
+			item = &(view->items[0]);
+
+			/* add .. directory */
+			item->name = rt_strdup("..");
+			item->type = RTGUI_FITEM_DIR;
+			item->size = 0;
+
+			index ++;
+		}
+		else
+		{
+			item = &(view->items[0]);
+
+			/* add .. directory */
+			item->name = rt_strdup("豖堤恅璃銡擬");
+			item->type = RTGUI_FITEM_DIR;
+			item->size = 0;
+
+			index ++;
+		}
+
+		/* reopen directory */
+		dir = opendir(directory);
+		fullpath = rtgui_malloc(256);
+		while (index < view->items_count)
+		{
+			dirent = readdir(dir);
+			if (dirent == RT_NULL) break;
+
+			if (strcmp(dirent->d_name, ".") == 0) continue;
+			if (strcmp(dirent->d_name, "..") == 0) continue;
+
+			item = &(view->items[index]);
+			item->name = rt_strdup(dirent->d_name);
+
+			rt_memset(&s, 0, sizeof(struct stat));
+
+			/* build full path for the file */
+			if (directory[strlen(directory) - 1] != PATH_SEPARATOR)
+				rt_snprintf(fullpath, 256, "%s%c%s", directory, PATH_SEPARATOR, dirent->d_name);
+			else
+				rt_snprintf(fullpath, 256, "%s%s", directory, dirent->d_name);
+
+			stat(fullpath, &s);
+			if ( s.st_mode & S_IFDIR )
+			{
+				item->type = RTGUI_FITEM_DIR;
+				item->size = 0;
+			}
+			else
+			{
+				item->type = RTGUI_FITEM_FILE;
+				item->size = s.st_size;
+			}
+
+			index ++;
+		}
+		rtgui_free(fullpath);
+		closedir(dir);
+    }
+
+	view->current_item = 0;
+
+__return:
+    /* update view */
+    rtgui_widget_update(RTGUI_WIDGET(view));
+}
+
+void rtgui_filelist_view_get_fullpath(rtgui_filelist_view_t* view, char* path, rt_size_t len)
+{
+	RT_ASSERT(view != RT_NULL);
+
+	if (view->current_directory[strlen(view->current_directory) - 1] != PATH_SEPARATOR)
+		rt_snprintf(path, len, "%s%c%s",view->current_directory, PATH_SEPARATOR,
+			view->items[view->current_item].name);
+	else
+		rt_snprintf(path, len, "%s%s",view->current_directory,
+			view->items[view->current_item].name);
+}
+#endif

+ 8 - 3
components/rtgui/widgets/iconbox.c

@@ -19,7 +19,7 @@ static void _rtgui_iconbox_constructor(rtgui_iconbox_t *iconbox)
 {
 {
 	/* init widget and set event handler */
 	/* init widget and set event handler */
 	RTGUI_WIDGET(iconbox)->flag |= RTGUI_WIDGET_FLAG_TRANSPARENT;
 	RTGUI_WIDGET(iconbox)->flag |= RTGUI_WIDGET_FLAG_TRANSPARENT;
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(iconbox), rtgui_iconbox_event_handler);
+	rtgui_object_set_event_handler(RTGUI_OBJECT(iconbox), rtgui_iconbox_event_handler);
 
 
 	/* set proper of control */
 	/* set proper of control */
 	iconbox->image = RT_NULL;
 	iconbox->image = RT_NULL;
@@ -46,9 +46,14 @@ DEFINE_CLASS_TYPE(iconbox, "iconbox",
 	_rtgui_iconbox_destructor,
 	_rtgui_iconbox_destructor,
 	sizeof(struct rtgui_iconbox));
 	sizeof(struct rtgui_iconbox));
 
 
-rt_bool_t rtgui_iconbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+rt_bool_t rtgui_iconbox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
 {
 {
-	struct rtgui_iconbox* iconbox = (struct rtgui_iconbox*)widget;
+	struct rtgui_iconbox* iconbox;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	iconbox = RTGUI_ICONBOX(object);
 
 
 	switch (event->type)
 	switch (event->type)
 	{
 	{

+ 5 - 6
components/rtgui/widgets/label.c

@@ -19,7 +19,7 @@
 static void _rtgui_label_constructor(rtgui_label_t *label)
 static void _rtgui_label_constructor(rtgui_label_t *label)
 {
 {
 	/* init widget and set event handler */
 	/* init widget and set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(label), rtgui_label_event_handler);
+	rtgui_object_set_event_handler(RTGUI_OBJECT(label), rtgui_label_event_handler);
 
 
 	/* set field */
 	/* set field */
 	label->text = RT_NULL;
 	label->text = RT_NULL;
@@ -38,13 +38,12 @@ DEFINE_CLASS_TYPE(label, "label",
 	_rtgui_label_destructor,
 	_rtgui_label_destructor,
 	sizeof(struct rtgui_label));
 	sizeof(struct rtgui_label));
 
 
-rt_bool_t rtgui_label_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+rt_bool_t rtgui_label_event_handler(struct rtgui_object *object, struct rtgui_event* event)
 {
 {
-	struct rtgui_label* label;
+	struct rtgui_label *label;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
 
 
-	RT_ASSERT(widget != RT_NULL);
-
-	label = (struct rtgui_label*) widget;
+	label = RTGUI_LABEL(object);
 	switch (event->type)
 	switch (event->type)
 	{
 	{
 	case RTGUI_EVENT_PAINT:
 	case RTGUI_EVENT_PAINT:

+ 636 - 636
components/rtgui/widgets/list_view.c

@@ -1,636 +1,636 @@
-/*
- * File      : list_view.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-01-06     Bernard      first version
- */
-
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/list_view.h>
-
-#define LIST_MARGIN		5
-
-static void _rtgui_list_view_constructor(struct rtgui_list_view *view)
-{
-	/* default rect */
-	struct rtgui_rect rect = {0, 0, 200, 200};
-
-	/* set default widget rect and set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(view),rtgui_list_view_event_handler);
-	rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
-
-	RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
-	view->flag = RTGUI_LIST_VIEW_LIST;
-	view->current_item = 0;
-	view->items_count = 0;
-	view->page_items = 0;
-
-	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white;
-	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(listview, "listview", 
-	RTGUI_VIEW_TYPE,
-	_rtgui_list_view_constructor,
-	RT_NULL,
-	sizeof(struct rtgui_list_view));
-
-static void rtgui_list_view_onicondraw(struct rtgui_list_view* view, struct rtgui_dc *dc)
-{
-	struct rtgui_rect rect, item_rect, drawing_rect;
-	rt_ubase_t c, r, item_index; /* col and row index */
-	rt_ubase_t item_width, item_height;
-	rtgui_image_t* image;
-
-	if (view->items_count == 0) return;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-	item_index = (view->current_item / view->page_items) * view->page_items;
-
-	item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
-	item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
-	image = view->items[0].image;
-
-	for (r = 0; r < view->row_items; r ++)
-	{
-		for (c = 0; c < view->col_items; c ++)
-		{
-			if (item_index < view->items_count)
-			{
-				item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
-				item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
-				item_rect.x2 = item_rect.x1 + item_width;
-				item_rect.y2 = item_rect.y1 + item_height;
-
-				if (item_index == view->current_item)
-				{
-					rtgui_theme_draw_selected(dc, &item_rect);
-				}
-
-				drawing_rect.x1 = drawing_rect.y1 = 0;
-				drawing_rect.x2 = image->w;
-				drawing_rect.y2 = image->h;
-				rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
-				drawing_rect.y1 += 5; drawing_rect.y2 += 5;
-				rtgui_image_blit(view->items[item_index].image, dc, &drawing_rect);
-
-				item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; 
-				item_rect.x1 += 3; item_rect.x2 -=3;
-				rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[item_index].name, 
-					&drawing_rect);
-				rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
-				rtgui_dc_draw_text(dc, view->items[item_index].name, &drawing_rect);
-
-				item_index ++;
-			}
-			else break;
-		}
-	}
-}
-
-static void rtgui_list_view_update_icon(struct rtgui_list_view* view, rt_int16_t old_item)
-{
-	struct rtgui_rect rect, item_rect, drawing_rect;
-	rt_ubase_t c, r; /* col and row index */
-	rt_ubase_t item_width, item_height;
-	rtgui_image_t* image;
-	struct rtgui_dc* dc;
-
-	if ((view->items_count == 0) ||
-		(old_item == view->current_item))
-		return;
-
-	if (old_item/view->page_items != view->current_item/view->page_items)
-	{
-		/* it's not a same page, update all */
-		rtgui_widget_update(RTGUI_WIDGET(view));
-		return;
-	}
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
-	if (dc == RT_NULL) return;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-
-	item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
-	item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
-	image = view->items[0].image;
-
-	/* update old item */
-	r = (old_item % view->page_items)/ view->col_items;
-	c = (old_item % view->page_items)% view->col_items;
-	item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
-	item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
-	item_rect.x2 = item_rect.x1 + item_width;
-	item_rect.y2 = item_rect.y1 + item_height;
-	rtgui_dc_fill_rect(dc, &item_rect);
-
-	/* draw image */
-	drawing_rect.x1 = drawing_rect.y1 = 0;
-	drawing_rect.x2 = image->w;
-	drawing_rect.y2 = image->h;
-	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
-	drawing_rect.y1 += 5; drawing_rect.y2 += 5;
-	rtgui_image_blit(view->items[old_item].image, dc, &drawing_rect);
-
-	/* draw text */
-	item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; 
-	item_rect.x1 += 3; item_rect.x2 -=3;
-	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[old_item].name, 
-		&drawing_rect);
-	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
-	rtgui_dc_draw_text(dc, view->items[old_item].name, &drawing_rect);
-
-	/* update new item as selected */
-	r = (view->current_item % view->page_items) / view->col_items;
-	c = (view->current_item % view->page_items) % view->col_items;
-	item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
-	item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
-	item_rect.x2 = item_rect.x1 + item_width;
-	item_rect.y2 = item_rect.y1 + item_height;
-	rtgui_theme_draw_selected(dc, &item_rect);
-
-	/* draw image */
-	drawing_rect.x1 = 0;
-	drawing_rect.y1 = 3;
-	drawing_rect.x2 = image->w;
-	drawing_rect.y2 = 3 + image->h;
-
-	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
-	rtgui_image_blit(view->items[view->current_item].image, dc, &drawing_rect);
-
-	/* draw text */
-	item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; 
-	item_rect.x1 += 3; item_rect.x2 -=3;
-	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), 
-		view->items[view->current_item].name, 
-		&drawing_rect);
-	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
-	rtgui_dc_draw_text(dc, view->items[view->current_item].name, &drawing_rect);
-
-	rtgui_dc_end_drawing(dc);
-}
-
-static void rtgui_list_view_onlistdraw(struct rtgui_list_view* view, struct rtgui_dc *dc)
-{
-	rt_ubase_t index, page_index;
-	rtgui_rect_t rect, item_rect, image_rect;
-	const struct rtgui_list_item* item;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-
-	/* get item base rect */
-	item_rect = rect;
-	item_rect.y1 += 2;
-	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
-	/* get current page */
-	page_index = (view->current_item / view->page_items) * view->page_items;
-	for (index = 0; index < view->page_items; index ++)
-	{
-		if (page_index + index >= view->items_count) break;
-
-		item = &(view->items[page_index + index]);
-
-		if (page_index + index == view->current_item)
-		{
-			rtgui_theme_draw_selected(dc, &item_rect);
-		}
-		item_rect.x1 += LIST_MARGIN;
-
-		if (item->image != RT_NULL)
-		{
-			/* blit on center */
-			image_rect.x1 = 0; image_rect.y1 = 0;
-			image_rect.x2 = item->image->w;
-			image_rect.y2 = item->image->h;
-
-			rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-			rtgui_image_blit(item->image, dc, &image_rect);
-			item_rect.x1 += item->image->w + 2;
-		}
-		/* draw text */
-		rtgui_dc_draw_text(dc, item->name, &item_rect);
-
-		if (item->image != RT_NULL)
-			item_rect.x1 -= (item->image->w + 2);
-		item_rect.x1 -= LIST_MARGIN;
-
-		/* move to next item position */
-		item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
-		item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
-	}
-}
-
-void rtgui_list_view_update_list(struct rtgui_list_view* view, rt_int16_t old_item)
-{
-	struct rtgui_dc* dc;
-	const struct rtgui_list_item* item;
-	rtgui_rect_t rect, item_rect;
-
-	if (old_item/view->page_items != view->current_item/view->page_items)
-	{
-		/* it's not a same page, update all */
-		rtgui_widget_update(RTGUI_WIDGET(view));
-		return;
-	}
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
-	if (dc == RT_NULL) return;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-
-	/* get old item's rect and draw old item */
-	item_rect.x1 = rect.x1; item_rect.x2 = rect.x2;
-	item_rect.y1 = rect.y1 + 2;
-	item_rect.y1 += (old_item % view->page_items) * (2 + rtgui_theme_get_selected_height());
-	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-	rtgui_dc_fill_rect(dc, &item_rect);
-
-	item_rect.x1 += LIST_MARGIN;
-
-	item = &(view->items[old_item]);
-	if (item->image != RT_NULL)
-	{
-		struct rtgui_rect image_rect;
-
-		/* blit on center */
-		image_rect.x1 = 0; image_rect.y1 = 0;
-		image_rect.x2 = item->image->w;
-		image_rect.y2 = item->image->h;
-
-		rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-		rtgui_image_blit(item->image, dc, &image_rect);
-		item_rect.x1 += item->image->w + 2;
-	}
-	rtgui_dc_draw_text(dc, item->name, &item_rect);
-
-	/* draw current item */
-	item_rect = rect;
-	/* get current item's rect */
-	item_rect.y1 += 2;
-	item_rect.y1 += (view->current_item % view->page_items) * (2 + rtgui_theme_get_selected_height());
-	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
-	/* draw current item */
-	rtgui_theme_draw_selected(dc, &item_rect);
-
-	item_rect.x1 += LIST_MARGIN;
-
-	item = &(view->items[view->current_item]);
-	if (item->image != RT_NULL)
-	{
-		struct rtgui_rect image_rect;
-
-		/* blit on center */
-		image_rect.x1 = 0; image_rect.y1 = 0;
-		image_rect.x2 = item->image->w;
-		image_rect.y2 = item->image->h;
-
-		rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-		rtgui_image_blit(item->image, dc, &image_rect);
-		item_rect.x1 += (item->image->w + 2);
-	}
-	rtgui_dc_draw_text(dc, item->name, &item_rect);
-
-	rtgui_dc_end_drawing(dc);
-}
-
-void rtgui_list_view_ondraw(struct rtgui_list_view* view)
-{
-	struct rtgui_rect rect;
-	struct rtgui_dc* dc;
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
-	if (dc == RT_NULL) return;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-	rtgui_dc_fill_rect(dc, &rect);
-
-	switch (view->flag)
-	{
-	case RTGUI_LIST_VIEW_LIST:
-		rtgui_list_view_onlistdraw(view, dc);
-		break;
-
-	case RTGUI_LIST_VIEW_ICON:
-		rtgui_list_view_onicondraw(view, dc);
-		break;
-	}
-
-	rtgui_dc_end_drawing(dc);
-}
-
-static rt_bool_t rtgui_list_view_onmouse(struct rtgui_list_view* view, struct rtgui_event_mouse* emouse)
-{
-	rtgui_rect_t rect;
-
-	/* calculate selected item */
-
-	/* get physical extent information */
-	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-	rtgui_widget_rect_to_device(RTGUI_WIDGET(view), &rect);
-
-	if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
-	{
-		rt_uint16_t index;
-		rt_uint16_t old_item;
-
-		/* get old item */
-		old_item = view->current_item;
-
-		switch (view->flag)
-		{
-		case RTGUI_LIST_VIEW_LIST:
-			index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
-
-			if ((index < view->items_count) && (index < view->page_items))
-			{
-				/* set selected item */
-				view->current_item = (view->current_item/view->page_items) * view->page_items + index;
-				if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
-				{
-					/* down event */
-					rtgui_list_view_update_list(view, old_item);
-				}
-				else
-				{
-					/* up event */
-					if (view->items[view->current_item].action != RT_NULL)
-					{
-						view->items[view->current_item].action(RTGUI_WIDGET(view), 
-							view->items[view->current_item].parameter);
-					}
-				}
-			}
-			break;
-
-		case RTGUI_LIST_VIEW_ICON:
-			{
-				rt_uint16_t x, y;
-				rt_uint16_t item_height, item_width;
-				rt_ubase_t current_page;
-
-				item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
-				item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
-				x = emouse->x - rect.x1;
-				y = emouse->y - rect.y1;
-
-				index = (y / item_height * view->col_items) + x / item_width;
-				current_page = view->current_item / view->page_items;
-
-				if ((index + (current_page * view->page_items) < view->items_count))
-				{
-					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
-					{
-						view->current_item = index + (current_page * view->page_items);
-
-						/* down event */
-						rtgui_list_view_update_icon(view, old_item);
-					}
-					else
-					{
-						/* up event */
-						if (view->items[view->current_item].action != RT_NULL)
-						{
-							view->items[view->current_item].action(RTGUI_WIDGET(view),
-								view->items[view->current_item].parameter);
-						}
-					}
-				}
-			}
-			break;
-
-		case RTGUI_LIST_VIEW_REPORT:
-			break;
-		}
-
-		return RT_TRUE;
-	}
-
-	return RT_FALSE;
-}
-
-rt_bool_t rtgui_list_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_list_view* view = RT_NULL;
-
-	view = RTGUI_LIST_VIEW(widget);
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-		rtgui_list_view_ondraw(view);
-		return RT_FALSE;
-
-    case RTGUI_EVENT_RESIZE:
-        {
-			struct rtgui_event_resize* resize;
-
-			resize = (struct rtgui_event_resize*)event;
-
-            /* recalculate page items */
-			view->page_items = resize->h  / (2 + rtgui_theme_get_selected_height());
-        }
-        break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-		{
-			struct rtgui_event_mouse* emouse;
-
-			emouse = (struct rtgui_event_mouse*)event;
-			return rtgui_list_view_onmouse(view, emouse);
-		}
-
-    case RTGUI_EVENT_KBD:
-        {
-            struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
-            if (ekbd->type == RTGUI_KEYDOWN)
-            {
-				rt_uint16_t old_item;
-
-				if (view->current_item == -1) 
-				{
-					/* set a initial item */
-					if ((view->items_count > 0) && 
-						(ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN))
-					{
-						view->current_item = 0;
-						if (view->flag == RTGUI_LIST_VIEW_LIST)
-							rtgui_list_view_update_list(view, -1);
-						else
-							rtgui_list_view_update_icon(view, -1);
-						break;
-					}
-					else return RT_FALSE;
-				}
-
-				old_item = view->current_item;
-                switch (ekbd->key)
-                {
-				case RTGUIK_LEFT:
-					if (view->flag == RTGUI_LIST_VIEW_LIST)
-					{
-						if (view->current_item - view->page_items >= 0)
-							view->current_item -= view->page_items;
-						
-						rtgui_list_view_update_list(view, old_item);
-					}
-					else if (view->flag == RTGUI_LIST_VIEW_ICON)
-					{
-						if (view->current_item > 0)
-							view->current_item --;
-						rtgui_list_view_update_icon(view, old_item);
-					}
-					return RT_FALSE;
-
-                case RTGUIK_UP:
-					if (view->flag == RTGUI_LIST_VIEW_LIST)
-					{
-						if (view->current_item > 0)
-							view->current_item --;
-						rtgui_list_view_update_list(view, old_item);
-					}
-					else if (view->flag == RTGUI_LIST_VIEW_ICON)
-					{
-						if (view->current_item >= view->col_items)
-							view->current_item -= view->col_items;
-						else 
-							view->current_item = 0;
-						
-						rtgui_list_view_update_icon(view, old_item);
-					}
-					return RT_FALSE;
-
-				case RTGUIK_RIGHT:
-					if (view->flag == RTGUI_LIST_VIEW_LIST)
-					{
-						if (view->current_item + view->page_items < view->items_count - 1)
-							view->current_item += view->page_items;
-						
-						rtgui_list_view_update_list(view, old_item);
-					}
-					else if (view->flag == RTGUI_LIST_VIEW_ICON)
-					{
-						if (view->current_item < view->items_count - 1)
-							view->current_item ++;
-						
-						rtgui_list_view_update_icon(view, old_item);
-					}
-					return RT_FALSE;
-
-                case RTGUIK_DOWN:
-					if (view->flag == RTGUI_LIST_VIEW_LIST)
-					{
-						if (view->current_item < view->items_count - 1)
-							view->current_item ++;
-						
-						rtgui_list_view_update_list(view, old_item);
-					}
-					else if (view->flag == RTGUI_LIST_VIEW_ICON)
-					{
-						if (view->current_item + view->col_items <= (view->items_count - 1))
-							view->current_item += view->col_items;
-						else 
-							view->current_item = view->items_count - 1;
-
-						rtgui_list_view_update_icon(view, old_item);
-					}
-					return RT_FALSE;
-
-				case RTGUIK_RETURN:
-                    if (view->items[view->current_item].action != RT_NULL)
-					{
-					    view->items[view->current_item].action(RTGUI_WIDGET(view),
-							view->items[view->current_item].parameter);
-					}
-					return RT_FALSE;
-
-                default:
-                    break;
-                }
-            }
-        }
-		return RT_FALSE;
-	}
-
-    /* use view event handler */
-    return rtgui_view_event_handler(widget, event);
-}
-
-static void rtgui_list_view_calc(struct rtgui_list_view* view)
-{
-	rtgui_rect_t rect;
-	rt_uint32_t image_width, image_height;
-	rt_ubase_t text_width, text_height;
-	rt_ubase_t item_width, item_height;
-
-	if (view->items_count == 0) return;
-
-	/* get image width and height */
-	if (view->items[0].image != RT_NULL)
-	{
-		image_width  = view->items[0].image->w;
-		image_height = view->items[0].image->h;
-	}
-	else
-	{
-		image_width  = 0;
-		image_height = 0;
-	}
-
-	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), "HHHHHH", &rect);
-
-	text_height = rtgui_rect_height(rect);
-	text_width = rtgui_rect_width(rect);
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-
-	item_width = (image_width + LIST_MARGIN);
-	if (item_width < (text_width + LIST_MARGIN)) item_width = text_width + LIST_MARGIN;
-	item_height = image_height + 8 + text_height + LIST_MARGIN; 
-	if (item_width > item_height) item_height = item_width;
-	else item_width = item_height;
-	
-	view->row_items = (rtgui_rect_height(rect) - 2 * LIST_MARGIN) / item_height;
-	view->col_items = (rtgui_rect_width(rect) - 2 * LIST_MARGIN) / item_width;
-	view->page_items = view->row_items * view->col_items;
-}
-
-rtgui_list_view_t* rtgui_list_view_create(const struct rtgui_list_item* items, rt_uint16_t count, 
-	rtgui_rect_t *rect, rt_uint16_t flag)
-{
-	struct rtgui_list_view* view = RT_NULL;
-
-	view = (struct rtgui_list_view*) rtgui_widget_create(RTGUI_LIST_VIEW_TYPE);
-	if (view != RT_NULL)
-	{
-	    view->items = items;
-	    view->items_count = count;
-
-		view->flag = flag;
-		rtgui_widget_set_rect(RTGUI_WIDGET(view), rect);
-
-		if (flag == RTGUI_LIST_VIEW_LIST)
-			view->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
-		else if ((flag == RTGUI_LIST_VIEW_ICON) && (count > 0))
-		{
-			rtgui_list_view_calc(view);
-		}
-	}
-
-	return view;
-}
-
-void rtgui_list_view_destroy(rtgui_list_view_t* view)
-{
-    /* destroy view */
-	rtgui_widget_destroy(RTGUI_WIDGET(view));
-}
+/*
+ * File      : list_view.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-01-06     Bernard      first version
+ */
+
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/list_view.h>
+
+#define LIST_MARGIN		5
+
+static void _rtgui_list_view_constructor(struct rtgui_list_view *view)
+{
+	/* default rect */
+	struct rtgui_rect rect = {0, 0, 200, 200};
+
+	/* set default widget rect and set event handler */
+	rtgui_object_set_event_handler(RTGUI_OBJECT(view),rtgui_list_view_event_handler);
+	rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
+
+	RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+	view->flag = RTGUI_LIST_VIEW_LIST;
+	view->current_item = 0;
+	view->items_count = 0;
+	view->page_items = 0;
+
+	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white;
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(listview, "listview", 
+	RTGUI_CONTAINER_TYPE,
+	_rtgui_list_view_constructor,
+	RT_NULL,
+	sizeof(struct rtgui_list_view));
+
+static void rtgui_list_view_onicondraw(struct rtgui_list_view* view, struct rtgui_dc *dc)
+{
+	struct rtgui_rect rect, item_rect, drawing_rect;
+	rt_ubase_t c, r, item_index; /* col and row index */
+	rt_ubase_t item_width, item_height;
+	rtgui_image_t* image;
+
+	if (view->items_count == 0) return;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+	item_index = (view->current_item / view->page_items) * view->page_items;
+
+	item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
+	item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
+	image = view->items[0].image;
+
+	for (r = 0; r < view->row_items; r ++)
+	{
+		for (c = 0; c < view->col_items; c ++)
+		{
+			if (item_index < view->items_count)
+			{
+				item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
+				item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
+				item_rect.x2 = item_rect.x1 + item_width;
+				item_rect.y2 = item_rect.y1 + item_height;
+
+				if (item_index == view->current_item)
+				{
+					rtgui_theme_draw_selected(dc, &item_rect);
+				}
+
+				drawing_rect.x1 = drawing_rect.y1 = 0;
+				drawing_rect.x2 = image->w;
+				drawing_rect.y2 = image->h;
+				rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+				drawing_rect.y1 += 5; drawing_rect.y2 += 5;
+				rtgui_image_blit(view->items[item_index].image, dc, &drawing_rect);
+
+				item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; 
+				item_rect.x1 += 3; item_rect.x2 -=3;
+				rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[item_index].name, 
+					&drawing_rect);
+				rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+				rtgui_dc_draw_text(dc, view->items[item_index].name, &drawing_rect);
+
+				item_index ++;
+			}
+			else break;
+		}
+	}
+}
+
+static void rtgui_list_view_update_icon(struct rtgui_list_view* view, rt_uint16_t old_item)
+{
+	struct rtgui_rect rect, item_rect, drawing_rect;
+	rt_ubase_t c, r; /* col and row index */
+	rt_ubase_t item_width, item_height;
+	rtgui_image_t* image;
+	struct rtgui_dc* dc;
+
+	if ((view->items_count == 0) ||
+		(old_item == view->current_item))
+		return;
+
+	if (old_item/view->page_items != view->current_item/view->page_items)
+	{
+		/* it's not a same page, update all */
+		rtgui_widget_update(RTGUI_WIDGET(view));
+		return;
+	}
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+	if (dc == RT_NULL) return;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+
+	item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
+	item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
+	image = view->items[0].image;
+
+	/* update old item */
+	r = (old_item % view->page_items)/ view->col_items;
+	c = (old_item % view->page_items)% view->col_items;
+	item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
+	item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
+	item_rect.x2 = item_rect.x1 + item_width;
+	item_rect.y2 = item_rect.y1 + item_height;
+	rtgui_dc_fill_rect(dc, &item_rect);
+
+	/* draw image */
+	drawing_rect.x1 = drawing_rect.y1 = 0;
+	drawing_rect.x2 = image->w;
+	drawing_rect.y2 = image->h;
+	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+	drawing_rect.y1 += 5; drawing_rect.y2 += 5;
+	rtgui_image_blit(view->items[old_item].image, dc, &drawing_rect);
+
+	/* draw text */
+	item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; 
+	item_rect.x1 += 3; item_rect.x2 -=3;
+	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[old_item].name, 
+		&drawing_rect);
+	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+	rtgui_dc_draw_text(dc, view->items[old_item].name, &drawing_rect);
+
+	/* update new item as selected */
+	r = (view->current_item % view->page_items) / view->col_items;
+	c = (view->current_item % view->page_items) % view->col_items;
+	item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
+	item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
+	item_rect.x2 = item_rect.x1 + item_width;
+	item_rect.y2 = item_rect.y1 + item_height;
+	rtgui_theme_draw_selected(dc, &item_rect);
+
+	/* draw image */
+	drawing_rect.x1 = 0;
+	drawing_rect.y1 = 3;
+	drawing_rect.x2 = image->w;
+	drawing_rect.y2 = 3 + image->h;
+
+	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+	rtgui_image_blit(view->items[view->current_item].image, dc, &drawing_rect);
+
+	/* draw text */
+	item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; 
+	item_rect.x1 += 3; item_rect.x2 -=3;
+	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), 
+		view->items[view->current_item].name, 
+		&drawing_rect);
+	rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+	rtgui_dc_draw_text(dc, view->items[view->current_item].name, &drawing_rect);
+
+	rtgui_dc_end_drawing(dc);
+}
+
+static void rtgui_list_view_onlistdraw(struct rtgui_list_view* view, struct rtgui_dc *dc)
+{
+	rt_ubase_t index, page_index;
+	rtgui_rect_t rect, item_rect, image_rect;
+	const struct rtgui_list_item* item;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+
+	/* get item base rect */
+	item_rect = rect;
+	item_rect.y1 += 2;
+	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+	/* get current page */
+	page_index = (view->current_item / view->page_items) * view->page_items;
+	for (index = 0; index < view->page_items; index ++)
+	{
+		if (page_index + index >= view->items_count) break;
+
+		item = &(view->items[page_index + index]);
+
+		if (page_index + index == view->current_item)
+		{
+			rtgui_theme_draw_selected(dc, &item_rect);
+		}
+		item_rect.x1 += LIST_MARGIN;
+
+		if (item->image != RT_NULL)
+		{
+			/* blit on center */
+			image_rect.x1 = 0; image_rect.y1 = 0;
+			image_rect.x2 = item->image->w;
+			image_rect.y2 = item->image->h;
+
+			rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+			rtgui_image_blit(item->image, dc, &image_rect);
+			item_rect.x1 += item->image->w + 2;
+		}
+		/* draw text */
+		rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+		if (item->image != RT_NULL)
+			item_rect.x1 -= (item->image->w + 2);
+		item_rect.x1 -= LIST_MARGIN;
+
+		/* move to next item position */
+		item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
+		item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
+	}
+}
+
+void rtgui_list_view_update_list(struct rtgui_list_view* view, rt_uint16_t old_item)
+{
+	struct rtgui_dc* dc;
+	const struct rtgui_list_item* item;
+	rtgui_rect_t rect, item_rect;
+
+	if (old_item/view->page_items != view->current_item/view->page_items)
+	{
+		/* it's not a same page, update all */
+		rtgui_widget_update(RTGUI_WIDGET(view));
+		return;
+	}
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+	if (dc == RT_NULL) return;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+
+	/* get old item's rect and draw old item */
+	item_rect.x1 = rect.x1; item_rect.x2 = rect.x2;
+	item_rect.y1 = rect.y1 + 2;
+	item_rect.y1 += (old_item % view->page_items) * (2 + rtgui_theme_get_selected_height());
+	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+	rtgui_dc_fill_rect(dc, &item_rect);
+
+	item_rect.x1 += LIST_MARGIN;
+
+	item = &(view->items[old_item]);
+	if (item->image != RT_NULL)
+	{
+		struct rtgui_rect image_rect;
+
+		/* blit on center */
+		image_rect.x1 = 0; image_rect.y1 = 0;
+		image_rect.x2 = item->image->w;
+		image_rect.y2 = item->image->h;
+
+		rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+		rtgui_image_blit(item->image, dc, &image_rect);
+		item_rect.x1 += item->image->w + 2;
+	}
+	rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+	/* draw current item */
+	item_rect = rect;
+	/* get current item's rect */
+	item_rect.y1 += 2;
+	item_rect.y1 += (view->current_item % view->page_items) * (2 + rtgui_theme_get_selected_height());
+	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+	/* draw current item */
+	rtgui_theme_draw_selected(dc, &item_rect);
+
+	item_rect.x1 += LIST_MARGIN;
+
+	item = &(view->items[view->current_item]);
+	if (item->image != RT_NULL)
+	{
+		struct rtgui_rect image_rect;
+
+		/* blit on center */
+		image_rect.x1 = 0; image_rect.y1 = 0;
+		image_rect.x2 = item->image->w;
+		image_rect.y2 = item->image->h;
+
+		rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+		rtgui_image_blit(item->image, dc, &image_rect);
+		item_rect.x1 += (item->image->w + 2);
+	}
+	rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+	rtgui_dc_end_drawing(dc);
+}
+
+void rtgui_list_view_ondraw(struct rtgui_list_view* view)
+{
+	struct rtgui_rect rect;
+	struct rtgui_dc* dc;
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+	if (dc == RT_NULL) return;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+	rtgui_dc_fill_rect(dc, &rect);
+
+	switch (view->flag)
+	{
+	case RTGUI_LIST_VIEW_LIST:
+		rtgui_list_view_onlistdraw(view, dc);
+		break;
+
+	case RTGUI_LIST_VIEW_ICON:
+		rtgui_list_view_onicondraw(view, dc);
+		break;
+	}
+
+	rtgui_dc_end_drawing(dc);
+}
+
+static rt_bool_t rtgui_list_view_onmouse(struct rtgui_list_view* view, struct rtgui_event_mouse* emouse)
+{
+	rtgui_rect_t rect;
+
+	/* calculate selected item */
+
+	/* get physical extent information */
+	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+	rtgui_widget_rect_to_device(RTGUI_WIDGET(view), &rect);
+
+	if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
+	{
+		rt_uint16_t index;
+		rt_uint16_t old_item;
+
+		/* get old item */
+		old_item = view->current_item;
+
+		switch (view->flag)
+		{
+		case RTGUI_LIST_VIEW_LIST:
+			index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
+
+			if ((index < view->items_count) && (index < view->page_items))
+			{
+				/* set selected item */
+				view->current_item = (view->current_item/view->page_items) * view->page_items + index;
+				if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+				{
+					/* down event */
+					rtgui_list_view_update_list(view, old_item);
+				}
+				else
+				{
+					/* up event */
+					if (view->items[view->current_item].action != RT_NULL)
+					{
+						view->items[view->current_item].action(RTGUI_WIDGET(view), 
+							view->items[view->current_item].parameter);
+					}
+				}
+			}
+			break;
+
+		case RTGUI_LIST_VIEW_ICON:
+			{
+				rt_uint16_t x, y;
+				rt_uint16_t item_height, item_width;
+				rt_ubase_t current_page;
+
+				item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
+				item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
+				x = emouse->x - rect.x1;
+				y = emouse->y - rect.y1;
+
+				index = (y / item_height * view->col_items) + x / item_width;
+				current_page = view->current_item / view->page_items;
+
+				if ((index + (current_page * view->page_items) < view->items_count))
+				{
+					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+					{
+						view->current_item = index + (current_page * view->page_items);
+
+						/* down event */
+						rtgui_list_view_update_icon(view, old_item);
+					}
+					else
+					{
+						/* up event */
+						if (view->items[view->current_item].action != RT_NULL)
+						{
+							view->items[view->current_item].action(RTGUI_WIDGET(view),
+								view->items[view->current_item].parameter);
+						}
+					}
+				}
+			}
+			break;
+
+		case RTGUI_LIST_VIEW_REPORT:
+			break;
+		}
+
+		return RT_TRUE;
+	}
+
+	return RT_FALSE;
+}
+
+rt_bool_t rtgui_list_view_event_handler(struct rtgui_object* widget, struct rtgui_event* event)
+{
+	struct rtgui_list_view* view = RT_NULL;
+
+	view = RTGUI_LIST_VIEW(widget);
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+		rtgui_list_view_ondraw(view);
+		return RT_FALSE;
+
+    case RTGUI_EVENT_RESIZE:
+        {
+			struct rtgui_event_resize* resize;
+
+			resize = (struct rtgui_event_resize*)event;
+
+            /* recalculate page items */
+			view->page_items = resize->h  / (2 + rtgui_theme_get_selected_height());
+        }
+        break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+		{
+			struct rtgui_event_mouse* emouse;
+
+			emouse = (struct rtgui_event_mouse*)event;
+			return rtgui_list_view_onmouse(view, emouse);
+		}
+
+    case RTGUI_EVENT_KBD:
+        {
+            struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+            if (ekbd->type == RTGUI_KEYDOWN)
+            {
+				rt_uint16_t old_item;
+
+				if (view->current_item == -1) 
+				{
+					/* set a initial item */
+					if ((view->items_count > 0) && 
+						(ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN))
+					{
+						view->current_item = 0;
+						if (view->flag == RTGUI_LIST_VIEW_LIST)
+							rtgui_list_view_update_list(view, -1);
+						else
+							rtgui_list_view_update_icon(view, -1);
+						break;
+					}
+					else return RT_FALSE;
+				}
+
+				old_item = view->current_item;
+                switch (ekbd->key)
+                {
+				case RTGUIK_LEFT:
+					if (view->flag == RTGUI_LIST_VIEW_LIST)
+					{
+						if (view->current_item - view->page_items >= 0)
+							view->current_item -= view->page_items;
+						
+						rtgui_list_view_update_list(view, old_item);
+					}
+					else if (view->flag == RTGUI_LIST_VIEW_ICON)
+					{
+						if (view->current_item > 0)
+							view->current_item --;
+						rtgui_list_view_update_icon(view, old_item);
+					}
+					return RT_FALSE;
+
+                case RTGUIK_UP:
+					if (view->flag == RTGUI_LIST_VIEW_LIST)
+					{
+						if (view->current_item > 0)
+							view->current_item --;
+						rtgui_list_view_update_list(view, old_item);
+					}
+					else if (view->flag == RTGUI_LIST_VIEW_ICON)
+					{
+						if (view->current_item >= view->col_items)
+							view->current_item -= view->col_items;
+						else 
+							view->current_item = 0;
+						
+						rtgui_list_view_update_icon(view, old_item);
+					}
+					return RT_FALSE;
+
+				case RTGUIK_RIGHT:
+					if (view->flag == RTGUI_LIST_VIEW_LIST)
+					{
+						if (view->current_item + view->page_items < view->items_count - 1)
+							view->current_item += view->page_items;
+						
+						rtgui_list_view_update_list(view, old_item);
+					}
+					else if (view->flag == RTGUI_LIST_VIEW_ICON)
+					{
+						if (view->current_item < view->items_count - 1)
+							view->current_item ++;
+						
+						rtgui_list_view_update_icon(view, old_item);
+					}
+					return RT_FALSE;
+
+                case RTGUIK_DOWN:
+					if (view->flag == RTGUI_LIST_VIEW_LIST)
+					{
+						if (view->current_item < view->items_count - 1)
+							view->current_item ++;
+						
+						rtgui_list_view_update_list(view, old_item);
+					}
+					else if (view->flag == RTGUI_LIST_VIEW_ICON)
+					{
+						if (view->current_item + view->col_items <= (view->items_count - 1))
+							view->current_item += view->col_items;
+						else 
+							view->current_item = view->items_count - 1;
+
+						rtgui_list_view_update_icon(view, old_item);
+					}
+					return RT_FALSE;
+
+				case RTGUIK_RETURN:
+                    if (view->items[view->current_item].action != RT_NULL)
+					{
+					    view->items[view->current_item].action(RTGUI_WIDGET(view),
+							view->items[view->current_item].parameter);
+					}
+					return RT_FALSE;
+
+                default:
+                    break;
+                }
+            }
+        }
+		return RT_FALSE;
+	}
+
+    /* use view event handler */
+    return rtgui_container_event_handler(widget, event);
+}
+
+static void rtgui_list_view_calc(struct rtgui_list_view* view)
+{
+	rtgui_rect_t rect;
+	rt_uint32_t image_width, image_height;
+	rt_ubase_t text_width, text_height;
+	rt_ubase_t item_width, item_height;
+
+	if (view->items_count == 0) return;
+
+	/* get image width and height */
+	if (view->items[0].image != RT_NULL)
+	{
+		image_width  = view->items[0].image->w;
+		image_height = view->items[0].image->h;
+	}
+	else
+	{
+		image_width  = 0;
+		image_height = 0;
+	}
+
+	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), "HHHHHH", &rect);
+
+	text_height = rtgui_rect_height(rect);
+	text_width = rtgui_rect_width(rect);
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+
+	item_width = (image_width + LIST_MARGIN);
+	if (item_width < (text_width + LIST_MARGIN)) item_width = text_width + LIST_MARGIN;
+	item_height = image_height + 8 + text_height + LIST_MARGIN; 
+	if (item_width > item_height) item_height = item_width;
+	else item_width = item_height;
+	
+	view->row_items = (rtgui_rect_height(rect) - 2 * LIST_MARGIN) / item_height;
+	view->col_items = (rtgui_rect_width(rect) - 2 * LIST_MARGIN) / item_width;
+	view->page_items = view->row_items * view->col_items;
+}
+
+rtgui_list_view_t* rtgui_list_view_create(const struct rtgui_list_item* items, rt_uint16_t count, 
+	rtgui_rect_t *rect, rt_uint16_t flag)
+{
+	struct rtgui_list_view* view = RT_NULL;
+
+	view = (struct rtgui_list_view*) rtgui_widget_create(RTGUI_LIST_VIEW_TYPE);
+	if (view != RT_NULL)
+	{
+	    view->items = items;
+	    view->items_count = count;
+
+		view->flag = flag;
+		rtgui_widget_set_rect(RTGUI_WIDGET(view), rect);
+
+		if (flag == RTGUI_LIST_VIEW_LIST)
+			view->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
+		else if ((flag == RTGUI_LIST_VIEW_ICON) && (count > 0))
+		{
+			rtgui_list_view_calc(view);
+		}
+	}
+
+	return view;
+}
+
+void rtgui_list_view_destroy(rtgui_list_view_t* view)
+{
+    /* destroy view */
+	rtgui_widget_destroy(RTGUI_WIDGET(view));
+}

+ 388 - 387
components/rtgui/widgets/listbox.c

@@ -1,387 +1,388 @@
-/*
- * File      : listbox.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-01-06     Bernard      first version
- */
-
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/listbox.h>
-
-#define LIST_MARGIN		5
-
-static void _rtgui_listbox_constructor(struct rtgui_listbox *box)
-{
-	/* set default widget rect and set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(box),rtgui_listbox_event_handler);
-
-	RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
-	box->current_item = -1;
-	box->items_count = 0;
-	box->page_items = 1;
-	box->on_item = 0;
-
-	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
-	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(listbox, "listbox", 
-	RTGUI_WIDGET_TYPE,
-	_rtgui_listbox_constructor,
-	RT_NULL,
-	sizeof(struct rtgui_listbox));
-
-void rtgui_listbox_ondraw(struct rtgui_listbox* box)
-{
-	struct rtgui_dc* dc;
-	rt_uint16_t page_index, index;
-	const struct rtgui_listbox_item* item;
-	struct rtgui_rect rect, item_rect, image_rect;
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
-	if (dc == RT_NULL) return;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
-	rtgui_dc_fill_rect(dc, &rect);
-
-	rect.x2 -= 1; rect.y2 -= 1;
-	/* draw focused border */
-	if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box)))
-		rtgui_dc_draw_focus_rect(dc, &rect);
-
-	/* get item base rect */
-	item_rect = rect;
-	item_rect.x1 += 1; item_rect.x2 -= 1;
-	item_rect.y1 += 2;
-	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
-	/* get current page */
-	if (box->current_item == -1)
-		page_index = 0;
-	else
-		page_index = (box->current_item / box->page_items) * box->page_items;
-
-	for (index = 0; index < box->page_items; index ++)
-	{
-		if (page_index + index >= box->items_count) break;
-
-		item = &(box->items[page_index + index]);
-
-		if (page_index + index == box->current_item)
-		{
-			rtgui_theme_draw_selected(dc, &item_rect);
-		}
-		item_rect.x1 += LIST_MARGIN;
-
-		if (item->image != RT_NULL)
-		{
-			rtgui_image_get_rect(item->image, &image_rect);
-			rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-
-			rtgui_image_blit(item->image, dc, &image_rect);
-			item_rect.x1 += item->image->w + 2;
-		}
-        /* draw text */
-		rtgui_dc_draw_text(dc, item->name, &item_rect);
-
-        if (item->image != RT_NULL)
-            item_rect.x1 -= (item->image->w + 2);
-		item_rect.x1 -= LIST_MARGIN;
-
-        /* move to next item position */
-		item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
-		item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
-	}
-	rtgui_dc_end_drawing(dc);
-}
-
-static void rtgui_listbox_update_current(struct rtgui_listbox* box, rt_int16_t old_item)
-{
-	struct rtgui_dc* dc;
-	const struct rtgui_listbox_item* item;
-	rtgui_rect_t rect, item_rect, image_rect;
-
-	if ((old_item == -1) || (old_item/box->page_items != box->current_item/box->page_items))
-	{
-		/* it's not a same page, update all */
-		rtgui_widget_update(RTGUI_WIDGET(box));
-		return;
-	}
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
-	if (dc == RT_NULL) return;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
-	rect.x2 -= 1; rect.y2 -= 1;
-
-	item_rect = rect;
-	/* get old item's rect */
-	item_rect.x1 += 1; item_rect.x2 -= 1;
-	item_rect.y1 += 2;
-	item_rect.y1 += (old_item % box->page_items) * (2 + rtgui_theme_get_selected_height());
-	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
-	/* draw old item */
-	rtgui_dc_fill_rect(dc, &item_rect);
-
-	item_rect.x1 += LIST_MARGIN;
-
-	item = &(box->items[old_item]);
-	if (item->image != RT_NULL)
-	{
-		rtgui_image_get_rect(item->image, &image_rect);
-		rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-		
-		rtgui_image_blit(item->image, dc, &image_rect);
-		item_rect.x1 += item->image->w + 2;
-	}
-	rtgui_dc_draw_text(dc, item->name, &item_rect);
-
-	/* draw current item */
-	item_rect = rect;
-	/* get current item's rect */
-	item_rect.x1 += 1; item_rect.x2 -= 1;
-	item_rect.y1 += 2;
-	item_rect.y1 += (box->current_item % box->page_items) * (2 + rtgui_theme_get_selected_height());
-	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
-	/* draw current item */
-	rtgui_theme_draw_selected(dc, &item_rect);
-
-	item_rect.x1 += LIST_MARGIN;
-
-	item = &(box->items[box->current_item]);
-	if (item->image != RT_NULL)
-	{
-		rtgui_image_get_rect(item->image, &image_rect);
-		rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-
-		rtgui_image_blit(item->image, dc, &image_rect);
-        item_rect.x1 += (item->image->w + 2);
-	}
-	rtgui_dc_draw_text(dc, item->name, &item_rect);
-
-	rtgui_dc_end_drawing(dc);
-}
-
-rt_bool_t rtgui_listbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_listbox* box = RT_NULL;
-
-	box = RTGUI_LISTBOX(widget);
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-		rtgui_listbox_ondraw(box);
-		return RT_FALSE;
-
-    case RTGUI_EVENT_RESIZE:
-        {
-			struct rtgui_event_resize* resize;
-
-			resize = (struct rtgui_event_resize*)event;
-
-            /* recalculate page items */
-			box->page_items = resize->h  / (2 + rtgui_theme_get_selected_height());
-        }
-        break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-		{
-			rtgui_rect_t rect;
-			struct rtgui_event_mouse* emouse;
-
-			emouse = (struct rtgui_event_mouse*)event;
-
-			/* calculate selected item */
-
-			/* get physical extent information */
-			rtgui_widget_get_rect(widget, &rect);
-			rtgui_widget_rect_to_device(widget, &rect);
-
-			if ((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) && (box->items_count > 0))
-			{
-				rt_uint16_t index;
-				index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
-
-				/* set focus */
-				rtgui_widget_focus(widget);
-				{
-					struct rtgui_rect rect;
-					struct rtgui_dc* dc;
-
-					dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
-					if (dc != RT_NULL)
-					{
-						/* get widget rect */
-						rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
-						/* update focus border */
-						rect.x2 -= 1; rect.y2 -= 1;
-						/* draw focused border */
-						if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box)))
-							rtgui_dc_draw_focus_rect(dc, &rect);
-						rtgui_dc_end_drawing(dc);
-					}
-				}
-
-				if ((index < box->items_count) && (index < box->page_items))
-				{
-					rt_uint16_t old_item;
-
-					old_item = box->current_item;
-
-					/* set selected item */
-					box->current_item = (box->current_item/box->page_items) * box->page_items + index;
-					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
-					{
-						/* down event */
-						rtgui_listbox_update_current(box, old_item);
-					}
-					else
-					{
-						/* up event */
-						if (box->on_item != RT_NULL)
-						{
-							box->on_item(RTGUI_WIDGET(box), RT_NULL);
-						}
-					}
-				}
-			}
-
-			return RT_TRUE;
-		}
-
-    case RTGUI_EVENT_KBD:
-        {
-            struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
-            if ((ekbd->type == RTGUI_KEYDOWN) && (box->items_count > 0))
-            {
-				rt_int16_t old_item;
-
-				if (box->current_item == -1) 
-				{
-					/* set a initial item */
-					if ((box->items_count > 0) && 
-						(ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN))
-					{
-						box->current_item = 0;
-						rtgui_listbox_update_current(box, -1);
-						break;
-					}
-					else return RT_FALSE;
-				}
-				old_item = box->current_item;
-
-                switch (ekbd->key)
-                {
-				case RTGUIK_LEFT:
-					if (box->current_item - box->page_items >= 0)
-						box->current_item -= box->page_items;
-					rtgui_listbox_update_current(box, old_item);
-					return RT_FALSE;
-
-                case RTGUIK_UP:
-					if (box->current_item > 0)
-						box->current_item --;
-					rtgui_listbox_update_current(box, old_item);
-					return RT_FALSE;
-
-				case RTGUIK_RIGHT:
-					if (box->current_item + box->page_items < box->items_count - 1)
-						box->current_item += box->page_items;
-					rtgui_listbox_update_current(box, old_item);
-					return RT_FALSE;
-
-                case RTGUIK_DOWN:
-					if (box->current_item < box->items_count - 1)
-						box->current_item ++;
-					rtgui_listbox_update_current(box, old_item);
-					return RT_FALSE;
-
-				case RTGUIK_RETURN:
-                    if (box->on_item != RT_NULL)
-					{
-						box->on_item(RTGUI_WIDGET(box), RT_NULL);
-					}
-					return RT_FALSE;
-
-                default:
-                    break;
-                }
-            }
-        }
-		return RT_FALSE;
-	}
-
-    /* use box event handler */
-    return rtgui_widget_event_handler(widget, event);
-}
-
-rtgui_listbox_t* rtgui_listbox_create(const struct rtgui_listbox_item* items, rt_uint16_t count, rtgui_rect_t *rect)
-{
-	struct rtgui_listbox* box = RT_NULL;
-
-	box = (struct rtgui_listbox*) rtgui_widget_create(RTGUI_LISTBOX_TYPE);
-	if (box != RT_NULL)
-	{
-	    box->items = items;
-	    box->items_count = count;
-
-		box->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
-		if (box->page_items == 0) box->page_items = 1;
-		rtgui_widget_set_rect(RTGUI_WIDGET(box), rect);
-	}
-
-	return box;
-}
-
-void rtgui_listbox_destroy(rtgui_listbox_t* box)
-{
-    /* destroy box */
-	rtgui_widget_destroy(RTGUI_WIDGET(box));
-}
-
-void rtgui_listbox_set_onitem(rtgui_listbox_t* box, rtgui_onitem_func_t func)
-{
-	RT_ASSERT(box != RT_NULL);
-
-	box->on_item = func;
-}
-
-void rtgui_listbox_set_items(rtgui_listbox_t* box, struct rtgui_listbox_item* items, rt_uint16_t count)
-{
-	rtgui_rect_t rect;
-	
-	box->items = items;
-	box->items_count = count;
-	box->current_item = -1;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
-	box->page_items = rtgui_rect_height(rect) / (2 + rtgui_theme_get_selected_height());
-
-	rtgui_widget_update(RTGUI_WIDGET(box));
-}
-
-void rtgui_listbox_set_current_item(rtgui_listbox_t* box, int index)
-{
-	RT_ASSERT(box != RT_NULL);
-
-	if (index != box->current_item)
-	{
-		int old_item; 
-
-		old_item = box->current_item;
-		box->current_item = index;
-
-		rtgui_listbox_update_current(box, old_item);
-	}
-}
-
+/*
+ * File      : listbox.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-01-06     Bernard      first version
+ */
+
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/listbox.h>
+
+#define LIST_MARGIN		5
+
+static void _rtgui_listbox_constructor(struct rtgui_listbox *box)
+{
+	/* set default widget rect and set event handler */
+	rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_listbox_event_handler);
+
+	RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+	box->current_item = -1;
+	box->items_count = 0;
+	box->page_items = 1;
+	box->on_item = 0;
+
+	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(listbox, "listbox", 
+	RTGUI_WIDGET_TYPE,
+	_rtgui_listbox_constructor,
+	RT_NULL,
+	sizeof(struct rtgui_listbox));
+
+void rtgui_listbox_ondraw(struct rtgui_listbox* box)
+{
+	struct rtgui_dc* dc;
+	rt_uint16_t page_index, index;
+	const struct rtgui_listbox_item* item;
+	struct rtgui_rect rect, item_rect, image_rect;
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
+	if (dc == RT_NULL) return;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
+	rtgui_dc_fill_rect(dc, &rect);
+
+	rect.x2 -= 1; rect.y2 -= 1;
+	/* draw focused border */
+	if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box)))
+		rtgui_dc_draw_focus_rect(dc, &rect);
+
+	/* get item base rect */
+	item_rect = rect;
+	item_rect.x1 += 1; item_rect.x2 -= 1;
+	item_rect.y1 += 2;
+	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+	/* get current page */
+	if (box->current_item == -1)
+		page_index = 0;
+	else
+		page_index = (box->current_item / box->page_items) * box->page_items;
+
+	for (index = 0; index < box->page_items; index ++)
+	{
+		if (page_index + index >= box->items_count) break;
+
+		item = &(box->items[page_index + index]);
+
+		if (page_index + index == box->current_item)
+		{
+			rtgui_theme_draw_selected(dc, &item_rect);
+		}
+		item_rect.x1 += LIST_MARGIN;
+
+		if (item->image != RT_NULL)
+		{
+			rtgui_image_get_rect(item->image, &image_rect);
+			rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+			rtgui_image_blit(item->image, dc, &image_rect);
+			item_rect.x1 += item->image->w + 2;
+		}
+        /* draw text */
+		rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+        if (item->image != RT_NULL)
+            item_rect.x1 -= (item->image->w + 2);
+		item_rect.x1 -= LIST_MARGIN;
+
+        /* move to next item position */
+		item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
+		item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
+	}
+	rtgui_dc_end_drawing(dc);
+}
+
+static void rtgui_listbox_update_current(struct rtgui_listbox* box, rt_int16_t old_item)
+{
+	struct rtgui_dc* dc;
+	const struct rtgui_listbox_item* item;
+	rtgui_rect_t rect, item_rect, image_rect;
+
+	if ((old_item == -1) || (old_item/box->page_items != box->current_item/box->page_items))
+	{
+		/* it's not a same page, update all */
+		rtgui_widget_update(RTGUI_WIDGET(box));
+		return;
+	}
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
+	if (dc == RT_NULL) return;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
+	rect.x2 -= 1; rect.y2 -= 1;
+
+	item_rect = rect;
+	/* get old item's rect */
+	item_rect.x1 += 1; item_rect.x2 -= 1;
+	item_rect.y1 += 2;
+	item_rect.y1 += (old_item % box->page_items) * (2 + rtgui_theme_get_selected_height());
+	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+	/* draw old item */
+	rtgui_dc_fill_rect(dc, &item_rect);
+
+	item_rect.x1 += LIST_MARGIN;
+
+	item = &(box->items[old_item]);
+	if (item->image != RT_NULL)
+	{
+		rtgui_image_get_rect(item->image, &image_rect);
+		rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+		
+		rtgui_image_blit(item->image, dc, &image_rect);
+		item_rect.x1 += item->image->w + 2;
+	}
+	rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+	/* draw current item */
+	item_rect = rect;
+	/* get current item's rect */
+	item_rect.x1 += 1; item_rect.x2 -= 1;
+	item_rect.y1 += 2;
+	item_rect.y1 += (box->current_item % box->page_items) * (2 + rtgui_theme_get_selected_height());
+	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+	/* draw current item */
+	rtgui_theme_draw_selected(dc, &item_rect);
+
+	item_rect.x1 += LIST_MARGIN;
+
+	item = &(box->items[box->current_item]);
+	if (item->image != RT_NULL)
+	{
+		rtgui_image_get_rect(item->image, &image_rect);
+		rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+		rtgui_image_blit(item->image, dc, &image_rect);
+        item_rect.x1 += (item->image->w + 2);
+	}
+	rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+	rtgui_dc_end_drawing(dc);
+}
+
+rt_bool_t rtgui_listbox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_listbox* box;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+	box = RTGUI_LISTBOX(object);
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+		rtgui_listbox_ondraw(box);
+		return RT_FALSE;
+
+    case RTGUI_EVENT_RESIZE:
+        {
+			struct rtgui_event_resize* resize;
+
+			resize = (struct rtgui_event_resize*)event;
+
+            /* recalculate page items */
+			box->page_items = resize->h  / (2 + rtgui_theme_get_selected_height());
+        }
+        break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+		{
+			rtgui_rect_t rect;
+			struct rtgui_event_mouse* emouse;
+
+			emouse = (struct rtgui_event_mouse*)event;
+
+			/* calculate selected item */
+
+			/* get physical extent information */
+			rtgui_widget_get_rect(widget, &rect);
+			rtgui_widget_rect_to_device(widget, &rect);
+
+			if ((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) && (box->items_count > 0))
+			{
+				rt_uint16_t index;
+				index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
+
+				/* set focus */
+				rtgui_widget_focus(widget);
+				{
+					struct rtgui_rect rect;
+					struct rtgui_dc* dc;
+
+					dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
+					if (dc != RT_NULL)
+					{
+						/* get widget rect */
+						rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
+						/* update focus border */
+						rect.x2 -= 1; rect.y2 -= 1;
+						/* draw focused border */
+						if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box)))
+							rtgui_dc_draw_focus_rect(dc, &rect);
+						rtgui_dc_end_drawing(dc);
+					}
+				}
+
+				if ((index < box->items_count) && (index < box->page_items))
+				{
+					rt_uint16_t old_item;
+
+					old_item = box->current_item;
+
+					/* set selected item */
+					box->current_item = (box->current_item/box->page_items) * box->page_items + index;
+					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+					{
+						/* down event */
+						rtgui_listbox_update_current(box, old_item);
+					}
+					else
+					{
+						/* up event */
+						if (box->on_item != RT_NULL)
+						{
+							box->on_item(RTGUI_OBJECT(box), RT_NULL);
+						}
+					}
+				}
+			}
+
+			return RT_TRUE;
+		}
+
+    case RTGUI_EVENT_KBD:
+        {
+            struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+            if ((ekbd->type == RTGUI_KEYDOWN) && (box->items_count > 0))
+            {
+				rt_int16_t old_item;
+
+				if (box->current_item == -1) 
+				{
+					/* set a initial item */
+					if ((box->items_count > 0) && 
+						(ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN))
+					{
+						box->current_item = 0;
+						rtgui_listbox_update_current(box, -1);
+						break;
+					}
+					else return RT_FALSE;
+				}
+				old_item = box->current_item;
+
+                switch (ekbd->key)
+                {
+				case RTGUIK_LEFT:
+					if (box->current_item - box->page_items >= 0)
+						box->current_item -= box->page_items;
+					rtgui_listbox_update_current(box, old_item);
+					return RT_FALSE;
+
+                case RTGUIK_UP:
+					if (box->current_item > 0)
+						box->current_item --;
+					rtgui_listbox_update_current(box, old_item);
+					return RT_FALSE;
+
+				case RTGUIK_RIGHT:
+					if (box->current_item + box->page_items < box->items_count - 1)
+						box->current_item += box->page_items;
+					rtgui_listbox_update_current(box, old_item);
+					return RT_FALSE;
+
+                case RTGUIK_DOWN:
+					if (box->current_item < box->items_count - 1)
+						box->current_item ++;
+					rtgui_listbox_update_current(box, old_item);
+					return RT_FALSE;
+
+				case RTGUIK_RETURN:
+                    if (box->on_item != RT_NULL)
+					{
+						box->on_item(RTGUI_OBJECT(box), RT_NULL);
+					}
+					return RT_FALSE;
+
+                default:
+                    break;
+                }
+            }
+        }
+		return RT_FALSE;
+	}
+
+    /* use box event handler */
+    return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event);
+}
+
+rtgui_listbox_t* rtgui_listbox_create(const struct rtgui_listbox_item* items, rt_uint16_t count, rtgui_rect_t *rect)
+{
+	struct rtgui_listbox* box = RT_NULL;
+
+	box = (struct rtgui_listbox*) rtgui_widget_create(RTGUI_LISTBOX_TYPE);
+	if (box != RT_NULL)
+	{
+	    box->items = items;
+	    box->items_count = count;
+
+		box->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
+		if (box->page_items == 0) box->page_items = 1;
+		rtgui_widget_set_rect(RTGUI_WIDGET(box), rect);
+	}
+
+	return box;
+}
+
+void rtgui_listbox_destroy(rtgui_listbox_t* box)
+{
+    /* destroy box */
+	rtgui_widget_destroy(RTGUI_WIDGET(box));
+}
+
+void rtgui_listbox_set_onitem(rtgui_listbox_t* box, rtgui_event_handler_ptr func)
+{
+	RT_ASSERT(box != RT_NULL);
+
+	box->on_item = func;
+}
+
+void rtgui_listbox_set_items(rtgui_listbox_t* box, struct rtgui_listbox_item* items, rt_uint16_t count)
+{
+	rtgui_rect_t rect;
+
+	box->items = items;
+	box->items_count = count;
+	box->current_item = -1;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
+	box->page_items = rtgui_rect_height(rect) / (2 + rtgui_theme_get_selected_height());
+
+	rtgui_widget_update(RTGUI_WIDGET(box));
+}
+
+void rtgui_listbox_set_current_item(rtgui_listbox_t* box, int index)
+{
+	RT_ASSERT(box != RT_NULL);
+
+	if (index != box->current_item)
+	{
+		int old_item; 
+
+		old_item = box->current_item;
+		box->current_item = index;
+
+		rtgui_listbox_update_current(box, old_item);
+	}
+}
+

+ 427 - 426
components/rtgui/widgets/listctrl.c

@@ -1,426 +1,427 @@
-/*
- * File      : listctrl.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-01-06     Bernard      first version
- */
-
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/listctrl.h>
-
-static void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_item);
-
-static void _rtgui_listctrl_constructor(struct rtgui_listctrl *ctrl)
-{
-	/* set default widget rect and set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(ctrl),rtgui_listctrl_event_handler);
-
-	RTGUI_WIDGET(ctrl)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
-	ctrl->current_item = -1;
-	ctrl->items_count = 0;
-	ctrl->page_items = 0;
-	ctrl->on_item = 0;
-	ctrl->on_item_draw = RT_NULL;
-
-	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(ctrl)) = white;
-	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(ctrl)) = RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(listctrl, "listctrl", 
-	RTGUI_WIDGET_TYPE,
-	_rtgui_listctrl_constructor,
-	RT_NULL,
-	sizeof(struct rtgui_listctrl));
-
-static void _rtgui_listctrl_get_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect)
-{
-	rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect);
-	if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height())
-	{
-		rect->x2 = rect->x2 - 8;
-	}
-}
-
-static void _rtgui_listctrl_get_scrollbar_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect)
-{
-	rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect);
-	if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height())
-	{
-		rect->x1 = rect->x2 - 8;
-	}
-	else
-	{
-		/* no scrollbar */
-		rt_memset(rect, 0, sizeof(rtgui_rect_t));
-	}
-}
-
-static void _rtgui_listctrl_scrollbar_ondraw(struct rtgui_listctrl* ctrl, struct rtgui_dc* dc)
-{
-	rtgui_rect_t rect;
-	rt_uint32_t height, y1;
-
-	/* get scrollbar rect */
-	_rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
-	rtgui_dc_fill_rect(dc, &rect);
-
-	height = rtgui_rect_height(rect);
-
-	height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items);
-	y1 = (ctrl->current_item / ctrl->page_items) * height;
-
-	rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height;
-	rect.x1 -= 3;
-	rtgui_theme_draw_selected(dc, &rect);
-}
-
-static void _rtgui_listctrl_scrollbar_onmouse(struct rtgui_listctrl* ctrl, struct rtgui_event_mouse* mouse)
-{
-	rtgui_rect_t rect;
-	rt_uint32_t height, y1;
-	rt_uint16_t old_item;
-
-	/* get scrollbar rect */
-	_rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
-	height = rtgui_rect_height(rect);
-	height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items);
-	y1 = (ctrl->current_item / ctrl->page_items) * height;
-
-	rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height;
-	rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect);
-
-	old_item = ctrl->current_item;
-	if (mouse->y < rect.y1)
-	{
-		if (ctrl->current_item - ctrl->page_items >= 0)
-			ctrl->current_item -= ctrl->page_items;
-		rtgui_listctrl_update_current(ctrl, old_item);
-	}
-	else if (mouse->y > rect.y2)
-	{
-		if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1)
-			ctrl->current_item += ctrl->page_items;
-		else
-			ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items;
-		rtgui_listctrl_update_current(ctrl, old_item);
-	}
-}
-
-static void _rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl)
-{
-	struct rtgui_rect rect, item_rect;
-	struct rtgui_dc* dc;
-	rt_uint16_t page_index, index;
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
-	if (dc == RT_NULL) return;
-
-	_rtgui_listctrl_get_rect(ctrl, &rect);
-	rtgui_dc_fill_rect(dc, &rect);
-
-	rect.x2 -= 1; rect.y2 -= 1;
-
-	/* get item base rect */
-	item_rect = rect;
-	item_rect.x1 += 1; item_rect.x2 -= 1;
-	item_rect.y1 += 2;
-	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
-	/* get current page */
-	page_index = (ctrl->current_item / ctrl->page_items) * ctrl->page_items;
-	for (index = 0; index < ctrl->page_items; index ++)
-	{
-		if (page_index + index >= ctrl->items_count) break;
-
-		if (page_index + index == ctrl->current_item)
-		{
-			rtgui_theme_draw_selected(dc, &item_rect);
-		}
-
-		if (ctrl->on_item_draw != RT_NULL)
-		{
-			ctrl->on_item_draw(ctrl, dc, &item_rect, page_index + index);
-		}
-
-        /* move to next item position */
-		item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
-		item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
-	}
-
-	/* draw scrollbar */
-	_rtgui_listctrl_scrollbar_ondraw(ctrl, dc);
-	rtgui_dc_end_drawing(dc);
-}
-
-void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_item)
-{
-	struct rtgui_dc* dc;
-	rtgui_rect_t rect, item_rect;
-
-	if (old_item/ctrl->page_items != ctrl->current_item/ctrl->page_items)
-	{
-		/* it's not a same page, update all */
-		rtgui_widget_update(RTGUI_WIDGET(ctrl));
-		return;
-	}
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
-	if (dc == RT_NULL) return;
-
-	_rtgui_listctrl_get_rect(ctrl, &rect);
-	rect.x2 -= 1; rect.y2 -= 1;
-
-	item_rect = rect;
-	/* get old item's rect */
-	item_rect.x1 += 1; item_rect.x2 -= 1;
-	item_rect.y1 += 2;
-	item_rect.y1 += (old_item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
-	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
-	/* draw old item */
-	rtgui_dc_fill_rect(dc, &item_rect);
-	if (ctrl->on_item_draw != RT_NULL)
-		ctrl->on_item_draw(ctrl, dc, &item_rect, old_item);
-
-	/* draw current item */
-	item_rect = rect;
-	/* get current item's rect */
-	item_rect.x1 += 1; item_rect.x2 -= 1;
-	item_rect.y1 += 2;
-	item_rect.y1 += (ctrl->current_item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
-	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
-	/* draw current item */
-	rtgui_theme_draw_selected(dc, &item_rect);
-	if (ctrl->on_item_draw != RT_NULL)
-		ctrl->on_item_draw(ctrl, dc, &item_rect, ctrl->current_item);
-
-	rtgui_dc_end_drawing(dc);
-}
-
-rt_bool_t rtgui_listctrl_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_listctrl* ctrl = RT_NULL;
-
-	ctrl = RTGUI_LISTCTRL(widget);
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-		_rtgui_listctrl_ondraw(ctrl);
-		return RT_FALSE;
-
-    case RTGUI_EVENT_RESIZE:
-        {
-			struct rtgui_event_resize* resize;
-
-			resize = (struct rtgui_event_resize*)event;
-
-            /* recalculate page items */
-			ctrl->page_items = resize->h  / (2 + rtgui_theme_get_selected_height());
-        }
-        break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-		{
-			rtgui_rect_t rect;
-			struct rtgui_event_mouse* emouse;
-
-			emouse = (struct rtgui_event_mouse*)event;
-
-			/* get scrollbar rect */
-			_rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
-			rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect);
-			if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
-			{
-				_rtgui_listctrl_scrollbar_onmouse(ctrl, emouse);
-				return RT_TRUE;
-			}
-
-			/* calculate selected item */
-
-			/* get physical extent information */
-			_rtgui_listctrl_get_rect(ctrl, &rect);
-			rtgui_widget_rect_to_device(widget, &rect);
-
-			if ((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) &&
-					(ctrl->items_count > 0))
-			{
-				rt_uint16_t index;
-				index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
-
-				/* set focus */
-				rtgui_widget_focus(widget);
-				{
-					struct rtgui_rect rect;
-					struct rtgui_dc* dc;
-
-					dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
-					if (dc != RT_NULL)
-					{
-						/* get widget rect */
-						rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect);
-						/* update focus border */
-						rect.x2 -= 1; rect.y2 -= 1;
-						rtgui_dc_end_drawing(dc);
-					}
-				}
-
-				if ((index < ctrl->page_items) &&
-					(ctrl->current_item/ctrl->page_items)* ctrl->page_items + index < ctrl->items_count)
-				{
-					rt_uint16_t old_item;
-
-					old_item = ctrl->current_item;
-
-					/* set selected item */
-					ctrl->current_item = (ctrl->current_item/ctrl->page_items) * ctrl->page_items + index;
-					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
-					{
-						/* down event */
-						rtgui_listctrl_update_current(ctrl, old_item);
-					}
-					else
-					{
-						/* up event */
-						if (ctrl->on_item != RT_NULL)
-						{
-							ctrl->on_item(RTGUI_WIDGET(ctrl), RT_NULL);
-						}
-					}
-				}
-			}
-
-			return RT_TRUE;
-		}
-
-    case RTGUI_EVENT_KBD:
-        {
-            struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
-            if ((ekbd->type == RTGUI_KEYDOWN) && (ctrl->items_count > 0))
-            {
-				rt_uint16_t old_item;
-
-				old_item = ctrl->current_item;
-                switch (ekbd->key)
-                {
-				case RTGUIK_LEFT:
-					if (ctrl->current_item - ctrl->page_items >= 0)
-						ctrl->current_item -= ctrl->page_items;
-					rtgui_listctrl_update_current(ctrl, old_item);
-					return RT_FALSE;
-
-                case RTGUIK_UP:
-					if (ctrl->current_item > 0)
-						ctrl->current_item --;
-					rtgui_listctrl_update_current(ctrl, old_item);
-					return RT_FALSE;
-
-				case RTGUIK_RIGHT:
-					if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1)
-						ctrl->current_item += ctrl->page_items;
-					else
-					{
-						if ((((ctrl->current_item/ctrl->page_items) + 1) * ctrl->page_items) < ctrl->items_count - 1)
-							ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items;
-					}
-					rtgui_listctrl_update_current(ctrl, old_item);
-					return RT_FALSE;
-
-                case RTGUIK_DOWN:
-					if (ctrl->current_item < ctrl->items_count - 1)
-						ctrl->current_item ++;
-					rtgui_listctrl_update_current(ctrl, old_item);
-					return RT_FALSE;
-
-				case RTGUIK_RETURN:
-                    if (ctrl->on_item != RT_NULL)
-					{
-						ctrl->on_item(RTGUI_WIDGET(ctrl), RT_NULL);
-					}
-					return RT_FALSE;
-
-                default:
-                    break;
-                }
-            }
-        }
-		return RT_FALSE;
-	}
-
-    /* use ctrl event handler */
-    return rtgui_widget_event_handler(widget, event);
-}
-
-rtgui_listctrl_t* rtgui_listctrl_create(rt_uint32_t items, rt_uint16_t count, rtgui_rect_t *rect, 
-										rtgui_onitem_draw_t ondraw)
-{
-	struct rtgui_listctrl* ctrl = RT_NULL;
-
-	ctrl = (struct rtgui_listctrl*) rtgui_widget_create(RTGUI_LISTCTRL_TYPE);
-	if (ctrl != RT_NULL)
-	{
-	    ctrl->items = items;
-	    ctrl->items_count = count;
-		ctrl->on_item_draw = ondraw;
-
-		ctrl->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
-		rtgui_widget_set_rect(RTGUI_WIDGET(ctrl), rect);
-	}
-
-	return ctrl;
-}
-
-void rtgui_listctrl_destroy(rtgui_listctrl_t* ctrl)
-{
-    /* destroy ctrl */
-	rtgui_widget_destroy(RTGUI_WIDGET(ctrl));
-}
-
-void rtgui_listctrl_set_onitem(rtgui_listctrl_t* ctrl, rtgui_onitem_func_t func)
-{
-	RT_ASSERT(ctrl != RT_NULL);
-
-	ctrl->on_item = func;
-}
-
-void rtgui_listctrl_set_items(rtgui_listctrl_t* ctrl, rt_uint32_t items, rt_uint16_t count)
-{
-	rtgui_rect_t rect;
-	
-	ctrl->items = items;
-	ctrl->items_count = count;
-	ctrl->current_item = 0;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect);
-	ctrl->page_items = rtgui_rect_height(rect) / (2 + rtgui_theme_get_selected_height());
-
-	rtgui_widget_update(RTGUI_WIDGET(ctrl));
-}
-
-rt_bool_t rtgui_listctrl_get_item_rect(rtgui_listctrl_t* ctrl, rt_uint16_t item, rtgui_rect_t* item_rect)
-{
-	if (item < ctrl->items_count)
-	{
-		rt_uint16_t index;
-
-		/* check whether this item in current page */
-		index = (ctrl->current_item / ctrl->page_items) * ctrl->page_items;
-		if (index > item || index + ctrl->page_items <= item) return RT_FALSE;
-
-		rtgui_widget_get_extent(RTGUI_WIDGET(ctrl), item_rect);
-		item_rect->y1 -= 2;
-		item_rect->y1 += (item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
-		item_rect->y2 = item_rect->y1 + (2 + rtgui_theme_get_selected_height());
-		return RT_TRUE;
-	}
-
-	return RT_FALSE;
-}
+/*
+ * File      : listctrl.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-01-06     Bernard      first version
+ */
+
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/listctrl.h>
+
+static void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_item);
+
+static void _rtgui_listctrl_constructor(struct rtgui_listctrl *ctrl)
+{
+	/* set default widget rect and set event handler */
+	rtgui_object_set_event_handler(RTGUI_OBJECT(ctrl), rtgui_listctrl_event_handler);
+
+	RTGUI_WIDGET(ctrl)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+	ctrl->current_item = -1;
+	ctrl->items_count = 0;
+	ctrl->page_items = 0;
+	ctrl->on_item = 0;
+	ctrl->on_item_draw = RT_NULL;
+
+	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(ctrl)) = white;
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(ctrl)) = RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(listctrl, "listctrl",
+	RTGUI_WIDGET_TYPE,
+	_rtgui_listctrl_constructor,
+	RT_NULL,
+	sizeof(struct rtgui_listctrl));
+
+static void _rtgui_listctrl_get_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect)
+{
+	rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect);
+	if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height())
+	{
+		rect->x2 = rect->x2 - 8;
+	}
+}
+
+static void _rtgui_listctrl_get_scrollbar_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect)
+{
+	rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect);
+	if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height())
+	{
+		rect->x1 = rect->x2 - 8;
+	}
+	else
+	{
+		/* no scrollbar */
+		rt_memset(rect, 0, sizeof(rtgui_rect_t));
+	}
+}
+
+static void _rtgui_listctrl_scrollbar_ondraw(struct rtgui_listctrl* ctrl, struct rtgui_dc* dc)
+{
+	rtgui_rect_t rect;
+	rt_uint32_t height, y1;
+
+	/* get scrollbar rect */
+	_rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
+	rtgui_dc_fill_rect(dc, &rect);
+
+	height = rtgui_rect_height(rect);
+
+	height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items);
+	y1 = (ctrl->current_item / ctrl->page_items) * height;
+
+	rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height;
+	rect.x1 -= 3;
+	rtgui_theme_draw_selected(dc, &rect);
+}
+
+static void _rtgui_listctrl_scrollbar_onmouse(struct rtgui_listctrl* ctrl, struct rtgui_event_mouse* mouse)
+{
+	rtgui_rect_t rect;
+	rt_uint32_t height, y1;
+	rt_uint16_t old_item;
+
+	/* get scrollbar rect */
+	_rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
+	height = rtgui_rect_height(rect);
+	height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items);
+	y1 = (ctrl->current_item / ctrl->page_items) * height;
+
+	rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height;
+	rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect);
+
+	old_item = ctrl->current_item;
+	if (mouse->y < rect.y1)
+	{
+		if (ctrl->current_item - ctrl->page_items >= 0)
+			ctrl->current_item -= ctrl->page_items;
+		rtgui_listctrl_update_current(ctrl, old_item);
+	}
+	else if (mouse->y > rect.y2)
+	{
+		if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1)
+			ctrl->current_item += ctrl->page_items;
+		else
+			ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items;
+		rtgui_listctrl_update_current(ctrl, old_item);
+	}
+}
+
+static void _rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl)
+{
+	struct rtgui_rect rect, item_rect;
+	struct rtgui_dc* dc;
+	rt_uint16_t page_index, index;
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
+	if (dc == RT_NULL) return;
+
+	_rtgui_listctrl_get_rect(ctrl, &rect);
+	rtgui_dc_fill_rect(dc, &rect);
+
+	rect.x2 -= 1; rect.y2 -= 1;
+
+	/* get item base rect */
+	item_rect = rect;
+	item_rect.x1 += 1; item_rect.x2 -= 1;
+	item_rect.y1 += 2;
+	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+	/* get current page */
+	page_index = (ctrl->current_item / ctrl->page_items) * ctrl->page_items;
+	for (index = 0; index < ctrl->page_items; index ++)
+	{
+		if (page_index + index >= ctrl->items_count) break;
+
+		if (page_index + index == ctrl->current_item)
+		{
+			rtgui_theme_draw_selected(dc, &item_rect);
+		}
+
+		if (ctrl->on_item_draw != RT_NULL)
+		{
+			ctrl->on_item_draw(ctrl, dc, &item_rect, page_index + index);
+		}
+
+        /* move to next item position */
+		item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
+		item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
+	}
+
+	/* draw scrollbar */
+	_rtgui_listctrl_scrollbar_ondraw(ctrl, dc);
+	rtgui_dc_end_drawing(dc);
+}
+
+void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_item)
+{
+	struct rtgui_dc* dc;
+	rtgui_rect_t rect, item_rect;
+
+	if (old_item/ctrl->page_items != ctrl->current_item/ctrl->page_items)
+	{
+		/* it's not a same page, update all */
+		rtgui_widget_update(RTGUI_WIDGET(ctrl));
+		return;
+	}
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
+	if (dc == RT_NULL) return;
+
+	_rtgui_listctrl_get_rect(ctrl, &rect);
+	rect.x2 -= 1; rect.y2 -= 1;
+
+	item_rect = rect;
+	/* get old item's rect */
+	item_rect.x1 += 1; item_rect.x2 -= 1;
+	item_rect.y1 += 2;
+	item_rect.y1 += (old_item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
+	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+	/* draw old item */
+	rtgui_dc_fill_rect(dc, &item_rect);
+	if (ctrl->on_item_draw != RT_NULL)
+		ctrl->on_item_draw(ctrl, dc, &item_rect, old_item);
+
+	/* draw current item */
+	item_rect = rect;
+	/* get current item's rect */
+	item_rect.x1 += 1; item_rect.x2 -= 1;
+	item_rect.y1 += 2;
+	item_rect.y1 += (ctrl->current_item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
+	item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+	/* draw current item */
+	rtgui_theme_draw_selected(dc, &item_rect);
+	if (ctrl->on_item_draw != RT_NULL)
+		ctrl->on_item_draw(ctrl, dc, &item_rect, ctrl->current_item);
+
+	rtgui_dc_end_drawing(dc);
+}
+
+rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_listctrl* ctrl;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+	ctrl = RTGUI_LISTCTRL(object);
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+		_rtgui_listctrl_ondraw(ctrl);
+		return RT_FALSE;
+
+    case RTGUI_EVENT_RESIZE:
+        {
+			struct rtgui_event_resize* resize;
+
+			resize = (struct rtgui_event_resize*)event;
+
+            /* recalculate page items */
+			ctrl->page_items = resize->h  / (2 + rtgui_theme_get_selected_height());
+        }
+        break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+		{
+			rtgui_rect_t rect;
+			struct rtgui_event_mouse* emouse;
+
+			emouse = (struct rtgui_event_mouse*)event;
+
+			/* get scrollbar rect */
+			_rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
+			rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect);
+			if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
+			{
+				_rtgui_listctrl_scrollbar_onmouse(ctrl, emouse);
+				return RT_TRUE;
+			}
+
+			/* calculate selected item */
+
+			/* get physical extent information */
+			_rtgui_listctrl_get_rect(ctrl, &rect);
+			rtgui_widget_rect_to_device(widget, &rect);
+
+			if ((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) &&
+					(ctrl->items_count > 0))
+			{
+				rt_uint16_t index;
+				index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
+
+				/* set focus */
+				rtgui_widget_focus(widget);
+				{
+					struct rtgui_rect rect;
+					struct rtgui_dc* dc;
+
+					dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
+					if (dc != RT_NULL)
+					{
+						/* get widget rect */
+						rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect);
+						/* update focus border */
+						rect.x2 -= 1; rect.y2 -= 1;
+						rtgui_dc_end_drawing(dc);
+					}
+				}
+
+				if ((index < ctrl->page_items) &&
+					(ctrl->current_item/ctrl->page_items)* ctrl->page_items + index < ctrl->items_count)
+				{
+					rt_uint16_t old_item;
+
+					old_item = ctrl->current_item;
+
+					/* set selected item */
+					ctrl->current_item = (ctrl->current_item/ctrl->page_items) * ctrl->page_items + index;
+					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+					{
+						/* down event */
+						rtgui_listctrl_update_current(ctrl, old_item);
+					}
+					else
+					{
+						/* up event */
+						if (ctrl->on_item != RT_NULL)
+						{
+							ctrl->on_item(RTGUI_OBJECT(ctrl), RT_NULL);
+						}
+					}
+				}
+			}
+
+			return RT_TRUE;
+		}
+
+    case RTGUI_EVENT_KBD:
+        {
+            struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+            if ((ekbd->type == RTGUI_KEYDOWN) && (ctrl->items_count > 0))
+            {
+				rt_uint16_t old_item;
+
+				old_item = ctrl->current_item;
+                switch (ekbd->key)
+                {
+				case RTGUIK_LEFT:
+					if (ctrl->current_item - ctrl->page_items >= 0)
+						ctrl->current_item -= ctrl->page_items;
+					rtgui_listctrl_update_current(ctrl, old_item);
+					return RT_FALSE;
+
+                case RTGUIK_UP:
+					if (ctrl->current_item > 0)
+						ctrl->current_item --;
+					rtgui_listctrl_update_current(ctrl, old_item);
+					return RT_FALSE;
+
+				case RTGUIK_RIGHT:
+					if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1)
+						ctrl->current_item += ctrl->page_items;
+					else
+					{
+						if ((((ctrl->current_item/ctrl->page_items) + 1) * ctrl->page_items) < ctrl->items_count - 1)
+							ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items;
+					}
+					rtgui_listctrl_update_current(ctrl, old_item);
+					return RT_FALSE;
+
+                case RTGUIK_DOWN:
+					if (ctrl->current_item < ctrl->items_count - 1)
+						ctrl->current_item ++;
+					rtgui_listctrl_update_current(ctrl, old_item);
+					return RT_FALSE;
+
+				case RTGUIK_RETURN:
+                    if (ctrl->on_item != RT_NULL)
+					{
+						ctrl->on_item(RTGUI_OBJECT(ctrl), RT_NULL);
+					}
+					return RT_FALSE;
+
+                default:
+                    break;
+                }
+            }
+        }
+		return RT_FALSE;
+	}
+
+    /* use ctrl event handler */
+    return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event);
+}
+
+rtgui_listctrl_t* rtgui_listctrl_create(rt_uint32_t items, rt_uint16_t count, rtgui_rect_t *rect,
+										rtgui_onitem_draw_t ondraw)
+{
+	struct rtgui_listctrl* ctrl = RT_NULL;
+
+	ctrl = (struct rtgui_listctrl*) rtgui_widget_create(RTGUI_LISTCTRL_TYPE);
+	if (ctrl != RT_NULL)
+	{
+	    ctrl->items = items;
+	    ctrl->items_count = count;
+		ctrl->on_item_draw = ondraw;
+
+		ctrl->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
+		rtgui_widget_set_rect(RTGUI_WIDGET(ctrl), rect);
+	}
+
+	return ctrl;
+}
+
+void rtgui_listctrl_destroy(rtgui_listctrl_t* ctrl)
+{
+    /* destroy ctrl */
+	rtgui_widget_destroy(RTGUI_WIDGET(ctrl));
+}
+
+void rtgui_listctrl_set_onitem(rtgui_listctrl_t* ctrl, rtgui_event_handler_ptr func)
+{
+	RT_ASSERT(ctrl != RT_NULL);
+
+	ctrl->on_item = func;
+}
+
+void rtgui_listctrl_set_items(rtgui_listctrl_t* ctrl, rt_uint32_t items, rt_uint16_t count)
+{
+	rtgui_rect_t rect;
+
+	ctrl->items = items;
+	ctrl->items_count = count;
+	ctrl->current_item = 0;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect);
+	ctrl->page_items = rtgui_rect_height(rect) / (2 + rtgui_theme_get_selected_height());
+
+	rtgui_widget_update(RTGUI_WIDGET(ctrl));
+}
+
+rt_bool_t rtgui_listctrl_get_item_rect(rtgui_listctrl_t* ctrl, rt_uint16_t item, rtgui_rect_t* item_rect)
+{
+	if (item < ctrl->items_count)
+	{
+		rt_uint16_t index;
+
+		/* check whether this item in current page */
+		index = (ctrl->current_item / ctrl->page_items) * ctrl->page_items;
+		if (index > item || index + ctrl->page_items <= item) return RT_FALSE;
+
+		rtgui_widget_get_extent(RTGUI_WIDGET(ctrl), item_rect);
+		item_rect->y1 -= 2;
+		item_rect->y1 += (item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
+		item_rect->y2 = item_rect->y1 + (2 + rtgui_theme_get_selected_height());
+		return RT_TRUE;
+	}
+
+	return RT_FALSE;
+}

+ 287 - 275
components/rtgui/widgets/menu.c

@@ -1,275 +1,287 @@
-#include <rtgui/dc.h>
-#include <rtgui/widgets/menu.h>
-#include <rtgui/rtgui_theme.h>
-
-static rt_bool_t rtgui_menu_on_deactivate(rtgui_widget_t* widget, rtgui_event_t* event);
-const static rt_uint8_t right_arrow[] = {0x80, 0xc0, 0xe0, 0xf0, 0xe0, 0xc0, 0x80};
-
-static void _rtgui_menu_constructor(rtgui_menu_t *menu)
-{
-	/* set window style */
-	RTGUI_WIN(menu)->style = RTGUI_WIN_STYLE_NO_TITLE;
-
-	/* set deactivate handler */
-	rtgui_win_set_ondeactivate(RTGUI_WIN(menu), rtgui_menu_on_deactivate);
-
-	/* set proper of control */
-	menu->parent_menu = RT_NULL;
-	menu->sub_menu = RT_NULL;
-
-	menu->items = RT_NULL;
-	menu->items_count = 0; 
-	menu->items_list = RT_NULL;
-
-	menu->on_menupop  = RT_NULL;
-	menu->on_menuhide = RT_NULL;
-}
-
-static void _rtgui_menu_destructor(rtgui_menu_t* menu)
-{
-	if (menu->sub_menu != RT_NULL)
-	{
-		rtgui_menu_destroy(menu->sub_menu);
-		menu->sub_menu = RT_NULL;
-	}
-
-	rtgui_listctrl_destroy(menu->items_list);
-	menu->items_list = RT_NULL;
-}
-
-static void _rtgui_menu_onitem(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_menu* menu;
-
-	/* get menu */
-	menu = RTGUI_MENU(rtgui_widget_get_toplevel(widget));
-	if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU)
-	{
-		const rtgui_menu_item_t* items;
-		rt_uint16_t count;
-		rtgui_rect_t item_rect;
-
-		items = (rtgui_menu_item_t*)menu->items[menu->items_list->current_item].submenu;
-		count = menu->items[menu->items_list->current_item].submenu_count;
-		if (menu->sub_menu != RT_NULL)
-		{
-			if (menu->sub_menu->items == items)
-			{
-				if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(menu->sub_menu)))
-				{
-					/* hide this sub menu */
-					rtgui_win_hiden(RTGUI_WIN(menu->sub_menu));
-					return;
-				}
-
-				/* show this sub menu */
-				rtgui_listctrl_get_item_rect(menu->items_list, menu->items_list->current_item, &item_rect);
-				rtgui_menu_pop(menu->sub_menu, item_rect.x2, item_rect.y1);
-				return;
-			}
-
-			/* delete sub menu */
-			rtgui_menu_destroy(menu->sub_menu);
-			menu->sub_menu = RT_NULL;
-		}
-
-		/* create sub menu */
-		menu->sub_menu = rtgui_menu_create("submenu", menu, items, count);
-
-		rtgui_listctrl_get_item_rect(menu->items_list, menu->items_list->current_item, &item_rect);
-		rtgui_menu_pop(menu->sub_menu, item_rect.x2 + 5, item_rect.y1);
-	}
-	else /* other menu item */
-	{
-		/* invoke action */
-		if (menu->items[menu->items_list->current_item].on_menuaction != RT_NULL)
-			menu->items[menu->items_list->current_item].on_menuaction(RTGUI_WIDGET(menu), RT_NULL);
-
-		/* hide sub-menu */
-		if (menu->sub_menu != RT_NULL)
-		{
-			rtgui_menu_hiden(menu->sub_menu);
-		}
-		rtgui_menu_hiden(menu);
-	}
-}
-
-static void _rtgui_menu_item_ondraw(struct rtgui_listctrl *list, struct rtgui_dc* dc, rtgui_rect_t* rect, rt_uint16_t index)
-{
-	rtgui_rect_t item_rect;
-	struct rtgui_menu_item* item;
-
-	item_rect = *rect;
-	item_rect.x1 += 5;
-
-	/* re-fill item */
-	if (list->current_item == index)
-	{
-		rtgui_color_t bc;
-
-		bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list));
-		RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = blue;
-		rtgui_dc_fill_rect(dc, rect);
-		RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = bc;
-	}
-
-	/* get menu item */
-	item = (rtgui_menu_item_t*)list->items;
-	item = &item[index];
-
-	if (item->type == RTGUI_ITEM_SUBMENU)
-	{
-		rtgui_rect_t r = {0, 0, 8, 8};
-		rtgui_dc_draw_text(dc, item->label, &item_rect);
-		item_rect.x1 = item_rect.x2 - 16; item_rect.x2 -= 8;
-		rtgui_rect_moveto_align(&item_rect, &r, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
-		rtgui_dc_draw_byte(dc, r.x1, r.y1, 8, right_arrow);
-	}
-	else if (item->type == RTGUI_ITEM_SEPARATOR)
-	{
-		rtgui_dc_draw_horizontal_line(dc, item_rect.x1, item_rect.x2, (item_rect.y2 + item_rect.y1)/2);
-	}
-	else if (item->type == RTGUI_ITEM_CHECK)
-	{
-		/* not support right now */
-	}
-	else
-	{
-		/* normal menu item */	
-		rtgui_dc_draw_text(dc, item->label, &item_rect);
-		if (item->image != RT_NULL)
-			rtgui_image_blit(item->image, dc, &item_rect);
-	}
-}
-
-DEFINE_CLASS_TYPE(menu, "menu", 
-	RTGUI_WIN_TYPE,
-	_rtgui_menu_constructor,
-	_rtgui_menu_destructor,
-	sizeof(struct rtgui_menu));
-
-static rt_bool_t rtgui_menu_on_deactivate(rtgui_widget_t* widget, rtgui_event_t* event)
-{
-	rtgui_menu_t* menu = (rtgui_menu_t*) widget;
-
-	if (menu->parent_menu != RT_NULL)
-	{
-		/* whether click on parent menu */
-		if (rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_TRUE &&
-			menu->parent_menu->items[menu->parent_menu->items_list->current_item].submenu == (struct rtgui_menu_item_t *)menu->items)
-			return RT_TRUE;
-	}
-
-	/* submenu is activate */
-	if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU)
-	{
-		/* if sub menu activated, not hide menu */
-		if (menu->sub_menu != RT_NULL && 
-			rtgui_win_is_activated(RTGUI_WIN(menu->sub_menu)) == RT_TRUE)
-			return RT_TRUE;
-	}
-
-	rtgui_win_hiden(RTGUI_WIN(menu));
-	if (menu->on_menuhide != RT_NULL)
-	{
-		menu->on_menuhide(RTGUI_WIDGET(menu), RT_NULL);
-	}
-
-	/* un-select item */
-	menu->items_list->current_item = -1;
-
-	/* if it's a submenu, try to hide parent menu */
-	if (menu->parent_menu != RT_NULL &&
-		rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_FALSE)
-	{
-		rtgui_menu_on_deactivate(RTGUI_WIDGET(menu->parent_menu), event);
-	}
-
-	return RT_TRUE;
-}
-
-struct rtgui_menu* rtgui_menu_create(const char* title, struct rtgui_menu* parent_menu, 
-	const struct rtgui_menu_item* items, rt_uint16_t count)
-{
-	rtgui_rect_t rect = {0, 0, 100, 100};
-    struct rtgui_menu* menu;
-
-    menu = (struct rtgui_menu*) rtgui_widget_create ( RTGUI_MENU_TYPE );
-	if (menu != RT_NULL)
-	{
-		rtgui_win_set_title(RTGUI_WIN(menu), title);
-		menu->parent_menu = parent_menu;
-		menu->items = items;
-		menu->items_count = count;
-
-		rtgui_widget_set_rect(RTGUI_WIDGET(menu), &rect);
-		rtgui_rect_inflate(&rect, -1);
-		/* create menu item list */
-		menu->items_list = rtgui_listctrl_create((rt_uint32_t)items, count, &rect, _rtgui_menu_item_ondraw); 
-		RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(menu->items_list)) = rtgui_theme_default_bc();
-		rtgui_container_add_child(RTGUI_CONTAINER(menu), RTGUI_WIDGET(menu->items_list));
-		rtgui_listctrl_set_onitem(menu->items_list, _rtgui_menu_onitem);
-	}
-
-	return menu;
-}
-
-void rtgui_menu_destroy(struct rtgui_menu* menu)
-{
-	rtgui_widget_destroy (RTGUI_WIDGET(menu));
-}
-
-void rtgui_menu_set_onmenupop(struct rtgui_menu* menu, rtgui_event_handler_ptr handler)
-{
-	if (menu == RT_NULL) return;
-
-	menu->on_menupop = handler;
-}
-
-void rtgui_menu_set_onmenuhide(struct rtgui_menu* menu, rtgui_event_handler_ptr handler)
-{
-	if (menu == RT_NULL) return;
-
-	menu->on_menuhide = handler;
-}
-
-void rtgui_menu_pop(struct rtgui_menu* menu, int x, int y)
-{
-	rtgui_rect_t rect;
-	struct rtgui_event_resize eresize;
-
-	if (menu == RT_NULL) return;
-
-	/* set window extent */
-	rect.x1 = 0; rect.y1 = 0;
-	rect.x2 = 100; rect.y2 = menu->items_count * (rtgui_theme_get_selected_height() + 2) + 5;
-	rtgui_rect_moveto(&rect, x, y);
-	rtgui_win_set_rect(RTGUI_WIN(menu), &rect);
-	rtgui_rect_inflate(&rect, -1);
-	rtgui_widget_set_rect(RTGUI_WIDGET(menu->items_list), &rect);
-
-	eresize.parent.type = RTGUI_EVENT_RESIZE;
-	eresize.x = rect.x1; eresize.y = rect.y1;
-	eresize.h = rect.y2 - rect.y1; eresize.w = rect.x2 - rect.x1;
-	rtgui_listctrl_event_handler(RTGUI_WIDGET(menu->items_list), &(eresize.parent));
-
-	/* on menu pop handler */
-	if (menu->on_menupop != RT_NULL)
-	{
-		menu->on_menupop(RTGUI_WIDGET(menu), RT_NULL);
-	}
-
-	/* show menu window */
-	rtgui_win_show(RTGUI_WIN(menu), RT_FALSE);
-}
-
-void rtgui_menu_hiden(struct rtgui_menu* menu)
-{
-	rtgui_win_hiden(RTGUI_WIN(menu));
-	/* un-select item */
-	menu->items_list->current_item = -1;
-
-	if (menu->parent_menu != RT_NULL)
-		rtgui_menu_hiden(menu->parent_menu);
-}
-
+#include <rtgui/dc.h>
+#include <rtgui/widgets/menu.h>
+#include <rtgui/rtgui_theme.h>
+
+static rt_bool_t rtgui_menu_on_deactivate(struct rtgui_object* object, rtgui_event_t* event);
+const static rt_uint8_t right_arrow[] = {0x80, 0xc0, 0xe0, 0xf0, 0xe0, 0xc0, 0x80};
+
+static void _rtgui_menu_constructor(rtgui_menu_t *menu)
+{
+	/* set window style */
+	RTGUI_WIN(menu)->style = RTGUI_WIN_STYLE_NO_TITLE;
+
+	/* set deactivate handler */
+	rtgui_win_set_ondeactivate(RTGUI_WIN(menu), rtgui_menu_on_deactivate);
+
+	/* set proper of control */
+	menu->parent_menu = RT_NULL;
+	menu->sub_menu = RT_NULL;
+
+	menu->items = RT_NULL;
+	menu->items_count = 0; 
+	menu->items_list = RT_NULL;
+
+	menu->on_menupop  = RT_NULL;
+	menu->on_menuhide = RT_NULL;
+}
+
+static void _rtgui_menu_destructor(rtgui_menu_t* menu)
+{
+	if (menu->sub_menu != RT_NULL)
+	{
+		rtgui_menu_destroy(menu->sub_menu);
+		menu->sub_menu = RT_NULL;
+	}
+
+	rtgui_listctrl_destroy(menu->items_list);
+	menu->items_list = RT_NULL;
+}
+
+static rt_bool_t _rtgui_menu_onitem(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_menu* menu;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+	/* get menu */
+	menu = RTGUI_MENU(rtgui_widget_get_toplevel(widget));
+	if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU)
+	{
+		const rtgui_menu_item_t* items;
+		rt_uint16_t count;
+		rtgui_rect_t item_rect;
+
+		items = (rtgui_menu_item_t*)menu->items[menu->items_list->current_item].submenu;
+		count = menu->items[menu->items_list->current_item].submenu_count;
+		if (menu->sub_menu != RT_NULL)
+		{
+			if (menu->sub_menu->items == items)
+			{
+				if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(menu->sub_menu)))
+				{
+					/* hide this sub menu */
+					rtgui_win_hiden(RTGUI_WIN(menu->sub_menu));
+					return RT_FALSE;
+				}
+
+				/* show this sub menu */
+				rtgui_listctrl_get_item_rect(menu->items_list, menu->items_list->current_item, &item_rect);
+				rtgui_menu_pop(menu->sub_menu, item_rect.x2, item_rect.y1);
+				return RT_FALSE;
+			}
+
+			/* delete sub menu */
+			rtgui_menu_destroy(menu->sub_menu);
+			menu->sub_menu = RT_NULL;
+		}
+
+		/* create sub menu */
+		menu->sub_menu = rtgui_menu_create("submenu", menu, items, count);
+
+		rtgui_listctrl_get_item_rect(menu->items_list, menu->items_list->current_item, &item_rect);
+		rtgui_menu_pop(menu->sub_menu, item_rect.x2 + 5, item_rect.y1);
+	}
+	else /* other menu item */
+	{
+		/* invoke action */
+		if (menu->items[menu->items_list->current_item].on_menuaction != RT_NULL)
+			menu->items[menu->items_list->current_item].on_menuaction(RTGUI_WIDGET(menu), RT_NULL);
+
+		/* hide sub-menu */
+		if (menu->sub_menu != RT_NULL)
+		{
+			rtgui_menu_hiden(menu->sub_menu);
+		}
+		rtgui_menu_hiden(menu);
+	}
+	return RT_FALSE;
+}
+
+static void _rtgui_menu_item_ondraw(struct rtgui_listctrl *list,
+									struct rtgui_dc* dc,
+									rtgui_rect_t* rect,
+									rt_uint16_t index)
+{
+	rtgui_rect_t item_rect;
+	struct rtgui_menu_item* item;
+
+	item_rect = *rect;
+	item_rect.x1 += 5;
+
+	/* re-fill item */
+	if (list->current_item == index)
+	{
+		rtgui_color_t bc;
+
+		bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list));
+		RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = blue;
+		rtgui_dc_fill_rect(dc, rect);
+		RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = bc;
+	}
+
+	/* get menu item */
+	item = (rtgui_menu_item_t*)list->items;
+	item = &item[index];
+
+	if (item->type == RTGUI_ITEM_SUBMENU)
+	{
+		rtgui_rect_t r = {0, 0, 8, 8};
+		rtgui_dc_draw_text(dc, item->label, &item_rect);
+		item_rect.x1 = item_rect.x2 - 16; item_rect.x2 -= 8;
+		rtgui_rect_moveto_align(&item_rect, &r, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
+		rtgui_dc_draw_byte(dc, r.x1, r.y1, 8, right_arrow);
+	}
+	else if (item->type == RTGUI_ITEM_SEPARATOR)
+	{
+		rtgui_dc_draw_horizontal_line(dc, item_rect.x1, item_rect.x2, (item_rect.y2 + item_rect.y1)/2);
+	}
+	else if (item->type == RTGUI_ITEM_CHECK)
+	{
+		/* not support right now */
+	}
+	else
+	{
+		/* normal menu item */	
+		rtgui_dc_draw_text(dc, item->label, &item_rect);
+		if (item->image != RT_NULL)
+			rtgui_image_blit(item->image, dc, &item_rect);
+	}
+}
+
+DEFINE_CLASS_TYPE(menu, "menu",
+	RTGUI_WIN_TYPE,
+	_rtgui_menu_constructor,
+	_rtgui_menu_destructor,
+	sizeof(struct rtgui_menu));
+
+static rt_bool_t rtgui_menu_on_deactivate(struct rtgui_object *object, rtgui_event_t* event)
+{
+	rtgui_menu_t* menu;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+	menu = RTGUI_MENU(object);
+	if (menu->parent_menu != RT_NULL)
+	{
+		/* whether click on parent menu */
+		if (rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_TRUE &&
+			menu->parent_menu->items[menu->parent_menu->items_list->current_item].submenu
+				== (struct rtgui_menu_item_t *)menu->items)
+			return RT_TRUE;
+	}
+
+	/* submenu is activate */
+	if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU)
+	{
+		/* if sub menu activated, not hide menu. But we cannot use the
+		 * activated flag as criteria since the old window is deactivated
+		 * before the new window got activated. But the window will be shown in
+		 * this context, so use 'is not hide'. */
+		if (menu->sub_menu != RT_NULL &&
+			!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(menu->sub_menu)))
+			return RT_TRUE;
+	}
+
+	rtgui_win_hiden(RTGUI_WIN(menu));
+	if (menu->on_menuhide != RT_NULL)
+	{
+		menu->on_menuhide(RTGUI_OBJECT(menu), RT_NULL);
+	}
+
+	/* un-select item */
+	menu->items_list->current_item = -1;
+
+	/* if it's a submenu, try to hide parent menu */
+	if (menu->parent_menu != RT_NULL &&
+		rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_FALSE)
+	{
+		rtgui_menu_on_deactivate(RTGUI_OBJECT(menu->parent_menu), event);
+	}
+
+	return RT_TRUE;
+}
+
+struct rtgui_menu* rtgui_menu_create(const char* title, struct rtgui_menu* parent_menu,
+									 const struct rtgui_menu_item* items, rt_uint16_t count)
+{
+	rtgui_rect_t rect = {0, 0, 100, 100};
+    struct rtgui_menu* menu;
+
+    menu = (struct rtgui_menu*) rtgui_widget_create ( RTGUI_MENU_TYPE );
+	if (menu != RT_NULL)
+	{
+		rtgui_win_set_title(RTGUI_WIN(menu), title);
+		menu->parent_menu = parent_menu;
+		menu->items = items;
+		menu->items_count = count;
+
+		rtgui_widget_set_rect(RTGUI_WIDGET(menu), &rect);
+		rtgui_rect_inflate(&rect, -1);
+		/* create menu item list */
+		menu->items_list = rtgui_listctrl_create((rt_uint32_t)items, count, &rect, _rtgui_menu_item_ondraw);
+		RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(menu->items_list)) = rtgui_theme_default_bc();
+		rtgui_container_add_child(RTGUI_CONTAINER(menu), RTGUI_WIDGET(menu->items_list));
+		rtgui_listctrl_set_onitem(menu->items_list, _rtgui_menu_onitem);
+	}
+
+	return menu;
+}
+
+void rtgui_menu_destroy(struct rtgui_menu* menu)
+{
+	rtgui_widget_destroy (RTGUI_WIDGET(menu));
+}
+
+void rtgui_menu_set_onmenupop(struct rtgui_menu* menu, rtgui_event_handler_ptr handler)
+{
+	if (menu == RT_NULL) return;
+
+	menu->on_menupop = handler;
+}
+
+void rtgui_menu_set_onmenuhide(struct rtgui_menu* menu, rtgui_event_handler_ptr handler)
+{
+	if (menu == RT_NULL) return;
+
+	menu->on_menuhide = handler;
+}
+
+void rtgui_menu_pop(struct rtgui_menu* menu, int x, int y)
+{
+	rtgui_rect_t rect;
+	struct rtgui_event_resize eresize;
+
+	if (menu == RT_NULL)
+		return;
+
+	/* set window extent */
+	rect.x1 = 0; rect.y1 = 0;
+	rect.x2 = 100; rect.y2 = menu->items_count * (rtgui_theme_get_selected_height() + 2) + 5;
+	rtgui_rect_moveto(&rect, x, y);
+	rtgui_win_set_rect(RTGUI_WIN(menu), &rect);
+	rtgui_rect_inflate(&rect, -1);
+	rtgui_widget_set_rect(RTGUI_WIDGET(menu->items_list), &rect);
+
+	eresize.parent.type = RTGUI_EVENT_RESIZE;
+	eresize.x = rect.x1; eresize.y = rect.y1;
+	eresize.h = rect.y2 - rect.y1; eresize.w = rect.x2 - rect.x1;
+	rtgui_listctrl_event_handler(RTGUI_OBJECT(menu->items_list), &(eresize.parent));
+
+	/* on menu pop handler */
+	if (menu->on_menupop != RT_NULL)
+	{
+		menu->on_menupop(RTGUI_OBJECT(menu), RT_NULL);
+	}
+
+	/* show menu window */
+	rtgui_win_show(RTGUI_WIN(menu), RT_FALSE);
+}
+
+void rtgui_menu_hiden(struct rtgui_menu* menu)
+{
+	rtgui_win_hiden(RTGUI_WIN(menu));
+	/* un-select item */
+	menu->items_list->current_item = -1;
+
+	if (menu->parent_menu != RT_NULL)
+		rtgui_menu_hiden(menu->parent_menu);
+}
+

+ 356 - 330
components/rtgui/widgets/notebook.c

@@ -1,330 +1,356 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/notebook.h>
-
-#define RTGUI_NOTEBOOK_TAB_WIDTH     80
-
-static void _rtgui_notebook_get_bar_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect);
-static void _rtgui_notebook_get_page_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect);
-
-static void _rtgui_notebook_constructor(rtgui_notebook_t *notebook)
-{
-	notebook->flag = 0;
-	notebook->childs = RT_NULL;
-	notebook->count = 0;
-	notebook->current = RTGUI_NOT_FOUND;
-
-	RTGUI_WIDGET(notebook)->gc.textalign = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(notebook), rtgui_notebook_event_handler);
-}
-
-static void _rtgui_notebook_destructor(rtgui_notebook_t *notebook)
-{
-	int index;
-
-	if (notebook->childs != RT_NULL)
-	{
-		for (index = 0; index < notebook->count; index ++)
-		{
-			rtgui_widget_destroy(notebook->childs[index].widget);
-			rt_free(notebook->childs[index].title);
-		}
-
-		rtgui_free(notebook->childs);
-	}
-}
-
-/* Draw tab bars of @param notebook. @param dc should be initialized and
- * finished outside this function. Don't pass @param notebook or @param dc as
- * RT_NULL, it should be checked outside.
- */
-static void _rtgui_notebook_draw_bar(struct rtgui_notebook *notebook,
-		struct rtgui_dc *dc)
-{
-	struct rtgui_rect rect;
-	int index;
-
-	RT_ASSERT((notebook != RT_NULL) && (dc != RT_NULL));
-
-	_rtgui_notebook_get_bar_rect(notebook, &rect);
-	rtgui_dc_fill_rect(dc, &rect);
-
-	rect.x2 = rect.x1 + RTGUI_NOTEBOOK_TAB_WIDTH;
-	/* draw tab bar */
-	for (index = 0; index < notebook->count; index++)
-	{
-		if (notebook->current == index)
-			rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN);
-		else
-			rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_BOX);
-
-		rtgui_dc_draw_text(dc, notebook->childs[index].title, &rect);
-		rect.x1 += RTGUI_NOTEBOOK_TAB_WIDTH;
-		rect.x2 += RTGUI_NOTEBOOK_TAB_WIDTH;
-	}
-
-}
-
-static void _rtgui_notebook_ondraw(rtgui_notebook_t *notebook)
-{
-	struct rtgui_dc* dc;
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook));
-	if (dc == RT_NULL) return;
-
-	if (notebook->count == 0)
-	{
-		rtgui_rect_t rect;
-		rtgui_widget_get_rect(RTGUI_WIDGET(notebook), &rect);
-		rtgui_dc_fill_rect(dc, &rect);
-	}
-	else
-	{
-		if (notebook->current == RTGUI_NOT_FOUND)
-			notebook->current = 0;
-
-		_rtgui_notebook_draw_bar(notebook, dc);
-
-		/* draw current tab */
-		rtgui_widget_update(notebook->childs[notebook->current].widget);
-	}
-	rtgui_dc_end_drawing(dc);
-}
-
-static void _rtgui_notebook_onmouse(rtgui_notebook_t *notebook, struct rtgui_event_mouse* emouse)
-{
-	rtgui_rect_t rect;
-
-	/* handle notebook bar */
-	_rtgui_notebook_get_bar_rect(notebook, &rect);
-	rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect);
-	if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
-	{
-		int index;
-		struct rtgui_dc* dc;
-
-		index = (emouse->x - rect.x1) / RTGUI_NOTEBOOK_TAB_WIDTH;
-		if (index < notebook->count && index != notebook->current)
-		{
-			/* update tab bar */
-			dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook));
-			if (dc == RT_NULL) return;
-
-			rtgui_notebook_set_current_by_index(notebook, index);
-
-			_rtgui_notebook_draw_bar(notebook, dc);
-
-			rtgui_dc_end_drawing(dc);
-		}
-	}
-	else
-	{
-	/* handle on page */
-		if (notebook->childs[notebook->current].widget->event_handler != RT_NULL)
-			notebook->childs[notebook->current].widget->event_handler(
-					notebook->childs[notebook->current].widget,
-					&(emouse->parent));
-	}
-}
-
-static void _rtgui_notebook_get_page_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect)
-{
-	RT_ASSERT(notebook != RT_NULL);
-	RT_ASSERT(rect != RT_NULL);
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect);
-
-	if (notebook->flag == RTGUI_NOTEBOOK_NOTAB) return;
-	else if (notebook->flag == RTGUI_NOTEBOOK_TOP)
-		rect->y1 = rect->y1 + 25;
-	else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM)
-		rect->y2 = rect->y2 - 25;
-}
-
-static void _rtgui_notebook_get_bar_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect)
-{
-	RT_ASSERT(notebook != RT_NULL);
-	RT_ASSERT(rect != RT_NULL);
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect);
-	if (notebook->flag == RTGUI_NOTEBOOK_NOTAB) return;
-	else if (notebook->flag == RTGUI_NOTEBOOK_TOP)
-		rect->y2 = rect->y1 + 25;
-	else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM)
-		rect->y1 = rect->y2 - 25;
-}
-
-DEFINE_CLASS_TYPE(notebook, "notebook", 
-	RTGUI_CONTAINER_TYPE,
-	_rtgui_notebook_constructor,
-	_rtgui_notebook_destructor,
-	sizeof(struct rtgui_notebook));
-
-rtgui_notebook_tab_t *tabs;
-struct rtgui_notebook *_notebook;
-rtgui_notebook_t* rtgui_notebook_create(const rtgui_rect_t* rect, rt_uint8_t style)
-{
-    struct rtgui_notebook* notebook;
-
-    notebook = (struct rtgui_notebook*) rtgui_widget_create (RTGUI_NOTEBOOK_TYPE);
-    if (notebook != RT_NULL)
-    {
-		notebook->flag = style;
-		rtgui_widget_set_rect(RTGUI_WIDGET(notebook), rect);
-    }
-
-	_notebook = notebook;
-    return notebook;
-}
-
-void rtgui_notebook_destroy(rtgui_notebook_t* notebook)
-{
-	rtgui_widget_destroy(RTGUI_WIDGET(notebook));
-}
-
-void rtgui_notebook_add(rtgui_notebook_t* notebook, const char* label, rtgui_widget_t* child)
-{
-	rtgui_rect_t rect;
-	RT_ASSERT(notebook != RT_NULL);
-
-	notebook->count += 1;
-	notebook->childs = (struct rtgui_notebook_tab*) rtgui_realloc(notebook->childs, 
-		sizeof(struct rtgui_notebook_tab) * notebook->count);
-
-	notebook->childs[notebook->count - 1].title = rt_strdup(label);
-	notebook->childs[notebook->count - 1].widget = child;
-
-	tabs = notebook->childs;
-
-	/* set parent */
-	rtgui_widget_set_parent(child, RTGUI_WIDGET(notebook));
-
-	_rtgui_notebook_get_page_rect(notebook, &rect);
-	rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect);
-	rtgui_widget_set_rect(child, &rect);
-}
-
-void rtgui_notebook_remove(rtgui_notebook_t* notebook, rt_uint16_t index)
-{
-	struct rtgui_notebook_tab tab;
-	RT_ASSERT(notebook != RT_NULL);
-
-	if (index < notebook->count)
-	{
-		if (notebook->count == 1)
-		{
-			tab = notebook->childs[0];
-			rtgui_free(notebook->childs);
-			notebook->childs = RT_NULL;
-			notebook->count = 0;
-		}
-		else
-		{
-			tab = notebook->childs[index];
-			for (;index < notebook->count - 1; index ++)
-			{
-				notebook->childs[index] = notebook->childs[index + 1];
-			}
-
-			notebook->count -= 1;
-			notebook->childs = (struct rtgui_notebook_tab*) rtgui_realloc(notebook->childs, 
-				sizeof(struct rtgui_notebook_tab) * notebook->count);
-		}
-
-		rtgui_widget_destroy(tab.widget);
-		rtgui_free(tab.title);
-
-		if (notebook->current == index)
-		{
-			/* update tab */
-			if (notebook->current > notebook->count - 1)
-				notebook->current = notebook->count - 1;
-			rtgui_widget_update(RTGUI_WIDGET(notebook));
-		}
-	}
-}
-
-int rtgui_notebook_get_count(rtgui_notebook_t* notebook)
-{
-	return notebook->count;
-}
-
-rtgui_widget_t* rtgui_notebook_get_current(rtgui_notebook_t* notebook)
-{
-	RT_ASSERT(notebook != RT_NULL);
-	if (notebook->current != RTGUI_NOT_FOUND)
-		return notebook->childs[notebook->current].widget;
-
-	return RT_NULL;
-}
-void rtgui_notebook_set_current(rtgui_notebook_t* notebook, rtgui_widget_t* widget)
-{
-	rt_int16_t index;
-
-	RT_ASSERT(notebook != RT_NULL);
-
-	for (index = 0; index < notebook->count; index ++)
-	{
-		if (widget == notebook->childs[index].widget)
-		{
-			rtgui_notebook_set_current_by_index(notebook, index);
-			return;
-		}
-	}
-}
-
-void rtgui_notebook_set_current_by_index(rtgui_notebook_t* notebook, rt_uint16_t index)
-{
-	RT_ASSERT(notebook != RT_NULL);
-
-	if ((index < notebook->count) && (notebook->current != index))
-	{
-		if (notebook->current != RTGUI_NOT_FOUND)
-			rtgui_widget_hide(notebook->childs[notebook->current].widget);
-
-		notebook->current = index;
-		rtgui_widget_show(notebook->childs[notebook->current].widget);
-		rtgui_widget_update(notebook->childs[notebook->current].widget);
-	}
-}
-
-rtgui_widget_t* rtgui_notebook_get_index(rtgui_notebook_t* notebook, rt_uint16_t index)
-{
-	RT_ASSERT(notebook != RT_NULL);
-	if (index < notebook->count)
-		return notebook->childs[index].widget;
-
-	return RT_NULL;
-}
-
-rt_bool_t rtgui_notebook_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_notebook* notebook;
-
-	notebook = RTGUI_NOTEBOOK(widget);
-	if (event->type == RTGUI_EVENT_PAINT)
-	{
-		_rtgui_notebook_ondraw(notebook);
-	}
-	else if (event->type == RTGUI_EVENT_MOUSE_BUTTON)
-	{
-		_rtgui_notebook_onmouse(notebook, (struct rtgui_event_mouse*)event);
-	}
-	else if (event->type == RTGUI_EVENT_KBD)
-	{
-		if (notebook->current != RTGUI_NOT_FOUND)
-		{
-			if (notebook->childs[notebook->current].widget->event_handler != RT_NULL)
-				return notebook->childs[notebook->current].widget->event_handler(notebook->childs[notebook->current].widget,
-					event);
-		}
-	}
-	else
-	{
-		/* use parent event handler */
-		return rtgui_widget_event_handler(widget, event);
-	}
-
-	return RT_FALSE;
-}
+#include <rtgui/dc.h>
+#include <rtgui/rtgui.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/notebook.h>
+
+#define RTGUI_NOTEBOOK_TAB_WIDTH     80
+
+struct rtgui_notebook_tab
+{
+	struct rtgui_widget *widget;
+	char *title;
+};
+
+static void _rtgui_notebook_get_bar_rect(struct rtgui_notebook *notebook, struct rtgui_rect* rect);
+static void _rtgui_notebook_get_page_rect(struct rtgui_notebook *notebook, struct rtgui_rect* rect);
+
+static void _rtgui_notebook_constructor(struct rtgui_notebook *notebook)
+{
+	notebook->flag    = 0;
+	notebook->childs  = RT_NULL;
+	notebook->count   = 0;
+	notebook->current = 0;
+
+	RTGUI_WIDGET(notebook)->gc.textalign = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
+	rtgui_object_set_event_handler(RTGUI_OBJECT(notebook), rtgui_notebook_event_handler);
+}
+
+static void _rtgui_notebook_destructor(struct rtgui_notebook *notebook)
+{
+	int index;
+
+	if (notebook->childs != RT_NULL)
+	{
+		for (index = 0; index < notebook->count; index ++)
+		{
+			rtgui_widget_destroy(notebook->childs[index].widget);
+			rt_free(notebook->childs[index].title);
+		}
+
+		rtgui_free(notebook->childs);
+	}
+}
+
+DEFINE_CLASS_TYPE(notebook, "notebook",
+	RTGUI_WIDGET_TYPE,
+	_rtgui_notebook_constructor,
+	_rtgui_notebook_destructor,
+	sizeof(struct rtgui_notebook));
+
+/* Draw tab bars of @param notebook. @param dc should be initialized and
+ * finished outside this function. Don't pass @param notebook or @param dc as
+ * RT_NULL, it should be checked outside.
+ */
+static void _rtgui_notebook_draw_bar(struct rtgui_notebook *notebook,
+		struct rtgui_dc *dc)
+{
+	struct rtgui_rect rect;
+	int index;
+
+	RT_ASSERT((notebook != RT_NULL) && (dc != RT_NULL));
+
+	if (notebook->flag & RTGUI_NOTEBOOK_NOTAB)
+		return;
+
+	_rtgui_notebook_get_bar_rect(notebook, &rect);
+	rtgui_dc_fill_rect(dc, &rect);
+
+	rect.x2 = rect.x1 + RTGUI_NOTEBOOK_TAB_WIDTH;
+	/* draw tab bar */
+	for (index = 0; index < notebook->count; index++)
+	{
+		if (notebook->current == index)
+			rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN);
+		else
+			rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_BOX);
+
+		rtgui_dc_draw_text(dc, notebook->childs[index].title, &rect);
+		rect.x1 += RTGUI_NOTEBOOK_TAB_WIDTH;
+		rect.x2 += RTGUI_NOTEBOOK_TAB_WIDTH;
+	}
+
+}
+
+static void _rtgui_notebook_ondraw(struct rtgui_notebook *notebook)
+{
+	struct rtgui_dc* dc;
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook));
+	if (dc == RT_NULL) return;
+
+	if (notebook->count == 0)
+	{
+		rtgui_rect_t rect;
+		rtgui_widget_get_rect(RTGUI_WIDGET(notebook), &rect);
+		rtgui_dc_fill_rect(dc, &rect);
+	}
+	else
+	{
+		if (notebook->current == RTGUI_NOT_FOUND)
+			notebook->current = 0;
+
+		_rtgui_notebook_draw_bar(notebook, dc);
+
+		/* draw current tab */
+		rtgui_widget_update(notebook->childs[notebook->current].widget);
+	}
+	rtgui_dc_end_drawing(dc);
+}
+
+static void _rtgui_notebook_onmouse(struct rtgui_notebook *notebook, struct rtgui_event_mouse* emouse)
+{
+	rtgui_rect_t rect;
+
+	/* handle notebook bar */
+	_rtgui_notebook_get_bar_rect(notebook, &rect);
+	rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect);
+	if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
+	{
+		int index;
+		struct rtgui_dc* dc;
+
+		index = (emouse->x - rect.x1) / RTGUI_NOTEBOOK_TAB_WIDTH;
+		if (index < notebook->count && index != notebook->current)
+		{
+			/* update tab bar */
+			dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook));
+			if (dc == RT_NULL) return;
+
+			rtgui_notebook_set_current_by_index(notebook, index);
+
+			_rtgui_notebook_draw_bar(notebook, dc);
+
+			rtgui_dc_end_drawing(dc);
+		}
+	}
+	else
+	{
+		/* handle on page */
+		if (RTGUI_OBJECT(notebook->childs[notebook->current].widget)->event_handler != RT_NULL)
+			RTGUI_OBJECT(notebook->childs[notebook->current].widget)->event_handler(
+					RTGUI_OBJECT(notebook->childs[notebook->current].widget),
+					&(emouse->parent));
+	}
+}
+
+static void _rtgui_notebook_get_page_rect(struct rtgui_notebook *notebook, struct rtgui_rect* rect)
+{
+	RT_ASSERT(notebook != RT_NULL);
+	RT_ASSERT(rect != RT_NULL);
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect);
+
+	if (notebook->flag == RTGUI_NOTEBOOK_NOTAB)
+		return;
+	else if (notebook->flag == RTGUI_NOTEBOOK_TOP)
+		rect->y1 = rect->y1 + 25;
+	else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM)
+		rect->y2 = rect->y2 - 25;
+}
+
+static void _rtgui_notebook_get_bar_rect(struct rtgui_notebook *notebook, struct rtgui_rect* rect)
+{
+	RT_ASSERT(notebook != RT_NULL);
+	RT_ASSERT(rect != RT_NULL);
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect);
+	if (notebook->flag == RTGUI_NOTEBOOK_NOTAB)
+	{
+		rect->x1 = rect->y1 = rect->x2 = rect->y2 = 0;
+	}
+	else if (notebook->flag == RTGUI_NOTEBOOK_TOP)
+		rect->y2 = rect->y1 + 25;
+	else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM)
+		rect->y1 = rect->y2 - 25;
+}
+
+struct rtgui_notebook* rtgui_notebook_create(const rtgui_rect_t* rect, rt_uint8_t style)
+{
+    struct rtgui_notebook* notebook;
+
+    notebook = (struct rtgui_notebook*) rtgui_widget_create(RTGUI_NOTEBOOK_TYPE);
+    if (notebook != RT_NULL)
+    {
+		notebook->flag = style;
+		rtgui_widget_set_rect(RTGUI_WIDGET(notebook), rect);
+    }
+
+    return notebook;
+}
+
+void rtgui_notebook_destroy(struct rtgui_notebook* notebook)
+{
+	rtgui_widget_destroy(RTGUI_WIDGET(notebook));
+}
+
+void rtgui_notebook_add(struct rtgui_notebook* notebook, const char* label, struct rtgui_widget* child)
+{
+	rtgui_rect_t rect;
+	RT_ASSERT(notebook != RT_NULL);
+
+	notebook->count += 1;
+	notebook->childs = (struct rtgui_notebook_tab*)
+						rtgui_realloc(notebook->childs,
+									  sizeof(struct rtgui_notebook_tab) * notebook->count);
+
+	notebook->childs[notebook->count - 1].title = rt_strdup(label);
+	notebook->childs[notebook->count - 1].widget = child;
+
+	/* set parent */
+	rtgui_widget_set_parent(child, RTGUI_WIDGET(notebook));
+
+	_rtgui_notebook_get_page_rect(notebook, &rect);
+	rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect);
+	rtgui_widget_set_rect(child, &rect);
+
+    if (notebook->count - 1 != notebook->current)
+        rtgui_widget_hide(child);
+}
+
+void rtgui_notebook_remove(struct rtgui_notebook* notebook, rt_uint16_t index)
+{
+	struct rtgui_notebook_tab tab;
+	RT_ASSERT(notebook != RT_NULL);
+
+	if (index < notebook->count)
+	{
+		if (notebook->count == 1)
+		{
+			tab = notebook->childs[0];
+			rtgui_free(notebook->childs);
+			notebook->childs = RT_NULL;
+			notebook->count = 0;
+		}
+		else
+		{
+			tab = notebook->childs[index];
+			for (;index < notebook->count - 1; index ++)
+			{
+				notebook->childs[index] = notebook->childs[index + 1];
+			}
+
+			notebook->count -= 1;
+			notebook->childs = (struct rtgui_notebook_tab*) rtgui_realloc(notebook->childs, 
+				sizeof(struct rtgui_notebook_tab) * notebook->count);
+		}
+
+		// FIXME: do we really want to destroy it?
+		rtgui_widget_destroy(tab.widget);
+		rtgui_free(tab.title);
+
+		if (notebook->current == index)
+		{
+			/* update tab */
+			if (notebook->current > notebook->count - 1)
+				notebook->current = notebook->count - 1;
+			rtgui_widget_update(RTGUI_WIDGET(notebook));
+		}
+	}
+}
+
+int rtgui_notebook_get_count(struct rtgui_notebook* notebook)
+{
+	RT_ASSERT(notebook != RT_NULL);
+	return notebook->count;
+}
+
+struct rtgui_widget* rtgui_notebook_get_current(struct rtgui_notebook* notebook)
+{
+	RT_ASSERT(notebook != RT_NULL);
+	if (notebook->current != RTGUI_NOT_FOUND)
+		return notebook->childs[notebook->current].widget;
+
+	return RT_NULL;
+}
+
+rt_int16_t rtgui_notebook_get_current_index(struct rtgui_notebook* notebook)
+{
+	RT_ASSERT(notebook != RT_NULL);
+	return notebook->current;
+}
+
+void rtgui_notebook_set_current(struct rtgui_notebook* notebook, struct rtgui_widget* widget)
+{
+	rt_int16_t index;
+
+	RT_ASSERT(notebook != RT_NULL);
+
+	for (index = 0; index < notebook->count; index ++)
+	{
+		if (widget == notebook->childs[index].widget)
+		{
+			rtgui_notebook_set_current_by_index(notebook, index);
+			return;
+		}
+	}
+}
+
+void rtgui_notebook_set_current_by_index(struct rtgui_notebook* notebook, rt_uint16_t index)
+{
+	RT_ASSERT(notebook != RT_NULL);
+
+	if ((index < notebook->count) && (notebook->current != index))
+	{
+		if (notebook->current != RTGUI_NOT_FOUND)
+			rtgui_widget_hide(notebook->childs[notebook->current].widget);
+
+		notebook->current = index;
+		rtgui_widget_show(notebook->childs[notebook->current].widget);
+		rtgui_widget_update(notebook->childs[notebook->current].widget);
+	}
+}
+
+struct rtgui_widget* rtgui_notebook_get_widget_at(struct rtgui_notebook* notebook, rt_uint16_t index)
+{
+	RT_ASSERT(notebook != RT_NULL);
+	if (index < notebook->count)
+		return notebook->childs[index].widget;
+
+	return RT_NULL;
+}
+
+rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_notebook* notebook;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	notebook = RTGUI_NOTEBOOK(object);
+
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+		_rtgui_notebook_ondraw(notebook);
+		break;
+	case RTGUI_EVENT_MOUSE_BUTTON:
+		_rtgui_notebook_onmouse(notebook, (struct rtgui_event_mouse*)event);
+		break;
+	case RTGUI_EVENT_KBD:
+		if (notebook->current != RTGUI_NOT_FOUND)
+		{
+			if (RTGUI_OBJECT(notebook->childs[notebook->current].widget
+						)->event_handler != RT_NULL)
+				return RTGUI_OBJECT(notebook->childs[notebook->current].widget
+						)->event_handler(
+							RTGUI_OBJECT(notebook->childs[notebook->current].widget),
+							event);
+		}
+		break;
+	default:
+		/* use parent event handler */
+		return rtgui_widget_event_handler(object, event);
+	}
+
+	return RT_FALSE;
+}

+ 104 - 101
components/rtgui/widgets/progressbar.c

@@ -1,101 +1,104 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/progressbar.h>
-
-#define RTGUI_PROGRESSBAR_DEFAULT_RANGE	100
-
-static void _rtgui_progressbar_constructor(rtgui_progressbar_t *bar)
-{
-	rtgui_rect_t rect = {0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT};
-
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(bar), rtgui_progressbar_event_handler);
-	rtgui_widget_set_rect(RTGUI_WIDGET(bar), &rect);
-
-	bar->orient = RTGUI_HORIZONTAL;
-	bar->range = RTGUI_PROGRESSBAR_DEFAULT_RANGE;
-	bar->position = 0;
-
-	/* set gc */
-	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(bar)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(progressbar, "progressbar", 
-	RTGUI_WIDGET_TYPE,
-	_rtgui_progressbar_constructor,
-	RT_NULL,
-	sizeof(struct rtgui_progressbar));
-
-rt_bool_t rtgui_progressbar_event_handler(struct rtgui_widget* widget,
-                                            struct rtgui_event* event)
-{
-	struct rtgui_progressbar* bar = (struct rtgui_progressbar*)widget;
-
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-		rtgui_theme_draw_progressbar(bar);
-		break;
-	}
-
-	return RT_FALSE;
-}
-
-struct rtgui_progressbar* rtgui_progressbar_create(int orientation, int range,
-	rtgui_rect_t* r)
-{
-    struct rtgui_progressbar* bar;
-
-    bar = (struct rtgui_progressbar*) rtgui_widget_create (RTGUI_PROGRESSBAR_TYPE);
-    if (bar != RT_NULL)
-    {
-		if (r != RT_NULL)
-			rtgui_widget_set_rect(RTGUI_WIDGET(bar), r);
-
-		bar->orient = orientation;
-        bar->range = range;
-    }
-
-    return bar;
-}
-
-void rtgui_progressbar_destroy(struct rtgui_progressbar* bar)
-{
-	rtgui_widget_destroy(RTGUI_WIDGET(bar));
-}
-
-void rtgui_progressbar_set_value(struct rtgui_progressbar *bar, int value)
-{
-    RT_ASSERT(bar != RT_NULL);
-
-	if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar))) return;
-
-    bar->position = value;
-
-    rtgui_theme_draw_progressbar(bar);
-    return;
-}
-
-int rtgui_progressbar_get_value(struct rtgui_progressbar *bar)
-{
-    RT_ASSERT(bar != RT_NULL);
-
-    return bar->position;
-}
-
-void rtgui_progressbar_set_range(struct rtgui_progressbar *bar, int range)
-{
-    RT_ASSERT(bar != RT_NULL);
-
-    bar->range = range;
-
-    rtgui_theme_draw_progressbar(bar);
-    return;
-}
-
-int rtgui_progressbar_get_range(struct rtgui_progressbar *bar)
-{
-    RT_ASSERT(bar != RT_NULL);
-
-    return bar->range;
-}
-
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/progressbar.h>
+
+#define RTGUI_PROGRESSBAR_DEFAULT_RANGE	100
+
+static void _rtgui_progressbar_constructor(rtgui_progressbar_t *bar)
+{
+	rtgui_rect_t rect = {0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT};
+
+	rtgui_object_set_event_handler(RTGUI_OBJECT(bar), rtgui_progressbar_event_handler);
+	rtgui_widget_set_rect(RTGUI_WIDGET(bar), &rect);
+
+	bar->orient = RTGUI_HORIZONTAL;
+	bar->range = RTGUI_PROGRESSBAR_DEFAULT_RANGE;
+	bar->position = 0;
+
+	/* set gc */
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(bar)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(progressbar, "progressbar", 
+	RTGUI_WIDGET_TYPE,
+	_rtgui_progressbar_constructor,
+	RT_NULL,
+	sizeof(struct rtgui_progressbar));
+
+rt_bool_t rtgui_progressbar_event_handler(struct rtgui_object* object,
+                                            struct rtgui_event* event)
+{
+	struct rtgui_progressbar* bar;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+	bar = RTGUI_PROGRESSBAR(object);
+
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+		rtgui_theme_draw_progressbar(bar);
+		break;
+	}
+
+	return RT_FALSE;
+}
+
+struct rtgui_progressbar* rtgui_progressbar_create(int orientation, int range,
+	rtgui_rect_t* r)
+{
+    struct rtgui_progressbar* bar;
+
+    bar = (struct rtgui_progressbar*) rtgui_widget_create (RTGUI_PROGRESSBAR_TYPE);
+    if (bar != RT_NULL)
+    {
+		if (r != RT_NULL)
+			rtgui_widget_set_rect(RTGUI_WIDGET(bar), r);
+
+		bar->orient = orientation;
+        bar->range = range;
+    }
+
+    return bar;
+}
+
+void rtgui_progressbar_destroy(struct rtgui_progressbar* bar)
+{
+	rtgui_widget_destroy(RTGUI_WIDGET(bar));
+}
+
+void rtgui_progressbar_set_value(struct rtgui_progressbar *bar, int value)
+{
+    RT_ASSERT(bar != RT_NULL);
+
+	if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar))) return;
+
+    bar->position = value;
+
+    rtgui_theme_draw_progressbar(bar);
+    return;
+}
+
+int rtgui_progressbar_get_value(struct rtgui_progressbar *bar)
+{
+    RT_ASSERT(bar != RT_NULL);
+
+    return bar->position;
+}
+
+void rtgui_progressbar_set_range(struct rtgui_progressbar *bar, int range)
+{
+    RT_ASSERT(bar != RT_NULL);
+
+    bar->range = range;
+
+    rtgui_theme_draw_progressbar(bar);
+    return;
+}
+
+int rtgui_progressbar_get_range(struct rtgui_progressbar *bar)
+{
+    RT_ASSERT(bar != RT_NULL);
+
+    return bar->range;
+}
+

+ 246 - 244
components/rtgui/widgets/radiobox.c

@@ -1,244 +1,246 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/radiobox.h>
-
-#define RTGUI_RADIOBOX_DEFAULT_WIDTH	100
-#define RTGUI_RADIOBOX_DEFAULT_HEIGHT	20
-
-static void _rtgui_radiobox_constructor(rtgui_radiobox_t *radiobox)
-{
-	rtgui_rect_t rect = {0, 0, RTGUI_RADIOBOX_DEFAULT_WIDTH, RTGUI_RADIOBOX_DEFAULT_HEIGHT};
-
-	/* init widget and set event handler */
-	RTGUI_WIDGET(radiobox)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(radiobox)) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL;
-	rtgui_widget_set_rect(RTGUI_WIDGET(radiobox), &rect);
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(radiobox), rtgui_radiobox_event_handler);
-
-	/* set proper of control */
-	radiobox->items = RT_NULL;
-	radiobox->item_count = 0;
-	radiobox->item_selection = -1;
-	radiobox->orient = RTGUI_HORIZONTAL;
-}
-
-DEFINE_CLASS_TYPE(radiobox, "radiobox", 
-	RTGUI_WIDGET_TYPE,
-	_rtgui_radiobox_constructor,
-	RT_NULL,
-	sizeof(struct rtgui_radiobox));
-
-static void rtgui_radiobox_onmouse(struct rtgui_radiobox* radiobox, struct rtgui_event_mouse* event)
-{
-	RT_ASSERT(radiobox != RT_NULL);
-	RT_ASSERT(event  != RT_NULL);
-
-	/* widget is hide, return */
-	if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(radiobox)) || 
-		!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(radiobox))) return;
-
-	if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
-		event->button & RTGUI_MOUSE_BUTTON_LEFT)
-	{
-		int bord_size;
-		struct rtgui_rect rect;
-
-		/* focus widgets */
-		rtgui_widget_focus(RTGUI_WIDGET(radiobox));
-
-		/* get widget physical rect */
-		rtgui_widget_get_rect(RTGUI_WIDGET(radiobox), &rect);
-		rtgui_widget_rect_to_device(RTGUI_WIDGET(radiobox), &rect);
-
-		/* get board size */
-		if (radiobox->orient == RTGUI_VERTICAL)
-			bord_size = radiobox->item_size;
-		else
-		{
-			struct rtgui_rect bord_rect;
-			
-			rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &bord_rect);
-			bord_size = rtgui_rect_height(bord_rect);
-		}
-		rtgui_rect_inflate(&rect, - bord_size);
-		if (rtgui_rect_contains_point(&rect, event->x, event->y) != RT_EOK) return;
-
-		if (radiobox->orient == RTGUI_VERTICAL)
-		{
-			int delta_y = event->y - rect.y1;
-			rtgui_radiobox_set_selection(radiobox, delta_y / radiobox->item_size);
-		}
-		else
-		{
-			int delta_x = event->x - rect.x1;
-			rtgui_radiobox_set_selection(radiobox, delta_x / radiobox->item_size);
-		}
-	}
-}
-
-rt_bool_t rtgui_radiobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_radiobox* radiobox = (struct rtgui_radiobox*)widget;
-
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-#ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
-		else
-#endif
-		{
-			rtgui_theme_draw_radiobox(radiobox);
-		}
-
-		break;
-
-	case RTGUI_EVENT_KBD:
-		if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(radiobox))) return RT_FALSE;
-
-#ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_key != RT_NULL) widget->on_key(widget, event);
-		else
-#endif
-		{
-            struct rtgui_event_kbd *e = (struct rtgui_event_kbd*)event;
-
-            /* set focused */
-            rtgui_widget_focus(RTGUI_WIDGET(radiobox));
-            if (!(RTGUI_KBD_IS_UP(e))) return RT_FALSE;
-
-			if (radiobox->orient == RTGUI_VERTICAL)
-			{
-	            if (e->key == RTGUIK_UP)
-	            {
-	                if (radiobox->item_selection > 0)
-	                    rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
-	            }
-	            else if (e->key == RTGUIK_DOWN)
-	            {
-	                if (radiobox->item_selection < radiobox->item_count - 1)
-	                    rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
-	            }
-			}
-			else
-			{
-	            if (e->key == RTGUIK_LEFT)
-	            {
-	                if (radiobox->item_selection > 0)
-	                    rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
-	            }
-	            else if (e->key == RTGUIK_RIGHT)
-	            {
-	                if (radiobox->item_selection < radiobox->item_count - 1)
-	                    rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
-	            }
-			}
-        }
-		break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-#ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
-		else
-#endif
-		{
-			rtgui_radiobox_onmouse(radiobox, (struct rtgui_event_mouse*)event);
-		}
-		break;
-	}
-
-	return RT_FALSE;
-}
-
-struct rtgui_radiobox* rtgui_radiobox_create(const char* label, int orient, char** radio_items, int number)
-{
-    struct rtgui_radiobox* radiobox;
-
-    radiobox = (struct rtgui_radiobox*) rtgui_widget_create (RTGUI_RADIOBOX_TYPE);
-    if (radiobox != RT_NULL)
-    {
-    	rt_uint8_t board_size;
-		struct rtgui_rect rect;
-		
-        radiobox->items = radio_items;
-        radiobox->item_count = number;
-        radiobox->item_selection = -1;
-		radiobox->text = rt_strdup(label);
-
-		/* set proper of control */
-		rtgui_radiobox_set_orientation(radiobox, orient);
-		rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &rect);
-		board_size = rtgui_rect_height(rect);
-
-		if (orient == RTGUI_VERTICAL)
-		{
-			radiobox->item_size = board_size;
-		}
-		else
-		{
-			int index;
-			struct rtgui_font* font;
-			struct rtgui_rect rect;
-
-			/* set init item size */
-			radiobox->item_size = 0;
-			
-			font = RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox));
-			for (index = 0; index < number; index ++)
-			{
-				rtgui_font_get_metrics(font, radio_items[index], &rect);
-				if ( (board_size + 3 + rtgui_rect_width(rect)) > radiobox->item_size)
-					radiobox->item_size = board_size + 3 + rtgui_rect_width(rect);
-			}
-		}
-
-		if (radiobox->item_size < RADIO_BOX_H + 2)
-			radiobox->item_size = RADIO_BOX_H + 2;
-	}
-
-	return radiobox;
-}
-
-void rtgui_radiobox_set_orientation(struct rtgui_radiobox* radiobox, int orientation)
-{
-	RT_ASSERT(radiobox != RT_NULL);
-
-	/* set orientation */
-	radiobox->orient = orientation;
-#ifndef RTGUI_USING_SMALL_SIZE
-	if (radiobox->orient == RTGUI_HORIZONTAL)
-	{
-		/* HORIZONTAL */
-		rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT);
-		rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH);
-	}
-	else
-	{
-		/* VERTICAL */
-		rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT);
-		rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH);
-	}
-#endif
-}
-
-void rtgui_radiobox_set_selection(struct rtgui_radiobox* radiobox, int selection)
-{
-	rt_uint16_t old_item;
-
-	if (selection == radiobox->item_selection) return;
-
-	old_item = radiobox->item_selection;
-    if (selection >= 0 && selection < radiobox->item_count)
-    {
-    	radiobox->item_selection = selection;
-    }
-
-    /* update radiobox widget */
-	rtgui_theme_draw_radiobutton(radiobox, old_item);
-	rtgui_theme_draw_radiobutton(radiobox, radiobox->item_selection);
-}
-
-int rtgui_radiobox_get_selection(struct rtgui_radiobox* radiobox)
-{
-    return radiobox->item_selection;
-}
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/radiobox.h>
+
+#define RTGUI_RADIOBOX_DEFAULT_WIDTH	100
+#define RTGUI_RADIOBOX_DEFAULT_HEIGHT	20
+
+static void _rtgui_radiobox_constructor(rtgui_radiobox_t *radiobox)
+{
+	rtgui_rect_t rect = {0, 0, RTGUI_RADIOBOX_DEFAULT_WIDTH, RTGUI_RADIOBOX_DEFAULT_HEIGHT};
+
+	/* init widget and set event handler */
+	RTGUI_WIDGET(radiobox)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(radiobox)) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL;
+	rtgui_widget_set_rect(RTGUI_WIDGET(radiobox), &rect);
+	rtgui_object_set_event_handler(RTGUI_OBJECT(radiobox), rtgui_radiobox_event_handler);
+
+	/* set proper of control */
+	radiobox->items = RT_NULL;
+	radiobox->item_count = 0;
+	radiobox->item_selection = -1;
+	radiobox->orient = RTGUI_HORIZONTAL;
+}
+
+DEFINE_CLASS_TYPE(radiobox, "radiobox", 
+	RTGUI_WIDGET_TYPE,
+	_rtgui_radiobox_constructor,
+	RT_NULL,
+	sizeof(struct rtgui_radiobox));
+
+static void rtgui_radiobox_onmouse(struct rtgui_radiobox* radiobox, struct rtgui_event_mouse* event)
+{
+	RT_ASSERT(radiobox != RT_NULL);
+	RT_ASSERT(event  != RT_NULL);
+
+	/* widget is hide, return */
+	if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(radiobox)) || 
+		!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(radiobox))) return;
+
+	if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
+		event->button & RTGUI_MOUSE_BUTTON_LEFT)
+	{
+		int bord_size;
+		struct rtgui_rect rect;
+
+		/* focus widgets */
+		rtgui_widget_focus(RTGUI_WIDGET(radiobox));
+
+		/* get widget physical rect */
+		rtgui_widget_get_rect(RTGUI_WIDGET(radiobox), &rect);
+		rtgui_widget_rect_to_device(RTGUI_WIDGET(radiobox), &rect);
+
+		/* get board size */
+		if (radiobox->orient == RTGUI_VERTICAL)
+			bord_size = radiobox->item_size;
+		else
+		{
+			struct rtgui_rect bord_rect;
+			
+			rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &bord_rect);
+			bord_size = rtgui_rect_height(bord_rect);
+		}
+		rtgui_rect_inflate(&rect, - bord_size);
+		if (rtgui_rect_contains_point(&rect, event->x, event->y) != RT_EOK) return;
+
+		if (radiobox->orient == RTGUI_VERTICAL)
+		{
+			int delta_y = event->y - rect.y1;
+			rtgui_radiobox_set_selection(radiobox, delta_y / radiobox->item_size);
+		}
+		else
+		{
+			int delta_x = event->x - rect.x1;
+			rtgui_radiobox_set_selection(radiobox, delta_x / radiobox->item_size);
+		}
+	}
+}
+
+rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_radiobox* radiobox;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+	radiobox = RTGUI_RADIOBOX(object);
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+#ifndef RTGUI_USING_SMALL_SIZE
+		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+		else
+#endif
+		{
+			rtgui_theme_draw_radiobox(radiobox);
+		}
+
+		break;
+
+	case RTGUI_EVENT_KBD:
+		if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(radiobox))) return RT_FALSE;
+
+#ifndef RTGUI_USING_SMALL_SIZE
+		if (widget->on_key != RT_NULL) widget->on_key(widget, event);
+		else
+#endif
+		{
+            struct rtgui_event_kbd *e = (struct rtgui_event_kbd*)event;
+
+            /* set focused */
+            rtgui_widget_focus(RTGUI_WIDGET(radiobox));
+            if (!(RTGUI_KBD_IS_UP(e))) return RT_FALSE;
+
+			if (radiobox->orient == RTGUI_VERTICAL)
+			{
+	            if (e->key == RTGUIK_UP)
+	            {
+	                if (radiobox->item_selection > 0)
+	                    rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
+	            }
+	            else if (e->key == RTGUIK_DOWN)
+	            {
+	                if (radiobox->item_selection < radiobox->item_count - 1)
+	                    rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
+	            }
+			}
+			else
+			{
+	            if (e->key == RTGUIK_LEFT)
+	            {
+	                if (radiobox->item_selection > 0)
+	                    rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
+	            }
+	            else if (e->key == RTGUIK_RIGHT)
+	            {
+	                if (radiobox->item_selection < radiobox->item_count - 1)
+	                    rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
+	            }
+			}
+        }
+		break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+#ifndef RTGUI_USING_SMALL_SIZE
+		if (widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
+		else
+#endif
+		{
+			rtgui_radiobox_onmouse(radiobox, (struct rtgui_event_mouse*)event);
+		}
+		break;
+	}
+
+	return RT_FALSE;
+}
+
+struct rtgui_radiobox* rtgui_radiobox_create(const char* label, int orient, char** radio_items, int number)
+{
+    struct rtgui_radiobox* radiobox;
+
+    radiobox = (struct rtgui_radiobox*) rtgui_widget_create (RTGUI_RADIOBOX_TYPE);
+    if (radiobox != RT_NULL)
+    {
+    	rt_uint8_t board_size;
+		struct rtgui_rect rect;
+		
+        radiobox->items = radio_items;
+        radiobox->item_count = number;
+        radiobox->item_selection = -1;
+		radiobox->text = rt_strdup(label);
+
+		/* set proper of control */
+		rtgui_radiobox_set_orientation(radiobox, orient);
+		rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &rect);
+		board_size = rtgui_rect_height(rect);
+
+		if (orient == RTGUI_VERTICAL)
+		{
+			radiobox->item_size = board_size;
+		}
+		else
+		{
+			int index;
+			struct rtgui_font* font;
+			struct rtgui_rect rect;
+
+			/* set init item size */
+			radiobox->item_size = 0;
+			
+			font = RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox));
+			for (index = 0; index < number; index ++)
+			{
+				rtgui_font_get_metrics(font, radio_items[index], &rect);
+				if ( (board_size + 3 + rtgui_rect_width(rect)) > radiobox->item_size)
+					radiobox->item_size = board_size + 3 + rtgui_rect_width(rect);
+			}
+		}
+
+		if (radiobox->item_size < RADIO_BOX_H + 2)
+			radiobox->item_size = RADIO_BOX_H + 2;
+	}
+
+	return radiobox;
+}
+
+void rtgui_radiobox_set_orientation(struct rtgui_radiobox* radiobox, int orientation)
+{
+	RT_ASSERT(radiobox != RT_NULL);
+
+	/* set orientation */
+	radiobox->orient = orientation;
+#ifndef RTGUI_USING_SMALL_SIZE
+	if (radiobox->orient == RTGUI_HORIZONTAL)
+	{
+		/* HORIZONTAL */
+		rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT);
+		rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH);
+	}
+	else
+	{
+		/* VERTICAL */
+		rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT);
+		rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH);
+	}
+#endif
+}
+
+void rtgui_radiobox_set_selection(struct rtgui_radiobox* radiobox, int selection)
+{
+	rt_uint16_t old_item;
+
+	if (selection == radiobox->item_selection) return;
+
+	old_item = radiobox->item_selection;
+    if (selection >= 0 && selection < radiobox->item_count)
+    {
+    	radiobox->item_selection = selection;
+    }
+
+    /* update radiobox widget */
+	rtgui_theme_draw_radiobutton(radiobox, old_item);
+	rtgui_theme_draw_radiobutton(radiobox, radiobox->item_selection);
+}
+
+int rtgui_radiobox_get_selection(struct rtgui_radiobox* radiobox)
+{
+    return radiobox->item_selection;
+}

+ 419 - 415
components/rtgui/widgets/scrollbar.c

@@ -1,415 +1,419 @@
-/*
- * File      : scrollbar.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2010-08-09     Bernard      first version
- */
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/scrollbar.h>
-
-static void _rtgui_scrollbar_constructor(rtgui_scrollbar_t *bar)
-{
-	struct rtgui_rect rect = {0, 0, RTGUI_DEFAULT_SB_WIDTH, RTGUI_DEFAULT_SB_HEIGHT};
-
-	/* set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(bar), rtgui_scrollbar_event_handler);
-
-	rtgui_scrollbar_set_range(bar, 0, 100);
-	rtgui_scrollbar_set_page_step(bar, 20);
-	rtgui_scrollbar_set_line_step(bar, 10);
-
-	bar->status = 0;
-	bar->thumb_position = 0;
-	bar->thumb_size = 16;
-	bar->on_scroll = RT_NULL;
-
-	bar->orient = RTGUI_HORIZONTAL;
-	rtgui_widget_set_rect(RTGUI_WIDGET(bar), &rect);
-
-	/* set gc */
-	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(bar)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-rt_inline rt_uint32_t _rtgui_scrollbar_get_length(rtgui_scrollbar_t *bar)
-{
-	struct rtgui_rect rect;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
-
-	if (bar->orient & RTGUI_VERTICAL)
-		return rect.y2 - 2 * (rect.x2 - rect.x1);
-
-	return rect.x2 - 2 * (rect.y2 - rect.y1);
-}
-
-rt_inline rt_uint32_t _rtgui_scrollbar_get_thumb_position(rtgui_scrollbar_t* bar)
-{
-	rt_uint32_t thumb_position;
-
-	/* calculate thumb position */
-	thumb_position = (rtgui_scrollbar_get_value(bar) - bar->min_position) * _rtgui_scrollbar_get_length(bar) / 
-		(bar->max_position - bar->min_position);
-
-	return thumb_position;
-}
-
-void rtgui_scrollbar_get_thumb_rect(rtgui_scrollbar_t *bar, rtgui_rect_t *rect)
-{
-	struct rtgui_rect scrollbar_rect;
-
-	rtgui_widget_get_rect(RTGUI_WIDGET(bar), &scrollbar_rect);
-	if (bar->orient & RTGUI_VERTICAL)
-	{
-		rt_uint32_t btn_width = scrollbar_rect.x2 - scrollbar_rect.x1;
-
-		/* vertical scroll bar */
-		rect->x1 = scrollbar_rect.x1;
-		rect->x2 = scrollbar_rect.x2;
-		rect->y1 = scrollbar_rect.y1 + btn_width + _rtgui_scrollbar_get_thumb_position(bar);
-		rect->y2 = rect->y1 + btn_width;
-	}
-	else
-	{
-		rt_uint32_t btn_height = scrollbar_rect.y2 - scrollbar_rect.y1;
-
-		/* horizontal scroll bar */
-		rect->x1 = scrollbar_rect.x1 + btn_height + _rtgui_scrollbar_get_thumb_position(bar);
-		rect->x2 = rect->x1 + btn_height;
-
-		rect->y1 = scrollbar_rect.y1;
-		rect->y2 = scrollbar_rect.y2;
-	}
-}
-
-DEFINE_CLASS_TYPE(scrollbar, "scrollbar", 
-	RTGUI_WIDGET_TYPE,
-	_rtgui_scrollbar_constructor,
-	RT_NULL,
-	sizeof(struct rtgui_scrollbar));
-
-static void _rtgui_scrollbar_on_mouseclick(struct rtgui_widget * widget, struct rtgui_event * event)
-{
-	rtgui_rect_t btn_rect, bar_rect;
-	rt_uint32_t thumb_size, thumb_position;
-    struct rtgui_scrollbar* bar = (struct rtgui_scrollbar*)widget;
-    struct rtgui_event_mouse* mouse = (struct rtgui_event_mouse*)event;
-
-	/* get the thumb size and position */
-	thumb_size = bar->thumb_size * (bar->max_position - bar->min_position) / _rtgui_scrollbar_get_length(bar);
-	thumb_position = _rtgui_scrollbar_get_thumb_position(bar);
-
-    if (bar->orient == RTGUI_VERTICAL)
-    {
-		/* get up arrow button rect */
-		btn_rect.x1 = widget->extent.x1;
-		btn_rect.x2 = widget->extent.x2;
-		btn_rect.y1 = widget->extent.y1;
-		btn_rect.y2 = widget->extent.y1 + (widget->extent.x2 - widget->extent.x1);
-        if (rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
-        {
-            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
-				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
-            {
-                bar->status |= SBS_UPARROW;
-
-				/* line step */
-				bar->thumb_position -= bar->line_step;
-				if (bar->thumb_position < bar->min_position) bar->thumb_position = bar->min_position;
-            }
-            else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
-			{
-                bar->status = 0;
-			}
-			goto __exit;
-        }
-
-		/* get bar rect */
-		bar_rect.x1 = widget->extent.x1;
-		bar_rect.x2 = widget->extent.x2;
-		bar_rect.y1 = widget->extent.y1 + (widget->extent.x2 - widget->extent.x1);
-		bar_rect.y2 = widget->extent.y2 - (widget->extent.x2 - widget->extent.x1);
-        if (rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
-        {
-			if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
-				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
-            {
-				/* page step */
-				if (mouse->y < bar_rect.y1 + thumb_position)
-				{
-					bar->thumb_position -= bar->page_step;
-					if (bar->thumb_position < bar->min_position)					
-						bar->thumb_position = bar->min_position;
-				}
-				else if (mouse->y > thumb_position + bar->thumb_size)
-				{
-					bar->thumb_position += bar->page_step;
-					if (bar->thumb_position > bar->max_position - thumb_size)
-						bar->thumb_position = bar->max_position - thumb_size;
-				}
-            }
-			goto __exit;
-        }
-
-		/* get down arrow button rect */
-        btn_rect.y1 = widget->extent.y2 - (widget->extent.x2 - widget->extent.x1);
-        btn_rect.y2 = widget->extent.y2;
-        bar_rect.y1 = widget->extent.y1 + ((widget->extent.y2 - widget->extent.y1)/2);
-        bar_rect.y2 = widget->extent.y2 - (widget->extent.x2 - widget->extent.x1);
-        if (rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
-        {
-            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
-				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
-            {
-                bar->status |= SBS_DOWNARROW;
-
-				/* line step */
-				bar->thumb_position += bar->line_step;
-				if (bar->thumb_position > bar->max_position - thumb_size)
-					bar->thumb_position = bar->max_position - thumb_size;
-            }
-            else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
-                bar->status = 0;
-        }
-    }
-    else
-    {
-		/* get left arrow button rect */
-		btn_rect.x1 = widget->extent.x1;
-		btn_rect.x2 = widget->extent.x1 + (widget->extent.y2 - widget->extent.y1);
-		btn_rect.y1 = widget->extent.y1;
-		btn_rect.y2 = widget->extent.y2;
-        if (rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
-        {
-            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
-				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
-            {
-                bar->status |= SBS_LEFTARROW;
-
-				/* line step */
-				bar->thumb_position -= bar->line_step;
-				if (bar->thumb_position < bar->min_position) bar->thumb_position = bar->min_position;
-            }
-             else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
-                bar->status = 0;
-			goto __exit;
-       }
-
-		/* get bar rect */
-		bar_rect.x1 = widget->extent.x1 + (widget->extent.y2 - widget->extent.y1);
-		bar_rect.x2 = widget->extent.x2 - (widget->extent.y2 - widget->extent.y1);
-		bar_rect.y1 = widget->extent.y1;
-		bar_rect.y2 = widget->extent.y2;
-        if (rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
-        {
-            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
-				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
-            {
-				/* page step */
-				if (mouse->x <  bar_rect.x1 + thumb_position)
-				{
-					bar->thumb_position -= bar->page_step;
-					if (bar->thumb_position < bar->min_position)					
-						bar->thumb_position = bar->min_position;
-				}
-				else if (mouse->x > thumb_position + bar->thumb_size)
-				{
-					bar->thumb_position += bar->page_step;
-					if (bar->thumb_position > bar->max_position - thumb_size)
-						bar->thumb_position = bar->max_position - thumb_size;
-				}
-            }
-			goto __exit;
-        }
-
-		/* get right arrow button rect */
-        btn_rect.x1 = widget->extent.x2 - (widget->extent.y2 - widget->extent.y1);
-        btn_rect.x2 = widget->extent.x2;
-        bar_rect.x1 = widget->extent.x1 + ((widget->extent.x2 - widget->extent.x1)/2);
-        bar_rect.x2 = widget->extent.x2 - (widget->extent.y2 - widget->extent.y1);
-        if (rtgui_rect_contains_point(&btn_rect,
-                            mouse->x, mouse->y) == RT_EOK)
-        {
-            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
-				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
-            {
-                bar->status |= SBS_RIGHTARROW;
-
-				/* line step */
-				bar->thumb_position += bar->line_step;
-				if (bar->thumb_position > bar->max_position - bar->line_step)
-					bar->thumb_position = bar->max_position - bar->line_step;
-            }
-             else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
-                bar->status = 0;
-        }
-    }
-
-__exit:
-    rtgui_theme_draw_scrollbar(bar);
-	if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
-		(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
-	{
-		if (bar->on_scroll != RT_NULL) bar->on_scroll(widget, RT_NULL);
-	}
-}
-
-rt_bool_t rtgui_scrollbar_event_handler(struct rtgui_widget * widget,
-	struct rtgui_event * event)
-{
-	struct rtgui_scrollbar* bar = (struct rtgui_scrollbar*)widget;
-
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-#ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
-		else
-#endif
-		{
-			rtgui_theme_draw_scrollbar(bar);
-		}
-
-		break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-		if (RTGUI_WIDGET_IS_ENABLE(widget) && !RTGUI_WIDGET_IS_HIDE(widget))
-		{
-#ifndef RTGUI_USING_SMALL_SIZE
-			if (widget->on_mouseclick != RT_NULL)
-			{
-				widget->on_mouseclick(widget, event);
-			}
-			else
-#endif
-			{
-				_rtgui_scrollbar_on_mouseclick(widget, event);
-			}
-		}
-
-		break;
-
-	default:
-		break;
-	}
-
-	return RT_FALSE;
-}
-
-struct rtgui_scrollbar* rtgui_scrollbar_create(int orient, rtgui_rect_t* r)
-{
-    struct rtgui_scrollbar* bar;
-
-    bar = (struct rtgui_scrollbar*) rtgui_widget_create (RTGUI_SCROLLBAR_TYPE);
-    if (bar != RT_NULL)
-    {
-		if (r != RT_NULL)
-		{
-			rtgui_widget_set_rect(RTGUI_WIDGET(bar), r);
-			if (orient == RTGUI_VERTICAL)
-				bar->thumb_size = (r->x2 - r->x1);
-			else
-				bar->thumb_size = (r->y2 - r->y1);
-		}
-
-		bar->orient = orient;
-    }
-
-    return bar;
-}
-
-void rtgui_scrollbar_destroy(struct rtgui_scrollbar* bar)
-{
-	rtgui_widget_destroy(RTGUI_WIDGET(bar));
-}
-
-void rtgui_scrollbar_set_orientation(rtgui_scrollbar_t* bar, int orientation)
-{
-	RT_ASSERT(bar != RT_NULL);
-
-	bar->orient = orientation;
-#ifndef RTGUI_USING_SMALL_SIZE
-	if (bar->orient == RTGUI_HORIZONTAL)
-	{
-		/* horizontal */
-		rtgui_widget_set_miniwidth(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_WIDTH);
-		rtgui_widget_set_miniheight(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_HEIGHT);
-	}
-	else 
-	{
-		/* vertical */
-		rtgui_widget_set_miniwidth(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_HEIGHT);
-		rtgui_widget_set_miniheight(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_WIDTH);
-	}
-#endif
-}
-
-void rtgui_scrollbar_set_range(struct rtgui_scrollbar* bar, int min, int max)
-{
-	RT_ASSERT(bar != RT_NULL);
-
-	if (min >= max )
-	{
-		RTGUI_WIDGET_DISABLE(RTGUI_WIDGET(bar));
-		return;
-	}
-
-	bar->min_position = (rt_int16_t)min;
-	bar->max_position = (rt_int16_t)max;
-}
-
-void rtgui_scrollbar_set_page_step(struct rtgui_scrollbar* bar, int step)
-{
-	RT_ASSERT(bar != RT_NULL);
-
-	bar->page_step = step;
-		
-	/* disable or enable scrollbar */
-	if (bar->page_step > (bar->max_position - bar->min_position))
-	{
-		/* disable bar */
-		RTGUI_WIDGET_DISABLE(RTGUI_WIDGET(bar));
-	}
-	else
-	{
-		/* enable bar */
-		RTGUI_WIDGET_ENABLE(RTGUI_WIDGET(bar));
-	}
-}
-
-void rtgui_scrollbar_set_line_step(struct rtgui_scrollbar* bar, int step)
-{
-	RT_ASSERT(bar != RT_NULL);
-
-	bar->line_step = step;
-}
-
-rt_int16_t rtgui_scrollbar_get_value(struct rtgui_scrollbar* bar)
-{
-	RT_ASSERT(bar != RT_NULL);
-
-	return bar->thumb_position;
-}
-
-void rtgui_scrollbar_set_value(struct rtgui_scrollbar* bar, rt_int16_t position)
-{
-	RT_ASSERT(bar != RT_NULL);
-
-	bar->thumb_position = position;
-	rtgui_widget_update(RTGUI_WIDGET(bar));
-}
-
-void rtgui_scrollbar_set_onscroll(struct rtgui_scrollbar* bar,
-								  rtgui_event_handler_ptr handler)
-{
-	if (bar == RT_NULL || handler == RT_NULL) return;
-
-	bar->on_scroll = handler;
-}
+/*
+ * File      : scrollbar.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2010-08-09     Bernard      first version
+ */
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/scrollbar.h>
+
+static void _rtgui_scrollbar_constructor(rtgui_scrollbar_t *bar)
+{
+	struct rtgui_rect rect = {0, 0, RTGUI_DEFAULT_SB_WIDTH, RTGUI_DEFAULT_SB_HEIGHT};
+
+	/* set event handler */
+	rtgui_object_set_event_handler(RTGUI_OBJECT(bar), rtgui_scrollbar_event_handler);
+
+	rtgui_scrollbar_set_range(bar, 0, 100);
+	rtgui_scrollbar_set_page_step(bar, 20);
+	rtgui_scrollbar_set_line_step(bar, 10);
+
+	bar->status = 0;
+	bar->thumb_position = 0;
+	bar->thumb_size = 16;
+	bar->on_scroll = RT_NULL;
+
+	bar->orient = RTGUI_HORIZONTAL;
+	rtgui_widget_set_rect(RTGUI_WIDGET(bar), &rect);
+
+	/* set gc */
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(bar)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+rt_inline rt_uint32_t _rtgui_scrollbar_get_length(rtgui_scrollbar_t *bar)
+{
+	struct rtgui_rect rect;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
+
+	if (bar->orient & RTGUI_VERTICAL)
+		return rect.y2 - 2 * (rect.x2 - rect.x1);
+
+	return rect.x2 - 2 * (rect.y2 - rect.y1);
+}
+
+rt_inline rt_uint32_t _rtgui_scrollbar_get_thumb_position(rtgui_scrollbar_t* bar)
+{
+	rt_uint32_t thumb_position;
+
+	/* calculate thumb position */
+	thumb_position = (rtgui_scrollbar_get_value(bar) - bar->min_position) * _rtgui_scrollbar_get_length(bar) / 
+		(bar->max_position - bar->min_position);
+
+	return thumb_position;
+}
+
+void rtgui_scrollbar_get_thumb_rect(rtgui_scrollbar_t *bar, rtgui_rect_t *rect)
+{
+	struct rtgui_rect scrollbar_rect;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(bar), &scrollbar_rect);
+	if (bar->orient & RTGUI_VERTICAL)
+	{
+		rt_uint32_t btn_width = scrollbar_rect.x2 - scrollbar_rect.x1;
+
+		/* vertical scroll bar */
+		rect->x1 = scrollbar_rect.x1;
+		rect->x2 = scrollbar_rect.x2;
+		rect->y1 = scrollbar_rect.y1 + btn_width + _rtgui_scrollbar_get_thumb_position(bar);
+		rect->y2 = rect->y1 + btn_width;
+	}
+	else
+	{
+		rt_uint32_t btn_height = scrollbar_rect.y2 - scrollbar_rect.y1;
+
+		/* horizontal scroll bar */
+		rect->x1 = scrollbar_rect.x1 + btn_height + _rtgui_scrollbar_get_thumb_position(bar);
+		rect->x2 = rect->x1 + btn_height;
+
+		rect->y1 = scrollbar_rect.y1;
+		rect->y2 = scrollbar_rect.y2;
+	}
+}
+
+DEFINE_CLASS_TYPE(scrollbar, "scrollbar", 
+	RTGUI_WIDGET_TYPE,
+	_rtgui_scrollbar_constructor,
+	RT_NULL,
+	sizeof(struct rtgui_scrollbar));
+
+static void _rtgui_scrollbar_on_mouseclick(struct rtgui_widget * widget, struct rtgui_event * event)
+{
+	rtgui_rect_t btn_rect, bar_rect;
+	rt_uint32_t thumb_size, thumb_position;
+    struct rtgui_scrollbar* bar = (struct rtgui_scrollbar*)widget;
+    struct rtgui_event_mouse* mouse = (struct rtgui_event_mouse*)event;
+
+	/* get the thumb size and position */
+	thumb_size = bar->thumb_size * (bar->max_position - bar->min_position) / _rtgui_scrollbar_get_length(bar);
+	thumb_position = _rtgui_scrollbar_get_thumb_position(bar);
+
+    if (bar->orient == RTGUI_VERTICAL)
+    {
+		/* get up arrow button rect */
+		btn_rect.x1 = widget->extent.x1;
+		btn_rect.x2 = widget->extent.x2;
+		btn_rect.y1 = widget->extent.y1;
+		btn_rect.y2 = widget->extent.y1 + (widget->extent.x2 - widget->extent.x1);
+        if (rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
+        {
+            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+                bar->status |= SBS_UPARROW;
+
+				/* line step */
+				bar->thumb_position -= bar->line_step;
+				if (bar->thumb_position < bar->min_position) bar->thumb_position = bar->min_position;
+            }
+            else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
+			{
+                bar->status = 0;
+			}
+			goto __exit;
+        }
+
+		/* get bar rect */
+		bar_rect.x1 = widget->extent.x1;
+		bar_rect.x2 = widget->extent.x2;
+		bar_rect.y1 = widget->extent.y1 + (widget->extent.x2 - widget->extent.x1);
+		bar_rect.y2 = widget->extent.y2 - (widget->extent.x2 - widget->extent.x1);
+        if (rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
+        {
+			if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+				/* page step */
+				if (mouse->y < bar_rect.y1 + thumb_position)
+				{
+					bar->thumb_position -= bar->page_step;
+					if (bar->thumb_position < bar->min_position)
+						bar->thumb_position = bar->min_position;
+				}
+				else if (mouse->y > thumb_position + bar->thumb_size)
+				{
+					bar->thumb_position += bar->page_step;
+					if (bar->thumb_position > bar->max_position - thumb_size)
+						bar->thumb_position = bar->max_position - thumb_size;
+				}
+            }
+			goto __exit;
+        }
+
+		/* get down arrow button rect */
+        btn_rect.y1 = widget->extent.y2 - (widget->extent.x2 - widget->extent.x1);
+        btn_rect.y2 = widget->extent.y2;
+        bar_rect.y1 = widget->extent.y1 + ((widget->extent.y2 - widget->extent.y1)/2);
+        bar_rect.y2 = widget->extent.y2 - (widget->extent.x2 - widget->extent.x1);
+        if (rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
+        {
+            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+                bar->status |= SBS_DOWNARROW;
+
+				/* line step */
+				bar->thumb_position += bar->line_step;
+				if (bar->thumb_position > bar->max_position - thumb_size)
+					bar->thumb_position = bar->max_position - thumb_size;
+            }
+            else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
+                bar->status = 0;
+        }
+    }
+    else
+    {
+		/* get left arrow button rect */
+		btn_rect.x1 = widget->extent.x1;
+		btn_rect.x2 = widget->extent.x1 + (widget->extent.y2 - widget->extent.y1);
+		btn_rect.y1 = widget->extent.y1;
+		btn_rect.y2 = widget->extent.y2;
+        if (rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
+        {
+            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+                bar->status |= SBS_LEFTARROW;
+
+				/* line step */
+				bar->thumb_position -= bar->line_step;
+				if (bar->thumb_position < bar->min_position) bar->thumb_position = bar->min_position;
+            }
+             else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
+                bar->status = 0;
+			goto __exit;
+       }
+
+		/* get bar rect */
+		bar_rect.x1 = widget->extent.x1 + (widget->extent.y2 - widget->extent.y1);
+		bar_rect.x2 = widget->extent.x2 - (widget->extent.y2 - widget->extent.y1);
+		bar_rect.y1 = widget->extent.y1;
+		bar_rect.y2 = widget->extent.y2;
+        if (rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
+        {
+            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+				/* page step */
+				if (mouse->x <  bar_rect.x1 + thumb_position)
+				{
+					bar->thumb_position -= bar->page_step;
+					if (bar->thumb_position < bar->min_position)
+						bar->thumb_position = bar->min_position;
+				}
+				else if (mouse->x > thumb_position + bar->thumb_size)
+				{
+					bar->thumb_position += bar->page_step;
+					if (bar->thumb_position > bar->max_position - thumb_size)
+						bar->thumb_position = bar->max_position - thumb_size;
+				}
+            }
+			goto __exit;
+        }
+
+		/* get right arrow button rect */
+        btn_rect.x1 = widget->extent.x2 - (widget->extent.y2 - widget->extent.y1);
+        btn_rect.x2 = widget->extent.x2;
+        bar_rect.x1 = widget->extent.x1 + ((widget->extent.x2 - widget->extent.x1)/2);
+        bar_rect.x2 = widget->extent.x2 - (widget->extent.y2 - widget->extent.y1);
+        if (rtgui_rect_contains_point(&btn_rect,
+                            mouse->x, mouse->y) == RT_EOK)
+        {
+            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+                bar->status |= SBS_RIGHTARROW;
+
+				/* line step */
+				bar->thumb_position += bar->line_step;
+				if (bar->thumb_position > bar->max_position - bar->line_step)
+					bar->thumb_position = bar->max_position - bar->line_step;
+            }
+             else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
+                bar->status = 0;
+        }
+    }
+
+__exit:
+    rtgui_theme_draw_scrollbar(bar);
+	if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+		(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+	{
+		if (bar->on_scroll != RT_NULL)
+			bar->on_scroll(RTGUI_OBJECT(widget), RT_NULL);
+	}
+}
+
+rt_bool_t rtgui_scrollbar_event_handler(struct rtgui_object *object,
+										struct rtgui_event *event)
+{
+	struct rtgui_scrollbar* bar;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+	bar = RTGUI_SCROLLBAR(object);
+
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+#ifndef RTGUI_USING_SMALL_SIZE
+		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+		else
+#endif
+		{
+			rtgui_theme_draw_scrollbar(bar);
+		}
+
+		break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+		if (RTGUI_WIDGET_IS_ENABLE(widget) && !RTGUI_WIDGET_IS_HIDE(widget))
+		{
+#ifndef RTGUI_USING_SMALL_SIZE
+			if (widget->on_mouseclick != RT_NULL)
+			{
+				widget->on_mouseclick(widget, event);
+			}
+			else
+#endif
+			{
+				_rtgui_scrollbar_on_mouseclick(widget, event);
+			}
+		}
+
+		break;
+
+	default:
+		break;
+	}
+
+	return RT_FALSE;
+}
+
+struct rtgui_scrollbar* rtgui_scrollbar_create(int orient, rtgui_rect_t* r)
+{
+    struct rtgui_scrollbar* bar;
+
+    bar = (struct rtgui_scrollbar*) rtgui_widget_create (RTGUI_SCROLLBAR_TYPE);
+    if (bar != RT_NULL)
+    {
+		if (r != RT_NULL)
+		{
+			rtgui_widget_set_rect(RTGUI_WIDGET(bar), r);
+			if (orient == RTGUI_VERTICAL)
+				bar->thumb_size = (r->x2 - r->x1);
+			else
+				bar->thumb_size = (r->y2 - r->y1);
+		}
+
+		bar->orient = orient;
+    }
+
+    return bar;
+}
+
+void rtgui_scrollbar_destroy(struct rtgui_scrollbar* bar)
+{
+	rtgui_widget_destroy(RTGUI_WIDGET(bar));
+}
+
+void rtgui_scrollbar_set_orientation(rtgui_scrollbar_t* bar, int orientation)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	bar->orient = orientation;
+#ifndef RTGUI_USING_SMALL_SIZE
+	if (bar->orient == RTGUI_HORIZONTAL)
+	{
+		/* horizontal */
+		rtgui_widget_set_miniwidth(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_WIDTH);
+		rtgui_widget_set_miniheight(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_HEIGHT);
+	}
+	else 
+	{
+		/* vertical */
+		rtgui_widget_set_miniwidth(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_HEIGHT);
+		rtgui_widget_set_miniheight(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_WIDTH);
+	}
+#endif
+}
+
+void rtgui_scrollbar_set_range(struct rtgui_scrollbar* bar, int min, int max)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	if (min >= max )
+	{
+		RTGUI_WIDGET_DISABLE(RTGUI_WIDGET(bar));
+		return;
+	}
+
+	bar->min_position = (rt_int16_t)min;
+	bar->max_position = (rt_int16_t)max;
+}
+
+void rtgui_scrollbar_set_page_step(struct rtgui_scrollbar* bar, int step)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	bar->page_step = step;
+		
+	/* disable or enable scrollbar */
+	if (bar->page_step > (bar->max_position - bar->min_position))
+	{
+		/* disable bar */
+		RTGUI_WIDGET_DISABLE(RTGUI_WIDGET(bar));
+	}
+	else
+	{
+		/* enable bar */
+		RTGUI_WIDGET_ENABLE(RTGUI_WIDGET(bar));
+	}
+}
+
+void rtgui_scrollbar_set_line_step(struct rtgui_scrollbar* bar, int step)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	bar->line_step = step;
+}
+
+rt_int16_t rtgui_scrollbar_get_value(struct rtgui_scrollbar* bar)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	return bar->thumb_position;
+}
+
+void rtgui_scrollbar_set_value(struct rtgui_scrollbar* bar, rt_int16_t position)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	bar->thumb_position = position;
+	rtgui_widget_update(RTGUI_WIDGET(bar));
+}
+
+void rtgui_scrollbar_set_onscroll(struct rtgui_scrollbar* bar,
+								  rtgui_event_handler_ptr handler)
+{
+	if (bar == RT_NULL || handler == RT_NULL) return;
+
+	bar->on_scroll = handler;
+}

+ 266 - 241
components/rtgui/widgets/slider.c

@@ -1,241 +1,266 @@
-/*
- * File      : slider.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- * 2010-09-10     Bernard      fix hide issue
- */
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/slider.h>
-
-#define RTGUI_SLIDER_DEFAULT_WIDTH	100
-#define RTGUI_SLIDER_DEFAULT_HEIGHT	20
-#define RTGUI_SLIDER_DEFAULT_MIN	0
-#define RTGUI_SLIDER_DEFAULT_MAX	100
-
-static void _rtgui_slider_constructor(rtgui_slider_t *slider)
-{
-	rtgui_rect_t rect = {0, 0, RTGUI_SLIDER_DEFAULT_WIDTH, RTGUI_SLIDER_DEFAULT_HEIGHT};
-
-	/* init widget and set event handler */
-	RTGUI_WIDGET(slider)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-	rtgui_widget_set_rect(RTGUI_WIDGET(slider), &rect);
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(slider), rtgui_slider_event_handler);
-
-	/* set proper of control */
-	slider->min = RTGUI_SLIDER_DEFAULT_MIN;
-	slider->max = RTGUI_SLIDER_DEFAULT_MAX;
-	slider->value = RTGUI_SLIDER_DEFAULT_MIN;
-	slider->orient = RTGUI_HORIZONTAL;
-
-	slider->ticks = 10;
-	slider->thumb_width = 8;
-	slider->on_changed = RT_NULL;
-}
-
-DEFINE_CLASS_TYPE(slider, "slider", 
-	RTGUI_WIDGET_TYPE,
-	_rtgui_slider_constructor,
-	RT_NULL,
-	sizeof(struct rtgui_slider));
-
-static void rtgui_slider_onmouse(struct rtgui_slider* slider, struct rtgui_event_mouse* event)
-{
-	RT_ASSERT(slider != RT_NULL);
-	RT_ASSERT(event  != RT_NULL);
-
-	if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
-		event->button & RTGUI_MOUSE_BUTTON_LEFT)
-	{
-		int sel;
-		int range = slider->max - slider->min;
-		int x0, xsize;
-		int x;
-		x0 = 1 + slider->thumb_width/2;
-
-		if (slider->orient == RTGUI_VERTICAL)
-		{
-			x = event->y - RTGUI_WIDGET(slider)->extent.y1;
-			x -= x0;
-			xsize = rtgui_rect_height(RTGUI_WIDGET(slider)->extent) - 2 * x0;
-		}
-		else
-		{
-			x = event->x - RTGUI_WIDGET(slider)->extent.x1;
-			x -= x0;
-			xsize = rtgui_rect_width(RTGUI_WIDGET(slider)->extent) - 2 * x0;
-		}
-
-		if (x <= 0)
-		{
-			sel = slider->min;
-		}
-		else if (x >= xsize)
-		{
-			sel = slider->max;
-		}
-		else
-		{
-			sel = ((range * x) + xsize/2) / xsize;
-			sel += slider->min;
-		}
-
-		rtgui_widget_focus(RTGUI_WIDGET(slider));
-		rtgui_slider_set_value(slider, sel);
-		if (slider->on_changed != RT_NULL) /* invoke callback function */
-			slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
-	}
-}
-
-static void rtgui_slider_onkey(struct rtgui_slider* slider, struct rtgui_event_kbd *event)
-{
-	RT_ASSERT(slider != RT_NULL);
-	RT_ASSERT(event != RT_NULL);
-
-	if (!(RTGUI_KBD_IS_UP(event))) return;
-
-	if (event->key == RTGUIK_LEFT)
-	{
-		if (slider->value > slider->min)
-			slider->value ++;
-	}
-
-	if (event->key == RTGUIK_RIGHT)
-	{
-		if (slider->value < slider->max)
-			slider->value --;
-	}
-
-	/* update widget */
-	rtgui_widget_update(RTGUI_WIDGET(slider));
-	if (slider->on_changed != RT_NULL) /* invoke callback function */
-		slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
-}
-
-rt_bool_t rtgui_slider_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_slider* slider = (struct rtgui_slider*)widget;
-
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-#ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
-		else
-#endif
-		{
-			rtgui_theme_draw_slider(slider);
-		}
-
-		break;
-
-	case RTGUI_EVENT_KBD:
-		if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
-
-#ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_key != RT_NULL) widget->on_key(widget, event);
-		else
-#endif
-		{
-			rtgui_slider_onkey(slider, (struct rtgui_event_kbd *)event);
-		}
-		break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-		if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
-
-#ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
-		else
-#endif
-		{
-			rtgui_slider_onmouse(slider, (struct rtgui_event_mouse*)event);
-		}
-		break;
-	}
-
-	return RT_FALSE;
-}
-
-struct rtgui_slider* rtgui_slider_create(rt_size_t min, rt_size_t max, int orient)
-{
-    struct rtgui_slider* slider;
-
-    slider = (struct rtgui_slider*) rtgui_widget_create (RTGUI_SLIDER_TYPE);
-    if (slider != RT_NULL)
-    {
-		/* set proper of control */
-		slider->min = min;
-		slider->max = max;
-		slider->value = min;
-
-		slider->ticks = 10;
-		slider->thumb_width = 8;
-
-		rtgui_slider_set_orientation(slider, orient);
-	}
-
-	return slider;
-}
-
-void rtgui_slider_set_range(struct rtgui_slider* slider, rt_size_t min, rt_size_t max)
-{
-	RT_ASSERT(slider != RT_NULL);
-
-	slider->max = max;
-	slider->min = min;
-}
-
-void rtgui_slider_set_value(struct rtgui_slider* slider, rt_size_t value)
-{
-	RT_ASSERT(slider != RT_NULL);
-
-	if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(slider)))
-	{
-		if (value < slider->min) value = slider->min;
-		if (value > slider->max) value = slider->max;
-
-		if (slider->value != value)
-		{
-			slider->value = value;
-			rtgui_theme_draw_slider(slider);
-		}
-	}
-}
-
-void rtgui_slider_set_orientation(struct rtgui_slider* slider, int orientation)
-{
-	RT_ASSERT(slider != RT_NULL);
-
-	/* set orientation */
-	slider->orient = orientation;
-#ifndef RTGUI_USING_SMALL_SIZE
-	if (slider->orient == RTGUI_HORIZONTAL)
-	{
-		/* HORIZONTAL */
-		rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
-		rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
-	}
-	else 
-	{
-		/* VERTICAL */
-		rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
-		rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
-	}
-#endif
-}
-
-rt_size_t rtgui_slider_get_value(struct rtgui_slider* slider)
-{
-	RT_ASSERT(slider != RT_NULL);
-
-	return slider->value;
-}
+/*
+ * File      : slider.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2009-10-16     Bernard      first version
+ * 2010-09-10     Bernard      fix hide issue
+ */
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/slider.h>
+
+#define RTGUI_SLIDER_DEFAULT_WIDTH	100
+#define RTGUI_SLIDER_DEFAULT_HEIGHT	20
+#define RTGUI_SLIDER_DEFAULT_MIN	0
+#define RTGUI_SLIDER_DEFAULT_MAX	100
+
+static void _rtgui_slider_constructor(rtgui_slider_t *slider)
+{
+	rtgui_rect_t rect = {0, 0, RTGUI_SLIDER_DEFAULT_WIDTH, RTGUI_SLIDER_DEFAULT_HEIGHT};
+
+	/* init widget and set event handler */
+	RTGUI_WIDGET(slider)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+	rtgui_widget_set_rect(RTGUI_WIDGET(slider), &rect);
+	rtgui_object_set_event_handler(RTGUI_OBJECT(slider), rtgui_slider_event_handler);
+
+	/* set proper of control */
+	slider->min = RTGUI_SLIDER_DEFAULT_MIN;
+	slider->max = RTGUI_SLIDER_DEFAULT_MAX;
+	slider->value = RTGUI_SLIDER_DEFAULT_MIN;
+	slider->orient = RTGUI_HORIZONTAL;
+
+	slider->ticks = 10;
+	slider->thumb_width = 8;
+	slider->on_changed = RT_NULL;
+}
+
+DEFINE_CLASS_TYPE(slider, "slider", 
+	RTGUI_WIDGET_TYPE,
+	_rtgui_slider_constructor,
+	RT_NULL,
+	sizeof(struct rtgui_slider));
+
+static void rtgui_slider_onmouse(struct rtgui_slider* slider, struct rtgui_event_mouse* event)
+{
+	RT_ASSERT(slider != RT_NULL);
+	RT_ASSERT(event  != RT_NULL);
+
+	if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
+		event->button & RTGUI_MOUSE_BUTTON_LEFT)
+	{
+		int sel;
+		int range = slider->max - slider->min;
+		int x0, xsize;
+		int x;
+		x0 = 1 + slider->thumb_width/2;
+
+		if (slider->orient == RTGUI_VERTICAL)
+		{
+			x = event->y - RTGUI_WIDGET(slider)->extent.y1;
+			x -= x0;
+			xsize = rtgui_rect_height(RTGUI_WIDGET(slider)->extent) - 2 * x0;
+		}
+		else
+		{
+			x = event->x - RTGUI_WIDGET(slider)->extent.x1;
+			x -= x0;
+			xsize = rtgui_rect_width(RTGUI_WIDGET(slider)->extent) - 2 * x0;
+		}
+
+		if (x <= 0)
+		{
+			sel = slider->min;
+		}
+		else if (x >= xsize)
+		{
+			sel = slider->max;
+		}
+		else
+		{
+			sel = ((range * x) + xsize/2) / xsize;
+			sel += slider->min;
+		}
+
+		rtgui_widget_focus(RTGUI_WIDGET(slider));
+		rtgui_slider_set_value(slider, sel);
+		if (slider->on_changed != RT_NULL) /* invoke callback function */
+			slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
+	}
+}
+
+static rt_bool_t rtgui_slider_onkey(struct rtgui_slider* slider, struct rtgui_event_kbd *event)
+{
+	RT_ASSERT(slider != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	if (!(RTGUI_KBD_IS_UP(event)))
+		return RT_TRUE;
+
+	if (slider->orient == RTGUI_HORIZONTAL)
+	{
+		if (event->key == RTGUIK_RIGHT)
+		{
+			if (slider->value > slider->min)
+				slider->value++;
+		}
+		else if (event->key == RTGUIK_LEFT)
+		{
+			if (slider->value < slider->max)
+				slider->value--;
+		}
+	}
+	else
+	{
+		if (event->key == RTGUIK_UP)
+		{
+			if (slider->value > slider->min)
+				slider->value--;
+		}
+		else if (event->key == RTGUIK_DOWN)
+		{
+			if (slider->value < slider->max)
+				slider->value++;
+		}
+	}
+
+	/* update widget */
+	rtgui_widget_update(RTGUI_WIDGET(slider));
+	if (slider->on_changed != RT_NULL) /* invoke callback function */
+		slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
+
+	return RT_TRUE;
+}
+
+rt_bool_t rtgui_slider_event_handler(struct rtgui_object *object, struct rtgui_event *event)
+{
+	struct rtgui_widget *widget;
+	struct rtgui_slider* slider;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	widget = RTGUI_WIDGET(object);
+	slider = RTGUI_SLIDER(object);
+
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+#ifndef RTGUI_USING_SMALL_SIZE
+		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+		else
+#endif
+		{
+			rtgui_theme_draw_slider(slider);
+		}
+
+		break;
+
+	case RTGUI_EVENT_KBD:
+		if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
+
+#ifndef RTGUI_USING_SMALL_SIZE
+		if (widget->on_key != RT_NULL) widget->on_key(widget, event);
+		else
+#endif
+		{
+			return rtgui_slider_onkey(slider, (struct rtgui_event_kbd *)event);
+		}
+		break;
+
+	case RTGUI_EVENT_MOUSE_BUTTON:
+		if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
+
+#ifndef RTGUI_USING_SMALL_SIZE
+		if (widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
+		else
+#endif
+		{
+			rtgui_slider_onmouse(slider, (struct rtgui_event_mouse*)event);
+		}
+		break;
+	}
+
+	return RT_FALSE;
+}
+
+struct rtgui_slider* rtgui_slider_create(rt_size_t min, rt_size_t max, int orient)
+{
+    struct rtgui_slider* slider;
+
+    slider = (struct rtgui_slider*) rtgui_widget_create (RTGUI_SLIDER_TYPE);
+    if (slider != RT_NULL)
+    {
+		/* set proper of control */
+		slider->min = min;
+		slider->max = max;
+		slider->value = min;
+
+		slider->ticks = 10;
+		slider->thumb_width = 8;
+
+		rtgui_slider_set_orientation(slider, orient);
+	}
+
+	return slider;
+}
+
+void rtgui_slider_set_range(struct rtgui_slider* slider, rt_size_t min, rt_size_t max)
+{
+	RT_ASSERT(slider != RT_NULL);
+
+	slider->max = max;
+	slider->min = min;
+}
+
+void rtgui_slider_set_value(struct rtgui_slider* slider, rt_size_t value)
+{
+	RT_ASSERT(slider != RT_NULL);
+
+	if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(slider)))
+	{
+		if (value < slider->min) value = slider->min;
+		if (value > slider->max) value = slider->max;
+
+		if (slider->value != value)
+		{
+			slider->value = value;
+			rtgui_theme_draw_slider(slider);
+		}
+	}
+}
+
+void rtgui_slider_set_orientation(struct rtgui_slider* slider, int orientation)
+{
+	RT_ASSERT(slider != RT_NULL);
+
+	/* set orientation */
+	slider->orient = orientation;
+#ifndef RTGUI_USING_SMALL_SIZE
+	if (slider->orient == RTGUI_HORIZONTAL)
+	{
+		/* HORIZONTAL */
+		rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
+		rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
+	}
+	else
+	{
+		/* VERTICAL */
+		rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
+		rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
+	}
+#endif
+}
+
+rt_size_t rtgui_slider_get_value(struct rtgui_slider* slider)
+{
+	RT_ASSERT(slider != RT_NULL);
+
+	return slider->value;
+}

+ 80 - 80
components/rtgui/widgets/staticline.c

@@ -1,80 +1,80 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/staticline.h>
-
-static void _rtgui_staticline_constructor(rtgui_staticline_t *staticline)
-{
-	/* init widget and set event handler */
-	rtgui_rect_t rect = {0, 0, 100, 2};
-
-	rtgui_widget_set_rect(RTGUI_WIDGET(staticline), &rect);
-	staticline->orient= RTGUI_HORIZONTAL;
-
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(staticline), rtgui_staticline_event_handler);
-}
-
-
-DEFINE_CLASS_TYPE(staticline, "staticline", 
-	RTGUI_WIDGET_TYPE,
-	_rtgui_staticline_constructor,
-	RT_NULL,
-	sizeof(struct rtgui_staticline));
-
-rt_bool_t rtgui_staticline_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_staticline* staticline;
-	RT_ASSERT(widget != RT_NULL);
-
-	staticline = (struct rtgui_staticline*) widget;
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-#ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
-		else
-#endif
-			rtgui_theme_draw_staticline(staticline);
-		break;
-	}
-
-	return RT_FALSE;
-}
-
-rtgui_staticline_t * rtgui_staticline_create(int orientation)
-{
-	rtgui_staticline_t* staticline;
-
-	staticline = (struct rtgui_staticline*) rtgui_widget_create(RTGUI_STATICLINE_TYPE);
-	if (staticline!= RT_NULL)
-	{
-		rtgui_staticline_set_orientation(staticline, orientation);
-	}
-
-	return staticline;
-}
-
-void rtgui_staticline_destroy(rtgui_staticline_t* staticline)
-{
-	rtgui_widget_destroy(RTGUI_WIDGET(staticline));
-}
-
-void rtgui_staticline_set_orientation(rtgui_staticline_t* staticline, int orientation)
-{
-	RT_ASSERT(staticline != RT_NULL);
-
-	staticline->orient = orientation;
-#ifndef RTGUI_USING_SMALL_SIZE
-	if (orientation == RTGUI_HORIZONTAL)
-	{
-		/* HORIZONTAL */
-		rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 2);
-		rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 100);
-	}
-	else
-	{
-		/* VERTICAL */
-		rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 2);
-		rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 100);
-	}
-#endif
-}
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/staticline.h>
+
+static void _rtgui_staticline_constructor(rtgui_staticline_t *staticline)
+{
+	/* init widget and set event handler */
+	rtgui_rect_t rect = {0, 0, 100, 2};
+
+	rtgui_widget_set_rect(RTGUI_WIDGET(staticline), &rect);
+	staticline->orient= RTGUI_HORIZONTAL;
+
+	rtgui_object_set_event_handler(RTGUI_OBJECT(staticline), rtgui_staticline_event_handler);
+}
+
+
+DEFINE_CLASS_TYPE(staticline, "staticline", 
+	RTGUI_WIDGET_TYPE,
+	_rtgui_staticline_constructor,
+	RT_NULL,
+	sizeof(struct rtgui_staticline));
+
+rt_bool_t rtgui_staticline_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_staticline* staticline;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+	staticline = RTGUI_STATICLINE(object);
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+#ifndef RTGUI_USING_SMALL_SIZE
+		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+		else
+#endif
+			rtgui_theme_draw_staticline(staticline);
+		break;
+	}
+
+	return RT_FALSE;
+}
+
+rtgui_staticline_t * rtgui_staticline_create(int orientation)
+{
+	rtgui_staticline_t* staticline;
+
+	staticline = (struct rtgui_staticline*) rtgui_widget_create(RTGUI_STATICLINE_TYPE);
+	if (staticline!= RT_NULL)
+	{
+		rtgui_staticline_set_orientation(staticline, orientation);
+	}
+
+	return staticline;
+}
+
+void rtgui_staticline_destroy(rtgui_staticline_t* staticline)
+{
+	rtgui_widget_destroy(RTGUI_WIDGET(staticline));
+}
+
+void rtgui_staticline_set_orientation(rtgui_staticline_t* staticline, int orientation)
+{
+	RT_ASSERT(staticline != RT_NULL);
+
+	staticline->orient = orientation;
+#ifndef RTGUI_USING_SMALL_SIZE
+	if (orientation == RTGUI_HORIZONTAL)
+	{
+		/* HORIZONTAL */
+		rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 2);
+		rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 100);
+	}
+	else
+	{
+		/* VERTICAL */
+		rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 2);
+		rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 100);
+	}
+#endif
+}

+ 16 - 10
components/rtgui/widgets/textbox.c

@@ -25,13 +25,13 @@
 #define RTGUI_TEXTBOX_MARGIN		3
 #define RTGUI_TEXTBOX_MARGIN		3
 
 
 static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kbd* event);
 static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kbd* event);
-static rt_bool_t rtgui_textbox_onfocus(struct rtgui_widget* widget, struct rtgui_event* event);
-static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_widget* widget, struct rtgui_event* event);
+static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* object, struct rtgui_event* event);
+static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* object, struct rtgui_event* event);
 
 
 static void _rtgui_textbox_caret_timeout(struct rtgui_timer* timer, void* parameter)
 static void _rtgui_textbox_caret_timeout(struct rtgui_timer* timer, void* parameter)
 {
 {
 	rtgui_textbox_t* box;
 	rtgui_textbox_t* box;
-	
+
 	box = (rtgui_textbox_t*)parameter;
 	box = (rtgui_textbox_t*)parameter;
 	/* set caret flag */
 	/* set caret flag */
 	if (box->flag & RTGUI_TEXTBOX_CARET_SHOW)
 	if (box->flag & RTGUI_TEXTBOX_CARET_SHOW)
@@ -51,7 +51,7 @@ static void _rtgui_textbox_constructor(rtgui_textbox_t *box)
 	rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
 	rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
 
 
 	RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
 	RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_textbox_event_handler);
+	rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_textbox_event_handler);
 	rtgui_widget_set_onfocus(RTGUI_WIDGET(box), rtgui_textbox_onfocus);
 	rtgui_widget_set_onfocus(RTGUI_WIDGET(box), rtgui_textbox_onfocus);
 	rtgui_widget_set_onunfocus(RTGUI_WIDGET(box), rtgui_textbox_onunfocus);
 	rtgui_widget_set_onunfocus(RTGUI_WIDGET(box), rtgui_textbox_onunfocus);
 
 
@@ -226,10 +226,12 @@ static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kb
 	rtgui_theme_draw_textbox(box);
 	rtgui_theme_draw_textbox(box);
 }
 }
 
 
-static rt_bool_t rtgui_textbox_onfocus(struct rtgui_widget* widget, struct rtgui_event* event)
+static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* object, struct rtgui_event* event)
 {
 {
-	struct rtgui_textbox* box = (struct rtgui_textbox*)widget;
+	struct rtgui_textbox* box;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
 
 
+	box = RTGUI_TEXTBOX(object);
 	/* set caret to show */
 	/* set caret to show */
 	box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
 	box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
 	/* start caret timer */
 	/* start caret timer */
@@ -238,10 +240,12 @@ static rt_bool_t rtgui_textbox_onfocus(struct rtgui_widget* widget, struct rtgui
 	return RT_TRUE;
 	return RT_TRUE;
 }
 }
 
 
-static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_widget* widget, struct rtgui_event* event)
+static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* object, struct rtgui_event* event)
 {
 {
-	struct rtgui_textbox* box = (struct rtgui_textbox*)widget;
+	struct rtgui_textbox* box;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
 
 
+	box = RTGUI_TEXTBOX(object);
 	/* stop caret timer */
 	/* stop caret timer */
 	rtgui_timer_stop(box->caret_timer);
 	rtgui_timer_stop(box->caret_timer);
 	/* set caret to hide */
 	/* set caret to hide */
@@ -250,10 +254,12 @@ static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_widget* widget, struct rtg
 	return RT_TRUE;
 	return RT_TRUE;
 }
 }
 
 
-rt_bool_t rtgui_textbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+rt_bool_t rtgui_textbox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
 {
 {
-	struct rtgui_textbox* box = (struct rtgui_textbox*)widget;
+	struct rtgui_textbox* box;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
 
 
+	box = RTGUI_TEXTBOX(object);
 	switch (event->type)
 	switch (event->type)
 	{
 	{
 	case RTGUI_EVENT_PAINT:
 	case RTGUI_EVENT_PAINT:

+ 351 - 352
components/rtgui/widgets/textview.c

@@ -1,352 +1,351 @@
-/*
- * File      : textview.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2011-03-05     Bernard      first version
- */
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/textview.h>
-
-rt_inline char* _get_line_text(rtgui_textview_t *textview, rt_uint16_t index)
-{
-	char* line;
-	if (index < textview->line_count)
-	{
-		line = textview->lines + (index * textview->line_width);
-		return line;
-	}
-
-	return RT_NULL;
-}
-
-static void _calc_line(rtgui_textview_t *textview, const char* text)
-{
-	char* line;
-	const unsigned char* ptr;
-	rt_ubase_t line_index, line_position;
-
-	if (textview->lines != RT_NULL)
-	{
-		rt_free(textview->lines);
-		textview->lines = RT_NULL;
-		textview->line_count = 0;
-	}
-
-	/* get line count */
-	line_index = 0; line_position = 0;
-	ptr = (const unsigned char*)text;
-	if (*ptr == 0) return;
-
-	while (*ptr != '\0')
-	{
-		if (*ptr == '\n') 
-		{
-			line_index ++;
-			line_position = 0;
-		}
-		else if (*ptr == '\r')
-		{
-			ptr ++;
-			continue;
-		}
-		else if (*ptr == '\t')
-		{
-			line_position += 4;
-			if (line_position >= textview->line_width - 1)
-			{
-				line_index ++;
-				line_position = 0;
-			}
-		}
-		else 
-		{
-			if ((*ptr) >= 0x80)
-			{
-				/* fill cjk character */
-				if (line_position + 1 >= (textview->line_width - 1))
-				{
-					/* split to next line */
-					line_index ++;
-					line_position = 0;
-				}
-
-				line_position ++;
-				line_position ++;
-			}
-			else 
-			{
-				line_position ++;
-			}
-
-			if (line_position >= textview->line_width - 1)
-			{
-				line_index ++;
-				line_position = 0;
-			}
-		}
-
-		ptr ++;
-	}
-
-	/* set line count */
-	textview->line_count = line_index + 1;
-
-	/* allocate lines */
-	textview->lines = rt_malloc(textview->line_count * textview->line_width);
-	rt_memset(textview->lines, 0, (textview->line_count * textview->line_width));
-
-	/* fill lines */
-	line_index = 0; line_position = 0;
-	ptr = (const unsigned char*)text;
-	line = _get_line_text(textview, line_index);
-	while (*ptr)
-	{
-		if (*ptr == '\n') 
-		{
-			line_index ++;
-			line_position = 0;
-			line = _get_line_text(textview, line_index);
-		}
-		else if (*ptr == '\r')
-		{
-			/* ignore '\r' */
-			ptr ++;
-			continue;
-		}
-		else if (*ptr == '\t')
-		{
-			line[line_position++] = ' ';
-			line[line_position++] = ' ';
-			line[line_position++] = ' ';
-			line[line_position++] = ' ';
-			if (line_position >= textview->line_width - 1)
-			{
-				line_index ++;
-				line_position = 0;
-				line = _get_line_text(textview, line_index);
-			}
-		}
-		else 
-		{
-			if ((*ptr) >= 0x80)
-			{
-				/* fill cjk character */
-				if (line_position + 1 >= (textview->line_width - 1))
-				{
-					/* split to next line */
-					line_index ++;
-					line_position = 0;
-					line = _get_line_text(textview, line_index);
-				}
-
-				line[line_position ++] = *ptr ++;
-				line[line_position ++] = *ptr;
-			}
-			else 
-			{
-				line[line_position ++] = *ptr;
-			}
-
-			if (line_position >= textview->line_width - 1)
-			{
-				line_index ++;
-				line_position = 0;
-				line = _get_line_text(textview, line_index);
-			}
-		}
-
-		ptr ++;
-	}
-
-	textview->line_current = 0;
-}
-
-static void _calc_width(rtgui_textview_t *textview)
-{
-	rtgui_rect_t rect;
-	rt_uint16_t width, height;
-
-	width = rtgui_rect_width(RTGUI_WIDGET(textview)->extent) - 6;
-	height = rtgui_rect_height(RTGUI_WIDGET(textview)->extent);
-
-	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &rect);
-	textview->line_width = width / rtgui_rect_width(rect) + 1;
-	textview->line_page_count = height / (rtgui_rect_height(rect) + 3);
-
-	/* set minimal value */
-	if (textview->line_page_count == 0) textview->line_page_count = 1;
-}
-
-static void _draw_textview(rtgui_textview_t *textview)
-{
-	struct rtgui_dc* dc;
-	struct rtgui_rect rect, font_rect;
-	char* line;
-	rt_ubase_t line_index, item_height;
-
-	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &font_rect);
-	item_height = rtgui_rect_height(font_rect) + 3;
-
-	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(textview));
-	if (dc == RT_NULL) return ;
-
-	/* fill rect */
-	rtgui_widget_get_rect(RTGUI_WIDGET(textview), &rect);
-	rtgui_dc_fill_rect(dc, &rect);
-
-	rect.x1 += 3;
-	rect.x2 -= 3;
-
-	for (line_index = textview->line_current; 
-		(line_index < textview->line_current + textview->line_page_count) &&
-		(line_index < textview->line_count); 
-		line_index ++)
-	{
-		line = (char* )_get_line_text(textview, line_index);
-		rtgui_dc_draw_text(dc, line, &rect);
-
-		rect.y1 += item_height;
-	}
-
-	rtgui_dc_end_drawing(dc);
-}
-
-static void _rtgui_textview_constructor(rtgui_textview_t *textview)
-{
-	/* init widget and set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(textview), rtgui_textview_event_handler);
-	RTGUI_WIDGET(textview)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
-	/* set field */
-	textview->line_count = 0;
-	textview->lines = RT_NULL;
-
-	textview->line_current = -1;
-	textview->line_page_count = 1;
-}
-
-static void _rtgui_textview_destructor(rtgui_textview_t *textview)
-{
-	/* release line memory */
-	rt_free(textview->lines);
-	textview->lines = RT_NULL;
-}
-
-DEFINE_CLASS_TYPE(textview, "textview", 
-	RTGUI_WIDGET_TYPE,
-	_rtgui_textview_constructor,
-	_rtgui_textview_destructor,
-	sizeof(struct rtgui_textview));
-
-rt_bool_t rtgui_textview_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_textview* textview;
-
-	RT_ASSERT(widget != RT_NULL);
-
-	textview = (struct rtgui_textview*) widget;
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-		_draw_textview(textview);
-		break;
-	
-	case RTGUI_EVENT_KBD:
-		{
-		struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
-		if (ekbd->type == RTGUI_KEYDOWN)
-		{
-			rt_int16_t line_current_update;
-			line_current_update = textview->line_current;
-			if (ekbd->key == RTGUIK_LEFT)
-			{
-				if (textview->line_current > textview->line_page_count)
-				{
-					line_current_update -= textview->line_page_count;
-				}
-				else if (textview->line_current > 0)
-				{
-					line_current_update = 0;
-				}
-			}
-			else if (ekbd->key == RTGUIK_RIGHT)
-			{
-				if (textview->line_current + textview->line_page_count < textview->line_count - 1)
-				{
-					line_current_update += textview->line_page_count;
-				}
-			}
-			else if (ekbd->key == RTGUIK_UP)
-			{
-				if (textview->line_current > 0)
-				{
-					line_current_update --;
-				}
-			}
-			else if (ekbd->key == RTGUIK_DOWN)
-			{
-				if (textview->line_current + textview->line_page_count < textview->line_count - 1)
-				{
-					line_current_update ++;
-				}
-			}
-
-			if (textview->line_current != line_current_update)
-			{
-				textview->line_current = line_current_update;
-				rtgui_widget_update(widget);
-				return RT_TRUE;
-			}
-		}
-		break;
-		}
-	}
-
-	return RT_FALSE;
-}
-
-rtgui_textview_t* rtgui_textview_create(const char* text, const rtgui_rect_t *rect)
-{
-    struct rtgui_textview* textview;
-
-    textview = (struct rtgui_textview*) rtgui_widget_create(RTGUI_TEXTVIEW_TYPE);
-    if (textview != RT_NULL)
-    {
-		rtgui_widget_set_rect(RTGUI_WIDGET(textview), rect);
-
-		/* calculate line width and line page count */
-		_calc_width(textview);
-
-		/* set text */
-		_calc_line(textview, text);
-    }
-
-    return textview;
-}
-
-void rtgui_textview_destroy(rtgui_textview_t* textview)
-{
-	rtgui_widget_destroy(RTGUI_WIDGET(textview));
-}
-
-void rtgui_textview_set_text(rtgui_textview_t* textview, const char* text)
-{
-	RT_ASSERT(textview != RT_NULL);
-
-	/* calculate line width and line page count */
-	_calc_width(textview);
-
-	/* set text */
-	_calc_line(textview, text);
-
-	/* update widget */
-	rtgui_widget_update(RTGUI_WIDGET(textview));
-}
+/*
+ * File      : textview.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2011-03-05     Bernard      first version
+ */
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/textview.h>
+
+rt_inline char* _get_line_text(rtgui_textview_t *textview, rt_uint16_t index)
+{
+	char* line;
+	if (index < textview->line_count)
+	{
+		line = textview->lines + (index * textview->line_width);
+		return line;
+	}
+
+	return RT_NULL;
+}
+
+static void _calc_line(rtgui_textview_t *textview, const char* text)
+{
+	char* line;
+	const unsigned char* ptr;
+	rt_ubase_t line_index, line_position;
+
+	if (textview->lines != RT_NULL)
+	{
+		rt_free(textview->lines);
+		textview->lines = RT_NULL;
+		textview->line_count = 0;
+	}
+
+	/* get line count */
+	line_index = 0; line_position = 0;
+	ptr = (const unsigned char*)text;
+	if (*ptr == 0) return;
+
+	while (*ptr != '\0')
+	{
+		if (*ptr == '\n') 
+		{
+			line_index ++;
+			line_position = 0;
+		}
+		else if (*ptr == '\r')
+		{
+			ptr ++;
+			continue;
+		}
+		else if (*ptr == '\t')
+		{
+			line_position += 4;
+			if (line_position >= textview->line_width - 1)
+			{
+				line_index ++;
+				line_position = 0;
+			}
+		}
+		else 
+		{
+			if ((*ptr) >= 0x80)
+			{
+				/* fill cjk character */
+				if (line_position + 1 >= (textview->line_width - 1))
+				{
+					/* split to next line */
+					line_index ++;
+					line_position = 0;
+				}
+
+				line_position ++;
+				line_position ++;
+			}
+			else 
+			{
+				line_position ++;
+			}
+
+			if (line_position >= textview->line_width - 1)
+			{
+				line_index ++;
+				line_position = 0;
+			}
+		}
+
+		ptr ++;
+	}
+
+	/* set line count */
+	textview->line_count = line_index + 1;
+
+	/* allocate lines */
+	textview->lines = rt_malloc(textview->line_count * textview->line_width);
+	rt_memset(textview->lines, 0, (textview->line_count * textview->line_width));
+
+	/* fill lines */
+	line_index = 0; line_position = 0;
+	ptr = (const unsigned char*)text;
+	line = _get_line_text(textview, line_index);
+	while (*ptr)
+	{
+		if (*ptr == '\n') 
+		{
+			line_index ++;
+			line_position = 0;
+			line = _get_line_text(textview, line_index);
+		}
+		else if (*ptr == '\r')
+		{
+			/* ignore '\r' */
+			ptr ++;
+			continue;
+		}
+		else if (*ptr == '\t')
+		{
+			line[line_position++] = ' ';
+			line[line_position++] = ' ';
+			line[line_position++] = ' ';
+			line[line_position++] = ' ';
+			if (line_position >= textview->line_width - 1)
+			{
+				line_index ++;
+				line_position = 0;
+				line = _get_line_text(textview, line_index);
+			}
+		}
+		else 
+		{
+			if ((*ptr) >= 0x80)
+			{
+				/* fill cjk character */
+				if (line_position + 1 >= (textview->line_width - 1))
+				{
+					/* split to next line */
+					line_index ++;
+					line_position = 0;
+					line = _get_line_text(textview, line_index);
+				}
+
+				line[line_position ++] = *ptr ++;
+				line[line_position ++] = *ptr;
+			}
+			else 
+			{
+				line[line_position ++] = *ptr;
+			}
+
+			if (line_position >= textview->line_width - 1)
+			{
+				line_index ++;
+				line_position = 0;
+				line = _get_line_text(textview, line_index);
+			}
+		}
+
+		ptr ++;
+	}
+
+	textview->line_current = 0;
+}
+
+static void _calc_width(rtgui_textview_t *textview)
+{
+	rtgui_rect_t rect;
+	rt_uint16_t width, height;
+
+	width = rtgui_rect_width(RTGUI_WIDGET(textview)->extent) - 6;
+	height = rtgui_rect_height(RTGUI_WIDGET(textview)->extent);
+
+	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &rect);
+	textview->line_width = width / rtgui_rect_width(rect) + 1;
+	textview->line_page_count = height / (rtgui_rect_height(rect) + 3);
+
+	/* set minimal value */
+	if (textview->line_page_count == 0) textview->line_page_count = 1;
+}
+
+static void _draw_textview(rtgui_textview_t *textview)
+{
+	struct rtgui_dc* dc;
+	struct rtgui_rect rect, font_rect;
+	char* line;
+	rt_ubase_t line_index, item_height;
+
+	rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &font_rect);
+	item_height = rtgui_rect_height(font_rect) + 3;
+
+	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(textview));
+	if (dc == RT_NULL) return ;
+
+	/* fill rect */
+	rtgui_widget_get_rect(RTGUI_WIDGET(textview), &rect);
+	rtgui_dc_fill_rect(dc, &rect);
+
+	rect.x1 += 3;
+	rect.x2 -= 3;
+
+	for (line_index = textview->line_current; 
+		(line_index < textview->line_current + textview->line_page_count) &&
+		(line_index < textview->line_count); 
+		line_index ++)
+	{
+		line = (char* )_get_line_text(textview, line_index);
+		rtgui_dc_draw_text(dc, line, &rect);
+
+		rect.y1 += item_height;
+	}
+
+	rtgui_dc_end_drawing(dc);
+}
+
+static void _rtgui_textview_constructor(rtgui_textview_t *textview)
+{
+	/* init widget and set event handler */
+	rtgui_object_set_event_handler(RTGUI_OBJECT(textview), rtgui_textview_event_handler);
+	RTGUI_WIDGET(textview)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+	/* set field */
+	textview->line_count = 0;
+	textview->lines = RT_NULL;
+
+	textview->line_current = -1;
+	textview->line_page_count = 1;
+}
+
+static void _rtgui_textview_destructor(rtgui_textview_t *textview)
+{
+	/* release line memory */
+	rt_free(textview->lines);
+	textview->lines = RT_NULL;
+}
+
+DEFINE_CLASS_TYPE(textview, "textview",
+	RTGUI_WIDGET_TYPE,
+	_rtgui_textview_constructor,
+	_rtgui_textview_destructor,
+	sizeof(struct rtgui_textview));
+
+rt_bool_t rtgui_textview_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_textview* textview;
+	RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+	textview = RTGUI_TEXTVIEW(object);
+	switch (event->type)
+	{
+	case RTGUI_EVENT_PAINT:
+		_draw_textview(textview);
+		break;
+
+	case RTGUI_EVENT_KBD:
+		{
+		struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+		if (ekbd->type == RTGUI_KEYDOWN)
+		{
+			rt_int16_t line_current_update;
+			line_current_update = textview->line_current;
+			if (ekbd->key == RTGUIK_LEFT)
+			{
+				if (textview->line_current > textview->line_page_count)
+				{
+					line_current_update -= textview->line_page_count;
+				}
+				else if (textview->line_current > 0)
+				{
+					line_current_update = 0;
+				}
+			}
+			else if (ekbd->key == RTGUIK_RIGHT)
+			{
+				if (textview->line_current + textview->line_page_count < textview->line_count - 1)
+				{
+					line_current_update += textview->line_page_count;
+				}
+			}
+			else if (ekbd->key == RTGUIK_UP)
+			{
+				if (textview->line_current > 0)
+				{
+					line_current_update --;
+				}
+			}
+			else if (ekbd->key == RTGUIK_DOWN)
+			{
+				if (textview->line_current + textview->line_page_count < textview->line_count - 1)
+				{
+					line_current_update ++;
+				}
+			}
+
+			if (textview->line_current != line_current_update)
+			{
+				textview->line_current = line_current_update;
+				rtgui_widget_update(widget);
+				return RT_TRUE;
+			}
+		}
+		break;
+		}
+	}
+
+	return RT_FALSE;
+}
+
+rtgui_textview_t* rtgui_textview_create(const char* text, const rtgui_rect_t *rect)
+{
+    struct rtgui_textview* textview;
+
+    textview = (struct rtgui_textview*) rtgui_widget_create(RTGUI_TEXTVIEW_TYPE);
+    if (textview != RT_NULL)
+    {
+		rtgui_widget_set_rect(RTGUI_WIDGET(textview), rect);
+
+		/* calculate line width and line page count */
+		_calc_width(textview);
+
+		/* set text */
+		_calc_line(textview, text);
+    }
+
+    return textview;
+}
+
+void rtgui_textview_destroy(rtgui_textview_t* textview)
+{
+	rtgui_widget_destroy(RTGUI_WIDGET(textview));
+}
+
+void rtgui_textview_set_text(rtgui_textview_t* textview, const char* text)
+{
+	RT_ASSERT(textview != RT_NULL);
+
+	/* calculate line width and line page count */
+	_calc_width(textview);
+
+	/* set text */
+	_calc_line(textview, text);
+
+	/* update widget */
+	rtgui_widget_update(RTGUI_WIDGET(textview));
+}

+ 24 - 56
components/rtgui/widgets/toplevel.c

@@ -13,26 +13,25 @@
  */
  */
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/widgets/toplevel.h>
 #include <rtgui/widgets/toplevel.h>
-extern void rtgui_topwin_do_clip(rtgui_widget_t* widget);
+#include <rtgui/widgets/window.h>
+#include <rtgui/widgets/title.h>
 
 
 static void _rtgui_toplevel_constructor(rtgui_toplevel_t *toplevel)
 static void _rtgui_toplevel_constructor(rtgui_toplevel_t *toplevel)
 {
 {
 	/* set event handler */
 	/* set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(toplevel), rtgui_toplevel_event_handler);
+	rtgui_object_set_event_handler(RTGUI_OBJECT(toplevel), rtgui_toplevel_event_handler);
 
 
 	/* set toplevel to self */
 	/* set toplevel to self */
-	RTGUI_WIDGET(toplevel)->toplevel = RTGUI_WIDGET(toplevel);
+	if (RTGUI_IS_WINTITLE(toplevel))
+		RTGUI_WIDGET(toplevel)->toplevel = (struct rtgui_win*)toplevel;
+	else
+		RTGUI_WIDGET(toplevel)->toplevel = RTGUI_WIN(toplevel);
 
 
 	/* init toplevel property */
 	/* init toplevel property */
 	toplevel->drawing = 0;
 	toplevel->drawing = 0;
 
 
 	/* hide toplevel default */
 	/* hide toplevel default */
 	RTGUI_WIDGET_HIDE(RTGUI_WIDGET(toplevel));
 	RTGUI_WIDGET_HIDE(RTGUI_WIDGET(toplevel));
-
-	/* set server as RT_NULL (no connected) */
-	toplevel->server = RT_NULL;
-	/* initialize last mouse event handled widget */
-	toplevel->last_mevent_widget = RT_NULL;
 }
 }
 
 
 static void _rtgui_toplevel_destructor(rtgui_toplevel_t* toplevel)
 static void _rtgui_toplevel_destructor(rtgui_toplevel_t* toplevel)
@@ -41,51 +40,35 @@ static void _rtgui_toplevel_destructor(rtgui_toplevel_t* toplevel)
 	toplevel->drawing = 0;
 	toplevel->drawing = 0;
 }
 }
 
 
-DEFINE_CLASS_TYPE(toplevel, "toplevel", 
+DEFINE_CLASS_TYPE(toplevel, "toplevel",
 	RTGUI_CONTAINER_TYPE,
 	RTGUI_CONTAINER_TYPE,
 	_rtgui_toplevel_constructor,
 	_rtgui_toplevel_constructor,
 	_rtgui_toplevel_destructor,
 	_rtgui_toplevel_destructor,
 	sizeof(struct rtgui_toplevel));
 	sizeof(struct rtgui_toplevel));
 
 
-rt_bool_t rtgui_toplevel_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
+rt_bool_t rtgui_toplevel_event_handler(struct rtgui_object* object, rtgui_event_t* event)
 {
 {
-	rtgui_toplevel_t* toplevel = (rtgui_toplevel_t*)widget;
+	struct rtgui_toplevel* toplevel;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	toplevel = RTGUI_TOPLEVEL(object);
 
 
 	switch (event->type)
 	switch (event->type)
 	{
 	{
-	case RTGUI_EVENT_KBD:
-		if (RTGUI_CONTAINER(toplevel)->focused != RT_NULL)
-		{
-			RTGUI_CONTAINER(toplevel)->focused->event_handler(RTGUI_CONTAINER(toplevel)->focused, event);
-		}
-		break;
-
 	case RTGUI_EVENT_CLIP_INFO:
 	case RTGUI_EVENT_CLIP_INFO:
 		/* update toplevel clip */
 		/* update toplevel clip */
 		rtgui_toplevel_update_clip(toplevel);
 		rtgui_toplevel_update_clip(toplevel);
 		break;
 		break;
 
 
-	case RTGUI_EVENT_TIMER:
-		{
-			struct rtgui_timer* timer;
-			struct rtgui_event_timer* etimer = (struct rtgui_event_timer*) event;
-
-			timer = etimer->timer;
-			if (timer->timeout != RT_NULL)
-			{
-				/* call timeout function */
-				timer->timeout(timer, timer->user_data);
-			}
-		}
-		break;
-
 	case RTGUI_EVENT_COMMAND:
 	case RTGUI_EVENT_COMMAND:
-		if (rtgui_container_dispatch_event(RTGUI_CONTAINER(widget), event) != RT_TRUE)
+		if (rtgui_container_dispatch_event(RTGUI_CONTAINER(object), event) != RT_TRUE)
 		{
 		{
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
-			if (widget->on_command != RT_NULL)
+			if (RTGUI_WIDGET(object)->on_command != RT_NULL)
 			{
 			{
-				widget->on_command(widget, event);
+				RTGUI_WIDGET(object)->on_command(object, event);
 			}
 			}
 #endif
 #endif
 		}
 		}
@@ -93,38 +76,23 @@ rt_bool_t rtgui_toplevel_event_handler(rtgui_widget_t* widget, rtgui_event_t* ev
 		break;
 		break;
 
 
 	default :
 	default :
-		return rtgui_container_event_handler(widget, event);
+		return rtgui_container_event_handler(object, event);
 	}
 	}
 
 
 	return RT_FALSE;
 	return RT_FALSE;
 }
 }
 
 
-#include <rtgui/driver.h> /* to get screen rect */
-
 void rtgui_toplevel_update_clip(rtgui_toplevel_t* top)
 void rtgui_toplevel_update_clip(rtgui_toplevel_t* top)
 {
 {
-	rtgui_container_t* container;
+	rtgui_container_t* view;
 	struct rtgui_list_node* node;
 	struct rtgui_list_node* node;
-	rtgui_rect_t screen_rect;
-
-	if (top == RT_NULL) return;
-
-	/* reset toplevel widget clip to extent */
-	rtgui_region_reset(&(RTGUI_WIDGET(top)->clip), &(RTGUI_WIDGET(top)->extent));
-
-	/* subtract the screen rect */
-	screen_rect.x1 = screen_rect.y1 = 0;
-	screen_rect.x2 = rtgui_graphic_driver_get_default()->width;
-	screen_rect.y2 = rtgui_graphic_driver_get_default()->height;
-	rtgui_region_intersect_rect(&(RTGUI_WIDGET(top)->clip), &(RTGUI_WIDGET(top)->clip),
-		&screen_rect);
 
 
-	/* subtract the external rect */
-	rtgui_topwin_do_clip(RTGUI_WIDGET(top));
+	if (top == RT_NULL)
+		return;
 
 
 	/* update the clip info of each child */
 	/* update the clip info of each child */
-	container = RTGUI_CONTAINER(top);
-	rtgui_list_foreach(node, &(container->children))
+	view = RTGUI_CONTAINER(top);
+	rtgui_list_foreach(node, &(view->children))
 	{
 	{
 		rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
 		rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
 
 

+ 0 - 214
components/rtgui/widgets/view.c

@@ -1,214 +0,0 @@
-/*
- * File      : view.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-16     Bernard      first version
- * 2010-09-24     Bernard      fix view destroy issue
- */
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/view.h>
-#include <rtgui/widgets/workbench.h>
-
-static void _rtgui_view_constructor(rtgui_view_t *view)
-{
-	/* init view */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(view),
-		rtgui_view_event_handler);
-
-	view->modal_show = RT_FALSE;
-	view->title = RT_NULL;
-}
-
-static void _rtgui_view_destructor(rtgui_view_t *view)
-{
-	/* remove view from workbench */
-	if (RTGUI_WIDGET(view)->parent != RT_NULL)
-	{
-		rtgui_workbench_t *workbench;
-
-		if (view->modal_show == RT_TRUE)
-			rtgui_view_end_modal(view, RTGUI_MODAL_CANCEL);
-
-		workbench = RTGUI_WORKBENCH(RTGUI_WIDGET(view)->parent);
-		rtgui_workbench_remove_view(workbench, view);
-	}
-
-	if (view->title != RT_NULL)
-	{
-		rt_free(view->title);
-		view->title = RT_NULL;
-	}
-}
-
-DEFINE_CLASS_TYPE(view, "view", 
-	RTGUI_CONTAINER_TYPE,
-	_rtgui_view_constructor,
-	_rtgui_view_destructor,
-	sizeof(struct rtgui_view));
-
-rt_bool_t rtgui_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
-	struct rtgui_view* view = (struct rtgui_view*) widget;
-	RT_ASSERT(widget != RT_NULL);
-
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PAINT:
-		{
-			struct rtgui_dc* dc;
-			struct rtgui_rect rect;
-
-			dc = rtgui_dc_begin_drawing(widget);
-			if (dc == RT_NULL) return RT_FALSE;
-			rtgui_widget_get_rect(widget, &rect);
-
-			/* fill view with background */
-			rtgui_dc_fill_rect(dc, &rect);
-
-			/* paint on each child */
-			rtgui_container_dispatch_event(RTGUI_CONTAINER(view), event);
-
-			rtgui_dc_end_drawing(dc);
-		}
-		break;
-
-	default:
-		return rtgui_container_event_handler(widget, event);
-	}
-
-	return RT_FALSE;
-}
-
-rtgui_view_t* rtgui_view_create(const char* title)
-{
-	struct rtgui_view* view;
-
-	/* allocate view */
-	view = (struct rtgui_view*) rtgui_widget_create (RTGUI_VIEW_TYPE);
-	if (view != RT_NULL)
-	{
-		if (title != RT_NULL)
-			view->title = rt_strdup(title);
-	}
-
-	return view;
-}
-
-void rtgui_view_destroy(rtgui_view_t* view)
-{
-	if (view->modal_show == RT_TRUE)
-		rtgui_view_end_modal(view, RTGUI_MODAL_CANCEL);
-	else
-	{
-		rtgui_view_hide(view);
-		rtgui_widget_destroy(RTGUI_WIDGET(view));
-	}
-}
-
-#ifndef RTGUI_USING_SMALL_SIZE
-void rtgui_view_set_box(rtgui_view_t* view, rtgui_box_t* box)
-{
-	if (view == RT_NULL ||
-		box  == RT_NULL) return;
-
-	rtgui_container_add_child(RTGUI_CONTAINER(view), RTGUI_WIDGET(box));
-	rtgui_widget_set_rect(RTGUI_WIDGET(box), &(RTGUI_WIDGET(view)->extent));
-}
-#endif
-
-rtgui_modal_code_t rtgui_view_show(rtgui_view_t* view, rt_bool_t is_modal)
-{
-	rtgui_workbench_t* workbench;
-
-	/* parameter check */
-	if (view == RT_NULL) return RTGUI_MODAL_CANCEL;
-
-	if (RTGUI_WIDGET(view)->parent == RT_NULL)
-	{
-		RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(view));
-		return RTGUI_MODAL_CANCEL;
-	}
-
-	workbench = RTGUI_WORKBENCH(RTGUI_WIDGET(view)->parent);
-	rtgui_workbench_show_view(workbench, view);
-	if (RTGUI_CONTAINER(view)->focused != RT_NULL)
-		rtgui_widget_focus(RTGUI_CONTAINER(view)->focused);
-	else
-	{
-		if (RTGUI_WIDGET_IS_FOCUSABLE(RTGUI_WIDGET(view)))
-			rtgui_widget_focus(RTGUI_WIDGET(view));
-	}
-
-	view->modal_show = is_modal;
-	if (is_modal == RT_TRUE)
-	{
-		/* set modal mode */
-		workbench->flag |= RTGUI_WORKBENCH_FLAG_MODAL_MODE;
-		workbench->modal_widget = RTGUI_WIDGET(view);
-
-		/* perform workbench event loop */
-		rtgui_workbench_event_loop(workbench);
-
-		workbench->modal_widget = RT_NULL;
-		return workbench->modal_code;
-	}
-
-	/* no modal mode, always return modal_ok */
-	return RTGUI_MODAL_OK;
-}
-
-void rtgui_view_end_modal(rtgui_view_t* view, rtgui_modal_code_t modal_code)
-{
-	rtgui_workbench_t* workbench;
-
-	/* parameter check */
-	if ((view == RT_NULL) || (RTGUI_WIDGET(view)->parent == RT_NULL))return ;
-
-	workbench = RTGUI_WORKBENCH(RTGUI_WIDGET(view)->parent);
-	workbench->modal_code = modal_code;
-	workbench->flag &= ~RTGUI_WORKBENCH_FLAG_MODAL_MODE;
-
-	/* remove modal mode */
-	view->modal_show = RT_FALSE;
-}
-
-void rtgui_view_hide(rtgui_view_t* view)
-{
-	if (view == RT_NULL) return;
-
-	if (RTGUI_WIDGET(view)->parent == RT_NULL)
-	{
-		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(view));
-		return;
-	}
-
-	rtgui_workbench_hide_view((rtgui_workbench_t*)(RTGUI_WIDGET(view)->parent), view);
-}
-
-char* rtgui_view_get_title(rtgui_view_t* view)
-{
-	RT_ASSERT(view != RT_NULL);
-
-	return view->title;
-}
-
-void rtgui_view_set_title(rtgui_view_t* view, const char *title)
-{
-	RT_ASSERT(view != RT_NULL);
-
-	if (view->title != RT_NULL)
-	{
-		rtgui_free(view->title);
-
-		if (title != RT_NULL) view->title = rt_strdup(title);
-		else view->title = RT_NULL;
-	}
-}

+ 88 - 64
components/rtgui/widgets/widget.c

@@ -14,10 +14,11 @@
  */
  */
 
 
 #include <rtgui/dc_client.h>
 #include <rtgui/dc_client.h>
+#include <rtgui/rtgui_application.h>
 #include <rtgui/widgets/widget.h>
 #include <rtgui/widgets/widget.h>
 #include <rtgui/widgets/window.h>
 #include <rtgui/widgets/window.h>
-#include <rtgui/widgets/view.h>
-extern void rtgui_topwin_do_clip(rtgui_widget_t* widget);
+#include <rtgui/widgets/container.h>
+#include <rtgui/widgets/notebook.h>
 
 
 static void _rtgui_widget_constructor(rtgui_widget_t *widget)
 static void _rtgui_widget_constructor(rtgui_widget_t *widget)
 {
 {
@@ -40,23 +41,25 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget)
 #endif
 #endif
 
 
 	/* set parent and toplevel root */
 	/* set parent and toplevel root */
-	widget->parent			= RT_NULL;
-	widget->toplevel		= RT_NULL;
+	widget->parent        = RT_NULL;
+	widget->toplevel      = RT_NULL;
 
 
 	/* some common event handler */
 	/* some common event handler */
-	widget->on_focus_in		= RT_NULL;
-	widget->on_focus_out	= RT_NULL;
+	widget->on_focus_in   = RT_NULL;
+	widget->on_focus_out  = RT_NULL;
+	widget->on_show       = RT_NULL;
+	widget->on_hide       = RT_NULL;
 
 
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
-	widget->on_draw 		= RT_NULL;
-	widget->on_mouseclick 	= RT_NULL;
-	widget->on_key 			= RT_NULL;
-	widget->on_size 		= RT_NULL;
-	widget->on_command 		= RT_NULL;
+	widget->on_draw       = RT_NULL;
+	widget->on_mouseclick = RT_NULL;
+	widget->on_key        = RT_NULL;
+	widget->on_size       = RT_NULL;
+	widget->on_command    = RT_NULL;
 #endif
 #endif
 
 
 	/* set default event handler */
 	/* set default event handler */
-	rtgui_widget_set_event_handler(widget,rtgui_widget_event_handler);
+	rtgui_object_set_event_handler(RTGUI_OBJECT(widget), rtgui_widget_event_handler);
 
 
 	/* init user data private to 0 */
 	/* init user data private to 0 */
 	widget->user_data = 0;
 	widget->user_data = 0;
@@ -203,13 +206,6 @@ void rtgui_widget_move_to_logic(rtgui_widget_t* widget, int dx, int dy)
 	}
 	}
 }
 }
 
 
-void rtgui_widget_set_event_handler(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
-{
-	RT_ASSERT(widget != RT_NULL);
-
-	widget->event_handler = handler;
-}
-
 void rtgui_widget_get_rect(rtgui_widget_t* widget, rtgui_rect_t *rect)
 void rtgui_widget_get_rect(rtgui_widget_t* widget, rtgui_rect_t *rect)
 {
 {
 	RT_ASSERT(widget != RT_NULL);
 	RT_ASSERT(widget != RT_NULL);
@@ -236,6 +232,20 @@ void rtgui_widget_set_onunfocus(rtgui_widget_t* widget, rtgui_event_handler_ptr
 	widget->on_focus_out = handler;
 	widget->on_focus_out = handler;
 }
 }
 
 
+void rtgui_widget_set_onshow(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
+{
+	RT_ASSERT(widget != RT_NULL);
+
+	widget->on_show = handler;
+}
+
+void rtgui_widget_set_onhide(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
+{
+	RT_ASSERT(widget != RT_NULL);
+
+	widget->on_hide = handler;
+}
+
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
 void rtgui_widget_set_ondraw(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
 void rtgui_widget_set_ondraw(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
 {
 {
@@ -280,35 +290,28 @@ void rtgui_widget_set_oncommand(rtgui_widget_t* widget, rtgui_event_handler_ptr
  */
  */
 void rtgui_widget_focus(rtgui_widget_t *widget)
 void rtgui_widget_focus(rtgui_widget_t *widget)
 {
 {
-	rtgui_container_t *parent;
+	struct rtgui_widget *old_focus;
 
 
 	RT_ASSERT(widget != RT_NULL);
 	RT_ASSERT(widget != RT_NULL);
 
 
-	if (!widget->parent || !widget->toplevel) return;
 	if (!RTGUI_WIDGET_IS_FOCUSABLE(widget) || !RTGUI_WIDGET_IS_ENABLE(widget))
 	if (!RTGUI_WIDGET_IS_FOCUSABLE(widget) || !RTGUI_WIDGET_IS_ENABLE(widget))
 		return;
 		return;
 
 
-	/* set widget as focused */
-	widget->flag |= RTGUI_WIDGET_FLAG_FOCUS;
-
-	/* get root parent container and old focused widget */
-	parent = RTGUI_CONTAINER(widget->toplevel);
-	if (parent->focused == widget) return ; /* it's the same focused widget */
+	old_focus = RTGUI_WIN(widget->toplevel)->focused_widget;
+	if (old_focus == widget)
+		return; /* it's the same focused widget */
 
 
 	/* unfocused the old widget */
 	/* unfocused the old widget */
-	if (parent->focused != RT_NULL)	rtgui_widget_unfocus(parent->focused);
+	if (old_focus != RT_NULL)
+		rtgui_widget_unfocus(old_focus);
 
 
-	/* set widget as focused widget in parent link */
-	parent = RTGUI_CONTAINER(widget->parent);
-	do 
-	{
-		parent->focused = widget;
-		parent = RTGUI_CONTAINER(RTGUI_WIDGET(parent)->parent);
-	} while ((parent != RT_NULL) && !RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(parent)));
+	/* set widget as focused */
+	widget->flag |= RTGUI_WIDGET_FLAG_FOCUS;
+	RTGUI_WIN(widget->toplevel)->focused_widget = widget;
 
 
 	/* invoke on focus in call back */
 	/* invoke on focus in call back */
 	if (widget->on_focus_in != RT_NULL)
 	if (widget->on_focus_in != RT_NULL)
-   		widget->on_focus_in(widget, RT_NULL);
+		widget->on_focus_in(RTGUI_OBJECT(widget), RT_NULL);
 }
 }
 
 
 /**
 /**
@@ -317,6 +320,7 @@ void rtgui_widget_focus(rtgui_widget_t *widget)
  */
  */
 void rtgui_widget_unfocus(rtgui_widget_t *widget)
 void rtgui_widget_unfocus(rtgui_widget_t *widget)
 {
 {
+
 	RT_ASSERT(widget != RT_NULL);
 	RT_ASSERT(widget != RT_NULL);
 
 
 	if (!widget->toplevel || !RTGUI_WIDGET_IS_FOCUSED(widget))
 	if (!widget->toplevel || !RTGUI_WIDGET_IS_FOCUSED(widget))
@@ -325,7 +329,9 @@ void rtgui_widget_unfocus(rtgui_widget_t *widget)
 	widget->flag &= ~RTGUI_WIDGET_FLAG_FOCUS;
 	widget->flag &= ~RTGUI_WIDGET_FLAG_FOCUS;
 
 
 	if (widget->on_focus_out != RT_NULL)
 	if (widget->on_focus_out != RT_NULL)
-   		widget->on_focus_out(widget, RT_NULL);
+		widget->on_focus_out(RTGUI_OBJECT(widget), RT_NULL);
+
+	RTGUI_WIN(widget->toplevel)->focused_widget = RT_NULL;
 
 
 	/* refresh widget */
 	/* refresh widget */
 	rtgui_widget_update(widget);
 	rtgui_widget_update(widget);
@@ -381,47 +387,62 @@ void rtgui_widget_rect_to_logic(rtgui_widget_t* widget, rtgui_rect_t* rect)
 	}
 	}
 }
 }
 
 
-rtgui_widget_t* rtgui_widget_get_toplevel(rtgui_widget_t* widget)
+struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget)
 {
 {
 	rtgui_widget_t* r;
 	rtgui_widget_t* r;
 
 
 	RT_ASSERT(widget != RT_NULL);
 	RT_ASSERT(widget != RT_NULL);
 
 
-	if (widget->toplevel) return widget->toplevel;
+	if (widget->toplevel)
+		return widget->toplevel;
 
 
+	rt_kprintf("widget->toplevel not properly set\n");
 	r = widget;
 	r = widget;
 	/* get the toplevel widget */
 	/* get the toplevel widget */
-	while (r->parent != RT_NULL) r = r->parent;
+	while (r->parent != RT_NULL)
+		r = r->parent;
 
 
 	/* set toplevel */
 	/* set toplevel */
-	widget->toplevel = r;
+	widget->toplevel = RTGUI_WIN(r);
 
 
-	return r;
+	return RTGUI_WIN(r);
 }
 }
 
 
-rt_bool_t rtgui_widget_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
+rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* event)
 {
 {
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
+	struct rtgui_widget *widget;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
+
+	widget = RTGUI_WIDGET(object);
+
 	switch (event->type)
 	switch (event->type)
 	{
 	{
 	case RTGUI_EVENT_PAINT:
 	case RTGUI_EVENT_PAINT:
-		if (widget->on_draw != RT_NULL) return widget->on_draw(widget, event);
+		if (widget->on_draw != RT_NULL)
+			return widget->on_draw(RTGUI_OBJECT(widget), event);
 		break;
 		break;
 
 
 	case RTGUI_EVENT_KBD:
 	case RTGUI_EVENT_KBD:
-		if (widget->on_key != RT_NULL) return widget->on_key(widget, event);
+		if (widget->on_key != RT_NULL)
+			return widget->on_key(RTGUI_OBJECT(widget), event);
 		break;
 		break;
 
 
 	case RTGUI_EVENT_MOUSE_BUTTON:
 	case RTGUI_EVENT_MOUSE_BUTTON:
-		if (widget->on_mouseclick != RT_NULL) return widget->on_mouseclick(widget, event);
+		if (widget->on_mouseclick != RT_NULL)
+			return widget->on_mouseclick(RTGUI_OBJECT(widget), event);
 		break;
 		break;
 
 
 	case RTGUI_EVENT_COMMAND:
 	case RTGUI_EVENT_COMMAND:
-		if (widget->on_command != RT_NULL) return widget->on_command(widget, event);
+		if (widget->on_command != RT_NULL)
+			return widget->on_command(RTGUI_OBJECT(widget), event);
 		break;
 		break;
 
 
 	case RTGUI_EVENT_RESIZE:
 	case RTGUI_EVENT_RESIZE:
-		if (widget->on_size != RT_NULL) return widget->on_size(widget, event);
+		if (widget->on_size != RT_NULL)
+			return widget->on_size(RTGUI_OBJECT(widget), event);
 		break;
 		break;
 	}
 	}
 #endif
 #endif
@@ -441,14 +462,9 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
 	if (widget == RT_NULL || RTGUI_WIDGET_IS_HIDE(widget)) return;
 	if (widget == RT_NULL || RTGUI_WIDGET_IS_HIDE(widget)) return;
 
 
 	parent = widget->parent;
 	parent = widget->parent;
-	/* if there is no parent, do not update clip (please use toplevel widget API) */
+	/* if there is no parent, there is no clip to update. */
 	if (parent == RT_NULL)
 	if (parent == RT_NULL)
 	{
 	{
-		if (RTGUI_IS_TOPLEVEL(widget))
-		{
-			/* if it's toplevel widget, update it by toplevel function */
-			rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(widget));
-		}
 		return;
 		return;
 	}
 	}
 
 
@@ -479,7 +495,7 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
 	 * intersect.
 	 * intersect.
 	 */
 	 */
 
 
-	/* if it's a container object, update the clip info of children */
+	/* if it's a view object, update the clip info of children */
 	if (RTGUI_IS_CONTAINER(widget))
 	if (RTGUI_IS_CONTAINER(widget))
 	{
 	{
 		rtgui_widget_t* child;
 		rtgui_widget_t* child;
@@ -490,17 +506,25 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
 			rtgui_widget_update_clip(child);
 			rtgui_widget_update_clip(child);
 		}
 		}
 	}
 	}
+	else if (RTGUI_IS_NOTEBOOK(widget))
+	{
+		rtgui_widget_update_clip(rtgui_notebook_get_current(RTGUI_NOTEBOOK(widget)));
+	}
 }
 }
 
 
 void rtgui_widget_show(rtgui_widget_t* widget)
 void rtgui_widget_show(rtgui_widget_t* widget)
 {
 {
 	/* there is no parent or the parent is hide, no show at all */
 	/* there is no parent or the parent is hide, no show at all */
 	if (widget->parent == RT_NULL ||
 	if (widget->parent == RT_NULL ||
-		RTGUI_WIDGET_IS_HIDE(widget->parent)) return;
+			RTGUI_WIDGET_IS_HIDE(widget->parent))
+		return;
 
 
 	/* update the clip info of widget */
 	/* update the clip info of widget */
 	RTGUI_WIDGET_UNHIDE(widget);
 	RTGUI_WIDGET_UNHIDE(widget);
 	rtgui_widget_update_clip(widget);
 	rtgui_widget_update_clip(widget);
+
+	if (widget->on_show != RT_NULL)
+		widget->on_show(RTGUI_OBJECT(widget), RT_NULL);
 }
 }
 
 
 void rtgui_widget_hide(rtgui_widget_t* widget)
 void rtgui_widget_hide(rtgui_widget_t* widget)
@@ -521,10 +545,10 @@ void rtgui_widget_hide(rtgui_widget_t* widget)
 
 
 		/* union widget rect */
 		/* union widget rect */
 		rtgui_region_union_rect(&(parent->clip), &(parent->clip), &(widget->extent));
 		rtgui_region_union_rect(&(parent->clip), &(parent->clip), &(widget->extent));
-
-		/* subtract the external rect */
-		rtgui_topwin_do_clip(RTGUI_WIDGET(parent));
 	}
 	}
+
+	if (widget->on_hide != RT_NULL)
+		widget->on_hide(RTGUI_OBJECT(widget), RT_NULL);
 }
 }
 
 
 rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t* widget)
 rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t* widget)
@@ -567,9 +591,11 @@ void rtgui_widget_update(rtgui_widget_t* widget)
 
 
 	RT_ASSERT(widget != RT_NULL);
 	RT_ASSERT(widget != RT_NULL);
 
 
-	if (widget->event_handler != RT_NULL)
+	if (RTGUI_OBJECT(widget)->event_handler != RT_NULL)
 	{
 	{
-		widget->event_handler(widget, &paint.parent);
+		RTGUI_OBJECT(widget)->event_handler(
+				RTGUI_OBJECT(widget),
+				&paint.parent);
 	}
 	}
 }
 }
 
 
@@ -617,11 +643,9 @@ void rtgui_widget_dump(rtgui_widget_t* widget)
 	obj = RTGUI_OBJECT(widget);
 	obj = RTGUI_OBJECT(widget);
 	rt_kprintf("widget type: %s ", obj->type->name);
 	rt_kprintf("widget type: %s ", obj->type->name);
 
 
-	if (RTGUI_IS_VIEW(widget) == RT_TRUE)
-		rt_kprintf(":%s ", RTGUI_VIEW(widget)->title);
 	if (RTGUI_IS_WIN(widget) == RT_TRUE)
 	if (RTGUI_IS_WIN(widget) == RT_TRUE)
 		rt_kprintf(":%s ", RTGUI_WIN(widget)->title);
 		rt_kprintf(":%s ", RTGUI_WIN(widget)->title);
-	if ((RTGUI_IS_LABEL(widget) == RT_TRUE) || (RTGUI_IS_BUTTON(widget) == RT_TRUE))
+	else if ((RTGUI_IS_LABEL(widget) == RT_TRUE) || (RTGUI_IS_BUTTON(widget) == RT_TRUE))
 		rt_kprintf(":%s ", RTGUI_LABEL(widget)->text);
 		rt_kprintf(":%s ", RTGUI_LABEL(widget)->text);
 
 
 	rt_kprintf("extent(%d, %d) - (%d, %d)\n", widget->extent.x1, 
 	rt_kprintf("extent(%d, %d) - (%d, %d)\n", widget->extent.x1, 

+ 258 - 300
components/rtgui/widgets/window.c

@@ -15,27 +15,37 @@
 #include <rtgui/color.h>
 #include <rtgui/color.h>
 #include <rtgui/image.h>
 #include <rtgui/image.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_server.h>
+#include <rtgui/rtgui_application.h>
 
 
 #include <rtgui/widgets/window.h>
 #include <rtgui/widgets/window.h>
 #include <rtgui/widgets/button.h>
 #include <rtgui/widgets/button.h>
-#include <rtgui/widgets/workbench.h>
 
 
 static void _rtgui_win_constructor(rtgui_win_t *win)
 static void _rtgui_win_constructor(rtgui_win_t *win)
 {
 {
+	RTGUI_WIDGET(win)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+	win->parent_window = RT_NULL;
 	/* init window attribute */
 	/* init window attribute */
-	win->on_activate	= RT_NULL;
-	win->on_deactivate	= RT_NULL;
-	win->on_close		= RT_NULL;
-	win->title			= RT_NULL;
-	win->modal_code		= RTGUI_MODAL_OK;
-	win->modal_widget	= RT_NULL;
+	win->on_activate   = RT_NULL;
+	win->on_deactivate = RT_NULL;
+	win->on_close      = RT_NULL;
+	win->on_key        = RT_NULL;
+	win->title         = RT_NULL;
+	win->modal_code    = RTGUI_MODAL_OK;
+
+	/* initialize last mouse event handled widget */
+	win->last_mevent_widget = RT_NULL;
+	win->focused_widget	= RT_NULL;
 
 
 	/* set window hide */
 	/* set window hide */
 	RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
 	RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
 
 
 	/* set window style */
 	/* set window style */
 	win->style = RTGUI_WIN_STYLE_DEFAULT;
 	win->style = RTGUI_WIN_STYLE_DEFAULT;
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(win), rtgui_win_event_handler);
+
+	win->flag  = RTGUI_WIN_FLAG_INIT;
+
+	rtgui_object_set_event_handler(RTGUI_OBJECT(win), rtgui_win_event_handler);
 
 
 	/* init user data */
 	/* init user data */
 	win->user_data = 0;
 	win->user_data = 0;
@@ -45,12 +55,12 @@ static void _rtgui_win_destructor(rtgui_win_t* win)
 {
 {
 	struct rtgui_event_win_destroy edestroy;
 	struct rtgui_event_win_destroy edestroy;
 
 
-	if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+	if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
 	{
 	{
 		/* destroy in server */
 		/* destroy in server */
 		RTGUI_EVENT_WIN_DESTROY_INIT(&edestroy);
 		RTGUI_EVENT_WIN_DESTROY_INIT(&edestroy);
 		edestroy.wid = win;
 		edestroy.wid = win;
-		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&edestroy),
+		if (rtgui_server_post_event_sync(RTGUI_EVENT(&edestroy),
 			sizeof(struct rtgui_event_win_destroy)) != RT_EOK)
 			sizeof(struct rtgui_event_win_destroy)) != RT_EOK)
 		{
 		{
 			/* destroy in server failed */
 			/* destroy in server failed */
@@ -62,225 +72,238 @@ static void _rtgui_win_destructor(rtgui_win_t* win)
 	rt_free(win->title);
 	rt_free(win->title);
 }
 }
 
 
-static rt_bool_t _rtgui_win_create_in_server(rtgui_win_t* win)
+static rt_bool_t _rtgui_win_create_in_server(struct rtgui_win *win)
 {
 {
-	if (RTGUI_TOPLEVEL(win)->server == RT_NULL)
+	if (!(win->flag & RTGUI_WIN_FLAG_CONNECTED))
 	{
 	{
-		rt_thread_t server;
 		struct rtgui_event_win_create ecreate;
 		struct rtgui_event_win_create ecreate;
 		RTGUI_EVENT_WIN_CREATE_INIT(&ecreate);
 		RTGUI_EVENT_WIN_CREATE_INIT(&ecreate);
 
 
-		/* get server thread id */
-		server = rtgui_thread_get_server();
-		if (server == RT_NULL)
-		{
-			rt_kprintf("RTGUI server is not running...\n");
-			return RT_FALSE;
-		}
-
 		/* send win create event to server */
 		/* send win create event to server */
-		ecreate.wid 		= win;
-		ecreate.parent.user	= win->style;
+		ecreate.parent_window = win->parent_window;
+		ecreate.wid           = win;
+		ecreate.parent.user	  = win->style;
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
-		ecreate.extent 		= RTGUI_WIDGET(win)->extent;
+		ecreate.extent        = RTGUI_WIDGET(win)->extent;
 		rt_strncpy((char*)ecreate.title, (char*)win->title, RTGUI_NAME_MAX);
 		rt_strncpy((char*)ecreate.title, (char*)win->title, RTGUI_NAME_MAX);
 #endif
 #endif
 
 
-		if (rtgui_thread_send_sync(server, RTGUI_EVENT(&ecreate),
-			sizeof(struct rtgui_event_win_create)) != RT_EOK)
+		if (rtgui_server_post_event_sync(RTGUI_EVENT(&ecreate),
+										 sizeof(struct rtgui_event_win_create)
+				) != RT_EOK)
 		{
 		{
 			rt_kprintf("create win: %s failed\n", win->title);
 			rt_kprintf("create win: %s failed\n", win->title);
 			return RT_FALSE;
 			return RT_FALSE;
 		}
 		}
 
 
-		/* set server */
-		RTGUI_TOPLEVEL(win)->server = server;
+		win->flag |= RTGUI_WIN_FLAG_CONNECTED;
 	}
 	}
 
 
 	return RT_TRUE;
 	return RT_TRUE;
 }
 }
 
 
-DEFINE_CLASS_TYPE(win, "win", 
+DEFINE_CLASS_TYPE(win, "win",
 	RTGUI_TOPLEVEL_TYPE,
 	RTGUI_TOPLEVEL_TYPE,
 	_rtgui_win_constructor,
 	_rtgui_win_constructor,
 	_rtgui_win_destructor,
 	_rtgui_win_destructor,
 	sizeof(struct rtgui_win));
 	sizeof(struct rtgui_win));
 
 
-rtgui_win_t* rtgui_win_create(rtgui_toplevel_t* parent_toplevel, const char* title, rtgui_rect_t *rect, rt_uint8_t style)
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+static struct rtgui_win *the_desktop_window;
+#endif
+
+rtgui_win_t* rtgui_win_create(struct rtgui_win* parent_window,
+		                      const char* title,
+							  rtgui_rect_t *rect,
+							  rt_uint16_t style)
 {
 {
 	struct rtgui_win* win;
 	struct rtgui_win* win;
 
 
 	/* allocate win memory */
 	/* allocate win memory */
-	win = (struct rtgui_win*) rtgui_widget_create (RTGUI_WIN_TYPE);
-	if (win != RT_NULL)
+	win = RTGUI_WIN(rtgui_widget_create(RTGUI_WIN_TYPE));
+	if (win == RT_NULL)
+		return RT_NULL;
+
+	/* set parent toplevel */
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+	if (style & RTGUI_WIN_STYLE_DESKTOP)
 	{
 	{
-		/* set parent toplevel */
-		win->parent_toplevel = parent_toplevel;
+		RT_ASSERT(the_desktop_window == RT_NULL);
+		win->parent_window = RT_NULL;
+		the_desktop_window = win;
+	}
+	else if (parent_window == RT_NULL)
+	{
+		RT_ASSERT(the_desktop_window != RT_NULL);
+		win->parent_window = the_desktop_window;
+	}
+	else
+		win->parent_window = parent_window;
+#else
+	win->parent_window = parent_window;
+#endif
 
 
-		/* set title, rect and style */
-		if (title != RT_NULL) win->title = rt_strdup(title);
-		else win->title = RT_NULL;
+	/* set title, rect and style */
+	if (title != RT_NULL)
+		win->title = rt_strdup(title);
+	else
+		win->title = RT_NULL;
 
 
-		rtgui_widget_set_rect(RTGUI_WIDGET(win), rect);
-		win->style = style;
+	rtgui_widget_set_rect(RTGUI_WIDGET(win), rect);
+	win->style = style;
 
 
-		if (_rtgui_win_create_in_server(win) == RT_FALSE)
-		{
-			rtgui_widget_destroy(RTGUI_WIDGET(win));
-			return RT_NULL;
-		}
+	if (_rtgui_win_create_in_server(win) == RT_FALSE)
+	{
+		goto __on_err;
 	}
 	}
-
 	return win;
 	return win;
+
+__on_err:
+	rtgui_widget_destroy(RTGUI_WIDGET(win));
+	return RT_NULL;
 }
 }
 
 
 void rtgui_win_destroy(struct rtgui_win* win)
 void rtgui_win_destroy(struct rtgui_win* win)
 {
 {
-	if (win->style & RTGUI_WIN_STYLE_MODAL)
+	if (win->flag & RTGUI_WIN_FLAG_MODAL)
 	{
 	{
-		/* end modal */
+		/* set the RTGUI_WIN_STYLE_DESTROY_ON_CLOSE flag so the window will be
+		 * destroyed after the event_loop */
+		win->style |= RTGUI_WIN_STYLE_DESTROY_ON_CLOSE;
 		rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
 		rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
 	}
 	}
 	else
 	else
-	{
 		rtgui_widget_destroy(RTGUI_WIDGET(win));
 		rtgui_widget_destroy(RTGUI_WIDGET(win));
+}
+
+static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win,
+									   struct rtgui_event *event)
+{
+	if (win->on_close != RT_NULL)
+	{
+		if (win->on_close(RTGUI_OBJECT(win), event) == RT_FALSE)
+			return RT_FALSE;
+	}
+
+	rtgui_win_hiden(win);
+
+	win->flag |= RTGUI_WIN_FLAG_CLOSED;
+
+	if (win->flag & RTGUI_WIN_FLAG_MODAL)
+	{
+		rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
 	}
 	}
+	else if (win->style & RTGUI_WIN_STYLE_DESTROY_ON_CLOSE)
+	{
+		rtgui_win_destroy(win);
+	}
+
+	return RT_TRUE;
 }
 }
 
 
-void rtgui_win_close(struct rtgui_win* win)
+/* send a close event to myself to get a consistent behavior */
+rt_bool_t rtgui_win_close(struct rtgui_win* win)
 {
 {
-	win->style |= RTGUI_WIN_STYLE_CLOSED;
+	struct rtgui_event_win_close eclose;
+
+	RTGUI_EVENT_WIN_CLOSE_INIT(&eclose);
+	eclose.wid = win;
+	return _rtgui_win_deal_close(win,
+								 (struct rtgui_event*)&eclose);
 }
 }
 
 
-rtgui_modal_code_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal)
+rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal)
 {
 {
-	rtgui_modal_code_t result;
+	struct rtgui_event_win_show eshow;
+	rt_base_t exit_code = -1;
 
 
-	RT_ASSERT(win != RT_NULL);
-	result = RTGUI_MODAL_CANCEL;
+	RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
+	eshow.wid = win;
+
+	if (win == RT_NULL)
+		return exit_code;
 
 
 	/* if it does not register into server, create it in server */
 	/* if it does not register into server, create it in server */
-	if (RTGUI_TOPLEVEL(win)->server == RT_NULL)
+	if (!(win->flag & RTGUI_WIN_FLAG_CONNECTED))
 	{
 	{
 		if (_rtgui_win_create_in_server(win) == RT_FALSE)
 		if (_rtgui_win_create_in_server(win) == RT_FALSE)
-			return result;
+			return exit_code;
 	}
 	}
 
 
-	if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)))
+	if (rtgui_server_post_event_sync(RTGUI_EVENT(&eshow),
+									 sizeof(struct rtgui_event_win_show)
+			) != RT_EOK)
 	{
 	{
-		/* send show message to server */
-		struct rtgui_event_win_show eshow;
-		RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
-		eshow.wid = win;
+		rt_kprintf("show win failed\n");
+		return exit_code;
+	}
 
 
-		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&eshow),
-			sizeof(struct rtgui_event_win_show)) != RT_EOK)
-		{
-			/* hide window failed */
-			return result;
-		}
+	/* set window unhidden */
+	RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
 
 
-		/* set window unhidden */
-		RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
-	}
-	else rtgui_widget_update(RTGUI_WIDGET(win));
+	if (win->focused_widget == RT_NULL)
+		rtgui_widget_focus(RTGUI_WIDGET(win));
 
 
-	if (is_modal == RT_TRUE)
-	{
-		if (win->parent_toplevel != RT_NULL)
-		{
-			rtgui_widget_t *parent_widget;
+    if (is_modal == RT_TRUE)
+    {
+		struct rtgui_application *app;
+		struct rtgui_event_win_modal_enter emodal;
 
 
-			/* set style */
-			win->style |= RTGUI_WIN_STYLE_MODAL;
+		RTGUI_EVENT_WIN_MODAL_ENTER_INIT(&emodal);
+		emodal.wid = win;
 
 
-			/* get root toplevel */
-			parent_widget = RTGUI_WIDGET(win->parent_toplevel);
-			if (RTGUI_IS_WORKBENCH(parent_widget))
-			{
-				rtgui_workbench_t* workbench;
-				workbench = RTGUI_WORKBENCH(win->parent_toplevel);
-				workbench->flag |= RTGUI_WORKBENCH_FLAG_MODAL_MODE;
-				workbench->modal_widget = RTGUI_WIDGET(win);
-
-				rtgui_workbench_event_loop(workbench);
-				result = workbench->modal_code;
-				workbench->flag &= ~RTGUI_WORKBENCH_FLAG_MODAL_MODE;
-				workbench->modal_widget = RT_NULL;
-			}
-			else if (RTGUI_IS_WIN(parent_widget))
-			{
-				rtgui_win_t* parent_win;
-				parent_win = RTGUI_WIN(win->parent_toplevel);
-				parent_win->style |= RTGUI_WIN_STYLE_UNDER_MODAL;
-				parent_win->modal_widget = RTGUI_WIDGET(win);
-
-				rtgui_win_event_loop(parent_win);
-				result = parent_win->modal_code;
-				parent_win->style &= ~RTGUI_WIN_STYLE_UNDER_MODAL;
-				parent_win->modal_widget = RT_NULL;
-			}
-		}
-		else
-		{
-			/* which is a root window */
-			win->style |= RTGUI_WIN_STYLE_MODAL;
-			rtgui_win_event_loop(win);
+		app = rtgui_application_self();
+		RT_ASSERT(app != RT_NULL);
+
+		win->flag |= RTGUI_WIN_FLAG_MODAL;
+
+		if (rtgui_server_post_event_sync((struct rtgui_event*)&emodal,
+										 sizeof(emodal)) != RT_EOK)
+			return exit_code;
+
+		app->modal_object = RTGUI_OBJECT(win);
+
+		exit_code = rtgui_application_run(app);
 
 
-			result = win->modal_code;
-			win->style &= ~RTGUI_WIN_STYLE_MODAL;
+		app->modal_object = RT_NULL;
+		win->flag &= ~RTGUI_WIN_FLAG_MODAL;
+
+		if (win->style & RTGUI_WIN_STYLE_DESTROY_ON_CLOSE)
+		{
+			rtgui_win_destroy(win);
 		}
 		}
-	}
+    }
 
 
-	return result;
+	return exit_code;
 }
 }
 
 
 void rtgui_win_end_modal(struct rtgui_win* win, rtgui_modal_code_t modal_code)
 void rtgui_win_end_modal(struct rtgui_win* win, rtgui_modal_code_t modal_code)
 {
 {
-	if (win->parent_toplevel != RT_NULL)
-	{
-		if (RTGUI_IS_WORKBENCH(win->parent_toplevel))
-		{
-			rtgui_workbench_t* workbench;
+	if (win == RT_NULL || !(win->flag & RTGUI_WIN_FLAG_MODAL))
+		return;
 
 
-			/* which is shown under workbench */
-			workbench = RTGUI_WORKBENCH(win->parent_toplevel);
-			workbench->modal_code = modal_code;
-			workbench->flag &= ~RTGUI_WORKBENCH_FLAG_MODAL_MODE;
-		}
-		else if (RTGUI_IS_WIN(win->parent_toplevel))
-		{
-			rtgui_win_t* parent_win;
-
-			/* which is shown under win */
-			parent_win = RTGUI_WIN(win->parent_toplevel);
-			parent_win->modal_code = modal_code;
-			parent_win->style &= ~RTGUI_WIN_STYLE_UNDER_MODAL;		
-		}
-	}
-	else
-	{
-		/* which is a stand alone window */
-		win->modal_code = modal_code;
-	}
+	rtgui_application_exit(rtgui_application_self(), modal_code);
 
 
 	/* remove modal mode */
 	/* remove modal mode */
-	win->style &= ~RTGUI_WIN_STYLE_MODAL;
+	win->flag &= ~RTGUI_WIN_FLAG_MODAL;
 }
 }
 
 
 void rtgui_win_hiden(struct rtgui_win* win)
 void rtgui_win_hiden(struct rtgui_win* win)
 {
 {
 	RT_ASSERT(win != RT_NULL);
 	RT_ASSERT(win != RT_NULL);
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+	RT_ASSERT(win != the_desktop_window);
+#endif
 
 
 	if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)) &&
 	if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)) &&
-		RTGUI_TOPLEVEL(win)->server != RT_NULL)
+		win->flag & RTGUI_WIN_FLAG_CONNECTED)
 	{
 	{
 		/* send hidden message to server */
 		/* send hidden message to server */
 		struct rtgui_event_win_hide ehide;
 		struct rtgui_event_win_hide ehide;
 		RTGUI_EVENT_WIN_HIDE_INIT(&ehide);
 		RTGUI_EVENT_WIN_HIDE_INIT(&ehide);
 		ehide.wid = win;
 		ehide.wid = win;
 
 
-		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&ehide),
+		if (rtgui_server_post_event_sync(RTGUI_EVENT(&ehide),
 			sizeof(struct rtgui_event_win_hide)) != RT_EOK)
 			sizeof(struct rtgui_event_win_hide)) != RT_EOK)
 		{
 		{
 			rt_kprintf("hide win: %s failed\n", win->title);
 			rt_kprintf("hide win: %s failed\n", win->title);
@@ -289,7 +312,7 @@ void rtgui_win_hiden(struct rtgui_win* win)
 
 
 		/* set window hide and deactivated */
 		/* set window hide and deactivated */
 		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
 		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
-		win->style &= ~RTGUI_WIN_STYLE_ACTIVATE;
+		win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE;
 	}
 	}
 }
 }
 
 
@@ -297,7 +320,7 @@ rt_bool_t rtgui_win_is_activated(struct rtgui_win* win)
 {
 {
 	RT_ASSERT(win != RT_NULL);
 	RT_ASSERT(win != RT_NULL);
 
 
-	if (win->style & RTGUI_WIN_STYLE_ACTIVATE) return RT_TRUE;
+	if (win->flag & RTGUI_WIN_FLAG_ACTIVATE) return RT_TRUE;
 
 
 	return RT_FALSE;
 	return RT_FALSE;
 }
 }
@@ -307,28 +330,29 @@ void rtgui_win_move(struct rtgui_win* win, int x, int y)
 	struct rtgui_event_win_move emove;
 	struct rtgui_event_win_move emove;
 	RTGUI_EVENT_WIN_MOVE_INIT(&emove);
 	RTGUI_EVENT_WIN_MOVE_INIT(&emove);
 
 
-	if (win == RT_NULL) return;
+	if (win == RT_NULL)
+		return;
+
+	/* move window to logic position */
+	rtgui_widget_move_to_logic(RTGUI_WIDGET(win),
+		x - RTGUI_WIDGET(win)->extent.x1,
+		y - RTGUI_WIDGET(win)->extent.y1);
 
 
-	if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+	if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
 	{
 	{
 		/* set win hide firstly */
 		/* set win hide firstly */
 		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
 		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
 
 
-		emove.wid 	= win;
+		emove.wid	= win;
 		emove.x		= x;
 		emove.x		= x;
 		emove.y		= y;
 		emove.y		= y;
-		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&emove),
+		if (rtgui_server_post_event_sync(RTGUI_EVENT(&emove),
 			sizeof(struct rtgui_event_win_move)) != RT_EOK)
 			sizeof(struct rtgui_event_win_move)) != RT_EOK)
 		{
 		{
 			return;
 			return;
 		}
 		}
 	}
 	}
 
 
-	/* move window to logic position */
-	rtgui_widget_move_to_logic(RTGUI_WIDGET(win),
-		x - RTGUI_WIDGET(win)->extent.x1,
-		y - RTGUI_WIDGET(win)->extent.y1);
-
 	/* set window visible */
 	/* set window visible */
 	RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
 	RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
 	return;
 	return;
@@ -342,7 +366,8 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win* win)
 
 
 	/* begin drawing */
 	/* begin drawing */
 	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(win));
 	dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(win));
-	if (dc == RT_NULL) return RT_FALSE;
+	if (dc == RT_NULL)
+		return RT_FALSE;
 
 
 	/* get window rect */
 	/* get window rect */
 	rtgui_widget_get_rect(RTGUI_WIDGET(win), &rect);
 	rtgui_widget_get_rect(RTGUI_WIDGET(win), &rect);
@@ -352,18 +377,22 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win* win)
 	/* paint each widget */
 	/* paint each widget */
 	RTGUI_EVENT_PAINT_INIT(&event);
 	RTGUI_EVENT_PAINT_INIT(&event);
 	event.wid = RT_NULL;
 	event.wid = RT_NULL;
-	rtgui_container_dispatch_event(RTGUI_CONTAINER(win), (rtgui_event_t*)&event);
+	rtgui_container_dispatch_event(RTGUI_CONTAINER(win),
+								   (rtgui_event_t*)&event);
 
 
 	rtgui_dc_end_drawing(dc);
 	rtgui_dc_end_drawing(dc);
 
 
 	return RT_FALSE;
 	return RT_FALSE;
 }
 }
 
 
-rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+rt_bool_t rtgui_win_event_handler(struct rtgui_object* object, struct rtgui_event* event)
 {
 {
-	struct rtgui_win* win = (struct rtgui_win*)widget;
+	struct rtgui_win* win;
+
+	RT_ASSERT(object != RT_NULL);
+	RT_ASSERT(event != RT_NULL);
 
 
-	RT_ASSERT((win != RT_NULL) && (event != RT_NULL));
+	win = RTGUI_WIN(object);
 
 
 	switch (event->type)
 	switch (event->type)
 	{
 	{
@@ -376,22 +405,8 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
 		break;
 		break;
 
 
 	case RTGUI_EVENT_WIN_CLOSE:
 	case RTGUI_EVENT_WIN_CLOSE:
-		if (win->on_close != RT_NULL)
-		{
-			if (win->on_close(widget, event) == RT_FALSE) return RT_TRUE;
-		}
-
-		if (win->style & RTGUI_WIN_STYLE_MODAL)
-		{
-			rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
-		}
-		else
-		{
-			/* destroy window */
-			rtgui_win_destroy(win);
-		}
-
-		/* exit event loop */
+		_rtgui_win_deal_close(win, event);
+		/* don't broadcast WIN_CLOSE event to others */
 		return RT_TRUE;
 		return RT_TRUE;
 
 
 	case RTGUI_EVENT_WIN_MOVE:
 	case RTGUI_EVENT_WIN_MOVE:
@@ -410,49 +425,54 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
 			return RT_TRUE;
 			return RT_TRUE;
 		}
 		}
 
 
-		win->style |= RTGUI_WIN_STYLE_ACTIVATE;
+		win->flag |= RTGUI_WIN_FLAG_ACTIVATE;
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
-		else 
+		if (RTGUI_WIDGET(object)->on_draw != RT_NULL)
+			RTGUI_WIDGET(object)->on_draw(object, event);
+		else
 #endif
 #endif
 		rtgui_widget_update(RTGUI_WIDGET(win));
 		rtgui_widget_update(RTGUI_WIDGET(win));
 
 
 		if (win->on_activate != RT_NULL)
 		if (win->on_activate != RT_NULL)
 		{
 		{
-			win->on_activate(widget, event);
+			win->on_activate(RTGUI_OBJECT(object), event);
 		}
 		}
 		break;
 		break;
 
 
 	case RTGUI_EVENT_WIN_DEACTIVATE:
 	case RTGUI_EVENT_WIN_DEACTIVATE:
-		if (win->style & RTGUI_WIN_STYLE_MODAL)
+		if (win->flag & RTGUI_WIN_FLAG_MODAL)
 		{
 		{
-			/* do not deactivate a modal win, re-send win-show event */
-			struct rtgui_event_win_show eshow;
-			RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
-			eshow.wid = win;
-
-			rtgui_thread_send(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&eshow),
-				sizeof(struct rtgui_event_win_show));
+			/* FIXME: make modal concept clear and easy. See the comment of
+			 * rtgui_topwin_modal_enter. */
+			/* There are various reason that a modal window got deactivated:
+			 *     1, it has child windows and the user activate one of them.
+			 *     2, the application has more than one root window and the
+			 *     user switched to one of the others.
+			 *
+			 * In any of the cases, we have nothing to do here.
+			 */
 		}
 		}
 		else
 		else
 		{
 		{
-			win->style &= ~RTGUI_WIN_STYLE_ACTIVATE;
+			win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE;
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
-			if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
-			else 
+			if (RTGUI_WIDGET(object)->on_draw != RT_NULL)
+				RTGUI_WIDGET(object)->on_draw(object, event);
+			else
 #endif
 #endif
-				rtgui_win_ondraw(win);
+				rtgui_widget_update(RTGUI_WIDGET(win));
 
 
 			if (win->on_deactivate != RT_NULL)
 			if (win->on_deactivate != RT_NULL)
 			{
 			{
-				win->on_deactivate(widget, event);
+				win->on_deactivate(RTGUI_OBJECT(object), event);
 			}
 			}
 		}
 		}
 		break;
 		break;
 
 
 	case RTGUI_EVENT_PAINT:
 	case RTGUI_EVENT_PAINT:
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
-		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+		if (RTGUI_WIDGET(object)->on_draw != RT_NULL)
+			RTGUI_WIDGET(object)->on_draw(object, event);
 		else
 		else
 #endif
 #endif
 			rtgui_win_ondraw(win);
 			rtgui_win_ondraw(win);
@@ -460,36 +480,22 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
 
 
 	case RTGUI_EVENT_MOUSE_BUTTON:
 	case RTGUI_EVENT_MOUSE_BUTTON:
 		/* check whether has widget which handled mouse event before */
 		/* check whether has widget which handled mouse event before */
-		if (RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win) != RT_NULL)
+		if (win->last_mevent_widget != RT_NULL)
 		{
 		{
-			struct rtgui_event_mouse* emouse;
-
-			emouse = (struct rtgui_event_mouse*)event;
-			
-			RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win)->event_handler(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win), event);
-			if (rtgui_rect_contains_point(&(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win)->extent), 
-				emouse->x, emouse->y) == RT_EOK)
-			{
-				RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win) = RT_NULL;
-				break; /* mouse event is inside of widget, do not handle it anymore */
-			}
+			RTGUI_OBJECT(win->last_mevent_widget)->event_handler(
+					RTGUI_OBJECT(win->last_mevent_widget),
+					event);
 
 
 			/* clean last mouse event handled widget */
 			/* clean last mouse event handled widget */
-			RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win) = RT_NULL;
+			win->last_mevent_widget = RT_NULL;
 		}
 		}
-
-		if (win->style & RTGUI_WIN_STYLE_UNDER_MODAL)
-		{
-			if (win->modal_widget != RT_NULL)
-				return win->modal_widget->event_handler(win->modal_widget, event);
-		}
- 		else if (rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win), 
+		else if (rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),
 			(struct rtgui_event_mouse*)event) == RT_FALSE)
 			(struct rtgui_event_mouse*)event) == RT_FALSE)
 		{
 		{
 #ifndef RTGUI_USING_SMALL_SIZE
 #ifndef RTGUI_USING_SMALL_SIZE
-			if (widget->on_mouseclick != RT_NULL)
+			if (RTGUI_WIDGET(object)->on_mouseclick != RT_NULL)
 			{
 			{
-				return widget->on_mouseclick(widget, event);
+				return RTGUI_WIDGET(object)->on_mouseclick(object, event);
 			}
 			}
 #endif
 #endif
 		}
 		}
@@ -512,101 +518,45 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
 #endif
 #endif
 		break;
 		break;
 
 
-    case RTGUI_EVENT_KBD:
-		if (win->style & RTGUI_WIN_STYLE_UNDER_MODAL)
+	case RTGUI_EVENT_KBD:
+		/* we should dispatch key event firstly */
+		if (!(win->flag & RTGUI_WIN_FLAG_HANDLE_KEY))
 		{
 		{
-			if (win->modal_widget != RT_NULL)
-				return win->modal_widget->event_handler(win->modal_widget, event);
+			rt_bool_t res = RT_FALSE;
+			/* we should dispatch the key event just once. Once entered the
+			 * dispatch mode, we should swtich to key handling mode. */
+			win->flag |= RTGUI_WIN_FLAG_HANDLE_KEY;
+
+			/* dispatch the key event */
+			if (win->focused_widget != RT_NULL &&
+					RTGUI_OBJECT(win->focused_widget)->event_handler != RT_NULL)
+				res = RTGUI_OBJECT(win->focused_widget)->event_handler(
+						RTGUI_OBJECT(win->focused_widget), event);
+
+			/* if the focused widget doesn't handle it, I will handle it. */
+			if (res != RT_TRUE && win->on_key != RT_NULL)
+				res = win->on_key(RTGUI_OBJECT(win), event);
+
+			win->flag &= ~RTGUI_WIN_FLAG_HANDLE_KEY;
+			return res;
 		}
 		}
-		else if (RTGUI_CONTAINER(win)->focused != widget &&
-				 RTGUI_CONTAINER(win)->focused != RT_NULL)
+		else
 		{
 		{
-			RTGUI_CONTAINER(win)->focused->event_handler(RTGUI_CONTAINER(win)->focused, event);
+			/* in key handling mode(it may reach here in
+			 * win->focused_widget->event_handler call) */
+			if (win->on_key != RT_NULL)
+				return win->on_key(RTGUI_OBJECT(win), event);
 		}
 		}
-        break;
+		break;
 
 
 	default:
 	default:
 		/* call parent event handler */
 		/* call parent event handler */
-		return rtgui_toplevel_event_handler(widget, event);
+		return rtgui_toplevel_event_handler(object, event);
 	}
 	}
 
 
 	return RT_FALSE;
 	return RT_FALSE;
 }
 }
 
 
-/* windows event loop */
-void rtgui_win_event_loop(rtgui_win_t* wnd)
-{
-	rt_err_t result;
-	rtgui_thread_t* tid;
-	struct rtgui_event* event;
-
-	tid = rtgui_thread_self();
-	RT_ASSERT(tid != RT_NULL);
-
-	/* point to event buffer */
-	event = (struct rtgui_event*)tid->event_buffer;
-
-	if (wnd->style & RTGUI_WIN_STYLE_UNDER_MODAL)
-	{
-		while (wnd->style & RTGUI_WIN_STYLE_UNDER_MODAL)
-		{
-			if (tid->on_idle != RT_NULL)
-			{
-				result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
-				if (result == RT_EOK)
-				{
-					/* perform event handler */
-					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
-				}
-				else if (result == -RT_ETIMEOUT)
-				{
-					tid->on_idle(RTGUI_WIDGET(wnd), RT_NULL);
-				}
-			}
-			else
-			{
-				result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
-				if (result == RT_EOK)
-				{
-					/* perform event handler */
-					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
-				}
-			}
-		}
-	}
-	else
-	{
-		while (!(wnd->style & RTGUI_WIN_STYLE_CLOSED))
-		{
-			if (tid->on_idle != RT_NULL)
-			{
-				result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
-				if (result == RT_EOK)
-				{
-					/* perform event handler */
-					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
-				}
-				else if (result == -RT_ETIMEOUT)
-				{
-					tid->on_idle(RTGUI_WIDGET(wnd), RT_NULL);
-				}
-			}
-			else
-			{
-				result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
-				if (result == RT_EOK)
-				{
-					/* perform event handler */
-					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
-				}
-			}
-		}
-	}
-
-	/* destroy window */
-	rtgui_widget_destroy(RTGUI_WIDGET(wnd));
-}
-
 void rtgui_win_set_rect(rtgui_win_t* win, rtgui_rect_t* rect)
 void rtgui_win_set_rect(rtgui_win_t* win, rtgui_rect_t* rect)
 {
 {
 	struct rtgui_event_win_resize event;
 	struct rtgui_event_win_resize event;
@@ -615,14 +565,14 @@ void rtgui_win_set_rect(rtgui_win_t* win, rtgui_rect_t* rect)
 
 
 	RTGUI_WIDGET(win)->extent = *rect;
 	RTGUI_WIDGET(win)->extent = *rect;
 
 
-	if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+	if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
 	{
 	{
 		/* set window resize event to server */
 		/* set window resize event to server */
 		RTGUI_EVENT_WIN_RESIZE_INIT(&event);
 		RTGUI_EVENT_WIN_RESIZE_INIT(&event);
 		event.wid = win;
 		event.wid = win;
 		event.rect = *rect;
 		event.rect = *rect;
 
 
-		rtgui_thread_send(RTGUI_TOPLEVEL(win)->server, &(event.parent), sizeof(struct rtgui_event_win_resize));
+		rtgui_server_post_event(&(event.parent), sizeof(struct rtgui_event_win_resize));
 	}
 	}
 }
 }
 
 
@@ -660,10 +610,18 @@ void rtgui_win_set_onclose(rtgui_win_t* win, rtgui_event_handler_ptr handler)
 	}
 	}
 }
 }
 
 
+void rtgui_win_set_onkey(rtgui_win_t* win, rtgui_event_handler_ptr handler)
+{
+	if (win != RT_NULL)
+	{
+		win->on_key = handler;
+	}
+}
+
 void rtgui_win_set_title(rtgui_win_t* win, const char *title)
 void rtgui_win_set_title(rtgui_win_t* win, const char *title)
 {
 {
 	/* send title to server */
 	/* send title to server */
-	if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+	if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
 	{
 	{
 	}
 	}
 
 

+ 0 - 581
components/rtgui/widgets/workbench.c

@@ -1,581 +0,0 @@
-/*
- * File      : workbench.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date           Author       Notes
- * 2009-10-04     Bernard      first version
- * 2010-09-24     Bernard      fix workbench destroy issue
- */
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/window.h>
-#include <rtgui/widgets/workbench.h>
-
-static void _rtgui_workbench_constructor(rtgui_workbench_t *workbench)
-{
-	/* set event handler */
-	rtgui_widget_set_event_handler(RTGUI_WIDGET(workbench), rtgui_workbench_event_handler);
-
-	/* set attributes */
-	workbench->flag 		= RTGUI_WORKBENCH_FLAG_DEFAULT;
-	workbench->panel 		= RT_NULL;
-	workbench->title 		= RT_NULL;
-	workbench->current_view = RT_NULL;
-	workbench->modal_code 	= RTGUI_MODAL_OK;
-	workbench->modal_widget = RT_NULL;
-}
-
-static void _rtgui_workbench_destructor(rtgui_workbench_t *workbench)
-{
-	RT_ASSERT(workbench != RT_NULL);
-
-	if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL)
-	{
-		struct rtgui_event_panel_detach edetach;
-		RTGUI_EVENT_PANEL_DETACH_INIT(&edetach);
-
-		/* detach from panel */
-		edetach.panel = workbench->panel;
-
-		/* send PANEL DETACH to server */
-		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server,
-			RTGUI_EVENT(&edetach), sizeof(struct rtgui_event_panel_detach)) != RT_EOK)
-			return;
-
-		RTGUI_TOPLEVEL(workbench)->server = RT_NULL;
-	}
-
-	/* release title */
-	rt_free(workbench->title);
-	workbench->title = RT_NULL;
-}
-
-DEFINE_CLASS_TYPE(workbench, "workbench", 
-	RTGUI_TOPLEVEL_TYPE,
-	_rtgui_workbench_constructor,
-	_rtgui_workbench_destructor,
-	sizeof(struct rtgui_workbench));
-
-rtgui_workbench_t *rtgui_workbench_create(const char* panel_name, const unsigned char* title)
-{
-	struct rtgui_workbench* workbench;
-
-	/* the server thread id */
-	rt_thread_t server = rtgui_thread_get_server();
-	if (server == RT_NULL)
-	{
-		rt_kprintf("can't find rtgui server\n");
-		return RT_NULL;
-	}
-
-	/* create workbench */
-	workbench = (rtgui_workbench_t*) rtgui_widget_create (RTGUI_WORKBENCH_TYPE);
-	if (workbench != RT_NULL)
-	{
-		/* the buffer uses to receive event */
-		union
-		{
-			struct rtgui_event_panel_attach ecreate;
-			struct rtgui_event_panel_info epanel;
-
-			char buffer[256];	/* use to recv other information */
-		} event;
-
-		/* set workbench title */
-		workbench->title = (unsigned char*)rt_strdup((char*)title);
-
-		/* create application in server */
-		RTGUI_EVENT_PANEL_ATTACH_INIT(&(event.ecreate));
-
-		/* set the panel name and workbench */
-		rt_strncpy(event.ecreate.panel_name, panel_name, RTGUI_NAME_MAX);
-		event.ecreate.workbench = workbench;
-
-		/* send PANEL ATTACH to server */
-		if (rtgui_thread_send_sync(server,
-			&(event.ecreate.parent), sizeof(struct rtgui_event_panel_attach)) != RTGUI_STATUS_OK)
-		{
-			return RT_NULL;
-		}
-
-		/* get PANEL INFO */
-		rtgui_thread_recv_filter(RTGUI_EVENT_PANEL_INFO, &(event.epanel.parent), sizeof(event));
-
-		/* set panel */
-		workbench->panel = (struct rtgui_panel*)event.epanel.panel;
-
-		/* connected */
-		RTGUI_TOPLEVEL(workbench)->server = server;
-
-		/* set extent of workbench */
-		rtgui_widget_set_rect(RTGUI_WIDGET(workbench), &(event.epanel.extent));
-
-		/* set workbench in thread */
-		rtgui_thread_set_widget(RTGUI_WIDGET(workbench));
-	}
-
-	return workbench;
-}
-
-void rtgui_workbench_destroy(rtgui_workbench_t* workbench)
-{
-	RT_ASSERT(workbench != RT_NULL);
-
-	if (workbench->flag & RTGUI_WORKBENCH_FLAG_CLOSED)
-	{
-		rtgui_widget_destroy(RTGUI_WIDGET(workbench));
-	}
-	else
-	{
-		/* just close workbench */
-		rtgui_workbench_close(workbench);
-	}
-}
-
-void rtgui_workbench_close(rtgui_workbench_t* workbench)
-{
-	/* detach workbench in server */
-	if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL)
-	{
-		struct rtgui_event_panel_detach edetach;
-		RTGUI_EVENT_PANEL_DETACH_INIT(&edetach);
-
-		/* detach from panel */
-		edetach.panel = workbench->panel;
-		edetach.workbench = workbench;
-
-		/* send PANEL DETACH to server */
-		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server,
-			RTGUI_EVENT(&edetach), sizeof(struct rtgui_event_panel_detach)) != RT_EOK)
-			return;
-
-		RTGUI_TOPLEVEL(workbench)->server = RT_NULL;
-	}
-
-	/* set status to close */
-	workbench->flag |= RTGUI_WORKBENCH_FLAG_CLOSED;
-}
-
-void rtgui_workbench_set_flag(rtgui_workbench_t* workbench, rt_uint8_t flag)
-{
-	RT_ASSERT(workbench != RT_NULL);
-
-	workbench->flag = flag;
-}
-
-rt_bool_t rtgui_workbench_event_loop(rtgui_workbench_t* workbench)
-{
-	rt_err_t result;
-	rtgui_thread_t* tid;
-	struct rtgui_event* event;
-
-	tid = rtgui_thread_self();
-	RT_ASSERT(tid != RT_NULL);
-
-	/* point to event buffer */
-	event = (struct rtgui_event*)tid->event_buffer;
-
-	if (workbench->flag & RTGUI_WORKBENCH_FLAG_MODAL_MODE)
-	{
-		/* event loop for modal mode shown view */
-		while (workbench->flag & RTGUI_WORKBENCH_FLAG_MODAL_MODE)
-		{
-			if (tid->on_idle != RT_NULL)
-			{
-				result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
-				if (result == RT_EOK)
-					RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
-				else if (result == -RT_ETIMEOUT)
-					tid->on_idle(RTGUI_WIDGET(workbench), RT_NULL);
-			}
-			else
-			{
-				result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
-				if (result == RT_EOK)
-					RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
-			}
-		}
-	}
-	else
-	{
-		/* show workbench firstly */
-		rtgui_workbench_show(workbench);
-
-		while (!(workbench->flag & RTGUI_WORKBENCH_FLAG_CLOSED))
-		{
-			if (tid->on_idle != RT_NULL)
-			{
-				result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
-				if (result == RT_EOK)
-					RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
-				else if (result == -RT_ETIMEOUT)
-					tid->on_idle(RTGUI_WIDGET(workbench), RT_NULL);
-			}
-			else 
-			{
-				result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
-				if (result == RT_EOK)
-					RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
-			}
-		}
-	}
-
-	return RT_TRUE;
-}
-
-rt_err_t rtgui_workbench_show(rtgui_workbench_t* workbench)
-{
-	RT_ASSERT(workbench != RT_NULL);
-
-	if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL)
-	{
-		struct rtgui_event_panel_show eraise;
-		RTGUI_EVENT_PANEL_SHOW_INIT(&eraise);
-		eraise.workbench = workbench;
-
-		eraise.panel = workbench->panel;
-		if (rtgui_thread_send_sync(workbench->parent.server, RTGUI_EVENT(&eraise),
-			sizeof(struct rtgui_event_panel_show)) != RT_EOK)
-			return -RT_ERROR;
-
-		RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(workbench));
-		rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench));
-	}
-	else return -RT_ERROR;
-
-	return RT_EOK;
-}
-
-rt_err_t rtgui_workbench_hide(rtgui_workbench_t* workbench)
-{
-	if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL)
-	{
-		struct rtgui_event_panel_hide ehide;
-		RTGUI_EVENT_PANEL_HIDE_INIT(&ehide);
-
-		RT_ASSERT(workbench != RT_NULL);
-		if (workbench->parent.server == RT_NULL) return -RT_ERROR;
-
-		ehide.panel = workbench->panel;
-		if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server, RTGUI_EVENT(&ehide),
-			sizeof(struct rtgui_event_panel_hide)) != RT_EOK)
-			return -RT_ERROR;
-
-		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench));
-		rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench));
-	}
-
-	return RT_EOK;
-}
-
-rt_bool_t rtgui_workbench_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
-{
-	struct rtgui_workbench* workbench = (struct rtgui_workbench*)widget;
-
-	switch (event->type)
-	{
-	case RTGUI_EVENT_PANEL_DETACH:
-		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench));
-		RTGUI_TOPLEVEL(workbench)->server = RT_NULL;
-		return RT_TRUE;
-
-	case RTGUI_EVENT_PANEL_SHOW:
-		/* show workbench in server */
-		rtgui_workbench_show(workbench);
-		break;
-
-	case RTGUI_EVENT_PANEL_HIDE:
-		/* hide widget */
-		RTGUI_WIDGET_HIDE(widget);
-		break;
-
-	case RTGUI_EVENT_MOUSE_MOTION:
-		{
-			struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;
-			struct rtgui_toplevel* top = RTGUI_TOPLEVEL(emouse->wid);
-
-			/* check the destination window */
-			if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
-			{
-				RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event);
-			}
-			else
-			{
-				/* let viewer to handle it */
-				rtgui_view_t* view = workbench->current_view;
-				if (view != RT_NULL &&
-					RTGUI_WIDGET(view)->event_handler != RT_NULL)
-				{
-					RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event);
-				}
-			}
-		}
-		break;
-
-	case RTGUI_EVENT_MOUSE_BUTTON:
-		{
-			struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;
-			struct rtgui_toplevel* top = RTGUI_TOPLEVEL(emouse->wid);
-
-			/* check whether has widget which handled mouse event before */
-			if (RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench) != RT_NULL)
-			{
-				struct rtgui_event_mouse* emouse;
-
-				emouse = (struct rtgui_event_mouse*)event;
-
-				RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench)->event_handler(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench), event);
-				if (rtgui_rect_contains_point(&(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench)->extent), 
-					emouse->x, emouse->y) == RT_EOK)
-				{
-					RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench) = RT_NULL;
-					break; /* mouse event is inside of widget, do not handle it anymore */
-				}
-
-				/* clean last mouse event handled widget */
-				RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench) = RT_NULL;
-			}
-
-			/* check the destination window */
-			if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
-			{
-				RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event);
-			}
-			else
-			{
-				if (RTGUI_WORKBENCH_IS_MODAL_MODE(workbench))
-				{
-					/* let modal widget to handle it */
-					if (workbench->modal_widget != RT_NULL &&
-							workbench->modal_widget->event_handler != RT_NULL)
-					{
-						workbench->modal_widget->event_handler(workbench->modal_widget, event);
-					}
-				}
-				else
-				{
-					/* let viewer to handle it */
-					rtgui_view_t* view = workbench->current_view;
-					if (view != RT_NULL &&
-							RTGUI_WIDGET(view)->event_handler != RT_NULL)
-					{
-						RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event);
-					}
-				}
-			}
-		}
-		break;
-
-	case RTGUI_EVENT_KBD:
-		{
-			struct rtgui_event_kbd* kbd = (struct rtgui_event_kbd*)event;
-			struct rtgui_toplevel* top = RTGUI_TOPLEVEL(kbd->wid);
-
-			/* check the destination window */
-			if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
-			{
-				RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event);
-			}
-			else
-			{
-				if (RTGUI_WORKBENCH_IS_MODAL_MODE(workbench))
-				{
-					/* let modal widget to handle it */
-					if (workbench->modal_widget != RT_NULL &&
-							workbench->modal_widget->event_handler != RT_NULL)
-					{
-						workbench->modal_widget->event_handler(workbench->modal_widget, event);
-					}
-				}
-				else
-				{
-					if (RTGUI_CONTAINER(widget)->focused == widget)
-					{
-						/* set focused widget to the current view */
-						if (workbench->current_view != RT_NULL)
-							rtgui_widget_focus(RTGUI_WIDGET(RTGUI_CONTAINER(workbench->current_view)->focused));
-					}
-
-					return rtgui_toplevel_event_handler(widget, event);
-				}
-			}
-		}
-		break;
-
-	case RTGUI_EVENT_PAINT:
-		{
-			struct rtgui_event_paint* epaint = (struct rtgui_event_paint*)event;
-			struct rtgui_toplevel* top = RTGUI_TOPLEVEL(epaint->wid);
-
-			/* check the destination window */
-			if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
-			{
-				RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event);
-			}
-			else
-			{
-				rtgui_view_t* view;
-
-				/* un-hide workbench */
-				RTGUI_WIDGET_UNHIDE(widget);
-
-				/* paint a view */
-				view = workbench->current_view;
-				if (view != RT_NULL)
-				{
-					/* remake a paint event */
-					RTGUI_EVENT_PAINT_INIT(epaint);
-					epaint->wid = RT_NULL;
-
-					/* send this event to the view */
-					if (RTGUI_WIDGET(view)->event_handler != RT_NULL)
-					{
-						RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event);
-					}
-				}
-				else
-				{
-					struct rtgui_dc* dc;
-					struct rtgui_rect rect;
-
-					dc = rtgui_dc_begin_drawing(widget);
-					rtgui_widget_get_rect(widget, &rect);
-					rtgui_dc_fill_rect(dc, &rect);
-					rtgui_dc_end_drawing(dc);
-				}
-			}
-		}
-		break;
-
-	case RTGUI_EVENT_CLIP_INFO:
-		{
-			struct rtgui_event_clip_info* eclip = (struct rtgui_event_clip_info*)event;
-			struct rtgui_widget* dest_widget = RTGUI_WIDGET(eclip->wid);
-
-			if (dest_widget != RT_NULL && dest_widget->event_handler != RT_NULL)
-			{
-				dest_widget->event_handler(dest_widget, event);
-			}
-			else
-			{
-				return rtgui_toplevel_event_handler(widget, event);
-			}
-		}
-		break;
-
-	case RTGUI_EVENT_WIN_CLOSE:
-	case RTGUI_EVENT_WIN_ACTIVATE:
-	case RTGUI_EVENT_WIN_DEACTIVATE:
-		{
-			struct rtgui_event_win* wevent = (struct rtgui_event_win*)event;
-			struct rtgui_widget* dest_widget = RTGUI_WIDGET(wevent->wid);
-			if (dest_widget != RT_NULL && dest_widget->event_handler != RT_NULL)
-			{
-				dest_widget->event_handler(dest_widget, event);
-			}
-		}
-		break;
-
-	case RTGUI_EVENT_WIN_MOVE:
-		{
-			struct rtgui_event_win_move* wevent = (struct rtgui_event_win_move*)event;
-			struct rtgui_toplevel* top = RTGUI_TOPLEVEL(wevent->wid);
-			if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
-			{
-				RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event);
-			}
-		}
-		break;
-
-	default:
-		return rtgui_toplevel_event_handler(widget, event);
-	}
-
-	return RT_TRUE;
-}
-
-/*
- *
- * view on workbench
- *
- */
-
-void rtgui_workbench_add_view(rtgui_workbench_t* workbench, rtgui_view_t* view)
-{
-	rtgui_container_add_child(RTGUI_CONTAINER(workbench), RTGUI_WIDGET(view));
-	/* hide view in default */
-	RTGUI_WIDGET_HIDE(RTGUI_WIDGET(view));
-
-	/* reset view extent */
-	rtgui_widget_set_rect(RTGUI_WIDGET(view), &(RTGUI_WIDGET(workbench)->extent));
-}
-
-void rtgui_workbench_remove_view(rtgui_workbench_t* workbench, rtgui_view_t* view)
-{
-	if (view == workbench->current_view)
-		rtgui_workbench_hide_view(workbench, view);
-
-	rtgui_container_remove_child(RTGUI_CONTAINER(workbench), RTGUI_WIDGET(view));
-}
-
-void rtgui_workbench_show_view(rtgui_workbench_t* workbench, rtgui_view_t* view)
-{
-	RT_ASSERT(workbench != RT_NULL);
-	RT_ASSERT(view != RT_NULL);
-
-	/* already shown */
-	if (workbench->current_view == view) return;
-
-	if (workbench->current_view != RT_NULL)
-	{
-		/* hide old view */
-		RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench->current_view));
-	}
-
-	/* show view */
-	RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(view));
-	workbench->current_view = view;
-
-	/* update workbench clip */
-	rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench));
-
-	if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(workbench)))
-	{
-		rtgui_widget_update(RTGUI_WIDGET(view));
-	}
-}
-
-void rtgui_workbench_hide_view(rtgui_workbench_t* workbench, rtgui_view_t* view)
-{
-	RT_ASSERT(workbench != RT_NULL);
-	RT_ASSERT(view != RT_NULL);
-
-	/* hide view */
-	RTGUI_WIDGET_HIDE(RTGUI_WIDGET(view));
-
-	if (view == workbench->current_view)
-	{
-		rtgui_view_t *next_view;
-
-		workbench->current_view = RT_NULL;
-
-		next_view = RTGUI_VIEW(rtgui_widget_get_next_sibling(RTGUI_WIDGET(view)));
-		if (next_view == RT_NULL)
-			next_view = RTGUI_VIEW(rtgui_widget_get_prev_sibling(RTGUI_WIDGET(view)));
-
-		if (next_view != RT_NULL)
-		{
-			rtgui_view_show(next_view, RT_FALSE);
-		}
-		else
-		{
-			/* update workbench clip */
-			rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench));
-		}
-	}
-}

+ 46 - 40
examples/gui/SConscript

@@ -1,40 +1,46 @@
-from building import *
-
-src = Split("""
-demo_view_dc_buffer.c
-demo_view_instrument_panel.c
-demo_fnview.c
-demo_listview.c
-demo_listview_icon.c
-demo_panel_single.c
-demo_view.c
-demo_view_animation.c
-demo_view_buffer_animation.c
-demo_view_box.c
-demo_view_button.c
-demo_view_checkbox.c
-demo_view_dc.c
-demo_view_image.c
-demo_view_module.c
-demo_view_label.c
-demo_view_mywidget.c
-demo_view_progressbar.c
-demo_view_radiobox.c
-demo_view_listbox.c
-demo_view_slider.c
-demo_view_notebook.c
-demo_view_combobox.c
-demo_view_listctrl.c
-demo_view_menu.c
-demo_view_scrollbar.c
-demo_view_textbox.c
-demo_view_window.c
-demo_view_benchmark.c
-demo_workbench.c
-gui_init.c
-mywidget.c
-""")
-
-group = DefineGroup('gui_examples', src, depend = ['RT_USING_RTGUI'])
-
-Return('group')
+from building import *
+
+'''
+demo_view_dc_buffer.c
+demo_fnview.c
+demo_listview.c
+demo_listview_icon.c
+demo_panel_single.c
+demo_view_box.c
+demo_view_image.c
+demo_view_module.c
+'''
+
+src = Split("""
+demo_application.c
+demo_view.c
+demo_view_benchmark.c
+demo_view_dc.c
+demo_view_ttf.c
+demo_view_dc_buffer.c
+demo_view_animation.c
+demo_view_buffer_animation.c
+demo_view_instrument_panel.c
+demo_view_window.c
+demo_view_label.c
+demo_view_button.c
+demo_view_checkbox.c
+demo_view_progressbar.c
+demo_view_scrollbar.c
+demo_view_radiobox.c
+demo_view_textbox.c
+demo_view_listbox.c
+demo_view_menu.c
+demo_view_listctrl.c
+demo_view_combobox.c
+demo_view_slider.c
+demo_view_notebook.c
+demo_view_mywidget.c
+mywidget.c
+""")
+
+
+
+group = DefineGroup('gui_examples', src, depend = ['RT_USING_RTGUI'])
+
+Return('group')

+ 147 - 0
examples/gui/demo_application.c

@@ -0,0 +1,147 @@
+#include <rtgui/rtgui.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_application.h>
+
+#include <rtgui/widgets/window.h>
+#include <rtgui/widgets/notebook.h>
+
+struct rtgui_notebook *the_notebook;
+
+static rt_bool_t demo_handle_key(struct rtgui_object* object, struct rtgui_event* event)
+{
+	struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+
+	if (ekbd->type == RTGUI_KEYDOWN)
+	{
+		if (ekbd->key == RTGUIK_RIGHT)
+		{
+			demo_view_next(RT_NULL, RT_NULL);
+			return RT_TRUE;
+		}
+		else if (ekbd->key == RTGUIK_LEFT)
+		{
+			demo_view_prev(RT_NULL, RT_NULL);
+			return RT_TRUE;
+		}
+	}
+	return RT_TRUE;
+}
+
+struct rtgui_win *main_win;
+static void application_entry(void* parameter)
+{
+	struct rtgui_application *app;
+	struct rtgui_rect rect;
+
+	app = rtgui_application_create(rt_thread_self(), "gui_demo");
+	if (app == RT_NULL)
+		return;
+
+	/* create a full screen window */
+	rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &rect);
+
+	main_win = rtgui_win_create(RT_NULL, "demo_win", &rect,
+						/*RTGUI_WIN_STYLE_DESKTOP_DEFAULT);*/
+						RTGUI_WIN_STYLE_NO_BORDER | RTGUI_WIN_STYLE_NO_TITLE);
+	if (main_win == RT_NULL)
+	{
+		rtgui_application_destroy(app);
+		return;
+	}
+
+	rtgui_win_set_onkey(main_win, demo_handle_key);
+
+	/* create a no title notebook that we can switch demo on it easily. */
+	the_notebook = rtgui_notebook_create(&rect, RTGUI_NOTEBOOK_NOTAB);
+	if (the_notebook == RT_NULL)
+	{
+		rtgui_win_destroy(main_win);
+		rtgui_application_destroy(app);
+		return;
+	}
+
+	rtgui_container_add_child(RTGUI_CONTAINER(main_win), RTGUI_WIDGET(the_notebook));
+
+	/* 初始化各个例子的视图 */
+	demo_view_benchmark();
+
+	demo_view_dc();
+#ifdef RTGUI_USING_TTF
+	demo_view_ttf();
+#endif
+
+#ifndef RTGUI_USING_SMALL_SIZE
+	demo_view_dc_buffer();
+#endif
+	demo_view_animation();
+#ifndef RTGUI_USING_SMALL_SIZE
+	demo_view_buffer_animation();
+	demo_view_instrument_panel();
+#endif
+	demo_view_window();
+	demo_view_label();
+	demo_view_button();
+	demo_view_checkbox();
+	demo_view_progressbar();
+	demo_view_scrollbar();
+	demo_view_radiobox();
+	demo_view_textbox();
+	demo_view_listbox();
+	demo_view_menu();
+	demo_view_listctrl();
+	demo_view_combobox();
+	demo_view_slider();
+	demo_view_notebook();
+	demo_view_mywidget();
+#if 0
+#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
+	demo_view_image();
+#endif
+#ifdef RT_USING_MODULE	
+#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
+	demo_view_module();
+#endif
+#endif
+	demo_listview_view();
+	demo_listview_icon_view();
+#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
+	demo_fn_view();
+#endif
+#endif
+
+	rtgui_win_show(main_win, RT_FALSE);
+
+	/* 执行工作台事件循环 */
+	rtgui_application_run(app);
+
+	rtgui_application_destroy(app);
+}
+
+void application_init()
+{
+	static rt_bool_t inited = RT_FALSE;
+
+	if (inited == RT_FALSE) /* 避免重复初始化而做的保护 */
+	{
+		rt_thread_t tid;
+
+		tid = rt_thread_create("wb",
+			application_entry, RT_NULL,
+			2048 * 2, 25, 10);
+
+		if (tid != RT_NULL)
+			rt_thread_startup(tid);
+
+		inited = RT_TRUE;
+	}
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+void application()
+{
+	application_init();
+}
+/* finsh的命令输出,可以直接执行application()函数以执行上面的函数 */
+FINSH_FUNCTION_EXPORT(application, application demo)
+#endif

Some files were not shown because too many files changed in this diff