diff --git a/components/rtgui/SConscript b/components/rtgui/SConscript index afe253a1e6..0192454551 100644 --- a/components/rtgui/SConscript +++ b/components/rtgui/SConscript @@ -9,6 +9,7 @@ common/rtgui_object.c common/rtgui_system.c common/rtgui_theme.c common/rtgui_xml.c +common/rtgui_app.c common/dc.c common/dc_hw.c common/dc_buffer.c @@ -34,7 +35,6 @@ common/pixel_driver.c """) server_src = Split(""" -server/rtgui_application.c server/driver.c server/mouse.c server/server.c @@ -63,10 +63,10 @@ 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 +widgets/panel.c """) # The set of source files associated with this SConscript file. diff --git a/components/rtgui/common/blit.c b/components/rtgui/common/blit.c index a9b0b36749..1d84fc3a00 100644 --- a/components/rtgui/common/blit.c +++ b/components/rtgui/common/blit.c @@ -1,3 +1,9 @@ +/* + * Change Logs: + * Date Author Notes + * 2012-01-24 onelife add one more blit table which exchanges the + * positions of R and B color components in output + */ #include #include @@ -305,3 +311,63 @@ rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp) return _blit_table[dst_bpp][src_bpp]; } + + +static void rtgui_blit_line_3_2_inv(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 << 8) & 0x0000F800) | + ((*(src_ptr + 1) << 3) & 0x000007E0) | + ((*(src_ptr + 2) >> 3) & 0x0000001F)); + + src_ptr += 3; + dst ++; + line --; + } + + return; +} + +void rtgui_blit_line_2_2_inv(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line) +{ + rt_uint16_t *dst, *src; + + dst = (rt_uint16_t *)dst_ptr; + src = (rt_uint16_t *)src_ptr; + line = line / 2; + while (line) + { + *dst = ((*src << 11) & 0xF800) | (*src & 0x07E0) | ((*src >> 11) & 0x001F); + src ++; + dst ++; + line --; + } +} + +static const rtgui_blit_line_func _blit_table_inv[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_2_2_inv, rtgui_blit_line_3_2_inv, 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_inv(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_inv[dst_bpp][src_bpp]; +} + diff --git a/components/rtgui/common/dc.c b/components/rtgui/common/dc.c index fa8b85225a..97e6fcaf5c 100644 --- a/components/rtgui/common/dc.c +++ b/components/rtgui/common/dc.c @@ -138,12 +138,12 @@ void rtgui_dc_draw_vertical_line(struct rtgui_dc* dc, int x, int y1, int y2) color = RTGUI_DC_FC(dc); RTGUI_DC_FC(dc) = dark_grey; - rtgui_dc_draw_hline(dc, x, y1, y2); + rtgui_dc_draw_vline(dc, x, y1, y2); x ++; RTGUI_DC_FC(dc) = high_light; - rtgui_dc_draw_hline(dc, x, y1, y2); + rtgui_dc_draw_vline(dc, x, y1, y2); /* restore color */ RTGUI_DC_FC(dc) = color; diff --git a/components/rtgui/common/dc_client.c b/components/rtgui/common/dc_client.c index 22d2887095..154eb359bd 100644 --- a/components/rtgui/common/dc_client.c +++ b/components/rtgui/common/dc_client.c @@ -21,7 +21,7 @@ #include #include -#include +#include #include #include #include @@ -139,7 +139,7 @@ struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner) #endif } } - else if (RTGUI_IS_APPLICATION(owner->toplevel)) + else if (RTGUI_IS_APP(owner->toplevel)) { RT_ASSERT(0); } @@ -207,7 +207,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc) #endif } } - else if (RTGUI_IS_APPLICATION(owner->toplevel) || + else if (RTGUI_IS_APP(owner->toplevel) || RTGUI_IS_WIN(owner->toplevel)) { rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel); diff --git a/components/rtgui/common/dc_hw.c b/components/rtgui/common/dc_hw.c index 2895797974..db226fd152 100644 --- a/components/rtgui/common/dc_hw.c +++ b/components/rtgui/common/dc_hw.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include @@ -117,7 +117,7 @@ struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner) #endif } } - else if (RTGUI_IS_APPLICATION(owner->toplevel) || + else if (RTGUI_IS_APP(owner->toplevel) || RTGUI_IS_WIN(owner->toplevel)) { rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel); @@ -184,7 +184,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc) #endif } } - else if (RTGUI_IS_APPLICATION(owner->toplevel) || + else if (RTGUI_IS_APP(owner->toplevel) || RTGUI_IS_WIN(owner->toplevel)) { rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel); diff --git a/components/rtgui/common/framebuffer_driver.c b/components/rtgui/common/framebuffer_driver.c index 04c21c42a5..3d46732ebb 100644 --- a/components/rtgui/common/framebuffer_driver.c +++ b/components/rtgui/common/framebuffer_driver.c @@ -1,3 +1,8 @@ +/* + * Change Logs: + * Date Author Notes + * 2012-01-24 onelife fix a bug in framebuffer_draw_raw_hline + */ #include #include @@ -108,7 +113,7 @@ 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)); + rt_memcpy(dst, pixels, (x2 - x1 + 1) * (rtgui_graphic_get_device()->bits_per_pixel/8)); } const struct rtgui_graphic_driver_ops _framebuffer_rgb565_ops = diff --git a/components/rtgui/common/image.c b/components/rtgui/common/image.c index 1ae57e0ece..358ba2bff5 100644 --- a/components/rtgui/common/image.c +++ b/components/rtgui/common/image.c @@ -10,6 +10,7 @@ * Change Logs: * Date Author Notes * 2009-10-16 Bernard first version + * 2012-01-24 onelife add TJpgDec (Tiny JPEG Decompressor) support */ #include #include @@ -27,7 +28,7 @@ #ifdef RTGUI_IMAGE_BMP #include #endif -#ifdef RTGUI_IMAGE_JPEG +#if (defined(RTGUI_IMAGE_JPEG) || defined(RTGUI_IMAGE_TJPGD)) #include #endif #ifdef RTGUI_IMAGE_PNG @@ -50,7 +51,7 @@ void rtgui_system_image_init(void) rtgui_image_bmp_init(); #endif -#ifdef RTGUI_IMAGE_JPEG +#if (defined(RTGUI_IMAGE_JPEG) || defined(RTGUI_IMAGE_TJPGD)) rtgui_image_jpeg_init(); #endif diff --git a/components/rtgui/common/image_bmp.c b/components/rtgui/common/image_bmp.c index 1c7c108217..2374c7537b 100644 --- a/components/rtgui/common/image_bmp.c +++ b/components/rtgui/common/image_bmp.c @@ -1,3 +1,10 @@ +/* + * Change Logs: + * Date Author Notes + * 2012-01-24 onelife Reimplement to improve efficiency and add + * features. The new decoder uses configurable fixed size working buffer and + * provides scaledown function. + */ #include #include #include @@ -5,6 +12,10 @@ #include #include +#ifdef RTGUI_USING_DFS_FILERW +#include +#endif + #ifdef RTGUI_IMAGE_BMP /* Compression encodings for BMP files */ #ifndef BI_RGB @@ -14,57 +25,32 @@ #define BI_BITFIELDS 3 #endif -#define hw_driver (rtgui_graphic_driver_get_default()) +#define BMP_WORKING_BUFFER_SIZE (384) /* In multiple of 12 and bigger than 48 */ +#define BMP_MAX_SCALING_FACTOR (10) // TODO: find the max value! +#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; + rt_uint32_t w, h; + rt_uint32_t pixel_offset; + rt_uint32_t pitch; rt_uint8_t scale; + rt_uint8_t bit_per_pixel; + rt_uint8_t pad; }; -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, + rt_uint32_t *width, rt_uint32_t *height); +static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, + struct rtgui_filerw* file, rt_uint8_t scale, rt_bool_t load); */ 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", @@ -75,342 +61,429 @@ struct rtgui_image_engine rtgui_image_bmp_engine = 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) +//static rt_bool_t rtgui_image_bmp_check(struct rtgui_filerw* file, +// rt_uint32_t *width, rt_uint32_t *height) { - char magic[2]; - rt_bool_t is_bmp; - rt_off_t start; + rt_uint8_t buffer[18]; + rt_bool_t is_bmp = RT_FALSE; - if ( !file ) return 0; + do + { + if (!file ) + { + break; + } - 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') + /* Prepare to decode */ + if (rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET) < 0) + { + break; + } + if (rtgui_filerw_read(file, (void *)buffer, 18, 1) != 18) + { + break; + } + /* Read file type */ + if (buffer[0] != 'B' || buffer[1] != 'M') { - is_bmp = RT_TRUE; + break; } - } - rtgui_filerw_seek(file, start, RTGUI_FILE_SEEK_SET); + /* Read BMP header size */ + if (*(rt_uint32_t *)&buffer[14] == 12) + { /* Bitmap Header Version 2.x */ + if (rtgui_filerw_read(file, (void *)buffer, 8, 1) != 8) + { + break; + } + /* Read image size */ +// *width = (rt_uint32_t)*(rt_uint16_t *)&buffer[0]; +// *height = (rt_uint32_t)*(rt_uint16_t *)&buffer[2]; + is_bmp = RT_TRUE; + } + else + { /* Bitmap Header Version bigger than 2.x */ + if (rtgui_filerw_read(file, (void *)buffer, 8, 1) != 8) + { + break; + } + /* Read image size */ +// *width = *(rt_uint32_t *)&buffer[0]; +// *height = *(rt_uint32_t *)&buffer[4]; + is_bmp = RT_TRUE; + } + } while(0); - return(is_bmp); + return is_bmp; } -static struct rtgui_image_palette* rtgui_image_bmp_load_palette(struct rtgui_image_bmp_header* header, struct rtgui_filerw* src) +static struct rtgui_image_palette* rtgui_image_bmp_load_palette( + struct rtgui_filerw* file, + rt_uint32_t colorsUsed, + rt_bool_t alpha) { /* Load the palette, if any */ - rt_size_t i; - struct rtgui_image_palette* palette; + rt_uint32_t i; + struct rtgui_image_palette *palette; - if (header->biClrUsed == 0) - header->biClrUsed = 1 << header->biBitCount; + palette = rtgui_image_palette_create(colorsUsed); + if (palette == RT_NULL) + { + return RT_NULL; + } - 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); - } - } + if (alpha) + { + rt_uint8_t temp[4]; + for (i = 0; i < colorsUsed; i++) + { + if (rtgui_filerw_read(file, (void *)&temp, 1, 4) != 4) + { + rtgui_free(palette); + return RT_NULL; + } + palette->colors[i] = RTGUI_ARGB(temp[3], temp[2], temp[1], temp[0]); + } + } + else + { + rt_uint8_t temp[3]; + for (i = 0; i < colorsUsed; i++) + { + if (rtgui_filerw_read(file, (void *)&temp, 1, 3) != 3) + { + rtgui_free(palette); + return RT_NULL; + } + palette->colors[i] = RTGUI_RGB(temp[2], temp[1], temp[0]); + } + } return palette; } -static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_filerw* src, rt_bool_t load) +static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, struct rtgui_filerw* file, rt_bool_t load) +//static rt_bool_t rtgui_image_bmp_load(struct rtgui_image* image, +// struct rtgui_filerw* file, rt_uint8_t scale, rt_bool_t load) { - rt_uint32_t Rmask; - rt_uint32_t Gmask; - rt_uint32_t Bmask; - int ExpandBMP, bmpPitch; + rt_uint8_t scale = 2; + rt_uint8_t *wrkBuffer; struct rtgui_image_bmp* bmp; - struct rtgui_image_bmp_header* header; - struct rtgui_image_palette* palette; + rt_uint32_t bmpHeaderSize; + rt_uint32_t colorsUsed; - 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 (scale > BMP_MAX_SCALING_FACTOR) + { + 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') + do + { + wrkBuffer = (rt_uint8_t *)rt_malloc(BMP_WORKING_BUFFER_SIZE); + if (wrkBuffer == RT_NULL) + { + rt_kprintf("BMP err: no mem\n"); + break; + } + + bmp = (struct rtgui_image_bmp*)rtgui_malloc(sizeof(struct rtgui_image_bmp)); + if (bmp == RT_NULL) + { + break; + } + + /* Prepare to decode */ + if (rtgui_filerw_seek(file, 0, RTGUI_FILE_SEEK_SET) < 0) + { + break; + } + if (rtgui_filerw_read(file, (void *)wrkBuffer, 18, 1) != 18) + { + break; + } + /* Read file type */ + if (wrkBuffer[0] != 'B' || wrkBuffer[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 */ +// rt_kprintf("BMP: format ok\n"); + /* Read pixel array offset */ + bmp->pixel_offset = *(rt_uint32_t *)&wrkBuffer[10]; +// rt_kprintf("BMP: bmp->pixel_offset %d\n", bmp->pixel_offset); + /* Read BMP header size */ + bmpHeaderSize = *(rt_uint32_t *)&wrkBuffer[14]; +// rt_kprintf("BMP: bmpHeaderSize %d\n", bmpHeaderSize); + colorsUsed = 0; + if (bmpHeaderSize == 12) + { /* Bitmap Header Version 2.x */ + if (rtgui_filerw_read(file, (void *)wrkBuffer, 8, 1) != 8) + { + break; + } + /* Read image size */ + bmp->w = (rt_uint32_t)*(rt_uint16_t *)&wrkBuffer[0]; + bmp->h = (rt_uint32_t)*(rt_uint16_t *)&wrkBuffer[2]; + /* Read bits per pixel */ + bmp->bit_per_pixel = (rt_uint8_t)*(rt_uint16_t *)&wrkBuffer[6]; + } + else + { /* Bitmap Header Version bigger than 2.x */ + rt_uint32_t compression; - 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; + if (rtgui_filerw_read(file, (void *)wrkBuffer, 36, 1) != 36) + { + break; + } + /* Read image size */ + bmp->w = *(rt_uint32_t *)&wrkBuffer[0]; + bmp->h = *(rt_uint32_t *)&wrkBuffer[4]; + /* Read bits per pixel */ + bmp->bit_per_pixel = (rt_uint8_t)*(rt_uint16_t *)&wrkBuffer[10]; + if (bmp->bit_per_pixel > 32) + { + rt_kprintf("BMP err: unsupported format\n"); + break; + } + /* Read compression method */ + compression = *(rt_uint32_t *)&wrkBuffer[12]; + if (compression != BI_RGB && compression != BI_BITFIELDS) + { + rt_kprintf("BMP err: unsupported format\n"); + break; + } + /* Read number of colors */ + colorsUsed = *(rt_uint32_t *)&wrkBuffer[28]; + } + if (!colorsUsed) + { + colorsUsed = 1 << bmp->bit_per_pixel; + } - default: - break; - } - break; + /* Load palette */ + if (bmp->bit_per_pixel <= 8) + { + if (rtgui_filerw_seek(file, 14 + bmpHeaderSize, RTGUI_FILE_SEEK_SET) < 0) + { + break; + } - default: - rt_kprintf("Compressed BMP files not supported\n"); - goto __exit; - } + image->palette = rtgui_image_bmp_load_palette(file, colorsUsed, + bmpHeaderSize > 12 ? RT_TRUE : RT_FALSE); + if (image->palette == RT_NULL) + { + break; + } + } - bmp = (struct rtgui_image_bmp*) rtgui_malloc(sizeof(struct rtgui_image_bmp)); - if (bmp == RT_NULL) - goto __exit; + /* Set image information */ + bmp->is_loaded = RT_FALSE; + bmp->scale = scale; + if (bmp->bit_per_pixel == 1) + { + bmp->pitch = (bmp->w + 7) >> 3; + } + else if (bmp->bit_per_pixel == 4) + { + bmp->pitch = (bmp->w + 1) >> 1; + } + else + { + bmp->pitch = bmp->w * (bmp->bit_per_pixel >> 3); + } + bmp->pad = ((bmp->pitch % 4) ? (4 - (bmp->pitch % 4)) : 0); + bmp->pixels = RT_NULL; + bmp->filerw = file; - /* 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; + image->w = bmp->w >> bmp->scale; + image->h = bmp->h >> bmp->scale; + image->engine = &rtgui_image_bmp_engine; + image->data = bmp; - /* get padding */ - switch (ExpandBMP) - { - case 1: - bmpPitch = (header->biWidth + 7) >> 3; - bmp->pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); - break; + /* Start to decode */ + if (load == RT_TRUE) + { + rt_bool_t error = RT_FALSE; + rt_uint8_t *dst; + rt_uint32_t imageWidth; + rt_uint16_t readLength, readIndex, loadIndex; + rt_uint8_t skipLength; + rt_uint16_t y; + rt_uint8_t bytePerPixel; + rt_int8_t scale1, scale2; - case 4: - bmpPitch = (header->biWidth + 1) >> 1; - bmp->pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); - break; + bytePerPixel = bmp->bit_per_pixel / 8; + if (!bytePerPixel) + { + bytePerPixel = 1; + } + imageWidth = image->w * bytePerPixel; /* Scaled width in byte */ + bmp->pixels = rtgui_malloc(image->h * imageWidth); + if (bmp->pixels == RT_NULL) + { + rt_kprintf("BMP err: no mem to load (%d)\n", image->h * imageWidth); + break; + } - default: - bmp->pad = ((bmp->pitch%4) ? (4-(bmp->pitch%4)) : 0); - break; - } + /* Read the pixels. Note that the bmp image is upside down */ + if (rtgui_filerw_seek(file, bmp->pixel_offset, RTGUI_FILE_SEEK_SET) < 0) + { + break; + } - if (load == RT_TRUE) - { - rt_uint8_t *bits; - rt_uint32_t i; + if (bmp->bit_per_pixel == 1) + { + if (bmp->scale > 3) + { + scale1 = bmp->scale - 3; + scale2 = 3; + } + else + { + scale1 = 0; + scale2 = bmp->scale; + } + } + else if (bmp->bit_per_pixel == 4) + { + if (bmp->scale > 1) + { + scale1 = bmp->scale - 1; + scale2 = 1; + } + else + { + scale1 = 0; + scale2 = bmp->scale; + } + } - /* load all pixels */ - bmp->pixels = rtgui_malloc(image->h * bmp->pitch); - if (bmp->pixels == RT_NULL) - goto __exit; + /* Process whole image */ + y = 0; + while (y < image->h) + { + dst = bmp->pixels + (image->h - y - 1) * imageWidth; + readIndex = 0; + skipLength= 0; - /* 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; + /* Process a line */ + while (readIndex < bmp->pitch) + { + /* Put progress indicator */ + rt_kprintf("\r%lu%%", y * 100UL / image->h); - 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; + /* Read data to buffer */ + readLength = (BMP_WORKING_BUFFER_SIZE > (bmp->pitch - readIndex)) ? \ + (bmp->pitch - readIndex) : BMP_WORKING_BUFFER_SIZE; + if (rtgui_filerw_read(file, (void *)wrkBuffer, 1, readLength) != readLength) + { + rt_kprintf("BMP err: read failed\n"); + error = RT_TRUE; + break; + } + readIndex += readLength; - } - *(bits+i) = (pixel>>shift); - pixel <<= ExpandBMP; - } - } - break; + /* Process read buffer */ + if (bmp->bit_per_pixel == 1) + { + rt_uint8_t j; - default: - if ( rtgui_filerw_read(src, bits, 1, bmp->pitch) != bmp->pitch ) goto __exit; - break; - } + for (loadIndex = skipLength; loadIndex < readLength; loadIndex += 1 << scale1) + { + for (j = 0; j < 8; j += 1 << scale2) + { + *(dst++) = (wrkBuffer[loadIndex] & (1 << (7 - j))) >> (7 - j); + } + } + if (scale1 && (readLength % (1 << scale1))) + { + skipLength = (1 << scale1) - readLength % (1 << scale1); + } + } + else if (bmp->bit_per_pixel == 4) + { + rt_uint8_t j; - /* Skip padding bytes */ - if ( bmp->pad ) - { - rt_uint8_t padbyte; - for ( i=0; i < bmp->pad; ++i ) - { - rtgui_filerw_read(src, &padbyte, 1, 1); - } - } - } + for (loadIndex = skipLength; loadIndex < readLength; loadIndex += 1 << scale1) + { + for (j = 0; j < 8; j += 1 << (2 + scale2)) + { + *(dst++) = (wrkBuffer[loadIndex] & (0x0F << (4 - j))) >> (4 - j); + } + } + if (scale1 && (readLength % (1 << scale1))) + { + skipLength = (1 << scale1) - readLength % (1 << scale1); + } + } + else + { + if (bmp->scale == 0) + { + rt_memcpy((void *)dst, (void *)wrkBuffer, readLength); + dst += readLength; + } + else + { + for (loadIndex = skipLength; loadIndex < readLength; loadIndex += bytePerPixel << bmp->scale) + { + rt_memcpy((void *)dst, (void *)&wrkBuffer[loadIndex], bytePerPixel); + dst += bytePerPixel; + } + if (readLength % (1 << bmp->scale)) + { + skipLength = (1 << bmp->scale) - readLength % (1 << bmp->scale); + } + } + } + } + if (error) + { + break; + } + y++; - 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); - } + /* Skip padding bytes */ + if (bmp->pad) + { + if ( rtgui_filerw_seek(file, bmp->pad, RTGUI_FILE_SEEK_CUR) < 0) + { + error = RT_TRUE; + break; + } + } - return RT_TRUE; + /* Height scale down */ + if (bmp->scale) + { + if (rtgui_filerw_seek(file, (bmp->pitch + bmp->pad) * ((1 << bmp->scale) - 1), + RTGUI_FILE_SEEK_CUR) < 0) + { + error = RT_TRUE; + break; + } + } + } + if (error) + { + break; + } + /* Close file */ + rtgui_filerw_close(bmp->filerw); + bmp->filerw = RT_NULL; + bmp->is_loaded = RT_TRUE; +// rt_kprintf("BMP: load to RAM\n"); + } -__exit: - rtgui_free(header); - if (palette != RT_NULL) - { - rtgui_free(palette); - image->palette = RT_NULL; - } + /* Release memory */ + rt_free(wrkBuffer); + return RT_TRUE; + } while(0); - if (bmp != RT_NULL) - rtgui_free(bmp->pixels); + /* Release memory */ + rt_free(wrkBuffer); + rtgui_free(image->palette); + rtgui_free(bmp->pixels); rtgui_free(bmp); return RT_FALSE; } @@ -421,220 +494,324 @@ static void rtgui_image_bmp_unload(struct rtgui_image* image) if (image != RT_NULL) { - bmp = (struct rtgui_image_bmp*) image->data; + 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); + /* Release memory */ + rtgui_free(bmp->pixels); if (bmp->filerw != RT_NULL) { + /* Close file */ 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; + rt_uint16_t w, h; struct rtgui_image_bmp* bmp; + rt_uint8_t bytePerPixel; + rt_uint32_t imageWidth; + rt_bool_t error; - RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL); + bmp = (struct rtgui_image_bmp*)image->data; + RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL || bmp != RT_NULL); - /* this dc is not visible */ - if (rtgui_dc_get_visible(dc) != RT_TRUE) return; + bytePerPixel = bmp->bit_per_pixel / 8; + if (!bytePerPixel) + { + bytePerPixel = 1; + } + imageWidth = image->w * bytePerPixel; /* Scaled width in byte */ + error = RT_FALSE; - bmp = (struct rtgui_image_bmp*) image->data; - RT_ASSERT(bmp != RT_NULL); + do + { + /* this dc is not visible */ + if (rtgui_dc_get_visible(dc) != RT_TRUE) + { + break; + } - /* 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); + /* 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; + if (!bmp->is_loaded) + { + rt_uint8_t *wrkBuffer; + rt_uint16_t readLength, readIndex, loadIndex; + rt_uint8_t skipLength; + rt_uint16_t x, y; + rt_int8_t scale1, scale2; - /* 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; + wrkBuffer = (rt_uint8_t *)rt_malloc(BMP_WORKING_BUFFER_SIZE); + if (wrkBuffer == RT_NULL) + { + rt_kprintf("BMP err: no mem (%d)\n", BMP_WORKING_BUFFER_SIZE); + break; + } - 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; + /* Read the pixels. Note that the bmp image is upside down */ + if (rtgui_filerw_seek(bmp->filerw, bmp->pixel_offset, RTGUI_FILE_SEEK_SET) < 0) + { + break; + } - /* 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; + if (bmp->bit_per_pixel == 1) + { + if (bmp->scale > 3) + { + scale1 = bmp->scale - 3; + scale2 = 3; + } + else + { + scale1 = 0; + scale2 = bmp->scale; + } + } + else if (bmp->bit_per_pixel == 4) + { + if (bmp->scale > 1) + { + scale1 = bmp->scale - 1; + scale2 = 1; + } + else + { + scale1 = 0; + scale2 = bmp->scale; + } + } - /* calculate offset */ - switch (bmp->ExpandBMP) - { - case 1: - offset = (image->h - h) * (image->w/8) * bmp->byte_per_pixel; - break; + /* Process whole image */ + y = 0; + while (y < image->h) + { + x = 0; + readIndex = 0; + skipLength= 0; - case 4: - offset = (image->h - h) * (image->w/2) * bmp->byte_per_pixel; - break; + /* Process a line */ + while (readIndex < bmp->pitch) + { + /* Put progress indicator */ + rt_kprintf("\r%lu%%", y * 100UL / image->h); - 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); + /* Read data to buffer */ + readLength = (BMP_WORKING_BUFFER_SIZE > (bmp->pitch - readIndex)) ? \ + (bmp->pitch - readIndex) : BMP_WORKING_BUFFER_SIZE; + if (rtgui_filerw_read(bmp->filerw, (void *)wrkBuffer, 1, readLength) != readLength) + { + rt_kprintf("BMP err: read failed\n"); + error = RT_TRUE; + break; + } + readIndex += readLength; - if (bmp->ExpandBMP == 1 || bmp->ExpandBMP == 4) - { - int x; - rtgui_color_t color; - /* 1, 4 bit per pixels */ + /* Process read buffer */ + if (bmp->bit_per_pixel == 1) + { + rt_uint8_t j; + rtgui_color_t color; - /* 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; + for (loadIndex = skipLength; loadIndex < readLength; loadIndex += 1 << scale1) + { + for (j = 0; j < 8; j += 1 << scale2) + { + color = image->palette->colors[(wrkBuffer[loadIndex] & (1 << (7 - j))) >> (7 - j)]; + rtgui_dc_draw_color_point(dc, + dst_rect->x1 + x++, + dst_rect->y1 + image->h - y, + color); + } + if (scale1 && (readLength % (1 << scale1))) + { + skipLength = (1 << scale1) - readLength % (1 << scale1); + } + } + } + else if (bmp->bit_per_pixel == 4) + { + rt_uint8_t j; + rtgui_color_t color; - 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; - } + for (loadIndex = skipLength; loadIndex < readLength; loadIndex += 1 << scale1) + { + for (j = 0; j < 8; j += 1 << (2 + scale2)) + { + color = image->palette->colors[(wrkBuffer[loadIndex] & (0x0F << (4 - j))) >> (4 - j)]; + rtgui_dc_draw_color_point(dc, + dst_rect->x1 + x++, + dst_rect->y1 + image->h - y, + color); + } + } + if (scale1 && (readLength % (1 << scale1))) + { + skipLength = (1 << scale1) - readLength % (1 << scale1); + } + } + else if (bmp->bit_per_pixel == 8) + { + rtgui_color_t color; - /* 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); - } + for (loadIndex = skipLength; loadIndex < readLength; loadIndex += 1 << bmp->scale) + { + color = image->palette->colors[wrkBuffer[loadIndex]]; + rtgui_dc_draw_color_point(dc, + dst_rect->x1 + x++, + dst_rect->y1 + image->h - y, + color); + } + if (readLength % (1 << bmp->scale)) + { + skipLength = (1 << bmp->scale) - readLength % (1 << bmp->scale); + } + } + else + { + rtgui_blit_line_func blit_line; + rt_uint8_t hw_bytePerPixel = hw_driver->bits_per_pixel / 8; + rt_uint8_t temp[4] = {0}; - /* 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; + if (!hw_bytePerPixel) + { + hw_bytePerPixel = 1; + } - /* draw each line */ - for (y = h - 1; y >= 0; y --) - { - /* read line pixels */ - rtgui_filerw_read(bmp->filerw, bmp->line_pixels, 1, bmp->pitch); + if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565) + { + blit_line = rtgui_blit_line_get_inv(hw_bytePerPixel, bytePerPixel); + } + else + { + blit_line = rtgui_blit_line_get(hw_bytePerPixel, bytePerPixel); + } - /* 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); - } + for (loadIndex = skipLength; loadIndex < readLength; loadIndex += bytePerPixel << bmp->scale) + { + blit_line(temp, &wrkBuffer[loadIndex], bytePerPixel); + dc->engine->blit_line(dc, + dst_rect->x1 + x, dst_rect->x1 + x, + dst_rect->y1 + image->h - y, + temp); + x++; + } + if (readLength % (1 << bmp->scale)) + { + skipLength = (1 << bmp->scale) - readLength % (1 << bmp->scale); + } + } + } + if (error) + { + break; + } + y++; - 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; + /* Skip padding bytes */ + if (bmp->pad) + { + if ( rtgui_filerw_seek(bmp->filerw, bmp->pad, RTGUI_FILE_SEEK_CUR) < 0) + { + error = RT_TRUE; + break; + } + } - /* 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); - } - } + /* Height scale down */ + if (bmp->scale) + { + if (rtgui_filerw_seek(bmp->filerw, (bmp->pitch + bmp->pad) * ((1 << bmp->scale) - 1), + RTGUI_FILE_SEEK_CUR) < 0) + { + error = RT_TRUE; + break; + } + } + } + if (error) + { + break; + } + /* Release memory */ + rt_free(wrkBuffer); +// rt_kprintf("BMP: load to display\n"); + } + else + { + rt_uint16_t x, y; + rt_uint8_t* ptr; + + for (y = 0; y < h; y ++) + { + ptr = bmp->pixels + (y * imageWidth); + if (bmp->bit_per_pixel <= 8) + { + rtgui_color_t color; + + /* Using palette */ + for (x = 0; x < w; x ++) + { + color = image->palette->colors[*(ptr++)]; + rtgui_dc_draw_color_point(dc, + dst_rect->x1 + x, + dst_rect->y1 + y, + color); + } + } + else + { + rtgui_blit_line_func blit_line; + rt_uint8_t hw_bytePerPixel = hw_driver->bits_per_pixel / 8; + rt_uint8_t temp[4] = {0}; + + if (!hw_bytePerPixel) + { + hw_bytePerPixel = 1; + } + + if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565) + { + blit_line = rtgui_blit_line_get_inv(hw_bytePerPixel, bytePerPixel); + } + else + { + blit_line = rtgui_blit_line_get(hw_bytePerPixel, bytePerPixel); + } + + for (x = 0; x < w; x ++) + { + blit_line(temp, ptr, bytePerPixel); + ptr += bytePerPixel; + dc->engine->blit_line(dc, + dst_rect->x1 + x, dst_rect->x1 + x, + dst_rect->y1 + y, + temp); + } + } + } + } +// rt_kprintf("BMP: blit ok\n"); + } while(0); } void rtgui_image_bmp_init() diff --git a/components/rtgui/common/image_jpg.c b/components/rtgui/common/image_jpg.c index decf6de8c7..0980fc68d1 100644 --- a/components/rtgui/common/image_jpg.c +++ b/components/rtgui/common/image_jpg.c @@ -1,3 +1,8 @@ +/* + * Change Logs: + * Date Author Notes + * 2012-01-24 onelife add TJpgDec (Tiny JPEG Decompressor) support + */ #include #include @@ -494,3 +499,477 @@ static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file) } #endif + +#if defined(RTGUI_IMAGE_TJPGD) +/***************************************************************************//** + * @file image_jpg.c + * @brief JPEG decoder using TJpgDec module (elm-chan.org) + * COPYRIGHT (C) 2012, RT-Thread Development Team + * @author onelife + * @version 1.0 + ******************************************************************************* + * @section License + * The license and distribution terms for this file may be found in the file + * LICENSE in this distribution or at http://www.rt-thread.org/license/LICENSE + ******************************************************************************* + * @section Change Logs + * Date Author Notes + * 2012-01-24 onelife Initial creation for limited memory devices + ******************************************************************************/ + +/***************************************************************************//** + * @addtogroup TJpgDec + * @{ + ******************************************************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "tjpgd.h" + +#include +#include +#include +#include + +#ifdef RTGUI_USING_DFS_FILERW +#include +#endif + +/* Private typedef -----------------------------------------------------------*/ +struct rtgui_image_jpeg +{ + struct rtgui_filerw* filerw; + struct rtgui_dc *dc; + rt_uint16_t dst_x, dst_y; + rt_uint16_t dst_w, dst_h; + rt_bool_t is_loaded; + rt_bool_t to_buffer; + rt_uint8_t scale; + rt_uint8_t byte_per_pixel; + JDEC tjpgd; /* jpeg structure */ + void *pool; + rt_uint8_t *pixels; +}; + +/* Private define ------------------------------------------------------------*/ +#define TJPGD_WORKING_BUFFER_SIZE (3100) +#define TJPGD_MAX_MCU_WIDTH_ON_DISP (2 * 8 * 4) /* Y component: 2x2; Display: 4-byte per pixel */ +#define TJPGD_MAX_SCALING_FACTOR (3) +#define hw_driver (rtgui_graphic_driver_get_default()) + +/* Private macro -------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file, + rt_uint16_t *width, rt_uint16_t *height); +static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image* image, + struct rtgui_filerw* file, rt_uint8_t scale, rt_bool_t load); */ +static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file); +static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image* image, struct rtgui_filerw* file, rt_bool_t load); +static void rtgui_image_jpeg_unload(struct rtgui_image* image); +static void rtgui_image_jpeg_blit(struct rtgui_image* image, + struct rtgui_dc* dc, struct rtgui_rect* dst_rect); + +/* Private variables ---------------------------------------------------------*/ +struct rtgui_image_engine rtgui_image_jpeg_engine = +{ + "jpeg", + {RT_NULL}, + rtgui_image_jpeg_check, + rtgui_image_jpeg_load, + rtgui_image_jpeg_unload, + rtgui_image_jpeg_blit +}; + +struct rtgui_image_engine rtgui_image_jpg_engine = +{ + "jpg", + {RT_NULL}, + rtgui_image_jpeg_check, + rtgui_image_jpeg_load, + rtgui_image_jpeg_unload, + rtgui_image_jpeg_blit +}; + +/* Private functions ---------------------------------------------------------*/ +void rtgui_image_jpeg_init() +{ + /* register jpeg on image system */ + rtgui_image_register_engine(&rtgui_image_jpeg_engine); + /* register jpg on image system */ + rtgui_image_register_engine(&rtgui_image_jpg_engine); +} + +static UINT tjpgd_in_func(JDEC *jdec, BYTE *buff, UINT ndata) +{ + struct rtgui_filerw *file = *(struct rtgui_filerw **)jdec->device; + + if (buff == RT_NULL) + { + return rtgui_filerw_seek(file, ndata, RTGUI_FILE_SEEK_CUR); + } + + return rtgui_filerw_read(file, (void *)buff, 1, ndata); +} + +static UINT tjpgd_out_func(JDEC *jdec, void *bitmap, JRECT *rect) +{ + struct rtgui_image_jpeg *jpeg = (struct rtgui_image_jpeg *)jdec->device; + rt_uint16_t w, h, y; + rt_uint16_t rectWidth; /* Width of source rectangular (bytes) */ + rt_uint8_t *src, *dst; + + /* Put progress indicator */ + if (rect->left == 0) + { + rt_kprintf("\r%lu%%", (rect->top << jpeg->scale) * 100UL / jdec->height); + } + + /* Copy the decompressed RGB rectanglar to the frame buffer */ + rectWidth = (rect->right - rect->left + 1) * jpeg->byte_per_pixel; + src = (rt_uint8_t *)bitmap; + + if (jpeg->to_buffer) + { + rt_uint16_t imageWidth; /* Width of image (bytes) */ + + imageWidth = (jdec->width >> jdec->scale) * jpeg->byte_per_pixel; + dst = jpeg->pixels + rect->top * imageWidth + rect->left * jpeg->byte_per_pixel; + /* Left-top of destination rectangular */ + for (h = rect->top; h <= rect->bottom; h++) + { + rt_memcpy(dst, src, rectWidth); + src += rectWidth; + dst += imageWidth; /* Next line */ + } + } + else + { + rtgui_blit_line_func blit_line = RT_NULL; + + w = rect->right < jpeg->dst_w ? rect->right : jpeg->dst_w; + w = w - rect->left + 1; + h = rect->bottom < jpeg->dst_h ? rect->bottom : jpeg->dst_h; + h = h - rect->top + 1; + if (jpeg->byte_per_pixel == hw_driver->bits_per_pixel / 8) + { + if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565) + { + blit_line = rtgui_blit_line_get_inv(hw_driver->bits_per_pixel / 8, jpeg->byte_per_pixel); + } + } + else + { + blit_line = rtgui_blit_line_get(hw_driver->bits_per_pixel / 8, jpeg->byte_per_pixel); + } + + if (blit_line) + { + rt_uint8_t line_buf[TJPGD_MAX_MCU_WIDTH_ON_DISP]; + + for (y = 0; y < h; y++) + { + blit_line(line_buf, src, w * jpeg->byte_per_pixel); + jpeg->dc->engine->blit_line(jpeg->dc, + jpeg->dst_x + rect->left, jpeg->dst_x + rect->left + w - 1, + jpeg->dst_y + rect->top + y, + line_buf); + src += rectWidth; + } + } + else + { + for (y = 0; y < h; y++) + { + jpeg->dc->engine->blit_line(jpeg->dc, + jpeg->dst_x + rect->left, jpeg->dst_x + rect->left + w - 1, + jpeg->dst_y + rect->top + y, + src); + src += rectWidth; + } + } + } + return 1; /* Continue to decompress */ +} + +static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file) +//static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file, +// rt_uint32_t *width, rt_uint32_t *height) +{ + rt_bool_t is_JPG; + JDEC tjpgd; + void *pool; + + is_JPG = RT_FALSE; + do + { + if (!file ) + { + break; + } + + pool = rt_malloc(TJPGD_WORKING_BUFFER_SIZE); + if (pool == RT_NULL) + { + rt_kprintf("TJPGD err: no mem\n"); + break; + } + + if (rtgui_filerw_seek(file, 0, SEEK_SET) == -1) + { + break; + } + + if (jd_prepare(&tjpgd, tjpgd_in_func, pool, + TJPGD_WORKING_BUFFER_SIZE, (void *)&file) == JDR_OK) + { +// *width = (rt_uint32_t)tjpgd.width; +// *height = (rt_uint32_t)tjpgd.height; + is_JPG = RT_TRUE; + } + + rt_kprintf("TJPGD: check OK\n"); + } while(0); + + rt_free(pool); + + return is_JPG; +} + +static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image* image, struct rtgui_filerw* file, rt_bool_t load) +//static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image* image, +// struct rtgui_filerw* file, rt_uint8_t scale, rt_bool_t load) +{ + rt_uint8_t scale = 2; + rt_bool_t res = RT_FALSE; + struct rtgui_image_jpeg *jpeg; + JRESULT ret; + + if (scale > TJPGD_MAX_SCALING_FACTOR) + { + return RT_FALSE; + } + + do + { + jpeg = (struct rtgui_image_jpeg *)rt_malloc(sizeof(struct rtgui_image_jpeg)); + if (jpeg == RT_NULL) + { + break; + } + jpeg->filerw = file; + jpeg->is_loaded = RT_FALSE; + jpeg->to_buffer = load; + jpeg->scale = scale; +#if (JD_FORMAT == 0) + jpeg->byte_per_pixel = 3; +#elif (JD_FORMAT == 1) + jpeg->byte_per_pixel = 2; +#endif + jpeg->pool = RT_NULL; + jpeg->pixels = RT_NULL; + + jpeg->pool = rt_malloc(TJPGD_WORKING_BUFFER_SIZE); + if (jpeg->pool == RT_NULL) + { + rt_kprintf("TJPGD err: no mem (%d)\n", TJPGD_WORKING_BUFFER_SIZE); + break; + } + + if (rtgui_filerw_seek(jpeg->filerw, 0, SEEK_SET) == -1) + { + break; + } + + ret = jd_prepare(&jpeg->tjpgd, tjpgd_in_func, jpeg->pool, + TJPGD_WORKING_BUFFER_SIZE, (void *)jpeg); + if (ret != JDR_OK) + { + if (ret == JDR_FMT3) + { + rt_kprintf("TJPGD: not supported format\n"); + } + break; + } + rt_kprintf("TJPGD: prepare OK\n"); + + image->w = (rt_uint16_t)jpeg->tjpgd.width >> jpeg->scale; + image->h = (rt_uint16_t)jpeg->tjpgd.height >> jpeg->scale; + + /* set image private data and engine */ + image->data = jpeg; + image->engine = &rtgui_image_jpeg_engine; + + if (jpeg->to_buffer == RT_TRUE) + { + jpeg->pixels = (rt_uint8_t *)rtgui_malloc( + jpeg->byte_per_pixel * image->w * image->h); + if (jpeg->pixels == RT_NULL) + { + rt_kprintf("TJPGD err: no mem to load (%d)\n", + jpeg->byte_per_pixel * image->w * image->h); + break; + } + + ret = jd_decomp(&jpeg->tjpgd, tjpgd_out_func, jpeg->scale); + if (ret != JDR_OK) + { + break; + } + + rtgui_filerw_close(jpeg->filerw); + jpeg->is_loaded = RT_TRUE; + + rt_kprintf("TJPGD: load to RAM\n"); + } + res = RT_TRUE; + } while(0); + + if (!res || jpeg->is_loaded) + { + rt_free(jpeg->pool); + } + if (!res) + { + rtgui_free(jpeg->pixels); + rt_free(jpeg); + } + + /* create jpeg image successful */ + return res; +} + + +static void rtgui_image_jpeg_unload(struct rtgui_image* image) +{ + if (image != RT_NULL) + { + struct rtgui_image_jpeg* jpeg; + + jpeg = (struct rtgui_image_jpeg*) image->data; + RT_ASSERT(jpeg != RT_NULL); + + if (jpeg->to_buffer == RT_TRUE) + { + if (jpeg->is_loaded == RT_TRUE) + { + rtgui_free(jpeg->pixels); + } + if (jpeg->is_loaded != RT_TRUE) + { + rtgui_filerw_close(jpeg->filerw); + } + } + else + { + rt_free(jpeg->pool); + rtgui_filerw_close(jpeg->filerw); + } + rt_free(jpeg); + } + rt_kprintf("TJPGD: unload\n"); +} + +static void rtgui_image_jpeg_blit(struct rtgui_image* image, + struct rtgui_dc* dc, struct rtgui_rect* dst_rect) +{ + rt_uint16_t w, h, y; + struct rtgui_image_jpeg *jpeg; + + jpeg = (struct rtgui_image_jpeg *) image->data; + RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL || jpeg != RT_NULL); + + do + { + /* this dc is not visible */ + if (rtgui_dc_get_visible(dc) != RT_TRUE) + { + break; + } + jpeg->dc= dc; + + /* 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 (!jpeg->is_loaded) + { + JRESULT ret; + + jpeg->dst_x = dst_rect->x1; + jpeg->dst_y = dst_rect->y1; + jpeg->dst_w = w; + jpeg->dst_h = h; + ret = jd_decomp(&jpeg->tjpgd, tjpgd_out_func, jpeg->scale); + if (ret != JDR_OK) + { + break; + } + rt_kprintf("TJPGD: load to display\n"); + } + else + { + rt_uint8_t* src = jpeg->pixels; + rt_uint16_t imageWidth = image->w * jpeg->byte_per_pixel; + rtgui_blit_line_func blit_line = RT_NULL; + + if (jpeg->byte_per_pixel == hw_driver->bits_per_pixel / 8) + { + if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565) + { + blit_line = rtgui_blit_line_get_inv(hw_driver->bits_per_pixel / 8, jpeg->byte_per_pixel); + } + } + else + { + blit_line = rtgui_blit_line_get(hw_driver->bits_per_pixel / 8, jpeg->byte_per_pixel); + } + + if (blit_line) + { + rt_uint16_t x; + rt_uint8_t temp[4]; + + for (y = 0; y < h; y++) + { + for (x = 0; x < w; x++) + { + blit_line(temp, src, jpeg->byte_per_pixel); + src += jpeg->byte_per_pixel; + dc->engine->blit_line(dc, + dst_rect->x1 + x, dst_rect->x1 + x, + dst_rect->y1 + y, + temp); + } + } + } + else + { + for (y = 0; y < h; y++) + { + dc->engine->blit_line(dc, + dst_rect->x1, dst_rect->x1 + w - 1, + dst_rect->y1 + y, + src); + src += imageWidth; + } + } + } + } while(0); +} +#endif /* defined(RTGUI_IMAGE_TJPGD) */ +/***************************************************************************//** + * @} + ******************************************************************************/ diff --git a/components/rtgui/common/image_png.c b/components/rtgui/common/image_png.c index 9c72ef02f4..5c858bfd6e 100644 --- a/components/rtgui/common/image_png.c +++ b/components/rtgui/common/image_png.c @@ -242,9 +242,16 @@ static void rtgui_image_png_unload(struct rtgui_image* image) static void rtgui_image_png_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect) { + struct rtgui_graphic_driver* hwdev = rtgui_graphic_get_device(); rt_uint16_t x, y, w, h; rtgui_color_t* ptr; struct rtgui_image_png* png; + int fg_maxsample; + int ialpha; + float alpha; + rtgui_color_t color; + rtgui_color_t c, bgcolor; + int fc[3], bc[3]; RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL); RT_ASSERT(image->data != RT_NULL); @@ -255,21 +262,56 @@ static void rtgui_image_png_blit(struct rtgui_image* image, struct rtgui_dc* dc, else w = rtgui_rect_width(*rect); if (image->h < rtgui_rect_height(*rect)) h = image->h; else h = rtgui_rect_height(*rect); + + fg_maxsample = (1 << png->info_ptr->bit_depth) - 1; if (png->pixels != RT_NULL) { ptr = (rtgui_color_t*)png->pixels; - /* draw each point within dc */ + bgcolor = rtgui_color_from_565(RTGUI_DC_BC(dc)); + bc[0] = RTGUI_RGB_R(bgcolor); + bc[1] = RTGUI_RGB_G(bgcolor); + bc[2] = RTGUI_RGB_B(bgcolor); + /* draw each point within dc */ for (y = 0; y < h; y ++) { for (x = 0; x < w; x++) { - /* not alpha */ - if ((*ptr >> 24) != 255) - { - rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, *ptr); - } - + c = *ptr; + ialpha = RTGUI_RGB_A(c); + if(ialpha == 0) + { + /* + * Foreground image is transparent hear. + * If the background image is already in the frame + * buffer, there is nothing to do. + */ + } + else if (ialpha == fg_maxsample) + { + /* + * Copy foreground pixel to frame buffer. + */ + rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, c); + } + else + { /* output = alpha * foreground + (1-alpha) * background */ + /* + * Compositing is necessary. + * Get floating-point alpha and its complement. + * Note: alpha is always linear: gamma does not + * affect it. + */ + fc[0] = RTGUI_RGB_R(c); + fc[1] = RTGUI_RGB_G(c); + fc[2] = RTGUI_RGB_B(c); + + alpha = (float) ialpha / fg_maxsample; + color = RTGUI_RGB( (rt_uint8_t)(fc[0]*alpha + bc[0]*(1-alpha)), + (rt_uint8_t)(fc[1]*alpha + bc[1]*(1-alpha)), + (rt_uint8_t)(fc[2]*alpha + bc[2]*(1-alpha))); + rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, color); + } /* move to next color buffer */ ptr ++; } diff --git a/components/rtgui/common/pixel_driver.c b/components/rtgui/common/pixel_driver.c index 31b22e164e..503efb76cd 100644 --- a/components/rtgui/common/pixel_driver.c +++ b/components/rtgui/common/pixel_driver.c @@ -1,9 +1,23 @@ +/* + * Change Logs: + * Date Author Notes + * 2012-01-24 onelife add mono color support + * 2012-01-24 onelife fix a bug in _pixel_draw_raw_hline + */ #include #include #define gfx_device (rtgui_graphic_get_device()->device) #define gfx_device_ops rt_graphix_ops(gfx_device) +static void _pixel_mono_set_pixel(rtgui_color_t *c, int x, int y) +{ + rt_uint8_t pixel; + + pixel = rtgui_color_to_mono(*c); + gfx_device_ops->set_pixel((char*)&pixel, x, y); +} + static void _pixel_rgb565p_set_pixel(rtgui_color_t *c, int x, int y) { rt_uint16_t pixel; @@ -28,6 +42,14 @@ static void _pixel_rgb888_set_pixel(rtgui_color_t *c, int x, int y) gfx_device_ops->set_pixel((char*)&pixel, x, y); } +static void _pixel_mono_get_pixel(rtgui_color_t *c, int x, int y) +{ + rt_uint8_t pixel; + + gfx_device_ops->get_pixel((char*)&pixel, x, y); + *c = rtgui_color_from_mono(pixel); +} + static void _pixel_rgb565p_get_pixel(rtgui_color_t *c, int x, int y) { rt_uint16_t pixel; @@ -52,6 +74,14 @@ static void _pixel_rgb888_get_pixel(rtgui_color_t *c, int x, int y) *c = rtgui_color_from_888(pixel); } +static void _pixel_mono_draw_hline(rtgui_color_t *c, int x1, int x2, int y) +{ + rt_uint8_t pixel; + + pixel = rtgui_color_to_mono(*c); + gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y); +} + static void _pixel_rgb565p_draw_hline(rtgui_color_t *c, int x1, int x2, int y) { rt_uint16_t pixel; @@ -76,6 +106,14 @@ static void _pixel_rgb888_draw_hline(rtgui_color_t *c, int x1, int x2, int y) gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y); } +static void _pixel_mono_draw_vline(rtgui_color_t *c, int x, int y1, int y2) +{ + rt_uint8_t pixel; + + pixel = rtgui_color_to_mono(*c); + gfx_device_ops->draw_vline((char*)&pixel, x, y1, y2); +} + static void _pixel_rgb565p_draw_vline(rtgui_color_t *c, int x, int y1, int y2) { rt_uint16_t pixel; @@ -102,13 +140,19 @@ static void _pixel_rgb888_draw_vline(rtgui_color_t *c, int x, int y1, int 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)); + gfx_device_ops->blit_line((char*)pixels, x1, x2, y); } /* pixel device */ +const struct rtgui_graphic_driver_ops _pixel_mono_ops = +{ + _pixel_mono_set_pixel, + _pixel_mono_get_pixel, + _pixel_mono_draw_hline, + _pixel_mono_draw_vline, + _pixel_draw_raw_hline, +}; + const struct rtgui_graphic_driver_ops _pixel_rgb565p_ops = { _pixel_rgb565p_set_pixel, @@ -140,6 +184,9 @@ const struct rtgui_graphic_driver_ops *rtgui_pixel_device_get_ops(int pixel_form { switch (pixel_format) { + case RTGRAPHIC_PIXEL_FORMAT_MONO: + return &_pixel_mono_ops; + case RTGRAPHIC_PIXEL_FORMAT_RGB565: return &_pixel_rgb565_ops; diff --git a/components/rtgui/common/rtgui_app.c b/components/rtgui/common/rtgui_app.c new file mode 100644 index 0000000000..f16a97cbf5 --- /dev/null +++ b/components/rtgui/common/rtgui_app.c @@ -0,0 +1,380 @@ +/* + * 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) + * 2012-07-07 Bernard move the send/recv message to the rtgui_system.c + */ + +#include +#include +#include + +static void _rtgui_app_constructor(struct rtgui_app *app) +{ + /* set event handler */ + rtgui_object_set_event_handler(RTGUI_OBJECT(app), + rtgui_app_event_handler); + + app->name = RT_NULL; + /* set EXITED so we can destroy an application that just created */ + app->state_flag = RTGUI_APP_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->main_object = RT_NULL; + app->on_idle = RT_NULL; +} + +static void _rtgui_app_destructor(struct rtgui_app *app) +{ + RT_ASSERT(app != RT_NULL); + + rt_free(app->name); + app->name = RT_NULL; +} + +DEFINE_CLASS_TYPE(application, "application", + RTGUI_OBJECT_TYPE, + _rtgui_app_constructor, + _rtgui_app_destructor, + sizeof(struct rtgui_app)); + +struct rtgui_app* rtgui_app_create( + rt_thread_t tid, + const char *title) +{ + rt_thread_t srv_tid; + struct rtgui_app *app; + struct rtgui_event_application event; + + RT_ASSERT(tid != RT_NULL); + RT_ASSERT(title != RT_NULL); + + /* create application */ + app = RTGUI_APP(rtgui_object_create(RTGUI_APP_TYPE)); + if (app == RT_NULL) + return RT_NULL; + + /* one thread only can create one rtgui application */ + RT_ASSERT(tid->user_data == 0); + 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("create msgq failed.\n"); + goto __mq_err; + } + + /* set application title */ + app->name = (unsigned char*)rt_strdup((char*)title); + if (app->name == RT_NULL) + goto __err; + + /* send a message to notify rtgui server */ + srv_tid = rtgui_get_server(); + if (srv_tid == RT_NULL) + { + rt_kprintf("gui server is not running.\n"); + goto __err; + } + + /* create the rtgui server application */ + if (srv_tid == rt_thread_self()) + return app; + + RTGUI_EVENT_APP_CREATE_INIT(&event); + event.app = app; + + /* notify rtgui server to one application has been created */ + if (rtgui_send_sync(srv_tid, RTGUI_EVENT(&event), sizeof(event)) == RT_EOK) + { + return app; + } + +__err: +__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_app_destroy(struct rtgui_app *app) +{ + rt_thread_t srv_tid; + _rtgui_application_check(app); + + if (!(app->state_flag & RTGUI_APP_FLAG_EXITED)) + { + rt_kprintf("cannot destroy a running application: %s.\n", + app->name); + return; + } + + /* send a message to notify rtgui server */ + srv_tid = rtgui_get_server(); + if (srv_tid != rt_thread_self()) /* must not the server thread */ + { + struct rtgui_event_application event; + RTGUI_EVENT_APP_DESTROY_INIT(&event); + event.app = app; + + if (rtgui_send_sync(srv_tid, RTGUI_EVENT(&event), sizeof(event)) != RT_EOK) + { + rt_kprintf("destroy an application in server failed\n"); + return ; + } + } + + app->tid->user_data = 0; + rt_mq_delete(app->mq); + rtgui_object_destroy(RTGUI_OBJECT(app)); +} + +struct rtgui_app* rtgui_app_self(void) +{ + struct rtgui_app *app; + rt_thread_t self; + + /* get current thread */ + self = rt_thread_self(); + app = (struct rtgui_app*)(self->user_data); + + return app; +} + +void rtgui_app_set_onidle(rtgui_idle_func_t onidle) +{ + struct rtgui_app *app; + + app = rtgui_app_self(); + if (app != RT_NULL) + app->on_idle = onidle; +} + +rtgui_idle_func_t rtgui_app_get_onidle(void) +{ + struct rtgui_app *app; + + app = rtgui_app_self(); + if (app != RT_NULL) + return app->on_idle; + else + return RT_NULL; +} + +rt_inline rt_bool_t _rtgui_application_dest_handle( + struct rtgui_app *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_app_event_handler(struct rtgui_object* object, rtgui_event_t* event) +{ + struct rtgui_app* app; + + RT_ASSERT(object != RT_NULL); + RT_ASSERT(event != RT_NULL); + + app = RTGUI_APP(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_APP_ACTIVATE: + if (app->main_object != RT_NULL) + { + rtgui_win_activate(RTGUI_WIN(app->main_object)); + if (app->modal_object != RT_NULL) + rtgui_win_activate(RTGUI_WIN(app->modal_object)); + } + else if (app->modal_object != RT_NULL) + { + rtgui_win_activate(RTGUI_WIN(app->modal_object)); + } + 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_app *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_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_recv(event, sizeof(union rtgui_event_generic)); + if (result == RT_EOK) + RTGUI_OBJECT(app)->event_handler(RTGUI_OBJECT(app), event); + } + } +} + +rt_base_t rtgui_app_run(struct rtgui_app *app) +{ + _rtgui_application_check(app); + + app->state_flag &= ~RTGUI_APP_FLAG_EXITED; + + _rtgui_application_event_loop(app); + + if (app->ref_count == 0) + app->state_flag |= RTGUI_APP_FLAG_EXITED; + + return app->exit_code; +} + +void rtgui_app_exit(struct rtgui_app* app, rt_uint16_t code) +{ + --app->ref_count; + app->exit_code = code; +} + +/** + * set this application as window manager + */ +rt_err_t rtgui_app_set_as_wm(void) +{ + rt_thread_t srv_tid; + struct rtgui_event_set_wm event; + struct rtgui_app* app; + + srv_tid = rtgui_get_server(); + app = rtgui_app_self(); + if (app != RT_NULL && srv_tid != RT_NULL) + { + /* notify rtgui server, this is a window manager */ + RTGUI_EVENT_SET_WM_INIT(&event); + event.app = app; + + rtgui_send_sync(srv_tid, RTGUI_EVENT(&event), sizeof(event)); + return RT_EOK; + } + + return RT_ERROR; +} + +void rtgui_app_set_main_win(struct rtgui_win* win) +{ + struct rtgui_app *app; + + app = rtgui_app_self(); + if (app != RT_NULL) + { + app->main_object = RTGUI_OBJECT(win); + } +} diff --git a/components/rtgui/common/rtgui_system.c b/components/rtgui/common/rtgui_system.c index b840893139..dce11bfaf5 100644 --- a/components/rtgui/common/rtgui_system.c +++ b/components/rtgui/common/rtgui_system.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include #include @@ -26,7 +26,7 @@ #define RTGUI_MEM_TRACE #endif -void rtgui_system_server_init(void) +void rtgui_system_server_init() { /* init image */ rtgui_system_image_init(); @@ -59,7 +59,7 @@ static void rtgui_time_out(void* parameter) event.timer = timer; - rtgui_application_send(timer->tid, &(event.parent), sizeof(rtgui_event_timer_t)); + rtgui_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) @@ -285,3 +285,416 @@ void rtgui_free(void* ptr) rt_free(ptr); } +#if defined(RTGUI_MEM_TRACE) && defined(RT_USING_FINSH) +#include +void list_mem(void) +{ + rt_kprintf("Current Used: %d, Maximal Used: %d\n", mem_info.allocated_size, mem_info.max_allocated); +} +FINSH_FUNCTION_EXPORT(list_mem, display memory information); +#endif + +/************************************************************************/ +/* RTGUI Event Dump */ +/************************************************************************/ + +#ifdef _WIN32 +#define RTGUI_EVENT_DEBUG +#endif + +#ifdef RTGUI_EVENT_DEBUG +const char *event_string[] = +{ + /* application event */ + "APP_CREATE", /* create an application */ + "APP_DESTROY", /* destroy an application */ + "APP_ACTIVATE", /* activate an application */ + + /* 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*/ + "SHOW", /* the widget is going to be shown */ + "HIDE", /* the widget is going to be hidden */ + "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_APP_CREATE: + case RTGUI_EVENT_APP_DESTROY: + case RTGUI_EVENT_APP_ACTIVATE: + { + struct rtgui_event_application *eapp = (struct rtgui_event_application *)event; + + rt_kprintf("app: %s", eapp->app->name); + } + break; + + 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 + +/************************************************************************/ +/* RTGUI IPC APIs */ +/************************************************************************/ +rt_err_t rtgui_send(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size) +{ + rt_err_t result; + struct rtgui_app *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_app*) (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_send_urgent(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size) +{ + rt_err_t result; + struct rtgui_app *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_app*) (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_send_sync(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size) +{ + rt_err_t r; + struct rtgui_app *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_app*) (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_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_recv(rtgui_event_t* event, rt_size_t event_size) +{ + struct rtgui_app* app; + rt_err_t r; + + RT_ASSERT(event != RT_NULL); + RT_ASSERT(event_size != 0); + + app = (struct rtgui_app*) (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_recv_nosuspend(rtgui_event_t* event, rt_size_t event_size) +{ + struct rtgui_app *app; + rt_err_t r; + + RT_ASSERT(event != RT_NULL); + RT_ASSERT(event != 0); + + app = (struct rtgui_app*) (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_recv_filter(rt_uint32_t type, rtgui_event_t* event, rt_size_t event_size) +{ + struct rtgui_app *app; + + RT_ASSERT(event != RT_NULL); + RT_ASSERT(event_size != 0); + + app = (struct rtgui_app*) (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_thread_t rtgui_get_server(void) +{ + return rt_thread_find("rtgui"); +} + diff --git a/components/rtgui/doc/attention.txt b/components/rtgui/doc/attention.txt index bb0de99966..d02745cd73 100644 --- a/components/rtgui/doc/attention.txt +++ b/components/rtgui/doc/attention.txt @@ -14,3 +14,5 @@ slider 澶勭悊涓婁笅閿紝涓婇潰鐨勫煎皬锛屼笅闈㈢殑鍊煎ぇ銆 6, view 涓嶅啀鎻愪緵 show 鏂规硶銆傚鏋滄兂鍗曠嫭鏄剧ず鎺т欢锛岃鐢 window 鍖呭惈涔嬨 +7, 鑻ョ獥鍙e湪閿姣(destroy)鏃舵病鏈夊叧闂紝鍒 RTGUI 浼氬厛鍏抽棴涔嬨備篃浼氳皟鐢 on_close 鍑芥暟 +浣嗘槸姝ゅ嚱鏁扮殑杩斿洖鍊间細琚拷鐣ャ diff --git a/components/rtgui/doc/road_map.txt b/components/rtgui/doc/road_map.txt index 74aa40fc3a..c14e519251 100644 --- a/components/rtgui/doc/road_map.txt +++ b/components/rtgui/doc/road_map.txt @@ -46,9 +46,9 @@ mq 鐨勬ā寮忋俽tgui_application 璁板綍褰撳墠渚濋檮鐨 panel锛屽拰 panel 鐨 ext 10, 鍦 widget 涓坊鍔 on_show 鍜 on_hide 浜嬩欢鍥炶皟鍑芥暟銆(Done) 11, 娣诲姞 EVENT_WIN_MODAL_ENTER 鍜 EVENT_WIN_MODAL_EXIT 浜嬩欢锛岀敤鏉ラ氱煡绐楀彛绠$悊鍣 -(topwin)涓涓獥鍙h繘鍏ユā鎬併傜獥鍙g鐞嗗櫒鏍规嵁杩欎釜杩涜鐩稿簲鐨勮缃 +(topwin)涓涓獥鍙h繘鍏ユā鎬併傜獥鍙g鐞嗗櫒鏍规嵁杩欎釜杩涜鐩稿簲鐨勮缃(Done) -12, rtgui_filelist_view 涓嶅繀缁ф壙鑷 container銆 +12, rtgui_filelist_view 涓嶅繀缁ф壙鑷 container銆(Deprecated) 13, 娣诲姞 desktop window 鏀寔銆(Done) 姒傚康涓庡悕璇嶏細 diff --git a/components/rtgui/include/rtgui/blit.h b/components/rtgui/include/rtgui/blit.h index df0d2a5b32..fb4564e6bc 100644 --- a/components/rtgui/include/rtgui/blit.h +++ b/components/rtgui/include/rtgui/blit.h @@ -5,5 +5,6 @@ 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); +rtgui_blit_line_func rtgui_blit_line_get_inv(int dst_bpp, int src_bpp); #endif diff --git a/components/rtgui/include/rtgui/color.h b/components/rtgui/include/rtgui/color.h index d8f5fce177..42eafbc96d 100644 --- a/components/rtgui/include/rtgui/color.h +++ b/components/rtgui/include/rtgui/color.h @@ -10,6 +10,7 @@ * Change Logs: * Date Author Notes * 2009-10-16 Bernard first version + * 2012-01-24 onelife add mono color support */ #ifndef __RTGUI_COLOR_H__ #define __RTGUI_COLOR_H__ @@ -45,6 +46,30 @@ extern const rtgui_color_t light_grey; * BBBB BBBB GGGG GGGG RRRR RRRR */ +/* convert rtgui color to mono */ +rt_inline rt_uint8_t rtgui_color_to_mono(rtgui_color_t c) +{ + rt_uint8_t pixel; + + pixel = (RTGUI_RGB_R(c) | RTGUI_RGB_G(c) | RTGUI_RGB_B(c)) ? 0x01 : 0x00; + return pixel; +} + +rt_inline rtgui_color_t rtgui_color_from_mono(rt_uint8_t pixel) +{ + rtgui_color_t color; + + if (pixel) + { + color = white; + } + else + { + color = black; + } + return color; +} + /* convert rtgui color to BBBBBGGGGGGRRRRR */ rt_inline rt_uint16_t rtgui_color_to_565(rtgui_color_t c) { diff --git a/components/rtgui/include/rtgui/driver.h b/components/rtgui/include/rtgui/driver.h index 664d9183f3..b341661dfd 100644 --- a/components/rtgui/include/rtgui/driver.h +++ b/components/rtgui/include/rtgui/driver.h @@ -54,6 +54,7 @@ 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_uint8_t* rtgui_graphic_driver_get_default_framebuffer(void); rt_err_t rtgui_graphic_set_device(rt_device_t device); diff --git a/components/rtgui/include/rtgui/event.h b/components/rtgui/include/rtgui/event.h index e20b5cabee..2a06f1850f 100644 --- a/components/rtgui/include/rtgui/event.h +++ b/components/rtgui/include/rtgui/event.h @@ -21,6 +21,11 @@ * rtgui_event_generic */ enum _rtgui_event_type { + /* applications event */ + RTGUI_EVENT_APP_CREATE, /* create an application */ + RTGUI_EVENT_APP_DESTROY, /* destroy an application */ + RTGUI_EVENT_APP_ACTIVATE, /* activate an application */ + /* window event */ RTGUI_EVENT_WIN_CREATE, /* create a window */ RTGUI_EVENT_WIN_DESTROY, /* destroy a window */ @@ -43,6 +48,8 @@ enum _rtgui_event_type 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_SHOW, /* the widget is going to be shown */ + RTGUI_EVENT_HIDE, /* the widget is going to be hidden */ RTGUI_EVENT_PAINT, /* paint on screen */ RTGUI_EVENT_TIMER, /* timer */ @@ -94,6 +101,24 @@ typedef struct rtgui_event rtgui_event_t; (e)->ack = RT_NULL; \ } while (0) +/* + * RTGUI Application Event + */ +struct rtgui_event_application +{ + struct rtgui_event parent; + + struct rtgui_app* app; +}; + +/* gui application init */ +#define RTGUI_EVENT_APP_CREATE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_APP_CREATE) +#define RTGUI_EVENT_APP_DESTROY_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_APP_DESTROY) +#define RTGUI_EVENT_APP_ACTIVATE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_APP_ACTIVATE) + +/* + * RTGUI Window Event + */ #define _RTGUI_EVENT_WIN_ELEMENTS \ struct rtgui_event parent; \ struct rtgui_win *wid; @@ -151,6 +176,16 @@ struct rtgui_event_win_resize #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 set window manager + */ +struct rtgui_event_set_wm +{ + struct rtgui_event parent; + struct rtgui_app *app; +}; +#define RTGUI_EVENT_SET_WM_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_SET_WM); + /* * RTGUI Other Event */ @@ -214,6 +249,12 @@ struct 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) +#define rtgui_event_show rtgui_event +#define rtgui_event_hide rtgui_event + +#define RTGUI_EVENT_SHOW_INIT(e) RTGUI_EVENT_INIT((e), RTGUI_EVENT_SHOW) +#define RTGUI_EVENT_HIDE_INIT(e) RTGUI_EVENT_INIT((e), RTGUI_EVENT_HIDE) + /* * RTGUI Mouse and Keyboard Event */ @@ -325,6 +366,12 @@ struct rtgui_event_resize union rtgui_event_generic { struct rtgui_event base; + + struct rtgui_event_application app_create; + struct rtgui_event_application app_destroy; + struct rtgui_event_application app_activate; + + struct rtgui_event_set_wm set_wm; struct rtgui_event_win win_base; struct rtgui_event_win_create win_create; struct rtgui_event_win_move win_move; diff --git a/components/rtgui/include/rtgui/rtgui.h b/components/rtgui/include/rtgui/rtgui.h index d35e17ec5e..188c354302 100644 --- a/components/rtgui/include/rtgui/rtgui.h +++ b/components/rtgui/include/rtgui/rtgui.h @@ -30,7 +30,7 @@ struct rtgui_font; typedef struct rtgui_win rtgui_win_t; typedef struct rtgui_workbench rtgui_workbench_t; -typedef rt_bool_t (*rtgui_event_handler_ptr)(struct rtgui_object* widget, struct rtgui_event* event); +typedef rt_bool_t (*rtgui_event_handler_ptr)(struct rtgui_object* object, struct rtgui_event* event); typedef void (*rtgui_onbutton_func_t)(struct rtgui_object* object, struct rtgui_event* event); struct rtgui_point diff --git a/components/rtgui/include/rtgui/rtgui_app.h b/components/rtgui/include/rtgui/rtgui_app.h new file mode 100644 index 0000000000..37bf77baec --- /dev/null +++ b/components/rtgui/include/rtgui/rtgui_app.h @@ -0,0 +1,88 @@ +/* + * 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 +#include +#include +#include + +DECLARE_CLASS_TYPE(application); + +/** Gets the type of a application */ +#define RTGUI_APP_TYPE (RTGUI_TYPE(application)) +/** Casts the object to an rtgui_workbench */ +#define RTGUI_APP(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_APP_TYPE, struct rtgui_app)) +/** Checks if the object is an rtgui_workbench */ +#define RTGUI_IS_APP(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_APP_TYPE)) + +enum rtgui_app_flag +{ + RTGUI_APP_FLAG_EXITED = 0x04, + RTGUI_APP_FLAG_SHOWN = 0x08 +}; + +typedef void (*rtgui_idle_func_t)(struct rtgui_object* obj, struct rtgui_event *event); + +struct rtgui_app +{ + struct rtgui_object parent; + + /* application name */ + unsigned char *name; + struct rtgui_image* icon; + + enum rtgui_app_flag state_flag; + + rt_uint16_t ref_count; + rt_uint16_t exit_code; + + /* the thread id */ + rt_thread_t tid; + /* the RTGUI server id */ + 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 in modal state by modal_object. If is + * RT_NULL, nothing modal windows. */ + struct rtgui_object *modal_object; + struct rtgui_object *main_object; + + /* on idle event handler */ + rtgui_idle_func_t on_idle; +}; + +/** + * create an application named @myname on thread @param tid + */ +struct rtgui_app* rtgui_app_create(rt_thread_t tid, const char *title); +void rtgui_app_destroy(struct rtgui_app *app); +rt_bool_t rtgui_app_event_handler(struct rtgui_object* obj, rtgui_event_t* event); + +rt_base_t rtgui_app_run(struct rtgui_app *app); +void rtgui_app_exit(struct rtgui_app *app, rt_uint16_t code); + +void rtgui_app_set_onidle(rtgui_idle_func_t onidle); +rtgui_idle_func_t rtgui_app_get_onidle(void); +struct rtgui_app* rtgui_app_self(void); + +rt_err_t rtgui_app_set_as_wm(void); +void rtgui_app_set_main_win(struct rtgui_win* win); + +#endif /* end of include guard: RTGUI_APPLICATION_H */ diff --git a/components/rtgui/include/rtgui/rtgui_application.h b/components/rtgui/include/rtgui/rtgui_application.h deleted file mode 100644 index 83c13aaff5..0000000000 --- a/components/rtgui/include/rtgui/rtgui_application.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 -#include -#include -#include - -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 33ae2ee061..e1e7e56112 100644 --- a/components/rtgui/include/rtgui/rtgui_config.h +++ b/components/rtgui/include/rtgui/rtgui_config.h @@ -77,5 +77,6 @@ //#define RTGUI_USING_DESKTOP_WINDOW #define RTGUI_EVENT_DEBUG -#undef RTGUI_USING_SMALL_SIZE +// #undef RTGUI_USING_SMALL_SIZE + #endif diff --git a/components/rtgui/include/rtgui/rtgui_object.h b/components/rtgui/include/rtgui/rtgui_object.h index eb9c005c30..8f38909bbe 100644 --- a/components/rtgui/include/rtgui/rtgui_object.h +++ b/components/rtgui/include/rtgui/rtgui_object.h @@ -31,7 +31,7 @@ extern "C" { /** Casts the function pointer to an rtgui_constructor */ #define RTGUI_DESTRUCTOR(destructor) ((rtgui_destructor_t)(destructor)) -/* pre-definetion */ +/* pre-definition */ struct rtgui_object; typedef struct rtgui_object rtgui_object_t; typedef void (*rtgui_constructor_t)(rtgui_object_t *object); @@ -125,9 +125,6 @@ rt_bool_t rtgui_object_event_handler(struct rtgui_object *object, struct rtgui_e /* 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, const char* func, int line); 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 8d1c57a6c4..f109f7297a 100644 --- a/components/rtgui/include/rtgui/rtgui_server.h +++ b/components/rtgui/include/rtgui/rtgui_server.h @@ -20,7 +20,7 @@ /* RTGUI server definitions */ /* top window definitions in server */ -enum +enum rtgui_topwin_flag { WINTITLE_NO = 0x01, WINTITLE_BORDER = 0x02, @@ -34,7 +34,9 @@ enum /* window is modaled by other window */ WINTITLE_MODALED = 0x80, /* window is modaling other window */ - WINTITLE_MODALING = 0x100 + WINTITLE_MODALING = 0x100, + WINTITLE_ONTOP = 0x200, + WINTITLE_ONBTM = 0x400, }; #define WINTITLE_HEIGHT 20 @@ -45,7 +47,7 @@ enum struct rtgui_topwin { /* the window flag */ - rt_uint32_t flag; + enum rtgui_topwin_flag flag; /* event mask */ rt_uint32_t mask; diff --git a/components/rtgui/include/rtgui/rtgui_system.h b/components/rtgui/include/rtgui/rtgui_system.h index 4f94ab83d1..ff9f5e2b52 100644 --- a/components/rtgui/include/rtgui/rtgui_system.h +++ b/components/rtgui/include/rtgui/rtgui_system.h @@ -53,5 +53,16 @@ void* rtgui_realloc(void* ptr, rt_size_t size); #define rtgui_enter_critical rt_enter_critical #define rtgui_exit_critical rt_exit_critical +rt_thread_t rtgui_get_server(void); + +struct rtgui_event; +rt_err_t rtgui_send(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size); +rt_err_t rtgui_send_urgent(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size); +rt_err_t rtgui_send_sync(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size); +rt_err_t rtgui_ack(struct rtgui_event* event, rt_int32_t status); +rt_err_t rtgui_recv(struct rtgui_event* event, rt_size_t event_size); +rt_err_t rtgui_recv_nosuspend(struct rtgui_event* event, rt_size_t event_size); +rt_err_t rtgui_recv_filter(rt_uint32_t type, struct rtgui_event* event, rt_size_t event_size); + #endif diff --git a/components/rtgui/include/rtgui/widgets/about_view.h b/components/rtgui/include/rtgui/widgets/about_view.h deleted file mode 100644 index 510796edf3..0000000000 --- a/components/rtgui/include/rtgui/widgets/about_view.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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 -#include -#include -#include - -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 370b9820d3..39d8e4dbca 100644 --- a/components/rtgui/include/rtgui/widgets/box.h +++ b/components/rtgui/include/rtgui/widgets/box.h @@ -33,26 +33,23 @@ DECLARE_CLASS_TYPE(box); struct rtgui_box { - struct rtgui_container parent; + struct rtgui_object parent; rt_uint16_t orient; rt_uint16_t border_size; + + struct rtgui_container* container; }; typedef struct rtgui_box rtgui_box_t; -struct rtgui_box* rtgui_box_create(int orientation, rtgui_rect_t* rect); +struct rtgui_box* rtgui_box_create(int orientation, int border_size); void rtgui_box_destroy(struct rtgui_box* box); -rt_bool_t rtgui_box_event_handler(struct rtgui_object* object, 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/container.h b/components/rtgui/include/rtgui/widgets/container.h index 57a92b432c..990876992b 100644 --- a/components/rtgui/include/rtgui/widgets/container.h +++ b/components/rtgui/include/rtgui/widgets/container.h @@ -15,6 +15,7 @@ #define __RTGUI_CONTAINER_H__ #include +#include #ifdef __cplusplus extern "C" { @@ -35,6 +36,9 @@ struct rtgui_container { struct rtgui_widget parent; + /* layout box */ + struct rtgui_box* layout_box; + rtgui_list_t children; }; typedef struct rtgui_container rtgui_container_t; @@ -44,12 +48,9 @@ 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; +/* set layout 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_layout(struct rtgui_container* 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); diff --git a/components/rtgui/include/rtgui/widgets/filelist_view.h b/components/rtgui/include/rtgui/widgets/filelist_view.h index 3ce9bbb195..6fc3b0b9d7 100644 --- a/components/rtgui/include/rtgui/widgets/filelist_view.h +++ b/components/rtgui/include/rtgui/widgets/filelist_view.h @@ -49,7 +49,7 @@ rtgui_filelist_view_t* rtgui_filelist_view_create(const char* directory, 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); +rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_object* object, 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); diff --git a/components/rtgui/include/rtgui/widgets/menu.h b/components/rtgui/include/rtgui/widgets/menu.h index ba620d3c74..2a137d7009 100644 --- a/components/rtgui/include/rtgui/widgets/menu.h +++ b/components/rtgui/include/rtgui/widgets/menu.h @@ -29,7 +29,7 @@ struct rtgui_menu_item rt_uint16_t submenu_count; /* menu action */ - rt_bool_t (*on_menuaction)(rtgui_widget_t* widget, rtgui_event_t* event); + rt_bool_t (*on_menuaction)(struct rtgui_object* object, struct rtgui_event* event); }; typedef struct rtgui_menu_item rtgui_menu_item_t; diff --git a/components/rtgui/include/rtgui/widgets/panel.h b/components/rtgui/include/rtgui/widgets/panel.h new file mode 100644 index 0000000000..4d4af5e021 --- /dev/null +++ b/components/rtgui/include/rtgui/widgets/panel.h @@ -0,0 +1,45 @@ +/* + * File : panel.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_PANEL_H__ +#define __RTGUI_PANEL_H__ + +#include +#include + +DECLARE_CLASS_TYPE(panel); + +/** Gets the type of a panel */ +#define RTGUI_PANEL_TYPE (RTGUI_TYPE(panel)) +/** Casts the object to an panel */ +#define RTGUI_PANEL(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_PANEL_TYPE, rtgui_panel_t)) +/** Checks if the object is an rtgui_button */ +#define RTGUI_IS_PANEL(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_PANEL_TYPE)) + +/* + * the panel widget + */ +struct rtgui_panel +{ + struct rtgui_container parent; + + int border_style; +}; +typedef struct rtgui_panel rtgui_panel_t; + +rtgui_panel_t* rtgui_panel_create(int border_style); +void rtgui_panel_destroy(rtgui_panel_t* panel); + +rt_bool_t rtgui_panel_event_handler(struct rtgui_object* object, struct rtgui_event* event); + +#endif diff --git a/components/rtgui/include/rtgui/widgets/textbox.h b/components/rtgui/include/rtgui/widgets/textbox.h index 972e80a579..55d74bf109 100644 --- a/components/rtgui/include/rtgui/widgets/textbox.h +++ b/components/rtgui/include/rtgui/widgets/textbox.h @@ -14,32 +14,34 @@ #ifndef __RTGUI_TEXTBOX_H__ #define __RTGUI_TEXTBOX_H__ -#include +#include #include +#include + +#ifdef __cplusplus +extern "C" { +#endif DECLARE_CLASS_TYPE(textbox); + /** Gets the type of a textbox */ #define RTGUI_TEXTBOX_TYPE (RTGUI_TYPE(textbox)) -/** Casts the object to a rtgui_textbox */ +/** Casts the object to a rtgui_textbox_t */ #define RTGUI_TEXTBOX(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_TEXTBOX_TYPE, rtgui_textbox_t)) -/** Checks if the object is a rtgui_textbox */ +/** Checks if the object is a rtgui_textbox_t */ #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_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 +#define RTGUI_TEXTBOX_SINGLE 0x00 +#define RTGUI_TEXTBOX_MULTI 0x01 /* multiline */ +#define RTGUI_TEXTBOX_MASK 0x02 /* ciphertext */ +#define RTGUI_TEXTBOX_DIGIT 0x04 /* digit */ +#define RTGUI_TEXTBOX_CARET_SHOW 0x10 +#define RTGUI_TEXTBOX_CARET_STAT 0x20 /* unused */ -struct rtgui_textbox_line -{ - char* line_text; - - struct rtgui_textbox_line *prev, *next; -}; +#define RTGUI_TEXTBOX_LINE_MAX 128 /* text line cache */ struct rtgui_textbox { @@ -47,22 +49,24 @@ struct rtgui_textbox struct rtgui_widget parent; /* text box flag */ - rt_uint8_t flag; + rt_uint32_t flag; /* current line and position */ rt_uint16_t line, line_begin, position, line_length; - + rt_uint16_t dis_length; /*may be display length.*/ char* text; rt_size_t font_width; - struct rtgui_timer* caret_timer; + rtgui_timer_t *caret_timer; + rtgui_color_t *caret; + rtgui_rect_t caret_rect; - /* widget private data */ - rt_bool_t (*on_enter) (struct rtgui_widget* widget, struct rtgui_event* event); + /* textbox private data */ + rt_bool_t (*on_enter) (struct rtgui_textbox *box, rtgui_event_t* event); }; typedef struct rtgui_textbox rtgui_textbox_t; -struct rtgui_textbox* rtgui_textbox_create(const char* text, rt_uint8_t flag); +struct rtgui_textbox* rtgui_textbox_create(const char* text, rt_uint32_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); @@ -72,4 +76,11 @@ const char* rtgui_textbox_get_value(struct rtgui_textbox* box); void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length); +void rtgui_textbox_get_edit_rect(struct rtgui_textbox *box,rtgui_rect_t *rect); + +void rtgui_textbox_ondraw(rtgui_textbox_t* box); +#ifdef __cplusplus +} +#endif + #endif diff --git a/components/rtgui/include/rtgui/widgets/widget.h b/components/rtgui/include/rtgui/widgets/widget.h index 7d747e677c..9b8fd439e9 100644 --- a/components/rtgui/include/rtgui/widgets/widget.h +++ b/components/rtgui/include/rtgui/widgets/widget.h @@ -26,16 +26,16 @@ extern "C" { #endif #define RTGUI_WIDGET_FLAG_DEFAULT 0x0000 -#define RTGUI_WIDGET_FLAG_HIDE 0x0001 +#define RTGUI_WIDGET_FLAG_SHOWN 0x0001 #define RTGUI_WIDGET_FLAG_DISABLE 0x0002 #define RTGUI_WIDGET_FLAG_FOCUS 0x0004 #define RTGUI_WIDGET_FLAG_TRANSPARENT 0x0008 #define RTGUI_WIDGET_FLAG_FOCUSABLE 0x0010 #define RTGUI_WIDGET_FLAG_DC_VISIBLE 0x0100 -#define RTGUI_WIDGET_UNHIDE(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_HIDE -#define RTGUI_WIDGET_HIDE(w) (w)->flag |= RTGUI_WIDGET_FLAG_HIDE -#define RTGUI_WIDGET_IS_HIDE(w) ((w)->flag & RTGUI_WIDGET_FLAG_HIDE) +#define RTGUI_WIDGET_UNHIDE(w) (w)->flag |= RTGUI_WIDGET_FLAG_SHOWN +#define RTGUI_WIDGET_HIDE(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_SHOWN +#define RTGUI_WIDGET_IS_HIDE(w) (!((w)->flag & RTGUI_WIDGET_FLAG_SHOWN)) #define RTGUI_WIDGET_ENABLE(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_DISABLE #define RTGUI_WIDGET_DISABLE(w) (w)->flag |= RTGUI_WIDGET_FLAG_DISABLE @@ -52,12 +52,13 @@ extern "C" { #define RTGUI_WIDGET_DC_SET_UNVISIBLE(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_DC_VISIBLE #define RTGUI_WIDGET_DC(w) ((struct rtgui_dc*)&((w)->dc_type)) -/* get rtgui widget object */ -#define RTGUI_WIDGET_FOREGROUND(w) ((w)->gc.foreground) -#define RTGUI_WIDGET_BACKGROUND(w) ((w)->gc.background) -#define RTGUI_WIDGET_TEXTALIGN(w) ((w)->gc.textalign) -#define RTGUI_WIDGET_FONT(w) ((w)->gc.font) -#define RTGUI_WIDGET_FLAG(w) ((w)->flag) +/* rtgui widget attribute */ +#define RTGUI_WIDGET_FOREGROUND(w) (RTGUI_WIDGET(w)->gc.foreground) +#define RTGUI_WIDGET_BACKGROUND(w) (RTGUI_WIDGET(w)->gc.background) +#define RTGUI_WIDGET_TEXTALIGN(w) (RTGUI_WIDGET(w)->gc.textalign) +#define RTGUI_WIDGET_FONT(w) (RTGUI_WIDGET(w)->gc.font) +#define RTGUI_WIDGET_FLAG(w) (RTGUI_WIDGET(w)->flag) +#define RTGUI_WIDGET_ALIGN(w) (RTGUI_WIDGET(w)->align) DECLARE_CLASS_TYPE(widget); @@ -96,14 +97,10 @@ struct rtgui_widget /* the widget extent */ rtgui_rect_t extent; -#ifndef RTGUI_USING_SMALL_SIZE /* minimal width and height of widget */ rt_int16_t mini_width, mini_height; - rt_int16_t margin, margin_style; - /* widget align */ rt_int32_t align; -#endif /* the rect clip */ rtgui_region_t clip; @@ -189,7 +186,9 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget); struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget); void rtgui_widget_show(rtgui_widget_t* widget); +rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *event); void rtgui_widget_hide(rtgui_widget_t* widget); +rt_bool_t rtgui_widget_onhide(struct rtgui_object *object, struct rtgui_event *event); void rtgui_widget_update(rtgui_widget_t* widget); /* get parent color */ diff --git a/components/rtgui/include/rtgui/widgets/window.h b/components/rtgui/include/rtgui/widgets/window.h index deb4378a36..ac3c2e7e36 100644 --- a/components/rtgui/include/rtgui/widgets/window.h +++ b/components/rtgui/include/rtgui/widgets/window.h @@ -37,16 +37,8 @@ DECLARE_CLASS_TYPE(win); #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_ONTOP 0x040 /* window is in the top layer */ +#define RTGUI_WIN_STYLE_ONBTM 0x080 /* window is in the bottom layer */ #define RTGUI_WIN_STYLE_DEFAULT (RTGUI_WIN_STYLE_CLOSEBOX | RTGUI_WIN_STYLE_MINIBOX) @@ -84,7 +76,7 @@ struct rtgui_win /* the widget that will grab the focus in current window */ struct rtgui_widget *focused_widget; - /* top window style */ + /* window style */ rt_uint16_t style; /* window state flag */ @@ -133,7 +125,7 @@ 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_err_t rtgui_win_activate(struct rtgui_win *win); rt_bool_t rtgui_win_is_activated(struct rtgui_win* win); void rtgui_win_move(struct rtgui_win* win, int x, int y); diff --git a/components/rtgui/server/driver.c b/components/rtgui/server/driver.c index 67e4aee909..1b35e4f6fc 100644 --- a/components/rtgui/server/driver.c +++ b/components/rtgui/server/driver.c @@ -88,3 +88,7 @@ rt_uint8_t* rtgui_graphic_driver_get_framebuffer(const struct rtgui_graphic_driv return (rt_uint8_t*)driver->framebuffer; } +rt_uint8_t* rtgui_graphic_driver_get_default_framebuffer(void) +{ + return rtgui_graphic_driver_get_framebuffer(&_driver); +} diff --git a/components/rtgui/server/mouse.c b/components/rtgui/server/mouse.c index c7a05aac4b..9acc989617 100644 --- a/components/rtgui/server/mouse.c +++ b/components/rtgui/server/mouse.c @@ -52,9 +52,6 @@ struct rtgui_cursor rt_uint8_t *win_top, *win_bottom; rt_bool_t win_rect_show, win_rect_has_saved; #endif - - /* screen framebuffer */ - rt_uint8_t* framebuffer; }; struct rtgui_cursor* _rtgui_cursor; @@ -140,7 +137,6 @@ void rtgui_mouse_init() /* init cursor */ _rtgui_cursor->bpp = gd->bits_per_pixel/8; - _rtgui_cursor->framebuffer = rtgui_graphic_driver_get_framebuffer(gd); _rtgui_cursor->screen_pitch = _rtgui_cursor->bpp * gd->width; #ifdef RTGUI_USING_MOUSE_CURSOR @@ -300,7 +296,7 @@ static void rtgui_cursor_restore() rt_base_t idx, height, cursor_pitch; rt_uint8_t *cursor_ptr, *fb_ptr; - fb_ptr = _rtgui_cursor->framebuffer + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch + fb_ptr = rtgui_graphic_driver_get_default_framebuffer() + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch + _rtgui_cursor->cx * _rtgui_cursor->bpp; cursor_ptr = _rtgui_cursor->cursor_saved; @@ -327,7 +323,7 @@ static void rtgui_cursor_save() rt_base_t idx, height, cursor_pitch; rt_uint8_t *cursor_ptr, *fb_ptr; - fb_ptr = _rtgui_cursor->framebuffer + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch + + fb_ptr = _driver_get_default_framebuffer() + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch + _rtgui_cursor->cx * _rtgui_cursor->bpp; cursor_ptr = _rtgui_cursor->cursor_saved; @@ -488,10 +484,11 @@ static void rtgui_winrect_show() static void rtgui_winrect_restore() { - rt_uint8_t *winrect_ptr, *fb_ptr; + rt_uint8_t *winrect_ptr, *fb_ptr, *driver_fb; int winrect_pitch, idx; rtgui_rect_t screen_rect, win_rect; + driver_fb = rtgui_graphic_driver_get_default_framebuffer(); win_rect = _rtgui_cursor->win_rect; rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), @@ -499,7 +496,7 @@ static void rtgui_winrect_restore() rtgui_rect_intersect(&screen_rect, &win_rect); /* restore winrect left */ - fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch + win_rect.x1 * _rtgui_cursor->bpp; winrect_ptr = _rtgui_cursor->win_left; winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp; @@ -507,7 +504,7 @@ static void rtgui_winrect_restore() (win_rect.y2 - win_rect.y1), winrect_pitch); /* restore winrect right */ - fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch + (win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp; winrect_ptr = _rtgui_cursor->win_right; winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp; @@ -515,7 +512,7 @@ static void rtgui_winrect_restore() (win_rect.y2 - win_rect.y1), winrect_pitch); /* restore winrect top */ - fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch + (win_rect.x1 + WIN_MOVE_BORDER)* _rtgui_cursor->bpp; winrect_ptr = _rtgui_cursor->win_top; winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp; @@ -523,7 +520,7 @@ static void rtgui_winrect_restore() WIN_MOVE_BORDER, winrect_pitch); /* restore winrect bottom */ - fb_ptr = _rtgui_cursor->framebuffer + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch + + fb_ptr = driver_fb + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch + (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp; winrect_ptr = _rtgui_cursor->win_bottom; display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch, @@ -532,10 +529,11 @@ static void rtgui_winrect_restore() static void rtgui_winrect_save() { - rt_uint8_t *winrect_ptr, *fb_ptr; + rt_uint8_t *winrect_ptr, *fb_ptr, *driver_fb; int winrect_pitch, idx; rtgui_rect_t screen_rect, win_rect; + driver_fb = rtgui_graphic_driver_get_default_framebuffer(); win_rect = _rtgui_cursor->win_rect; rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), @@ -546,7 +544,7 @@ static void rtgui_winrect_save() _rtgui_cursor->win_rect_has_saved = RT_TRUE; /* save winrect left */ - fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch + win_rect.x1 * _rtgui_cursor->bpp; winrect_ptr = _rtgui_cursor->win_left; winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp; @@ -554,7 +552,7 @@ static void rtgui_winrect_save() (win_rect.y2 - win_rect.y1), winrect_pitch); /* save winrect right */ - fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch + (win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp; winrect_ptr = _rtgui_cursor->win_right; winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp; @@ -562,7 +560,7 @@ static void rtgui_winrect_save() (win_rect.y2 - win_rect.y1), winrect_pitch); /* save winrect top */ - fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch + (win_rect.x1 + WIN_MOVE_BORDER)* _rtgui_cursor->bpp; winrect_ptr = _rtgui_cursor->win_top; winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp; @@ -570,7 +568,7 @@ static void rtgui_winrect_save() WIN_MOVE_BORDER, winrect_pitch); /* save winrect bottom */ - fb_ptr = _rtgui_cursor->framebuffer + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch + + fb_ptr = driver_fb + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch + (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp; winrect_ptr = _rtgui_cursor->win_bottom; display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch, diff --git a/components/rtgui/server/rtgui_application.c b/components/rtgui/server/rtgui_application.c deleted file mode 100644 index 5aa32433af..0000000000 --- a/components/rtgui/server/rtgui_application.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * 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 -#include -#include - -#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: - case RTGUI_EVENT_WIN_HIDE: - { - 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; - - default: - 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 10ddfbf77a..28f0fb771f 100644 --- a/components/rtgui/server/server.c +++ b/components/rtgui/server/server.c @@ -16,14 +16,16 @@ #include #include #include -#include +#include #include #include "mouse.h" #include "topwin.h" static struct rt_thread *rtgui_server_tid; -static struct rtgui_application *rtgui_server_application; + +static struct rtgui_app *rtgui_server_application = RT_NULL; +static struct rtgui_app *rtgui_wm_application = RT_NULL; void rtgui_server_handle_update(struct rtgui_event_update_end* event) { @@ -85,7 +87,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event) } /* send to client thread */ - rtgui_application_send(topwin->tid, &(ewin.parent), sizeof(ewin)); + rtgui_send(topwin->tid, &(ewin.parent), sizeof(ewin)); return; } @@ -101,7 +103,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event) if (rtgui_topwin_get_focus() != wnd) { /* raise this window */ - rtgui_topwin_activate_win(wnd); + rtgui_topwin_activate_topwin(wnd); } if (wnd->title != RT_NULL && @@ -112,7 +114,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event) else { /* send mouse event to thread */ - rtgui_application_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_mouse)); + rtgui_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_mouse)); } return ; } @@ -144,7 +146,7 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse* event) { event->wid = last_monitor_topwin->wid; /* send mouse motion event */ - rtgui_application_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); + rtgui_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); } if (last_monitor_topwin != win) @@ -155,7 +157,7 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse* event) event->wid = last_monitor_topwin->wid; /* send mouse motion event */ - rtgui_application_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); + rtgui_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); } } @@ -181,7 +183,7 @@ void rtgui_server_handle_kbd(struct rtgui_event_kbd* event) event->wid = wnd->wid; /* send keyboard event to thread */ - rtgui_application_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_kbd)); + rtgui_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_kbd)); return; } @@ -200,58 +202,113 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object, /* dispatch event */ switch (event->type) { + case RTGUI_EVENT_APP_CREATE: + case RTGUI_EVENT_APP_DESTROY: + if (rtgui_wm_application != RT_NULL) + { + /* forward event to wm application */ + rtgui_send(rtgui_wm_application->tid, event, sizeof(struct rtgui_event_application)); + } + else + { + /* always ack with OK */ + rtgui_ack(event, RTGUI_STATUS_OK); + } + break; + + /* mouse and keyboard event */ + case RTGUI_EVENT_MOUSE_MOTION: + /* handle mouse motion event */ + rtgui_server_handle_mouse_motion((struct rtgui_event_mouse*)event); + break; + + case RTGUI_EVENT_MOUSE_BUTTON: + /* handle mouse button */ + rtgui_server_handle_mouse_btn((struct rtgui_event_mouse*)event); + break; + + case RTGUI_EVENT_KBD: + /* handle keyboard event */ + rtgui_server_handle_kbd((struct rtgui_event_kbd*)event); + break; + /* 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); + rtgui_ack(event, RTGUI_STATUS_OK); else - rtgui_application_ack(event, RTGUI_STATUS_ERROR); + rtgui_ack(event, RTGUI_STATUS_ERROR); break; + case RTGUI_EVENT_WIN_SHOW: + if (rtgui_topwin_show((struct rtgui_event_win*)event) == RT_EOK) + rtgui_ack(event, RTGUI_STATUS_OK); + else + rtgui_ack(event, RTGUI_STATUS_ERROR); + break; + + case RTGUI_EVENT_WIN_HIDE: + if (rtgui_topwin_hide((struct rtgui_event_win*)event) == RT_EOK) + rtgui_ack(event, RTGUI_STATUS_OK); + else + rtgui_ack(event, RTGUI_STATUS_ERROR); + break; + + case RTGUI_EVENT_WIN_MOVE: + if (rtgui_topwin_move((struct rtgui_event_win_move*)event) == RT_EOK) + rtgui_ack(event, RTGUI_STATUS_OK); + else + rtgui_ack(event, RTGUI_STATUS_ERROR); + break; + + case RTGUI_EVENT_WIN_MODAL_ENTER: + if (rtgui_topwin_modal_enter((struct rtgui_event_win_modal_enter*)event) == RT_EOK) + rtgui_ack(event, RTGUI_STATUS_OK); + else + rtgui_ack(event, RTGUI_STATUS_ERROR); + break; + + case RTGUI_EVENT_WIN_ACTIVATE: + if (rtgui_topwin_activate((struct rtgui_event_win_activate*)event) == RT_EOK) + rtgui_ack(event, RTGUI_STATUS_OK); + else + rtgui_ack(event, RTGUI_STATUS_ERROR); + break; + case RTGUI_EVENT_WIN_DESTROY: if (last_monitor_topwin != RT_NULL && last_monitor_topwin->wid == ((struct rtgui_event_win*)event)->wid) last_monitor_topwin = RT_NULL; if (rtgui_topwin_remove(((struct rtgui_event_win*)event)->wid) == RT_EOK) - rtgui_application_ack(event, RTGUI_STATUS_OK); + rtgui_ack(event, RTGUI_STATUS_OK); else - rtgui_application_ack(event, RTGUI_STATUS_ERROR); + rtgui_ack(event, RTGUI_STATUS_ERROR); break; - case RTGUI_EVENT_WIN_SHOW: - if (rtgui_topwin_show((struct rtgui_event_win*)event) == RT_EOK) - rtgui_application_ack(event, RTGUI_STATUS_OK); - else - rtgui_application_ack(event, RTGUI_STATUS_ERROR); - break; - - case RTGUI_EVENT_WIN_HIDE: - if (rtgui_topwin_hide((struct rtgui_event_win*)event) == RT_EOK) - rtgui_application_ack(event, RTGUI_STATUS_OK); - else - rtgui_application_ack(event, RTGUI_STATUS_ERROR); - break; - - case RTGUI_EVENT_WIN_MOVE: - if (rtgui_topwin_move((struct rtgui_event_win_move*)event) == RT_EOK) - rtgui_application_ack(event, RTGUI_STATUS_OK); - else - rtgui_application_ack(event, RTGUI_STATUS_ERROR); - break; - - case RTGUI_EVENT_WIN_MODAL_ENTER: - if (rtgui_topwin_modal_enter((struct rtgui_event_win_modal_enter*)event) == RT_EOK) - rtgui_application_ack(event, RTGUI_STATUS_OK); - else - rtgui_application_ack(event, RTGUI_STATUS_ERROR); - break; - 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: + if (rtgui_wm_application != RT_NULL) + { + rtgui_ack(event, RTGUI_STATUS_ERROR); + } + else + { + struct rtgui_event_set_wm *set_wm; + + set_wm = (struct rtgui_event_set_wm*) event; + rtgui_wm_application = set_wm->app; + rtgui_ack(event, RTGUI_STATUS_OK); + } + break; + /* other event */ + case RTGUI_EVENT_COMMAND: + break; + case RTGUI_EVENT_UPDATE_BEGIN: #ifdef RTGUI_USING_MOUSE_CURSOR /* hide cursor */ @@ -272,25 +329,6 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object, /* handle mouse monitor */ rtgui_server_handle_monitor_add((struct rtgui_event_monitor*)event); break; - - /* mouse and keyboard event */ - case RTGUI_EVENT_MOUSE_MOTION: - /* handle mouse motion event */ - rtgui_server_handle_mouse_motion((struct rtgui_event_mouse*)event); - break; - - case RTGUI_EVENT_MOUSE_BUTTON: - /* handle mouse button */ - rtgui_server_handle_mouse_btn((struct rtgui_event_mouse*)event); - break; - - case RTGUI_EVENT_KBD: - /* handle keyboard event */ - rtgui_server_handle_kbd((struct rtgui_event_kbd*)event); - break; - - case RTGUI_EVENT_COMMAND: - break; } return RT_TRUE; @@ -307,8 +345,8 @@ static void rtgui_server_entry(void* parameter) SetThreadPriority(hCurrentThread, THREAD_PRIORITY_HIGHEST); #endif - /* register rtgui server thread */ - rtgui_server_application = rtgui_application_create(rtgui_server_tid, + /* create rtgui server application */ + rtgui_server_application = rtgui_app_create(rtgui_server_tid, "rtgui"); if (rtgui_server_application == RT_NULL) return; @@ -321,16 +359,16 @@ static void rtgui_server_entry(void* parameter) rtgui_mouse_show_cursor(); #endif - rtgui_application_run(rtgui_server_application); + rtgui_app_run(rtgui_server_application); - rtgui_application_destroy(rtgui_server_application); + rtgui_app_destroy(rtgui_server_application); rtgui_server_application = RT_NULL; } void rtgui_server_post_event(struct rtgui_event* event, rt_size_t size) { if (rtgui_server_tid != RT_NULL) - rtgui_application_send(rtgui_server_tid, event, size); + rtgui_send(rtgui_server_tid, event, size); else rt_kprintf("post when server is not running\n"); } @@ -338,7 +376,7 @@ 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) { if (rtgui_server_tid != RT_NULL) - return rtgui_application_send_sync(rtgui_server_tid, event, size); + return rtgui_send_sync(rtgui_server_tid, event, size); else { rt_kprintf("post when server is not running\n"); diff --git a/components/rtgui/server/topwin.c b/components/rtgui/server/topwin.c index 14c9432b18..4c75cc1159 100644 --- a/components/rtgui/server/topwin.c +++ b/components/rtgui/server/topwin.c @@ -19,41 +19,36 @@ #include #include #include -#include +#include #include /* 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. + * hidden items, 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 + * be in the first tree. The order of this list is the order of the windows. + * 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. + * clip each other with the same rule as this list. 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. + * Thus, the left most leaf of the tree is the top most window and the right + * most root node is the bottom window. The hidden part 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 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); +static void _rtgui_topwin_activate_next(enum rtgui_topwin_flag); void rtgui_topwin_init(void) { @@ -113,11 +108,6 @@ rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event) { 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 { @@ -138,6 +128,8 @@ rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event) 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; if (event->parent.user & RTGUI_WIN_STYLE_NO_FOCUS) topwin->flag |= WINTITLE_NOFOCUS; + if (event->parent.user & RTGUI_WIN_STYLE_ONTOP) topwin->flag |= WINTITLE_ONTOP; + if (event->parent.user & RTGUI_WIN_STYLE_ONBTM) topwin->flag |= WINTITLE_ONBTM; if(!(topwin->flag & WINTITLE_NO) || (topwin->flag & WINTITLE_BORDER)) { @@ -195,12 +187,31 @@ static struct rtgui_topwin* _rtgui_topwin_get_topmost_child_shown(struct rtgui_t return topwin; } -static struct rtgui_topwin* _rtgui_topwin_get_topmost_window_shown(void) +static rt_bool_t _rtgui_topwin_in_layer(struct rtgui_topwin *topwin, enum rtgui_topwin_flag flag) { - 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)); + return (topwin->flag & (WINTITLE_ONTOP|WINTITLE_ONBTM)) + == (flag & (WINTITLE_ONTOP|WINTITLE_ONBTM)); +} + +/* find the topmost window shown in the layer set by flag. The flag has many + * other infomations but we only use the ONTOP/ONBTM */ +static struct rtgui_topwin* _rtgui_topwin_get_topmost_window_shown(enum rtgui_topwin_flag flag) +{ + struct rtgui_dlist_node *node; + + rtgui_dlist_foreach(node, &_rtgui_topwin_list, next) + { + struct rtgui_topwin *topwin = get_topwin_from_list(node); + + /* reach the hidden region no window shown in current layer */ + if (!(topwin->flag & WINTITLE_SHOWN)) + return RT_NULL; + + if (_rtgui_topwin_in_layer(topwin, flag)) + return _rtgui_topwin_get_topmost_child_shown(topwin); + } + /* no window in current layer is shown */ + return RT_NULL; } /* a hidden parent will hide it's children. Top level window can be shown at @@ -286,24 +297,23 @@ rt_err_t rtgui_topwin_remove(struct rtgui_win* wid) 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(); - } - - /* 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); + if (old_focus == topwin) + { + _rtgui_topwin_activate_next(topwin->flag); + } + + if (topwin->flag & WINTITLE_SHOWN) + { + rtgui_topwin_update_clip(); + /* redraw the old rect */ + _rtgui_topwin_union_region_tree(topwin, ®ion); + rtgui_topwin_redraw(rtgui_region_extents(®ion)); + } + _rtgui_topwin_free_tree(topwin); return RT_EOK; @@ -327,7 +337,7 @@ static void _rtgui_topwin_only_activate(struct rtgui_topwin *topwin) topwin->flag |= WINTITLE_ACTIVATE; event.wid = topwin->wid; - rtgui_application_send(topwin->tid, &(event.parent), sizeof(struct rtgui_event_win)); + rtgui_send(topwin->tid, &(event.parent), sizeof(struct rtgui_event_win)); /* redraw title */ if (topwin->title != RT_NULL) @@ -336,11 +346,13 @@ static void _rtgui_topwin_only_activate(struct rtgui_topwin *topwin) } } -static void _rtgui_topwin_activate_next(void) +/* activate next window in the same layer as flag. The flag has many other + * infomations but we only use the ONTOP/ONBTM */ +static void _rtgui_topwin_activate_next(enum rtgui_topwin_flag flag) { struct rtgui_topwin *topwin; - topwin = _rtgui_topwin_get_topmost_window_shown(); + topwin = _rtgui_topwin_get_topmost_window_shown(flag); if (topwin == RT_NULL) return; @@ -358,7 +370,7 @@ static void _rtgui_topwin_deactivate(struct rtgui_topwin *topwin) RTGUI_EVENT_WIN_DEACTIVATE_INIT(&event); event.wid = topwin->wid; - rtgui_application_send(topwin->tid, + rtgui_send(topwin->tid, &event.parent, sizeof(struct rtgui_event_win)); topwin->flag &= ~WINTITLE_ACTIVATE; @@ -376,17 +388,6 @@ static void _rtgui_topwin_move_whole_tree2top(struct rtgui_topwin *topwin) RT_ASSERT(topwin != RT_NULL); -#ifdef RTGUI_USING_DESKTOP_WINDOW - /* handle desktop window separately, avoid calling - * _rtgui_topwin_get_root_win */ - if (topwin == the_desktop_topwin) - { - rtgui_dlist_remove(&the_desktop_topwin->list); - rtgui_dlist_insert_after(&_rtgui_topwin_list, &the_desktop_topwin->list); - return; - } -#endif - /* move the whole tree */ topparent = _rtgui_topwin_get_root_win(topwin); RT_ASSERT(topparent != RT_NULL); @@ -394,20 +395,58 @@ static void _rtgui_topwin_move_whole_tree2top(struct rtgui_topwin *topwin) /* 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 + if (topwin->flag & WINTITLE_ONTOP) + { + rtgui_dlist_insert_after(&_rtgui_topwin_list, &(topparent->list)); + } + else if (topwin->flag & WINTITLE_ONBTM) + { + /* botton layer window, before the fisrt bottom window or hidden window. */ + struct rtgui_topwin *ntopwin = get_topwin_from_list(&_rtgui_topwin_list); + struct rtgui_dlist_node *node; + + rtgui_dlist_foreach(node, &_rtgui_topwin_list, next) + { + ntopwin = get_topwin_from_list(node); + if ((ntopwin->flag & WINTITLE_ONBTM) + || !(ntopwin->flag & WINTITLE_SHOWN)) + break; + } + /* all other windows are shown top/normal layer windows. Insert it as + * the last window. */ + if (node == &_rtgui_topwin_list) + rtgui_dlist_insert_before(&_rtgui_topwin_list, &(topparent->list)); + else + rtgui_dlist_insert_before(&ntopwin->list, &(topparent->list)); + } + else + { + /* normal layer window, before the fisrt shown normal layer window. */ + struct rtgui_topwin *ntopwin = get_topwin_from_list(&_rtgui_topwin_list); + struct rtgui_dlist_node *node; + + rtgui_dlist_foreach(node, &_rtgui_topwin_list, next) + { + ntopwin = get_topwin_from_list(node); + if (!((ntopwin->flag & WINTITLE_ONTOP) + && (ntopwin->flag & WINTITLE_SHOWN))) + break; + } + /* all other windows are shown top layer windows. Insert it as + * the last window. */ + if (node == &_rtgui_topwin_list) + rtgui_dlist_insert_before(&_rtgui_topwin_list, &(topparent->list)); + else + rtgui_dlist_insert_before(&ntopwin->list, &(topparent->list)); + } } -static void _rtgui_topwin_raise_topwin_in_tree(struct rtgui_topwin *topwin) +static void _rtgui_topwin_raise_in_sibling(struct rtgui_topwin *topwin) { struct rtgui_dlist_node *win_level; RT_ASSERT(topwin != RT_NULL); - _rtgui_topwin_move_whole_tree2top(topwin); if (topwin->parent == RT_NULL) win_level = &_rtgui_topwin_list; else @@ -416,33 +455,64 @@ static void _rtgui_topwin_raise_topwin_in_tree(struct rtgui_topwin *topwin) rtgui_dlist_insert_after(win_level, &topwin->list); } +/* it will do 2 things. One is moving the whole tree(the root of the tree) to + * the front and the other is moving topwin to the front of it's siblings. */ +static void _rtgui_topwin_raise_tree_from_root(struct rtgui_topwin *topwin) +{ + RT_ASSERT(topwin != RT_NULL); + + _rtgui_topwin_move_whole_tree2top(topwin); + /* root win is aleady moved by _rtgui_topwin_move_whole_tree2top */ + if (!IS_ROOT_WIN(topwin)) + _rtgui_topwin_raise_in_sibling(topwin); +} + /* 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) +rt_err_t rtgui_topwin_activate(struct rtgui_event_win_activate* event) +{ + struct rtgui_topwin *topwin; + + RT_ASSERT(event); + + topwin = rtgui_topwin_search_in_list(event->wid, &_rtgui_topwin_list); + if (topwin == RT_NULL) + return -RT_ERROR; + + return rtgui_topwin_activate_topwin(topwin); +} + +rt_err_t rtgui_topwin_activate_topwin(struct rtgui_topwin* topwin) { struct rtgui_topwin *old_focus_topwin; RT_ASSERT(topwin != RT_NULL); + if (!(topwin->flag & WINTITLE_SHOWN)) + return -RT_ERROR; + if (topwin->flag & WINTITLE_NOFOCUS) { /* just raise it, not affect others. */ - _rtgui_topwin_raise_topwin_in_tree(topwin); + _rtgui_topwin_raise_tree_from_root(topwin); /* update clip info */ rtgui_topwin_update_clip(); - return; + return RT_EOK; } + if (topwin->flag & WINTITLE_ACTIVATE) + return RT_EOK; + old_focus_topwin = rtgui_topwin_get_focus(); + /* if topwin has the focus, it shoule have WINTITLE_ACTIVATE set and + * returned above. */ + RT_ASSERT(old_focus_topwin != topwin); - if (old_focus_topwin == topwin) - return; - - _rtgui_topwin_raise_topwin_in_tree(topwin); + _rtgui_topwin_raise_tree_from_root(topwin); /* update clip info */ rtgui_topwin_update_clip(); @@ -454,6 +524,8 @@ void rtgui_topwin_activate_win(struct rtgui_topwin* topwin) } _rtgui_topwin_only_activate(topwin); + + return RT_EOK; } /* map func to the topwin tree in preorder. @@ -486,6 +558,10 @@ rt_inline void _rtgui_topwin_mark_hidden(struct rtgui_topwin *topwin) rt_inline void _rtgui_topwin_mark_shown(struct rtgui_topwin *topwin) { + if (!(topwin->flag & WINTITLE_SHOWN) + && RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(topwin->wid))) + return; + topwin->flag |= WINTITLE_SHOWN; if (topwin->title != RT_NULL) { @@ -504,10 +580,12 @@ static void _rtgui_topwin_draw_tree(struct rtgui_topwin *topwin, struct rtgui_ev } epaint->wid = topwin->wid; - rtgui_application_send(topwin->tid, &(epaint->parent), sizeof(struct rtgui_event_paint)); + rtgui_send(topwin->tid, &(epaint->parent), sizeof(struct rtgui_event_paint)); rtgui_dlist_foreach(node, &topwin->child_list, prev) { + if (!(get_topwin_from_list(node)->flag & WINTITLE_SHOWN)) + return; _rtgui_topwin_draw_tree(get_topwin_from_list(node), epaint); } } @@ -519,7 +597,7 @@ static void _rtgui_topwin_show_tree(struct rtgui_topwin *topwin, struct rtgui_ev RT_ASSERT(topwin != RT_NULL); RT_ASSERT(epaint != RT_NULL); - _rtgui_topwin_raise_topwin_in_tree(topwin); + _rtgui_topwin_raise_tree_from_root(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); @@ -532,14 +610,6 @@ static void _rtgui_topwin_show_tree(struct rtgui_topwin *topwin, struct rtgui_ev _rtgui_topwin_draw_tree(topwin, epaint); } -/** 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, *old_focus; @@ -548,25 +618,30 @@ rt_err_t rtgui_topwin_show(struct rtgui_event_win* event) 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)) + /* no such a window recorded */ + if (topwin == RT_NULL) return -RT_ERROR; + /* if the parent is hidden, just mark it as shown. It will be shown when + * the parent is shown. */ + if (!_rtgui_topwin_could_show(topwin)) + { + topwin->flag |= WINTITLE_SHOWN; + _rtgui_topwin_raise_in_sibling(topwin); + + return -RT_ERROR; + } + old_focus = rtgui_topwin_get_focus(); _rtgui_topwin_show_tree(topwin, &epaint); /* 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) - { + if (old_focus && old_focus != topwin) _rtgui_topwin_deactivate(old_focus); - _rtgui_topwin_only_activate(topwin); - } + _rtgui_topwin_only_activate(topwin); return RT_EOK; } @@ -633,7 +708,7 @@ rt_err_t rtgui_topwin_hide(struct rtgui_event_win* event) if (old_focus_topwin == topwin) { - _rtgui_topwin_activate_next(); + _rtgui_topwin_activate_next(topwin->flag); } return RT_EOK; @@ -697,7 +772,7 @@ rt_err_t rtgui_topwin_move(struct rtgui_event_win_move* event) struct rtgui_event_paint epaint; RTGUI_EVENT_PAINT_INIT(&epaint); epaint.wid = topwin->wid; - rtgui_application_send(topwin->tid, &(epaint.parent), sizeof(epaint)); + rtgui_send(topwin->tid, &(epaint.parent), sizeof(epaint)); } return RT_EOK; @@ -772,24 +847,7 @@ static struct rtgui_topwin* _rtgui_topwin_get_focus_from_list(struct rtgui_dlist struct rtgui_topwin* rtgui_topwin_get_focus(void) { -#if 1 - // debug code - struct rtgui_topwin *topwin = _rtgui_topwin_get_focus_from_list(&_rtgui_topwin_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, @@ -885,7 +943,12 @@ static void rtgui_topwin_update_clip(void) rtgui_graphic_driver_get_default()->height); /* from top to bottom. */ - top = _rtgui_topwin_get_topmost_window_shown(); + top = _rtgui_topwin_get_topmost_window_shown(WINTITLE_ONTOP); + /* 0 is normal layer */ + if (top == RT_NULL) + top = _rtgui_topwin_get_topmost_window_shown(0); + if (top == RT_NULL) + top = _rtgui_topwin_get_topmost_window_shown(WINTITLE_ONBTM); while (top != RT_NULL) { @@ -906,7 +969,7 @@ static void rtgui_topwin_update_clip(void) /* send clip event to destination window */ eclip.wid = top->wid; - rtgui_application_send(top->tid, &(eclip.parent), sizeof(struct rtgui_event_clip_info)); + rtgui_send(top->tid, &(eclip.parent), sizeof(struct rtgui_event_clip_info)); /* move to next sibling tree */ if (top->parent == RT_NULL) @@ -915,6 +978,7 @@ static void rtgui_topwin_update_clip(void) top = _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(top->list.next)); else break; + /* move to next slibing topwin */ 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)); @@ -951,7 +1015,7 @@ static void _rtgui_topwin_redraw_tree(struct rtgui_dlist_node *list, if (rtgui_rect_is_intersect(rect, &(topwin->extent)) == RT_EOK) { epaint->wid = topwin->wid; - rtgui_application_send(topwin->tid, &(epaint->parent), sizeof(*epaint)); + rtgui_send(topwin->tid, &(epaint->parent), sizeof(*epaint)); /* draw title */ if (topwin->title != RT_NULL) @@ -1019,7 +1083,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_application_send(win->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); + rtgui_send(win->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); return; } @@ -1058,7 +1122,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_application_send(win->tid, &(event.parent), sizeof(struct rtgui_event_win)); + rtgui_send(win->tid, &(event.parent), sizeof(struct rtgui_event_win)); } } } @@ -1120,19 +1184,18 @@ void rtgui_topwin_dump_tree(void) { struct rtgui_dlist_node *node; -#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"); - } -#else rtgui_dlist_foreach(node, &_rtgui_topwin_list, next) { _rtgui_topwin_dump_tree(get_topwin_from_list(node)); rt_kprintf("\n"); } -#endif } + +#ifdef RT_USING_FINSH +#include +void dump_tree() +{ + rtgui_topwin_dump_tree(); +} +FINSH_FUNCTION_EXPORT(dump_tree, dump rtgui topwin tree) +#endif diff --git a/components/rtgui/server/topwin.h b/components/rtgui/server/topwin.h index bc9db9d284..59b8f30e79 100644 --- a/components/rtgui/server/topwin.h +++ b/components/rtgui/server/topwin.h @@ -23,8 +23,8 @@ /* add or remove a top win */ rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event); rt_err_t rtgui_topwin_remove(struct rtgui_win* wid); - -void rtgui_topwin_activate_win(struct rtgui_topwin* win); +rt_err_t rtgui_topwin_activate(struct rtgui_event_win_activate* event); +rt_err_t rtgui_topwin_activate_topwin(struct rtgui_topwin* win); /* show a window */ rt_err_t rtgui_topwin_show(struct rtgui_event_win* event); diff --git a/components/rtgui/widgets/about_view.c b/components/rtgui/widgets/about_view.c deleted file mode 100644 index 6bc012b255..0000000000 --- a/components/rtgui/widgets/about_view.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * 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 -#include - -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 860245c0db..68ee608372 100644 --- a/components/rtgui/widgets/box.c +++ b/components/rtgui/widgets/box.c @@ -14,73 +14,37 @@ #include #include -#ifndef RTGUI_USING_SMALL_SIZE static void _rtgui_box_constructor(rtgui_box_t *box) { /* init widget and set event handler */ - rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_box_event_handler); - - RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_TRANSPARENT; - rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_box_event_handler); + rtgui_object_set_event_handler(RTGUI_OBJECT(box), RT_NULL); /* set proper of control */ box->orient = RTGUI_HORIZONTAL; box->border_size = RTGUI_BORDER_DEFAULT_WIDTH; + box->container = RT_NULL; } DEFINE_CLASS_TYPE(box, "box", - RTGUI_CONTAINER_TYPE, + RTGUI_OBJECT_TYPE, _rtgui_box_constructor, RT_NULL, sizeof(struct rtgui_box)); -rt_bool_t rtgui_box_event_handler(struct rtgui_object *widget, rtgui_event_t *event) -{ - struct rtgui_box* box = (struct rtgui_box*)widget; - - RT_ASSERT(box != RT_NULL); - - switch (event->type) - { - case RTGUI_EVENT_RESIZE: - /* re-layout */ - rtgui_box_layout(box); - break; - - default: - return rtgui_container_event_handler(RTGUI_OBJECT(box), event); - } - - return RT_FALSE; -} - -struct rtgui_box* rtgui_box_create(int orientation, rtgui_rect_t* rect) +struct rtgui_box* rtgui_box_create(int orientation, int border_size) { struct rtgui_box* box; - box = (struct rtgui_box*) rtgui_widget_create (RTGUI_BOX_TYPE); + box = (struct rtgui_box*) rtgui_object_create (RTGUI_BOX_TYPE); if (box != RT_NULL) { - /* set proper of control */ - rtgui_widget_set_rect(RTGUI_WIDGET(box), rect); box->orient = orientation; + box->border_size = border_size; } return box; } -void rtgui_box_append(struct rtgui_box* box, rtgui_widget_t* widget) -{ - /* put to box's children list */ - rtgui_container_add_child(RTGUI_CONTAINER(box), widget); -} - -void rtgui_box_delete(struct rtgui_box* box, rtgui_widget_t* widget) -{ - /* remove from box's children list */ - rtgui_container_remove_child(RTGUI_CONTAINER(box), widget); -} - static void rtgui_box_layout_vertical(rtgui_box_t* box) { rtgui_list_t *node; @@ -89,16 +53,18 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box) rt_int32_t next_x, next_y; rt_int32_t total_height, space_height; struct rtgui_event_resize size_event; - + struct rtgui_widget *container_widget; + /* prepare the resize event */ RTGUI_EVENT_RESIZE_INIT(&size_event); + container_widget = RTGUI_WIDGET(box->container); /* find spaces */ space_count = 0; total_height = 0; space_height = 0; - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) + rtgui_list_foreach(node, &(box->container->children)) { rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++; @@ -108,16 +74,16 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box) /* calculate the height for each spaces */ if (space_count != 0) { - space_height = (rtgui_rect_height(RTGUI_WIDGET(box)->extent) - total_height - (box->border_size << 1)) / space_count; + space_height = (rtgui_rect_height(container_widget->extent) - total_height - (box->border_size << 1)) / space_count; } /* init (x, y) and box width */ - next_x = RTGUI_WIDGET(box)->extent.x1 + box->border_size; - next_y = RTGUI_WIDGET(box)->extent.y1 + box->border_size; - box_width = rtgui_rect_width(RTGUI_WIDGET(box)->extent) - (box->border_size << 1); + next_x = container_widget->extent.x1 + box->border_size; + next_y = container_widget->extent.y1 + box->border_size; + box_width = rtgui_rect_width(container_widget->extent) - (box->border_size << 1); /* layout each widget */ - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) + rtgui_list_foreach(node, &(box->container->children)) { rtgui_rect_t *rect; rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); @@ -170,7 +136,7 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box) &size_event.parent); /* point to next height */ - next_y = rect->y2; + next_y = rect->y2 + box->border_size; } } @@ -182,16 +148,18 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box) rt_int32_t next_x, next_y; rt_int32_t total_width, space_width; struct rtgui_event_resize size_event; + struct rtgui_widget *container_widget; /* prepare the resize event */ RTGUI_EVENT_RESIZE_INIT(&size_event); + container_widget = RTGUI_WIDGET(box->container); /* find spaces */ space_count = 0; total_width = 0; space_width = 0; - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) + rtgui_list_foreach(node, &(box->container->children)) { rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++; @@ -201,16 +169,16 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box) if (space_count != 0) { /* calculate the height for each spaces */ - space_width = (rtgui_rect_width(RTGUI_WIDGET(box)->extent) - total_width) / space_count; + space_width = (rtgui_rect_width(container_widget->extent) - total_width) / space_count; } /* init (x, y) and box height */ - next_x = RTGUI_WIDGET(box)->extent.x1 + box->border_size; - next_y = RTGUI_WIDGET(box)->extent.y1 + box->border_size; - box_height = rtgui_rect_height(RTGUI_WIDGET(box)->extent) - (box->border_size << 1); + next_x = container_widget->extent.x1 + box->border_size; + next_y = container_widget->extent.y1 + box->border_size; + box_height = rtgui_rect_height(container_widget->extent) - (box->border_size << 1); /* layout each widget */ - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) + rtgui_list_foreach(node, &(box->container->children)) { rtgui_rect_t *rect; rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); @@ -263,7 +231,7 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box) &size_event.parent); /* point to next width */ - next_x = rect->x2; + next_x = rect->x2 + box->border_size; } } @@ -271,6 +239,8 @@ void rtgui_box_layout(rtgui_box_t* box) { RT_ASSERT(box != RT_NULL); + if (box->container == RT_NULL) return; + if (box->orient & RTGUI_VERTICAL) { rtgui_box_layout_vertical(box); @@ -281,64 +251,9 @@ void rtgui_box_layout(rtgui_box_t* box) } /* update box and its children clip */ - if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(box))) + if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(box->container))) { - rtgui_widget_update_clip(RTGUI_WIDGET(box)); + rtgui_widget_update_clip(RTGUI_WIDGET(box->container)); } } -rt_uint32_t rtgui_box_get_width(rtgui_box_t* box) -{ - rtgui_list_t *node; - rt_uint32_t width; - - width = 0; - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) - { - rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); - rt_uint32_t widget_width; - - widget_width = rtgui_rect_width(widget->extent); - if (box->orient & RTGUI_VERTICAL) - { - /* get the max width */ - if (width < widget_width) width = widget_width; - } - else - { - /* get the total width */ - width += widget_width; - } - } - - return width; -} - -rt_uint32_t rtgui_box_get_height(rtgui_box_t* box) -{ - rtgui_list_t *node; - rt_uint32_t height; - - height = 0; - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) - { - rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); - rt_uint32_t widget_height; - - widget_height = rtgui_rect_height(widget->extent); - if (box->orient & RTGUI_HORIZONTAL) - { - /* get the max height */ - if (height < widget_height) height = widget_height; - } - else - { - /* get the total height */ - height += widget_height; - } - } - - return height; -} -#endif - diff --git a/components/rtgui/widgets/button.c b/components/rtgui/widgets/button.c index aab1333b56..2a7571e392 100644 --- a/components/rtgui/widgets/button.c +++ b/components/rtgui/widgets/button.c @@ -62,7 +62,7 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object* object, struct rtgui_e struct rtgui_widget *widget; struct rtgui_button *btn; - RT_ASSERT(widget != RT_NULL); + RT_ASSERT(object != RT_NULL); RT_ASSERT(event != RT_NULL); widget = RTGUI_WIDGET(object); @@ -189,6 +189,8 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object* object, struct rtgui_e return RT_TRUE; } + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/checkbox.c b/components/rtgui/widgets/checkbox.c index cfa23d4ef4..ad1657baab 100644 --- a/components/rtgui/widgets/checkbox.c +++ b/components/rtgui/widgets/checkbox.c @@ -92,6 +92,8 @@ rt_bool_t rtgui_checkbox_event_handler(struct rtgui_object* object, struct rtgui return RT_TRUE; } + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/combobox.c b/components/rtgui/widgets/combobox.c index 5b3010677c..a504682c57 100644 --- a/components/rtgui/widgets/combobox.c +++ b/components/rtgui/widgets/combobox.c @@ -38,7 +38,6 @@ rt_bool_t rtgui_combobox_pdwin_onitem(struct rtgui_object* object, struct rtgui_ rtgui_listbox_t* list; RT_ASSERT(object != RT_NULL); - RT_ASSERT(event != RT_NULL); widget = RTGUI_WIDGET(object); list = RTGUI_LISTBOX(widget); @@ -228,6 +227,8 @@ rt_bool_t rtgui_combobox_event_handler(struct rtgui_object* object, struct rtgui } } break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/container.c b/components/rtgui/widgets/container.c index fc23030429..f5c954ddcf 100644 --- a/components/rtgui/widgets/container.c +++ b/components/rtgui/widgets/container.c @@ -14,7 +14,7 @@ */ #include #include -#include +#include #include #include @@ -25,26 +25,17 @@ static void _rtgui_container_constructor(rtgui_container_t *container) rtgui_container_event_handler); rtgui_list_init(&(container->children)); + container->layout_box = RT_NULL; - /* 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; + RTGUI_WIDGET(container)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; } static void _rtgui_container_destructor(rtgui_container_t *container) { rtgui_container_destroy_children(container); + + if (container->layout_box != RT_NULL) + rtgui_object_destroy(RTGUI_OBJECT(container->layout_box)); } static void _rtgui_container_update_toplevel(rtgui_container_t* container) @@ -152,15 +143,6 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object* object, struct rtgu break; case RTGUI_EVENT_KBD: - /* let parent to handle keyboard event */ - if (widget->parent != RT_NULL && - widget->parent != RTGUI_WIDGET(widget->toplevel) && - RTGUI_OBJECT(widget->parent)->event_handler) - { - return RTGUI_OBJECT(widget->parent)->event_handler( - RTGUI_OBJECT(widget->parent), - event); - } break; case RTGUI_EVENT_MOUSE_BUTTON: @@ -169,6 +151,14 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object* object, struct rtgu return rtgui_container_dispatch_mouse_event(container, (struct rtgui_event_mouse*)event); + case RTGUI_EVENT_SHOW: + rtgui_widget_onshow(RTGUI_OBJECT(container), event); + rtgui_container_dispatch_event(container, event); + break; + case RTGUI_EVENT_HIDE: + rtgui_widget_onhide(RTGUI_OBJECT(container), event); + rtgui_container_dispatch_event(container, event); + break; case RTGUI_EVENT_COMMAND: case RTGUI_EVENT_RESIZE: rtgui_container_dispatch_event(container, event); @@ -193,7 +183,6 @@ rtgui_container_t* rtgui_container_create(void) void rtgui_container_destroy(rtgui_container_t* container) { - rtgui_container_hide(container); rtgui_widget_destroy(RTGUI_WIDGET(container)); } @@ -296,26 +285,20 @@ 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)); + container->layout_box = box; + box->container = container; } -#endif -void rtgui_container_hide(rtgui_container_t* container) +void rtgui_container_layout(struct rtgui_container* container) { - if (container == RT_NULL) + if (container == RT_NULL || container->layout_box == RT_NULL) return; - if (RTGUI_WIDGET(container)->parent == RT_NULL) - { - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(container)); - return; - } + rtgui_box_layout(container->layout_box); } diff --git a/components/rtgui/widgets/filelist_view.c b/components/rtgui/widgets/filelist_view.c index 7d70b1f104..b3bf93f3e5 100644 --- a/components/rtgui/widgets/filelist_view.c +++ b/components/rtgui/widgets/filelist_view.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include #include @@ -235,14 +235,14 @@ static struct rtgui_listbox_item items[] = }; 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) +static rt_bool_t rtgui_filelist_view_on_folder_item(rtgui_object_t* object, 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)); + listbox = RTGUI_LISTBOX(object); + menu = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object))); view = RTGUI_FILELIST_VIEW(menu->user_data); /* hide window */ @@ -273,12 +273,14 @@ static void rtgui_filelist_view_on_folder_item(rtgui_widget_t* widget, struct rt rtgui_win_destroy(menu); break; } + + return RT_TRUE; } -static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_widget_t* widget, struct rtgui_event* event) +static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_object_t* object, struct rtgui_event* event) { rtgui_win_t *menu; - menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget)); + menu = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object))); /* destroy menu window */ rtgui_win_destroy(menu); @@ -295,7 +297,7 @@ static void rtgui_filelist_view_menu_pop(rtgui_widget_t *parent) 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_widget_get_toplevel(parent), + menu = rtgui_win_create(RTGUI_WIN(rtgui_widget_get_toplevel(parent)), "Folder Menu", &rect, RTGUI_WIN_STYLE_DEFAULT); if (menu != RT_NULL) { @@ -533,10 +535,12 @@ static void rtgui_filelist_view_onenturn(struct rtgui_filelist_view* view) } } -rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) +rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_object* object, struct rtgui_event* event) { + struct rtgui_widget *widget; struct rtgui_filelist_view* view = RT_NULL; + widget = RTGUI_WIDGET(object); view = RTGUI_FILELIST_VIEW(widget); switch (event->type) { @@ -650,7 +654,7 @@ rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct } /* use view event handler */ - return rtgui_container_event_handler(RTGUI_OBJECT(widget), event); + return rtgui_container_event_handler(object, event); } rtgui_filelist_view_t* rtgui_filelist_view_create(const char* directory, diff --git a/components/rtgui/widgets/iconbox.c b/components/rtgui/widgets/iconbox.c index 03db07bd83..ddd058cd97 100644 --- a/components/rtgui/widgets/iconbox.c +++ b/components/rtgui/widgets/iconbox.c @@ -66,6 +66,8 @@ rt_bool_t rtgui_iconbox_event_handler(struct rtgui_object* object, struct rtgui_ } break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/label.c b/components/rtgui/widgets/label.c index db8528e139..85ea6ceb44 100644 --- a/components/rtgui/widgets/label.c +++ b/components/rtgui/widgets/label.c @@ -49,6 +49,8 @@ rt_bool_t rtgui_label_event_handler(struct rtgui_object *object, struct rtgui_ev case RTGUI_EVENT_PAINT: rtgui_theme_draw_label(label); break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/listbox.c b/components/rtgui/widgets/listbox.c index 859cbc1304..e7d0dbbffb 100644 --- a/components/rtgui/widgets/listbox.c +++ b/components/rtgui/widgets/listbox.c @@ -267,17 +267,18 @@ rt_bool_t rtgui_listbox_event_handler(struct rtgui_object* object, struct rtgui_ { rt_int16_t old_item; - if (box->current_item == -1) + if (box->current_item == -1) { /* set a initial item */ - if ((box->items_count > 0) && + if ((box->items_count > 0) && (ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN)) { box->current_item = 0; rtgui_listbox_update_current(box, -1); - break; + return RT_TRUE; } - else return RT_FALSE; + else + return RT_FALSE; } old_item = box->current_item; @@ -287,32 +288,30 @@ rt_bool_t rtgui_listbox_event_handler(struct rtgui_object* object, struct rtgui_ if (box->current_item - box->page_items >= 0) box->current_item -= box->page_items; rtgui_listbox_update_current(box, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_UP: if (box->current_item > 0) box->current_item --; rtgui_listbox_update_current(box, old_item); - return RT_FALSE; + return RT_TRUE; 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; + return RT_TRUE; case RTGUIK_DOWN: if (box->current_item < box->items_count - 1) box->current_item ++; rtgui_listbox_update_current(box, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_RETURN: if (box->on_item != RT_NULL) - { box->on_item(RTGUI_OBJECT(box), RT_NULL); - } - return RT_FALSE; + return RT_TRUE; default: break; diff --git a/components/rtgui/widgets/listctrl.c b/components/rtgui/widgets/listctrl.c index 6fdc4028d6..bc3b75e0f1 100644 --- a/components/rtgui/widgets/listctrl.c +++ b/components/rtgui/widgets/listctrl.c @@ -316,13 +316,13 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui if (ctrl->current_item - ctrl->page_items >= 0) ctrl->current_item -= ctrl->page_items; rtgui_listctrl_update_current(ctrl, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_UP: if (ctrl->current_item > 0) ctrl->current_item --; rtgui_listctrl_update_current(ctrl, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_RIGHT: if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1) @@ -333,18 +333,18 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items; } rtgui_listctrl_update_current(ctrl, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_DOWN: if (ctrl->current_item < ctrl->items_count - 1) ctrl->current_item ++; rtgui_listctrl_update_current(ctrl, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_RETURN: if (ctrl->on_item != RT_NULL) { - ctrl->on_item(RTGUI_OBJECT(ctrl), RT_NULL); + return ctrl->on_item(RTGUI_OBJECT(ctrl), RT_NULL); } return RT_FALSE; diff --git a/components/rtgui/widgets/menu.c b/components/rtgui/widgets/menu.c index c56041db83..6ff278f71c 100644 --- a/components/rtgui/widgets/menu.c +++ b/components/rtgui/widgets/menu.c @@ -40,10 +40,12 @@ static void _rtgui_menu_destructor(rtgui_menu_t* menu) static rt_bool_t _rtgui_menu_onitem(struct rtgui_object* object, struct rtgui_event* event) { struct rtgui_menu* menu; - RTGUI_WIDGET_EVENT_HANDLER_PREPARE + + /* event will be NULL, don't check it. */ + RT_ASSERT(object); /* get menu */ - menu = RTGUI_MENU(rtgui_widget_get_toplevel(widget)); + menu = RTGUI_MENU(rtgui_widget_get_toplevel(RTGUI_WIDGET(object))); if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU) { const rtgui_menu_item_t* items; @@ -84,7 +86,7 @@ static rt_bool_t _rtgui_menu_onitem(struct rtgui_object* object, struct rtgui_ev { /* 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); + menu->items[menu->items_list->current_item].on_menuaction(RTGUI_OBJECT(menu), RT_NULL); /* hide sub-menu */ if (menu->sub_menu != RT_NULL) diff --git a/components/rtgui/widgets/notebook.c b/components/rtgui/widgets/notebook.c index c928cd268d..6b6f9ec49f 100644 --- a/components/rtgui/widgets/notebook.c +++ b/components/rtgui/widgets/notebook.c @@ -301,12 +301,16 @@ void rtgui_notebook_set_current_by_index(struct rtgui_notebook* notebook, rt_uin if ((index < notebook->count) && (notebook->current != index)) { + struct rtgui_widget *widget; + 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); + widget = notebook->childs[notebook->current].widget; + rtgui_widget_show(widget); + rtgui_widget_update(widget); + rtgui_widget_focus(widget); } } @@ -319,6 +323,16 @@ struct rtgui_widget* rtgui_notebook_get_widget_at(struct rtgui_notebook* noteboo return RT_NULL; } +static rt_bool_t _rtgui_notebook_current_widget_handle(struct rtgui_notebook *notebook, + struct rtgui_event *event) +{ + struct rtgui_widget *widget = rtgui_notebook_get_current(notebook); + if (widget && widget != RTGUI_WIDGET(notebook)) + return RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget), event); + else + return RT_FALSE; +} + rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui_event* event) { struct rtgui_notebook* notebook; @@ -336,17 +350,18 @@ rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui case RTGUI_EVENT_MOUSE_BUTTON: _rtgui_notebook_onmouse(notebook, (struct rtgui_event_mouse*)event); break; + case RTGUI_EVENT_SHOW: + /* show myself */ + rtgui_widget_onshow(object, event); + /* show the tab widget */ + return _rtgui_notebook_current_widget_handle(notebook, event); + case RTGUI_EVENT_HIDE: + /* hide myself */ + rtgui_widget_onhide(object, event); + /* hide the tab widget */ + return _rtgui_notebook_current_widget_handle(notebook, event); 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; + return _rtgui_notebook_current_widget_handle(notebook, event); default: /* use parent event handler */ return rtgui_widget_event_handler(object, event); diff --git a/components/rtgui/widgets/panel.c b/components/rtgui/widgets/panel.c new file mode 100644 index 0000000000..a2aa912cc5 --- /dev/null +++ b/components/rtgui/widgets/panel.c @@ -0,0 +1,89 @@ +/* + * File : panel.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 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-07-07 Bernard implement panel as a widget + */ +#include +#include +#include +#include + +static void _rtgui_panel_constructor(rtgui_panel_t *panel) +{ + /* init widget and set event handler */ + rtgui_object_set_event_handler(RTGUI_OBJECT(panel), rtgui_panel_event_handler); + + /* set field */ + panel->border_style = RTGUI_BORDER_NONE; +} + +DEFINE_CLASS_TYPE(panel, "panel", + RTGUI_CONTAINER_TYPE, + _rtgui_panel_constructor, + RT_NULL, + sizeof(struct rtgui_panel)); + +rt_bool_t rtgui_panel_event_handler(struct rtgui_object *object, struct rtgui_event* event) +{ + struct rtgui_panel* panel; + + panel = RTGUI_PANEL(object); + switch (event->type) + { + case RTGUI_EVENT_PAINT: + { + struct rtgui_dc* dc; + struct rtgui_rect rect; + + rtgui_widget_get_rect(RTGUI_WIDGET(object), &rect); + + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(object)); + if (dc == RT_NULL) return RT_FALSE; + + rtgui_dc_fill_rect(dc, &rect); + // rtgui_rect_inflate(&rect, RTGUI_WIDGET(panel)->); + rtgui_dc_draw_border(dc, &rect, panel->border_style); + + /* paint on each child */ + rtgui_container_dispatch_event(RTGUI_CONTAINER(panel), event); + + rtgui_dc_end_drawing(dc); + } + break; + + default: + return rtgui_container_event_handler(object, event); + } + + return RT_FALSE; +} + +rtgui_panel_t* rtgui_panel_create(int border_style) +{ + struct rtgui_panel* panel; + + panel = (struct rtgui_panel*) rtgui_widget_create(RTGUI_PANEL_TYPE); + if (panel != RT_NULL) + { + rtgui_rect_t rect = {0, 0, 100, 100}; + rtgui_widget_set_rect(RTGUI_WIDGET(panel), &rect); + + panel->border_style = border_style; + } + + return panel; +} + +void rtgui_panel_destroy(rtgui_panel_t* panel) +{ + rtgui_object_destroy(RTGUI_OBJECT(panel)); +} + diff --git a/components/rtgui/widgets/progressbar.c b/components/rtgui/widgets/progressbar.c index c42f2a3688..ea8a2bece9 100644 --- a/components/rtgui/widgets/progressbar.c +++ b/components/rtgui/widgets/progressbar.c @@ -38,6 +38,8 @@ rt_bool_t rtgui_progressbar_event_handler(struct rtgui_object* object, case RTGUI_EVENT_PAINT: rtgui_theme_draw_progressbar(bar); break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/radiobox.c b/components/rtgui/widgets/radiobox.c index b1def7af01..5f67d2fcbc 100644 --- a/components/rtgui/widgets/radiobox.c +++ b/components/rtgui/widgets/radiobox.c @@ -101,7 +101,7 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui #ifndef RTGUI_USING_SMALL_SIZE if (widget->on_key != RT_NULL) - widget->on_key(RTGUI_OBJECT(widget), event); + return widget->on_key(RTGUI_OBJECT(widget), event); else #endif { @@ -116,12 +116,18 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui if (e->key == RTGUIK_UP) { if (radiobox->item_selection > 0) + { rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1); + return RT_TRUE; + } } else if (e->key == RTGUIK_DOWN) { if (radiobox->item_selection < radiobox->item_count - 1) + { rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1); + return RT_TRUE; + } } } else @@ -129,12 +135,18 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui if (e->key == RTGUIK_LEFT) { if (radiobox->item_selection > 0) + { rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1); + return RT_TRUE; + } } else if (e->key == RTGUIK_RIGHT) { if (radiobox->item_selection < radiobox->item_count - 1) + { rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1); + return RT_TRUE; + } } } } @@ -150,6 +162,8 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui rtgui_radiobox_onmouse(radiobox, (struct rtgui_event_mouse*)event); } break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/scrollbar.c b/components/rtgui/widgets/scrollbar.c index 257591a028..4a6a63e471 100644 --- a/components/rtgui/widgets/scrollbar.c +++ b/components/rtgui/widgets/scrollbar.c @@ -302,7 +302,7 @@ rt_bool_t rtgui_scrollbar_event_handler(struct rtgui_object *object, break; default: - break; + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/slider.c b/components/rtgui/widgets/slider.c index ca71fdfaad..c3631cf0d5 100644 --- a/components/rtgui/widgets/slider.c +++ b/components/rtgui/widgets/slider.c @@ -168,13 +168,10 @@ rt_bool_t rtgui_slider_event_handler(struct rtgui_object *object, struct rtgui_e #ifndef RTGUI_USING_SMALL_SIZE if (widget->on_key != RT_NULL) - widget->on_key(RTGUI_OBJECT(widget), event); + return widget->on_key(RTGUI_OBJECT(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; @@ -188,6 +185,9 @@ rt_bool_t rtgui_slider_event_handler(struct rtgui_object *object, struct rtgui_e rtgui_slider_onmouse(slider, (struct rtgui_event_mouse*)event); } break; + + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/staticline.c b/components/rtgui/widgets/staticline.c index 10bdd8bad8..0a2ea20079 100644 --- a/components/rtgui/widgets/staticline.c +++ b/components/rtgui/widgets/staticline.c @@ -36,6 +36,8 @@ rt_bool_t rtgui_staticline_event_handler(struct rtgui_object* object, struct rtg #endif rtgui_theme_draw_staticline(staticline); break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/textbox.c b/components/rtgui/widgets/textbox.c index a28b3ec5f9..df56cbc9ff 100644 --- a/components/rtgui/widgets/textbox.c +++ b/components/rtgui/widgets/textbox.c @@ -11,106 +11,197 @@ * Date Author Notes * 2009-10-16 Bernard first version * 2011-01-224 Bernard fix backspace issue. + * 2012-06-09 asml refactor + * 2012-06-17 Grissiom misc cleanup and merge */ -#include -#include -#include +#include #include +#include +#include -#ifndef _WIN32 #include -#endif -#define RTGUI_TEXTBOX_LINE_MAX 64 -#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_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) - box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; - else - box->flag |= RTGUI_TEXTBOX_CARET_SHOW; - - /* re-darw textbox */ - rtgui_theme_draw_textbox(box); - - return ; -} +static void rtgui_textbox_draw_caret(rtgui_textbox_t *box, rt_uint16_t position); +static rt_bool_t rtgui_textbox_onkey(struct rtgui_object* widget, rtgui_event_t* event); +static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* widget, rtgui_event_t* event); +static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* widget, rtgui_event_t* event); static void _rtgui_textbox_constructor(rtgui_textbox_t *box) { - rtgui_rect_t rect = {0, 0, RTGUI_TEXTBOX_DEFAULT_WIDTH, RTGUI_TEXTBOX_DEFAULT_HEIGHT}; - rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect); + rtgui_rect_t rect; + + RTGUI_WIDGET_FLAG(RTGUI_WIDGET(box)) |= RTGUI_WIDGET_FLAG_FOCUSABLE; - RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; 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); +#ifndef RTGUI_USING_SMALL_SIZE + rtgui_widget_set_onkey(RTGUI_WIDGET(box),rtgui_textbox_onkey); +#endif + RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = black; + RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white; /* set default text align */ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL; - /* set proper of control */ - box->caret_timer = rtgui_timer_create(RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC, - _rtgui_textbox_caret_timeout, box); + box->caret_timer = RT_NULL; + box->caret = RT_NULL; box->line = box->line_begin = box->position = 0; box->flag = RTGUI_TEXTBOX_SINGLE; - /* allocate default line buffer */ box->text = RT_NULL; - rtgui_font_get_metrics(RTGUI_WIDGET(box)->gc.font, "h", &rect); + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(box)), "H", &rect); box->font_width = rtgui_rect_width(rect); + box->on_enter = RT_NULL; + box->dis_length = 0; } -static void _rtgui_textbox_deconstructor(rtgui_textbox_t *box) +static void _rtgui_textbox_deconstructor(rtgui_textbox_t *textbox) { - if (box->text != RT_NULL) + if(textbox->text != RT_NULL) { - rt_free(box->text); - box->text = RT_NULL; + rtgui_free(textbox->text); + textbox->text = RT_NULL; + } + if(textbox->caret_timer != RT_NULL) + { + rtgui_timer_destory(textbox->caret_timer); + textbox->caret_timer = RT_NULL; + } + if(textbox->caret != RT_NULL) + { + rtgui_free(textbox->caret); + textbox->caret = RT_NULL; } - - rtgui_timer_destory(box->caret_timer); - box->caret_timer = RT_NULL; } -DEFINE_CLASS_TYPE(textbox, "textbox", +DEFINE_CLASS_TYPE(textbox, "textbox", RTGUI_WIDGET_TYPE, _rtgui_textbox_constructor, _rtgui_textbox_deconstructor, sizeof(struct rtgui_textbox)); -static void rtgui_textbox_onmouse(struct rtgui_textbox* box, struct rtgui_event_mouse* event) +static void rtgui_textbox_get_caret_rect(rtgui_textbox_t *box, rtgui_rect_t *rect, rt_uint16_t position) +{ + int font_h,box_h; + rtgui_rect_t item_rect; + + RT_ASSERT(box != RT_NULL); + + rtgui_widget_get_rect(RTGUI_WIDGET(box), rect); + + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(box)), "H", &item_rect); + font_h = rtgui_rect_height(item_rect); + box_h = rtgui_rect_height(*rect); + + rect->x1 += position * box->font_width + 2; + rect->x2 = rect->x1 + 2; + rect->y1 += (box_h - font_h) / 2; + rect->y2 = rect->y1 + font_h; +} + +static void rtgui_textbox_init_caret(rtgui_textbox_t *box, rt_uint16_t position) +{ + int x, y; + rtgui_color_t color; + rtgui_rect_t rect; + int ofs = 0; + + RT_ASSERT(box != RT_NULL); + + if (!RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box))) + return; + + rtgui_textbox_get_caret_rect(box, &box->caret_rect, position); + rect = box->caret_rect; + rtgui_widget_rect_to_device(RTGUI_WIDGET(box), &rect); + + if (box->caret == RT_NULL) + box->caret = rtgui_malloc(rtgui_rect_width(rect)*rtgui_rect_height(rect)*sizeof(rtgui_color_t)); + + for (x = rect.x1; x < rect.x2; x++) + { + for(y = rect.y1; y < rect.y2; y++) + { + rtgui_graphic_driver_get_default()->ops->get_pixel(&color, x, y); + *(box->caret + ofs) = color; + ofs++; + } + } +} + +/* draw caret */ +static void rtgui_textbox_draw_caret(rtgui_textbox_t *box, rt_uint16_t position) +{ + int x,y; + rtgui_color_t color; + rtgui_rect_t rect; + int ofs = 0; + struct rtgui_dc *dc; + + RT_ASSERT(box != RT_NULL); + if (box->caret == RT_NULL) + return; + + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box)); + if (dc == RT_NULL) + return; + + rect = box->caret_rect; + + for(x = rect.x1; x < rect.x2; x++) + { + for(y = rect.y1; y < rect.y2; y++) + { + color = *(box->caret + ofs); + ofs++; + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW) + { + color = ~color; + } + rtgui_dc_draw_color_point(dc, x, y, color); + } + } + + rtgui_dc_end_drawing(dc); +} + +static void rtgui_textbox_timeout(rtgui_timer_t* timer, void* parameter) +{ + rtgui_textbox_t* box; + + box = RTGUI_TEXTBOX(parameter); + /* set caret flag */ + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW) + box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; + else + box->flag |= RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box,box->position); +} + +static void rtgui_textbox_onmouse(rtgui_textbox_t* box, struct rtgui_event_mouse* event) { rt_size_t length; + rt_uint16_t posbak = box->position; RT_ASSERT(box != RT_NULL); RT_ASSERT(event != RT_NULL); - length = rt_strlen((const char*)box->text); + length = rt_strlen(box->text); - if (event->button & RTGUI_MOUSE_BUTTON_LEFT && - event->button & RTGUI_MOUSE_BUTTON_DOWN) + if(event->button & RTGUI_MOUSE_BUTTON_LEFT && event->button & RTGUI_MOUSE_BUTTON_DOWN) { rt_int32_t x; - + /* single line text */ /* set caret position */ x = event->x - RTGUI_WIDGET(box)->extent.x1; - if (x < 0) + if(x < 0) { box->position = 0; } - else if (x > length * box->font_width) + else if(x > length * box->font_width) { box->position = length; } @@ -119,30 +210,54 @@ static void rtgui_textbox_onmouse(struct rtgui_textbox* box, struct rtgui_event_ box->position = x / box->font_width; } - /* set caret to show */ - box->flag |= RTGUI_TEXTBOX_CARET_SHOW; + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW) + { + if(box->caret_timer != RT_NULL) + rtgui_timer_stop(box->caret_timer); - /* set widget focus */ - rtgui_widget_focus(RTGUI_WIDGET(box)); - /* re-draw text box */ - rtgui_theme_draw_textbox(box); + box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box, posbak); + + if(box->caret_timer != RT_NULL) + rtgui_timer_start(box->caret_timer); + } + + rtgui_textbox_init_caret(box, box->position); + box->flag |= RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box,box->position); } } -static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kbd* event) +static rt_bool_t rtgui_textbox_onkey(struct rtgui_object* widget, rtgui_event_t* event) { + rtgui_textbox_t* box = RTGUI_TEXTBOX(widget); + struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; rt_size_t length; + rt_uint16_t posbak = box->position; RT_ASSERT(box != RT_NULL); - RT_ASSERT(event != RT_NULL); + RT_ASSERT(ekbd != RT_NULL); - if (event->type != RTGUI_KEYUP) - return ; + /* handle the key at down time and nothing to do with up */ + if (RTGUI_KBD_IS_UP(ekbd)) + return RT_TRUE; - length = rt_strlen((const char*)box->text); - if (event->key == RTGUIK_DELETE) + if (box->dis_length == 0) { - if (box->position == length - 1) + rtgui_rect_t rect; + + rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect); + + if (box->font_width == 0) + return RT_FALSE; + + box->dis_length = (rtgui_rect_width(rect) - 5) / box->font_width; + } + + length = rt_strlen(box->text); + if(ekbd->key == RTGUIK_DELETE) + {/* delete latter character */ + if(box->position == length - 1) { box->text[box->position] = '\0'; } @@ -151,197 +266,278 @@ static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kb char *c; /* remove character */ - for (c = &box->text[box->position]; c[1] != '\0'; c++) + for(c = &box->text[box->position]; c[1] != '\0'; c++) *c = c[1]; *c = '\0'; } } - else if (event->key == RTGUIK_BACKSPACE) - { - if ((box->position == length - 1) && length != 1) + else if(ekbd->key == RTGUIK_BACKSPACE) + {/* delete front character */ + + if(box->position == length - 1) { box->text[box->position] = '\0'; box->position --; } - else if (box->position != 0) + else if(box->position != 0) { /* remove current character */ - char *c; + if(box->position != 0) + { + char *c; - /* remove character */ - for (c = &box->text[box->position - 1]; c[1] != '\0'; c++) - *c = c[1]; - *c = '\0'; + /* remove character */ + for(c = &box->text[box->position - 1]; c[1] != '\0'; c++) + *c = c[1]; + *c = '\0'; + } box->position --; } } - else if (event->key == RTGUIK_LEFT) - { - if (box->position > 0) box->position --; + else if(ekbd->key == RTGUIK_LEFT) + {/* move to prev */ + if(box->position > 0) + { + box->position --; + } } - else if (event->key == RTGUIK_RIGHT) - { - if (box->position < length) box->position ++; + else if(ekbd->key == RTGUIK_RIGHT) + {/* move to next */ + if(box->position < length) + { + box->position ++; + } } - else if (event->key == RTGUIK_HOME) - { + else if(ekbd->key == RTGUIK_HOME) + {/* move cursor to start */ box->position = 0; } - else if (event->key == RTGUIK_END) - { + else if(ekbd->key == RTGUIK_END) + {/* move cursor to end */ box->position = length; } - else if (event->key == RTGUIK_RETURN) + else if(ekbd->key == RTGUIK_RETURN) { - if (box->on_enter != RT_NULL) + if(box->on_enter != RT_NULL) { - box->on_enter(RTGUI_WIDGET(box), RT_NULL); + box->on_enter(box, event); } } + else if(ekbd->key == RTGUIK_NUMLOCK) + { + /* change numlock state */ + /* + extern void update_number_lock(void); + update_number_lock(); + */ + } else { - if (isprint(event->key) || isdigit(event->key)) - { + if(isprint(ekbd->key)) + {/* it's may print character */ /* no buffer on this line */ - if (length + 1 > box->line_length) return; + if(box->flag & RTGUI_TEXTBOX_DIGIT) + {/* only input digit */ + if(!isdigit(ekbd->key)) + {/* exception: '.' and '-' */ + if(ekbd->key != '.' && ekbd->key !='-')return RT_FALSE; + if(ekbd->key == '.' && strchr(box->text,'.'))return RT_FALSE; - if (box->position < length - 1) + if(ekbd->key == '-') + { + if(length+1 > box->line_length) return RT_FALSE; + if(length+1 > box->dis_length) return RT_FALSE; + + if(strchr(box->text,'-')) + { + char* c; + for(c = &box->text[0]; c != &box->text[length]; c++) + *c = *(c+1); + box->text[length] = '\0'; + box->position --; + goto _exit; + } + else + { + char* c; + for(c = &box->text[length]; c != &box->text[0]; c--) + *c = *(c-1); + box->text[0] = '-'; + box->text[length+1] = '\0'; + box->position ++; + goto _exit; + } + } + } + //rt_kprintf("%c ",ekbd->key);//debug printf + } + if(length+1 > box->line_length) return RT_FALSE; + if(length+1 > box->dis_length) return RT_FALSE; + + if(box->position <= length-1) { char* c; - for (c = &box->text[length]; c != &box->text[box->position]; c--) + for(c = &box->text[length]; c != &box->text[box->position]; c--) *c = *(c-1); - box->text[length + 1] = '\0'; + box->text[length+1] = '\0'; } - box->text[box->position] = event->key; + box->text[box->position] = ekbd->key; box->position ++; } } - /* set caret to show */ - box->flag |= RTGUI_TEXTBOX_CARET_SHOW; - - /* re-draw text box */ - rtgui_theme_draw_textbox(box); -} - -static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* object, struct rtgui_event* event) -{ - 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 */ - rtgui_timer_start(box->caret_timer); - - return RT_TRUE; -} - -static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* object, struct rtgui_event* event) -{ - 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 */ - box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; - - return RT_TRUE; -} - -rt_bool_t rtgui_textbox_event_handler(struct rtgui_object* object, struct rtgui_event* event) -{ - struct rtgui_textbox* box; - RTGUI_WIDGET_EVENT_HANDLER_PREPARE - - box = RTGUI_TEXTBOX(object); - switch (event->type) +_exit: + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW) { - case RTGUI_EVENT_PAINT: -#ifndef RTGUI_USING_SMALL_SIZE - if (widget->on_draw != RT_NULL) - widget->on_draw(RTGUI_OBJECT(widget), event); - else -#endif - rtgui_theme_draw_textbox(box); - break; + if(box->caret_timer != RT_NULL) + rtgui_timer_stop(box->caret_timer); - 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(RTGUI_OBJECT(widget), event); - else -#endif - rtgui_textbox_onmouse(box, (struct rtgui_event_mouse*)event); - return RT_TRUE; - - 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(RTGUI_OBJECT(widget), event); - else -#endif - rtgui_textbox_onkey(box, (struct rtgui_event_kbd*)event); - return RT_TRUE; + box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box, posbak);/* refresh it */ + if(box->caret_timer != RT_NULL) + rtgui_timer_start(box->caret_timer); } - return RT_FALSE; + /* re-draw text box */ + rtgui_textbox_ondraw(box); + + rtgui_textbox_init_caret(box, box->position); + box->flag |= RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box,box->position); + + return RT_TRUE; } -struct rtgui_textbox* rtgui_textbox_create(const char* text, rt_uint8_t flag) +static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* widget, rtgui_event_t* event) { - struct rtgui_textbox* box; + rtgui_textbox_t* box = RTGUI_TEXTBOX(widget); - box = (struct rtgui_textbox*) rtgui_widget_create (RTGUI_TEXTBOX_TYPE); - if (box != RT_NULL) + /* if there is already a timer, don't create another one. */ + if (box->caret_timer == RT_NULL) + { + box->caret_timer = rtgui_timer_create(100, RT_TIMER_FLAG_PERIODIC,rtgui_textbox_timeout, box); + /* set caret to show */ + box->flag |= RTGUI_TEXTBOX_CARET_SHOW; + /* start caret timer */ + if(box->caret_timer != RT_NULL) + rtgui_timer_start(box->caret_timer); + } + + return RT_TRUE; +} + +static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* widget, rtgui_event_t* event) +{ + rtgui_textbox_t* box = RTGUI_TEXTBOX(widget); + + /* stop caret timer */ + if(box->caret_timer != RT_NULL) + { + rtgui_timer_stop(box->caret_timer); + rtgui_timer_destory(box->caret_timer); + box->caret_timer = RT_NULL; + } + /* set caret to hide */ + box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box,box->position); + + if(box->on_enter != RT_NULL) + box->on_enter(box,event); + + return RT_TRUE; +} + +rtgui_textbox_t* rtgui_textbox_create(const char* text, rt_uint32_t flag) +{ + rtgui_textbox_t* box; + + box = (struct rtgui_textbox*)rtgui_widget_create(RTGUI_TEXTBOX_TYPE); + if(box != RT_NULL) { - rtgui_rect_t rect = {0, 0, RTGUI_TEXTBOX_DEFAULT_WIDTH, RTGUI_TEXTBOX_DEFAULT_HEIGHT}; - /* allocate default line buffer */ rtgui_textbox_set_value(box, text); box->flag = flag; - - rtgui_font_get_metrics(RTGUI_WIDGET(box)->gc.font, "h", &rect); } return box; } -void rtgui_textbox_destroy(struct rtgui_textbox* box) +void rtgui_textbox_destroy(rtgui_textbox_t* box) { rtgui_widget_destroy(RTGUI_WIDGET(box)); } -void rtgui_textbox_set_value(struct rtgui_textbox* box, const char* text) +void rtgui_textbox_ondraw(rtgui_textbox_t* box) { - if (box->text != RT_NULL) + /* draw button */ + rtgui_rect_t rect; + struct rtgui_dc* dc; + rtgui_color_t fc; + + RT_ASSERT(box != RT_NULL); + + /* begin drawing */ + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box)); + if (dc == RT_NULL) + return; + + /* get widget rect */ + rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect); + fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)); + + rtgui_rect_inflate(&rect, -1); + + /* fill widget rect with white color */ + RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white; + rtgui_dc_fill_rect(dc,&rect); + + rtgui_rect_inflate(&rect, 1); + /* draw border */ + RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = RTGUI_RGB(123, 158, 189); + rtgui_dc_draw_rect(dc, &rect); + + /* draw text */ + RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = fc; + if(box->text != RT_NULL) { - if (box->line_length > rt_strlen(text) + 1) + rect.x1 += RTGUI_WIDGET_DEFAULT_MARGIN; + /* draw single text */ + if(box->flag & RTGUI_TEXTBOX_MASK) { - rt_memcpy(box->text, text, rt_strlen(text) + 1); - /* set current position */ - box->position = 0; - return; + /* draw '*' */ + rt_size_t len = rt_strlen(box->text); + if(len > 0) + { + char *text_mask = rtgui_malloc(len + 1); + rt_memset(text_mask, '*', len + 1); + text_mask[len] = 0; + rtgui_dc_draw_text(dc, text_mask, &rect); + rtgui_free(text_mask); + } } else { - /* free the old text */ - rtgui_free(box->text); - box->text = RT_NULL; + rtgui_dc_draw_text(dc, box->text, &rect); } } - box->line_length = RTGUI_TEXTBOX_LINE_MAX > rt_strlen(text) + 1 ? - RTGUI_TEXTBOX_LINE_MAX : rt_strlen(text) + 1; + rtgui_dc_end_drawing(dc); +} + +/* set textbox text */ +void rtgui_textbox_set_value(rtgui_textbox_t* box, const char* text) +{ + if(box->text != RT_NULL) + {/* yet exist something */ + /* free the old text */ + rtgui_free(box->text); + box->text = RT_NULL; + } + + /* no something */ + box->line_length = ((rt_strlen(text)+1)/RTGUI_TEXTBOX_LINE_MAX+1)*RTGUI_TEXTBOX_LINE_MAX; /* allocate line buffer */ box->text = rtgui_malloc(box->line_length); @@ -351,25 +547,26 @@ void rtgui_textbox_set_value(struct rtgui_textbox* box, const char* text) rt_memcpy(box->text, text, rt_strlen(text) + 1); /* set current position */ - box->position = 0; + box->position = rt_strlen(text); } -const char* rtgui_textbox_get_value(struct rtgui_textbox* box) +const char* rtgui_textbox_get_value(rtgui_textbox_t* box) { return (const char*)box->text; } -void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length) +void rtgui_textbox_set_line_length(rtgui_textbox_t* box, rt_size_t length) { rt_uint8_t* new_line; RT_ASSERT(box != RT_NULL); /* invalid length */ - if (length <= 0) return; + if(length <= 0) + return; new_line = rtgui_malloc(length); - if (length < box->line_length) + if(length < box->line_length) { rt_memcpy(new_line, box->text, length - 1); new_line[length] = '\0'; @@ -383,3 +580,51 @@ void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length) box->line_length = length; } +/* get textbox text area */ +void rtgui_textbox_get_edit_rect(rtgui_textbox_t *box,rtgui_rect_t *rect) +{ + rtgui_widget_get_rect(RTGUI_WIDGET(box), rect); + rtgui_rect_inflate(rect,-1); +} + +rt_bool_t rtgui_textbox_event_handler(struct rtgui_object *object, rtgui_event_t* event) +{ + rtgui_widget_t *widget = RTGUI_WIDGET(object); + rtgui_textbox_t* box = RTGUI_TEXTBOX(object); + + switch (event->type) + { + case RTGUI_EVENT_PAINT: +#ifndef RTGUI_USING_SMALL_SIZE + if(widget->on_draw != RT_NULL) + widget->on_draw(RTGUI_OBJECT(widget), event); + else +#endif + rtgui_textbox_ondraw(box); + break; + + case RTGUI_EVENT_MOUSE_BUTTON: +#ifndef RTGUI_USING_SMALL_SIZE + if(widget->on_mouseclick != RT_NULL) + widget->on_mouseclick(RTGUI_OBJECT(widget), event); + else +#endif + rtgui_textbox_onmouse(box, (struct rtgui_event_mouse*)event); + return RT_TRUE; + + case RTGUI_EVENT_KBD: +#ifndef RTGUI_USING_SMALL_SIZE + if(widget->on_key != RT_NULL) + widget->on_key(RTGUI_OBJECT(widget), event); + else +#endif + rtgui_textbox_onkey(RTGUI_OBJECT(box), (struct rtgui_event*)event); + return RT_TRUE; + + default: + return rtgui_widget_event_handler(RTGUI_OBJECT(widget),event); + } + + return RT_FALSE; +} + diff --git a/components/rtgui/widgets/textview.c b/components/rtgui/widgets/textview.c index fe57b82ab2..af16854198 100644 --- a/components/rtgui/widgets/textview.c +++ b/components/rtgui/widgets/textview.c @@ -307,6 +307,8 @@ rt_bool_t rtgui_textview_event_handler(struct rtgui_object* object, struct rtgui } break; } + default: + return rtgui_widget_event_handler(RTGUI_OBJECT(widget),event); } return RT_FALSE; diff --git a/components/rtgui/widgets/widget.c b/components/rtgui/widgets/widget.c index e639eb8bed..dbdd644ce2 100644 --- a/components/rtgui/widgets/widget.c +++ b/components/rtgui/widgets/widget.c @@ -14,7 +14,7 @@ */ #include -#include +#include #include #include #include @@ -36,9 +36,7 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget) widget->gc.font = rtgui_font_default(); widget->gc.textstyle = RTGUI_TEXTSTYLE_NORMAL; widget->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP; -#ifndef RTGUI_USING_SMALL_SIZE widget->align = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP; -#endif /* set parent and toplevel root */ widget->parent = RT_NULL; @@ -88,7 +86,7 @@ static void _rtgui_widget_destructor(rtgui_widget_t *widget) rtgui_region_fini(&(widget->clip)); } -DEFINE_CLASS_TYPE(widget, "widget", +DEFINE_CLASS_TYPE(widget, "widget", RTGUI_OBJECT_TYPE, _rtgui_widget_constructor, _rtgui_widget_destructor, @@ -114,11 +112,9 @@ void rtgui_widget_set_rect(rtgui_widget_t* widget, const rtgui_rect_t* rect) widget->extent = *rect; -#ifndef RTGUI_USING_SMALL_SIZE /* reset mini width and height */ widget->mini_width = rtgui_rect_width(widget->extent); widget->mini_height = rtgui_rect_height(widget->extent); -#endif /* it's not empty, fini it */ if (rtgui_region_not_empty(&(widget->clip))) @@ -166,7 +162,6 @@ void rtgui_widget_get_extent(rtgui_widget_t* widget, rtgui_rect_t *rect) *rect = widget->extent; } -#ifndef RTGUI_USING_SMALL_SIZE void rtgui_widget_set_miniwidth(rtgui_widget_t* widget, int width) { RT_ASSERT(widget != RT_NULL); @@ -180,7 +175,6 @@ void rtgui_widget_set_miniheight(rtgui_widget_t* widget, int height) widget->mini_height = height; } -#endif /* * This function moves widget and its children to a logic point @@ -410,16 +404,16 @@ struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget) 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_SHOW: + return rtgui_widget_onshow(object, event); + case RTGUI_EVENT_HIDE: + return rtgui_widget_onhide(object, event); +#ifndef RTGUI_USING_SMALL_SIZE case RTGUI_EVENT_PAINT: if (widget->on_draw != RT_NULL) return widget->on_draw(RTGUI_OBJECT(widget), event); @@ -444,8 +438,8 @@ rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* if (widget->on_size != RT_NULL) return widget->on_size(RTGUI_OBJECT(widget), event); break; - } #endif + } return RT_FALSE; } @@ -512,12 +506,26 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget) } } -void rtgui_widget_show(rtgui_widget_t* widget) +void rtgui_widget_show(struct rtgui_widget *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; + struct rtgui_event_show eshow; + RT_ASSERT(widget != RT_NULL); + + if (!RTGUI_WIDGET_IS_HIDE(widget)) + return; + + RTGUI_EVENT_SHOW_INIT(&eshow); + if (RTGUI_OBJECT(widget)->event_handler != RT_NULL) + { + RTGUI_OBJECT(widget)->event_handler( + RTGUI_OBJECT(widget), + &eshow); + } +} + +rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *event) +{ + struct rtgui_widget *widget = RTGUI_WIDGET(object); /* update the clip info of widget */ RTGUI_WIDGET_UNHIDE(widget); @@ -525,10 +533,14 @@ void rtgui_widget_show(rtgui_widget_t* widget) if (widget->on_show != RT_NULL) widget->on_show(RTGUI_OBJECT(widget), RT_NULL); + + return RT_FALSE; } -void rtgui_widget_hide(rtgui_widget_t* widget) +rt_bool_t rtgui_widget_onhide(struct rtgui_object *object, struct rtgui_event *event) { + struct rtgui_widget *widget = RTGUI_WIDGET(object); + /* hide this widget */ RTGUI_WIDGET_HIDE(widget); @@ -549,12 +561,31 @@ void rtgui_widget_hide(rtgui_widget_t* widget) if (widget->on_hide != RT_NULL) widget->on_hide(RTGUI_OBJECT(widget), RT_NULL); + + return RT_FALSE; +} + +void rtgui_widget_hide(struct rtgui_widget *widget) +{ + struct rtgui_event_hide ehide; + RT_ASSERT(widget != RT_NULL); + + if (RTGUI_WIDGET_IS_HIDE(widget)) + return; + + RTGUI_EVENT_HIDE_INIT(&ehide); + if (RTGUI_OBJECT(widget)->event_handler != RT_NULL) + { + RTGUI_OBJECT(widget)->event_handler( + RTGUI_OBJECT(widget), + &ehide); + } } rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t* widget) { rtgui_widget_t* parent; - + /* get parent widget */ parent = widget->parent; while (parent->parent != RT_NULL && (RTGUI_WIDGET_FLAG(parent) & RTGUI_WIDGET_FLAG_TRANSPARENT)) @@ -591,6 +622,9 @@ void rtgui_widget_update(rtgui_widget_t* widget) RT_ASSERT(widget != RT_NULL); + if (RTGUI_WIDGET_IS_HIDE(widget)) + return; + if (RTGUI_OBJECT(widget)->event_handler != RT_NULL) { RTGUI_OBJECT(widget)->event_handler( diff --git a/components/rtgui/widgets/window.c b/components/rtgui/widgets/window.c index f8d5db3d24..515817cd21 100644 --- a/components/rtgui/widgets/window.c +++ b/components/rtgui/widgets/window.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include @@ -108,10 +108,6 @@ DEFINE_CLASS_TYPE(win, "win", _rtgui_win_destructor, sizeof(struct rtgui_win)); -#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, @@ -125,23 +121,7 @@ rtgui_win_t* rtgui_win_create(struct rtgui_win* parent_window, return RT_NULL; /* set parent toplevel */ -#ifdef RTGUI_USING_DESKTOP_WINDOW - if (style & RTGUI_WIN_STYLE_DESKTOP) - { - 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) @@ -163,25 +143,13 @@ __on_err: return RT_NULL; } -void rtgui_win_destroy(struct rtgui_win* win) -{ - if (win->flag & RTGUI_WIN_FLAG_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) + struct rtgui_event *event, + rt_bool_t force_close) { if (win->on_close != RT_NULL) { - if (win->on_close(RTGUI_OBJECT(win), event) == RT_FALSE) + if ((win->on_close(RTGUI_OBJECT(win), event) == RT_FALSE) && !force_close) return RT_FALSE; } @@ -201,6 +169,42 @@ static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win, return RT_TRUE; } +void rtgui_win_destroy(struct rtgui_win* win) +{ + /* close the window first if it's not. */ + if (!(win->flag & RTGUI_WIN_FLAG_CLOSED)) + { + struct rtgui_event_win_close eclose; + + RTGUI_EVENT_WIN_CLOSE_INIT(&eclose); + eclose.wid = win; + + if (win->style & RTGUI_WIN_STYLE_DESTROY_ON_CLOSE) + { + _rtgui_win_deal_close(win, + (struct rtgui_event*)&eclose, + RT_TRUE); + return; + } + else + _rtgui_win_deal_close(win, + (struct rtgui_event*)&eclose, + RT_TRUE); + } + + if (win->flag & RTGUI_WIN_FLAG_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)); + } +} + /* send a close event to myself to get a consistent behavior */ rt_bool_t rtgui_win_close(struct rtgui_win* win) { @@ -209,14 +213,17 @@ rt_bool_t rtgui_win_close(struct rtgui_win* win) RTGUI_EVENT_WIN_CLOSE_INIT(&eclose); eclose.wid = win; return _rtgui_win_deal_close(win, - (struct rtgui_event*)&eclose); + (struct rtgui_event*)&eclose, + RT_FALSE); } rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal) { - struct rtgui_event_win_show eshow; rt_base_t exit_code = -1; + struct rtgui_app *app; + struct rtgui_event_win_show eshow; + app = rtgui_app_self(); RTGUI_EVENT_WIN_SHOW_INIT(&eshow); eshow.wid = win; @@ -230,29 +237,33 @@ rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal) return exit_code; } + /* set window unhidden before notify the server */ + rtgui_widget_show(RTGUI_WIDGET(win)); + if (rtgui_server_post_event_sync(RTGUI_EVENT(&eshow), - sizeof(struct rtgui_event_win_show) - ) != RT_EOK) + sizeof(struct rtgui_event_win_show)) != RT_EOK) { - rt_kprintf("show win failed\n"); + /* It could not be shown if a parent window is hidden. */ + rtgui_widget_hide(RTGUI_WIDGET(win)); return exit_code; } - /* set window unhidden */ - RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win)); - if (win->focused_widget == RT_NULL) rtgui_widget_focus(RTGUI_WIDGET(win)); + /* set main window */ + if (app->main_object == RT_NULL) + rtgui_app_set_main_win(win); + if (is_modal == RT_TRUE) { - struct rtgui_application *app; + struct rtgui_app *app; struct rtgui_event_win_modal_enter emodal; RTGUI_EVENT_WIN_MODAL_ENTER_INIT(&emodal); emodal.wid = win; - app = rtgui_application_self(); + app = rtgui_app_self(); RT_ASSERT(app != RT_NULL); win->flag |= RTGUI_WIN_FLAG_MODAL; @@ -263,7 +274,7 @@ rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal) app->modal_object = RTGUI_OBJECT(win); - exit_code = rtgui_application_run(app); + exit_code = rtgui_app_run(app); app->modal_object = RT_NULL; win->flag &= ~RTGUI_WIN_FLAG_MODAL; @@ -282,7 +293,7 @@ void rtgui_win_end_modal(struct rtgui_win* win, rtgui_modal_code_t modal_code) if (win == RT_NULL || !(win->flag & RTGUI_WIN_FLAG_MODAL)) return; - rtgui_application_exit(rtgui_application_self(), modal_code); + rtgui_app_exit(rtgui_app_self(), modal_code); /* remove modal mode */ win->flag &= ~RTGUI_WIN_FLAG_MODAL; @@ -291,9 +302,6 @@ void rtgui_win_end_modal(struct rtgui_win* win, rtgui_modal_code_t modal_code) 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)) && win->flag & RTGUI_WIN_FLAG_CONNECTED) @@ -310,12 +318,21 @@ void rtgui_win_hiden(struct rtgui_win* win) return; } - /* set window hide and deactivated */ - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win)); + rtgui_widget_hide(RTGUI_WIDGET(win)); win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE; } } +rt_err_t rtgui_win_activate(struct rtgui_win *win) +{ + struct rtgui_event_win_activate eact; + RTGUI_EVENT_WIN_ACTIVATE_INIT(&eact); + eact.wid = win; + + return rtgui_server_post_event_sync(RTGUI_EVENT(&eact), + sizeof(eact)); +} + rt_bool_t rtgui_win_is_activated(struct rtgui_win* win) { RT_ASSERT(win != RT_NULL); @@ -341,7 +358,7 @@ void rtgui_win_move(struct rtgui_win* win, int x, int y) if (win->flag & RTGUI_WIN_FLAG_CONNECTED) { /* set win hide firstly */ - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win)); + rtgui_widget_hide(RTGUI_WIDGET(win)); emove.wid = win; emove.x = x; @@ -354,7 +371,7 @@ void rtgui_win_move(struct rtgui_win* win, int x, int y) } /* set window visible */ - RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win)); + rtgui_widget_show(RTGUI_WIDGET(win)); return; } @@ -405,7 +422,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object* object, struct rtgui_even break; case RTGUI_EVENT_WIN_CLOSE: - _rtgui_win_deal_close(win, event); + _rtgui_win_deal_close(win, event, RT_FALSE); /* don't broadcast WIN_CLOSE event to others */ return RT_TRUE; @@ -522,20 +539,21 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object* object, struct rtgui_even /* we should dispatch key event firstly */ if (!(win->flag & RTGUI_WIN_FLAG_HANDLE_KEY)) { + struct rtgui_widget *widget; 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); + for (widget = win->focused_widget; + widget && !res; + widget = widget->parent) + { + if (RTGUI_OBJECT(widget)->event_handler != RT_NULL) + res = RTGUI_OBJECT(widget)->event_handler( + RTGUI_OBJECT(widget), event); + } win->flag &= ~RTGUI_WIN_FLAG_HANDLE_KEY; return res; diff --git a/examples/gui/SConscript b/examples/gui/SConscript index 73d0f6731f..35f4c9e810 100644 --- a/examples/gui/SConscript +++ b/examples/gui/SConscript @@ -36,6 +36,7 @@ demo_view_combobox.c demo_view_slider.c demo_view_notebook.c demo_view_mywidget.c +demo_view_box.c mywidget.c """) diff --git a/examples/gui/demo_application.c b/examples/gui/demo_application.c index c46d271a76..b84eaa704f 100644 --- a/examples/gui/demo_application.c +++ b/examples/gui/demo_application.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include @@ -11,7 +11,7 @@ static rt_bool_t demo_handle_key(struct rtgui_object* object, struct rtgui_event { struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; - if (ekbd->type == RTGUI_KEYDOWN) + if (ekbd->type == RTGUI_KEYUP) { if (ekbd->key == RTGUIK_RIGHT) { @@ -30,10 +30,10 @@ static rt_bool_t demo_handle_key(struct rtgui_object* object, struct rtgui_event struct rtgui_win *main_win; static void application_entry(void* parameter) { - struct rtgui_application *app; + struct rtgui_app *app; struct rtgui_rect rect; - app = rtgui_application_create(rt_thread_self(), "gui_demo"); + app = rtgui_app_create(rt_thread_self(), "gui_demo"); if (app == RT_NULL) return; @@ -41,11 +41,10 @@ static void application_entry(void* parameter) rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &rect); main_win = rtgui_win_create(RT_NULL, "demo_win", &rect, - /*RTGUI_WIN_STYLE_DESKTOP_DEFAULT);*/ - RTGUI_WIN_STYLE_NO_BORDER | RTGUI_WIN_STYLE_NO_TITLE); + RTGUI_WIN_STYLE_NO_BORDER | RTGUI_WIN_STYLE_NO_TITLE); if (main_win == RT_NULL) { - rtgui_application_destroy(app); + rtgui_app_destroy(app); return; } @@ -56,12 +55,14 @@ static void application_entry(void* parameter) if (the_notebook == RT_NULL) { rtgui_win_destroy(main_win); - rtgui_application_destroy(app); + rtgui_app_destroy(app); return; } rtgui_container_add_child(RTGUI_CONTAINER(main_win), RTGUI_WIDGET(the_notebook)); + demo_view_box(); + /* 初始化各个例子的视图 */ demo_view_benchmark(); @@ -112,12 +113,12 @@ static void application_entry(void* parameter) rtgui_win_show(main_win, RT_FALSE); /* 执行工作台事件循环 */ - rtgui_application_run(app); + rtgui_app_run(app); - rtgui_application_destroy(app); + rtgui_app_destroy(app); } -void application_init(void) +void application_init() { static rt_bool_t inited = RT_FALSE; @@ -138,7 +139,7 @@ void application_init(void) #ifdef RT_USING_FINSH #include -void application(void) +void application() { application_init(); } diff --git a/examples/gui/demo_listview_icon.c b/examples/gui/demo_listview_icon.c index a5f6e20b4b..9723059ce2 100644 --- a/examples/gui/demo_listview_icon.c +++ b/examples/gui/demo_listview_icon.c @@ -45,11 +45,7 @@ static void listitem_action(rtgui_widget_t* widget, void* parameter) } /* 返回功能的动作函数 */ -#if RT_VERSION == 4 static void return_action(rtgui_widget_t* widget, void* parameter) -#else -static void return_action(void* parameter) -#endif { /* 退出模态显示 */ rtgui_container_end_modal(RTGUI_CONTAINER(_view), RTGUI_MODAL_OK); diff --git a/examples/gui/demo_view.c b/examples/gui/demo_view.c index b1c1d657aa..885e600aeb 100644 --- a/examples/gui/demo_view.c +++ b/examples/gui/demo_view.c @@ -1,10 +1,11 @@ #include -#include +#include #include #include #include #include +#include extern struct rtgui_notebook *the_notebook; @@ -130,7 +131,6 @@ void demo_view_get_logic_rect(rtgui_container_t* container, rtgui_rect_t *rect) /* 当是标准版本时,这个函数用于返回自动布局引擎box控件 */ #ifndef RTGUI_USING_SMALL_SIZE -#include struct rtgui_box* demo_view_create_box(struct rtgui_container *container, int orient) { rtgui_rect_t rect; @@ -142,7 +142,7 @@ struct rtgui_box* demo_view_create_box(struct rtgui_container *container, int or rect.y2 -= 25; /* 创建一个自动布局引擎 */ - box = rtgui_box_create(orient, &rect); + box = rtgui_box_create(orient, 5); /* 添加box控件到视图中 */ rtgui_container_add_child(container, RTGUI_WIDGET(box)); diff --git a/examples/gui/demo_view.h b/examples/gui/demo_view.h index e1c93a53b3..8f138a2750 100644 --- a/examples/gui/demo_view.h +++ b/examples/gui/demo_view.h @@ -15,7 +15,7 @@ #define __DEMO_VIEW_H__ #include -#include +#include #include /* 濡傛灉鏄爣鍑嗙増鏈紝鍙互鍚敤box鑷姩甯冨眬寮曟搸 */ diff --git a/examples/gui/demo_view_benchmark.c b/examples/gui/demo_view_benchmark.c index cd24824c62..956bf9e4a2 100644 --- a/examples/gui/demo_view_benchmark.c +++ b/examples/gui/demo_view_benchmark.c @@ -74,18 +74,21 @@ rt_bool_t benchmark_event_handler(struct rtgui_object *object, rtgui_event_t *ev { struct rtgui_event_kbd *kbd = (struct rtgui_event_kbd*)event; + if (kbd->key == RTGUIK_LEFT || kbd->key == RTGUIK_RIGHT) + return RT_FALSE; + if (RTGUI_KBD_IS_UP(kbd)) { if (running) { /* stop */ - rtgui_application_set_onidle(RT_NULL); + rtgui_app_set_onidle(RT_NULL); _draw_default(object, event); } else { /* run */ - rtgui_application_set_onidle(_onidle); + rtgui_app_set_onidle(_onidle); } running = !running; @@ -101,11 +104,19 @@ rt_bool_t benchmark_event_handler(struct rtgui_object *object, rtgui_event_t *ev return RT_FALSE; } +static rt_bool_t _benchmark_onshow(struct rtgui_object *obj, struct rtgui_event* ev) +{ + rtgui_widget_focus(RTGUI_WIDGET(obj)); + return RT_TRUE; +} + rtgui_container_t *demo_view_benchmark(void) { srand(100); container = demo_view("绘图测试"); + RTGUI_WIDGET(container)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; rtgui_object_set_event_handler(RTGUI_OBJECT(container), benchmark_event_handler); + rtgui_widget_set_onshow(RTGUI_WIDGET(container), _benchmark_onshow); return container; } diff --git a/examples/gui/demo_view_box.c b/examples/gui/demo_view_box.c index 41f1338c44..f567acdb78 100644 --- a/examples/gui/demo_view_box.c +++ b/examples/gui/demo_view_box.c @@ -1,15 +1,44 @@ #include "demo_view.h" -#ifndef RTGUI_USING_SMALL_SIZE #include +#include +#include +#include -rtgui_container_t* demo_view_box(rtgui_workbench_t* workbench) +rtgui_container_t* demo_view_box(void) { rtgui_rect_t rect; rtgui_container_t* view; + struct rtgui_panel *panel; + struct rtgui_box *box; - view = demo_view(workbench, "Box View"); + struct rtgui_label *label; + struct rtgui_button *button; + + view = demo_view("Box View"); demo_view_get_rect(view, &rect); + panel = rtgui_panel_create(RTGUI_BORDER_NONE); + rtgui_widget_set_rect(RTGUI_WIDGET(panel), &rect); + rtgui_container_add_child(RTGUI_CONTAINER(view), RTGUI_WIDGET(panel)); + + box = rtgui_box_create(RTGUI_VERTICAL, 5); + rtgui_container_set_box(RTGUI_CONTAINER(panel), box); + + label = rtgui_label_create("label 1"); + rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(label)); + label = rtgui_label_create("label 2"); + rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(label)); + + button = rtgui_button_create("button 1"); + rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(button)); + + button = rtgui_button_create("button 2"); + rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(button)); + rtgui_widget_set_miniheight(RTGUI_WIDGET(button), 25); + RTGUI_WIDGET_ALIGN(button) = RTGUI_ALIGN_EXPAND; + + rtgui_container_layout(RTGUI_CONTAINER(panel)); + return view; } -#endif + diff --git a/examples/gui/demo_view_image.c b/examples/gui/demo_view_image.c index ba866424da..a846ce377f 100644 --- a/examples/gui/demo_view_image.c +++ b/examples/gui/demo_view_image.c @@ -26,7 +26,7 @@ static void open_btn_onbutton(rtgui_widget_t* widget, struct rtgui_event* event) filelist = rtgui_filelist_view_create("/", "*.*", &rect); #endif /* 模态显示一个文件列表视图,以提供给用户选择图像文件 */ - if (rtgui_container_show(RTGUI_CONTAINER(filelist), RT_TRUE) == RTGUI_MODAL_OK) + if (rtgui_widget_show(RTGUI_WIDGET(filelist), RT_TRUE) == RTGUI_MODAL_OK) { char path[32], image_type[8]; diff --git a/examples/gui/demo_view_listbox.c b/examples/gui/demo_view_listbox.c index 9236d58425..7ff049a32c 100644 --- a/examples/gui/demo_view_listbox.c +++ b/examples/gui/demo_view_listbox.c @@ -141,14 +141,16 @@ static struct rtgui_listbox_item items[] = {"list #3", RT_NULL}, }; -static void on_items(rtgui_widget_t* widget, struct rtgui_event* event) +static rt_bool_t on_items(struct rtgui_object* object, struct rtgui_event* event) { rtgui_listbox_t* box; /* get listbox */ - box = RTGUI_LISTBOX(widget); + box = RTGUI_LISTBOX(object); /* 鎵撳嵃褰撳墠鐨勯」 */ rt_kprintf("current item: %d\n", box->current_item); + + return RT_TRUE; } /* 鍒涘缓鐢ㄤ簬婕旂ずlabel鎺т欢鐨勮鍥 */ diff --git a/examples/gui/demo_view_listctrl.c b/examples/gui/demo_view_listctrl.c index fb7128fd22..2efe78b369 100644 --- a/examples/gui/demo_view_listctrl.c +++ b/examples/gui/demo_view_listctrl.c @@ -204,14 +204,16 @@ void _rtgui_listctrl_item_draw(struct rtgui_listctrl *list, } } -static void on_items(rtgui_widget_t* widget, struct rtgui_event* event) +static rt_bool_t on_items(struct rtgui_object* object, struct rtgui_event* event) { rtgui_listctrl_t* ctrl; /* get listctrl */ - ctrl = RTGUI_LISTCTRL(widget); + ctrl = RTGUI_LISTCTRL(object); /* 打印当前的项 */ rt_kprintf("current item: %d\n", ctrl->current_item); + + return RT_TRUE; } /* 创建用于演示label控件的视图 */ diff --git a/examples/gui/demo_view_menu.c b/examples/gui/demo_view_menu.c index da323f67a3..5e42d84c8c 100644 --- a/examples/gui/demo_view_menu.c +++ b/examples/gui/demo_view_menu.c @@ -7,7 +7,7 @@ #include #include -static rt_bool_t _onmenuitem(struct rtgui_widget *widget, struct rtgui_event* event) +static rt_bool_t _onmenuitem(struct rtgui_object *object, struct rtgui_event* event) { rt_kprintf("menu action!!\n"); return RT_TRUE; @@ -31,15 +31,17 @@ static const rtgui_menu_item_t items[] = }; static rtgui_menu_t* menu; -static _onmenu(struct rtgui_widget* widget, struct rtgui_event* event) +static rt_bool_t _onmenu(struct rtgui_object* object, struct rtgui_event* event) { rtgui_rect_t rect; - rtgui_widget_get_rect(widget, &rect); - rtgui_widget_rect_to_device(widget, &rect); + rtgui_widget_get_rect(RTGUI_WIDGET(object), &rect); + rtgui_widget_rect_to_device(RTGUI_WIDGET(object), &rect); if (menu != RT_NULL) rtgui_menu_pop(menu, rect.x1, rect.y2 + 5); + + return RT_TRUE; } /* 鍒涘缓鐢ㄤ簬婕旂ずmenu鎺т欢鐨勮鍥 */ diff --git a/examples/gui/demo_view_window.c b/examples/gui/demo_view_window.c index d6d278681c..46616ab52e 100644 --- a/examples/gui/demo_view_window.c +++ b/examples/gui/demo_view_window.c @@ -57,14 +57,16 @@ static void create_normal_win(void) } /* 触发正常窗口显示 */ -static void demo_normal_window_onbutton(struct rtgui_widget* widget, rtgui_event_t* event) +static void demo_normal_window_onbutton(struct rtgui_object* object, rtgui_event_t* event) { rt_sprintf(normal_window_label_text, "第 %d 次显示", normal_window_show_count); rtgui_label_set_text(normal_window_label, normal_window_label_text); - /* 非模态显示窗口 */ - rtgui_win_show(normal_window, RT_FALSE); + if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(normal_window))) + rtgui_win_show(normal_window, RT_FALSE); + else + rtgui_win_activate(normal_window); } /* 获取一个递增的窗口标题 */ @@ -91,10 +93,6 @@ void diag_close(struct rtgui_timer* timer, void* parameter) { /* 超时,关闭对话框 */ rtgui_win_destroy(msgbox); - - /* 停止并删除定时器 */ - rtgui_timer_stop(timer); - rtgui_timer_destory(timer); } } @@ -117,7 +115,7 @@ static rt_uint16_t delta_x = 20; static rt_uint16_t delta_y = 40; /* 触发自动窗口显示 */ -static void demo_autowin_onbutton(struct rtgui_widget* widget, rtgui_event_t* event) +static void demo_autowin_onbutton(struct rtgui_object* object, rtgui_event_t* event) { struct rtgui_rect rect ={50, 50, 200, 200}; @@ -147,7 +145,7 @@ static void demo_autowin_onbutton(struct rtgui_widget* widget, rtgui_event_t* ev } /* 触发模态窗口显示 */ -static void demo_modalwin_onbutton(struct rtgui_widget* widget, rtgui_event_t* event) +static void demo_modalwin_onbutton(struct rtgui_object* object, rtgui_event_t* event) { rtgui_win_t *win; rtgui_label_t *label; @@ -177,19 +175,19 @@ static void demo_modalwin_onbutton(struct rtgui_widget* widget, rtgui_event_t* e rtgui_win_destroy(win); } -static void demo_close_ntitle_window(struct rtgui_widget* widget, rtgui_event_t* event) +static void demo_close_ntitle_window(struct rtgui_object* object, rtgui_event_t* event) { rtgui_win_t* win; /* 获得最顶层控件 */ - win = RTGUI_WIN(rtgui_widget_get_toplevel(widget)); + win = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object))); /* 销毁窗口 */ rtgui_win_destroy(win); } /* 触发无标题窗口显示 */ -static void demo_ntitlewin_onbutton(struct rtgui_widget* widget, rtgui_event_t* event) +static void demo_ntitlewin_onbutton(struct rtgui_object* object, rtgui_event_t* event) { rtgui_win_t *win; rtgui_label_t *label; diff --git a/examples/gui/mywidget.c b/examples/gui/mywidget.c index 24ff207627..1fc94d66fe 100644 --- a/examples/gui/mywidget.c +++ b/examples/gui/mywidget.c @@ -71,10 +71,10 @@ static void rtgui_mywidget_onmouse(struct rtgui_mywidget* me, struct rtgui_event } /* mywidget鎺т欢鐨勪簨浠跺鐞嗗嚱鏁?*/ -rt_bool_t rtgui_mywidget_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) +rt_bool_t rtgui_mywidget_event_handler(struct rtgui_object* object, struct rtgui_event* event) { /* 璋冪敤浜嬩欢澶勭悊鍑芥暟鏃讹紝widget鎸囬拡鎸囧悜鎺т欢鏈韩锛屾墍浠ュ厛鑾峰緱鐩稿簲鎺т欢瀵硅薄鐨勬寚閽?*/ - struct rtgui_mywidget* me = RTGUI_MYWIDGET(widget); + struct rtgui_mywidget* me = RTGUI_MYWIDGET(object); switch (event->type) { @@ -90,7 +90,7 @@ rt_bool_t rtgui_mywidget_event_handler(struct rtgui_widget* widget, struct rtgui /* 鍏朵粬浜嬩欢璋冪敤鐖剁被鐨勪簨浠跺鐞嗗嚱鏁?*/ default: - return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event); + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/examples/gui/mywidget.h b/examples/gui/mywidget.h index 65a68a01bd..ac8d25ffe1 100644 --- a/examples/gui/mywidget.h +++ b/examples/gui/mywidget.h @@ -45,6 +45,6 @@ void rtgui_mywidget_destroy(struct rtgui_mywidget* me); * 瀵逛竴涓帶浠惰岃█锛屽鏋滄淳鐢熻嚜瀹冪殑瀛愭帶浠跺緢鍙兘浼氳皟鐢ㄧ埗鎺т欢鐨勪簨浠跺鐞嗗嚱鏁帮紝 * 鎵浠ヨ繖閲岄噰鐢ㄥ叕寮澹版槑鐨勬柟寮忋? */ -rt_bool_t rtgui_mywidget_event_handler(struct rtgui_widget* widget, struct rtgui_event* event); +rt_bool_t rtgui_mywidget_event_handler(struct rtgui_object* object, struct rtgui_event* event); #endif