summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
Diffstat (limited to 'components')
-rw-r--r--components/rtgui/SConscript164
-rw-r--r--components/rtgui/common/blit.c568
-rw-r--r--components/rtgui/common/dc_client.c39
-rw-r--r--components/rtgui/common/dc_hw.c24
-rw-r--r--components/rtgui/common/filerw.c926
-rw-r--r--components/rtgui/common/font_freetype.c474
-rw-r--r--components/rtgui/common/font_hz_bmp.c4
-rw-r--r--components/rtgui/common/font_hz_file.c4
-rw-r--r--components/rtgui/common/framebuffer_driver.c450
-rw-r--r--components/rtgui/common/image.c30
-rw-r--r--components/rtgui/common/image_bmp.c1290
-rw-r--r--components/rtgui/common/image_container.c890
-rw-r--r--components/rtgui/common/pixel_driver.c308
-rw-r--r--components/rtgui/common/rtgui_object.c35
-rw-r--r--components/rtgui/common/rtgui_system.c467
-rw-r--r--components/rtgui/common/rtgui_xml.c2
-rw-r--r--components/rtgui/doc/attention.txt16
-rw-r--r--components/rtgui/doc/road_map.txt70
-rw-r--r--components/rtgui/include/rtgui/blit.h18
-rw-r--r--components/rtgui/include/rtgui/color.h228
-rw-r--r--components/rtgui/include/rtgui/dc.h392
-rw-r--r--components/rtgui/include/rtgui/dc_client.h54
-rw-r--r--components/rtgui/include/rtgui/dc_hw.h48
-rw-r--r--components/rtgui/include/rtgui/dlist.h119
-rw-r--r--components/rtgui/include/rtgui/driver.h134
-rw-r--r--components/rtgui/include/rtgui/event.h775
-rw-r--r--components/rtgui/include/rtgui/filerw.h94
-rw-r--r--components/rtgui/include/rtgui/font.h206
-rw-r--r--components/rtgui/include/rtgui/font_freetype.h20
-rw-r--r--components/rtgui/include/rtgui/image.h160
-rw-r--r--components/rtgui/include/rtgui/kbddef.h586
-rw-r--r--components/rtgui/include/rtgui/list.h132
-rw-r--r--components/rtgui/include/rtgui/rtgui.h5
-rw-r--r--components/rtgui/include/rtgui/rtgui_application.h99
-rw-r--r--components/rtgui/include/rtgui/rtgui_config.h156
-rw-r--r--components/rtgui/include/rtgui/rtgui_object.h33
-rw-r--r--components/rtgui/include/rtgui/rtgui_server.h163
-rw-r--r--components/rtgui/include/rtgui/rtgui_system.h157
-rw-r--r--components/rtgui/include/rtgui/widgets/about_view.h90
-rw-r--r--components/rtgui/include/rtgui/widgets/box.h116
-rw-r--r--components/rtgui/include/rtgui/widgets/button.h162
-rw-r--r--components/rtgui/include/rtgui/widgets/checkbox.h86
-rw-r--r--components/rtgui/include/rtgui/widgets/combobox.h98
-rw-r--r--components/rtgui/include/rtgui/widgets/container.h115
-rw-r--r--components/rtgui/include/rtgui/widgets/filelist_view.h115
-rw-r--r--components/rtgui/include/rtgui/widgets/iconbox.h110
-rw-r--r--components/rtgui/include/rtgui/widgets/label.h98
-rw-r--r--components/rtgui/include/rtgui/widgets/list_view.h154
-rw-r--r--components/rtgui/include/rtgui/widgets/listbox.h135
-rw-r--r--components/rtgui/include/rtgui/widgets/listctrl.h129
-rw-r--r--components/rtgui/include/rtgui/widgets/menu.h158
-rw-r--r--components/rtgui/include/rtgui/widgets/notebook.h102
-rw-r--r--components/rtgui/include/rtgui/widgets/progressbar.h80
-rw-r--r--components/rtgui/include/rtgui/widgets/radiobox.h90
-rw-r--r--components/rtgui/include/rtgui/widgets/scrollbar.h178
-rw-r--r--components/rtgui/include/rtgui/widgets/slider.h106
-rw-r--r--components/rtgui/include/rtgui/widgets/staticline.h70
-rw-r--r--components/rtgui/include/rtgui/widgets/textbox.h150
-rw-r--r--components/rtgui/include/rtgui/widgets/textview.h134
-rw-r--r--components/rtgui/include/rtgui/widgets/title.h88
-rw-r--r--components/rtgui/include/rtgui/widgets/toplevel.h97
-rw-r--r--components/rtgui/include/rtgui/widgets/view.h66
-rw-r--r--components/rtgui/include/rtgui/widgets/widget.h43
-rw-r--r--components/rtgui/include/rtgui/widgets/window.h267
-rw-r--r--components/rtgui/include/rtgui/widgets/workbench.h87
-rw-r--r--components/rtgui/server/mouse.c2
-rw-r--r--components/rtgui/server/panel.c315
-rw-r--r--components/rtgui/server/panel.h72
-rw-r--r--components/rtgui/server/rtgui_application.c673
-rw-r--r--components/rtgui/server/server.c601
-rw-r--r--components/rtgui/server/topwin.c1255
-rw-r--r--components/rtgui/server/topwin.h22
-rw-r--r--components/rtgui/widgets/about_view.c202
-rw-r--r--components/rtgui/widgets/box.c16
-rw-r--r--components/rtgui/widgets/button.c19
-rw-r--r--components/rtgui/widgets/checkbox.c299
-rw-r--r--components/rtgui/widgets/combobox.c535
-rw-r--r--components/rtgui/widgets/container.c159
-rw-r--r--components/rtgui/widgets/filelist_view.c1673
-rw-r--r--components/rtgui/widgets/iconbox.c11
-rw-r--r--components/rtgui/widgets/label.c11
-rw-r--r--components/rtgui/widgets/list_view.c1272
-rw-r--r--components/rtgui/widgets/listbox.c775
-rw-r--r--components/rtgui/widgets/listctrl.c853
-rw-r--r--components/rtgui/widgets/menu.c562
-rw-r--r--components/rtgui/widgets/notebook.c686
-rw-r--r--components/rtgui/widgets/progressbar.c205
-rw-r--r--components/rtgui/widgets/radiobox.c490
-rw-r--r--components/rtgui/widgets/scrollbar.c834
-rw-r--r--components/rtgui/widgets/slider.c507
-rw-r--r--components/rtgui/widgets/staticline.c160
-rw-r--r--components/rtgui/widgets/textbox.c26
-rw-r--r--components/rtgui/widgets/textview.c703
-rw-r--r--components/rtgui/widgets/toplevel.c80
-rw-r--r--components/rtgui/widgets/view.c214
-rw-r--r--components/rtgui/widgets/widget.c152
-rw-r--r--components/rtgui/widgets/window.c554
-rw-r--r--components/rtgui/widgets/workbench.c581
98 files changed, 13119 insertions, 13864 deletions
diff --git a/components/rtgui/SConscript b/components/rtgui/SConscript
index 59489267e8..afe253a1e6 100644
--- a/components/rtgui/SConscript
+++ b/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')
diff --git a/components/rtgui/common/blit.c b/components/rtgui/common/blit.c
index 39d0e32823..a9b0b36749 100644
--- a/components/rtgui/common/blit.c
+++ b/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;
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 ++;
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;
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 ++;
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];
+}
diff --git a/components/rtgui/common/dc_client.c b/components/rtgui/common/dc_client.c
index 244de209a4..22d2887095 100644
--- a/components/rtgui/common/dc_client.c
+++ b/components/rtgui/common/dc_client.c
@@ -21,9 +21,10 @@
#include <rtgui/driver.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/workbench.h>
#include <rtgui/widgets/title.h>
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);
- 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)
- {
- /* use hardware DC */
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)
@@ -63,7 +61,7 @@ void rtgui_dc_end_drawing(struct rtgui_dc* 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_color_point,
@@ -116,7 +114,7 @@ struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner)
if (RTGUI_WIDGET_IS_HIDE(widget))
{
RTGUI_WIDGET_DC_SET_UNVISIBLE(owner);
- break;
+ return RT_NULL;
}
widget = widget->parent;
@@ -130,7 +128,7 @@ struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner)
if (top->drawing == 1)
{
#ifdef RTGUI_USING_MOUSE_CURSOR
-#ifdef __WIN32__
+#ifdef _WIN32
rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
rt_kprintf("hide cursor\n");
rtgui_mouse_hide_cursor();
@@ -141,15 +139,18 @@ struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner)
#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);
top->drawing ++;
if (top->drawing == 1)
{
-#ifdef __WIN32__
+#ifdef _WIN32
#ifdef RTGUI_USING_MOUSE_CURSOR
rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
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));
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
}
}
@@ -186,7 +187,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc)
top->drawing --;
if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
{
-#ifdef __WIN32__
+#ifdef _WIN32
#ifdef RTGUI_USING_MOUSE_CURSOR
rt_mutex_release(&cursor_mutex);
/* show cursor */
@@ -206,7 +207,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc)
#endif
}
}
- else if (RTGUI_IS_WORKBENCH(owner->toplevel) ||
+ else if (RTGUI_IS_APPLICATION(owner->toplevel) ||
RTGUI_IS_WIN(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))
{
-#ifdef __WIN32__
+#ifdef _WIN32
#ifdef RTGUI_USING_MOUSE_CURSOR
rt_mutex_release(&cursor_mutex);
/* show cursor */
@@ -229,7 +230,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc)
RTGUI_EVENT_UPDATE_END_INIT(&(eupdate));
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
}
}
diff --git a/components/rtgui/common/dc_hw.c b/components/rtgui/common/dc_hw.c
index 5b6670bfd1..2895797974 100644
--- a/components/rtgui/common/dc_hw.c
+++ b/components/rtgui/common/dc_hw.c
@@ -15,9 +15,11 @@
#include <rtgui/dc_hw.h>
#include <rtgui/driver.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/workbench.h>
#include <rtgui/widgets/title.h>
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))
{
RTGUI_WIDGET_DC_SET_UNVISIBLE(owner);
- break;
+ return RT_NULL;
}
widget = widget->parent;
@@ -104,7 +106,7 @@ struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner)
if (top->drawing == 1)
{
#ifdef RTGUI_USING_MOUSE_CURSOR
-#ifdef __WIN32__
+#ifdef _WIN32
rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
rt_kprintf("hide cursor\n");
rtgui_mouse_hide_cursor();
@@ -115,7 +117,7 @@ struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner)
#endif
}
}
- else if (RTGUI_IS_WORKBENCH(owner->toplevel) ||
+ else if (RTGUI_IS_APPLICATION(owner->toplevel) ||
RTGUI_IS_WIN(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)
{
-#ifdef __WIN32__
+#ifdef _WIN32
#ifdef RTGUI_USING_MOUSE_CURSOR
rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
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));
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
}
}
@@ -162,7 +164,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc)
top->drawing --;
if ((top->drawing == 0) && RTGUI_WIDGET_IS_DC_VISIBLE(owner))
{
-#ifdef __WIN32__
+#ifdef _WIN32
#ifdef RTGUI_USING_MOUSE_CURSOR
rt_mutex_release(&cursor_mutex);
/* show cursor */
@@ -182,7 +184,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc)
#endif
}
}
- else if (RTGUI_IS_WORKBENCH(owner->toplevel) ||
+ else if (RTGUI_IS_APPLICATION(owner->toplevel) ||
RTGUI_IS_WIN(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))
{
-#ifdef __WIN32__
+#ifdef _WIN32
#ifdef RTGUI_USING_MOUSE_CURSOR
rt_mutex_release(&cursor_mutex);
/* show cursor */
@@ -205,7 +207,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc)
RTGUI_EVENT_UPDATE_END_INIT(&(eupdate));
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
}
}
diff --git a/components/rtgui/common/filerw.c b/components/rtgui/common/filerw.c
index 3d50bbb36f..8fd8073970 100644
--- a/components/rtgui/common/filerw.c
+++ b/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;
+}
diff --git a/components/rtgui/common/font_freetype.c b/components/rtgui/common/font_freetype.c
index dc231fc04b..11d7788272 100644
--- a/components/rtgui/common/font_freetype.c
+++ b/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
diff --git a/components/rtgui/common/font_hz_bmp.c b/components/rtgui/common/font_hz_bmp.c
index fd8ea9b058..72088f7848 100644
--- a/components/rtgui/common/font_hz_bmp.c
+++ b/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)
{
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 */
if (len > 0)
{
@@ -97,7 +97,7 @@ static void rtgui_hz_bitmap_font_draw_text (struct rtgui_font* font, struct rtgu
}
len = 0;
- while (((rt_uint8_t)*(text + len)) >= 0x80) len ++;
+ while (((rt_uint8_t)*(text + len)) >= 0x80 && len < length) len ++;
if (len > 0)
{
_rtgui_hz_bitmap_font_draw_text(bmp_font, dc, text, len, rect);
diff --git a/components/rtgui/common/font_hz_file.c b/components/rtgui/common/font_hz_file.c
index 35e878f24a..6150864032 100644
--- a/components/rtgui/common/font_hz_file.c
+++ b/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)
{
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 */
if (len > 0)
{
@@ -188,7 +188,7 @@ static void rtgui_hz_file_font_draw_text(struct rtgui_font* font, struct rtgui_d
}
len = 0;
- while (((rt_uint8_t)*(text + len)) >= 0x80) len ++;
+ while (((rt_uint8_t)*(text + len)) >= 0x80 && len < length) len ++;
if (len > 0)
{
_rtgui_hz_file_font_draw_text(hz_file_font, dc, text, len, rect);
diff --git a/components/rtgui/common/framebuffer_driver.c b/components/rtgui/common/framebuffer_driver.c
index 78dea306ad..04c21c42a5 100644
--- a/components/rtgui/common/framebuffer_driver.c
+++ b/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;
+}
+
diff --git a/components/rtgui/common/image.c b/components/rtgui/common/image.c
index 45a1013a69..0160c990ea 100644
--- a/components/rtgui/common/image.c
+++ b/components/rtgui/common/image.c
@@ -64,47 +64,47 @@ void rtgui_system_image_init(void)
#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_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)
{
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 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_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)
{
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 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_filerw* filerw;
diff --git a/components/rtgui/common/image_bmp.c b/components/rtgui/common/image_bmp.c
index 9dd9798675..1c7c108217 100644
--- a/components/rtgui/common/image_bmp.c
+++ b/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
diff --git a/components/rtgui/common/image_container.c b/components/rtgui/common/image_container.c
index 9146f4f829..1088c9bbaf 100644
--- a/components/rtgui/common/image_container.c
+++ b/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
diff --git a/components/rtgui/common/pixel_driver.c b/components/rtgui/common/pixel_driver.c
index 8edabcb81d..31b22e164e 100644
--- a/components/rtgui/common/pixel_driver.c
+++ b/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;
+}
diff --git a/components/rtgui/common/rtgui_object.c b/components/rtgui/common/rtgui_object.c
index f3f779e3a8..a4248cfb29 100644
--- a/components/rtgui/common/rtgui_object.c
+++ b/components/rtgui/common/rtgui_object.c
@@ -17,9 +17,10 @@
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 */
@@ -28,7 +29,7 @@ static void _rtgui_object_destructor(rtgui_object_t *object)
/* nothing */
}
-DEFINE_CLASS_TYPE(type, "object",
+DEFINE_CLASS_TYPE(type, "object",
RT_NULL,
_rtgui_object_constructor,
_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)
-{
- const rtgui_type_t *t;
-
+{
+ const rtgui_type_t *t;
+
t = type;
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)
-{
- const rtgui_type_t *t;
-
+{
+ const rtgui_type_t *t;
+
t = type;
while (t)
{
@@ -115,7 +116,6 @@ rtgui_object_t *rtgui_object_create(rtgui_type_t *object_type)
#endif
new_object->type = object_type;
- new_object->is_static = RT_FALSE;
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)
{
- if (!object || object->is_static == RT_TRUE) return;
+ if (!object || object->flag & RTGUI_OBJECT_FLAG_STATIC)
+ return;
#ifdef RTGUI_OBJECT_TRACE
obj_info.objs_number --;
@@ -178,3 +179,15 @@ const rtgui_type_t *rtgui_object_object_type_get(rtgui_object_t *object)
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;
+}
+
diff --git a/components/rtgui/common/rtgui_system.c b/components/rtgui/common/rtgui_system.c
index 3d9d48445c..a503e946be 100644
--- a/components/rtgui/common/rtgui_system.c
+++ b/components/rtgui/common/rtgui_system.c
@@ -16,15 +16,13 @@
#include <rtgui/image.h>
#include <rtgui/font.h>
#include <rtgui/event.h>
+#include <rtgui/rtgui_application.h>
#include <rtgui/rtgui_server.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/window.h>
#include <rtgui/rtgui_theme.h>
-#define RTGUI_EVENT_DEBUG
-
#ifdef _WIN32
-#define RTGUI_EVENT_DEBUG
#define RTGUI_MEM_TRACE
#endif
@@ -44,467 +42,6 @@ void rtgui_system_server_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 */
/************************************************************************/
static void rtgui_time_out(void* parameter)
@@ -522,7 +59,7 @@ static void rtgui_time_out(void* parameter)
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)
diff --git a/components/rtgui/common/rtgui_xml.c b/components/rtgui/common/rtgui_xml.c
index eecb197d59..47407bec3e 100644
--- a/components/rtgui/common/rtgui_xml.c
+++ b/components/rtgui/common/rtgui_xml.c
@@ -1,5 +1,5 @@
#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. */
enum {
diff --git a/components/rtgui/doc/attention.txt b/components/rtgui/doc/attention.txt
new file mode 100644
index 0000000000..bb0de99966
--- /dev/null
+++ b/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 包含之。
+
diff --git a/components/rtgui/doc/road_map.txt b/components/rtgui/doc/road_map.txt
new file mode 100644
index 0000000000..74aa40fc3a
--- /dev/null
+++ b/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。
diff --git a/components/rtgui/include/rtgui/blit.h b/components/rtgui/include/rtgui/blit.h
index 615e5b6d7e..df0d2a5b32 100644
--- a/components/rtgui/include/rtgui/blit.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/color.h b/components/rtgui/include/rtgui/color.h
index 0e78bd0fd3..d8f5fce177 100644
--- a/components/rtgui/include/rtgui/color.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/dc.h b/components/rtgui/include/rtgui/dc.h
index bca0a65015..15ae971cb0 100644
--- a/components/rtgui/include/rtgui/dc.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/dc_client.h b/components/rtgui/include/rtgui/dc_client.h
index 297307c875..1a1de04851 100644
--- a/components/rtgui/include/rtgui/dc_client.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/dc_hw.h b/components/rtgui/include/rtgui/dc_hw.h
index f4c84dd755..a9eca07aa1 100644
--- a/components/rtgui/include/rtgui/dc_hw.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/dlist.h b/components/rtgui/include/rtgui/dlist.h
new file mode 100644
index 0000000000..5491daca0c
--- /dev/null
+++ b/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
diff --git a/components/rtgui/include/rtgui/driver.h b/components/rtgui/include/rtgui/driver.h
index 052fc137b1..664d9183f3 100644
--- a/components/rtgui/include/rtgui/driver.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/event.h b/components/rtgui/include/rtgui/event.h
index 231263d5fe..e20b5cabee 100644
--- a/components/rtgui/include/rtgui/event.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/filerw.h b/components/rtgui/include/rtgui/filerw.h
index b05ce3f8e9..c254d51afa 100644
--- a/components/rtgui/include/rtgui/filerw.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/font.h b/components/rtgui/include/rtgui/font.h
index 177d6a6ec6..f3bf5ef464 100644
--- a/components/rtgui/include/rtgui/font.h
+++ b/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
{
const rt_uint8_t* bmp; /* bitmap font data */
@@ -46,69 +46,69 @@ struct rtgui_font_bitmap
rt_uint8_t first_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
diff --git a/components/rtgui/include/rtgui/font_freetype.h b/components/rtgui/include/rtgui/font_freetype.h
index ced143ff07..b99108e7c4 100644
--- a/components/rtgui/include/rtgui/font_freetype.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/image.h b/components/rtgui/include/rtgui/image.h
index 45030dec40..e876354286 100644
--- a/components/rtgui/include/rtgui/image.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/kbddef.h b/components/rtgui/include/rtgui/kbddef.h
index c078404c60..7a97e7f990 100644
--- a/components/rtgui/include/rtgui/kbddef.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/list.h b/components/rtgui/include/rtgui/list.h
index a58f689984..bead36be39 100644
--- a/components/rtgui/include/rtgui/list.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/rtgui.h b/components/rtgui/include/rtgui/rtgui.h
index 5fb795b481..b473b9d794 100644
--- a/components/rtgui/include/rtgui/rtgui.h
+++ b/components/rtgui/include/rtgui/rtgui.h
@@ -21,17 +21,16 @@
#define RT_INT16_MIN (-RT_INT16_MAX-1)
#define RTGUI_NOT_FOUND (-1)
-struct rtgui_panel;
struct rtgui_event;
+struct rtgui_object;
struct rtgui_widget;
struct rtgui_win;
struct rtgui_font;
-typedef struct rtgui_panel rtgui_panel_t;
typedef struct rtgui_win rtgui_win_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);
struct rtgui_point
diff --git a/components/rtgui/include/rtgui/rtgui_application.h b/components/rtgui/include/rtgui/rtgui_application.h
new file mode 100644
index 0000000000..83c13aaff5
--- /dev/null
+++ b/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 */
diff --git a/components/rtgui/include/rtgui/rtgui_config.h b/components/rtgui/include/rtgui/rtgui_config.h
index 2bd82a7b74..f1dae17ca8 100644
--- a/components/rtgui/include/rtgui/rtgui_config.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/rtgui_object.h b/components/rtgui/include/rtgui/rtgui_object.h
index f385246b71..f89bfbf1b2 100644
--- a/components/rtgui/include/rtgui/rtgui_object.h
+++ b/components/rtgui/include/rtgui/rtgui_object.h
@@ -16,6 +16,7 @@
#include <rtthread.h>
+#include <rtgui/rtgui.h>
#ifdef __cplusplus
extern "C" {
@@ -85,25 +86,47 @@ DECLARE_CLASS_TYPE(type);
/** Gets the type of an object */
#define RTGUI_OBJECT_TYPE RTGUI_TYPE(type)
/** 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 */
#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 */
struct rtgui_object
{
/* object 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);
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_type_t *rtk_object_object_type_get(rtgui_object_t *object);
diff --git a/components/rtgui/include/rtgui/rtgui_server.h b/components/rtgui/include/rtgui/rtgui_server.h
index f5c798fbee..8d1c57a6c4 100644
--- a/components/rtgui/include/rtgui/rtgui_server.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/rtgui_system.h b/components/rtgui/include/rtgui/rtgui_system.h
index 6577f38b67..4f94ab83d1 100644
--- a/components/rtgui/include/rtgui/rtgui_system.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/widgets/about_view.h b/components/rtgui/include/rtgui/widgets/about_view.h
index 9058d84bb7..510796edf3 100644
--- a/components/rtgui/include/rtgui/widgets/about_view.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/box.h b/components/rtgui/include/rtgui/widgets/box.h
index a58f07568e..0e0b814e8b 100644
--- a/components/rtgui/include/rtgui/widgets/box.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/button.h b/components/rtgui/include/rtgui/widgets/button.h
index cab0fcaf01..0d7678d358 100644
--- a/components/rtgui/include/rtgui/widgets/button.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/checkbox.h b/components/rtgui/include/rtgui/widgets/checkbox.h
index 554a00d9f9..bf226e061e 100644
--- a/components/rtgui/include/rtgui/widgets/checkbox.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/combobox.h b/components/rtgui/include/rtgui/widgets/combobox.h
index 2409d7fb5c..6be860b76b 100644
--- a/components/rtgui/include/rtgui/widgets/combobox.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/container.h b/components/rtgui/include/rtgui/widgets/container.h
index 09a79d71d6..57a92b432c 100644
--- a/components/rtgui/include/rtgui/widgets/container.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/filelist_view.h b/components/rtgui/include/rtgui/widgets/filelist_view.h
index 6be873efc9..3ce9bbb195 100644
--- a/components/rtgui/include/rtgui/widgets/filelist_view.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/iconbox.h b/components/rtgui/include/rtgui/widgets/iconbox.h
index 9ce5fee57c..17545951d5 100644
--- a/components/rtgui/include/rtgui/widgets/iconbox.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/label.h b/components/rtgui/include/rtgui/widgets/label.h
index e19c15984d..be75e3957d 100644
--- a/components/rtgui/include/rtgui/widgets/label.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/list_view.h b/components/rtgui/include/rtgui/widgets/list_view.h
index 28792366c8..7f03098bc2 100644
--- a/components/rtgui/include/rtgui/widgets/list_view.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/widgets/listbox.h b/components/rtgui/include/rtgui/widgets/listbox.h
index 8eb10206c7..cb38802d53 100644
--- a/components/rtgui/include/rtgui/widgets/listbox.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/widgets/listctrl.h b/components/rtgui/include/rtgui/widgets/listctrl.h
index ad3bb924cb..d3f9ce703d 100644
--- a/components/rtgui/include/rtgui/widgets/listctrl.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/menu.h b/components/rtgui/include/rtgui/widgets/menu.h
index 629fb84e46..ba620d3c74 100644
--- a/components/rtgui/include/rtgui/widgets/menu.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/widgets/notebook.h b/components/rtgui/include/rtgui/widgets/notebook.h
index e14c895647..92fb9e6c4d 100644
--- a/components/rtgui/include/rtgui/widgets/notebook.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/progressbar.h b/components/rtgui/include/rtgui/widgets/progressbar.h
index ef2ccc9db5..08733c3496 100644
--- a/components/rtgui/include/rtgui/widgets/progressbar.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/radiobox.h b/components/rtgui/include/rtgui/widgets/radiobox.h
index e0f68bfca0..2a53daa477 100644
--- a/components/rtgui/include/rtgui/widgets/radiobox.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/widgets/scrollbar.h b/components/rtgui/include/rtgui/widgets/scrollbar.h
index 8ae56aa8b1..a4e57b7204 100644
--- a/components/rtgui/include/rtgui/widgets/scrollbar.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/slider.h b/components/rtgui/include/rtgui/widgets/slider.h
index 6b3bee28e2..2273177acc 100644
--- a/components/rtgui/include/rtgui/widgets/slider.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/staticline.h b/components/rtgui/include/rtgui/widgets/staticline.h
index 481c8da306..67ccfa4dec 100644
--- a/components/rtgui/include/rtgui/widgets/staticline.h
+++ b/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
+
diff --git a/components/rtgui/include/rtgui/widgets/textbox.h b/components/rtgui/include/rtgui/widgets/textbox.h
index 912da4ca84..972e80a579 100644
--- a/components/rtgui/include/rtgui/widgets/textbox.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/textview.h b/components/rtgui/include/rtgui/widgets/textview.h
index 523b5ee9c1..49024207cf 100644
--- a/components/rtgui/include/rtgui/widgets/textview.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/title.h b/components/rtgui/include/rtgui/widgets/title.h
index ee6ac2c824..09a67ea2ba 100644
--- a/components/rtgui/include/rtgui/widgets/title.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/toplevel.h b/components/rtgui/include/rtgui/widgets/toplevel.h
index 3b46aeaa5c..9b4b5573d2 100644
--- a/components/rtgui/include/rtgui/widgets/toplevel.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/view.h b/components/rtgui/include/rtgui/widgets/view.h
deleted file mode 100644
index a35095cf30..0000000000
--- a/components/rtgui/include/rtgui/widgets/view.h
+++ /dev/null
@@ -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
diff --git a/components/rtgui/include/rtgui/widgets/widget.h b/components/rtgui/include/rtgui/widgets/widget.h
index ab44d23b39..7d747e677c 100644
--- a/components/rtgui/include/rtgui/widgets/widget.h
+++ b/components/rtgui/include/rtgui/widgets/widget.h
@@ -76,8 +76,10 @@ struct rtgui_widget
/* inherit from rtgui_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 */
rtgui_list_t sibling;
@@ -106,18 +108,25 @@ struct rtgui_widget
/* the rect clip */
rtgui_region_t clip;
- /* the event handler */
- rt_bool_t (*event_handler) (struct rtgui_widget* widget, struct rtgui_event* event);
-
/* 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
- 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
/* user private data */
@@ -125,14 +134,10 @@ struct rtgui_widget
};
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);
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 */
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 */
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_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
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);
@@ -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);
/* 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_hide(rtgui_widget_t* widget);
diff --git a/components/rtgui/include/rtgui/widgets/window.h b/components/rtgui/include/rtgui/widgets/window.h
index 4807407b00..deb4378a36 100644
--- a/components/rtgui/include/rtgui/widgets/window.h
+++ b/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
diff --git a/components/rtgui/include/rtgui/widgets/workbench.h b/components/rtgui/include/rtgui/widgets/workbench.h
deleted file mode 100644
index 3ec089f345..0000000000
--- a/components/rtgui/include/rtgui/widgets/workbench.h
+++ /dev/null
@@ -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
diff --git a/components/rtgui/server/mouse.c b/components/rtgui/server/mouse.c
index 8d851f0f85..c7a05aac4b 100644
--- a/components/rtgui/server/mouse.c
+++ b/components/rtgui/server/mouse.c
@@ -432,7 +432,7 @@ static void rtgui_winrect_show()
rt_uint16_t x, y;
rtgui_color_t c;
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;
set_pixel = rtgui_graphic_driver_get_default()->ops->set_pixel;
diff --git a/components/rtgui/server/panel.c b/components/rtgui/server/panel.c
deleted file mode 100644
index f9cd93a578..0000000000
--- a/components/rtgui/server/panel.c
+++ /dev/null
@@ -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;
-}
-
diff --git a/components/rtgui/server/panel.h b/components/rtgui/server/panel.h
deleted file mode 100644
index 559ddc4307..0000000000
--- a/components/rtgui/server/panel.h
+++ /dev/null
@@ -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
-
diff --git a/components/rtgui/server/rtgui_application.c b/components/rtgui/server/rtgui_application.c
new file mode 100644
index 0000000000..97de7bd17a
--- /dev/null
+++ b/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;
+}
diff --git a/components/rtgui/server/server.c b/components/rtgui/server/server.c
index 5b90b64b1b..10ddfbf77a 100644
--- a/components/rtgui/server/server.c
+++ b/components/rtgui/server/server.c
@@ -15,176 +15,15 @@
#include <rtgui/rtgui.h>
#include <rtgui/event.h>
#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_object.h>
+#include <rtgui/rtgui_application.h>
#include <rtgui/driver.h>
#include "mouse.h"
-#include "panel.h"
#include "topwin.h"
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)
{
@@ -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)
{
- 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)
{
- 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)
{
struct rtgui_topwin* wnd;
- struct rtgui_panel* panel;
/* re-init to server thread */
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 */
- rtgui_thread_send(topwin->tid, &(ewin.parent), sizeof(ewin));
+ rtgui_application_send(topwin->tid, &(ewin.parent), sizeof(ewin));
return;
}
@@ -271,16 +93,15 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
#endif
/* 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)
{
event->wid = wnd->wid;
- if (rtgui_server_focus_topwin != wnd)
+ if (rtgui_topwin_get_focus() != wnd)
{
/* raise this window */
rtgui_topwin_activate_win(wnd);
- rtgui_server_focus_panel = RT_NULL;
}
if (wnd->title != RT_NULL &&
@@ -291,137 +112,39 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
else
{
/* 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 ;
}
-
- /* 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;
void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse* event)
{
/* the topwin contains current mouse */
struct rtgui_topwin* win = RT_NULL;
- struct rtgui_panel* panel = RT_NULL;
/* re-init mouse 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 */
- 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;
-
- /* 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;
-
/* 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)
@@ -432,7 +155,7 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse* event)
event->wid = last_monitor_topwin->wid;
/* 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)
{
struct rtgui_topwin* wnd;
- struct rtgui_panel* panel;
/* re-init to server thread */
RTGUI_EVENT_KBD_INIT(event);
/* 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 */
event->wid = wnd->wid;
/* 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;
}
-
- panel = rtgui_server_focus_panel;
- if (panel != RT_NULL)
- {
- rt_thread_t tid;
-
- /* 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;
-
- /* send keyboard event to thread */
- rtgui_thread_send(tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_kbd));
- }
- }
}
-#ifdef __WIN32__
+#ifdef _WIN32
#include <windows.h>
#endif
-/**
- * rtgui server thread's entry
- */
-static void rtgui_server_entry(void* parameter)
+static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
+ struct rtgui_event *event)
{
-#ifdef __WIN32__
- /* set the server thread to highest */
- HANDLE hCurrentThread = GetCurrentThread();
- SetThreadPriority(hCurrentThread, THREAD_PRIORITY_HIGHEST);
-#endif
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
-#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 */
- rtgui_thread_register(rtgui_server_tid, rtgui_server_mq);
+ /* 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;
- /* init mouse and show */
- rtgui_mouse_init();
-#ifdef RTGUI_USING_MOUSE_CURSOR
- rtgui_mouse_show_cursor();
-#endif
+ 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;
- 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]);
+ 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;
- 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_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_PANEL_DETACH:
- /* unregister an application */
- rtgui_server_destroy_application((struct rtgui_event_panel_detach*)event);
- 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_PANEL_SHOW:
- /* handle raise an application */
- rtgui_server_thread_panel_show((struct rtgui_event_panel_show*)event);
- 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;
- case RTGUI_EVENT_PANEL_HIDE:
- /* handle hide an application */
- rtgui_server_thread_panel_hide((struct rtgui_event_panel_hide*)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;
- case RTGUI_EVENT_SET_WM:
- /* handle set workbench manager event */
- rtgui_server_handle_set_wm((struct rtgui_event_set_wm*)event);
- break;
+ /* other event */
+ case RTGUI_EVENT_UPDATE_BEGIN:
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ /* hide cursor */
+ rtgui_mouse_hide_cursor();
+#endif
+ 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_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_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_MONITOR_ADD:
+ /* handle mouse monitor */
+ rtgui_server_handle_monitor_add((struct rtgui_event_monitor*)event);
+ break;
- case RTGUI_EVENT_WIN_SHOW:
- rtgui_topwin_show((struct rtgui_event_win*)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_WIN_HIDE:
- rtgui_topwin_hide((struct rtgui_event_win*)event);
- break;
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ /* handle mouse button */
+ rtgui_server_handle_mouse_btn((struct rtgui_event_mouse*)event);
+ break;
- case RTGUI_EVENT_WIN_MOVE:
- rtgui_topwin_move((struct rtgui_event_win_move*)event);
- break;
+ case RTGUI_EVENT_KBD:
+ /* handle keyboard event */
+ rtgui_server_handle_kbd((struct rtgui_event_kbd*)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;
+ case RTGUI_EVENT_COMMAND:
+ break;
+ }
- /* other event */
- case RTGUI_EVENT_UPDATE_BEGIN:
-#ifdef RTGUI_USING_MOUSE_CURSOR
- /* hide cursor */
- rtgui_mouse_hide_cursor();
-#endif
- break;
+ return RT_TRUE;
+}
- 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();
+/**
+ * rtgui server thread's entry
+ */
+static void rtgui_server_entry(void* parameter)
+{
+#ifdef _WIN32
+ /* set the server thread to highest */
+ HANDLE hCurrentThread = GetCurrentThread();
+ SetThreadPriority(hCurrentThread, THREAD_PRIORITY_HIGHEST);
#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;
+ /* register rtgui server thread */
+ rtgui_server_application = rtgui_application_create(rtgui_server_tid,
+ "rtgui");
+ if (rtgui_server_application == RT_NULL)
+ return;
- case RTGUI_EVENT_KBD:
- /* handle keyboard event */
- rtgui_server_handle_kbd((struct rtgui_event_kbd*)event);
- break;
+ rtgui_object_set_event_handler(RTGUI_OBJECT(rtgui_server_application),
+ rtgui_server_event_handler);
+ /* init mouse and show */
+ rtgui_mouse_init();
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ rtgui_mouse_show_cursor();
+#endif
- case RTGUI_EVENT_COMMAND:
- break;
- }
- }
- }
+ rtgui_application_run(rtgui_server_application);
- /* 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)
{
- 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_entry, RT_NULL,
RTGUI_SVR_THREAD_STACK_SIZE,
diff --git a/components/rtgui/server/topwin.c b/components/rtgui/server/topwin.c
index 498f8987a8..14c9432b18 100644
--- a/components/rtgui/server/topwin.c
+++ b/components/rtgui/server/topwin.c
@@ -11,51 +11,82 @@
* Date Author Notes
* 2009-10-16 Bernard first version
*/
-#include "panel.h"
#include "topwin.h"
#include "mouse.h"
+#include <rtgui/dlist.h>
#include <rtgui/event.h>
#include <rtgui/image.h>
#include <rtgui/rtgui_theme.h>
#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_application.h>
#include <rtgui/widgets/window.h>
-struct rtgui_topwin* rtgui_server_focus_topwin = RT_NULL;
+/* This list is divided into two parts. The first part is the shown list, in
+ * which all the windows have the WINTITLE_SHOWN flag set. Second part is the
+ * hidden list, in which all the windows don't have WINTITLE_SHOWN flag.
+ *
+ * The active window is the one that would receive kbd events. It should always
+ * in the first tree. The order of this list is the order of the windows.
+ * Thus, the first item is the top most window and the last item is the bottom
+ * window. Top window can always clip the window beneath it when the two
+ * overlapping. Child window can always clip it's parent. Slibing windows can
+ * clip each other with the same rule as this list. Thus, each child list is
+ * the same as _rtgui_topwin_list. This forms the hierarchy tree structure of
+ * all windows.
+ *
+ * The hidden list have no specific order.
+ */
+static struct rtgui_dlist_node _rtgui_topwin_list;
+#define get_topwin_from_list(list_entry) \
+ (rtgui_dlist_entry((list_entry), struct rtgui_topwin, list))
+
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+static struct rtgui_topwin *the_desktop_topwin;
+
+#define IS_ROOT_WIN(topwin) ((topwin)->parent == the_desktop_topwin)
+#else
+#define IS_ROOT_WIN(topwin) ((topwin)->parent == RT_NULL)
+#endif
-static struct rtgui_list_node _rtgui_topwin_show_list;
-static struct rtgui_list_node _rtgui_topwin_hide_list;
static struct rt_semaphore _rtgui_topwin_lock;
static void rtgui_topwin_update_clip(void);
static void rtgui_topwin_redraw(struct rtgui_rect* rect);
+static void _rtgui_topwin_activate_next(void);
-void rtgui_topwin_init()
+void rtgui_topwin_init(void)
{
/* init window list */
- rtgui_list_init(&_rtgui_topwin_show_list);
- rtgui_list_init(&_rtgui_topwin_hide_list);
+ rtgui_dlist_init(&_rtgui_topwin_list);
- rt_sem_init(&_rtgui_topwin_lock,
+ rt_sem_init(&_rtgui_topwin_lock,
"topwin", 1, RT_IPC_FLAG_FIFO);
}
-static struct rtgui_topwin*
-rtgui_topwin_search_in_list(struct rtgui_win* wid, struct rtgui_list_node* list)
+static struct rtgui_topwin* rtgui_topwin_search_in_list(struct rtgui_win* window,
+ struct rtgui_dlist_node* list)
{
- struct rtgui_list_node* node;
+ /* TODO: use a cache to speed up the search. */
+ struct rtgui_dlist_node* node;
struct rtgui_topwin* topwin;
- /* search in list */
- rtgui_list_foreach(node, list)
+ /* the action is tend to operate on the top most window. So we search in a
+ * depth first order.
+ */
+ rtgui_dlist_foreach(node, list, next)
{
- topwin = rtgui_list_entry(node, struct rtgui_topwin, list);
+ topwin = rtgui_dlist_entry(node, struct rtgui_topwin, list);
/* is this node? */
- if (topwin->wid == wid)
+ if (topwin->wid == window)
{
return topwin;
}
+
+ topwin = rtgui_topwin_search_in_list(window, &topwin->child_list);
+ if (topwin != RT_NULL)
+ return topwin;
}
return RT_NULL;
@@ -67,17 +98,42 @@ rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event)
struct rtgui_topwin* topwin;
topwin = rtgui_malloc(sizeof(struct rtgui_topwin));
- if (topwin == RT_NULL) return -RT_ERROR;
+ if (topwin == RT_NULL)
+ return -RT_ERROR;
- topwin->wid = event->wid;
+ topwin->wid = event->wid;
#ifdef RTGUI_USING_SMALL_SIZE
- topwin->extent = RTGUI_WIDGET(event->wid)->extent;
+ topwin->extent = RTGUI_WIDGET(event->wid)->extent;
#else
- topwin->extent = event->extent;
+ topwin->extent = event->extent;
#endif
- topwin->tid = event->parent.sender;
+ topwin->tid = event->parent.sender;
- topwin->flag = 0;
+ if (event->parent_window == RT_NULL)
+ {
+ topwin->parent = RT_NULL;
+ rtgui_dlist_insert_before(&_rtgui_topwin_list, &topwin->list);
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+ RT_ASSERT(the_desktop_topwin == RT_NULL);
+ RT_ASSERT(event->parent.user & RTGUI_WIN_STYLE_DESKTOP);
+ the_desktop_topwin = topwin;
+#endif
+ }
+ else
+ {
+ topwin->parent = rtgui_topwin_search_in_list(event->parent_window, &_rtgui_topwin_list);
+ if (topwin->parent == RT_NULL)
+ {
+ /* parent does not exist. Orphan window? */
+ rtgui_free(topwin);
+ return -RT_ERROR;
+ }
+ rtgui_dlist_insert_before(&topwin->parent->child_list, &topwin->list);
+ }
+
+ rtgui_dlist_init(&topwin->child_list);
+
+ topwin->flag = 0;
if (event->parent.user & RTGUI_WIN_STYLE_NO_TITLE) topwin->flag |= WINTITLE_NO;
if (event->parent.user & RTGUI_WIN_STYLE_CLOSEBOX) topwin->flag |= WINTITLE_CLOSEBOX;
if (!(event->parent.user & RTGUI_WIN_STYLE_NO_BORDER)) topwin->flag |= WINTITLE_BORDER;
@@ -105,541 +161,660 @@ rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event)
rtgui_widget_set_rect(RTGUI_WIDGET(topwin->title), &rect);
/* update clip info */
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(topwin->title));
rtgui_region_subtract_rect(&(RTGUI_WIDGET(topwin->title)->clip),
&(RTGUI_WIDGET(topwin->title)->clip),
&(topwin->extent));
}
- else topwin->title = RT_NULL;
+ else
+ topwin->title = RT_NULL;
- rtgui_list_init(&topwin->list);
rtgui_list_init(&topwin->monitor_list);
- /* add topwin node to the hidden window list */
- rtgui_list_insert(&(_rtgui_topwin_hide_list), &(topwin->list));
-
return RT_EOK;
}
-rt_err_t rtgui_topwin_remove(struct rtgui_win* wid)
+static struct rtgui_topwin* _rtgui_topwin_get_root_win(struct rtgui_topwin *topwin)
{
- struct rtgui_topwin* topwin;
+ struct rtgui_topwin *topparent;
- /* find the topwin node */
- topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_show_list);
+ RT_ASSERT(topwin != RT_NULL);
+
+ topparent = topwin;
+ while (topparent && !IS_ROOT_WIN(topparent))
+ topparent = topparent->parent;
+ return topparent;
+}
- if (topwin)
+static struct rtgui_topwin* _rtgui_topwin_get_topmost_child_shown(struct rtgui_topwin *topwin)
+{
+ RT_ASSERT(topwin != RT_NULL);
+
+ while (!(rtgui_dlist_isempty(&topwin->child_list)) &&
+ get_topwin_from_list(topwin->child_list.next)->flag & WINTITLE_SHOWN)
+ topwin = get_topwin_from_list(topwin->child_list.next);
+ return topwin;
+}
+
+static struct rtgui_topwin* _rtgui_topwin_get_topmost_window_shown(void)
+{
+ if (!(get_topwin_from_list(_rtgui_topwin_list.next)->flag & WINTITLE_SHOWN))
+ return RT_NULL;
+ else
+ return _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(_rtgui_topwin_list.next));
+}
+
+/* a hidden parent will hide it's children. Top level window can be shown at
+ * any time. */
+static rt_bool_t _rtgui_topwin_could_show(struct rtgui_topwin *topwin)
+{
+ struct rtgui_topwin *parent;
+
+ RT_ASSERT(topwin != RT_NULL);
+
+ for (parent = topwin->parent; parent != RT_NULL; parent = parent->parent)
{
- /* remove node from list */
- rtgui_list_remove(&_rtgui_topwin_show_list, &(topwin->list));
+ if (!(parent->flag & WINTITLE_SHOWN))
+ return RT_FALSE;
+ }
+ return RT_TRUE;
+}
- rtgui_topwin_update_clip();
+static void _rtgui_topwin_union_region_tree(struct rtgui_topwin *topwin,
+ struct rtgui_region *region)
+{
+ struct rtgui_dlist_node *node;
- /* redraw the old rect */
- rtgui_topwin_redraw(&(topwin->extent));
+ RT_ASSERT(topwin != RT_NULL);
- if (rtgui_server_focus_topwin == topwin)
- {
- /* activate the next window */
- if (_rtgui_topwin_show_list.next != RT_NULL)
- {
- struct rtgui_event_win wevent;
- struct rtgui_topwin* wnd;
+ rtgui_dlist_foreach(node, &topwin->child_list, next)
+ _rtgui_topwin_union_region_tree(get_topwin_from_list(node), region);
- /* get the topwin */
- wnd = rtgui_list_entry(_rtgui_topwin_show_list.next,
- struct rtgui_topwin, list);
+ if (topwin->title != RT_NULL)
+ rtgui_region_union_rect(region, region, &RTGUI_WIDGET(topwin->title)->extent);
+ else
+ rtgui_region_union_rect(region, region, &topwin->extent);
+}
- /* activate the window */
- RTGUI_EVENT_WIN_ACTIVATE_INIT(&wevent);
- wevent.wid = wnd->wid;
- rtgui_thread_send(wnd->tid, &(wevent.parent), sizeof(struct rtgui_event_win));
+/* The return value of this function is the next node in tree.
+ *
+ * As we freed the node in this function, it would be a null reference error of
+ * the caller iterate the tree normally.
+ */
+static struct rtgui_dlist_node* _rtgui_topwin_free_tree(struct rtgui_topwin *topwin)
+{
+ struct rtgui_dlist_node *node, *next_node;
- /* set new focus topwin */
- rtgui_server_focus_topwin = wnd;
- }
- else
- {
- /* there is no shown window right now */
- rtgui_server_focus_topwin = RT_NULL;
- }
- }
+ RT_ASSERT(topwin != RT_NULL);
- /* free the monitor rect list, topwin node and title */
- while (topwin->monitor_list.next != RT_NULL)
- {
- struct rtgui_mouse_monitor* monitor = rtgui_list_entry(topwin->monitor_list.next,
+ node = topwin->child_list.next;
+ while (node != &topwin->child_list)
+ node = _rtgui_topwin_free_tree(get_topwin_from_list(node));
+
+ next_node = topwin->list.next;
+ rtgui_dlist_remove(&topwin->list);
+
+ /* free the monitor rect list, topwin node and title */
+ while (topwin->monitor_list.next != RT_NULL)
+ {
+ struct rtgui_mouse_monitor* monitor = rtgui_list_entry(topwin->monitor_list.next,
struct rtgui_mouse_monitor, list);
- topwin->monitor_list.next = topwin->monitor_list.next->next;
- rtgui_free(monitor);
- }
+ topwin->monitor_list.next = topwin->monitor_list.next->next;
+ rtgui_free(monitor);
+ }
- /* destroy win title */
- rtgui_wintitle_destroy(topwin->title);
- topwin->title = RT_NULL;
+ /* destroy win title */
+ rtgui_wintitle_destroy(topwin->title);
+ topwin->title = RT_NULL;
- rtgui_free(topwin);
+ rtgui_free(topwin);
+ return next_node;
+}
- return RT_EOK;
- }
+rt_err_t rtgui_topwin_remove(struct rtgui_win* wid)
+{
+ struct rtgui_topwin *topwin, *old_focus;
+ struct rtgui_region region;
- topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_hide_list);
- if (topwin)
- {
- /* remove node from list */
- rtgui_list_remove(&_rtgui_topwin_hide_list, &(topwin->list));
+ /* find the topwin node */
+ topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_list);
- /* free the topwin node and title */
- rtgui_wintitle_destroy(topwin->title);
- topwin->title = RT_NULL;
+ if (topwin == RT_NULL)
+ return -RT_ERROR;
- rtgui_free(topwin);
+ rtgui_region_init(&region);
- return RT_EOK;
+ old_focus = rtgui_topwin_get_focus();
+
+ // TODO: if the window is hidden, there is no need to update the window
+ // region
+ _rtgui_topwin_union_region_tree(topwin, &region);
+ if (topwin->flag & WINTITLE_SHOWN)
+ rtgui_topwin_update_clip();
+
+ if (old_focus == topwin)
+ {
+ _rtgui_topwin_activate_next();
}
- return -RT_ERROR;
+ /* redraw the old rect */
+ rtgui_topwin_redraw(rtgui_region_extents(&region));
+
+ /* remove the root from _rtgui_topwin_list will remove the whole tree from
+ * _rtgui_topwin_list. */
+ rtgui_dlist_remove(&topwin->list);
+
+ _rtgui_topwin_free_tree(topwin);
+
+ return RT_EOK;
}
-/* activate a win
- * - deactivate the old focus win
- * - activate a win
- * - set the focus win to activate win
- * - draw win title
- */
-void rtgui_topwin_activate_win(struct rtgui_topwin* win)
+/* neither deactivate the old focus nor change _rtgui_topwin_list.
+ * Suitable to be called when the first item is the window to be activated
+ * already. */
+static void _rtgui_topwin_only_activate(struct rtgui_topwin *topwin)
{
struct rtgui_event_win event;
+ RT_ASSERT(topwin != RT_NULL);
+
+ if (topwin->flag & WINTITLE_NOFOCUS)
+ return;
+
/* activate the raised window */
RTGUI_EVENT_WIN_ACTIVATE_INIT(&event);
- event.wid = win->wid;
- rtgui_thread_send(win->tid, &(event.parent), sizeof(struct rtgui_event_win));
+
+ topwin->flag |= WINTITLE_ACTIVATE;
+
+ event.wid = topwin->wid;
+ rtgui_application_send(topwin->tid, &(event.parent), sizeof(struct rtgui_event_win));
/* redraw title */
- if (win->title != RT_NULL)
+ if (topwin->title != RT_NULL)
{
- win->flag |= WINTITLE_ACTIVATE;
- rtgui_theme_draw_win(win);
+ rtgui_theme_draw_win(topwin);
}
+}
- if ((rtgui_server_focus_topwin != RT_NULL) && (rtgui_server_focus_topwin != win))
- {
- /* deactivate the old focus win */
- RTGUI_EVENT_WIN_DEACTIVATE_INIT(&event);
- event.wid = rtgui_server_focus_topwin->wid;
- rtgui_thread_send(rtgui_server_focus_topwin->tid,
- &event.parent, sizeof(struct rtgui_event_win));
+static void _rtgui_topwin_activate_next(void)
+{
+ struct rtgui_topwin *topwin;
- /* redraw title */
- if (rtgui_server_focus_topwin->title != RT_NULL)
- {
- rtgui_server_focus_topwin->flag &= ~WINTITLE_ACTIVATE;
- rtgui_theme_draw_win(rtgui_server_focus_topwin);
- }
- }
+ topwin = _rtgui_topwin_get_topmost_window_shown();
+ if (topwin == RT_NULL)
+ return;
- rtgui_server_focus_topwin = win;
+ _rtgui_topwin_only_activate(topwin);
}
-/*
- * deactivate a win
- * - deactivate the win
- * - redraw win title
- * - set rtgui_server_focus_topwin
- */
-void rtgui_topwin_deactivate_win(struct rtgui_topwin* win)
+/* this function does not update the clip(to avoid doubel clipping). So if the
+ * tree has changed, make sure it has already updated outside. */
+static void _rtgui_topwin_deactivate(struct rtgui_topwin *topwin)
{
- /* deactivate win */
struct rtgui_event_win event;
+
+ RT_ASSERT(topwin != RT_NULL);
+ RT_ASSERT(topwin->tid != RT_NULL);
+
RTGUI_EVENT_WIN_DEACTIVATE_INIT(&event);
- event.wid = win->wid;
- rtgui_thread_send(win->tid,
- &event.parent, sizeof(struct rtgui_event_win));
+ event.wid = topwin->wid;
+ rtgui_application_send(topwin->tid,
+ &event.parent, sizeof(struct rtgui_event_win));
- win->flag &= ~WINTITLE_ACTIVATE;
- rtgui_theme_draw_win(win);
+ topwin->flag &= ~WINTITLE_ACTIVATE;
- if (rtgui_server_focus_topwin == win)
+ /* redraw title */
+ if (topwin->title != RT_NULL)
{
- rtgui_server_focus_topwin = RT_NULL;
+ rtgui_theme_draw_win(topwin);
}
}
-/* raise window to front */
-void rtgui_topwin_raise(struct rtgui_win* wid, rt_thread_t sender)
+static void _rtgui_topwin_move_whole_tree2top(struct rtgui_topwin *topwin)
{
- struct rtgui_topwin* topwin;
- struct rtgui_list_node* node;
- struct rtgui_event_clip_info eclip;
+ struct rtgui_topwin *topparent;
- RTGUI_EVENT_CLIP_INFO_INIT(&eclip);
- eclip.wid = RT_NULL;
+ RT_ASSERT(topwin != RT_NULL);
- /* the window is already placed in front */
- if (&(topwin->list) == _rtgui_topwin_show_list.next)
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+ /* handle desktop window separately, avoid calling
+ * _rtgui_topwin_get_root_win */
+ if (topwin == the_desktop_topwin)
{
- rtgui_server_focus_topwin = RT_NULL;
- rtgui_topwin_activate_win(topwin);
- return ;
+ rtgui_dlist_remove(&the_desktop_topwin->list);
+ rtgui_dlist_insert_after(&_rtgui_topwin_list, &the_desktop_topwin->list);
+ return;
}
+#endif
- // rt_sem_take(&_rtgui_topwin_lock, RT_WAITING_FOREVER);
- /* find the topwin node */
- for (node = _rtgui_topwin_show_list.next; node->next != RT_NULL; node = node->next)
- {
- topwin = rtgui_list_entry(node->next, struct rtgui_topwin, list);
- if (topwin->wid == wid)
- {
- /* found target */
-
- struct rtgui_list_node* n;
- n = node->next;
- /* remove node */
- node->next = node->next->next;
- /* insert node to the header */
- n->next = _rtgui_topwin_show_list.next;
- _rtgui_topwin_show_list.next = n;
+ /* move the whole tree */
+ topparent = _rtgui_topwin_get_root_win(topwin);
+ RT_ASSERT(topparent != RT_NULL);
- /* send clip update to each upper window */
- for (n = _rtgui_topwin_show_list.next; n != node->next; n = n->next)
- {
- struct rtgui_topwin* wnd = rtgui_list_entry(n, struct rtgui_topwin, list);
- eclip.wid = wnd->wid;
+ /* remove node from hidden list */
+ rtgui_dlist_remove(&topparent->list);
+ /* add node to show list */
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+ rtgui_dlist_insert_after(&the_desktop_topwin->child_list, &(topparent->list));
+#else
+ rtgui_dlist_insert_after(&_rtgui_topwin_list, &(topparent->list));
+#endif
+}
- /* send to destination window */
- rtgui_thread_send(wnd->tid, &(eclip.parent), sizeof(struct rtgui_event_clip_info));
+static void _rtgui_topwin_raise_topwin_in_tree(struct rtgui_topwin *topwin)
+{
+ struct rtgui_dlist_node *win_level;
- /* reset clip info in title */
- if (wnd->title != RT_NULL)
- {
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(wnd->title));
- rtgui_region_subtract_rect(&(RTGUI_WIDGET(wnd->title)->clip),
- &(RTGUI_WIDGET(wnd->title)->clip),
- &(wnd->extent));
- }
- }
+ RT_ASSERT(topwin != RT_NULL);
- /* active window */
- rtgui_topwin_activate_win(topwin);
- break;
- }
- }
- // rt_sem_release(&_rtgui_topwin_lock);
+ _rtgui_topwin_move_whole_tree2top(topwin);
+ if (topwin->parent == RT_NULL)
+ win_level = &_rtgui_topwin_list;
+ else
+ win_level = &topwin->parent->child_list;
+ rtgui_dlist_remove(&topwin->list);
+ rtgui_dlist_insert_after(win_level, &topwin->list);
}
-/* show a window */
-void rtgui_topwin_show(struct rtgui_event_win* event)
+/* activate a win means:
+ * - deactivate the old focus win if any
+ * - raise the window to the front of it's siblings
+ * - activate a win
+ */
+void rtgui_topwin_activate_win(struct rtgui_topwin* topwin)
{
- struct rtgui_topwin* topwin;
- struct rtgui_win* wid = event->wid;
- rt_thread_t sender = RTGUI_EVENT(event)->sender;
+ struct rtgui_topwin *old_focus_topwin;
- /* find in hide list */
- topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_hide_list);
+ RT_ASSERT(topwin != RT_NULL);
- /* find it */
- if (topwin != RT_NULL)
+ if (topwin->flag & WINTITLE_NOFOCUS)
{
- /* remove node from hidden list */
- rtgui_list_remove(&_rtgui_topwin_hide_list, &(topwin->list));
-
- /* add node to show list */
- rtgui_list_insert(&_rtgui_topwin_show_list, &(topwin->list));
-
- /* show window title */
- if (topwin->title != RT_NULL)
- {
- RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(topwin->title));
- }
+ /* just raise it, not affect others. */
+ _rtgui_topwin_raise_topwin_in_tree(topwin);
/* update clip info */
rtgui_topwin_update_clip();
+ return;
+ }
- rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_OK);
+ old_focus_topwin = rtgui_topwin_get_focus();
- /* activate this window */
- rtgui_topwin_activate_win(topwin);
- }
- else
- {
- /* the wnd is located in show list, raise wnd to front */
- topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_show_list);
- if (topwin != RT_NULL)
- {
- if (_rtgui_topwin_show_list.next != &(topwin->list))
- {
- rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_OK);
+ if (old_focus_topwin == topwin)
+ return;
- /* not the front window, raise it */
- rtgui_topwin_raise(wid, sender);
- }
- else
- {
- /* just raise it */
- rtgui_topwin_raise(wid, sender);
- }
- }
- else
- {
- /* there is no wnd in wnd list */
- rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_ERROR);
- }
+ _rtgui_topwin_raise_topwin_in_tree(topwin);
+ /* update clip info */
+ rtgui_topwin_update_clip();
+
+ if (old_focus_topwin != RT_NULL)
+ {
+ /* deactivate the old focus window firstly, otherwise it will make the new
+ * window invisible. */
+ _rtgui_topwin_deactivate(old_focus_topwin);
}
+
+ _rtgui_topwin_only_activate(topwin);
}
-/* send clip info to panel */
-#ifdef RTGUI_USING_SMALL_SIZE
-void rtgui_topwin_update_clip_to_panel(struct rtgui_panel* panel)
+/* map func to the topwin tree in preorder.
+ *
+ * Remember that we are in a embedded system so write the @param func memory
+ * efficiently.
+ */
+rt_inline void _rtgui_topwin_preorder_map(struct rtgui_topwin *topwin, void (*func)(struct rtgui_topwin*))
{
- rt_uint32_t count;
- rt_thread_t tid;
- struct rtgui_list_node* node;
- struct rtgui_event_clip_info eclip;
+ struct rtgui_dlist_node *child;
- /* get topwin count */
- count = 0;
- node = _rtgui_topwin_show_list.next;
- while (node != RT_NULL)
- {
- count ++;
- node = node->next;
- }
+ RT_ASSERT(topwin != RT_NULL);
+ RT_ASSERT(func != RT_NULL);
- /* send clip info event to panel */
- RTGUI_EVENT_CLIP_INFO_INIT(&eclip);
- eclip.num_rect = count; eclip.wid = RT_NULL;
+ func(topwin);
- /* send to the activated thread of panel */
- tid = rtgui_panel_get_active_thread(panel);
- rtgui_thread_send(tid, &eclip.parent, sizeof(struct rtgui_event_clip_info));
+ rtgui_dlist_foreach(child, &topwin->child_list, next)
+ _rtgui_topwin_preorder_map(get_topwin_from_list(child), func);
}
-#else
-void rtgui_topwin_update_clip_to_panel(struct rtgui_panel* panel)
-{
- rt_uint32_t count;
- rt_thread_t tid;
- struct rtgui_list_node* node;
- struct rtgui_event_clip_info* eclip;
- /* get topwin count */
- count = 0;
- node = _rtgui_topwin_show_list.next;
- while (node != RT_NULL)
+rt_inline void _rtgui_topwin_mark_hidden(struct rtgui_topwin *topwin)
+{
+ topwin->flag &= ~WINTITLE_SHOWN;
+ if (topwin->title != RT_NULL)
{
- count ++;
- node = node->next;
+ RTGUI_WIDGET_HIDE(RTGUI_WIDGET(topwin->title));
}
+ RTGUI_WIDGET_HIDE(RTGUI_WIDGET(topwin->wid));
+}
- eclip = (struct rtgui_event_clip_info*)rtgui_malloc(sizeof(struct rtgui_event_clip_info)
- + (count + 1)* sizeof(struct rtgui_rect));
- if (eclip == RT_NULL)
+rt_inline void _rtgui_topwin_mark_shown(struct rtgui_topwin *topwin)
+{
+ topwin->flag |= WINTITLE_SHOWN;
+ if (topwin->title != RT_NULL)
{
- /* no memory */
- return ;
+ RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(topwin->title));
}
+ RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(topwin->wid));
+}
- /* reset clip info to top window */
- RTGUI_EVENT_CLIP_INFO_INIT(eclip);
- eclip->num_rect = count; eclip->wid = RT_NULL;
+static void _rtgui_topwin_draw_tree(struct rtgui_topwin *topwin, struct rtgui_event_paint *epaint)
+{
+ struct rtgui_dlist_node *node;
- count = 0;
- for (node = _rtgui_topwin_show_list.next; node != RT_NULL; node = node->next)
+ if (topwin->title != RT_NULL)
{
- struct rtgui_topwin* wnd;
- struct rtgui_rect* rect;
+ rtgui_theme_draw_win(topwin);
+ }
- wnd = rtgui_list_entry(node, struct rtgui_topwin, list);
+ epaint->wid = topwin->wid;
+ rtgui_application_send(topwin->tid, &(epaint->parent), sizeof(struct rtgui_event_paint));
- rect = RTGUI_EVENT_GET_RECT(eclip, count++);
- *rect = (wnd->title != RT_NULL)? RTGUI_WIDGET(wnd->title)->extent : wnd->extent;
+ rtgui_dlist_foreach(node, &topwin->child_list, prev)
+ {
+ _rtgui_topwin_draw_tree(get_topwin_from_list(node), epaint);
}
+}
+
+/* show the window tree. @param epaint can be initialized outside and reduce stack
+ * usage. */
+static void _rtgui_topwin_show_tree(struct rtgui_topwin *topwin, struct rtgui_event_paint *epaint)
+{
+ RT_ASSERT(topwin != RT_NULL);
+ RT_ASSERT(epaint != RT_NULL);
- /* send to the activated thread of panel */
- tid = rtgui_panel_get_active_thread(panel);
- rtgui_thread_send(tid, (struct rtgui_event*)eclip, sizeof(struct rtgui_event_clip_info)
- + count* sizeof(struct rtgui_rect));
+ _rtgui_topwin_raise_topwin_in_tree(topwin);
+ /* we have to mark the _all_ tree before update_clip because update_clip
+ * will stop as hidden windows */
+ _rtgui_topwin_preorder_map(topwin, _rtgui_topwin_mark_shown);
- /* release clip info event */
- rtgui_free(eclip);
+ // TODO: if all the window is shown already, there is no need to
+ // update_clip. But since we use peorder_map, it seems it's a bit difficult
+ // to tell whether @param topwin and it's children are all shown.
+ rtgui_topwin_update_clip();
+
+ _rtgui_topwin_draw_tree(topwin, epaint);
}
-#endif
-/* hide a window */
-void rtgui_topwin_hide(struct rtgui_event_win* event)
+/** show a window
+ *
+ * If any parent window in the hierarchy tree is hidden, this window won't be
+ * shown. If this window could be shown, all the child windows will be shown as
+ * well. The topmost child will be active.
+ *
+ * Top level window(parent == RT_NULL) can always be shown.
+ */
+rt_err_t rtgui_topwin_show(struct rtgui_event_win* event)
{
- struct rtgui_topwin* topwin;
+ struct rtgui_topwin *topwin, *old_focus;
struct rtgui_win* wid = event->wid;
+ struct rtgui_event_paint epaint;
- /* find in show list */
- topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_show_list);
+ RTGUI_EVENT_PAINT_INIT(&epaint);
+
+ /* find in hide list */
+ topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_list);
+ if (topwin == RT_NULL ||
+ !_rtgui_topwin_could_show(topwin))
+ return -RT_ERROR;
+
+ old_focus = rtgui_topwin_get_focus();
+
+ _rtgui_topwin_show_tree(topwin, &epaint);
- /* found it */
- if (topwin)
+ /* we don't want double clipping(bare rtgui_topwin_activate_win will clip),
+ * so we have to do deactivate/activate manually. */
+ if (old_focus == RT_NULL)
+ _rtgui_topwin_only_activate(topwin);
+ else if (old_focus != topwin)
{
- /* remove node from show list */
- rtgui_list_remove(&_rtgui_topwin_show_list, &(topwin->list));
+ _rtgui_topwin_deactivate(old_focus);
+ _rtgui_topwin_only_activate(topwin);
+ }
- /* add node to hidden list */
- rtgui_list_insert(&_rtgui_topwin_hide_list, &(topwin->list));
+ return RT_EOK;
+}
- /* show window title */
- if (topwin->title != RT_NULL)
- {
- RTGUI_WIDGET_HIDE(RTGUI_WIDGET(topwin->title));
- }
+static void _rtgui_topwin_clear_modal_tree(struct rtgui_topwin *topwin)
+{
+ struct rtgui_dlist_node *node;
- /* update clip info */
- rtgui_topwin_update_clip();
+ RT_ASSERT(topwin != RT_NULL);
+ RT_ASSERT(topwin->parent != RT_NULL);
- /* redraw the old rect */
- rtgui_topwin_redraw(&(topwin->extent));
+ while (!IS_ROOT_WIN(topwin))
+ {
+ rtgui_dlist_foreach(node, &topwin->parent->child_list, next)
+ get_topwin_from_list(node)->flag &= ~WINTITLE_MODALED;
+ topwin = topwin->parent;
+ }
+ /* clear the modal flag of the root window */
+ topwin->flag &= ~WINTITLE_MODALED;
+}
- if (rtgui_server_focus_topwin == topwin)
- {
- /* activate the next window */
- if (_rtgui_topwin_show_list.next != RT_NULL)
- {
- /* get the topwin */
- topwin = rtgui_list_entry(_rtgui_topwin_show_list.next,
- struct rtgui_topwin, list);
+/* hide a window */
+rt_err_t rtgui_topwin_hide(struct rtgui_event_win* event)
+{
+ struct rtgui_topwin *topwin;
+ struct rtgui_topwin *old_focus_topwin = rtgui_topwin_get_focus();
+ struct rtgui_win *wid = event->wid;
+ struct rtgui_dlist_node *containing_list;
- rtgui_server_focus_topwin = RT_NULL;
- rtgui_topwin_activate_win(topwin);
- }
- else
- {
- /* there is no shown window right now */
- rtgui_server_focus_topwin = RT_NULL;
- }
- }
+ /* find in show list */
+ topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_list);
+ if (topwin == RT_NULL)
+ {
+ return -RT_ERROR;
+ }
+ if (!(topwin->flag & WINTITLE_SHOWN))
+ {
+ return RT_EOK;
}
+
+ old_focus_topwin = rtgui_topwin_get_focus();
+
+ _rtgui_topwin_preorder_map(topwin, _rtgui_topwin_mark_hidden);
+
+ if (topwin->parent == RT_NULL)
+ containing_list = &_rtgui_topwin_list;
else
+ containing_list = &topwin->parent->child_list;
+
+ rtgui_dlist_remove(&topwin->list);
+ rtgui_dlist_insert_before(containing_list, &topwin->list);
+
+ /* update clip info */
+ rtgui_topwin_update_clip();
+
+ /* redraw the old rect */
+ rtgui_topwin_redraw(&(topwin->extent));
+
+ if (topwin->flag & WINTITLE_MODALING)
{
- rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_ERROR);
- return;
+ _rtgui_topwin_clear_modal_tree(topwin);
+ topwin->flag &= ~WINTITLE_MODALING;
+ }
+
+ if (old_focus_topwin == topwin)
+ {
+ _rtgui_topwin_activate_next();
}
- rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_OK);
+ return RT_EOK;
}
/* move top window */
-void rtgui_topwin_move(struct rtgui_event_win_move* event)
+rt_err_t rtgui_topwin_move(struct rtgui_event_win_move* event)
{
struct rtgui_topwin* topwin;
+ int dx, dy;
+ rtgui_rect_t old_rect; /* the old topwin coverage area */
+ struct rtgui_list_node* node;
/* find in show list */
- topwin = rtgui_topwin_search_in_list(event->wid, &_rtgui_topwin_show_list);
- if (topwin != RT_NULL)
+ topwin = rtgui_topwin_search_in_list(event->wid, &_rtgui_topwin_list);
+ if (topwin == RT_NULL ||
+ !(topwin->flag & WINTITLE_SHOWN))
{
- int dx, dy;
- rtgui_rect_t rect; /* the old topwin coverage area */
- struct rtgui_list_node* node;
-
- /* send status ok */
- rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_OK);
+ return -RT_ERROR;
+ }
- /* get the delta move x, y */
- dx = event->x - topwin->extent.x1;
- dy = event->y - topwin->extent.y1;
+ /* get the delta move x, y */
+ dx = event->x - topwin->extent.x1;
+ dy = event->y - topwin->extent.y1;
- rect = topwin->extent;
- /* move window rect */
- rtgui_rect_moveto(&(topwin->extent), dx, dy);
+ old_rect = topwin->extent;
+ /* move window rect */
+ rtgui_rect_moveto(&(topwin->extent), dx, dy);
- /* move window title */
- if (topwin->title != RT_NULL)
- {
- rect = RTGUI_WIDGET(topwin->title)->extent;
- rtgui_widget_move_to_logic(RTGUI_WIDGET(topwin->title), dx, dy);
- }
+ /* move window title */
+ if (topwin->title != RT_NULL)
+ {
+ old_rect = RTGUI_WIDGET(topwin->title)->extent;
+ rtgui_widget_move_to_logic(RTGUI_WIDGET(topwin->title), dx, dy);
+ }
- /* move the monitor rect list */
- rtgui_list_foreach(node, &(topwin->monitor_list))
- {
- struct rtgui_mouse_monitor* monitor = rtgui_list_entry(node,
+ /* move the monitor rect list */
+ rtgui_list_foreach(node, &(topwin->monitor_list))
+ {
+ struct rtgui_mouse_monitor* monitor = rtgui_list_entry(node,
struct rtgui_mouse_monitor,
list);
- rtgui_rect_moveto(&(monitor->rect), dx, dy);
- }
+ rtgui_rect_moveto(&(monitor->rect), dx, dy);
+ }
- /* update windows clip info */
- rtgui_topwin_update_clip();
+ /* update windows clip info */
+ rtgui_topwin_update_clip();
- /* update top window title */
- if (topwin->title != RT_NULL) rtgui_theme_draw_win(topwin);
- if (rtgui_rect_is_intersect(&rect, &(topwin->extent)) != RT_EOK)
- {
- /*
- * the old rect is not intersect with moved rect,
- * re-paint window
- */
- struct rtgui_event_paint epaint;
- RTGUI_EVENT_PAINT_INIT(&epaint);
- epaint.wid = topwin->wid;
- rtgui_thread_send(topwin->tid, &(epaint.parent), sizeof(epaint));
- }
+ /* update old window coverage area */
+ rtgui_topwin_redraw(&old_rect);
- /* update old window coverage area */
- rtgui_topwin_redraw(&rect);
- }
- else
+ /* update top window title */
+ if (topwin->title != RT_NULL)
+ rtgui_theme_draw_win(topwin);
+ if (rtgui_rect_is_intersect(&old_rect, &(topwin->extent)) != RT_EOK)
{
- rtgui_thread_ack(RTGUI_EVENT(event), RTGUI_STATUS_ERROR);
+ /*
+ * the old rect is not intersect with moved rect,
+ * re-paint window
+ */
+ struct rtgui_event_paint epaint;
+ RTGUI_EVENT_PAINT_INIT(&epaint);
+ epaint.wid = topwin->wid;
+ rtgui_application_send(topwin->tid, &(epaint.parent), sizeof(epaint));
}
+
+ return RT_EOK;
}
/*
* resize a top win
* Note: currently, only support resize hidden window
*/
-void rtgui_topwin_resize(struct rtgui_win* wid, rtgui_rect_t* r)
+void rtgui_topwin_resize(struct rtgui_win* wid, rtgui_rect_t* rect)
{
struct rtgui_topwin* topwin;
+ struct rtgui_region region;
/* find in show list */
- topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_hide_list);
- if (topwin)
+ topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_list);
+ if (topwin == RT_NULL ||
+ !(topwin->flag & WINTITLE_SHOWN))
+ return;
+
+ /* record the old rect */
+ rtgui_region_init_with_extents(&region, &topwin->extent);
+ /* union the new rect so this is the region we should redraw */
+ rtgui_region_union_rect(&region, &region, rect);
+
+ topwin->extent = *rect;
+
+ if (topwin->title != RT_NULL)
{
- topwin->extent = *r;
+ /* get win extent */
+ rtgui_rect_t rect = topwin->extent;
- if (topwin->title != RT_NULL)
+ /* add border rect */
+ if (topwin->flag & WINTITLE_BORDER)
{
- /* get win extent */
- rtgui_rect_t rect = topwin->extent;
+ rtgui_rect_inflate(&rect, WINTITLE_BORDER_SIZE);
+ }
- /* add border rect */
- if (topwin->flag & WINTITLE_BORDER)
- {
- rtgui_rect_inflate(&rect, WINTITLE_BORDER_SIZE);
- }
+ /* add title rect */
+ if (!(topwin->flag & WINTITLE_NO))
+ rect.y1 -= WINTITLE_HEIGHT;
- /* add title rect */
- if (!(topwin->flag & WINTITLE_NO)) rect.y1 -= WINTITLE_HEIGHT;
+ RTGUI_WIDGET(topwin->title)->extent = rect;
+ }
- RTGUI_WIDGET(topwin->title)->extent = rect;
+ /* update windows clip info */
+ rtgui_topwin_update_clip();
- /* update title & border clip info */
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(topwin->title));
- rtgui_region_subtract_rect(&(RTGUI_WIDGET(topwin->title)->clip),
- &(RTGUI_WIDGET(topwin->title)->clip),
- &(topwin->extent));
- }
+ /* update old window coverage area */
+ rtgui_topwin_redraw(rtgui_region_extents(&region));
+}
+
+static struct rtgui_topwin* _rtgui_topwin_get_focus_from_list(struct rtgui_dlist_node *list)
+{
+ struct rtgui_dlist_node *node;
+
+ RT_ASSERT(list != RT_NULL);
+
+ rtgui_dlist_foreach(node, list, next)
+ {
+ struct rtgui_topwin *child = get_topwin_from_list(node);
+ if (child->flag & WINTITLE_ACTIVATE)
+ return child;
+
+ child = _rtgui_topwin_get_focus_from_list(&child->child_list);
+ if (child != RT_NULL)
+ return child;
}
+
+ return RT_NULL;
}
-struct rtgui_topwin* rtgui_topwin_get_wnd(int x, int y)
+struct rtgui_topwin* rtgui_topwin_get_focus(void)
{
- struct rtgui_list_node* node;
- struct rtgui_topwin* topwin;
+#if 1
+ // debug code
+ struct rtgui_topwin *topwin = _rtgui_topwin_get_focus_from_list(&_rtgui_topwin_list);
- /* search in list */
- rtgui_list_foreach(node, &(_rtgui_topwin_show_list))
+ if (topwin != RT_NULL)
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+ RT_ASSERT(topwin == the_desktop_topwin ||\
+ get_topwin_from_list(the_desktop_topwin->child_list.next) ==
+ _rtgui_topwin_get_root_win(topwin));
+#else
+ RT_ASSERT(get_topwin_from_list(_rtgui_topwin_list.next) ==
+ _rtgui_topwin_get_root_win(topwin));
+#endif
+
+ return topwin;
+#else
+ return _rtgui_topwin_get_focus_from_list(&_rtgui_topwin_list);
+#endif
+}
+
+static struct rtgui_topwin* _rtgui_topwin_get_wnd_from_tree(struct rtgui_dlist_node *list,
+ int x, int y,
+ rt_bool_t exclude_modaled)
+{
+ struct rtgui_dlist_node *node;
+ struct rtgui_topwin *topwin, *target;
+
+ RT_ASSERT(list != RT_NULL);
+
+ rtgui_dlist_foreach(node, list, next)
{
- topwin = rtgui_list_entry(node, struct rtgui_topwin, list);
+ topwin = get_topwin_from_list(node);
+ if (!(topwin->flag & WINTITLE_SHOWN))
+ break;
+
+ /* if higher window have this point, return it */
+ target = _rtgui_topwin_get_wnd_from_tree(&topwin->child_list, x, y, exclude_modaled);
+ if (target != RT_NULL)
+ return target;
+
+ if (exclude_modaled && (topwin->flag & WINTITLE_MODALED))
+ break;
- /* is this window? */
if ((topwin->title != RT_NULL) &&
rtgui_rect_contains_point(&(RTGUI_WIDGET(topwin->title)->extent), x, y) == RT_EOK)
{
@@ -654,105 +829,186 @@ struct rtgui_topwin* rtgui_topwin_get_wnd(int x, int y)
return RT_NULL;
}
-extern struct rtgui_list_node _rtgui_panel_list;
-static void rtgui_topwin_update_clip()
+struct rtgui_topwin* rtgui_topwin_get_wnd(int x, int y)
+{
+ return _rtgui_topwin_get_wnd_from_tree(&_rtgui_topwin_list, x, y, RT_FALSE);
+}
+
+struct rtgui_topwin* rtgui_topwin_get_wnd_no_modaled(int x, int y)
+{
+ return _rtgui_topwin_get_wnd_from_tree(&_rtgui_topwin_list, x, y, RT_TRUE);
+}
+
+/* clip region from topwin, and the windows beneath it. */
+rt_inline void _rtgui_topwin_clip_to_region(struct rtgui_region *region,
+ struct rtgui_topwin *topwin)
+{
+ RT_ASSERT(region != RT_NULL);
+ RT_ASSERT(topwin != RT_NULL);
+
+ if (topwin->title != RT_NULL)
+ {
+ rtgui_region_reset(&(RTGUI_WIDGET(topwin->title)->clip),
+ &(RTGUI_WIDGET(topwin->title)->extent));
+ rtgui_region_intersect(&(RTGUI_WIDGET(topwin->title)->clip),
+ &(RTGUI_WIDGET(topwin->title)->clip),
+ region);
+ rtgui_region_subtract_rect(&(RTGUI_WIDGET(topwin->title)->clip),
+ &(RTGUI_WIDGET(topwin->title)->clip),
+ &topwin->extent);
+ }
+
+ rtgui_region_reset(&RTGUI_WIDGET(topwin->wid)->clip,
+ &RTGUI_WIDGET(topwin->wid)->extent);
+ rtgui_region_intersect(&RTGUI_WIDGET(topwin->wid)->clip,
+ &RTGUI_WIDGET(topwin->wid)->clip,
+ region);
+}
+
+static void rtgui_topwin_update_clip(void)
{
- rt_int32_t count = 0;
+ struct rtgui_topwin *top;
struct rtgui_event_clip_info eclip;
- struct rtgui_list_node* node = _rtgui_topwin_show_list.next;
+ /* Note that the region is a "female die", that means it's the region you
+ * can paint to, not the region covered by others.
+ */
+ struct rtgui_region region_available;
+
+ if (rtgui_dlist_isempty(&_rtgui_topwin_list) ||
+ !(get_topwin_from_list(_rtgui_topwin_list.next)->flag & WINTITLE_SHOWN))
+ return;
RTGUI_EVENT_CLIP_INFO_INIT(&eclip);
- rtgui_list_foreach(node, &_rtgui_topwin_show_list)
- {
- struct rtgui_topwin* wnd;
- wnd = rtgui_list_entry(node, struct rtgui_topwin, list);
+ rtgui_region_init_rect(&region_available, 0, 0,
+ rtgui_graphic_driver_get_default()->width,
+ rtgui_graphic_driver_get_default()->height);
+
+ /* from top to bottom. */
+ top = _rtgui_topwin_get_topmost_window_shown();
- eclip.num_rect = count;
- eclip.wid = wnd->wid;
+ while (top != RT_NULL)
+ {
+ /* clip the topwin */
+ _rtgui_topwin_clip_to_region(&region_available, top);
+#if 0
+ /* debug window clipping */
+ rt_kprintf("clip %s ", top->wid->title);
+ rtgui_region_dump(&region_available);
+ rt_kprintf("\n");
+#endif
- count ++;
+ /* update available region */
+ if (top->title != RT_NULL)
+ rtgui_region_subtract_rect(&region_available, &region_available, &RTGUI_WIDGET(top->title)->extent);
+ else
+ rtgui_region_subtract_rect(&region_available, &region_available, &top->extent);
- /* send to destination window */
- rtgui_thread_send(wnd->tid, &(eclip.parent), sizeof(struct rtgui_event_clip_info));
+ /* send clip event to destination window */
+ eclip.wid = top->wid;
+ rtgui_application_send(top->tid, &(eclip.parent), sizeof(struct rtgui_event_clip_info));
- /* update clip in win title */
- if (wnd->title != RT_NULL)
- {
- /* reset clip info */
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(wnd->title));
- rtgui_region_subtract_rect(&(RTGUI_WIDGET(wnd->title)->clip),
- &(RTGUI_WIDGET(wnd->title)->clip),
- &(wnd->extent));
- }
+ /* move to next sibling tree */
+ if (top->parent == RT_NULL)
+ if (top->list.next != &_rtgui_topwin_list &&
+ get_topwin_from_list(top->list.next)->flag & WINTITLE_SHOWN)
+ top = _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(top->list.next));
+ else
+ break;
+ else if (top->list.next != &top->parent->child_list &&
+ get_topwin_from_list(top->list.next)->flag & WINTITLE_SHOWN)
+ top = _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(top->list.next));
+ /* level up */
+ else
+ top = top->parent;
}
+}
+
+static void _rtgui_topwin_redraw_tree(struct rtgui_dlist_node *list,
+ struct rtgui_rect* rect,
+ struct rtgui_event_paint *epaint)
+{
+ struct rtgui_dlist_node *node;
- /* send clip info to each panel */
- eclip.wid = RT_NULL;
- eclip.num_rect = count;
+ RT_ASSERT(list != RT_NULL);
+ RT_ASSERT(rect != RT_NULL);
+ RT_ASSERT(epaint != RT_NULL);
- rtgui_list_foreach(node, &(_rtgui_panel_list))
+ /* skip the hidden windows */
+ rtgui_dlist_foreach(node, list, prev)
{
- struct rtgui_panel* panel;
- struct rtgui_list_node* panel_node;
+ if (get_topwin_from_list(node)->flag & WINTITLE_SHOWN)
+ break;
+ }
- panel = rtgui_list_entry(node, struct rtgui_panel, sibling);
+ for (; node != list; node = node->prev)
+ {
+ struct rtgui_topwin *topwin;
- rtgui_list_foreach(panel_node, &(panel->thread_list))
+ topwin = get_topwin_from_list(node);
+
+ //FIXME: intersect with clip?
+ if (rtgui_rect_is_intersect(rect, &(topwin->extent)) == RT_EOK)
{
- struct rtgui_panel_thread* thread;
- thread = rtgui_list_entry(panel_node, struct rtgui_panel_thread, list);
+ epaint->wid = topwin->wid;
+ rtgui_application_send(topwin->tid, &(epaint->parent), sizeof(*epaint));
- /* send clip info to panel */
- rtgui_thread_send(thread->tid, &(eclip.parent), sizeof(struct rtgui_event_clip_info));
+ /* draw title */
+ if (topwin->title != RT_NULL)
+ {
+ rtgui_theme_draw_win(topwin);
+ }
}
+
+ _rtgui_topwin_redraw_tree(&topwin->child_list, rect, epaint);
}
}
static void rtgui_topwin_redraw(struct rtgui_rect* rect)
{
- struct rtgui_list_node* node;
struct rtgui_event_paint epaint;
RTGUI_EVENT_PAINT_INIT(&epaint);
epaint.wid = RT_NULL;
- rtgui_list_foreach(node, &_rtgui_topwin_show_list)
- {
- struct rtgui_topwin* wnd = rtgui_list_entry(node, struct rtgui_topwin, list);
+ _rtgui_topwin_redraw_tree(&_rtgui_topwin_list, rect, &epaint);
+}
- if (rtgui_rect_is_intersect(rect, &(wnd->extent)) == RT_EOK)
- {
- /* draw window */
- epaint.wid = wnd->wid;
- rtgui_thread_send(wnd->tid, &(epaint.parent), sizeof(epaint));
+/* a window enter modal mode will modal all the sibling window and parent
+ * window all along to the root window(which parent is RT_NULL or the desktop
+ * window if there is). If a root window modals, there is nothing to do here.*/
+rt_err_t rtgui_topwin_modal_enter(struct rtgui_event_win_modal_enter* event)
+{
+ struct rtgui_topwin *topwin, *parent_top;
+ struct rtgui_dlist_node *node;
- /* draw title */
- if (wnd->title != RT_NULL)
- {
- rtgui_theme_draw_win(wnd);
- }
- }
- }
+ topwin = rtgui_topwin_search_in_list(event->wid, &_rtgui_topwin_list);
- /* redraw the panel */
- rtgui_list_foreach(node, &(_rtgui_panel_list))
- {
- struct rtgui_panel* panel;
- panel = rtgui_list_entry(node, struct rtgui_panel, sibling);
+ if (topwin == RT_NULL)
+ return -RT_ERROR;
- if (rtgui_rect_is_intersect(rect, &(panel->extent)) == RT_EOK)
- {
- rt_thread_t tid;
+ if (IS_ROOT_WIN(topwin))
+ return RT_EOK;
- tid = rtgui_panel_get_active_thread(panel);
- if (tid != RT_NULL)
- {
- /* draw panel */
- epaint.wid = RT_NULL;
- rtgui_thread_send(tid, &(epaint.parent), sizeof(epaint));
- }
- }
+ parent_top = topwin->parent;
+
+ /* modal window should be on top already */
+ RT_ASSERT(get_topwin_from_list(parent_top->child_list.next) == topwin);
+
+ while (!IS_ROOT_WIN(parent_top))
+ {
+ rtgui_dlist_foreach(node, &parent_top->child_list, next)
+ get_topwin_from_list(node)->flag |= WINTITLE_MODALED;
+ parent_top->flag |= WINTITLE_MODALED;
+
+ parent_top = parent_top->parent;
}
+ /* mark root window as modaled */
+ parent_top->flag |= WINTITLE_MODALED;
+
+ topwin->flag &= ~WINTITLE_MODALED;
+ topwin->flag |= WINTITLE_MODALING;
+
+ return RT_EOK;
}
void rtgui_topwin_title_onmouse(struct rtgui_topwin* win, struct rtgui_event_mouse* event)
@@ -763,7 +1019,7 @@ void rtgui_topwin_title_onmouse(struct rtgui_topwin* win, struct rtgui_event_mou
if (rtgui_rect_contains_point(&win->extent, event->x, event->y) == RT_EOK)
{
/* send mouse event to thread */
- rtgui_thread_send(win->tid, &(event->parent), sizeof(struct rtgui_event_mouse));
+ rtgui_application_send(win->tid, &(event->parent), sizeof(struct rtgui_event_mouse));
return;
}
@@ -790,7 +1046,7 @@ void rtgui_topwin_title_onmouse(struct rtgui_topwin* win, struct rtgui_event_mou
}
#endif
}
- else if (event->button & RTGUI_MOUSE_BUTTON_UP)
+ else if (win->flag & WINTITLE_CB_PRESSED && event->button & RTGUI_MOUSE_BUTTON_UP)
{
if (rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
{
@@ -802,7 +1058,7 @@ void rtgui_topwin_title_onmouse(struct rtgui_topwin* win, struct rtgui_event_mou
/* send close event to window */
RTGUI_EVENT_WIN_CLOSE_INIT(&event);
event.wid = win->wid;
- rtgui_thread_send(win->tid, &(event.parent), sizeof(struct rtgui_event_win));
+ rtgui_application_send(win->tid, &(event.parent), sizeof(struct rtgui_event_win));
}
}
}
@@ -816,11 +1072,9 @@ void rtgui_topwin_append_monitor_rect(struct rtgui_win* wid, rtgui_rect_t* rect)
if (wid == RT_NULL || rect == RT_NULL) return;
/* find topwin */
- win = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_show_list);
+ win = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_list);
if (win == RT_NULL)
- win = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_hide_list);
-
- if (win == RT_NULL) return;
+ return;
/* append rect to top window monitor rect list */
rtgui_mouse_monitor_append(&(win->monitor_list), rect);
@@ -831,51 +1085,54 @@ void rtgui_topwin_remove_monitor_rect(struct rtgui_win* wid, rtgui_rect_t* rect)
struct rtgui_topwin* win;
/* parameters check */
- if (wid == RT_NULL || rect == RT_NULL) return;
+ if (wid == RT_NULL || rect == RT_NULL)
+ return;
/* find topwin */
- win = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_show_list);
+ win = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_list);
if (win == RT_NULL)
- win = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_hide_list);
-
- if (win == RT_NULL) return;
+ return;
/* remove rect from top window monitor rect list */
rtgui_mouse_monitor_remove(&(win->monitor_list), rect);
}
-/**
- * do clip for topwin list
- * widget, the clip widget to be done clip
- */
-void rtgui_topwin_do_clip(rtgui_widget_t* widget)
+static void _rtgui_topwin_dump(struct rtgui_topwin *topwin)
{
- rtgui_widget_t* wid;
- struct rtgui_rect* rect;
- struct rtgui_topwin* topwin;
- struct rtgui_list_node* node;
+ rt_kprintf("0x%p:%s,0x%x", topwin, topwin->wid->title, topwin->flag);
+}
+
+static void _rtgui_topwin_dump_tree(struct rtgui_topwin *topwin)
+{
+ struct rtgui_dlist_node *node;
- /* get toplevel wid */
- wid = widget->toplevel;
+ _rtgui_topwin_dump(topwin);
- rt_sem_take(&_rtgui_topwin_lock, RT_WAITING_FOREVER);
- /* get all of topwin rect list */
- rtgui_list_foreach(node, &_rtgui_topwin_show_list)
+ rt_kprintf("(");
+ rtgui_dlist_foreach(node, &topwin->child_list, next)
{
- topwin = rtgui_list_entry(node, struct rtgui_topwin, list);
-
- if (topwin->wid == (rtgui_win_t*)(wid) ||
- RTGUI_WIDGET(topwin->title) == widget) break; /* it's self window, break */
+ _rtgui_topwin_dump_tree(get_topwin_from_list(node));
+ }
+ rt_kprintf(")");
+}
- /* get extent */
- if (topwin->title != RT_NULL)
- rect = &(RTGUI_WIDGET(topwin->title)->extent);
- else
- rect = &(topwin->extent);
+void rtgui_topwin_dump_tree(void)
+{
+ struct rtgui_dlist_node *node;
- /* subtract the topwin rect */
- rtgui_region_subtract_rect(&(widget->clip), &(widget->clip), rect);
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+ _rtgui_topwin_dump(the_desktop_topwin);
+ rt_kprintf("\n");
+ rtgui_dlist_foreach(node, &the_desktop_topwin->child_list, next)
+ {
+ _rtgui_topwin_dump_tree(get_topwin_from_list(node));
+ rt_kprintf("\n");
}
- rt_sem_release(&_rtgui_topwin_lock);
+#else
+ rtgui_dlist_foreach(node, &_rtgui_topwin_list, next)
+ {
+ _rtgui_topwin_dump_tree(get_topwin_from_list(node));
+ rt_kprintf("\n");
+ }
+#endif
}
-
diff --git a/components/rtgui/server/topwin.h b/components/rtgui/server/topwin.h
index 8ec5a5c6cc..bc9db9d284 100644
--- a/components/rtgui/server/topwin.h
+++ b/components/rtgui/server/topwin.h
@@ -15,7 +15,6 @@
#define __RTGUI_TOPWIN_H__
#include <rtgui/rtgui.h>
-#include <rtgui/list.h>
#include <rtgui/region.h>
#include <rtgui/event.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_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 */
-void rtgui_topwin_show(struct rtgui_event_win* event);
+rt_err_t rtgui_topwin_show(struct rtgui_event_win* event);
/* 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 */
-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 */
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) */
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 */
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_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
diff --git a/components/rtgui/widgets/about_view.c b/components/rtgui/widgets/about_view.c
index 45f9a9431e..6bc012b255 100644
--- a/components/rtgui/widgets/about_view.c
+++ b/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));
+}
diff --git a/components/rtgui/widgets/box.c b/components/rtgui/widgets/box.c
index e5fc0e8318..860245c0db 100644
--- a/components/rtgui/widgets/box.c
+++ b/components/rtgui/widgets/box.c
@@ -18,23 +18,23 @@
static void _rtgui_box_constructor(rtgui_box_t *box)
{
/* 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_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 */
box->orient = RTGUI_HORIZONTAL;
box->border_size = RTGUI_BORDER_DEFAULT_WIDTH;
}
-DEFINE_CLASS_TYPE(box, "box",
+DEFINE_CLASS_TYPE(box, "box",
RTGUI_CONTAINER_TYPE,
_rtgui_box_constructor,
RT_NULL,
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;
@@ -48,7 +48,7 @@ rt_bool_t rtgui_box_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
break;
default:
- return rtgui_container_event_handler(RTGUI_WIDGET(box), event);
+ return rtgui_container_event_handler(RTGUI_OBJECT(box), event);
}
return RT_FALSE;
@@ -166,7 +166,8 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box)
size_event.y = rect->y1;
size_event.w = rect->x2 - rect->x1;
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 */
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.w = rect->x2 - rect->x1;
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 */
next_x = rect->x2;
diff --git a/components/rtgui/widgets/button.c b/components/rtgui/widgets/button.c
index ecd4e24e87..a10d04ebbf 100644
--- a/components/rtgui/widgets/button.c
+++ b/components/rtgui/widgets/button.c
@@ -14,13 +14,13 @@
#include <rtgui/dc.h>
#include <rtgui/rtgui_theme.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)
{
/* init widget and set event handler */
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 */
button->flag = 0;
@@ -57,13 +57,16 @@ DEFINE_CLASS_TYPE(button, "button",
_rtgui_button_destructor,
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(event != RT_NULL);
- btn = (struct rtgui_button*) widget;
+ widget = RTGUI_WIDGET(object);
+ btn = RTGUI_BUTTON(widget);
switch (event->type)
{
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)
{
/* 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 */
if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
diff --git a/components/rtgui/widgets/checkbox.c b/components/rtgui/widgets/checkbox.c
index 35c76d46a5..78c3cd97c8 100644
--- a/components/rtgui/widgets/checkbox.c
+++ b/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;
+}
+
diff --git a/components/rtgui/widgets/combobox.c b/components/rtgui/widgets/combobox.c
index 972d467fed..282a975f08 100644
--- a/components/rtgui/widgets/combobox.c
+++ b/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;
+}
diff --git a/components/rtgui/widgets/container.c b/components/rtgui/widgets/container.c
index c1e90f719a..3e919ba19a 100644
--- a/components/rtgui/widgets/container.c
+++ b/components/rtgui/widgets/container.c
@@ -10,37 +10,55 @@
* Change Logs:
* Date Author Notes
* 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/window.h>
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));
-
- /* 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)
{
- /* destroy children of container */
rtgui_container_destroy_children(container);
}
static void _rtgui_container_update_toplevel(rtgui_container_t* container)
{
+ struct rtgui_win *window;
struct rtgui_list_node* node;
+ window = rtgui_widget_get_toplevel(RTGUI_WIDGET(container));
+
rtgui_list_foreach(node, &(container->children))
{
rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
/* set child toplevel */
- child->toplevel = rtgui_widget_get_toplevel(RTGUI_WIDGET(container));
+ child->toplevel = window;
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_container_constructor,
_rtgui_container_destructor,
@@ -65,7 +83,8 @@ rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_eve
struct rtgui_widget* w;
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;
@@ -75,64 +94,106 @@ rt_bool_t rtgui_container_dispatch_mouse_event(rtgui_container_t *container, str
{
/* handle in child widget */
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))
{
struct rtgui_widget* w;
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);
- 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;
}
-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)
{
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;
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;
case RTGUI_EVENT_MOUSE_BUTTON:
+ case RTGUI_EVENT_MOUSE_MOTION:
/* handle in child widget */
return rtgui_container_dispatch_mouse_event(container,
(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:
/* call parent widget event handler */
- return rtgui_widget_event_handler(widget, event);
+ return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event);
}
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
* 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(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 */
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->focused = RTGUI_WIDGET(container);
- if (RTGUI_WIDGET(container)->parent != RT_NULL)
- rtgui_widget_focus(RTGUI_WIDGET(container));
/* update widget clip */
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;
}
+
+#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;
+ }
+}
+
diff --git a/components/rtgui/widgets/filelist_view.c b/components/rtgui/widgets/filelist_view.c
index 3e38cb193f..14209749ca 100644
--- a/components/rtgui/widgets/filelist_view.c
+++ b/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},
+ {"���v�`����", RT_NULL},
+ {"�X��", 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("�X�̐`��㚔M");
+ 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
diff --git a/components/rtgui/widgets/iconbox.c b/components/rtgui/widgets/iconbox.c
index 860fc44476..1ba74e3ce2 100644
--- a/components/rtgui/widgets/iconbox.c
+++ b/components/rtgui/widgets/iconbox.c
@@ -19,7 +19,7 @@ static void _rtgui_iconbox_constructor(rtgui_iconbox_t *iconbox)
{
/* init widget and set event handler */
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 */
iconbox->image = RT_NULL;
@@ -46,9 +46,14 @@ DEFINE_CLASS_TYPE(iconbox, "iconbox",
_rtgui_iconbox_destructor,
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)
{
diff --git a/components/rtgui/widgets/label.c b/components/rtgui/widgets/label.c
index 59cf22b6f4..db8528e139 100644
--- a/components/rtgui/widgets/label.c
+++ b/components/rtgui/widgets/label.c
@@ -19,7 +19,7 @@
static void _rtgui_label_constructor(rtgui_label_t *label)
{
/* 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 */
label->text = RT_NULL;
@@ -38,13 +38,12 @@ DEFINE_CLASS_TYPE(label, "label",
_rtgui_label_destructor,
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)
{
case RTGUI_EVENT_PAINT:
diff --git a/components/rtgui/widgets/list_view.c b/components/rtgui/widgets/list_view.c
index 99783f2cf3..1b45365271 100644
--- a/components/rtgui/widgets/list_view.c
+++ b/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));
+}
diff --git a/components/rtgui/widgets/listbox.c b/components/rtgui/widgets/listbox.c
index 0ce5aebe32..859cbc1304 100644
--- a/components/rtgui/widgets/listbox.c
+++ b/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);
+ }
+}
+
diff --git a/components/rtgui/widgets/listctrl.c b/components/rtgui/widgets/listctrl.c
index 23e5c8696a..6fdc4028d6 100644
--- a/components/rtgui/widgets/listctrl.c
+++ b/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;
+}
diff --git a/components/rtgui/widgets/menu.c b/components/rtgui/widgets/menu.c
index 7d8b02dd3b..c56041db83 100644
--- a/components/rtgui/widgets/menu.c
+++ b/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);
+}
+
diff --git a/components/rtgui/widgets/notebook.c b/components/rtgui/widgets/notebook.c
index 667baa9ec2..c928cd268d 100644
--- a/components/rtgui/widgets/notebook.c
+++ b/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;
+}
diff --git a/components/rtgui/widgets/progressbar.c b/components/rtgui/widgets/progressbar.c
index 84e2adea1d..c42f2a3688 100644
--- a/components/rtgui/widgets/progressbar.c
+++ b/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;
+}
+
diff --git a/components/rtgui/widgets/radiobox.c b/components/rtgui/widgets/radiobox.c
index a4f1f7de94..b886c584c4 100644
--- a/components/rtgui/widgets/radiobox.c
+++ b/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;
+}
diff --git a/components/rtgui/widgets/scrollbar.c b/components/rtgui/widgets/scrollbar.c
index 5581ba0560..58a3017b3c 100644
--- a/components/rtgui/widgets/scrollbar.c
+++ b/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;
+}
diff --git a/components/rtgui/widgets/slider.c b/components/rtgui/widgets/slider.c
index d44954f9b4..30d29d84f9 100644
--- a/components/rtgui/widgets/slider.c
+++ b/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;
+}
diff --git a/components/rtgui/widgets/staticline.c b/components/rtgui/widgets/staticline.c
index a1c38bbd20..19a1caed49 100644
--- a/components/rtgui/widgets/staticline.c
+++ b/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
+}
diff --git a/components/rtgui/widgets/textbox.c b/components/rtgui/widgets/textbox.c
index 4bbaaed615..15f2bd44ef 100644
--- a/components/rtgui/widgets/textbox.c
+++ b/components/rtgui/widgets/textbox.c
@@ -25,13 +25,13 @@
#define RTGUI_TEXTBOX_MARGIN 3
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)
{
rtgui_textbox_t* box;
-
+
box = (rtgui_textbox_t*)parameter;
/* set caret flag */
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(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_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);
}
-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 */
box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
/* start caret timer */
@@ -238,10 +240,12 @@ static rt_bool_t rtgui_textbox_onfocus(struct rtgui_widget* widget, struct rtgui
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 */
rtgui_timer_stop(box->caret_timer);
/* set caret to hide */
@@ -250,10 +254,12 @@ static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_widget* widget, struct rtg
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)
{
case RTGUI_EVENT_PAINT:
diff --git a/components/rtgui/widgets/textview.c b/components/rtgui/widgets/textview.c
index 2bb7a41e1d..fe57b82ab2 100644
--- a/components/rtgui/widgets/textview.c
+++ b/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));
+}
diff --git a/components/rtgui/widgets/toplevel.c b/components/rtgui/widgets/toplevel.c
index eeabcf09a8..b6882e7c3b 100644
--- a/components/rtgui/widgets/toplevel.c
+++ b/components/rtgui/widgets/toplevel.c
@@ -13,26 +13,25 @@
*/
#include <rtgui/rtgui_system.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)
{
/* 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 */
- 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 */
toplevel->drawing = 0;
/* hide toplevel default */
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)
@@ -41,51 +40,35 @@ static void _rtgui_toplevel_destructor(rtgui_toplevel_t* toplevel)
toplevel->drawing = 0;
}
-DEFINE_CLASS_TYPE(toplevel, "toplevel",
+DEFINE_CLASS_TYPE(toplevel, "toplevel",
RTGUI_CONTAINER_TYPE,
_rtgui_toplevel_constructor,
_rtgui_toplevel_destructor,
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)
{
- 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:
/* update toplevel clip */
rtgui_toplevel_update_clip(toplevel);
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:
- 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
- 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
}
@@ -93,38 +76,23 @@ rt_bool_t rtgui_toplevel_event_handler(rtgui_widget_t* widget, rtgui_event_t* ev
break;
default :
- return rtgui_container_event_handler(widget, event);
+ return rtgui_container_event_handler(object, event);
}
return RT_FALSE;
}
-#include <rtgui/driver.h> /* to get screen rect */
-
void rtgui_toplevel_update_clip(rtgui_toplevel_t* top)
{
- rtgui_container_t* container;
+ rtgui_container_t* view;
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 */
- 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);
diff --git a/components/rtgui/widgets/view.c b/components/rtgui/widgets/view.c
deleted file mode 100644
index 0f35f42eb4..0000000000
--- a/components/rtgui/widgets/view.c
+++ /dev/null
@@ -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;
- }
-}
diff --git a/components/rtgui/widgets/widget.c b/components/rtgui/widgets/widget.c
index 91a14ac27e..e639eb8bed 100644
--- a/components/rtgui/widgets/widget.c
+++ b/components/rtgui/widgets/widget.c
@@ -14,10 +14,11 @@
*/
#include <rtgui/dc_client.h>
+#include <rtgui/rtgui_application.h>
#include <rtgui/widgets/widget.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)
{
@@ -40,23 +41,25 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget)
#endif
/* 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 */
- 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
- 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
/* 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 */
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)
{
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;
}
+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
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)
{
- rtgui_container_t *parent;
+ struct rtgui_widget *old_focus;
RT_ASSERT(widget != RT_NULL);
- if (!widget->parent || !widget->toplevel) return;
if (!RTGUI_WIDGET_IS_FOCUSABLE(widget) || !RTGUI_WIDGET_IS_ENABLE(widget))
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 */
- 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 */
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)
{
+
RT_ASSERT(widget != RT_NULL);
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;
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 */
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;
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;
/* get the toplevel widget */
- while (r->parent != RT_NULL) r = r->parent;
+ while (r->parent != RT_NULL)
+ r = r->parent;
/* 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
+ struct rtgui_widget *widget;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ widget = RTGUI_WIDGET(object);
+
switch (event->type)
{
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;
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;
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;
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;
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;
}
#endif
@@ -441,14 +462,9 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
if (widget == RT_NULL || RTGUI_WIDGET_IS_HIDE(widget)) return;
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 (RTGUI_IS_TOPLEVEL(widget))
- {
- /* if it's toplevel widget, update it by toplevel function */
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(widget));
- }
return;
}
@@ -479,7 +495,7 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
* 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))
{
rtgui_widget_t* child;
@@ -490,17 +506,25 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
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)
{
/* there is no parent or the parent is hide, no show at all */
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 */
RTGUI_WIDGET_UNHIDE(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)
@@ -521,10 +545,10 @@ void rtgui_widget_hide(rtgui_widget_t* widget)
/* union widget rect */
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)
@@ -567,9 +591,11 @@ void rtgui_widget_update(rtgui_widget_t* widget)
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);
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)
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("extent(%d, %d) - (%d, %d)\n", widget->extent.x1,
diff --git a/components/rtgui/widgets/window.c b/components/rtgui/widgets/window.c
index c1df9379ff..f8d5db3d24 100644
--- a/components/rtgui/widgets/window.c
+++ b/components/rtgui/widgets/window.c
@@ -15,27 +15,37 @@
#include <rtgui/color.h>
#include <rtgui/image.h>
#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_server.h>
+#include <rtgui/rtgui_application.h>
#include <rtgui/widgets/window.h>
#include <rtgui/widgets/button.h>
-#include <rtgui/widgets/workbench.h>
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 */
- 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 */
RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
/* set window style */
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 */
win->user_data = 0;
@@ -45,12 +55,12 @@ static void _rtgui_win_destructor(rtgui_win_t* win)
{
struct rtgui_event_win_destroy edestroy;
- if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+ if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
{
/* destroy in server */
RTGUI_EVENT_WIN_DESTROY_INIT(&edestroy);
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)
{
/* destroy in server failed */
@@ -62,225 +72,238 @@ static void _rtgui_win_destructor(rtgui_win_t* win)
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;
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 */
- 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
- ecreate.extent = RTGUI_WIDGET(win)->extent;
+ ecreate.extent = RTGUI_WIDGET(win)->extent;
rt_strncpy((char*)ecreate.title, (char*)win->title, RTGUI_NAME_MAX);
#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);
return RT_FALSE;
}
- /* set server */
- RTGUI_TOPLEVEL(win)->server = server;
+ win->flag |= RTGUI_WIN_FLAG_CONNECTED;
}
return RT_TRUE;
}
-DEFINE_CLASS_TYPE(win, "win",
+DEFINE_CLASS_TYPE(win, "win",
RTGUI_TOPLEVEL_TYPE,
_rtgui_win_constructor,
_rtgui_win_destructor,
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;
/* 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;
+
+__on_err:
+ rtgui_widget_destroy(RTGUI_WIDGET(win));
+ return RT_NULL;
}
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);
}
else
- {
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 (RTGUI_TOPLEVEL(win)->server == RT_NULL)
+ if (!(win->flag & RTGUI_WIN_FLAG_CONNECTED))
{
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);
+ app = rtgui_application_self();
+ RT_ASSERT(app != RT_NULL);
- 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);
+ win->flag |= RTGUI_WIN_FLAG_MODAL;
- 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);
+ if (rtgui_server_post_event_sync((struct rtgui_event*)&emodal,
+ sizeof(emodal)) != RT_EOK)
+ return exit_code;
- result = win->modal_code;
- win->style &= ~RTGUI_WIN_STYLE_MODAL;
+ app->modal_object = RTGUI_OBJECT(win);
+
+ exit_code = rtgui_application_run(app);
+
+ 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)
{
- 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 */
- win->style &= ~RTGUI_WIN_STYLE_MODAL;
+ win->flag &= ~RTGUI_WIN_FLAG_MODAL;
}
void rtgui_win_hiden(struct rtgui_win* win)
{
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)) &&
- RTGUI_TOPLEVEL(win)->server != RT_NULL)
+ win->flag & RTGUI_WIN_FLAG_CONNECTED)
{
/* send hidden message to server */
struct rtgui_event_win_hide ehide;
RTGUI_EVENT_WIN_HIDE_INIT(&ehide);
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)
{
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 */
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);
- if (win->style & RTGUI_WIN_STYLE_ACTIVATE) return RT_TRUE;
+ if (win->flag & RTGUI_WIN_FLAG_ACTIVATE) return RT_TRUE;
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;
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 */
RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
- emove.wid = win;
+ emove.wid = win;
emove.x = x;
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)
{
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 */
RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
return;
@@ -342,7 +366,8 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win* win)
/* begin drawing */
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 */
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 */
RTGUI_EVENT_PAINT_INIT(&event);
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);
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)
{
@@ -376,22 +405,8 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
break;
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;
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;
}
- win->style |= RTGUI_WIN_STYLE_ACTIVATE;
+ win->flag |= RTGUI_WIN_FLAG_ACTIVATE;
#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
rtgui_widget_update(RTGUI_WIDGET(win));
if (win->on_activate != RT_NULL)
{
- win->on_activate(widget, event);
+ win->on_activate(RTGUI_OBJECT(object), event);
}
break;
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
{
- win->style &= ~RTGUI_WIN_STYLE_ACTIVATE;
+ win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE;
#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
- rtgui_win_ondraw(win);
+ rtgui_widget_update(RTGUI_WIDGET(win));
if (win->on_deactivate != RT_NULL)
{
- win->on_deactivate(widget, event);
+ win->on_deactivate(RTGUI_OBJECT(object), event);
}
}
break;
case RTGUI_EVENT_PAINT:
#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
#endif
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:
/* 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 */
- 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)
{
#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
}
@@ -512,101 +518,45 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
#endif
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:
/* call parent event handler */
- return rtgui_toplevel_event_handler(widget, event);
+ return rtgui_toplevel_event_handler(object, event);
}
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)
{
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;
- if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+ if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
{
/* set window resize event to server */
RTGUI_EVENT_WIN_RESIZE_INIT(&event);
event.wid = win;
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)
{
/* send title to server */
- if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+ if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
{
}
diff --git a/components/rtgui/widgets/workbench.c b/components/rtgui/widgets/workbench.c
deleted file mode 100644
index 4dd3f7e6e8..0000000000
--- a/components/rtgui/widgets/workbench.c
+++ /dev/null
@@ -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));
- }
- }
-}