diff options
Diffstat (limited to 'components')
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(®ion); - 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, ®ion); + 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(®ion)); + + /* 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(®ion, &topwin->extent); + /* union the new rect so this is the region we should redraw */ + rtgui_region_union_rect(®ion, ®ion, 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(®ion)); +} + +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(®ion_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(®ion_available, top); +#if 0 + /* debug window clipping */ + rt_kprintf("clip %s ", top->wid->title); + rtgui_region_dump(®ion_available); + rt_kprintf("\n"); +#endif - count ++; + /* update available region */ + if (top->title != RT_NULL) + rtgui_region_subtract_rect(®ion_available, ®ion_available, &RTGUI_WIDGET(top->title)->extent); + else + rtgui_region_subtract_rect(®ion_available, ®ion_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)); - } - } -} |
