From e6a9dd1922246a26e159d48afb840007d8c986d9 Mon Sep 17 00:00:00 2001 From: "dzzxzz@gmail.com" Date: Mon, 13 Aug 2012 06:30:05 +0000 Subject: [PATCH] sync with github f5619cb8ad5e4f581e3b2f6a44be4ddd5b432e59 As always, full log is in GitHub. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2253 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/rtgui/SConscript | 2 + components/rtgui/common/dc.c | 33 +- components/rtgui/common/dc_client.c | 12 +- components/rtgui/common/dc_hw.c | 5 + components/rtgui/common/font_bmp.c | 34 +- components/rtgui/common/font_freetype.c | 4 +- components/rtgui/common/font_hz_file.c | 216 +-- components/rtgui/common/image_bmp.c | 10 +- components/rtgui/common/image_container.c | 54 +- components/rtgui/common/region.c | 7 + components/rtgui/common/rtgui_app.c | 32 +- components/rtgui/common/rtgui_system.c | 39 +- components/rtgui/common/rtgui_theme.c | 121 +- components/rtgui/include/rtgui/color.h | 4 +- components/rtgui/include/rtgui/dc.h | 2 + components/rtgui/include/rtgui/event.h | 4 +- components/rtgui/include/rtgui/region.h | 1 + components/rtgui/include/rtgui/rtgui.h | 17 +- components/rtgui/include/rtgui/rtgui_app.h | 25 +- components/rtgui/include/rtgui/rtgui_config.h | 10 +- components/rtgui/include/rtgui/rtgui_object.h | 13 + components/rtgui/include/rtgui/rtgui_system.h | 7 +- components/rtgui/include/rtgui/widgets/box.h | 2 +- components/rtgui/include/rtgui/widgets/edit.h | 129 ++ .../rtgui/include/rtgui/widgets/groupbox.h | 73 + .../rtgui/include/rtgui/widgets/iconbox.h | 1 + .../rtgui/include/rtgui/widgets/listctrl.h | 2 + .../rtgui/include/rtgui/widgets/notebook.h | 22 + .../rtgui/include/rtgui/widgets/panel.h | 8 +- .../rtgui/include/rtgui/widgets/widget.h | 44 +- .../rtgui/include/rtgui/widgets/window.h | 20 +- components/rtgui/server/mouse.c | 25 +- components/rtgui/server/mouse.h | 1 + components/rtgui/server/topwin.c | 10 +- components/rtgui/widgets/box.c | 58 +- components/rtgui/widgets/button.c | 6 +- components/rtgui/widgets/checkbox.c | 2 +- components/rtgui/widgets/combobox.c | 8 +- components/rtgui/widgets/container.c | 2 +- components/rtgui/widgets/edit.c | 1666 +++++++++++++++++ components/rtgui/widgets/filelist_view.c | 18 +- components/rtgui/widgets/groupbox.c | 155 ++ components/rtgui/widgets/iconbox.c | 49 +- components/rtgui/widgets/label.c | 5 +- components/rtgui/widgets/list_view.c | 12 +- components/rtgui/widgets/listbox.c | 8 +- components/rtgui/widgets/listctrl.c | 48 +- components/rtgui/widgets/menu.c | 12 +- components/rtgui/widgets/notebook.c | 266 ++- components/rtgui/widgets/progressbar.c | 4 +- components/rtgui/widgets/radiobox.c | 14 +- components/rtgui/widgets/scrollbar.c | 8 +- components/rtgui/widgets/slider.c | 2 +- components/rtgui/widgets/textbox.c | 30 +- components/rtgui/widgets/textview.c | 10 +- components/rtgui/widgets/title.c | 7 +- components/rtgui/widgets/toplevel.c | 2 +- components/rtgui/widgets/widget.c | 49 +- components/rtgui/widgets/window.c | 19 +- 59 files changed, 3008 insertions(+), 441 deletions(-) create mode 100644 components/rtgui/include/rtgui/widgets/edit.h create mode 100644 components/rtgui/include/rtgui/widgets/groupbox.h create mode 100644 components/rtgui/widgets/edit.c create mode 100644 components/rtgui/widgets/groupbox.c diff --git a/components/rtgui/SConscript b/components/rtgui/SConscript index 3aae1f0ad..eae39ce7d 100644 --- a/components/rtgui/SConscript +++ b/components/rtgui/SConscript @@ -67,6 +67,8 @@ widgets/filelist_view.c widgets/widget.c widgets/window.c widgets/panel.c +widgets/groupbox.c +widgets/edit.c """) # The set of source files associated with this SConscript file. diff --git a/components/rtgui/common/dc.c b/components/rtgui/common/dc.c index 97e6fcaf5..1de54318a 100644 --- a/components/rtgui/common/dc.c +++ b/components/rtgui/common/dc.c @@ -290,6 +290,31 @@ void rtgui_dc_draw_text (struct rtgui_dc* dc, const char* text, struct rtgui_rec rtgui_font_draw(font, dc, text, len, &text_rect); } +void rtgui_dc_draw_text_stroke (struct rtgui_dc* dc, const char* text, struct rtgui_rect* rect, + rtgui_color_t color_stroke, rtgui_color_t color_core) +{ + int x, y; + rtgui_rect_t r; + rtgui_color_t fc; + + RT_ASSERT(dc != RT_NULL); + + fc = RTGUI_DC_FC(dc); + RTGUI_DC_FC(dc) = color_stroke; + for(x=-1; x<2; x++) + { + for(y=-1; y<2; y++) + { + r = *rect; + rtgui_rect_moveto(&r, x, y); + rtgui_dc_draw_text(dc, text, &r); + } + } + RTGUI_DC_FC(dc) = color_core; + rtgui_dc_draw_text(dc, text, rect); + RTGUI_DC_FC(dc) = fc; +} + /* * draw a monochrome color bitmap data */ @@ -424,8 +449,8 @@ void rtgui_dc_draw_regular_polygon(struct rtgui_dc* dc, int x, int y, int r, int * Pointer setup */ - x_head = xx = (int *)rt_malloc(sizeof(int) * count); - y_head = yy = (int *)rt_malloc(sizeof(int) * count); + x_head = xx = (int *)rtgui_malloc(sizeof(int) * count); + y_head = yy = (int *)rtgui_malloc(sizeof(int) * count); for(i = 0; i < count; i++) { @@ -445,8 +470,8 @@ void rtgui_dc_draw_regular_polygon(struct rtgui_dc* dc, int x, int y, int r, int rtgui_dc_draw_polygon(dc, (const int *)x_head, (const int *)y_head, count); - rt_free(x_head); - rt_free(y_head); + rtgui_free(x_head); + rtgui_free(y_head); } diff --git a/components/rtgui/common/dc_client.c b/components/rtgui/common/dc_client.c index 154eb359b..abff12b3a 100644 --- a/components/rtgui/common/dc_client.c +++ b/components/rtgui/common/dc_client.c @@ -47,18 +47,26 @@ static void rtgui_dc_client_get_rect(struct rtgui_dc* dc, rtgui_rect_t* rect); struct rtgui_dc* rtgui_dc_begin_drawing(rtgui_widget_t* owner) { + struct rtgui_dc* dc; RT_ASSERT(owner != RT_NULL); + rtgui_screen_lock(RT_WAITING_FOREVER); + if ((rtgui_region_is_flat(&owner->clip) == RT_EOK) && rtgui_rect_is_equal(&(owner->extent), &(owner->clip.extents)) == RT_EOK) - return rtgui_dc_hw_create(owner); + dc = rtgui_dc_hw_create(owner); else - return rtgui_dc_client_create(owner); + dc = rtgui_dc_client_create(owner); + + if (dc == RT_NULL) rtgui_screen_unlock(); + + return dc; } void rtgui_dc_end_drawing(struct rtgui_dc* dc) { dc->engine->fini(dc); + rtgui_screen_unlock(); } const struct rtgui_dc_engine dc_client_engine = diff --git a/components/rtgui/common/dc_hw.c b/components/rtgui/common/dc_hw.c index db226fd15..e0867cfb7 100644 --- a/components/rtgui/common/dc_hw.c +++ b/components/rtgui/common/dc_hw.c @@ -22,6 +22,8 @@ #include #include +#define _int_swap(x, y) do {x ^= y; y ^= x; x ^= y;} while (0) + static void rtgui_dc_hw_draw_point(struct rtgui_dc* dc, int x, int y); static void rtgui_dc_hw_draw_color_point(struct rtgui_dc* dc, int x, int y, rtgui_color_t color); static void rtgui_dc_hw_draw_hline(struct rtgui_dc* dc, int x1, int x2, int y); @@ -267,6 +269,7 @@ static void rtgui_dc_hw_draw_vline(struct rtgui_dc* self, int x, int y1, int y2) x = x + dc->owner->extent.x1; y1 = y1 + dc->owner->extent.y1; y2 = y2 + dc->owner->extent.y1; + if (y1 > y2) _int_swap(y1, y2); /* draw vline */ dc->hw_driver->ops->draw_vline(&(dc->owner->gc.foreground), x, y1, y2); @@ -285,6 +288,7 @@ static void rtgui_dc_hw_draw_hline(struct rtgui_dc* self, int x1, int x2, int y) /* convert logic to device */ x1 = x1 + dc->owner->extent.x1; x2 = x2 + dc->owner->extent.x1; + if (x1 > x2) _int_swap(x1, x2); y = y + dc->owner->extent.y1; /* draw hline */ @@ -323,6 +327,7 @@ static void rtgui_dc_hw_blit_line (struct rtgui_dc* self, int x1, int x2, int y, /* convert logic to device */ x1 = x1 + dc->owner->extent.x1; x2 = x2 + dc->owner->extent.x1; + if (x1 > x2) _int_swap(x1, x2); y = y + dc->owner->extent.y1; dc->hw_driver->ops->draw_raw_hline(line_data, x1, x2, y); diff --git a/components/rtgui/common/font_bmp.c b/components/rtgui/common/font_bmp.c index e897cedb6..6b690fc83 100644 --- a/components/rtgui/common/font_bmp.c +++ b/components/rtgui/common/font_bmp.c @@ -31,8 +31,8 @@ void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap* font, struct rtgui_dc { rtgui_color_t bc; const rt_uint8_t* font_ptr; - rt_uint16_t x, y, h, style; - register rt_base_t i, j, k, word_bytes; + rt_uint16_t x, y, w, h, style; + register rt_base_t i, j, /*k,*/ word_bytes; /* check first and last char */ if (ch < font->first_char || ch > font->last_char) return; @@ -54,25 +54,21 @@ void rtgui_bitmap_font_draw_char(struct rtgui_font_bitmap* font, struct rtgui_dc word_bytes = ((font->char_width[ch - font->first_char] - 1)/8) + 1; font_ptr = font->bmp + font->offset[ch - font->first_char]; } - + w = (font->width + x > rect->x2) ? rect->x2 - rect->x1 : font->width; h = (font->height + y > rect->y2) ? rect->y2 - rect->y1 : font->height; - for (i = 0; i < h; i++) + for(i = 0; i < h; i++) { - for (j = 0; j < word_bytes; j++) + rt_uint8_t chr; + const rt_uint8_t *ptr = font_ptr + i * word_bytes; + for(j = 0; j < w; j++) { - for (k = 0; k < 8; k++) - { - if (((font_ptr[i * word_bytes + j] >> (7 - k)) & 0x01) != 0) - { - /* draw a pixel */ - rtgui_dc_draw_point(dc, k + 8 * j + x, i + y); - } - else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND) - { - rtgui_dc_draw_color_point(dc, k + 8 * j + x, i + y, bc); - } - } + if(j % 8 == 0)chr = *ptr++; + if(chr & 0x80) + rtgui_dc_draw_point(dc, j + x, i + y); + else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND) + rtgui_dc_draw_color_point(dc, j + x, i + y, bc); + chr <<= 1; } } } @@ -87,6 +83,8 @@ static void rtgui_bitmap_font_draw_text(struct rtgui_font* font, struct rtgui_dc RT_ASSERT(bmp_font != RT_NULL); + if (rect->y1 > rect->y2) return; + hz_font = rtgui_font_refer("hz", font->height); while ((rect->x1 < rect->x2) && len) { @@ -121,6 +119,8 @@ static void rtgui_bitmap_font_draw_text(struct rtgui_font* font, struct rtgui_dc if (hz_font != RT_NULL) rtgui_font_derefer(hz_font); #else + if (rect->y1 > rect->y2) return; + while ((rect->x1 < rect->x2) && len) { length = 0; diff --git a/components/rtgui/common/font_freetype.c b/components/rtgui/common/font_freetype.c index 11d778827..5306d6a15 100644 --- a/components/rtgui/common/font_freetype.c +++ b/components/rtgui/common/font_freetype.c @@ -163,7 +163,7 @@ rtgui_font_t* rtgui_freetype_font_create(const char* filename, int bold, int ita freetype = (struct rtgui_freetype_font*) rtgui_malloc (sizeof(struct rtgui_freetype_font)); if (freetype == RT_NULL) { - rt_free(font); + rtgui_free(font); font = RT_NULL; } else @@ -173,7 +173,7 @@ rtgui_font_t* rtgui_freetype_font_create(const char* filename, int bold, int ita { FT_Done_FreeType(freetype->library); - rt_free(font); + rtgui_free(font); font = RT_NULL; } else diff --git a/components/rtgui/common/font_hz_file.c b/components/rtgui/common/font_hz_file.c index 615086403..f5945442a 100644 --- a/components/rtgui/common/font_hz_file.c +++ b/components/rtgui/common/font_hz_file.c @@ -18,10 +18,10 @@ static void rtgui_hz_file_font_draw_text(struct rtgui_font* font, struct rtgui_d static void rtgui_hz_file_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect); const struct rtgui_font_engine rtgui_hz_file_font_engine = { - RT_NULL, - rtgui_hz_file_font_load, - rtgui_hz_file_font_draw_text, - rtgui_hz_file_font_get_metrics + RT_NULL, + rtgui_hz_file_font_load, + rtgui_hz_file_font_draw_text, + rtgui_hz_file_font_get_metrics }; SPLAY_PROTOTYPE(cache_tree, hz_cache, hz_node, _font_cache_compare); @@ -42,26 +42,26 @@ static rt_uint8_t* _font_cache_get(struct rtgui_hz_file_font* font, rt_uint16_t search.hz_id = hz_id; - /* enter critical */ - rtgui_enter_critical(); + /* enter critical */ + rtgui_enter_critical(); - cache = SPLAY_FIND(cache_tree, &(font->cache_root), &search); + cache = SPLAY_FIND(cache_tree, &(font->cache_root), &search); if (cache != RT_NULL) { - /* exit critical */ - rtgui_exit_critical(); + /* exit critical */ + rtgui_exit_critical(); /* found it */ return (rt_uint8_t*)(cache + 1); } - /* exit critical */ - rtgui_exit_critical(); + /* exit critical */ + rtgui_exit_critical(); - /* can not find it, load to cache */ + /* can not find it, load to cache */ cache = (struct hz_cache*) rtgui_malloc(sizeof(struct hz_cache) + font->font_data_size); if (cache == RT_NULL) - return RT_NULL; /* no memory yet */ + return RT_NULL; /* no memory yet */ cache->hz_id = hz_id; seek = 94 * (((hz_id & 0xff) - 0xA0) - 1) + ((hz_id >> 8) - 0xA0) - 1; @@ -76,14 +76,10 @@ static rt_uint8_t* _font_cache_get(struct rtgui_hz_file_font* font, rt_uint16_t return RT_NULL; } - /* enter critical */ - rtgui_enter_critical(); + /* enter critical */ + rtgui_enter_critical(); - /* insert to cache */ - SPLAY_INSERT(cache_tree, &(font->cache_root), cache); - font->cache_size ++; - - if (font->cache_size > HZ_CACHE_MAX) + if (font->cache_size >= HZ_CACHE_MAX) { /* remove a cache */ struct hz_cache* left; @@ -92,12 +88,16 @@ static rt_uint8_t* _font_cache_get(struct rtgui_hz_file_font* font, rt_uint16_t /* remove the left node */ SPLAY_REMOVE(cache_tree, &(font->cache_root), left); - rtgui_free(left); - font->cache_size --; + rtgui_free(left); + font->cache_size --; } - /* exit critical */ - rtgui_exit_critical(); + /* insert to cache */ + SPLAY_INSERT(cache_tree, &(font->cache_root), cache); + font->cache_size ++; + + /* exit critical */ + rtgui_exit_critical(); return (rt_uint8_t*)(cache + 1); } @@ -112,93 +112,93 @@ static void rtgui_hz_file_font_load(struct rtgui_font* font) static void _rtgui_hz_file_font_draw_text(struct rtgui_hz_file_font* hz_file_font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect) { - rt_uint8_t* str; - rtgui_color_t bc; - rt_uint16_t style; - register rt_base_t h, word_bytes; + rt_uint8_t* str; + rtgui_color_t bc; + rt_uint16_t style; + register rt_base_t h, word_bytes; - /* get text style */ - style = rtgui_dc_get_gc(dc)->textstyle; - bc = rtgui_dc_get_gc(dc)->background; + /* get text style */ + style = rtgui_dc_get_gc(dc)->textstyle; + bc = rtgui_dc_get_gc(dc)->background; - /* drawing height */ - h = (hz_file_font->font_size + rect->y1 > rect->y2)? + /* drawing height */ + h = (hz_file_font->font_size + rect->y1 > rect->y2)? rect->y2 - rect->y1 : hz_file_font->font_size; - word_bytes = (hz_file_font->font_size + 7) / 8; - - str = (rt_uint8_t*)text; - - while (len > 0 && rect->x1 < rect->x2) - { - const rt_uint8_t* font_ptr; - register rt_base_t i, j, k; - - /* get font pixel data */ - font_ptr = _font_cache_get(hz_file_font, *str | (*(str+1) << 8)); - - /* draw word */ - for (i=0; i < h; i ++) - { - for (j=0; j < word_bytes; j++) - for (k=0; k < 8; k++) - { - if ( ((font_ptr[i*word_bytes + j] >> (7-k)) & 0x01) != 0 && - (rect->x1 + 8 * j + k < rect->x2)) - { - rtgui_dc_draw_point(dc, rect->x1 + 8*j + k, rect->y1 + i); - } - else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND) - { - rtgui_dc_draw_color_point(dc, rect->x1 + 8*j + k, rect->y1 + i, bc); - } - } - } - - /* move x to next character */ - rect->x1 += hz_file_font->font_size; - str += 2; - len -= 2; - } + word_bytes = (hz_file_font->font_size + 7) / 8; + + str = (rt_uint8_t*)text; + + while (len > 0 && rect->x1 < rect->x2) + { + const rt_uint8_t* font_ptr; + register rt_base_t i, j, k; + + /* get font pixel data */ + font_ptr = _font_cache_get(hz_file_font, *str | (*(str+1) << 8)); + + /* draw word */ + for (i=0; i < h; i ++) + { + for (j=0; j < word_bytes; j++) + for (k=0; k < 8; k++) + { + if ( ((font_ptr[i*word_bytes + j] >> (7-k)) & 0x01) != 0 && + (rect->x1 + 8 * j + k < rect->x2)) + { + rtgui_dc_draw_point(dc, rect->x1 + 8*j + k, rect->y1 + i); + } + else if (style & RTGUI_TEXTSTYLE_DRAW_BACKGROUND) + { + rtgui_dc_draw_color_point(dc, rect->x1 + 8*j + k, rect->y1 + i, bc); + } + } + } + + /* move x to next character */ + rect->x1 += hz_file_font->font_size; + str += 2; + len -= 2; + } } static void rtgui_hz_file_font_draw_text(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t length, struct rtgui_rect* rect) { - rt_uint32_t len; - struct rtgui_font *efont; - struct rtgui_hz_file_font* hz_file_font = (struct rtgui_hz_file_font*)font->data; - - RT_ASSERT(dc != RT_NULL); - RT_ASSERT(hz_file_font != RT_NULL); - - /* get English font */ - efont = rtgui_font_refer("asc", hz_file_font->font_size); - if (efont == RT_NULL) efont = rtgui_font_default(); /* use system default font */ - - while (length > 0) - { - len = 0; - while (((rt_uint8_t)*(text + len)) < 0x80 && *(text + len) && len < length) len ++; - /* draw text with English font */ - if (len > 0) - { - rtgui_font_draw(efont, dc, text, len, rect); - - text += len; - length -= len; - } - - len = 0; - while (((rt_uint8_t)*(text + len)) >= 0x80 && len < length) len ++; - if (len > 0) - { - _rtgui_hz_file_font_draw_text(hz_file_font, dc, text, len, rect); - - text += len; - length -= len; - } - } - - rtgui_font_derefer(efont); + rt_uint32_t len; + struct rtgui_font *efont; + struct rtgui_hz_file_font* hz_file_font = (struct rtgui_hz_file_font*)font->data; + + RT_ASSERT(dc != RT_NULL); + RT_ASSERT(hz_file_font != RT_NULL); + + /* get English font */ + efont = rtgui_font_refer("asc", hz_file_font->font_size); + if (efont == RT_NULL) efont = rtgui_font_default(); /* use system default font */ + + while (length > 0) + { + len = 0; + while (((rt_uint8_t)*(text + len)) < 0x80 && *(text + len) && len < length) len ++; + /* draw text with English font */ + if (len > 0) + { + rtgui_font_draw(efont, dc, text, len, rect); + + text += len; + length -= len; + } + + len = 0; + while (((rt_uint8_t)*(text + len)) >= 0x80 && len < length) len ++; + if (len > 0) + { + _rtgui_hz_file_font_draw_text(hz_file_font, dc, text, len, rect); + + text += len; + length -= len; + } + } + + rtgui_font_derefer(efont); } static void rtgui_hz_file_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect) @@ -206,9 +206,9 @@ static void rtgui_hz_file_font_get_metrics(struct rtgui_font* font, const char* struct rtgui_hz_file_font* hz_file_font = (struct rtgui_hz_file_font*)font->data; RT_ASSERT(hz_file_font != RT_NULL); - /* set metrics rect */ - rect->x1 = rect->y1 = 0; - rect->x2 = (rt_int16_t)(hz_file_font->font_size/2 * rt_strlen((const char*)text)); - rect->y2 = hz_file_font->font_size; + /* set metrics rect */ + rect->x1 = rect->y1 = 0; + rect->x2 = (rt_int16_t)(hz_file_font->font_size/2 * rt_strlen((const char*)text)); + rect->y2 = hz_file_font->font_size; } #endif diff --git a/components/rtgui/common/image_bmp.c b/components/rtgui/common/image_bmp.c index a5ef3e9e8..71f7adbec 100644 --- a/components/rtgui/common/image_bmp.c +++ b/components/rtgui/common/image_bmp.c @@ -172,7 +172,7 @@ static rt_bool_t rtgui_image_bmp_load(struct rtgui_image *image, struct rtgui_fi do { - wrkBuffer = (rt_uint8_t *)rt_malloc(BMP_WORKING_BUFFER_SIZE); + wrkBuffer = (rt_uint8_t *)rtgui_malloc(BMP_WORKING_BUFFER_SIZE); if (wrkBuffer == RT_NULL) { rt_kprintf("BMP err: no mem\n"); @@ -470,13 +470,13 @@ static rt_bool_t rtgui_image_bmp_load(struct rtgui_image *image, struct rtgui_fi } /* Release memory */ - rt_free(wrkBuffer); + rtgui_free(wrkBuffer); return RT_TRUE; } while (0); /* Release memory */ - rt_free(wrkBuffer); + rtgui_free(wrkBuffer); rtgui_free(image->palette); rtgui_free(bmp->pixels); rtgui_free(bmp); @@ -602,7 +602,7 @@ static void rtgui_image_bmp_blit(struct rtgui_image *image, struct rtgui_dc *dc, } } - wrkBuffer = (rt_uint8_t *)rt_malloc( + wrkBuffer = (rt_uint8_t *)rtgui_malloc( (BMP_WORKING_BUFFER_SIZE > bmp->pitch) ? \ bmp->pitch : BMP_WORKING_BUFFER_SIZE); if (wrkBuffer == RT_NULL) @@ -770,7 +770,7 @@ static void rtgui_image_bmp_blit(struct rtgui_image *image, struct rtgui_dc *dc, break; } /* Release memory */ - rt_free(wrkBuffer); + rtgui_free(wrkBuffer); // rt_kprintf("BMP: load to display\n"); } else diff --git a/components/rtgui/common/image_container.c b/components/rtgui/common/image_container.c index 1088c9bba..6a31b9420 100644 --- a/components/rtgui/common/image_container.c +++ b/components/rtgui/common/image_container.c @@ -12,16 +12,16 @@ typedef void (*rtgui_user_func_t) (const void* value, const void* data); rtgui_hash_table_t* hash_table_create(rtgui_hash_func_t hash_func, rtgui_equal_func_t key_equal_func); void hash_table_destroy (rtgui_hash_table_t* hash_table); -void* hash_table_find (rtgui_hash_table_t* hash_table, void* key); -void hash_table_insert (rtgui_hash_table_t* hash_table, void* key, void* value); -rt_bool_t hash_table_remove (rtgui_hash_table_t* hash_table, void* key); +void* hash_table_find (rtgui_hash_table_t* hash_table, const void* key); +void hash_table_insert (rtgui_hash_table_t* hash_table, const void* key, void* value); +rt_bool_t hash_table_remove (rtgui_hash_table_t* hash_table, const void* key); void hash_table_foreach(rtgui_hash_table_t* hash_table, rtgui_user_func_t user_func, void* data); unsigned int hash_table_get_size (rtgui_hash_table_t* hash_table); /* Hash Functions */ -unsigned int direct_hash (void* v); +unsigned int direct_hash (const void* v); #define HASH_TABLE_MIN_SIZE 11 #define HASH_TABLE_MAX_SIZE 6247 @@ -87,8 +87,8 @@ static const unsigned int primes[] = static const unsigned int nprimes = sizeof (primes) / sizeof (primes[0]); static void hash_table_resize (rtgui_hash_table_t *hash_table); -static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, void* key); -static rtgui_hash_node_t* hash_node_create (void* key, void* value); +static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, const void* key); +static rtgui_hash_node_t* hash_node_create (const void* key, void* value); static void hash_node_destroy (rtgui_hash_node_t *hash_node); static void hash_nodes_destroy (rtgui_hash_node_t *hash_node); static unsigned int primes_closest (unsigned int num); @@ -106,7 +106,7 @@ rt_inline unsigned int primes_closest (unsigned int num) } /* directly hash */ -unsigned int direct_hash (void* v) +unsigned int direct_hash (const void* v) { return (unsigned int)v; } @@ -115,18 +115,18 @@ rtgui_hash_table_t* hash_table_create(rtgui_hash_func_t hash_func, rtgui_equal_f { rtgui_hash_table_t *hash_table; - hash_table = (rtgui_hash_table_t*) rt_malloc (sizeof(rtgui_hash_table_t)); + hash_table = (rtgui_hash_table_t*) rtgui_malloc (sizeof(rtgui_hash_table_t)); if (hash_table != RT_NULL) { hash_table->size = HASH_TABLE_MIN_SIZE; hash_table->nnodes = 0; hash_table->hash_func = hash_func ? hash_func : direct_hash; hash_table->key_equal_func = key_equal_func; - hash_table->nodes = (rtgui_hash_node_t **)rt_malloc ( sizeof(rtgui_hash_node_t*) * hash_table->size); + hash_table->nodes = (rtgui_hash_node_t **)rtgui_malloc ( sizeof(rtgui_hash_node_t*) * hash_table->size); if (hash_table->nodes == RT_NULL) { /* no memory yet */ - rt_free(hash_table); + rtgui_free(hash_table); return RT_NULL; } @@ -145,11 +145,11 @@ void hash_table_destroy (rtgui_hash_table_t *hash_table) for (i = 0; i < hash_table->size; i++) hash_nodes_destroy (hash_table->nodes[i]); - rt_free (hash_table->nodes); - rt_free (hash_table); + rtgui_free (hash_table->nodes); + rtgui_free (hash_table); } -static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, void* key) +static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, const void* key) { rtgui_hash_node_t **node; @@ -165,7 +165,7 @@ static rtgui_hash_node_t** hash_table_find_node (rtgui_hash_table_t *hash_table, return node; } -void* hash_table_find (rtgui_hash_table_t* hash_table, void* key) +void* hash_table_find (rtgui_hash_table_t* hash_table, const void* key) { rtgui_hash_node_t *node; @@ -178,7 +178,7 @@ void* hash_table_find (rtgui_hash_table_t* hash_table, void* key) else return RT_NULL; } -void hash_table_insert (rtgui_hash_table_t *hash_table, void* key, void* value) +void hash_table_insert (rtgui_hash_table_t *hash_table, const void* key, void* value) { rtgui_hash_node_t **node; @@ -197,7 +197,7 @@ void hash_table_insert (rtgui_hash_table_t *hash_table, void* key, void* value) } } -rt_bool_t hash_table_remove (rtgui_hash_table_t *hash_table, void* key) +rt_bool_t hash_table_remove (rtgui_hash_table_t *hash_table, const void* key) { rtgui_hash_node_t **node, *dest; @@ -258,7 +258,7 @@ static void hash_table_resize (rtgui_hash_table_t *hash_table) i = primes_closest(hash_table->nnodes); new_size = i > HASH_TABLE_MAX_SIZE ? HASH_TABLE_MAX_SIZE : i < HASH_TABLE_MIN_SIZE ? HASH_TABLE_MIN_SIZE : i ; - new_nodes = (rtgui_hash_node_t **)rt_malloc ( sizeof(rtgui_hash_node_t*) * new_size); + new_nodes = (rtgui_hash_node_t **)rtgui_malloc ( sizeof(rtgui_hash_node_t*) * new_size); if (new_nodes == RT_NULL) return; /* no memory yet */ rt_memset(new_nodes, 0, sizeof(rtgui_hash_node_t*) * new_size); @@ -275,7 +275,7 @@ static void hash_table_resize (rtgui_hash_table_t *hash_table) } } - rt_free (hash_table->nodes); + rtgui_free (hash_table->nodes); hash_table->nodes = new_nodes; hash_table->size = new_size; } @@ -284,7 +284,7 @@ static rtgui_hash_node_t* hash_node_create (void* key, void* value) { rtgui_hash_node_t *hash_node; - hash_node = (rtgui_hash_node_t*) rt_malloc ( sizeof(rtgui_hash_node_t) ); + hash_node = (rtgui_hash_node_t*) rtgui_malloc ( sizeof(rtgui_hash_node_t) ); if (hash_node != RT_NULL) { /* set value and key */ @@ -299,7 +299,7 @@ static rtgui_hash_node_t* hash_node_create (void* key, void* value) static void hash_node_destroy (rtgui_hash_node_t *hash_node) { - rt_free(hash_node); + rtgui_free(hash_node); } static void hash_nodes_destroy (rtgui_hash_node_t *hash_node) @@ -316,12 +316,12 @@ static void hash_nodes_destroy (rtgui_hash_node_t *hash_node) temp = node; node = node->next; - rt_free(temp); + rtgui_free(temp); } node->key = NULL; node->value = NULL; - rt_free(node); + rtgui_free(node); } } @@ -372,14 +372,14 @@ rtgui_image_item_t* rtgui_image_container_get(const char* filename) item = hash_table_find(image_hash_table, filename); if (item == RT_NULL) { - item = (struct rtgui_image_item*) rt_malloc (sizeof(struct rtgui_image_item)); + item = (struct rtgui_image_item*) rtgui_malloc (sizeof(struct rtgui_image_item)); if (item == RT_NULL) return RT_NULL; /* create a image object */ item->image = rtgui_image_create(filename, load_image); if (item->image == RT_NULL) { - rt_free(item); + rtgui_free(item); return RT_NULL; /* create image failed */ } @@ -407,14 +407,14 @@ rtgui_image_item_t* rtgui_image_container_get_memref(const char* type, const rt_ item = hash_table_find(image_hash_table, filename); if (item == RT_NULL) { - item = (struct rtgui_image_item*) rt_malloc (sizeof(struct rtgui_image_item)); + item = (struct rtgui_image_item*) rtgui_malloc (sizeof(struct rtgui_image_item)); if (item == RT_NULL) return RT_NULL; /* create image object */ item->image = rtgui_image_create_from_mem(type, memory, length, load_image); if (item->image == RT_NULL) { - rt_free(item); + rtgui_free(item); return RT_NULL; /* create image failed */ } @@ -438,7 +438,7 @@ void rtgui_image_container_put(rtgui_image_item_t* item) /* destroy image and image item */ rt_free(item->filename); rtgui_image_destroy(item->image); - rt_free(item); + rtgui_free(item); } } diff --git a/components/rtgui/common/region.c b/components/rtgui/common/region.c index cca9d7fd8..d597370cb 100644 --- a/components/rtgui/common/region.c +++ b/components/rtgui/common/region.c @@ -2266,3 +2266,10 @@ int rtgui_rect_is_equal(const rtgui_rect_t *rect1, const rtgui_rect_t *rect2) return -RT_ERROR; } + +rt_bool_t rtgui_rect_is_empty(const rtgui_rect_t *rect) +{ + if (rtgui_rect_is_equal(rect, &rtgui_empty_rect) == RT_EOK) return RT_TRUE; + return RT_FALSE; +} + diff --git a/components/rtgui/common/rtgui_app.c b/components/rtgui/common/rtgui_app.c index f16a97cbf..da6310717 100644 --- a/components/rtgui/common/rtgui_app.c +++ b/components/rtgui/common/rtgui_app.c @@ -1,5 +1,5 @@ /* - * File : rtgui_application.c + * File : rtgui_app.c * This file is part of RTGUI in RT-Thread RTOS * COPYRIGHT (C) 2012, RT-Thread Development Team * @@ -24,6 +24,7 @@ static void _rtgui_app_constructor(struct rtgui_app *app) rtgui_app_event_handler); app->name = RT_NULL; + app->icon = RT_NULL; /* set EXITED so we can destroy an application that just created */ app->state_flag = RTGUI_APP_FLAG_EXITED; app->ref_count = 0; @@ -240,6 +241,10 @@ rt_bool_t rtgui_app_event_handler(struct rtgui_object* object, rtgui_event_t* ev } break; + case RTGUI_EVENT_APP_DESTROY: + rtgui_app_exit(app, 0); + break; + case RTGUI_EVENT_MOUSE_BUTTON: case RTGUI_EVENT_MOUSE_MOTION: { @@ -282,12 +287,9 @@ rt_bool_t rtgui_app_event_handler(struct rtgui_object* object, rtgui_event_t* ev if (ecmd->wid != RT_NULL) return _rtgui_application_dest_handle(app, event); } - - default: - return rtgui_object_event_handler(object, event); } - return RT_TRUE; + return rtgui_object_event_handler(object, event); } rt_inline void _rtgui_application_event_loop(struct rtgui_app *app) @@ -344,6 +346,26 @@ void rtgui_app_exit(struct rtgui_app* app, rt_uint16_t code) app->exit_code = code; } +void rtgui_app_activate(struct rtgui_app *app) +{ + struct rtgui_event_application event; + + RTGUI_EVENT_APP_ACTIVATE_INIT(&event); + event.app = app; + + rtgui_send(app->tid, RTGUI_EVENT(&event), sizeof(struct rtgui_event_application)); +} + +void rtgui_app_close(struct rtgui_app *app) +{ + struct rtgui_event_application event; + + RTGUI_EVENT_APP_DESTROY_INIT(&event); + event.app = app; + + rtgui_send(app->tid, RTGUI_EVENT(&event), sizeof(struct rtgui_event_application)); +} + /** * set this application as window manager */ diff --git a/components/rtgui/common/rtgui_system.c b/components/rtgui/common/rtgui_system.c index 556d67987..4669ef301 100644 --- a/components/rtgui/common/rtgui_system.c +++ b/components/rtgui/common/rtgui_system.c @@ -26,13 +26,24 @@ #define RTGUI_MEM_TRACE #endif +static rtgui_rect_t _mainwin_rect; +static struct rt_mutex _screen_lock; + void rtgui_system_server_init() { + rt_mutex_init(&_screen_lock, "screen", RT_IPC_FLAG_FIFO); + + /* the graphic device driver must be set before initialization */ + RT_ASSERT(rtgui_graphic_driver_get_default() != RT_NULL); + /* init image */ rtgui_system_image_init(); /* init font */ rtgui_font_system_init(); + /* set the rect of main window to full screen */ + rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &_mainwin_rect); + /* init rtgui server */ rtgui_topwin_init(); rtgui_server_init(); @@ -287,11 +298,11 @@ void rtgui_free(void* ptr) #if defined(RTGUI_MEM_TRACE) && defined(RT_USING_FINSH) #include -void list_mem(void) +void list_guimem(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); +FINSH_FUNCTION_EXPORT(list_guimem, display memory information); #endif /************************************************************************/ @@ -699,3 +710,27 @@ rt_thread_t rtgui_get_server(void) return rt_thread_find("rtgui"); } +void rtgui_set_mainwin_rect(struct rtgui_rect *rect) +{ + _mainwin_rect = *rect; +} + +void rtgui_get_mainwin_rect(struct rtgui_rect *rect) +{ + *rect = _mainwin_rect; +} + +void rtgui_get_screen_rect(struct rtgui_rect *rect) +{ + rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), rect); +} + +void rtgui_screen_lock(rt_int32_t timeout) +{ + rt_mutex_take(&_screen_lock, timeout); +} + +void rtgui_screen_unlock(void) +{ + rt_mutex_release(&_screen_lock); +} diff --git a/components/rtgui/common/rtgui_theme.c b/components/rtgui/common/rtgui_theme.c index b9e52b3a9..6c9384809 100644 --- a/components/rtgui/common/rtgui_theme.c +++ b/components/rtgui/common/rtgui_theme.c @@ -71,19 +71,19 @@ void rtgui_theme_draw_win(struct rtgui_topwin* win) if (win->flag & WINTITLE_BORDER) { rect.x2 -= 1; rect.y2 -= 1; - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = RTGUI_RGB(212, 208, 200); + RTGUI_WIDGET_FOREGROUND(win->title) = RTGUI_RGB(212, 208, 200); rtgui_dc_draw_hline(dc, rect.x1, rect.x2, rect.y1); rtgui_dc_draw_vline(dc, rect.x1, rect.y1, rect.y2); - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = white; + RTGUI_WIDGET_FOREGROUND(win->title) = white; rtgui_dc_draw_hline(dc, rect.x1 + 1, rect.x2 - 1, rect.y1 + 1); rtgui_dc_draw_vline(dc, rect.x1 + 1, rect.y1 + 1, rect.y2 - 1); - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = RTGUI_RGB(128, 128, 128); + RTGUI_WIDGET_FOREGROUND(win->title) = RTGUI_RGB(128, 128, 128); rtgui_dc_draw_hline(dc, rect.x1 + 1, rect.x2 - 1, rect.y2 - 1); rtgui_dc_draw_vline(dc, rect.x2 - 1, rect.y1 + 1, rect.y2); - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = RTGUI_RGB(64, 64, 64); + RTGUI_WIDGET_FOREGROUND(win->title) = RTGUI_RGB(64, 64, 64); rtgui_dc_draw_hline(dc, rect.x1, rect.x2, rect.y2); rtgui_dc_draw_vline(dc, rect.x2, rect.y1, rect.y2 + 1); @@ -108,7 +108,7 @@ void rtgui_theme_draw_win(struct rtgui_topwin* win) delta = 64 / (float)(rect.x2 - rect.x1); } - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = RTGUI_RGB(r, g, b); + RTGUI_WIDGET_FOREGROUND(win->title) = RTGUI_RGB(r, g, b); for (index = rect.x1; index < rect.x2 + 1; index ++) { rtgui_dc_draw_vline(dc, index, rect.y1, rect.y2); @@ -117,11 +117,11 @@ void rtgui_theme_draw_win(struct rtgui_topwin* win) if (win->flag & WINTITLE_ACTIVATE) { - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = white; + RTGUI_WIDGET_FOREGROUND(win->title) = white; } else { - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = RTGUI_RGB(212, 208, 200); + RTGUI_WIDGET_FOREGROUND(win->title) = RTGUI_RGB(212, 208, 200); } rect.x1 += 4; @@ -140,13 +140,13 @@ void rtgui_theme_draw_win(struct rtgui_topwin* win) if (win->flag & WINTITLE_CB_PRESSED) { rtgui_dc_draw_border(dc, &box_rect, RTGUI_BORDER_SUNKEN); - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = red; + RTGUI_WIDGET_FOREGROUND(win->title) = red; rtgui_dc_draw_word(dc, box_rect.x1, box_rect.y1 + 6, 7, close_byte); } else { rtgui_dc_draw_border(dc, &box_rect, RTGUI_BORDER_RAISE); - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(win->title)) = black; + RTGUI_WIDGET_FOREGROUND(win->title) = black; rtgui_dc_draw_word(dc, box_rect.x1 - 1, box_rect.y1 + 5, 7, close_byte); } } @@ -171,61 +171,63 @@ void rtgui_theme_draw_button(rtgui_button_t* btn) rtgui_widget_get_rect(RTGUI_WIDGET(btn), &rect); /* get foreground color */ - bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(btn)); - fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(btn)); + bc = RTGUI_WIDGET_BACKGROUND(btn); + fc = RTGUI_WIDGET_FOREGROUND(btn); if (btn->flag & RTGUI_BUTTON_FLAG_PRESS) { + /* fill button rect with background color */ + rtgui_dc_fill_rect(dc, &rect); + if (btn->pressed_image != RT_NULL) { rtgui_rect_t image_rect; image_rect.x1 = 0; image_rect.y1 = 0; image_rect.x2 = btn->unpressed_image->w; image_rect.y2 = btn->unpressed_image->h; - rtgui_rect_moveto_align(&rect, &image_rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL); + rtgui_rect_moveto_align(&rect, &image_rect, RTGUI_ALIGN_CENTER); rtgui_image_blit(btn->pressed_image, dc, &image_rect); } else { - /* fill button rect with background color */ - rtgui_dc_fill_rect(dc, &rect); rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN); } } else { + /* fill button rect with background color */ + rtgui_dc_fill_rect(dc, &rect); + if (btn->unpressed_image != RT_NULL) { rtgui_rect_t image_rect; image_rect.x1 = 0; image_rect.y1 = 0; image_rect.x2 = btn->unpressed_image->w; image_rect.y2 = btn->unpressed_image->h; - rtgui_rect_moveto_align(&rect, &image_rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL); + rtgui_rect_moveto_align(&rect, &image_rect, RTGUI_ALIGN_CENTER); rtgui_image_blit(btn->unpressed_image, dc, &image_rect); } else { - /* fill button rect with background color */ - rtgui_dc_fill_rect(dc, &rect); rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_RAISE); } } - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(btn))) + if (RTGUI_WIDGET_IS_FOCUSED(btn)) { /* re-set foreground and get default rect */ rtgui_widget_get_rect(RTGUI_WIDGET(btn), &rect); rtgui_rect_inflate(&rect, -2); - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(btn)) = black; + RTGUI_WIDGET_FOREGROUND(btn) = black; rtgui_dc_draw_focus_rect(dc, &rect); } /* set forecolor */ - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(btn)) = bc; - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(btn)) = fc; + RTGUI_WIDGET_BACKGROUND(btn) = bc; + RTGUI_WIDGET_FOREGROUND(btn) = fc; if (btn->pressed_image == RT_NULL) { @@ -277,18 +279,18 @@ void rtgui_theme_draw_textbox(rtgui_textbox_t* box) /* get widget rect */ rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect); - fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)); + fc = RTGUI_WIDGET_FOREGROUND(box); /* fill widget rect with white color */ - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white; + RTGUI_WIDGET_BACKGROUND(box) = white; rtgui_dc_fill_rect(dc, &rect); /* draw border */ - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = RTGUI_RGB(123, 158, 189); + RTGUI_WIDGET_FOREGROUND(box) = RTGUI_RGB(123, 158, 189); rtgui_dc_draw_rect(dc, &rect); /* draw text */ - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = fc; + RTGUI_WIDGET_FOREGROUND(box) = fc; if (box->text != RT_NULL) { rect.x1 += RTGUI_TEXTBOX_MARGIN; @@ -303,7 +305,7 @@ void rtgui_theme_draw_textbox(rtgui_textbox_t* box) rt_memset(text_mask, '*', len + 1); text_mask[len] = 0; rtgui_dc_draw_text(dc, text_mask, &rect); - rt_free(text_mask); + rtgui_free(text_mask); } } else @@ -320,7 +322,7 @@ void rtgui_theme_draw_textbox(rtgui_textbox_t* box) rect.y2 -= 2; rect.y1 = rect.y2 - 3; - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = black; + RTGUI_WIDGET_BACKGROUND(box) = black; rtgui_dc_fill_rect(dc, &rect); } } @@ -333,6 +335,7 @@ void rtgui_theme_draw_iconbox(rtgui_iconbox_t* iconbox) { struct rtgui_dc* dc; struct rtgui_rect rect; + struct rtgui_rect text_rect; /* begin drawing */ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(iconbox)); @@ -348,12 +351,16 @@ void rtgui_theme_draw_iconbox(rtgui_iconbox_t* iconbox) if (iconbox->text_position == RTGUI_ICONBOX_TEXT_BELOW && iconbox->text != RT_NULL) { rect.y1 = iconbox->image->h + RTGUI_WIDGET_DEFAULT_MARGIN; - rtgui_dc_draw_text(dc, iconbox->text, &rect); + rtgui_font_get_metrics(rtgui_dc_get_gc(dc)->font, iconbox->text, &text_rect); + rtgui_rect_moveto_align(&rect, &text_rect, RTGUI_ALIGN_CENTER); + rtgui_dc_draw_text(dc, iconbox->text, &text_rect); } else if (iconbox->text_position == RTGUI_ICONBOX_TEXT_RIGHT && iconbox->text != RT_NULL) { rect.x1 = iconbox->image->w + RTGUI_WIDGET_DEFAULT_MARGIN; - rtgui_dc_draw_text(dc, iconbox->text, &rect); + rtgui_font_get_metrics(rtgui_dc_get_gc(dc)->font, iconbox->text, &text_rect); + rtgui_rect_moveto_align(&rect, &text_rect, RTGUI_ALIGN_CENTER); + rtgui_dc_draw_text(dc, iconbox->text, &text_rect); } /* end drawing */ @@ -367,8 +374,8 @@ void rtgui_theme_draw_checkbox(struct rtgui_checkbox* checkbox) struct rtgui_rect rect, box_rect; rtgui_color_t bc, fc; - fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(checkbox)); - bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(checkbox)); + fc = RTGUI_WIDGET_FOREGROUND(checkbox); + bc = RTGUI_WIDGET_BACKGROUND(checkbox); /* begin drawing */ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(checkbox)); @@ -380,9 +387,9 @@ void rtgui_theme_draw_checkbox(struct rtgui_checkbox* checkbox) /* fill rect */ rtgui_dc_fill_rect(dc, &rect); - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(checkbox))) + if (RTGUI_WIDGET_IS_FOCUSED(checkbox)) { - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(checkbox)) = black; + RTGUI_WIDGET_FOREGROUND(checkbox) = black; /* draw focused border */ rtgui_rect_inflate(&rect, -1); @@ -401,17 +408,17 @@ void rtgui_theme_draw_checkbox(struct rtgui_checkbox* checkbox) rtgui_dc_draw_border(dc, &box_rect, RTGUI_BORDER_BOX); rtgui_rect_inflate(&box_rect, -1); - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(checkbox)) = RTGUI_RGB(247, 247, 246); + RTGUI_WIDGET_BACKGROUND(checkbox) = RTGUI_RGB(247, 247, 246); rtgui_dc_fill_rect(dc, &box_rect); if (checkbox->status_down == RTGUI_CHECKBOX_STATUS_CHECKED) { - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(checkbox)) = RTGUI_RGB(33, 161, 33); + RTGUI_WIDGET_FOREGROUND(checkbox) = RTGUI_RGB(33, 161, 33); rtgui_dc_draw_byte(dc, box_rect.x1 + 2, box_rect.y1 + 2, 7, checked_byte); } /* restore saved color */ - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(checkbox)) = bc; - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(checkbox)) = fc; + RTGUI_WIDGET_BACKGROUND(checkbox) = bc; + RTGUI_WIDGET_FOREGROUND(checkbox) = fc; /* draw text */ rect.x1 += rtgui_rect_height(rect) - 4 + 5; @@ -471,7 +478,7 @@ void rtgui_theme_draw_radiobutton(struct rtgui_radiobox* radiobox, rt_uint16_t i /* draw radio */ if (radiobox->item_selection == item) { - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(radiobox))) + if (RTGUI_WIDGET_IS_FOCUSED(radiobox)) rtgui_dc_draw_focus_rect(dc, &item_rect); rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1 + (item_size - RADIO_BOX_H) / 2, @@ -501,7 +508,7 @@ void rtgui_theme_draw_radiobutton(struct rtgui_radiobox* radiobox, rt_uint16_t i /* draw radio */ if (radiobox->item_selection == item) { - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(radiobox))) + if (RTGUI_WIDGET_IS_FOCUSED(radiobox)) rtgui_dc_draw_focus_rect(dc, &item_rect); rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1, RADIO_BOX_H, radio_checked_byte); } @@ -549,17 +556,17 @@ void rtgui_theme_draw_radiobox(struct rtgui_radiobox* radiobox) /* draw box */ rtgui_rect_inflate(&rect, -bord_size/2); - fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(radiobox)); + fc = RTGUI_WIDGET_FOREGROUND(radiobox); - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(radiobox)) = white; + RTGUI_WIDGET_FOREGROUND(radiobox) = white; rect.x1 ++; rect.y1 ++; rect.x2 ++; rect.y2 ++; rtgui_dc_draw_rect(dc, &rect); - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(radiobox)) = RTGUI_RGB(128, 128, 128); + RTGUI_WIDGET_FOREGROUND(radiobox) = RTGUI_RGB(128, 128, 128); rect.x1 --; rect.y1 --; rect.x2 --; rect.y2 --; rtgui_dc_draw_rect(dc, &rect); - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(radiobox)) = fc; + RTGUI_WIDGET_FOREGROUND(radiobox) = fc; rtgui_rect_inflate(&rect, bord_size/2); if (radiobox->text != RT_NULL) @@ -595,7 +602,7 @@ void rtgui_theme_draw_radiobox(struct rtgui_radiobox* radiobox) /* draw radio */ if (radiobox->item_selection == index) { - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(radiobox))) + if (RTGUI_WIDGET_IS_FOCUSED(radiobox)) rtgui_dc_draw_focus_rect(dc, &item_rect); rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1 + offset, RADIO_BOX_H, radio_checked_byte); @@ -628,7 +635,7 @@ void rtgui_theme_draw_radiobox(struct rtgui_radiobox* radiobox) /* draw radio */ if (radiobox->item_selection == index) { - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(radiobox))) + if (RTGUI_WIDGET_IS_FOCUSED(radiobox)) rtgui_dc_draw_focus_rect(dc, &item_rect); rtgui_dc_draw_word(dc, item_rect.x1, item_rect.y1, RADIO_BOX_H, radio_checked_byte); } @@ -732,7 +739,7 @@ void rtgui_theme_draw_slider(struct rtgui_slider* slider) } /* draw focus */ - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(slider))) + if (RTGUI_WIDGET_IS_FOCUSED(slider)) { rtgui_dc_draw_focus_rect(dc, &focus_rect); } @@ -762,15 +769,15 @@ void rtgui_theme_draw_scrollbar(struct rtgui_scrollbar* bar) rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect); /* draw background */ - fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(bar)); - if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar))) - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(128, 128, 128); + fc = RTGUI_WIDGET_FOREGROUND(bar); + if (!RTGUI_WIDGET_IS_ENABLE(bar)) + RTGUI_WIDGET_FOREGROUND(bar) = RTGUI_RGB(128, 128, 128); - bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)); - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)) = white; + bc = RTGUI_WIDGET_BACKGROUND(bar); + RTGUI_WIDGET_BACKGROUND(bar) = white; rtgui_dc_fill_rect(dc, &rect); - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)) = bc; + RTGUI_WIDGET_BACKGROUND(bar) = bc; if (bar->orient == RTGUI_VERTICAL) { @@ -791,7 +798,7 @@ void rtgui_theme_draw_scrollbar(struct rtgui_scrollbar* bar) rtgui_rect_height(arrow_rect), _up_arrow); /* draw thumb */ - if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar))) + if (RTGUI_WIDGET_IS_ENABLE(bar)) { rtgui_scrollbar_get_thumb_rect(bar, &thum_rect); rtgui_dc_fill_rect(dc, &thum_rect); @@ -833,7 +840,7 @@ void rtgui_theme_draw_scrollbar(struct rtgui_scrollbar* bar) rtgui_rect_height(arrow_rect), _left_arrow); /* draw thumb */ - if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar))) + if (RTGUI_WIDGET_IS_ENABLE(bar)) { rtgui_scrollbar_get_thumb_rect(bar, &thum_rect); rtgui_dc_fill_rect(dc, &thum_rect); @@ -858,7 +865,7 @@ void rtgui_theme_draw_scrollbar(struct rtgui_scrollbar* bar) /* end drawing */ rtgui_dc_end_drawing(dc); - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(bar)) = fc; + RTGUI_WIDGET_FOREGROUND(bar) = fc; return; } @@ -881,7 +888,7 @@ void rtgui_theme_draw_progressbar(struct rtgui_progressbar* bar) rtgui_widget_get_rect(&(bar->parent), &rect); /* fill button rect with background color */ - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(212, 208, 200); + RTGUI_WIDGET_BACKGROUND(bar) = RTGUI_RGB(212, 208, 200); /* draw border */ rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN); @@ -896,7 +903,7 @@ void rtgui_theme_draw_progressbar(struct rtgui_progressbar* bar) rect.x2 ++; rect.y2 ++; left = max - pos; rtgui_rect_inflate(&rect, -2); - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(0, 0, 255); + RTGUI_WIDGET_BACKGROUND(bar) = RTGUI_RGB(0, 0, 255); rect.y2 --; rect.x2 --; if (bar->orient == RTGUI_VERTICAL) diff --git a/components/rtgui/include/rtgui/color.h b/components/rtgui/include/rtgui/color.h index 42eafbc96..22d9017a9 100644 --- a/components/rtgui/include/rtgui/color.h +++ b/components/rtgui/include/rtgui/color.h @@ -89,7 +89,7 @@ rt_inline rtgui_color_t rtgui_color_from_565(rt_uint16_t pixel) g = (pixel >> 5) & 0x3f; b = (pixel >> 11) & 0x1f; - color = r * 8225 / 1024 + ((g * 4047 / 1024) << 8) + ((b * 8225 / 1024) << 16); + color = r * 255 / 31 + ((g * 255 / 63) << 8) + ((b * 255 / 31) << 16); return color; } @@ -112,7 +112,7 @@ rt_inline rtgui_color_t rtgui_color_from_565p(rt_uint16_t pixel) g = (pixel >> 5) & 0x3f; b = pixel & 0x1f; - color = r * 8225 / 1024 + ((g * 4047 / 1024) << 8) + ((b * 8225 / 1024) << 16); + color = r * 255 / 31 + ((g * 255 / 63) << 8) + ((b * 255 / 31) << 16); return color; } diff --git a/components/rtgui/include/rtgui/dc.h b/components/rtgui/include/rtgui/dc.h index 15ae971cb..07bf09672 100644 --- a/components/rtgui/include/rtgui/dc.h +++ b/components/rtgui/include/rtgui/dc.h @@ -86,6 +86,8 @@ void rtgui_dc_draw_sector(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_in void rtgui_dc_fill_sector(struct rtgui_dc *dc, rt_int16_t x, rt_int16_t y, rt_int16_t r, rt_int16_t start, rt_int16_t end); void rtgui_dc_draw_text (struct rtgui_dc* dc, const char* text, struct rtgui_rect* rect); +void rtgui_dc_draw_text_stroke (struct rtgui_dc* dc, const char* text, struct rtgui_rect* rect, + rtgui_color_t color_stroke, rtgui_color_t color_core); void rtgui_dc_draw_mono_bmp(struct rtgui_dc* dc, int x, int y, int w, int h, const rt_uint8_t* data); void rtgui_dc_draw_byte(struct rtgui_dc*dc, int x, int y, int h, const rt_uint8_t* data); diff --git a/components/rtgui/include/rtgui/event.h b/components/rtgui/include/rtgui/event.h index 5acdf6225..e43390e06 100644 --- a/components/rtgui/include/rtgui/event.h +++ b/components/rtgui/include/rtgui/event.h @@ -63,12 +63,14 @@ enum _rtgui_event_type RTGUI_EVENT_KBD, /* keyboard info */ /* user command event */ - RTGUI_EVENT_COMMAND, /* user command */ + RTGUI_EVENT_COMMAND=0x0100, /* user command */ /* widget event */ RTGUI_EVENT_FOCUSED, /* widget focused */ RTGUI_EVENT_SCROLLED, /* scroll bar scrolled */ RTGUI_EVENT_RESIZE, /* widget resize */ + RTGUI_EVENT_SELECTED, /* widget selected */ + RTGUI_EVENT_UNSELECTED, /* widget un-selected */ }; typedef enum _rtgui_event_type rtgui_event_type; diff --git a/components/rtgui/include/rtgui/region.h b/components/rtgui/include/rtgui/region.h index 3b292f735..70041e526 100644 --- a/components/rtgui/include/rtgui/region.h +++ b/components/rtgui/include/rtgui/region.h @@ -94,6 +94,7 @@ void rtgui_rect_intersect(rtgui_rect_t *src, rtgui_rect_t *dest); int rtgui_rect_contains_point(const rtgui_rect_t *rect, int x, int y); int rtgui_rect_is_intersect(const rtgui_rect_t *rect1, const rtgui_rect_t *rect2); int rtgui_rect_is_equal(const rtgui_rect_t *rect1, const rtgui_rect_t *rect2); +rt_bool_t rtgui_rect_is_empty(const rtgui_rect_t *rect); #if defined(__cplusplus) || defined(c_plusplus) } diff --git a/components/rtgui/include/rtgui/rtgui.h b/components/rtgui/include/rtgui/rtgui.h index 188c35430..f03a94c91 100644 --- a/components/rtgui/include/rtgui/rtgui.h +++ b/components/rtgui/include/rtgui/rtgui.h @@ -29,10 +29,12 @@ struct rtgui_win; 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* object, struct rtgui_event* event); typedef void (*rtgui_onbutton_func_t)(struct rtgui_object* object, struct rtgui_event* event); +/** + * Coordinate point + */ struct rtgui_point { rt_int16_t x, y; @@ -40,6 +42,9 @@ struct rtgui_point typedef struct rtgui_point rtgui_point_t; extern rtgui_point_t rtgui_empty_point; +/** + * Rectangle structure + */ struct rtgui_rect { rt_int16_t x1, y1, x2, y2; @@ -50,6 +55,9 @@ typedef struct rtgui_rect rtgui_rect_t; typedef unsigned long rtgui_color_t; +/** + * Graphic context + */ struct rtgui_gc { /* foreground and background color */ @@ -73,6 +81,10 @@ enum RTGUI_MARGIN_STYLE RTGUI_MARGIN_BOTTOM = 0x08, RTGUI_MARGIN_ALL = RTGUI_MARGIN_LEFT | RTGUI_MARGIN_RIGHT | RTGUI_MARGIN_TOP | RTGUI_MARGIN_BOTTOM }; + +/** + * Border style + */ enum RTGUI_BORDER_STYLE { RTGUI_BORDER_NONE = 0, @@ -88,6 +100,9 @@ enum RTGUI_BORDER_STYLE #define RTGUI_BORDER_DEFAULT_WIDTH 2 #define RTGUI_WIDGET_DEFAULT_MARGIN 3 +/** + * Orientation + */ enum RTGUI_ORIENTATION { RTGUI_HORIZONTAL = 0x01, diff --git a/components/rtgui/include/rtgui/rtgui_app.h b/components/rtgui/include/rtgui/rtgui_app.h index 37bf77bae..6d973198c 100644 --- a/components/rtgui/include/rtgui/rtgui_app.h +++ b/components/rtgui/include/rtgui/rtgui_app.h @@ -1,7 +1,7 @@ /* - * File : rtgui_application.h + * File : rtgui_app.h * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * 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 @@ -11,8 +11,9 @@ * Date Author Notes * 2012-01-13 Grissiom first version */ -#ifndef __RTGUI_APPLICATION_H__ -#define __RTGUI_APPLICATION_H__ + +#ifndef __RTGUI_APP_H__ +#define __RTGUI_APP_H__ #include #include @@ -34,7 +35,7 @@ enum rtgui_app_flag RTGUI_APP_FLAG_SHOWN = 0x08 }; -typedef void (*rtgui_idle_func_t)(struct rtgui_object* obj, struct rtgui_event *event); +typedef void (*rtgui_idle_func_t)(struct rtgui_object *obj, struct rtgui_event *event); struct rtgui_app { @@ -52,7 +53,7 @@ struct rtgui_app /* the thread id */ rt_thread_t tid; /* the RTGUI server id */ - rt_thread_t server; + rt_thread_t server; /* the message queue of thread */ rt_mq_t mq; @@ -71,18 +72,20 @@ struct rtgui_app /** * create an application named @myname on thread @param tid */ -struct rtgui_app* rtgui_app_create(rt_thread_t tid, const char *title); +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_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_activate(struct rtgui_app *app); +void rtgui_app_close(struct rtgui_app *app); 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); +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); +void rtgui_app_set_main_win(struct rtgui_win *win); -#endif /* end of include guard: RTGUI_APPLICATION_H */ +#endif /* end of include guard: __RTGUI_APP_H__ */ diff --git a/components/rtgui/include/rtgui/rtgui_config.h b/components/rtgui/include/rtgui/rtgui_config.h index e1e7e5611..73672aa73 100644 --- a/components/rtgui/include/rtgui/rtgui_config.h +++ b/components/rtgui/include/rtgui/rtgui_config.h @@ -35,15 +35,19 @@ #define RTGUI_DEFAULT_FONT_SIZE 12 #define RTGUI_USING_STDIO_FILERW + // #define RTGUI_USING_DFS_FILERW #define RTGUI_IMAGE_CONTAINER #define RTGUI_IMAGE_XPM #define RTGUI_IMAGE_BMP #define RTGUI_IMAGE_PNG - #define RTGUI_IMAGE_JPEG + // #define RTGUI_IMAGE_JPEG + // #define RTGUI_IMAGE_TJPGD #define RTGUI_USING_FONT12 #define RTGUI_USING_HZ_BMP #define RTGUI_MEM_TRACE #define RTGUI_USING_WINMOVE + #define RTGUI_USING_NOTEBOOK_IMAGE + #else /* native running under RT-Thread */ #ifndef RT_USING_DFS @@ -75,8 +79,6 @@ #define RTGUI_USING_CAST_CHECK //#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 8f38909bb..aa2f9a330 100644 --- a/components/rtgui/include/rtgui/rtgui_object.h +++ b/components/rtgui/include/rtgui/rtgui_object.h @@ -125,6 +125,19 @@ rt_bool_t rtgui_object_event_handler(struct rtgui_object *object, struct rtgui_e /* supress compiler warning */ \ widget = widget; +/** handle @param event on @param object's own event handler + * + * If the @param object does not have an event handler, which means the object + * does not interested in any event, it will return RT_FALSE. Otherwise, the + * return code of that handler is returned. + */ +rt_inline rt_bool_t rtgui_object_handle(struct rtgui_object *object, struct rtgui_event *event) +{ + if (object->event_handler) + return object->event_handler(object, event); + return RT_FALSE; +} + 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_system.h b/components/rtgui/include/rtgui/rtgui_system.h index ff9f5e2b5..48f6ebb10 100644 --- a/components/rtgui/include/rtgui/rtgui_system.h +++ b/components/rtgui/include/rtgui/rtgui_system.h @@ -54,6 +54,12 @@ void* rtgui_realloc(void* ptr, rt_size_t size); #define rtgui_exit_critical rt_exit_critical rt_thread_t rtgui_get_server(void); +void rtgui_set_mainwin_rect(struct rtgui_rect *rect); +void rtgui_get_mainwin_rect(struct rtgui_rect *rect); +void rtgui_get_screen_rect(struct rtgui_rect *rect); + +void rtgui_screen_lock(rt_int32_t timeout); +void rtgui_screen_unlock(void); struct rtgui_event; rt_err_t rtgui_send(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size); @@ -65,4 +71,3 @@ 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/box.h b/components/rtgui/include/rtgui/widgets/box.h index 39d8e4dbc..621a64991 100644 --- a/components/rtgui/include/rtgui/widgets/box.h +++ b/components/rtgui/include/rtgui/widgets/box.h @@ -46,10 +46,10 @@ struct rtgui_box* rtgui_box_create(int orientation, int border_size); void rtgui_box_destroy(struct rtgui_box* box); void rtgui_box_layout(rtgui_box_t* box); +void rtgui_box_layout_rect(rtgui_box_t* box, struct rtgui_rect* rect); #ifdef __cplusplus } #endif #endif - diff --git a/components/rtgui/include/rtgui/widgets/edit.h b/components/rtgui/include/rtgui/widgets/edit.h new file mode 100644 index 000000000..c1ca18199 --- /dev/null +++ b/components/rtgui/include/rtgui/widgets/edit.h @@ -0,0 +1,129 @@ +/* + * File : edit.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 + * 2012-06-04 amsl first version + */ +#ifndef __RTGUI_EDIT_H__ +#define __RTGUI_EDIT_H__ + +#include +#include + +#ifdef _WIN32 +#include +#include +#include +#include +#else +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _WIN32 +#define open _open +#define close _close +#define read _read +#define write _write +#define unlink _unlink +#endif + +DECLARE_CLASS_TYPE(edit); + +/** Gets the type of a edit */ +#define RTGUI_EDIT_TYPE (RTGUI_TYPE(edit)) +/** Casts the object to a rtgui_edit */ +#define RTGUI_EDIT(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_EDIT_TYPE, struct rtgui_edit)) +/** Checks if the object is a rtgui_edit */ +#define RTGUI_IS_EDIT(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_EDIT_TYPE)) + +#define RTGUI_EDIT_NONE 0x00 +#define RTGUI_EDIT_CARET 0x01 +#define RTGUI_EDIT_VSCROLL 0x02 +#define RTGUI_EDIT_HSCROLL 0x04 +#define RTGUI_EDIT_SHIFT 0x10 +#define RTGUI_EDIT_CTRL 0x20 +#define RTGUI_EDIT_ALT 0x40 +#define RTGUI_EDIT_CAPSLOCK 0x80 +#define RTGUI_EDIT_NUMLOCK 0x100 + +struct edit_update +{ + /* rt_uint32_t type; */ /* update type */ + rtgui_point_t start, end; /* update area */ +}; + +struct edit_line +{ + rt_size_t zsize; /* zone size */ + rt_uint32_t len; + struct edit_line *prev; + struct edit_line *next; + char *text; +}; + +struct rtgui_edit +{ + /* inherit from container */ + rtgui_container_t parent; + + /* edit flag */ + rt_uint32_t flag; + rt_uint32_t max_rows, max_cols; + rt_uint16_t row_per_page, col_per_page; + rtgui_point_t upleft; + rtgui_point_t visual; + rt_uint8_t tabsize; + rt_uint8_t item_height; + rt_uint8_t font_width,font_height; + rt_uint8_t margin; + rt_size_t bzsize; /* base zone size */ + + struct rtgui_timer *caret_timer; + rtgui_color_t *caret; + rtgui_rect_t caret_rect; + struct edit_update update; + char *update_buf; /* speed up renewal process */ + + struct edit_line *head; + struct edit_line *tail; + struct edit_line *first_line; +#ifdef RTGUI_EDIT_USING_SCROLL + struct rtgui_scrollbar *hscroll; + struct rtgui_scrollbar *vscroll; +#endif +}; + +rt_bool_t rtgui_edit_append_line(struct rtgui_edit *edit, const char *text); +rt_bool_t rtgui_edit_insert_line(struct rtgui_edit *edit, struct edit_line *p, char *text); +rt_bool_t rtgui_edit_delete_line(struct rtgui_edit *edit, struct edit_line *line); +rt_bool_t rtgui_edit_connect_line(struct rtgui_edit *edit, struct edit_line *line, struct edit_line *connect); + +void _rtgui_edit_constructor(struct rtgui_edit *box); +void _rtgui_edit_deconstructor(struct rtgui_edit *textbox); + +struct rtgui_edit* rtgui_edit_create(struct rtgui_container* container, int left, int top, int w, int h); +void rtgui_edit_destroy(struct rtgui_edit *edit); +void rtgui_edit_update(struct rtgui_edit *edit); +void rtgui_edit_ondraw(struct rtgui_edit *edit); +rt_bool_t rtgui_edit_event_handler(struct rtgui_object* object, rtgui_event_t* event); +void rtgui_edit_set_text(struct rtgui_edit *edit, const char* text); + +rt_bool_t rtgui_edit_readin_file(struct rtgui_edit *edit, const char *filename); +rt_bool_t rtgui_edit_saveas_file(struct rtgui_edit *edit, const char *filename); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/rtgui/include/rtgui/widgets/groupbox.h b/components/rtgui/include/rtgui/widgets/groupbox.h new file mode 100644 index 000000000..8cc06d461 --- /dev/null +++ b/components/rtgui/include/rtgui/widgets/groupbox.h @@ -0,0 +1,73 @@ +/* + * File : groupbox.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 + * 2012-07-29 Bernard first version + */ +#ifndef __RTGUI_GROUPBOX_H__ +#define __RTGUI_GROUPBOX_H__ + +#include +#include +#include +#include + +DECLARE_CLASS_TYPE(groupbox); + +/** Gets the type of a groupbox */ +#define RTGUI_GROUPBOX_TYPE (RTGUI_TYPE(groupbox)) +/** Casts the object to an groupbox */ +#define RTGUI_GROUPBOX(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_GROUPBOX_TYPE, rtgui_groupbox_t)) +/** Checks if the object is an rtgui_groupbox */ +#define RTGUI_IS_GROUPBOX(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_GROUPBOX_TYPE)) + +typedef void (*widget_select_t)(struct rtgui_widget* widget, rt_bool_t selected); + +/* + * the groupbox widget + * + * The Group Box is a container widget, in which user can place some other widget into it. + * However, the current selected in group box must be notified by user: + * - invoke rtgui_groupbox_select_widget to notify group box the current selected widget; + * - when a widget has been selected, group box invokes groupbox->select_func to change + * the status of widget, for example un-select this widget. + */ +struct rtgui_groupbox +{ + struct rtgui_panel parent; + + char* label; + struct rtgui_box *box; + struct rtgui_widget *selected; + + widget_select_t select_func; + rtgui_event_handler_ptr on_selected; +}; +typedef struct rtgui_groupbox rtgui_groupbox_t; + +rtgui_groupbox_t* rtgui_groupbox_create(const char* label, struct rtgui_rect *rect, int style, widget_select_t select_func); +void rtgui_groupbox_destroy(rtgui_groupbox_t* groupbox); + +void rtgui_groupbox_layout(struct rtgui_groupbox *box); + +void rtgui_groupbox_add_widget(struct rtgui_groupbox *box, struct rtgui_widget *widget); +void rtgui_groupbox_select_widget(struct rtgui_groupbox *box, struct rtgui_widget *widget); +struct rtgui_widget* rtgui_groupbox_get_selected(struct rtgui_groupbox *box); + +rt_bool_t rtgui_groupbox_event_handler(struct rtgui_object* object, struct rtgui_event* event); + +rt_inline void rtgui_groupbox_set_onselected(struct rtgui_groupbox* box, rtgui_event_handler_ptr on_selected) +{ + RT_ASSERT(box != RT_NULL); + box->on_selected = on_selected; +} + +#endif + diff --git a/components/rtgui/include/rtgui/widgets/iconbox.h b/components/rtgui/include/rtgui/widgets/iconbox.h index 17545951d..5c46f9734 100644 --- a/components/rtgui/include/rtgui/widgets/iconbox.h +++ b/components/rtgui/include/rtgui/widgets/iconbox.h @@ -51,5 +51,6 @@ void rtgui_iconbox_destroy(struct rtgui_iconbox* iconbox); rt_bool_t rtgui_iconbox_event_handler(struct rtgui_object* object, struct rtgui_event* event); void rtgui_iconbox_set_text_position(struct rtgui_iconbox* iconbox, int position); +void rtgui_iconbox_set_selected(struct rtgui_iconbox* iconbox, rt_bool_t selected); #endif diff --git a/components/rtgui/include/rtgui/widgets/listctrl.h b/components/rtgui/include/rtgui/widgets/listctrl.h index d3f9ce703..51905f594 100644 --- a/components/rtgui/include/rtgui/widgets/listctrl.h +++ b/components/rtgui/include/rtgui/widgets/listctrl.h @@ -42,6 +42,7 @@ struct rtgui_listctrl rt_uint16_t page_items; /* current item */ rt_int16_t current_item; + rt_uint16_t item_height; /* item event handler */ rtgui_event_handler_ptr on_item; @@ -59,5 +60,6 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui void rtgui_listctrl_set_onitem(rtgui_listctrl_t* ctrl, rtgui_event_handler_ptr func); void rtgui_listctrl_set_items(rtgui_listctrl_t* ctrl, rt_uint32_t items, rt_uint16_t count); rt_bool_t rtgui_listctrl_get_item_rect(rtgui_listctrl_t* ctrl, rt_uint16_t item, rtgui_rect_t* item_rect); +void rtgui_listctrl_set_itemheight(struct rtgui_listctrl* ctrl, int height); #endif diff --git a/components/rtgui/include/rtgui/widgets/notebook.h b/components/rtgui/include/rtgui/widgets/notebook.h index 881f11fc1..9d8cfa8ad 100644 --- a/components/rtgui/include/rtgui/widgets/notebook.h +++ b/components/rtgui/include/rtgui/widgets/notebook.h @@ -2,6 +2,7 @@ #define __RTGUI_NOTEBOOK_H__ #include +#include #include DECLARE_CLASS_TYPE(notebook); @@ -15,6 +16,8 @@ DECLARE_CLASS_TYPE(notebook); #define RTGUI_NOTEBOOK_TOP 0x00 #define RTGUI_NOTEBOOK_BOTTOM 0x01 #define RTGUI_NOTEBOOK_NOTAB 0x02 +#define RTGUI_NOTEBOOK_LEFT 0x03 +#define RTGUI_NOTEBOOK_RIGHT 0x04 struct rtgui_notebook_tab; @@ -28,17 +31,36 @@ struct rtgui_notebook struct rtgui_notebook_tab *childs; rt_uint16_t count; rt_int16_t current; + + rt_uint16_t tab_w, tab_h; }; struct rtgui_notebook* rtgui_notebook_create(const rtgui_rect_t* rect, rt_uint8_t style); void rtgui_notebook_destroy(struct rtgui_notebook* notebook); +rt_inline void rtgui_notebook_set_tab_height(struct rtgui_notebook *notebook, rt_uint16_t height) +{ + RT_ASSERT(notebook != RT_NULL); + notebook->tab_h = height; +} + +rt_inline void rtgui_notebook_set_tab_width(struct rtgui_notebook *notebook, rt_uint16_t width) +{ + RT_ASSERT(notebook != RT_NULL); + notebook->tab_w = width; +} + void rtgui_notebook_add(struct rtgui_notebook* notebook, const char* label, struct rtgui_widget* child); +#ifdef RTGUI_USING_NOTEBOOK_IMAGE +void rtgui_notebook_add_image(struct rtgui_notebook* notebook, const char* label, struct rtgui_widget* child, + struct rtgui_image *pressed_image, struct rtgui_image *unpressed_image); +#endif void rtgui_notebook_remove(struct rtgui_notebook* notebook, rt_uint16_t index); struct rtgui_widget* rtgui_notebook_get_current(struct rtgui_notebook* notebook); rt_int16_t rtgui_notebook_get_current_index(struct rtgui_notebook* notebook); int rtgui_notebook_get_count(struct rtgui_notebook* notebook); +void rtgui_notebook_get_client_rect(struct rtgui_notebook* notebook, struct rtgui_rect *rect); void rtgui_notebook_set_current(struct rtgui_notebook* notebook, struct rtgui_widget* child); void rtgui_notebook_set_current_by_index(struct rtgui_notebook* notebook, rt_uint16_t index); diff --git a/components/rtgui/include/rtgui/widgets/panel.h b/components/rtgui/include/rtgui/widgets/panel.h index 4d4af5e02..3343e4e9f 100644 --- a/components/rtgui/include/rtgui/widgets/panel.h +++ b/components/rtgui/include/rtgui/widgets/panel.h @@ -23,7 +23,7 @@ DECLARE_CLASS_TYPE(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 */ +/** Checks if the object is an rtgui_panel */ #define RTGUI_IS_PANEL(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_PANEL_TYPE)) /* @@ -40,6 +40,12 @@ 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_inline void rtgui_panel_set_border(struct rtgui_panel* panel, int border_style) +{ + RT_ASSERT(panel != RT_NULL); + panel->border_style = border_style; +} + rt_bool_t rtgui_panel_event_handler(struct rtgui_object* object, struct rtgui_event* event); #endif diff --git a/components/rtgui/include/rtgui/widgets/widget.h b/components/rtgui/include/rtgui/widgets/widget.h index e588df166..3deef998e 100644 --- a/components/rtgui/include/rtgui/widgets/widget.h +++ b/components/rtgui/include/rtgui/widgets/widget.h @@ -33,25 +33,6 @@ extern "C" { #define RTGUI_WIDGET_FLAG_FOCUSABLE 0x0010 #define RTGUI_WIDGET_FLAG_DC_VISIBLE 0x0100 -#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 -#define RTGUI_WIDGET_IS_ENABLE(w) !(w->flag & RTGUI_WIDGET_FLAG_DISABLE) - -#define RTGUI_WIDGET_UNFOCUS(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_FOCUS -#define RTGUI_WIDGET_FOCUS(w) (w)->flag |= RTGUI_WIDGET_FLAG_FOCUS -#define RTGUI_WIDGET_IS_FOCUSED(w) ((w)->flag & RTGUI_WIDGET_FLAG_FOCUS) - -#define RTGUI_WIDGET_IS_FOCUSABLE(w) ((w)->flag & RTGUI_WIDGET_FLAG_FOCUSABLE) - -#define RTGUI_WIDGET_IS_DC_VISIBLE(w) ((w)->flag & RTGUI_WIDGET_FLAG_DC_VISIBLE) -#define RTGUI_WIDGET_DC_SET_VISIBLE(w) (w)->flag |= RTGUI_WIDGET_FLAG_DC_VISIBLE -#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)) - /* rtgui widget attribute */ #define RTGUI_WIDGET_FOREGROUND(w) (RTGUI_WIDGET(w)->gc.foreground) #define RTGUI_WIDGET_BACKGROUND(w) (RTGUI_WIDGET(w)->gc.background) @@ -59,6 +40,27 @@ extern "C" { #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) +#define RTGUI_WIDGET_BORDER(w) (RTGUI_WIDGET(w)->border) +#define RTGUI_WIDGET_BORDER_STYLE(w) (RTGUI_WIDGET(w)->border_style) + +#define RTGUI_WIDGET_UNHIDE(w) RTGUI_WIDGET_FLAG(w) |= RTGUI_WIDGET_FLAG_SHOWN +#define RTGUI_WIDGET_HIDE(w) RTGUI_WIDGET_FLAG(w) &= ~RTGUI_WIDGET_FLAG_SHOWN +#define RTGUI_WIDGET_IS_HIDE(w) (!(RTGUI_WIDGET_FLAG(w) & RTGUI_WIDGET_FLAG_SHOWN)) + +#define RTGUI_WIDGET_ENABLE(w) RTGUI_WIDGET_FLAG(w) &= ~RTGUI_WIDGET_FLAG_DISABLE +#define RTGUI_WIDGET_DISABLE(w) RTGUI_WIDGET_FLAG(w) |= RTGUI_WIDGET_FLAG_DISABLE +#define RTGUI_WIDGET_IS_ENABLE(w) (!((RTGUI_WIDGET_FLAG(w) & RTGUI_WIDGET_FLAG_DISABLE))) + +#define RTGUI_WIDGET_UNFOCUS(w) RTGUI_WIDGET_FLAG(w) &= ~RTGUI_WIDGET_FLAG_FOCUS +#define RTGUI_WIDGET_FOCUS(w) RTGUI_WIDGET_FLAG(w) |= RTGUI_WIDGET_FLAG_FOCUS +#define RTGUI_WIDGET_IS_FOCUSED(w) (RTGUI_WIDGET_FLAG(w) & RTGUI_WIDGET_FLAG_FOCUS) + +#define RTGUI_WIDGET_IS_FOCUSABLE(w) (RTGUI_WIDGET_FLAG(w) & RTGUI_WIDGET_FLAG_FOCUSABLE) + +#define RTGUI_WIDGET_IS_DC_VISIBLE(w) (RTGUI_WIDGET_FLAG(w) & RTGUI_WIDGET_FLAG_DC_VISIBLE) +#define RTGUI_WIDGET_DC_SET_VISIBLE(w) RTGUI_WIDGET_FLAG(w) |= RTGUI_WIDGET_FLAG_DC_VISIBLE +#define RTGUI_WIDGET_DC_SET_UNVISIBLE(w) RTGUI_WIDGET_FLAG(w) &= ~RTGUI_WIDGET_FLAG_DC_VISIBLE +#define RTGUI_WIDGET_DC(w) ((struct rtgui_dc*)&((w)->dc_type)) DECLARE_CLASS_TYPE(widget); @@ -101,7 +103,8 @@ struct rtgui_widget rt_int16_t mini_width, mini_height; /* widget align */ rt_int32_t align; - + rt_uint16_t border; + rt_uint16_t border_style; /* the rect clip */ rtgui_region_t clip; @@ -155,6 +158,7 @@ void rtgui_widget_set_oncommand(rtgui_widget_t* widget, rtgui_event_handler_ptr /* get and set rect of widget */ void rtgui_widget_get_rect(rtgui_widget_t* widget, rtgui_rect_t *rect); +void rtgui_widget_set_border(rtgui_widget_t* widget, rt_uint32_t style); void rtgui_widget_set_rect(rtgui_widget_t* widget, const rtgui_rect_t* rect); void rtgui_widget_set_rectangle(rtgui_widget_t* widget, int x, int y, int width, int height); void rtgui_widget_get_extent(rtgui_widget_t* widget, rtgui_rect_t *rect); diff --git a/components/rtgui/include/rtgui/widgets/window.h b/components/rtgui/include/rtgui/widgets/window.h index 7f2756905..735a7b283 100644 --- a/components/rtgui/include/rtgui/widgets/window.h +++ b/components/rtgui/include/rtgui/widgets/window.h @@ -29,16 +29,16 @@ DECLARE_CLASS_TYPE(win); /** Checks if the object is an rtgui_win */ #define RTGUI_IS_WIN(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_WIN_TYPE)) -#define RTGUI_WIN_STYLE_NO_FOCUS 0x001 /* non-focused window */ +#define RTGUI_WIN_STYLE_NO_FOCUS 0x0001 /* non-focused window */ +#define RTGUI_WIN_STYLE_NO_TITLE 0x0002 /* no title window */ +#define RTGUI_WIN_STYLE_NO_BORDER 0x0004 /* no border window */ +#define RTGUI_WIN_STYLE_CLOSEBOX 0x0008 /* window has the close button */ +#define RTGUI_WIN_STYLE_MINIBOX 0x0010 /* window has the mini button */ -#define RTGUI_WIN_STYLE_NO_TITLE 0x002 /* no title window */ -#define RTGUI_WIN_STYLE_NO_BORDER 0x004 /* no border window */ -#define RTGUI_WIN_STYLE_CLOSEBOX 0x008 /* window has the close button */ -#define RTGUI_WIN_STYLE_MINIBOX 0x010 /* window has the mini button */ - -#define RTGUI_WIN_STYLE_DESTROY_ON_CLOSE 0x020 /* window is destroyed when closed */ -#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_DESTROY_ON_CLOSE 0x0020 /* window is destroyed when closed */ +#define RTGUI_WIN_STYLE_ONTOP 0x0040 /* window is in the top layer */ +#define RTGUI_WIN_STYLE_ONBTM 0x0080 /* window is in the bottom layer */ +#define RTGUI_WIN_STYLE_MAINWIN 0x0106 /* window is a main window */ #define RTGUI_WIN_STYLE_DEFAULT (RTGUI_WIN_STYLE_CLOSEBOX | RTGUI_WIN_STYLE_MINIBOX) @@ -109,6 +109,8 @@ struct rtgui_win rtgui_win_t* rtgui_win_create(struct rtgui_win *parent_window, const char* title, rtgui_rect_t *rect, rt_uint16_t style); +rtgui_win_t* rtgui_mainwin_create(struct rtgui_win *parent_window, const char* title, rt_uint16_t style); + void rtgui_win_destroy(rtgui_win_t* win); /** Close window. diff --git a/components/rtgui/server/mouse.c b/components/rtgui/server/mouse.c index 9acc98961..8bd399dbb 100644 --- a/components/rtgui/server/mouse.c +++ b/components/rtgui/server/mouse.c @@ -124,10 +124,12 @@ static void rtgui_winrect_show (void); #endif #define WIN_MOVE_BORDER 4 -void rtgui_mouse_init() +void rtgui_mouse_init(void) { const struct rtgui_graphic_driver* gd = rtgui_graphic_driver_get_default(); + if (_rtgui_cursor != RT_NULL) rtgui_mouse_fini(); + _rtgui_cursor = (struct rtgui_cursor*) rtgui_malloc(sizeof(struct rtgui_cursor)); rt_memset(_rtgui_cursor, 0, sizeof(struct rtgui_cursor)); @@ -178,6 +180,27 @@ void rtgui_mouse_init() #endif } +void rtgui_mouse_fini(void) +{ + if (_rtgui_cursor != RT_NULL) + { +#ifdef RTGUI_USING_WINMOVE + rtgui_free(_rtgui_cursor->win_left); + rtgui_free(_rtgui_cursor->win_right); + rtgui_free(_rtgui_cursor->win_top); + rtgui_free(_rtgui_cursor->win_bottom); +#endif +#ifdef RTGUI_USING_MOUSE_CURSOR + rt_mutex_detach(&cursor_mutex); + rtgui_image_destroy(_rtgui_cursor->cursor_image); + rtgui_free(_rtgui_cursor->rtgui_malloc); +#endif + rtgui_free(_rtgui_cursor); + + _rtgui_cursor = RT_NULL; + } +} + void rtgui_mouse_moveto(int x, int y) { #ifdef RTGUI_USING_MOUSE_CURSOR diff --git a/components/rtgui/server/mouse.h b/components/rtgui/server/mouse.h index e1815f3a9..01c8fc47c 100644 --- a/components/rtgui/server/mouse.h +++ b/components/rtgui/server/mouse.h @@ -29,6 +29,7 @@ struct rtgui_mouse_monitor typedef struct rtgui_mouse_monitor rtgui_mouse_monitor_t; void rtgui_mouse_init(void); +void rtgui_mouse_fini(void); void rtgui_mouse_moveto(int x, int y); void rtgui_mouse_set_cursor_enable(rt_bool_t enable); diff --git a/components/rtgui/server/topwin.c b/components/rtgui/server/topwin.c index 4c75cc115..6f6274048 100644 --- a/components/rtgui/server/topwin.c +++ b/components/rtgui/server/topwin.c @@ -551,23 +551,23 @@ rt_inline void _rtgui_topwin_mark_hidden(struct rtgui_topwin *topwin) topwin->flag &= ~WINTITLE_SHOWN; if (topwin->title != RT_NULL) { - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(topwin->title)); + RTGUI_WIDGET_HIDE(topwin->title); } - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(topwin->wid)); + RTGUI_WIDGET_HIDE(topwin->wid); } rt_inline void _rtgui_topwin_mark_shown(struct rtgui_topwin *topwin) { if (!(topwin->flag & WINTITLE_SHOWN) - && RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(topwin->wid))) + && RTGUI_WIDGET_IS_HIDE(topwin->wid)) return; topwin->flag |= WINTITLE_SHOWN; if (topwin->title != RT_NULL) { - RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(topwin->title)); + RTGUI_WIDGET_UNHIDE(topwin->title); } - RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(topwin->wid)); + RTGUI_WIDGET_UNHIDE(topwin->wid); } static void _rtgui_topwin_draw_tree(struct rtgui_topwin *topwin, struct rtgui_event_paint *epaint) diff --git a/components/rtgui/widgets/box.c b/components/rtgui/widgets/box.c index 68ee60837..b69767e85 100644 --- a/components/rtgui/widgets/box.c +++ b/components/rtgui/widgets/box.c @@ -45,7 +45,12 @@ struct rtgui_box* rtgui_box_create(int orientation, int border_size) return box; } -static void rtgui_box_layout_vertical(rtgui_box_t* box) +void rtgui_box_destroy(struct rtgui_box* box) +{ + rtgui_object_destroy(RTGUI_OBJECT(box)); +} + +static void rtgui_box_layout_vertical(struct rtgui_box* box, struct rtgui_rect* extent) { rtgui_list_t *node; rt_int32_t box_width; @@ -53,11 +58,9 @@ 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; @@ -74,18 +77,18 @@ 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(container_widget->extent) - total_height - (box->border_size << 1)) / space_count; + space_height = (rtgui_rect_height(*extent) - total_height - (box->border_size << 1)) / space_count; } /* init (x, y) and box width */ - 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); + next_x = extent->x1 + box->border_size; + next_y = extent->y1 + box->border_size; + box_width = rtgui_rect_width(*extent) - (box->border_size << 1); /* layout each widget */ rtgui_list_foreach(node, &(box->container->children)) { - rtgui_rect_t *rect; + struct rtgui_rect *rect; rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); /* get extent of widget */ @@ -140,7 +143,7 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box) } } -static void rtgui_box_layout_horizontal(rtgui_box_t* box) +static void rtgui_box_layout_horizontal(struct rtgui_box* box, struct rtgui_rect* extent) { rtgui_list_t *node; rt_int32_t box_height; @@ -148,11 +151,9 @@ 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; @@ -169,13 +170,13 @@ 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(container_widget->extent) - total_width) / space_count; + space_width = (rtgui_rect_width(*extent) - total_width) / space_count; } /* init (x, y) and box height */ - 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); + next_x = extent->x1 + box->border_size; + next_y = extent->y1 + box->border_size; + box_height = rtgui_rect_height(*extent) - (box->border_size << 1); /* layout each widget */ rtgui_list_foreach(node, &(box->container->children)) @@ -237,17 +238,19 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box) void rtgui_box_layout(rtgui_box_t* box) { + struct rtgui_rect extent; RT_ASSERT(box != RT_NULL); if (box->container == RT_NULL) return; + rtgui_widget_get_extent(RTGUI_WIDGET(box->container), &extent); if (box->orient & RTGUI_VERTICAL) { - rtgui_box_layout_vertical(box); + rtgui_box_layout_vertical(box, &extent); } else { - rtgui_box_layout_horizontal(box); + rtgui_box_layout_horizontal(box, &extent); } /* update box and its children clip */ @@ -257,3 +260,24 @@ void rtgui_box_layout(rtgui_box_t* box) } } +void rtgui_box_layout_rect(rtgui_box_t* box, struct rtgui_rect* rect) +{ + RT_ASSERT(box != RT_NULL); + + if (box->container == RT_NULL) return; + + if (box->orient & RTGUI_VERTICAL) + { + rtgui_box_layout_vertical(box, rect); + } + else + { + rtgui_box_layout_horizontal(box, rect); + } + + /* update box and its children clip */ + if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(box->container))) + { + rtgui_widget_update_clip(RTGUI_WIDGET(box->container)); + } +} diff --git a/components/rtgui/widgets/button.c b/components/rtgui/widgets/button.c index 2a7571e39..0e02b2761 100644 --- a/components/rtgui/widgets/button.c +++ b/components/rtgui/widgets/button.c @@ -31,9 +31,9 @@ static void _rtgui_button_constructor(rtgui_button_t *button) button->on_button = RT_NULL; /* set gc */ - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(button)) = default_foreground; - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(button)) = RTGUI_RGB(212, 208, 200); - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(button)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_FOREGROUND(button) = default_foreground; + RTGUI_WIDGET_BACKGROUND(button) = RTGUI_RGB(212, 208, 200); + RTGUI_WIDGET_TEXTALIGN(button) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL; } static void _rtgui_button_destructor(rtgui_button_t *button) diff --git a/components/rtgui/widgets/checkbox.c b/components/rtgui/widgets/checkbox.c index ad1657baa..ee3b2a32f 100644 --- a/components/rtgui/widgets/checkbox.c +++ b/components/rtgui/widgets/checkbox.c @@ -13,7 +13,7 @@ static void _rtgui_checkbox_constructor(rtgui_checkbox_t *box) box->on_button = RT_NULL; /* set default gc */ - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_TEXTALIGN(box) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL; } DEFINE_CLASS_TYPE(checkbox, "checkbox", diff --git a/components/rtgui/widgets/combobox.c b/components/rtgui/widgets/combobox.c index a504682c5..a1d4c8634 100644 --- a/components/rtgui/widgets/combobox.c +++ b/components/rtgui/widgets/combobox.c @@ -13,7 +13,7 @@ static void _rtgui_combobox_constructor(rtgui_combobox_t *box) rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_combobox_event_handler); rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect); - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_TEXTALIGN(box) = RTGUI_ALIGN_CENTER_VERTICAL; box->pd_pressed = RT_FALSE; box->current_item = 0; @@ -96,11 +96,11 @@ static void rtgui_combobox_ondraw(struct rtgui_combobox* box) dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box)); if (dc == RT_NULL) return; - bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)); + bc = RTGUI_WIDGET_BACKGROUND(box); /* get widget rect */ rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect); - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white; + RTGUI_WIDGET_BACKGROUND(box) = white; /* fill widget rect with background color */ rtgui_dc_fill_rect(dc, &rect); @@ -114,7 +114,7 @@ static void rtgui_combobox_ondraw(struct rtgui_combobox* box) } /* restore background color */ - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = bc; + RTGUI_WIDGET_BACKGROUND(box) = bc; /* draw pull down button */ rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH; diff --git a/components/rtgui/widgets/container.c b/components/rtgui/widgets/container.c index 7cfe455f5..4c3af36fb 100644 --- a/components/rtgui/widgets/container.c +++ b/components/rtgui/widgets/container.c @@ -74,7 +74,7 @@ rt_bool_t rtgui_container_broadcast_event(struct rtgui_container *container, str w = rtgui_list_entry(node, struct rtgui_widget, sibling); if (RTGUI_OBJECT(w)->event_handler) - RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w), event) == RT_TRUE; + RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w), event); } return RT_FALSE; diff --git a/components/rtgui/widgets/edit.c b/components/rtgui/widgets/edit.c new file mode 100644 index 000000000..21fe2929a --- /dev/null +++ b/components/rtgui/widgets/edit.c @@ -0,0 +1,1666 @@ +/* + * File : edit.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-06-04 amsl firist version. + * 2012-08-09 amsl beta 0.1 + */ +#include +#include +#include +#include + +static void rtgui_edit_draw_caret(struct rtgui_edit *edit); +static void rtgui_edit_timeout(struct rtgui_timer* timer, void* parameter); +static rt_bool_t rtgui_edit_onfocus(struct rtgui_object* object, rtgui_event_t* event); +static rt_bool_t rtgui_edit_onunfocus(struct rtgui_object* object, rtgui_event_t* event); +static rt_bool_t rtgui_edit_hscroll_handle(struct rtgui_widget* widget, rtgui_event_t* event); +static rt_bool_t rtgui_edit_vscroll_handle(struct rtgui_widget* widget, rtgui_event_t* event); + +void _rtgui_edit_constructor(struct rtgui_edit *edit) +{ + rtgui_rect_t font_rect; + RTGUI_WIDGET_FLAG(edit) |= RTGUI_WIDGET_FLAG_FOCUSABLE; + + rtgui_object_set_event_handler(RTGUI_OBJECT(edit), rtgui_edit_event_handler); + rtgui_widget_set_onfocus(RTGUI_WIDGET(edit), rtgui_edit_onfocus); + rtgui_widget_set_onunfocus(RTGUI_WIDGET(edit), rtgui_edit_onunfocus); + + RTGUI_WIDGET_FOREGROUND(edit) = black; + RTGUI_WIDGET_BACKGROUND(edit) = white; + /* set default text align */ + RTGUI_WIDGET_TEXTALIGN(edit) = RTGUI_ALIGN_CENTER_VERTICAL; + rtgui_widget_set_border(RTGUI_WIDGET(edit), RTGUI_BORDER_SUNKEN); + /* set proper of control */ + edit->caret_timer = RT_NULL; + edit->caret = RT_NULL; + + edit->tabsize = 4; + edit->margin = 1; + edit->max_rows = edit->max_cols = 0; + edit->visual.x = edit->visual.y = 0; + edit->upleft.x = edit->upleft.y = 0; + edit->row_per_page = edit->col_per_page = 0; + + edit->update_buf = RT_NULL; + edit->flag = RTGUI_EDIT_NONE; +#ifdef RTGUI_EDIT_USING_SCROLL + edit->flag |= RTGUI_EDIT_VSCROLL; + edit->flag |= RTGUI_EDIT_HSCROLL; +#endif + /* allocate default line buffer */ + edit->bzsize = 16; + + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(edit), "H", &font_rect); + edit->font_width = rtgui_rect_width(font_rect); + edit->font_height = rtgui_rect_height(font_rect); + + edit->head = RT_NULL; + edit->tail = RT_NULL; + edit->first_line = RT_NULL; +#ifdef RTGUI_EDIT_USING_SCROLL + edit->hscroll = RT_NULL; + edit->vscroll = RT_NULL; +#endif +} + +void _rtgui_edit_deconstructor(struct rtgui_edit *edit) +{ + if(edit->max_rows > 0) + { + while(edit->max_rows > 0) + rtgui_edit_delete_line(edit, edit->head); + edit->max_rows = 0; + } + if(edit->caret_timer != RT_NULL) + rtgui_timer_destory(edit->caret_timer); + edit->caret_timer = RT_NULL; + + if(edit->caret != RT_NULL) + rtgui_free(edit->caret); + edit->caret = RT_NULL; + if(edit->update_buf != RT_NULL) + rtgui_free(edit->update_buf); +} + +DEFINE_CLASS_TYPE(edit, "edit", + RTGUI_CONTAINER_TYPE, + _rtgui_edit_constructor, + _rtgui_edit_deconstructor, + sizeof(struct rtgui_edit)); + +#ifdef RTGUI_EDIT_USING_SCROLL +void rtgui_edit_adjust_scroll(rtgui_scrollbar_t *bar) +{ + struct rtgui_edit *edit; + + RT_ASSERT(bar != RT_NULL); + + if(bar->widget_link != RT_NULL) + { + rtgui_rect_t rect; + rt_uint32_t _left=0,_top=0,_width=RTGUI_DEFAULT_SB_WIDTH,_len=0; + + edit = bar->widget_link; + rtgui_widget_get_rect(edit, &rect); + rtgui_widget_rect_to_device(edit,&rect); + if(bar->orient==RTGUI_HORIZONTAL) + { + if(RTGUI_WIDGET_IS_HIDE(edit->hscroll)) + { + if(edit->max_rows > edit->row_per_page) + { + RTGUI_WIDGET_SHOW(edit->hscroll); + rtgui_scrollbar_set_line_step(edit->hscroll, 1); + rtgui_scrollbar_set_page_step(edit->hscroll, edit->row_per_page); + rtgui_scrollbar_set_range(edit->hscroll, edit->max_rows); + } + else + RTGUI_WIDGET_HIDE(edit->vscroll); + rtgui_widget_update_clip(RTGUI_WIDGET(edit)); + } + else + { + _left = RTGUI_WIDGET_BORDER(edit); + _top = rtgui_rect_height(rect)-RTGUI_WIDGET_BORDER(edit)-_width; + _len = rtgui_rect_width(rect)-RTGUI_WIDGET_BORDER(edit)*2; + + if(!RTGUI_WIDGET_IS_HIDE(edit->vscroll)) + _len -= _width; + rect.x1 += _left; + rect.y1 += _top; + rect.x2 = rect.x1+_len; + rect.y2 = rect.y1+_width; + } + } + else if(bar->orient==RTGUI_VERTICAL) + { + _left = rtgui_rect_width(rect)-RTGUI_WIDGET_BORDER(edit)-_width; + _top = RTGUI_WIDGET_BORDER(edit); + _len = rtgui_rect_height(rect)-RTGUI_WIDGET_BORDER(edit)*2; + + if(!RTGUI_WIDGET_IS_HIDE(edit->hscroll)) + _len -= _width; + rect.x1 += _left; + rect.y1 += _top; + rect.x2 = rect.x1+_width; + rect.y2 = rect.y1+_len; + } + rtgui_widget_set_rect(bar,&rect); + } +} +#endif + +struct rtgui_edit* rtgui_edit_create(struct rtgui_container* container, int left, int top, int w, int h) +{ + struct rtgui_edit* edit; + + RT_ASSERT(container != RT_NULL); + + edit = (struct rtgui_edit*)rtgui_widget_create(RTGUI_EDIT_TYPE); + if(edit != RT_NULL) + { + rtgui_rect_t rect; + int effe; + rtgui_widget_get_rect(RTGUI_WIDGET(container), &rect); + rtgui_widget_rect_to_device(RTGUI_WIDGET(container),&rect); + rect.x1 += left; + rect.y1 += top; + rect.x2 = rect.x1+w; + rect.y2 = rect.y1+h; + rtgui_widget_set_rect(RTGUI_WIDGET(edit),&rect); + rtgui_container_add_child(container, RTGUI_WIDGET(edit)); + + /* set character number */ + edit->item_height = edit->font_height; /* the same height */ + effe = h-(edit->margin + RTGUI_WIDGET_BORDER(edit))*2; + edit->row_per_page = effe / edit->item_height; + if(effe % edit->item_height) + edit->row_per_page += 1; + + effe = w-(edit->margin + RTGUI_WIDGET_BORDER(edit))*2; + edit->col_per_page = effe / edit->font_width; + if(effe % edit->font_width) + edit->col_per_page += 1; + edit->update_buf = rtgui_malloc(edit->col_per_page + 1); + +#ifdef RTGUI_EDIT_USING_SCROLL + if(edit->hscroll == RT_NULL && edit->flag & RTGUI_EDIT_HSCROLL) + { + /* create horizontal scrollbar */ + rt_uint32_t _left,_top,_width=RTGUI_DEFAULT_SB_WIDTH,_len; + _left = RTGUI_WIDGET_BORDER(edit); + _top = rtgui_rect_height(rect)-RTGUI_WIDGET_BORDER(edit)-_width; + _len = rtgui_rect_width(rect)-RTGUI_WIDGET_BORDER(edit)*2; + if(edit->max_rows > edit->row_per_page) _len -= _width; + + edit->hscroll = rtgui_scrollbar_create(edit,_left,_top,_width,_len,RTGUI_HORIZONTAL); + + if(edit->hscroll != RT_NULL) + { + edit->hscroll->widget_link = (pvoid)edit; + edit->hscroll->on_scroll = rtgui_edit_hscroll_handle; + RTGUI_WIDGET_HIDE(edit->hscroll); + } + } + if(edit->vscroll == RT_NULL && edit->flag & RTGUI_EDIT_VSCROLL) + { + /* create vertical scrollbar */ + rt_uint32_t _left,_top,_width=RTGUI_DEFAULT_SB_WIDTH,_len; + _left = rtgui_rect_width(rect)-RTGUI_WIDGET_BORDER(edit)-_width; + _top = RTGUI_WIDGET_BORDER(edit); + _len = rtgui_rect_height(rect)-RTGUI_WIDGET_BORDER(edit)*2; + if(edit->max_cols > edit->col_per_page) _len -= _width; + + edit->vscroll = rtgui_scrollbar_create(edit,_left,_top,_width,_len,RTGUI_VERTICAL); + + if(edit->vscroll != RT_NULL) + { + edit->vscroll->widget_link = (pvoid)edit; + edit->vscroll->on_scroll = rtgui_edit_vscroll_handle; + RTGUI_WIDGET_HIDE(edit->vscroll); + } + } +#endif + } + + return edit; +} + +void rtgui_edit_destroy(struct rtgui_edit* edit) +{ + rtgui_widget_destroy(RTGUI_WIDGET(edit)); +} + +/** + * calc line buffer alloc length + * + * @param n a standard buffer value, please use edit->bzsize + * @param m given a reference value + * + * @return get a proper standard values + */ +rt_inline rt_size_t rtgui_edit_alloc_len(rt_size_t n, rt_size_t m) +{ + if(n > m) return n; +#ifndef RTGUI_USING_SMALL_SIZE + return rtgui_edit_alloc_len(n*2, m); +#else + return rtgui_edit_alloc_len(n+16, m); +#endif +} + +/** + * please use it to replace rt_strlen + * especially in reading the source file. + */ +rt_inline rt_size_t rtgui_edit_line_strlen(const char *s) +{ + const char *sc; + /* ascii text end of 0x0A or 0x0D-0x0A*/ + for(sc = s; *sc != 0x0D && *sc != 0x0A && *sc != 0x00; ++sc); + return sc - s; +} + +rt_bool_t rtgui_edit_append_line(struct rtgui_edit* edit, const char *text) +{ + rt_size_t len; + struct edit_line *line, *node; + + RT_ASSERT(edit != RT_NULL); + + line = rtgui_malloc(sizeof(struct edit_line)); + if(line == RT_NULL) return RT_FALSE; + + len = rtgui_edit_line_strlen(text); + line->zsize = rtgui_edit_alloc_len(edit->bzsize, len+1); + line->text = rtgui_malloc(line->zsize); + rt_memcpy(line->text, text, len); + *(line->text+len) = '\0'; + line->len = rtgui_edit_line_strlen(line->text); + + line->next = RT_NULL; + edit->max_rows++; + if(edit->max_cols < len) edit->max_cols = len; + + node = edit->head; + if(node == RT_NULL) + { + edit->head = line; + edit->tail = line; + line->prev = RT_NULL; + return RT_TRUE; + } + while(node->next != RT_NULL) node = node->next; + /* to tail item on to queue */ + node->next = line; + line->prev = node; + /* re-fixed position tail */ + edit->tail = line; + + return RT_TRUE; +} + +rt_bool_t rtgui_edit_insert_line(struct rtgui_edit *edit, struct edit_line *p, char *text) +{ + rt_size_t len; + struct edit_line *line; + + RT_ASSERT(edit != RT_NULL); + RT_ASSERT(p != RT_NULL); + + if(p->next == RT_NULL) + { + rtgui_edit_append_line(edit, text); + return RT_TRUE; + } + + line = rtgui_malloc(sizeof(struct edit_line)); + if(line == RT_NULL) return RT_FALSE; + + line->prev = p; + line->next = p->next; + p->next = line; + if(line->next != RT_NULL) + { + line->next->prev = line; + } + + len = rtgui_edit_line_strlen(text); + line->zsize = rtgui_edit_alloc_len(edit->bzsize, len+1); + + line->text = rtgui_malloc(line->zsize); + rt_memset(line->text, 0, line->zsize); + rt_memcpy(line->text, text, len); + *(line->text+len) = '\0'; + + edit->max_rows ++; + line->len = rtgui_edit_line_strlen(line->text); + + return RT_TRUE; +} + +rt_bool_t rtgui_edit_delete_line(struct rtgui_edit* edit, struct edit_line *line) +{ + RT_ASSERT(edit != RT_NULL); + RT_ASSERT(line != RT_NULL); + + if(edit->max_rows == 0) return RT_FALSE; + + if(line->prev == RT_NULL) + { + if(line->next == RT_NULL) + { + /* only one item */ + edit->head = RT_NULL; + edit->tail = RT_NULL; + } + else + { + /* first item */ + line->next->prev = RT_NULL; + edit->head = line->next; + } + } + else + { + if(line->next == RT_NULL) + { + /* last item */ + line->prev->next = RT_NULL; + edit->tail = line->prev; + } + else + { + /* middle item */ + line->prev->next = line->next; + line->next->prev = line->prev; + } + } + + if(edit->max_rows > 0)edit->max_rows--; + if(line->text) + { + rtgui_free(line->text); + line->text = RT_NULL; + } + rtgui_free(line); + line = RT_NULL; + + return RT_TRUE; +} + +rt_bool_t rtgui_edit_connect_line(struct rtgui_edit* edit, struct edit_line *line, struct edit_line *connect) +{ + rt_size_t len1,len2; + + RT_ASSERT(edit != RT_NULL); + RT_ASSERT(line != RT_NULL); + RT_ASSERT(connect != RT_NULL); + + len1 = rtgui_edit_line_strlen(line->text); + len2 = rtgui_edit_line_strlen(connect->text); + + line->zsize = rtgui_edit_alloc_len(edit->bzsize, len1+len2+1); + line->text = rt_realloc(line->text, line->zsize); + rt_memcpy(line->text+len1, connect->text, len2); + *(line->text+len1+len2) = '\0'; + + line->len = rtgui_edit_line_strlen(line->text); + return RT_TRUE; +} + +static void rtgui_edit_get_caret_rect(struct rtgui_edit *edit, rtgui_rect_t *rect, rtgui_point_t visual) +{ + RT_ASSERT(edit != RT_NULL); + + rtgui_widget_get_rect(RTGUI_WIDGET(edit), rect); + + rect->x1 += visual.x * edit->font_width + RTGUI_WIDGET_BORDER(edit) + edit->margin; + rect->x2 = rect->x1+1; /* caret width: 1 */ + rect->y1 += visual.y * edit->item_height + RTGUI_WIDGET_BORDER(edit) + edit->margin; + if((rect->y1 + edit->font_height) < (rect->y2 - RTGUI_WIDGET_BORDER(edit) - edit->margin)) + rect->y2 = rect->y1 + edit->font_height; + else + rect->y2 = rect->y2 - RTGUI_WIDGET_BORDER(edit) - edit->margin; +} + +static void rtgui_edit_init_caret(struct rtgui_edit *edit, rtgui_point_t visual) +{ + struct rtgui_graphic_driver *hw_driver = rtgui_graphic_driver_get_default(); + int x, y; + rtgui_color_t color; + rtgui_rect_t rect; + int ofs=0; + + RT_ASSERT(edit != RT_NULL); + if(!RTGUI_WIDGET_IS_FOCUSED(edit)) return; + + rtgui_edit_get_caret_rect(edit, &edit->caret_rect, visual); + rect = edit->caret_rect; + rtgui_widget_rect_to_device(RTGUI_WIDGET(edit), &rect); + + if(edit->caret == RT_NULL) + edit->caret = (rtgui_color_t*)rtgui_malloc(rtgui_rect_width(rect) * rtgui_rect_height(rect)*sizeof(rtgui_color_t)); + rtgui_timer_stop(edit->caret_timer); + + for(x=rect.x1; xops->get_pixel(&color,x,y); + *(edit->caret + ofs++) = color; + } + } + + rtgui_timer_start(edit->caret_timer); +} + +/* draw caret */ +static void rtgui_edit_draw_caret(struct rtgui_edit *edit) +{ + int x,y; + rtgui_color_t color; + rtgui_rect_t rect; + int ofs=0; + struct rtgui_dc *dc; + + RT_ASSERT(edit != RT_NULL); + if(edit->caret == RT_NULL) return; + + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(edit)); + if(dc == RT_NULL)return; + + rect = edit->caret_rect; + + for(x=rect.x1; xcaret + ofs); + ofs++; + if(edit->flag & RTGUI_EDIT_CARET) + { + color = ~color; + rtgui_dc_draw_color_point(dc, x,y, color); + } + else + { + rtgui_dc_draw_color_point(dc, x,y, color); + } + } + } + + rtgui_dc_end_drawing(dc); +} + +static void rtgui_edit_timeout(struct rtgui_timer* timer, void* parameter) +{ + struct rtgui_edit* edit; + + edit = RTGUI_EDIT(parameter); + /* set caret flag */ + if(edit->flag & RTGUI_EDIT_CARET) + edit->flag &= ~RTGUI_EDIT_CARET; + else + edit->flag |= RTGUI_EDIT_CARET; + + rtgui_edit_draw_caret(edit); + + return; +} + +struct edit_line* rtgui_edit_get_line_by_index(struct rtgui_edit *edit, rt_uint32_t index) +{ + struct edit_line *line = RT_NULL; + + RT_ASSERT(edit != RT_NULL); + + if(edit->head != RT_NULL) + { + int i=0; + line = edit->first_line; + while(line) + { + if((edit->upleft.y + i++) == index) + break; + line = line->next; + } + } + return line; +} + +rt_uint32_t rtgui_edit_get_index_by_line(struct rtgui_edit *edit, struct edit_line *line) +{ + rt_uint32_t index=0; + struct edit_line *tmp; + + RT_ASSERT(edit != RT_NULL); + RT_ASSERT(line != RT_NULL); + + if(edit->head != RT_NULL) + { + tmp = edit->first_line; + index = edit->upleft.y; + while(tmp) + { + if(tmp == line) + break; + index ++; + tmp = tmp->next; + } + } + return index; +} + +static void rtgui_edit_onmouse(struct rtgui_edit* edit, struct rtgui_event_mouse* emouse) +{ + rtgui_rect_t rect; + + RT_ASSERT(edit != RT_NULL); + RT_ASSERT(emouse != RT_NULL); + + rtgui_widget_get_rect(RTGUI_WIDGET(edit), &rect); + if((rtgui_region_contains_point(&(RTGUI_WIDGET(edit)->clip), emouse->x, emouse->y, &rect) == RT_EOK)) + { + rt_uint16_t x, y; + + /* multiline text */ + x = (emouse->x - rect.x1) / (edit->font_width); + y = (emouse->y - rect.y1) / (edit->item_height); + if((x < edit->col_per_page) && (y < edit->row_per_page)) + { + if(emouse->button & RTGUI_MOUSE_BUTTON_DOWN) + { + struct edit_line *line; + + edit->visual.x = x; + edit->visual.y = y; + + line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->visual.y); + if(line == RT_NULL) + return; + + if(edit->visual.x > line->len) + edit->visual.x = line->len; + + if(edit->flag & RTGUI_EDIT_CARET) + { + if(edit->caret_timer != RT_NULL) + rtgui_timer_stop(edit->caret_timer); + + edit->flag &= ~RTGUI_EDIT_CARET; + rtgui_edit_draw_caret(edit); + + if(edit->caret_timer != RT_NULL) + rtgui_timer_start(edit->caret_timer); + } + + /* set widget focus */ + rtgui_widget_focus(RTGUI_WIDGET(edit)); + + if(RTGUI_WIDGET_IS_FOCUSED(edit)) + { + rtgui_edit_init_caret(edit, edit->visual); + edit->flag |= RTGUI_EDIT_CARET; + rtgui_edit_draw_caret(edit); + } + } + else if(emouse->button & RTGUI_MOUSE_BUTTON_UP) + { + /* please add codes at here. */ + } +#ifdef RTGUI_EDIT_USING_SCROLL + if(edit->vscroll && !RTGUI_WIDGET_IS_HIDE(edit)) + { + if(!RTGUI_WIDGET_IS_HIDE(edit->vscroll)) + rtgui_scrollbar_set_value(edit->vscroll,edit->upleft.y); + } + if(edit->hscroll && !RTGUI_WIDGET_IS_HIDE(edit)) + { + if(!RTGUI_WIDGET_IS_HIDE(edit->hscroll)) + rtgui_scrollbar_set_value(edit->hscroll,edit->upleft.x); + } +#endif + } + } +} + +rt_inline rt_uint16_t query_shift_code(rt_uint16_t key) +{ + if(key >= RTGUIK_a && key <= RTGUIK_z) + return (key - ('a'-'A')); + else + { + switch (key) + { + case '1': return '!'; + case '2': return '@'; + case '3': return '#'; + case '4': return '$'; + case '5': return '%'; + case '6': return '^'; + case '7': return '&'; + case '8': return '*'; + case '9': return '('; + case '0': return ')'; + case '-': return '_'; + case '=': return '+'; + case '\\':return '|'; + case ';': return ':'; + case '\'':return '"'; + case ',': return '<'; + case '.': return '>'; + case '/': return '?'; + case '`': return '~'; + } + } + return key; +} + +rt_inline rt_uint16_t query_caps_code(rt_uint16_t key) +{ + if(key >= RTGUIK_a && key <= RTGUIK_z) + return (key - ('a'-'A')); + return key; +} + +rt_inline rt_bool_t is_small_keyboard(rt_uint16_t *key) +{ + if(*key >= RTGUIK_KP0 && *key <= RTGUIK_KP9) + { + *key = *key - (RTGUIK_KP0 - RTGUIK_0); + return RT_TRUE; + } + else if(*key == RTGUIK_KP_PERIOD) + { + *key = '.'; + return RT_TRUE; + } + else if(*key == RTGUIK_KP_DIVIDE) + { + *key = '/'; + return RT_TRUE; + } + else if(*key == RTGUIK_KP_MULTIPLY) + { + *key = '*'; + return RT_TRUE; + } + else if(*key == RTGUIK_KP_MINUS) + { + *key = '-'; + return RT_TRUE; + } + else if(*key == RTGUIK_KP_PLUS) + { + *key = '+'; + return RT_TRUE; + } + else if(*key == RTGUIK_KP_ENTER) + { + *key = RTGUIK_RETURN; + return RT_TRUE; + } + return RT_FALSE; +} + +void kbd_event_set_key(struct rtgui_event_kbd *ekbd, rt_uint16_t key) +{ + RTGUI_EVENT_KBD_INIT(ekbd); + ekbd->mod = RTGUI_KMOD_NONE; + ekbd->unicode = 0; + + ekbd->key = key; + ekbd->type = RTGUI_KEYDOWN; +} + +static rt_bool_t rtgui_edit_onkey(struct rtgui_object* object, rtgui_event_t* event) +{ + enum { EDIT_NONE, EDIT_ONDRAW, EDIT_UPDATE }; + struct rtgui_edit *edit = RTGUI_EDIT(object); + struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd*)event; + struct edit_line *line=RT_NULL; + rt_bool_t update_type = EDIT_NONE; + + RT_ASSERT(edit != RT_NULL); + RT_ASSERT(ekbd != RT_NULL); + + if (RTGUI_KBD_IS_UP(ekbd)) + { /* reset function key */ + if(ekbd->key == RTGUIK_RCTRL || ekbd->key == RTGUIK_LCTRL) + edit->flag &= ~RTGUI_EDIT_CTRL; + else if(ekbd->key == RTGUIK_RALT || ekbd->key == RTGUIK_LALT) + edit->flag &= ~RTGUI_EDIT_ALT; + else if(ekbd->key == RTGUIK_RSHIFT || ekbd->key == RTGUIK_LSHIFT) + edit->flag &= ~RTGUI_EDIT_SHIFT; + else if(ekbd->key == RTGUIK_CAPSLOCK) + edit->flag &= ~RTGUI_EDIT_CAPSLOCK; + else if(ekbd->key == RTGUIK_NUMLOCK) + edit->flag &= ~RTGUI_EDIT_NUMLOCK; + return RT_TRUE; + } + + line = rtgui_edit_get_line_by_index(edit, edit->upleft.y + edit->visual.y); + if(line == RT_NULL) + return RT_FALSE; + + /* rt_kprintf("key=%04X ",ekbd->key); */ + if(ekbd->key == RTGUIK_RCTRL || ekbd->key == RTGUIK_LCTRL) + { /* use CTRL key */ + edit->flag |= RTGUI_EDIT_CTRL; + return RT_FALSE; + } + else if(ekbd->key == RTGUIK_RALT || ekbd->key == RTGUIK_LALT) + { /* use ALT key */ + edit->flag |= RTGUI_EDIT_ALT; + return RT_FALSE; + } + else if(ekbd->key == RTGUIK_RSHIFT || ekbd->key == RTGUIK_LSHIFT) + { /* use SHIFT key */ + edit->flag |= RTGUI_EDIT_SHIFT; + return RT_FALSE; + } + else if(ekbd->key == RTGUIK_CAPSLOCK) + { + edit->flag |= RTGUI_EDIT_CAPSLOCK; + return RT_FALSE; + } + else if(ekbd->key == RTGUIK_NUMLOCK) + { + edit->flag |= RTGUI_EDIT_NUMLOCK; + return RT_FALSE; + } + else if(ekbd->key == RTGUIK_DELETE) + { /* delete latter character */ + int ofs = edit->upleft.x + edit->visual.x; + if(ofs > line->len - 1 || (ofs==0 && line->len==0)) + { /* will the next line marges into the current line */ + struct edit_line* next_line = line->next; + if(next_line != RT_NULL) + { + struct edit_line *update_end_line; + + update_type = EDIT_UPDATE; + edit->update.start = edit->visual; + + rtgui_edit_connect_line(edit, line, next_line); + rtgui_edit_delete_line(edit, next_line); + + if(edit->max_rows-edit->upleft.y > edit->row_per_page) + { + update_end_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->row_per_page); + if(update_end_line != RT_NULL) + { + edit->update.end.x = edit->col_per_page; + edit->update.end.y = edit->upleft.y + edit->row_per_page; + } + } + else + { + int update_end_index = rtgui_edit_get_index_by_line(edit, edit->tail); + edit->update.end.x = edit->col_per_page; + edit->update.end.y = update_end_index+1; + } + } + line->len = rtgui_edit_line_strlen(line->text); + goto _edit_exit; + } + else if(ofs == line->len - 1) + { + line->text[ofs] = '\0'; + } + else + { + char *c; + /* remove character */ + for(c = &line->text[ofs]; c[1] != '\0'; c++) + *c = c[1]; + *c = '\0'; + } + update_type = EDIT_UPDATE; + edit->update.start = edit->visual; + edit->update.end.x = line->len-edit->upleft.x; + if (edit->update.end.x > edit->col_per_page) + edit->update.end.x = edit->col_per_page; + edit->update.end.y = edit->visual.y; + } + else if(ekbd->key == RTGUIK_BACKSPACE) + { + if(edit->visual.x == 0) + { /* incorporated into prev line */ + struct rtgui_event_kbd event_kbd; + struct edit_line* prev_line = line->prev; + if(prev_line != RT_NULL) + { + struct edit_line *update_end_line; + + update_type = EDIT_UPDATE; + edit->visual.x = prev_line->len; + + rtgui_edit_connect_line(edit, prev_line, line); + kbd_event_set_key(&event_kbd, RTGUIK_UP); + rtgui_edit_onkey(object, (rtgui_event_t*)&event_kbd); + rtgui_edit_delete_line(edit, line); + + edit->update.start = edit->visual; /* update.start.y is changed */ + if(edit->max_rows-edit->upleft.y > edit->row_per_page) + { + update_end_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->row_per_page); + if(update_end_line != RT_NULL) + { + edit->update.end.x = edit->col_per_page; + edit->update.end.y = edit->upleft.y + edit->row_per_page; + } + } + else + { + int update_end_index = rtgui_edit_get_index_by_line(edit, edit->tail); + edit->update.end.x = edit->col_per_page; + edit->update.end.y = update_end_index+1; + } + } + goto _edit_exit; + } + + /* delete front character */ + if(edit->visual.x == line->len) + { + line->text[edit->visual.x-1] = '\0'; + edit->visual.x --; + } + else if(edit->visual.x != 0) + { /* remove current character */ + char *c; + /* remove character */ + for(c = &line->text[edit->visual.x - 1]; c[1] != '\0'; c++) + { + *c = c[1]; + } + *c = '\0'; + edit->visual.x --; + } + /* adjusted line buffer length */ + if(rtgui_edit_alloc_len(edit->bzsize, line->len+2) < line->zsize) + { + line->zsize = rtgui_edit_alloc_len(edit->bzsize, line->len+1); + line->text = rt_realloc(line->text, line->zsize); + } + update_type = EDIT_UPDATE; + edit->update.start = edit->visual; + edit->update.end.x = line->len; + edit->update.end.y = edit->visual.y; + } + else if(ekbd->key == RTGUIK_UP) + { /* move to prev line */ + struct edit_line* prev_line; + if(edit->visual.y > 0) + edit->visual.y --; + else + { + /* change first row */ + if(edit->upleft.y > 0) + { + edit->upleft.y --; + if(edit->first_line->prev != RT_NULL) + edit->first_line = edit->first_line->prev; + update_type = EDIT_ONDRAW; + } + } + + /* The position of the recount X */ + prev_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->visual.y); + if(prev_line == RT_NULL) + return RT_FALSE; + + if(edit->upleft.x > 0) + { + if(prev_line->len <= edit->upleft.x) + { + edit->upleft.x = 0; + edit->visual.x = prev_line->len; + update_type = EDIT_ONDRAW; + } + else if(prev_line->len - edit->upleft.x < edit->col_per_page) + edit->visual.x = prev_line->len - edit->upleft.x; + } + else if(edit->visual.x > prev_line->len) + edit->visual.x = prev_line->len; + +#ifdef RTGUI_EDIT_USING_SCROLL + /* update vscroll */ + if(edit->vscroll && !RTGUI_WIDGET_IS_HIDE(edit)) + { + if(!RTGUI_WIDGET_IS_HIDE(edit->vscroll)) + rtgui_scrollbar_set_value(edit->vscroll,edit->upleft.y); + } +#endif + } + else if(ekbd->key == RTGUIK_DOWN) + { + struct edit_line *tail_line, *next_line; + tail_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y + edit->visual.y); + if(tail_line != RT_NULL) + { /* it is tail line */ + if(tail_line == edit->tail) return RT_FALSE; + } + /* move to next line */ + if(edit->visual.y < edit->row_per_page - 2) + { + edit->visual.y ++; + } + else if(edit->visual.y+edit->upleft.y < edit->max_rows-1) + { + /* change first row */ + edit->upleft.y++; + if(edit->first_line->next != RT_NULL) + edit->first_line = edit->first_line->next; + update_type = EDIT_ONDRAW; + } + + /* adjust next line end position */ + next_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->visual.y); + if(next_line == RT_NULL) + return RT_FALSE; + + if(edit->upleft.x > 0) + { + if(next_line->len <= edit->upleft.x) + { + edit->upleft.x = 0; + edit->visual.x = next_line->len; + update_type = EDIT_ONDRAW; + } + else if(next_line->len - edit->upleft.x < edit->col_per_page) + edit->visual.x = next_line->len - edit->upleft.x; + } + else if(edit->visual.x > next_line->len) + edit->visual.x = next_line->len; + +#ifdef RTGUI_EDIT_USING_SCROLL + /* update vscroll */ + if(edit->vscroll && !RTGUI_WIDGET_IS_HIDE(edit)) + { + if(!RTGUI_WIDGET_IS_HIDE(edit->vscroll)) + rtgui_scrollbar_set_value(edit->vscroll,edit->upleft.y); + } +#endif + } + else if(ekbd->key == RTGUIK_LEFT) + { /* move to prev char */ + if(edit->visual.x > 0) + edit->visual.x --; + else + { + if(edit->upleft.x > 0) + { + edit->upleft.x --; + update_type = EDIT_ONDRAW; + } + else + { + struct rtgui_event_kbd event_kbd; + struct edit_line* first_line; + first_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y + edit->visual.y); + if(first_line != RT_NULL) + { /* it is head line */ + if(first_line == edit->head) return RT_FALSE; + } + /* move the caret to the prev line end */ + kbd_event_set_key(&event_kbd, RTGUIK_UP); + rtgui_edit_onkey(object, (rtgui_event_t*)&event_kbd); + kbd_event_set_key(&event_kbd, RTGUIK_END); + rtgui_edit_onkey(object, (rtgui_event_t*)&event_kbd); + } + } + } + else if(ekbd->key == RTGUIK_RIGHT) + { /* move to next char */ + if(line->len >= edit->col_per_page) + { + if(edit->upleft.x+edit->col_per_page <= line->len) + { + if(edit->visual.x < edit->col_per_page-1) + edit->visual.x ++; + else if(edit->visual.x == edit->col_per_page-1) + { + if(edit->upleft.x+edit->col_per_page < line->len) + edit->upleft.x ++; + else + edit->upleft.x = line->len - edit->col_per_page + 1; + update_type = EDIT_ONDRAW; + } + } + else + { + struct rtgui_event_kbd event_kbd; + /* move to next head */ + kbd_event_set_key(&event_kbd, RTGUIK_DOWN); + rtgui_edit_onkey(object, (rtgui_event_t*)&event_kbd); + kbd_event_set_key(&event_kbd, RTGUIK_HOME); + rtgui_edit_onkey(object, (rtgui_event_t*)&event_kbd); + } + } + else + { + if(edit->visual.x < line->len) + edit->visual.x ++; + else + { + struct rtgui_event_kbd event_kbd; + struct edit_line* tail_line; + tail_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y + edit->visual.y); + if(tail_line != RT_NULL) + { /* it is tail line */ + if(tail_line == edit->tail) return RT_FALSE; + } + /* move the caret to the next line head */ + kbd_event_set_key(&event_kbd, RTGUIK_DOWN); + rtgui_edit_onkey(object, (rtgui_event_t*)&event_kbd); + kbd_event_set_key(&event_kbd, RTGUIK_HOME); + rtgui_edit_onkey(object, (rtgui_event_t*)&event_kbd); + } + } + } + else if(ekbd->key == RTGUIK_HOME) + { /* move cursor to line head */ + edit->visual.x = 0; + if(edit->upleft.x > 0) + { + edit->upleft.x = 0; + update_type = EDIT_ONDRAW; + } + } + else if(ekbd->key == RTGUIK_END) + { /* move cursor to line tail */ + if(line->len >= edit->col_per_page) + { + edit->visual.x = edit->col_per_page - 1; + edit->upleft.x = line->len - (edit->col_per_page-1); + update_type = EDIT_ONDRAW; + } + else + edit->visual.x = line->len; + } + else if(ekbd->key == RTGUIK_TAB) + { + int space_nums; + struct rtgui_event_kbd event_kbd; + /* using spaces to replace TAB */ + space_nums = edit->tabsize - (edit->upleft.x+edit->visual.x) % edit->tabsize; + while(space_nums--) + { + kbd_event_set_key(&event_kbd, RTGUIK_SPACE); + rtgui_edit_onkey(object, (rtgui_event_t*)&event_kbd); + } + } + else if(ekbd->key == RTGUIK_RETURN) + { + struct edit_line *update_end_line; + struct rtgui_event_kbd event_kbd; + + update_type = EDIT_UPDATE; + edit->update.start = edit->visual; + + /* insert a new line buffer */ + rtgui_edit_insert_line(edit, line, line->text + edit->upleft.x + edit->visual.x); + line->text[edit->upleft.x + edit->visual.x] = '\0'; + line->len = rtgui_edit_line_strlen(line->text); + + /* adjust update line end position */ + if((edit->max_rows-edit->upleft.y) >= edit->row_per_page) + { + update_end_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->row_per_page-1); + if(update_end_line != RT_NULL) + { + edit->update.end.x = update_end_line->len; + edit->update.end.y = edit->upleft.y + edit->row_per_page; + } + } + else + { + int update_end_index = rtgui_edit_get_index_by_line(edit, edit->tail); + edit->update.end.x = edit->tail->len; + edit->update.end.y = update_end_index; + } + + /* move the caret to the next line head */ + kbd_event_set_key(&event_kbd, RTGUIK_DOWN); + rtgui_edit_onkey(object, (rtgui_event_t*)&event_kbd); + kbd_event_set_key(&event_kbd, RTGUIK_HOME); + rtgui_edit_onkey(object, (rtgui_event_t*)&event_kbd); + } + else + { + if(isprint(ekbd->key)) + { /* it's may print character */ + update_type = EDIT_UPDATE; + edit->update.start = edit->visual; + + if(edit->flag & RTGUI_EDIT_SHIFT) + ekbd->key = query_shift_code(ekbd->key); + if(edit->flag & RTGUI_EDIT_CAPSLOCK) + ekbd->key = query_caps_code(ekbd->key); + + if(line->len < line->zsize-1) + { + int ofs = edit->upleft.x + edit->visual.x; + if(edit->visual.x >= edit->col_per_page-1) + { + edit->upleft.x ++; + update_type = EDIT_ONDRAW; + } + + if(ofs < line->len) + { + char* c; + for(c = &line->text[line->len]; c != &line->text[ofs]; c--) + *c = *(c-1); + } + line->text[ofs] = ekbd->key; + if(edit->visual.x < edit->col_per_page-1) + edit->visual.x ++; + line->text[line->len+1] = '\0'; + line->len = rtgui_edit_line_strlen(line->text); + edit->update.end.x = line->len; + if(edit->update.end.x > edit->col_per_page) + edit->update.end.x = edit->col_per_page; + edit->update.end.y = edit->visual.y; + } + else + { /* adjust line buffer's zone size */ + line->zsize = rtgui_edit_alloc_len(edit->bzsize, line->len+1); + line->text = rt_realloc(line->text, line->zsize); + rtgui_edit_onkey(object, event); /* reentry */ + } + } + else + { + /* Is small keyboard ? */ + if(edit->flag & RTGUI_EDIT_NUMLOCK) + { + if(is_small_keyboard(&ekbd->key)) + rtgui_edit_onkey(object, event); + /* small keyboard another value reserved */ + } + } + } + line->len = rtgui_edit_line_strlen(line->text); + +_edit_exit: + if(edit->flag & RTGUI_EDIT_CARET) + { + if(edit->caret_timer != RT_NULL) + rtgui_timer_stop(edit->caret_timer); + + edit->flag &= ~RTGUI_EDIT_CARET; + rtgui_edit_draw_caret(edit);/* refresh it */ + if(edit->caret_timer != RT_NULL) + rtgui_timer_start(edit->caret_timer); + } + + /* re-draw edit widget */ + if(update_type == EDIT_ONDRAW) + rtgui_edit_ondraw(edit); + else if(update_type == EDIT_UPDATE) + rtgui_edit_update(edit); + + if(RTGUI_WIDGET_IS_FOCUSED(edit)) + { + rtgui_edit_init_caret(edit, edit->visual); + edit->flag |= RTGUI_EDIT_CARET; + rtgui_edit_draw_caret(edit); + } + return RT_TRUE; +} + +static rt_bool_t rtgui_edit_onfocus(struct rtgui_object* object, rtgui_event_t* event) +{ + struct rtgui_edit* edit = RTGUI_EDIT(object); + + edit->caret_timer = rtgui_timer_create(50, RT_TIMER_FLAG_PERIODIC, + rtgui_edit_timeout, (void*)edit); + /* set caret to show */ + edit->flag |= RTGUI_EDIT_CARET; + /* start caret timer */ + if(edit->caret_timer != RT_NULL) + rtgui_timer_start(edit->caret_timer); + + return RT_TRUE; +} + +static rt_bool_t rtgui_edit_onunfocus(struct rtgui_object* object, rtgui_event_t* event) +{ + struct rtgui_edit* edit = RTGUI_EDIT(object); + + /* stop caret timer */ + if(edit->caret_timer != RT_NULL) + { + rtgui_timer_stop(edit->caret_timer); + rtgui_timer_destory(edit->caret_timer); + } + /* set caret to hide */ + edit->flag &= ~RTGUI_EDIT_CARET; + rtgui_edit_draw_caret(edit); + + return RT_TRUE; +} + +#ifdef RTGUI_EDIT_USING_SCROLL +static rt_bool_t rtgui_edit_hscroll_handle(struct rtgui_widget* widget, rtgui_event_t* event) +{ + struct rtgui_edit *edit = RTGUI_EDIT(widget); + + /* adjust first display row when dragging */ + edit->upleft.y = edit->hscroll->value; + + rtgui_edit_ondraw(edit); + + return RT_TRUE; +} + +static rt_bool_t rtgui_edit_vscroll_handle(struct rtgui_widget* widget, rtgui_event_t* event) +{ + struct rtgui_edit *edit = RTGUI_EDIT(widget); + + /* adjust first display row when dragging */ + edit->upleft.x = edit->vscroll->value; + + rtgui_edit_ondraw(edit); + + return RT_TRUE; +} +#endif + +/* local area update */ +void rtgui_edit_update(struct rtgui_edit *edit) +{ + rt_uint32_t i,cpy_len=0,prev_len; + rtgui_rect_t rect, r; + struct rtgui_dc *dc; + char *src; + + RT_ASSERT(edit != RT_NULL); + + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(edit)); + if(dc == RT_NULL) return; + + rtgui_widget_get_rect(RTGUI_WIDGET(edit), &rect); + rtgui_rect_inflate(&rect, -(edit->margin + RTGUI_WIDGET_BORDER(edit))); + + if(edit->update_buf == RT_NULL) + { /* try again allocate */ + edit->update_buf = rtgui_malloc(edit->col_per_page+1); + } + + prev_len = edit->col_per_page; + for(i=edit->update.start.y; i<=edit->update.end.y; i++) + { + struct edit_line *line = rtgui_edit_get_line_by_index(edit, edit->upleft.y + i); + + if(i > edit->upleft.y+edit->row_per_page) break; + if(line == RT_NULL) + { /* when use "RTGUIK_BACKSPACE" backspace forward, + * the last line is blank, that only fill background. */ + r.x1 = rect.x1; + r.x2 = rect.x1 + prev_len * edit->font_width; + r.y1 = rect.y1 + i * edit->font_height; + r.y2 = r.y1 + edit->font_height; + if(r.x2 > rect.x2) r.x2 = rect.x2; + if(r.y2 > rect.y2) r.y2 = rect.y2; + rtgui_dc_fill_rect(dc, &r); + break; + } + + if(edit->update.start.y == edit->update.end.y) + { + r.x1 = rect.x1 + edit->update.start.x * edit->font_width; + r.x2 = rect.x1 + edit->update.end.x * edit->font_width; + r.y1 = rect.y1 + i * edit->font_height; + r.y2 = r.y1 + edit->font_height; + cpy_len = edit->update.end.x - edit->update.start.x; + src = line->text + edit->update.start.x + edit->upleft.x; + } + else + { + if(i == edit->update.start.y) + { + r.x1 = rect.x1 + edit->update.start.x * edit->font_width; + r.x2 = rect.x2; + r.y1 = rect.y1 + i * edit->font_height; + r.y2 = r.y1 + edit->font_height; + cpy_len = line->len - edit->update.start.x - edit->upleft.x; + if(cpy_len > (edit->col_per_page-edit->update.start.x)) + cpy_len = edit->col_per_page-edit->update.start.x; + src = line->text + edit->update.start.x + edit->upleft.x; + } + else if(i == edit->update.end.y) + { + r.x1 = rect.x1; + r.x2 = rect.x1 + edit->update.end.x * edit->font_width; + cpy_len = edit->update.end.x; + r.y1 = rect.y1 + i * edit->font_height; + r.y2 = r.y1 + edit->font_height; + src = line->text + edit->upleft.x; + } + else + { + r.x1 = rect.x1; + r.x2 = rect.x2; + r.y1 = rect.y1 + i * edit->font_height; + r.y2 = r.y1 + edit->font_height; + cpy_len = line->len - edit->upleft.x; + if(cpy_len > edit->col_per_page) + cpy_len = edit->col_per_page; + src = line->text + edit->upleft.x; + } + } + if(r.y1 > rect.y2) break; + if(r.x2 > rect.x2) r.x2 = rect.x2; + if(r.y2 > rect.y2) r.y2 = rect.y2; + + rt_memcpy(edit->update_buf, src, cpy_len); + *(edit->update_buf + cpy_len) = '\0'; + + rtgui_dc_fill_rect(dc, &r); + rtgui_dc_draw_text(dc, edit->update_buf, &r); + prev_len = line->len; + } + + rtgui_dc_end_drawing(dc); +} + +void rtgui_edit_ondraw(struct rtgui_edit *edit) +{ + rtgui_rect_t rect, r; + struct rtgui_dc *dc; + int hscroll_flag=0; + int vscroll_flag=0; + + RT_ASSERT(edit != RT_NULL); + + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(edit)); + if(dc == RT_NULL) return; + + /* get widget rect */ + rtgui_widget_get_rect(RTGUI_WIDGET(edit), &rect); + rtgui_rect_inflate(&rect, -RTGUI_WIDGET_BORDER(edit)); + + /* fill widget rect with edit background color */ + RTGUI_DC_BC(dc) = RTGUI_WIDGET_BACKGROUND(edit); + rtgui_dc_fill_rect(dc, &rect); + + rtgui_rect_inflate(&rect, RTGUI_WIDGET_BORDER(edit)); + /* draw border */ + rtgui_dc_draw_border(dc, &rect, RTGUI_WIDGET_BORDER_STYLE(edit)); + + rtgui_rect_inflate(&rect, -(edit->margin + RTGUI_WIDGET_BORDER(edit))); + +#ifdef RTGUI_EDIT_USING_SCROLL + if(edit->vscroll && !RTGUI_WIDGET_IS_HIDE(edit->vscroll)) + { + rect.x2 = rect.x2 - rtgui_rect_width(edit->vscroll->parent.extent); + } + if(edit->hscroll && !RTGUI_WIDGET_IS_HIDE(edit->hscroll)) + { + rect.y2 = rect.y2 - rtgui_rect_height(edit->hscroll->parent.extent); + } +#endif + r = rect; + + /* draw text */ + if(edit->head != RT_NULL) + { + struct edit_line *line = edit->first_line; + int num=0; + + rect.y2 = rect.y1 + edit->item_height; + while(line) + { + if(edit->upleft.x < line->len) + rtgui_dc_draw_text(dc, line->text+edit->upleft.x, &rect); + line = line->next; + rect.y1 += edit->item_height; + if((rect.y1 + edit->item_height) < r.y2) + rect.y2 = rect.y1 + edit->item_height; + else + rect.y2 = r.y2; + + if(num++ >= edit->row_per_page) + break; + } + } + +#ifdef RTGUI_EDIT_USING_SCROLL + if(edit->hscroll && !RTGUI_WIDGET_IS_HIDE(edit->hscroll)) + { + hscroll_flag = 1; + rtgui_scrollbar_ondraw(edit->hscroll); + } + if(edit->vscroll && !RTGUI_WIDGET_IS_HIDE(edit->vscroll)) + { + vscroll_flag = 1; + rtgui_scrollbar_ondraw(edit->vscroll); + } + + if(hscroll_flag && vscroll_flag) + { + rtgui_color_t _bc; + rtgui_widget_get_rect(RTGUI_WIDGET(edit), &rect); + rect.x1 = rect.x2-RTGUI_WIDGET_BORDER(edit); + rect.y1 = rect.y2-RTGUI_WIDGET_BORDER(edit); + _bc = RTGUI_DC_BC(dc); + RTGUI_DC_BC(dc) = default_background; + rtgui_dc_fill_rect(dc,&rect); + RTGUI_DC_BC(dc) = _bc; + } +#endif + rtgui_dc_end_drawing(dc); +} + +/* set edit text */ +void rtgui_edit_set_text(struct rtgui_edit* edit, const char* text) +{ + const char *begin, *ptr; + int hscroll_flag=0; + int vscroll_flag=0; + + RT_ASSERT(edit != RT_NULL); + + while(edit->max_rows > 0) + rtgui_edit_delete_line(edit, edit->head); + edit->max_rows = 0; + + begin = text; + for(ptr=begin; *ptr != '\0'; ptr++) + { + if(*ptr == 0x0A) + { /* unix style */ + rtgui_edit_append_line(edit, begin); + begin = ptr+1; + } + else if(*ptr == 0x0D && *(ptr+1) == 0x0A) + { /* windows style */ + rtgui_edit_append_line(edit, begin); + begin = ptr+2; + } + } + if(*ptr == '\0') + { + if(begin < ptr) + rtgui_edit_append_line(edit, begin); + } + edit->first_line = edit->head; + +#ifdef RTGUI_EDIT_USING_SCROLL + if(edit->hscroll != RT_NULL) + { + if(edit->max_cols > edit->col_per_page) + { + RTGUI_WIDGET_SHOW(edit->hscroll); + rtgui_scrollbar_set_line_step(edit->hscroll, 1); + rtgui_scrollbar_set_page_step(edit->hscroll, edit->col_per_page); + rtgui_scrollbar_set_range(edit->hscroll, edit->max_cols); + hscroll_flag = 1; + } + else + { + RTGUI_WIDGET_HIDE(edit->hscroll); + } + } + if(edit->vscroll != RT_NULL) + { + if(edit->max_rows > edit->row_per_page) + { + RTGUI_WIDGET_SHOW(edit->vscroll); + rtgui_scrollbar_set_line_step(edit->vscroll, 1); + rtgui_scrollbar_set_page_step(edit->vscroll, edit->row_per_page); + rtgui_scrollbar_set_range(edit->vscroll, edit->max_rows); + vscroll_flag = 1; + } + else + { + RTGUI_WIDGET_HIDE(edit->vscroll); + } + } + + if(edit->hscroll != RT_NULL && !RTGUI_WIDGET_IS_HIDE(edit->hscroll)) + { + rtgui_edit_adjust_scroll(edit->hscroll); + } + if(edit->vscroll != RT_NULL && !RTGUI_WIDGET_IS_HIDE(edit->vscroll)) + { + rtgui_edit_adjust_scroll(edit->vscroll); + } +#endif + if(hscroll_flag || vscroll_flag) + { + rtgui_widget_update_clip(RTGUI_WIDGET(edit)); + } +} + +rt_bool_t rtgui_edit_event_handler(struct rtgui_object* object, rtgui_event_t* event) +{ + rtgui_widget_t *widget = RTGUI_WIDGET(object); + struct rtgui_edit* edit = RTGUI_EDIT(object); + + switch(event->type) + { + case RTGUI_EVENT_PAINT: +#ifndef RTGUI_USING_SMALL_SIZE + if(widget->on_draw != RT_NULL) + widget->on_draw(object, event); + else +#endif + rtgui_edit_ondraw(edit); + break; + + case RTGUI_EVENT_MOUSE_BUTTON: +#ifndef RTGUI_USING_SMALL_SIZE + if(widget->on_mouseclick != RT_NULL) + widget->on_mouseclick(object, event); + else +#endif + rtgui_edit_onmouse(edit, (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(object, event); + else +#endif + rtgui_edit_onkey(object, event); + return RT_TRUE; + + default: + return rtgui_widget_event_handler(object, event); + } + + return RT_FALSE; +} + +/** + * File access component, General File Access Interface + */ + +rt_bool_t rtgui_edit_readin_file(struct rtgui_edit *edit, const char *filename) +{ + int fd, num=0, read_bytes, size ,len=0; + char *text ,ch; + + fd = open(filename, O_RDONLY, 0); + if (fd < 0) + { + return RT_FALSE; + } + + while(edit->max_rows > 0) + rtgui_edit_delete_line(edit, edit->head); + edit->max_rows = 0; + + size = edit->bzsize; + text = rtgui_malloc(size); + if(text == RT_NULL) return RT_FALSE; + + do { + if ( (read_bytes = read(fd, &ch, 1)) > 0 ) + { + if(num >= size - 1) + text = rt_realloc(text, rtgui_edit_alloc_len(size, num)); + if(ch == 0x09) //Tab + { + len = edit->tabsize - num%edit->tabsize; + while(len--) + *(text + num++) = ' '; + } + else + *(text + num++) = ch; + if(ch == 0x0A) + { + rtgui_edit_append_line(edit, text); + num = 0; + } + + } + } while(read_bytes); + + close(fd); + rtgui_free(text); + rtgui_edit_ondraw(edit); + + return RT_TRUE; +} + +rt_bool_t rtgui_edit_saveas_file(struct rtgui_edit *edit, const char *filename) +{ + int fd; + char ch_tailed = 0x0A; + struct edit_line *line; + + fd = open(filename, O_WRONLY | O_CREAT, 0); + if (fd < 0) + { + return RT_FALSE; + } + + line = edit->head; + while(line) + { + write(fd, line->text, line->len); + if(line != edit->tail) + write(fd, &ch_tailed, 1); + line = line->next; + } + + close(fd); + + return RT_TRUE; +} diff --git a/components/rtgui/widgets/filelist_view.c b/components/rtgui/widgets/filelist_view.c index b3bf93f3e..67c141d45 100644 --- a/components/rtgui/widgets/filelist_view.c +++ b/components/rtgui/widgets/filelist_view.c @@ -260,7 +260,7 @@ static rt_bool_t rtgui_filelist_view_on_folder_item(rtgui_object_t* object, stru dir_ptr = (char*) rtgui_malloc (256); rtgui_filelist_view_get_fullpath(view, dir_ptr, 256); rtgui_filelist_view_set_directory(view, dir_ptr); - rt_free(dir_ptr); + rtgui_free(dir_ptr); } break; case 1: @@ -332,8 +332,8 @@ static void _rtgui_filelist_view_constructor(struct rtgui_filelist_view *view) view->current_directory = RT_NULL; view->pattern = RT_NULL; - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white; - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_BACKGROUND(view) = white; + RTGUI_WIDGET_TEXTALIGN(view) = RTGUI_ALIGN_CENTER_VERTICAL; file_image = rtgui_image_create_from_mem("xpm", (rt_uint8_t*)file_xpm, sizeof(file_xpm), RT_TRUE); @@ -346,8 +346,16 @@ static void _rtgui_filelist_view_destructor(struct rtgui_filelist_view *view) /* delete all file items */ rtgui_filelist_view_clear(view); /* delete current directory and pattern */ - rtgui_free(view->current_directory); view->current_directory = RT_NULL; - rtgui_free(view->pattern); view->pattern = RT_NULL; + if (view->current_directory != RT_NULL) + { + rt_free(view->current_directory); + view->current_directory = RT_NULL; + } + if (view->pattern != RT_NULL) + { + rt_free(view->pattern); + view->pattern = RT_NULL; + } /* delete image */ rtgui_image_destroy(file_image); diff --git a/components/rtgui/widgets/groupbox.c b/components/rtgui/widgets/groupbox.c new file mode 100644 index 000000000..709759ea5 --- /dev/null +++ b/components/rtgui/widgets/groupbox.c @@ -0,0 +1,155 @@ +/* + * File : groupbox.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-29 Bernard first version + */ +#include +#include +#include +#include + +static void _rtgui_groupbox_constructor(rtgui_groupbox_t *box) +{ + /* init widget and set event handler */ + rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_groupbox_event_handler); + + /* set field */ + box->box = RT_NULL; + box->label = RT_NULL; + box->selected = RT_NULL; + + box->on_selected = RT_NULL; +} + +DEFINE_CLASS_TYPE(groupbox, "groupbox", + RTGUI_PANEL_TYPE, + _rtgui_groupbox_constructor, + RT_NULL, + sizeof(struct rtgui_groupbox)); + +rt_bool_t rtgui_groupbox_event_handler(struct rtgui_object *object, struct rtgui_event* event) +{ + struct rtgui_groupbox* box; + + box = RTGUI_GROUPBOX(object); + switch (event->type) + { + case RTGUI_EVENT_PAINT: + { + rtgui_panel_event_handler(RTGUI_OBJECT(box), event); + + /* dispatch paint event to child */ + rtgui_container_dispatch_event(RTGUI_CONTAINER(box), event); + } + break; + default: + return rtgui_container_event_handler(object, event); + } + + return RT_FALSE; +} + +rtgui_groupbox_t* rtgui_groupbox_create(const char* label, struct rtgui_rect *rect, + int style, widget_select_t select_func) +{ + struct rtgui_groupbox *box; + + RT_ASSERT(select_func != RT_NULL); + + box = (struct rtgui_groupbox*) rtgui_widget_create(RTGUI_GROUPBOX_TYPE); + if (box != RT_NULL) + { + rtgui_widget_set_rect(RTGUI_WIDGET(box), rect); + + if (label != RT_NULL) + { + box->label = rt_strdup(label); + } + + /* create layout box */ + box->box = rtgui_box_create(style, RTGUI_WIDGET_DEFAULT_MARGIN + 1); + rtgui_container_set_box(RTGUI_CONTAINER(box), box->box); + + rtgui_panel_set_border(RTGUI_PANEL(box), RTGUI_BORDER_NONE); + + box->select_func = select_func; + } + + return box; +} + +void rtgui_groupbox_destroy(rtgui_groupbox_t* groupbox) +{ + rtgui_object_destroy(RTGUI_OBJECT(groupbox)); +} + +void rtgui_groupbox_select_widget(struct rtgui_groupbox *box, struct rtgui_widget *widget) +{ + struct rtgui_event event; + + RT_ASSERT(box != RT_NULL); + RT_ASSERT(widget != RT_NULL); + + if (box->selected != widget) + { + if (box->selected != RT_NULL) + { + box->select_func(box->selected, RT_FALSE); + if (box->on_selected != RT_NULL) + { + RTGUI_EVENT_INIT(&event, RTGUI_EVENT_UNSELECTED); + box->on_selected(RTGUI_OBJECT(widget), &event); + } + rtgui_widget_update(widget); + } + box->selected = widget; + } + + box->select_func(box->selected, RT_TRUE); + + if (box->on_selected != RT_NULL) + { + RTGUI_EVENT_INIT(&event, RTGUI_EVENT_SELECTED); + box->on_selected(RTGUI_OBJECT(widget), &event); + } +} + +struct rtgui_widget *rtgui_groupbox_get_selected(struct rtgui_groupbox *box) +{ + RT_ASSERT(box != RT_NULL); + + return box->selected; +} + +void rtgui_groupbox_add_widget(struct rtgui_groupbox *box, struct rtgui_widget *widget) +{ + widget->user_data = (rt_uint32_t)box; + rtgui_container_add_child(RTGUI_CONTAINER(box), widget); + RTGUI_WIDGET_ALIGN(widget) = RTGUI_ALIGN_CENTER; + RTGUI_WIDGET_BACKGROUND(widget) = RTGUI_WIDGET_BACKGROUND(box); +} + +void rtgui_groupbox_layout(struct rtgui_groupbox *box) +{ + if (RTGUI_PANEL(box)->border_style != RTGUI_BORDER_NONE) + { + rtgui_box_layout(box->box); + } + else + { + struct rtgui_rect extent; + + RT_ASSERT(box != RT_NULL); + rtgui_widget_get_extent(RTGUI_WIDGET(box), &extent); + rtgui_rect_inflate(&extent, -RTGUI_WIDGET_DEFAULT_MARGIN); + rtgui_box_layout_rect(box->box, &extent); + } +} diff --git a/components/rtgui/widgets/iconbox.c b/components/rtgui/widgets/iconbox.c index ddd058cd9..9514038ab 100644 --- a/components/rtgui/widgets/iconbox.c +++ b/components/rtgui/widgets/iconbox.c @@ -18,7 +18,7 @@ static void _rtgui_iconbox_constructor(rtgui_iconbox_t *iconbox) { /* init widget and set event handler */ - RTGUI_WIDGET(iconbox)->flag |= RTGUI_WIDGET_FLAG_TRANSPARENT; + RTGUI_WIDGET(iconbox)->flag |= (RTGUI_WIDGET_FLAG_TRANSPARENT | RTGUI_WIDGET_FLAG_FOCUSABLE); rtgui_object_set_event_handler(RTGUI_OBJECT(iconbox), rtgui_iconbox_event_handler); /* set proper of control */ @@ -36,8 +36,11 @@ static void _rtgui_iconbox_destructor(rtgui_iconbox_t *iconbox) iconbox->image = RT_NULL; } - rt_free(iconbox->text); - iconbox->text = RT_NULL; + if (iconbox->text != RT_NULL) + { + rt_free(iconbox->text); + iconbox->text = RT_NULL; + } } DEFINE_CLASS_TYPE(iconbox, "iconbox", @@ -49,23 +52,35 @@ DEFINE_CLASS_TYPE(iconbox, "iconbox", rt_bool_t rtgui_iconbox_event_handler(struct rtgui_object* object, struct rtgui_event* event) { struct rtgui_iconbox* iconbox; - RTGUI_WIDGET_EVENT_HANDLER_PREPARE iconbox = RTGUI_ICONBOX(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_theme_draw_iconbox(iconbox); + break; + + case RTGUI_EVENT_MOUSE_BUTTON: + if (RTGUI_WIDGET_IS_HIDE(object)) return RT_FALSE; + { - rtgui_theme_draw_iconbox(iconbox); + struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event; + + /* it's not this widget event, clean status */ + if (rtgui_rect_contains_point(&(RTGUI_WIDGET(iconbox)->extent), + emouse->x, emouse->y) != RT_EOK) + { + if (iconbox->selected != RT_TRUE) + { + rtgui_iconbox_set_selected(iconbox, RT_TRUE); + rtgui_widget_focus(RTGUI_WIDGET(iconbox)); + } + break; + } } + return RT_TRUE; - break; default: return rtgui_widget_event_handler(object, event); } @@ -127,7 +142,7 @@ void rtgui_iconbox_destroy(struct rtgui_iconbox* iconbox) void rtgui_iconbox_set_text_position(struct rtgui_iconbox* iconbox, int position) { - rtgui_rect_t rect = {0, 0, 0, 0}, text_rect; + struct rtgui_rect rect = {0, 0, 0, 0}, text_rect; RT_ASSERT(iconbox != RT_NULL); @@ -161,9 +176,11 @@ void rtgui_iconbox_set_text_position(struct rtgui_iconbox* iconbox, int position rect.x2 += text_rect.x2; } } +} + +void rtgui_iconbox_set_selected(struct rtgui_iconbox* iconbox, rt_bool_t selected) +{ + RT_ASSERT(iconbox != RT_NULL); -#ifndef RTGUI_USING_SMALL_SIZE - rtgui_widget_set_miniwidth(RTGUI_WIDGET(iconbox), rect.x2); - rtgui_widget_set_miniheight(RTGUI_WIDGET(iconbox), rect.y2); -#endif + iconbox->selected = selected; } diff --git a/components/rtgui/widgets/label.c b/components/rtgui/widgets/label.c index 85ea6ceb4..a3ddbaa3e 100644 --- a/components/rtgui/widgets/label.c +++ b/components/rtgui/widgets/label.c @@ -28,7 +28,8 @@ static void _rtgui_label_constructor(rtgui_label_t *label) static void _rtgui_label_destructor(rtgui_label_t *label) { /* release text memory */ - rt_free(label->text); + if (label->text) + rt_free(label->text); label->text = RT_NULL; } @@ -100,7 +101,7 @@ void rtgui_label_set_text(rtgui_label_t* label, const char* text) if (rt_strncmp(text, label->text, rt_strlen(text)) == 0) return; /* release old text memory */ - rt_free(label->text); + rtgui_free(label->text); } if (text != RT_NULL) label->text = (char*)rt_strdup((const char*)text); diff --git a/components/rtgui/widgets/list_view.c b/components/rtgui/widgets/list_view.c index 6012d350e..14244654f 100644 --- a/components/rtgui/widgets/list_view.c +++ b/components/rtgui/widgets/list_view.c @@ -33,8 +33,8 @@ static void _rtgui_list_view_constructor(struct rtgui_list_view *view) view->items_count = 0; view->page_items = 0; - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white; - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_BACKGROUND(view) = white; + RTGUI_WIDGET_TEXTALIGN(view) = RTGUI_ALIGN_CENTER_VERTICAL; } DEFINE_CLASS_TYPE(listview, "listview", @@ -84,7 +84,7 @@ static void rtgui_list_view_onicondraw(struct rtgui_list_view* view, struct rtgu item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; item_rect.x1 += 3; item_rect.x2 -=3; - rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[item_index].name, + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(view), view->items[item_index].name, &drawing_rect); rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL); rtgui_dc_draw_text(dc, view->items[item_index].name, &drawing_rect); @@ -144,7 +144,7 @@ static void rtgui_list_view_update_icon(struct rtgui_list_view* view, rt_int16_t /* draw text */ item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; item_rect.x1 += 3; item_rect.x2 -=3; - rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[old_item].name, + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(view), view->items[old_item].name, &drawing_rect); rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL); rtgui_dc_draw_text(dc, view->items[old_item].name, &drawing_rect); @@ -170,7 +170,7 @@ static void rtgui_list_view_update_icon(struct rtgui_list_view* view, rt_int16_t /* draw text */ item_rect.y1 = drawing_rect.y2 + LIST_MARGIN; item_rect.x1 += 3; item_rect.x2 -=3; - rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(view), view->items[view->current_item].name, &drawing_rect); rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL); @@ -586,7 +586,7 @@ static void rtgui_list_view_calc(struct rtgui_list_view* view) image_height = 0; } - rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), "HHHHHH", &rect); + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(view), "HHHHHH", &rect); text_height = rtgui_rect_height(rect); text_width = rtgui_rect_width(rect); diff --git a/components/rtgui/widgets/listbox.c b/components/rtgui/widgets/listbox.c index e7d0dbbff..9ec5a3b3a 100644 --- a/components/rtgui/widgets/listbox.c +++ b/components/rtgui/widgets/listbox.c @@ -29,8 +29,8 @@ static void _rtgui_listbox_constructor(struct rtgui_listbox *box) box->page_items = 1; box->on_item = 0; - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white; - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_BACKGROUND(box) = white; + RTGUI_WIDGET_TEXTALIGN(box) = RTGUI_ALIGN_CENTER_VERTICAL; } DEFINE_CLASS_TYPE(listbox, "listbox", @@ -54,7 +54,7 @@ void rtgui_listbox_ondraw(struct rtgui_listbox* box) rect.x2 -= 1; rect.y2 -= 1; /* draw focused border */ - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box))) + if (RTGUI_WIDGET_IS_FOCUSED(box)) rtgui_dc_draw_focus_rect(dc, &rect); /* get item base rect */ @@ -227,7 +227,7 @@ rt_bool_t rtgui_listbox_event_handler(struct rtgui_object* object, struct rtgui_ /* update focus border */ rect.x2 -= 1; rect.y2 -= 1; /* draw focused border */ - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box))) + if (RTGUI_WIDGET_IS_FOCUSED(box)) rtgui_dc_draw_focus_rect(dc, &rect); rtgui_dc_end_drawing(dc); } diff --git a/components/rtgui/widgets/listctrl.c b/components/rtgui/widgets/listctrl.c index bc3b75e0f..b1e428d2e 100644 --- a/components/rtgui/widgets/listctrl.c +++ b/components/rtgui/widgets/listctrl.c @@ -25,13 +25,14 @@ static void _rtgui_listctrl_constructor(struct rtgui_listctrl *ctrl) RTGUI_WIDGET(ctrl)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; ctrl->current_item = -1; + ctrl->item_height = rtgui_theme_get_selected_height(); ctrl->items_count = 0; ctrl->page_items = 0; ctrl->on_item = 0; ctrl->on_item_draw = RT_NULL; - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(ctrl)) = white; - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(ctrl)) = RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_BACKGROUND(ctrl) = white; + RTGUI_WIDGET_TEXTALIGN(ctrl) = RTGUI_ALIGN_CENTER_VERTICAL; } DEFINE_CLASS_TYPE(listctrl, "listctrl", @@ -43,7 +44,7 @@ DEFINE_CLASS_TYPE(listctrl, "listctrl", static void _rtgui_listctrl_get_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect) { rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect); - if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height()) + if (ctrl->items_count > rtgui_rect_height(*rect)/ctrl->item_height) { rect->x2 = rect->x2 - 8; } @@ -52,7 +53,7 @@ static void _rtgui_listctrl_get_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* static void _rtgui_listctrl_get_scrollbar_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect) { rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect); - if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height()) + if (ctrl->items_count > rtgui_rect_height(*rect)/ctrl->item_height) { rect->x1 = rect->x2 - 8; } @@ -70,10 +71,11 @@ static void _rtgui_listctrl_scrollbar_ondraw(struct rtgui_listctrl* ctrl, struct /* get scrollbar rect */ _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect); + if (rtgui_rect_is_empty(&rect) == RT_TRUE) return; + rtgui_dc_fill_rect(dc, &rect); height = rtgui_rect_height(rect); - height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items); y1 = (ctrl->current_item / ctrl->page_items) * height; @@ -132,7 +134,7 @@ static void _rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl) item_rect = rect; item_rect.x1 += 1; item_rect.x2 -= 1; item_rect.y1 += 2; - item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height()); + item_rect.y2 = item_rect.y1 + (2 + ctrl->item_height); /* get current page */ page_index = (ctrl->current_item / ctrl->page_items) * ctrl->page_items; @@ -151,8 +153,8 @@ static void _rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl) } /* move to next item position */ - item_rect.y1 += (rtgui_theme_get_selected_height() + 2); - item_rect.y2 += (rtgui_theme_get_selected_height() + 2); + item_rect.y1 += (ctrl->item_height + 2); + item_rect.y2 += (ctrl->item_height + 2); } /* draw scrollbar */ @@ -182,8 +184,8 @@ void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_ /* get old item's rect */ item_rect.x1 += 1; item_rect.x2 -= 1; item_rect.y1 += 2; - item_rect.y1 += (old_item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height()); - item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height()); + item_rect.y1 += (old_item % ctrl->page_items) * (2 + ctrl->item_height); + item_rect.y2 = item_rect.y1 + (2 + ctrl->item_height); /* draw old item */ rtgui_dc_fill_rect(dc, &item_rect); @@ -195,8 +197,8 @@ void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_ /* get current item's rect */ item_rect.x1 += 1; item_rect.x2 -= 1; item_rect.y1 += 2; - item_rect.y1 += (ctrl->current_item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height()); - item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height()); + item_rect.y1 += (ctrl->current_item % ctrl->page_items) * (2 + ctrl->item_height); + item_rect.y2 = item_rect.y1 + (2 + ctrl->item_height); /* draw current item */ rtgui_theme_draw_selected(dc, &item_rect); @@ -225,7 +227,7 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui resize = (struct rtgui_event_resize*)event; /* recalculate page items */ - ctrl->page_items = resize->h / (2 + rtgui_theme_get_selected_height()); + ctrl->page_items = resize->h / (2 + ctrl->item_height); } break; @@ -255,7 +257,7 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui (ctrl->items_count > 0)) { rt_uint16_t index; - index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height()); + index = (emouse->y - rect.y1) / (2 + ctrl->item_height); /* set focus */ rtgui_widget_focus(widget); @@ -372,7 +374,7 @@ rtgui_listctrl_t* rtgui_listctrl_create(rt_uint32_t items, rt_uint16_t count, rt ctrl->items_count = count; ctrl->on_item_draw = ondraw; - ctrl->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height()); + ctrl->page_items = rtgui_rect_height(*rect) / (2 + ctrl->item_height); rtgui_widget_set_rect(RTGUI_WIDGET(ctrl), rect); } @@ -401,7 +403,7 @@ void rtgui_listctrl_set_items(rtgui_listctrl_t* ctrl, rt_uint32_t items, rt_uint ctrl->current_item = 0; rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect); - ctrl->page_items = rtgui_rect_height(rect) / (2 + rtgui_theme_get_selected_height()); + ctrl->page_items = rtgui_rect_height(rect) / (2 + ctrl->item_height); rtgui_widget_update(RTGUI_WIDGET(ctrl)); } @@ -418,10 +420,20 @@ rt_bool_t rtgui_listctrl_get_item_rect(rtgui_listctrl_t* ctrl, rt_uint16_t item, rtgui_widget_get_extent(RTGUI_WIDGET(ctrl), item_rect); item_rect->y1 -= 2; - item_rect->y1 += (item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height()); - item_rect->y2 = item_rect->y1 + (2 + rtgui_theme_get_selected_height()); + item_rect->y1 += (item % ctrl->page_items) * (2 + ctrl->item_height); + item_rect->y2 = item_rect->y1 + (2 + ctrl->item_height); return RT_TRUE; } return RT_FALSE; } + +void rtgui_listctrl_set_itemheight(struct rtgui_listctrl* ctrl, int height) +{ + RT_ASSERT(ctrl != RT_NULL); + if (height <= 0) return; + + ctrl->item_height = height; + ctrl->page_items = rtgui_rect_height(RTGUI_WIDGET(ctrl)->extent) / (2 + ctrl->item_height); +} + diff --git a/components/rtgui/widgets/menu.c b/components/rtgui/widgets/menu.c index 6ff278f71..b4856ee8f 100644 --- a/components/rtgui/widgets/menu.c +++ b/components/rtgui/widgets/menu.c @@ -58,7 +58,7 @@ static rt_bool_t _rtgui_menu_onitem(struct rtgui_object* object, struct rtgui_ev { if (menu->sub_menu->items == items) { - if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(menu->sub_menu))) + if (!RTGUI_WIDGET_IS_HIDE(menu->sub_menu)) { /* hide this sub menu */ rtgui_win_hiden(RTGUI_WIN(menu->sub_menu)); @@ -114,10 +114,10 @@ static void _rtgui_menu_item_ondraw(struct rtgui_listctrl *list, { rtgui_color_t bc; - bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)); - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = blue; + bc = RTGUI_WIDGET_BACKGROUND(list); + RTGUI_WIDGET_BACKGROUND(list) = blue; rtgui_dc_fill_rect(dc, rect); - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = bc; + RTGUI_WIDGET_BACKGROUND(list) = bc; } /* get menu item */ @@ -178,7 +178,7 @@ static rt_bool_t rtgui_menu_on_deactivate(struct rtgui_object *object, rtgui_eve * before the new window got activated. But the window will be shown in * this context, so use 'is not hide'. */ if (menu->sub_menu != RT_NULL && - !RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(menu->sub_menu))) + !RTGUI_WIDGET_IS_HIDE(menu->sub_menu)) return RT_TRUE; } @@ -219,7 +219,7 @@ struct rtgui_menu* rtgui_menu_create(const char* title, struct rtgui_menu* paren rtgui_rect_inflate(&rect, -1); /* create menu item list */ menu->items_list = rtgui_listctrl_create((rt_uint32_t)items, count, &rect, _rtgui_menu_item_ondraw); - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(menu->items_list)) = rtgui_theme_default_bc(); + RTGUI_WIDGET_BACKGROUND(menu->items_list) = rtgui_theme_default_bc(); rtgui_container_add_child(RTGUI_CONTAINER(menu), RTGUI_WIDGET(menu->items_list)); rtgui_listctrl_set_onitem(menu->items_list, _rtgui_menu_onitem); } diff --git a/components/rtgui/widgets/notebook.c b/components/rtgui/widgets/notebook.c index dcbeac941..51ff06fc9 100644 --- a/components/rtgui/widgets/notebook.c +++ b/components/rtgui/widgets/notebook.c @@ -3,11 +3,18 @@ #include #include #include +#include -#define RTGUI_NOTEBOOK_TAB_WIDTH 80 +#define RTGUI_NOTEBOOK_TAB_DEFAULT_WIDTH 80 +#define RTGUI_NOTEBOOK_TAB_DEFAULT_HEIGHT 25 struct rtgui_notebook_tab { +#ifdef RTGUI_USING_NOTEBOOK_IMAGE + struct rtgui_image *pressed_image; + struct rtgui_image *unpressed_image; +#endif + struct rtgui_widget *widget; char *title; }; @@ -22,6 +29,9 @@ static void _rtgui_notebook_constructor(struct rtgui_notebook *notebook) notebook->count = 0; notebook->current = 0; + notebook->tab_h = RTGUI_NOTEBOOK_TAB_DEFAULT_HEIGHT; + notebook->tab_w = RTGUI_NOTEBOOK_TAB_DEFAULT_WIDTH; + RTGUI_WIDGET(notebook)->gc.textalign = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL; rtgui_object_set_event_handler(RTGUI_OBJECT(notebook), rtgui_notebook_event_handler); } @@ -55,31 +65,137 @@ DEFINE_CLASS_TYPE(notebook, "notebook", static void _rtgui_notebook_draw_bar(struct rtgui_notebook *notebook, struct rtgui_dc *dc) { - struct rtgui_rect rect; int index; + struct rtgui_rect rect; + struct rtgui_rect text_rect; +#ifdef RTGUI_USING_NOTEBOOK_IMAGE + struct rtgui_image* image = RT_NULL; + struct rtgui_rect image_rect; +#endif RT_ASSERT((notebook != RT_NULL) && (dc != RT_NULL)); - if (notebook->flag & RTGUI_NOTEBOOK_NOTAB) + if (notebook->flag == RTGUI_NOTEBOOK_NOTAB) return; _rtgui_notebook_get_bar_rect(notebook, &rect); rtgui_dc_fill_rect(dc, &rect); - rect.x2 = rect.x1 + RTGUI_NOTEBOOK_TAB_WIDTH; - /* draw tab bar */ - for (index = 0; index < notebook->count; index++) + if (notebook->flag == RTGUI_NOTEBOOK_TOP || + notebook->flag == RTGUI_NOTEBOOK_BOTTOM) { - if (notebook->current == index) - rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN); - else - rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_BOX); + rect.x2 = rect.x1 + notebook->tab_w; + /* draw tab bar */ + for (index = 0; index < notebook->count; index++) + { + if (notebook->current == index) + { +#ifdef RTGUI_USING_NOTEBOOK_IMAGE + if (notebook->childs[index].pressed_image != RT_NULL) + image = notebook->childs[index].pressed_image; + else +#endif + rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN); + } + else + { +#ifdef RTGUI_USING_NOTEBOOK_IMAGE + if (notebook->childs[index].unpressed_image != RT_NULL) + image = notebook->childs[index].unpressed_image; + else +#endif + rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_BOX); + } + + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(notebook), + notebook->childs[index].title, &text_rect); + rtgui_rect_moveto_align(&rect, &text_rect, RTGUI_ALIGN_CENTER); - rtgui_dc_draw_text(dc, notebook->childs[index].title, &rect); - rect.x1 += RTGUI_NOTEBOOK_TAB_WIDTH; - rect.x2 += RTGUI_NOTEBOOK_TAB_WIDTH; +#ifdef RTGUI_USING_NOTEBOOK_IMAGE + if (image != RT_NULL) + { + image_rect.x1 = 0; + image_rect.y1 = RTGUI_WIDGET_DEFAULT_MARGIN; + image_rect.x2 = image_rect.x1 + image->w; + image_rect.y2 = image_rect.y1 + image->h; + rtgui_rect_moveto_align(&rect, &image_rect, RTGUI_ALIGN_CENTER_HORIZONTAL); + + rtgui_image_blit(image, dc, &image_rect); + } + if (image != RT_NULL) + { + int text_height = text_rect.y2 - text_rect.y1; + + text_rect.y1 = image_rect.y2 + RTGUI_WIDGET_DEFAULT_MARGIN; + text_rect.y2 = text_rect.y1 + text_height; + } + image = RT_NULL; +#endif + + rtgui_dc_draw_text(dc, notebook->childs[index].title, &text_rect); + + /* move to next tab */ + rect.x1 = rect.x2; + rect.x2 = rect.x1 + notebook->tab_w; + } } + else + { + rect.y2 = rect.y1 + notebook->tab_h; + /* draw tab bar */ + for (index = 0; index < notebook->count; index++) + { + if (notebook->current == index) + { +#ifdef RTGUI_USING_NOTEBOOK_IMAGE + if (notebook->childs[index].pressed_image != RT_NULL) + image = notebook->childs[index].pressed_image; + else +#endif + rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN); + } + else + { +#ifdef RTGUI_USING_NOTEBOOK_IMAGE + if (notebook->childs[index].unpressed_image != RT_NULL) + image = notebook->childs[index].unpressed_image; + else +#endif + rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_BOX); + } + + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(notebook), + notebook->childs[index].title, &text_rect); + rtgui_rect_moveto_align(&rect, &text_rect, RTGUI_ALIGN_CENTER); +#ifdef RTGUI_USING_NOTEBOOK_IMAGE + if (image != RT_NULL) + { + image_rect.x1 = 0; + image_rect.y1 = RTGUI_WIDGET_DEFAULT_MARGIN; + image_rect.x2 = image->w; + image_rect.y2 = image_rect.y1 + image->h; + rtgui_rect_moveto_align(&rect, &image_rect, RTGUI_ALIGN_CENTER_HORIZONTAL); + + rtgui_image_blit(image, dc, &image_rect); + } + + if (image != RT_NULL) + { + int text_height = text_rect.y2 - text_rect.y1; + + text_rect.y1 = image_rect.y2 + RTGUI_WIDGET_DEFAULT_MARGIN; + text_rect.y2 = text_rect.y1 + text_height; + } + image = RT_NULL; +#endif + rtgui_dc_draw_text(dc, notebook->childs[index].title, &text_rect); + + /* move to next tab */ + rect.y1 = rect.y2; + rect.y2 = rect.y1 + notebook->tab_h; + } + } } static void _rtgui_notebook_ondraw(struct rtgui_notebook *notebook) @@ -120,18 +236,36 @@ static void _rtgui_notebook_onmouse(struct rtgui_notebook *notebook, struct rtgu int index; struct rtgui_dc* dc; - index = (emouse->x - rect.x1) / RTGUI_NOTEBOOK_TAB_WIDTH; - if (index < notebook->count && index != notebook->current) + if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM || notebook->flag == RTGUI_NOTEBOOK_TOP) { - /* update tab bar */ - dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook)); - if (dc == RT_NULL) return; + index = (emouse->x - rect.x1) / notebook->tab_w; + if (index < notebook->count && index != notebook->current) + { + /* update tab bar */ + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook)); + if (dc == RT_NULL) return; - rtgui_notebook_set_current_by_index(notebook, index); + rtgui_notebook_set_current_by_index(notebook, index); - _rtgui_notebook_draw_bar(notebook, dc); + _rtgui_notebook_draw_bar(notebook, dc); - rtgui_dc_end_drawing(dc); + rtgui_dc_end_drawing(dc); + } + } + else + { + index = (emouse->y - rect.y1) / notebook->tab_h; + if (index < notebook->count && index != notebook->current) + { + /* update tab bar */ + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook)); + if (dc == RT_NULL) return; + + rtgui_notebook_set_current_by_index(notebook, index); + _rtgui_notebook_draw_bar(notebook, dc); + + rtgui_dc_end_drawing(dc); + } } } else @@ -146,17 +280,32 @@ static void _rtgui_notebook_onmouse(struct rtgui_notebook *notebook, struct rtgu static void _rtgui_notebook_get_page_rect(struct rtgui_notebook *notebook, struct rtgui_rect* rect) { + struct rtgui_rect tab_rect; + RT_ASSERT(notebook != RT_NULL); RT_ASSERT(rect != RT_NULL); + _rtgui_notebook_get_bar_rect(notebook, &tab_rect); rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect); if (notebook->flag == RTGUI_NOTEBOOK_NOTAB) return; else if (notebook->flag == RTGUI_NOTEBOOK_TOP) - rect->y1 = rect->y1 + 25; + { + rect->y1 = tab_rect.y2; + } else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM) - rect->y2 = rect->y2 - 25; + { + rect->y2 = tab_rect.y1; + } + else if (notebook->flag == RTGUI_NOTEBOOK_LEFT) + { + rect->x1 = tab_rect.x2; + } + else if (notebook->flag == RTGUI_NOTEBOOK_RIGHT) + { + rect->x2 = tab_rect.x1; + } } static void _rtgui_notebook_get_bar_rect(struct rtgui_notebook *notebook, struct rtgui_rect* rect) @@ -170,9 +319,21 @@ static void _rtgui_notebook_get_bar_rect(struct rtgui_notebook *notebook, struct rect->x1 = rect->y1 = rect->x2 = rect->y2 = 0; } else if (notebook->flag == RTGUI_NOTEBOOK_TOP) - rect->y2 = rect->y1 + 25; + { + rect->y2 = rect->y1 + notebook->tab_h; + } else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM) - rect->y1 = rect->y2 - 25; + { + rect->y1 = rect->y2 - notebook->tab_h; + } + else if (notebook->flag == RTGUI_NOTEBOOK_LEFT) + { + rect->x2 = rect->x1 + notebook->tab_w; + } + else if (notebook->flag == RTGUI_NOTEBOOK_RIGHT) + { + rect->x1 = rect->x2 - notebook->tab_w; + } } struct rtgui_notebook* rtgui_notebook_create(const rtgui_rect_t* rect, rt_uint8_t style) @@ -202,10 +363,14 @@ void rtgui_notebook_add(struct rtgui_notebook* notebook, const char* label, stru notebook->count += 1; notebook->childs = (struct rtgui_notebook_tab*) rtgui_realloc(notebook->childs, - sizeof(struct rtgui_notebook_tab) * notebook->count); + sizeof(struct rtgui_notebook_tab) * notebook->count); notebook->childs[notebook->count - 1].title = rt_strdup(label); notebook->childs[notebook->count - 1].widget = child; +#ifdef RTGUI_USING_NOTEBOOK_IMAGE + notebook->childs[notebook->count - 1].pressed_image = RT_NULL; + notebook->childs[notebook->count - 1].unpressed_image = RT_NULL; +#endif /* set parent */ rtgui_widget_set_parent(child, RTGUI_WIDGET(notebook)); @@ -228,6 +393,47 @@ void rtgui_notebook_add(struct rtgui_notebook* notebook, const char* label, stru } } +#ifdef RTGUI_USING_NOTEBOOK_IMAGE +void rtgui_notebook_add_image(struct rtgui_notebook* notebook, const char* label, struct rtgui_widget* child, + struct rtgui_image *pressed_image, struct rtgui_image *unpressed_image) +{ + rtgui_rect_t rect; + RT_ASSERT(notebook != RT_NULL); + + notebook->count += 1; + notebook->childs = (struct rtgui_notebook_tab*) + rtgui_realloc(notebook->childs, + sizeof(struct rtgui_notebook_tab) * notebook->count); + + notebook->childs[notebook->count - 1].title = rt_strdup(label); + notebook->childs[notebook->count - 1].widget = child; + notebook->childs[notebook->count - 1].pressed_image = pressed_image; + notebook->childs[notebook->count - 1].unpressed_image = unpressed_image; + + /* set parent */ + rtgui_widget_set_parent(child, RTGUI_WIDGET(notebook)); + + _rtgui_notebook_get_page_rect(notebook, &rect); + rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect); + rtgui_widget_set_rect(child, &rect); + + if (notebook->count - 1 != notebook->current) + rtgui_widget_hide(child); + + if (RTGUI_WIDGET(notebook)->toplevel != RT_NULL && + RTGUI_IS_TOPLEVEL(RTGUI_WIDGET(notebook)->toplevel)) + { + struct rtgui_event_update_toplvl eup; + RTGUI_EVENT_UPDATE_TOPLVL_INIT(&eup); + eup.toplvl = RTGUI_WIDGET(notebook)->toplevel; + if (RTGUI_OBJECT(child)->event_handler) + RTGUI_OBJECT(child)->event_handler(RTGUI_OBJECT(child), (struct rtgui_event*)&eup); + } + + return; +} +#endif + void rtgui_notebook_remove(struct rtgui_notebook* notebook, rt_uint16_t index) { struct rtgui_notebook_tab tab; @@ -260,7 +466,7 @@ void rtgui_notebook_remove(struct rtgui_notebook* notebook, rt_uint16_t index) sizeof(struct rtgui_notebook_tab) * notebook->count); } - rtgui_free(tab.title); + rt_free(tab.title); if (need_update) { @@ -281,6 +487,12 @@ int rtgui_notebook_get_count(struct rtgui_notebook* notebook) return notebook->count; } +void rtgui_notebook_get_client_rect(struct rtgui_notebook* notebook, struct rtgui_rect *rect) +{ + _rtgui_notebook_get_page_rect(notebook, rect); + rtgui_rect_moveto(rect, 0, 0); +} + struct rtgui_widget* rtgui_notebook_get_current(struct rtgui_notebook* notebook) { RT_ASSERT(notebook != RT_NULL); diff --git a/components/rtgui/widgets/progressbar.c b/components/rtgui/widgets/progressbar.c index ea8a2bece..bafd82995 100644 --- a/components/rtgui/widgets/progressbar.c +++ b/components/rtgui/widgets/progressbar.c @@ -16,7 +16,7 @@ static void _rtgui_progressbar_constructor(rtgui_progressbar_t *bar) bar->position = 0; /* set gc */ - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(bar)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_TEXTALIGN(bar) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL; } DEFINE_CLASS_TYPE(progressbar, "progressbar", @@ -72,7 +72,7 @@ void rtgui_progressbar_set_value(struct rtgui_progressbar *bar, int value) { RT_ASSERT(bar != RT_NULL); - if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar))) return; + if (!RTGUI_WIDGET_IS_ENABLE(bar)) return; bar->position = value; diff --git a/components/rtgui/widgets/radiobox.c b/components/rtgui/widgets/radiobox.c index 5f67d2fcb..cab215b16 100644 --- a/components/rtgui/widgets/radiobox.c +++ b/components/rtgui/widgets/radiobox.c @@ -11,7 +11,7 @@ static void _rtgui_radiobox_constructor(rtgui_radiobox_t *radiobox) /* init widget and set event handler */ RTGUI_WIDGET(radiobox)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(radiobox)) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_TEXTALIGN(radiobox) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL; rtgui_widget_set_rect(RTGUI_WIDGET(radiobox), &rect); rtgui_object_set_event_handler(RTGUI_OBJECT(radiobox), rtgui_radiobox_event_handler); @@ -34,8 +34,8 @@ static void rtgui_radiobox_onmouse(struct rtgui_radiobox* radiobox, struct rtgui RT_ASSERT(event != RT_NULL); /* widget is hide, return */ - if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(radiobox)) || - !RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(radiobox))) return; + if (RTGUI_WIDGET_IS_HIDE(radiobox) || + !RTGUI_WIDGET_IS_ENABLE(radiobox)) return; if (event->button & RTGUI_MOUSE_BUTTON_DOWN && event->button & RTGUI_MOUSE_BUTTON_LEFT) @@ -57,7 +57,7 @@ static void rtgui_radiobox_onmouse(struct rtgui_radiobox* radiobox, struct rtgui { struct rtgui_rect bord_rect; - rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &bord_rect); + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(radiobox), "H", &bord_rect); bord_size = rtgui_rect_height(bord_rect); } rtgui_rect_inflate(&rect, - bord_size); @@ -97,7 +97,7 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui break; case RTGUI_EVENT_KBD: - if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(radiobox))) return RT_FALSE; + if (RTGUI_WIDGET_IS_HIDE(radiobox)) return RT_FALSE; #ifndef RTGUI_USING_SMALL_SIZE if (widget->on_key != RT_NULL) @@ -186,7 +186,7 @@ struct rtgui_radiobox* rtgui_radiobox_create(const char* label, int orient, char /* set proper of control */ rtgui_radiobox_set_orientation(radiobox, orient); - rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &rect); + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(radiobox), "H", &rect); board_size = rtgui_rect_height(rect); if (orient == RTGUI_VERTICAL) @@ -202,7 +202,7 @@ struct rtgui_radiobox* rtgui_radiobox_create(const char* label, int orient, char /* set init item size */ radiobox->item_size = 0; - font = RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)); + font = RTGUI_WIDGET_FONT(radiobox); for (index = 0; index < number; index ++) { rtgui_font_get_metrics(font, radio_items[index], &rect); diff --git a/components/rtgui/widgets/scrollbar.c b/components/rtgui/widgets/scrollbar.c index 4a6a63e47..89e76dc24 100644 --- a/components/rtgui/widgets/scrollbar.c +++ b/components/rtgui/widgets/scrollbar.c @@ -35,7 +35,7 @@ static void _rtgui_scrollbar_constructor(rtgui_scrollbar_t *bar) rtgui_widget_set_rect(RTGUI_WIDGET(bar), &rect); /* set gc */ - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(bar)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_TEXTALIGN(bar) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL; } rt_inline rt_uint32_t _rtgui_scrollbar_get_length(rtgui_scrollbar_t *bar) @@ -362,7 +362,7 @@ void rtgui_scrollbar_set_range(struct rtgui_scrollbar* bar, int min, int max) if (min >= max ) { - RTGUI_WIDGET_DISABLE(RTGUI_WIDGET(bar)); + RTGUI_WIDGET_DISABLE(bar); return; } @@ -380,12 +380,12 @@ void rtgui_scrollbar_set_page_step(struct rtgui_scrollbar* bar, int step) if (bar->page_step > (bar->max_position - bar->min_position)) { /* disable bar */ - RTGUI_WIDGET_DISABLE(RTGUI_WIDGET(bar)); + RTGUI_WIDGET_DISABLE(bar); } else { /* enable bar */ - RTGUI_WIDGET_ENABLE(RTGUI_WIDGET(bar)); + RTGUI_WIDGET_ENABLE(bar); } } diff --git a/components/rtgui/widgets/slider.c b/components/rtgui/widgets/slider.c index c3631cf0d..b0204d8a0 100644 --- a/components/rtgui/widgets/slider.c +++ b/components/rtgui/widgets/slider.c @@ -226,7 +226,7 @@ void rtgui_slider_set_value(struct rtgui_slider* slider, rt_size_t value) { RT_ASSERT(slider != RT_NULL); - if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(slider))) + if (RTGUI_WIDGET_IS_ENABLE(slider)) { if (value < slider->min) value = slider->min; if (value > slider->max) value = slider->max; diff --git a/components/rtgui/widgets/textbox.c b/components/rtgui/widgets/textbox.c index df56cbc9f..9023624b3 100644 --- a/components/rtgui/widgets/textbox.c +++ b/components/rtgui/widgets/textbox.c @@ -39,10 +39,10 @@ static void _rtgui_textbox_constructor(rtgui_textbox_t *box) 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; + RTGUI_WIDGET_FOREGROUND(box) = black; + RTGUI_WIDGET_BACKGROUND(box) = white; /* set default text align */ - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_TEXTALIGN(box) = RTGUI_ALIGN_CENTER_VERTICAL; /* set proper of control */ box->caret_timer = RT_NULL; box->caret = RT_NULL; @@ -52,7 +52,7 @@ static void _rtgui_textbox_constructor(rtgui_textbox_t *box) /* allocate default line buffer */ box->text = RT_NULL; - rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(box)), "H", &rect); + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(box), "H", &rect); box->font_width = rtgui_rect_width(rect); box->on_enter = RT_NULL; box->dis_length = 0; @@ -92,7 +92,7 @@ static void rtgui_textbox_get_caret_rect(rtgui_textbox_t *box, rtgui_rect_t *rec rtgui_widget_get_rect(RTGUI_WIDGET(box), rect); - rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(box)), "H", &item_rect); + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(box), "H", &item_rect); font_h = rtgui_rect_height(item_rect); box_h = rtgui_rect_height(*rect); @@ -111,7 +111,7 @@ static void rtgui_textbox_init_caret(rtgui_textbox_t *box, rt_uint16_t position) RT_ASSERT(box != RT_NULL); - if (!RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box))) + if (!RTGUI_WIDGET_IS_FOCUSED(box)) return; rtgui_textbox_get_caret_rect(box, &box->caret_rect, position); @@ -273,10 +273,11 @@ static rt_bool_t rtgui_textbox_onkey(struct rtgui_object* widget, rtgui_event_t* } else if(ekbd->key == RTGUIK_BACKSPACE) {/* delete front character */ - - if(box->position == length - 1) + if(box->position == 0) + return RT_FALSE; + else if(box->position == length) { - box->text[box->position] = '\0'; + box->text[box->position-1] = '\0'; box->position --; } else if(box->position != 0) @@ -369,7 +370,6 @@ static rt_bool_t rtgui_textbox_onkey(struct rtgui_object* widget, rtgui_event_t* } } } - //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; @@ -417,7 +417,7 @@ static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* widget, rtgui_event_ /* 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); + box->caret_timer = rtgui_timer_create(50, RT_TIMER_FLAG_PERIODIC,rtgui_textbox_timeout, box); /* set caret to show */ box->flag |= RTGUI_TEXTBOX_CARET_SHOW; /* start caret timer */ @@ -485,21 +485,21 @@ void rtgui_textbox_ondraw(rtgui_textbox_t* box) /* get widget rect */ rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect); - fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)); + fc = RTGUI_WIDGET_FOREGROUND(box); rtgui_rect_inflate(&rect, -1); /* fill widget rect with white color */ - RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white; + RTGUI_WIDGET_BACKGROUND(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_WIDGET_FOREGROUND(box) = RTGUI_RGB(123, 158, 189); rtgui_dc_draw_rect(dc, &rect); /* draw text */ - RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = fc; + RTGUI_WIDGET_FOREGROUND(box) = fc; if(box->text != RT_NULL) { rect.x1 += RTGUI_WIDGET_DEFAULT_MARGIN; diff --git a/components/rtgui/widgets/textview.c b/components/rtgui/widgets/textview.c index af1685419..4ae1253c1 100644 --- a/components/rtgui/widgets/textview.c +++ b/components/rtgui/widgets/textview.c @@ -35,7 +35,7 @@ static void _calc_line(rtgui_textview_t *textview, const char* text) if (textview->lines != RT_NULL) { - rt_free(textview->lines); + rtgui_free(textview->lines); textview->lines = RT_NULL; textview->line_count = 0; } @@ -100,7 +100,7 @@ static void _calc_line(rtgui_textview_t *textview, const char* text) textview->line_count = line_index + 1; /* allocate lines */ - textview->lines = rt_malloc(textview->line_count * textview->line_width); + textview->lines = rtgui_malloc(textview->line_count * textview->line_width); rt_memset(textview->lines, 0, (textview->line_count * textview->line_width)); /* fill lines */ @@ -177,7 +177,7 @@ static void _calc_width(rtgui_textview_t *textview) width = rtgui_rect_width(RTGUI_WIDGET(textview)->extent) - 6; height = rtgui_rect_height(RTGUI_WIDGET(textview)->extent); - rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &rect); + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(textview), "W", &rect); textview->line_width = width / rtgui_rect_width(rect) + 1; textview->line_page_count = height / (rtgui_rect_height(rect) + 3); @@ -192,7 +192,7 @@ static void _draw_textview(rtgui_textview_t *textview) char* line; rt_ubase_t line_index, item_height; - rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &font_rect); + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(textview), "W", &font_rect); item_height = rtgui_rect_height(font_rect) + 3; dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(textview)); @@ -236,7 +236,7 @@ static void _rtgui_textview_constructor(rtgui_textview_t *textview) static void _rtgui_textview_destructor(rtgui_textview_t *textview) { /* release line memory */ - rt_free(textview->lines); + rtgui_free(textview->lines); textview->lines = RT_NULL; } diff --git a/components/rtgui/widgets/title.c b/components/rtgui/widgets/title.c index b682c1eeb..38066ebdb 100644 --- a/components/rtgui/widgets/title.c +++ b/components/rtgui/widgets/title.c @@ -19,12 +19,13 @@ static void _rtgui_wintitle_constructor(rtgui_wintitle_t* wintitle) { wintitle->title = RT_NULL; RTGUI_WIDGET(wintitle)->flag = RTGUI_WIDGET_FLAG_DEFAULT; - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(wintitle)) = RTGUI_ALIGN_CENTER_VERTICAL; + RTGUI_WIDGET_TEXTALIGN(wintitle) = RTGUI_ALIGN_CENTER_VERTICAL; } static void _rtgui_wintitle_deconstructor(rtgui_wintitle_t* wintitle) { - rt_free(wintitle->title); + if (wintitle->title != RT_NULL) + rt_free(wintitle->title); wintitle->title = RT_NULL; } @@ -58,7 +59,7 @@ void rtgui_wintitle_set_title(rtgui_wintitle_t* wintitle, const char* title) if (wintitle->title != RT_NULL) { - rtgui_free(wintitle->title); + rt_free(wintitle->title); } if (title != RT_NULL) wintitle->title = (char*)rt_strdup((const char*)title); diff --git a/components/rtgui/widgets/toplevel.c b/components/rtgui/widgets/toplevel.c index b6882e7c3..dc2b72aa1 100644 --- a/components/rtgui/widgets/toplevel.c +++ b/components/rtgui/widgets/toplevel.c @@ -31,7 +31,7 @@ static void _rtgui_toplevel_constructor(rtgui_toplevel_t *toplevel) toplevel->drawing = 0; /* hide toplevel default */ - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(toplevel)); + RTGUI_WIDGET_HIDE(toplevel); } static void _rtgui_toplevel_destructor(rtgui_toplevel_t* toplevel) diff --git a/components/rtgui/widgets/widget.c b/components/rtgui/widgets/widget.c index 1a62d1666..0f506cd76 100644 --- a/components/rtgui/widgets/widget.c +++ b/components/rtgui/widgets/widget.c @@ -108,8 +108,20 @@ void rtgui_widget_destroy(rtgui_widget_t* widget) void rtgui_widget_set_rect(rtgui_widget_t* widget, const rtgui_rect_t* rect) { + int delta_x, delta_y; + if (widget == RT_NULL || rect == RT_NULL) return; + /* move to a logic position if it's a container widget */ + if (RTGUI_IS_CONTAINER(widget)) + { + delta_x = rect->x1 - widget->extent.x1; + delta_y = rect->y1 - widget->extent.y1; + + rtgui_widget_move_to_logic(widget, delta_x, delta_y); + } + + /* update extent rectangle */ widget->extent = *rect; /* reset mini width and height */ @@ -205,6 +217,37 @@ void rtgui_widget_get_rect(rtgui_widget_t* widget, rtgui_rect_t *rect) } } +/** + * set widget draw style + */ +void rtgui_widget_set_border(rtgui_widget_t* widget, rt_uint32_t style) +{ + RT_ASSERT(widget != RT_NULL); + + widget->border_style = style; + switch(style) + { + case RTGUI_BORDER_NONE: + widget->border = 0; + break; + case RTGUI_BORDER_SIMPLE: + case RTGUI_BORDER_UP: + case RTGUI_BORDER_DOWN: + widget->border = 1; + break; + case RTGUI_BORDER_STATIC: + case RTGUI_BORDER_RAISE: + case RTGUI_BORDER_SUNKEN: + case RTGUI_BORDER_BOX: + case RTGUI_BORDER_EXTRA: + widget->border = 2; + break; + default: + widget->border = 2; + break; + } +} + void rtgui_widget_set_onfocus(rtgui_widget_t* widget, rtgui_event_handler_ptr handler) { RT_ASSERT(widget != RT_NULL); @@ -451,7 +494,7 @@ rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* #endif } - return RT_FALSE; + return rtgui_object_event_handler(object, event); } /* @@ -537,7 +580,7 @@ rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *e { struct rtgui_widget *widget = RTGUI_WIDGET(object); - if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(object))) + if (!RTGUI_WIDGET_IS_HIDE(object)) return RT_FALSE; RTGUI_WIDGET_UNHIDE(widget); @@ -552,7 +595,7 @@ rt_bool_t rtgui_widget_onhide(struct rtgui_object *object, struct rtgui_event *e { struct rtgui_widget *widget = RTGUI_WIDGET(object); - if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(object))) + if (RTGUI_WIDGET_IS_HIDE(object)) return RT_FALSE; /* hide this widget */ diff --git a/components/rtgui/widgets/window.c b/components/rtgui/widgets/window.c index 96300a534..33ab4684a 100644 --- a/components/rtgui/widgets/window.c +++ b/components/rtgui/widgets/window.c @@ -38,7 +38,7 @@ static void _rtgui_win_constructor(rtgui_win_t *win) win->focused_widget = RT_NULL; /* set window hide */ - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win)); + RTGUI_WIDGET_HIDE(win); /* set window style */ win->style = RTGUI_WIN_STYLE_DEFAULT; @@ -69,7 +69,8 @@ static void _rtgui_win_destructor(rtgui_win_t* win) } /* release field */ - rt_free(win->title); + if (win->title != RT_NULL) + rt_free(win->title); } static rt_bool_t _rtgui_win_create_in_server(struct rtgui_win *win) @@ -143,6 +144,16 @@ __on_err: return RT_NULL; } +rtgui_win_t* rtgui_mainwin_create(struct rtgui_win *parent_window, const char* title, rt_uint16_t style) +{ + struct rtgui_rect rect; + + /* get rect of main window */ + rtgui_get_mainwin_rect(&rect); + + return rtgui_win_create(parent_window, title, &rect, style); +} + static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win, struct rtgui_event *event, rt_bool_t force_close) @@ -303,7 +314,7 @@ void rtgui_win_hiden(struct rtgui_win* win) { RT_ASSERT(win != RT_NULL); - if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)) && + if (!RTGUI_WIDGET_IS_HIDE(win) && win->flag & RTGUI_WIN_FLAG_CONNECTED) { /* send hidden message to server */ @@ -436,7 +447,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object* object, struct rtgui_even break; case RTGUI_EVENT_WIN_ACTIVATE: - if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win))) + if (RTGUI_WIDGET_IS_HIDE(win)) { /* activate a hide window */ return RT_TRUE; -- GitLab