diff options
| author | [email protected] <[email protected]> | 2012-07-20 12:37:56 +0000 |
|---|---|---|
| committer | [email protected] <[email protected]> | 2012-07-20 12:37:56 +0000 |
| commit | 92a50c838d8ca2ae4027fd77b71db12fb52d86e3 (patch) | |
| tree | 08cb5a9273c78c36df97f48eea17eb2e1034a497 /components/rtgui/widgets | |
| parent | c2868be90d0f1f43ee13bacdb1c0f55a9fe34276 (diff) | |
sync with RTGUI c074ff2898b9e
Full log is in GitHub.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2222 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/rtgui/widgets')
23 files changed, 793 insertions, 561 deletions
diff --git a/components/rtgui/widgets/about_view.c b/components/rtgui/widgets/about_view.c deleted file mode 100644 index 6bc012b255..0000000000 --- a/components/rtgui/widgets/about_view.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * File : about_view.c - * This file is part of RTGUI in RT-Thread RTOS - * COPYRIGHT (C) 2010, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2010-01-06 Bernard first version - */ - -#include <rtgui/rtgui_theme.h> -#include <rtgui/widgets/about_view.h> - -static void _rtgui_about_view_constructor(struct rtgui_about_view *view) -{ - /* default rect */ - struct rtgui_rect rect = {0, 0, 200, 200}; - - /* set default widget rect and set event handler */ - rtgui_object_set_event_handler(RTGUI_OBJECT(view),rtgui_about_view_event_handler); - rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect); - - RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; - - view->logo = RT_NULL; - view->description = RT_NULL; - - RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL; -} - -DEFINE_CLASS_TYPE(aboutview, "aboutview", - RTGUI_CONTAINER_TYPE, - _rtgui_about_view_constructor, - RT_NULL, - sizeof(struct rtgui_about_view)); - -void rtgui_about_view_ondraw(struct rtgui_about_view* view) -{ - struct rtgui_rect rect; - struct rtgui_dc* dc; - - dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view)); - if (dc == RT_NULL) return; - - rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect); - rtgui_dc_fill_rect(dc, &rect); - - if (view->logo != RT_NULL) - rtgui_image_blit(view->logo, dc, &rect); - - rect.y1 += view->logo->h + 5; - if (view->description != RT_NULL) - rtgui_dc_draw_text(dc, view->description, &rect); - - rect.y1 += rtgui_dc_get_gc(dc)->font->height; - rtgui_dc_draw_hline(dc, rect.x1 + 3, rect.x2 - 3, rect.y1); - RTGUI_DC_FC(dc) = white; - rtgui_dc_draw_hline(dc, rect.x1 + 4, rect.x2 - 2, rect.y1 + 1); - - rtgui_dc_end_drawing(dc); -} - -rt_bool_t rtgui_about_view_event_handler(struct rtgui_object* widget, struct rtgui_event* event) -{ - struct rtgui_about_view* view = RT_NULL; - - view = RTGUI_ABOUT_VIEW(widget); - switch (event->type) - { - case RTGUI_EVENT_PAINT: - rtgui_about_view_ondraw(view); - return RT_FALSE; - } - - /* use view event handler */ - return rtgui_container_event_handler(widget, event); -} - -rtgui_about_view_t* rtgui_about_view_create(rtgui_image_t *logo, const char* description) -{ - struct rtgui_about_view* view = RT_NULL; - - view = (struct rtgui_about_view*) rtgui_widget_create(RTGUI_ABOUT_VIEW_TYPE); - if (view != RT_NULL) - { - view->logo = logo; - view->description = description; - } - - return view; -} - -void rtgui_about_view_destroy(rtgui_about_view_t* view) -{ - /* destroy view */ - rtgui_widget_destroy(RTGUI_WIDGET(view)); -} diff --git a/components/rtgui/widgets/box.c b/components/rtgui/widgets/box.c index 860245c0db..68ee608372 100644 --- a/components/rtgui/widgets/box.c +++ b/components/rtgui/widgets/box.c @@ -14,73 +14,37 @@ #include <rtgui/dc.h> #include <rtgui/widgets/box.h> -#ifndef RTGUI_USING_SMALL_SIZE static void _rtgui_box_constructor(rtgui_box_t *box) { /* init widget and set event handler */ - rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_box_event_handler); - - RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_TRANSPARENT; - rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_box_event_handler); + rtgui_object_set_event_handler(RTGUI_OBJECT(box), RT_NULL); /* set proper of control */ box->orient = RTGUI_HORIZONTAL; box->border_size = RTGUI_BORDER_DEFAULT_WIDTH; + box->container = RT_NULL; } DEFINE_CLASS_TYPE(box, "box", - RTGUI_CONTAINER_TYPE, + RTGUI_OBJECT_TYPE, _rtgui_box_constructor, RT_NULL, sizeof(struct rtgui_box)); -rt_bool_t rtgui_box_event_handler(struct rtgui_object *widget, rtgui_event_t *event) -{ - struct rtgui_box* box = (struct rtgui_box*)widget; - - RT_ASSERT(box != RT_NULL); - - switch (event->type) - { - case RTGUI_EVENT_RESIZE: - /* re-layout */ - rtgui_box_layout(box); - break; - - default: - return rtgui_container_event_handler(RTGUI_OBJECT(box), event); - } - - return RT_FALSE; -} - -struct rtgui_box* rtgui_box_create(int orientation, rtgui_rect_t* rect) +struct rtgui_box* rtgui_box_create(int orientation, int border_size) { struct rtgui_box* box; - box = (struct rtgui_box*) rtgui_widget_create (RTGUI_BOX_TYPE); + box = (struct rtgui_box*) rtgui_object_create (RTGUI_BOX_TYPE); if (box != RT_NULL) { - /* set proper of control */ - rtgui_widget_set_rect(RTGUI_WIDGET(box), rect); box->orient = orientation; + box->border_size = border_size; } return box; } -void rtgui_box_append(struct rtgui_box* box, rtgui_widget_t* widget) -{ - /* put to box's children list */ - rtgui_container_add_child(RTGUI_CONTAINER(box), widget); -} - -void rtgui_box_delete(struct rtgui_box* box, rtgui_widget_t* widget) -{ - /* remove from box's children list */ - rtgui_container_remove_child(RTGUI_CONTAINER(box), widget); -} - static void rtgui_box_layout_vertical(rtgui_box_t* box) { rtgui_list_t *node; @@ -89,16 +53,18 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box) rt_int32_t next_x, next_y; rt_int32_t total_height, space_height; struct rtgui_event_resize size_event; - + struct rtgui_widget *container_widget; + /* prepare the resize event */ RTGUI_EVENT_RESIZE_INIT(&size_event); + container_widget = RTGUI_WIDGET(box->container); /* find spaces */ space_count = 0; total_height = 0; space_height = 0; - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) + rtgui_list_foreach(node, &(box->container->children)) { rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++; @@ -108,16 +74,16 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box) /* calculate the height for each spaces */ if (space_count != 0) { - space_height = (rtgui_rect_height(RTGUI_WIDGET(box)->extent) - total_height - (box->border_size << 1)) / space_count; + space_height = (rtgui_rect_height(container_widget->extent) - total_height - (box->border_size << 1)) / space_count; } /* init (x, y) and box width */ - next_x = RTGUI_WIDGET(box)->extent.x1 + box->border_size; - next_y = RTGUI_WIDGET(box)->extent.y1 + box->border_size; - box_width = rtgui_rect_width(RTGUI_WIDGET(box)->extent) - (box->border_size << 1); + next_x = container_widget->extent.x1 + box->border_size; + next_y = container_widget->extent.y1 + box->border_size; + box_width = rtgui_rect_width(container_widget->extent) - (box->border_size << 1); /* layout each widget */ - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) + rtgui_list_foreach(node, &(box->container->children)) { rtgui_rect_t *rect; rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); @@ -170,7 +136,7 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box) &size_event.parent); /* point to next height */ - next_y = rect->y2; + next_y = rect->y2 + box->border_size; } } @@ -182,16 +148,18 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box) rt_int32_t next_x, next_y; rt_int32_t total_width, space_width; struct rtgui_event_resize size_event; + struct rtgui_widget *container_widget; /* prepare the resize event */ RTGUI_EVENT_RESIZE_INIT(&size_event); + container_widget = RTGUI_WIDGET(box->container); /* find spaces */ space_count = 0; total_width = 0; space_width = 0; - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) + rtgui_list_foreach(node, &(box->container->children)) { rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++; @@ -201,16 +169,16 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box) if (space_count != 0) { /* calculate the height for each spaces */ - space_width = (rtgui_rect_width(RTGUI_WIDGET(box)->extent) - total_width) / space_count; + space_width = (rtgui_rect_width(container_widget->extent) - total_width) / space_count; } /* init (x, y) and box height */ - next_x = RTGUI_WIDGET(box)->extent.x1 + box->border_size; - next_y = RTGUI_WIDGET(box)->extent.y1 + box->border_size; - box_height = rtgui_rect_height(RTGUI_WIDGET(box)->extent) - (box->border_size << 1); + next_x = container_widget->extent.x1 + box->border_size; + next_y = container_widget->extent.y1 + box->border_size; + box_height = rtgui_rect_height(container_widget->extent) - (box->border_size << 1); /* layout each widget */ - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) + rtgui_list_foreach(node, &(box->container->children)) { rtgui_rect_t *rect; rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); @@ -263,7 +231,7 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box) &size_event.parent); /* point to next width */ - next_x = rect->x2; + next_x = rect->x2 + box->border_size; } } @@ -271,6 +239,8 @@ void rtgui_box_layout(rtgui_box_t* box) { RT_ASSERT(box != RT_NULL); + if (box->container == RT_NULL) return; + if (box->orient & RTGUI_VERTICAL) { rtgui_box_layout_vertical(box); @@ -281,64 +251,9 @@ void rtgui_box_layout(rtgui_box_t* box) } /* update box and its children clip */ - if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(box))) - { - rtgui_widget_update_clip(RTGUI_WIDGET(box)); - } -} - -rt_uint32_t rtgui_box_get_width(rtgui_box_t* box) -{ - rtgui_list_t *node; - rt_uint32_t width; - - width = 0; - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) + if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(box->container))) { - rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); - rt_uint32_t widget_width; - - widget_width = rtgui_rect_width(widget->extent); - if (box->orient & RTGUI_VERTICAL) - { - /* get the max width */ - if (width < widget_width) width = widget_width; - } - else - { - /* get the total width */ - width += widget_width; - } + rtgui_widget_update_clip(RTGUI_WIDGET(box->container)); } - - return width; -} - -rt_uint32_t rtgui_box_get_height(rtgui_box_t* box) -{ - rtgui_list_t *node; - rt_uint32_t height; - - height = 0; - rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) - { - rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); - rt_uint32_t widget_height; - - widget_height = rtgui_rect_height(widget->extent); - if (box->orient & RTGUI_HORIZONTAL) - { - /* get the max height */ - if (height < widget_height) height = widget_height; - } - else - { - /* get the total height */ - height += widget_height; - } - } - - return height; } -#endif diff --git a/components/rtgui/widgets/button.c b/components/rtgui/widgets/button.c index aab1333b56..2a7571e392 100644 --- a/components/rtgui/widgets/button.c +++ b/components/rtgui/widgets/button.c @@ -62,7 +62,7 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object* object, struct rtgui_e struct rtgui_widget *widget; struct rtgui_button *btn; - RT_ASSERT(widget != RT_NULL); + RT_ASSERT(object != RT_NULL); RT_ASSERT(event != RT_NULL); widget = RTGUI_WIDGET(object); @@ -189,6 +189,8 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object* object, struct rtgui_e return RT_TRUE; } + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/checkbox.c b/components/rtgui/widgets/checkbox.c index cfa23d4ef4..ad1657baab 100644 --- a/components/rtgui/widgets/checkbox.c +++ b/components/rtgui/widgets/checkbox.c @@ -92,6 +92,8 @@ rt_bool_t rtgui_checkbox_event_handler(struct rtgui_object* object, struct rtgui return RT_TRUE; } + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/combobox.c b/components/rtgui/widgets/combobox.c index 5b3010677c..a504682c57 100644 --- a/components/rtgui/widgets/combobox.c +++ b/components/rtgui/widgets/combobox.c @@ -38,7 +38,6 @@ rt_bool_t rtgui_combobox_pdwin_onitem(struct rtgui_object* object, struct rtgui_ rtgui_listbox_t* list; RT_ASSERT(object != RT_NULL); - RT_ASSERT(event != RT_NULL); widget = RTGUI_WIDGET(object); list = RTGUI_LISTBOX(widget); @@ -228,6 +227,8 @@ rt_bool_t rtgui_combobox_event_handler(struct rtgui_object* object, struct rtgui } } break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/container.c b/components/rtgui/widgets/container.c index fc23030429..f5c954ddcf 100644 --- a/components/rtgui/widgets/container.c +++ b/components/rtgui/widgets/container.c @@ -14,7 +14,7 @@ */ #include <rtgui/dc.h> #include <rtgui/rtgui_system.h> -#include <rtgui/rtgui_application.h> +#include <rtgui/rtgui_app.h> #include <rtgui/widgets/container.h> #include <rtgui/widgets/window.h> @@ -25,26 +25,17 @@ static void _rtgui_container_constructor(rtgui_container_t *container) rtgui_container_event_handler); rtgui_list_init(&(container->children)); + container->layout_box = RT_NULL; - /* container is used to 'contain'(show) widgets and dispatch events to - * them, not interact with user. So no need to grab focus. If we did it, - * some widget inherited from container(e.g. notebook) will grab the focus - * annoyingly. - * - * For example, a focusable notebook N has a widget W. When the user press - * W, N will gain the focus and W will lose it at first. Then N will set - * focus to W because it is W that eventually interact with people. N will - * yield focus and W will gain the focus again. This loop will make W - * repaint twice every time user press it. - * - * Just eliminate it. - */ - RTGUI_WIDGET(container)->flag &= ~RTGUI_WIDGET_FLAG_FOCUSABLE; + RTGUI_WIDGET(container)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; } static void _rtgui_container_destructor(rtgui_container_t *container) { rtgui_container_destroy_children(container); + + if (container->layout_box != RT_NULL) + rtgui_object_destroy(RTGUI_OBJECT(container->layout_box)); } static void _rtgui_container_update_toplevel(rtgui_container_t* container) @@ -152,15 +143,6 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object* object, struct rtgu break; case RTGUI_EVENT_KBD: - /* let parent to handle keyboard event */ - if (widget->parent != RT_NULL && - widget->parent != RTGUI_WIDGET(widget->toplevel) && - RTGUI_OBJECT(widget->parent)->event_handler) - { - return RTGUI_OBJECT(widget->parent)->event_handler( - RTGUI_OBJECT(widget->parent), - event); - } break; case RTGUI_EVENT_MOUSE_BUTTON: @@ -169,6 +151,14 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object* object, struct rtgu return rtgui_container_dispatch_mouse_event(container, (struct rtgui_event_mouse*)event); + case RTGUI_EVENT_SHOW: + rtgui_widget_onshow(RTGUI_OBJECT(container), event); + rtgui_container_dispatch_event(container, event); + break; + case RTGUI_EVENT_HIDE: + rtgui_widget_onhide(RTGUI_OBJECT(container), event); + rtgui_container_dispatch_event(container, event); + break; case RTGUI_EVENT_COMMAND: case RTGUI_EVENT_RESIZE: rtgui_container_dispatch_event(container, event); @@ -193,7 +183,6 @@ rtgui_container_t* rtgui_container_create(void) void rtgui_container_destroy(rtgui_container_t* container) { - rtgui_container_hide(container); rtgui_widget_destroy(RTGUI_WIDGET(container)); } @@ -296,26 +285,20 @@ rtgui_widget_t* rtgui_container_get_first_child(rtgui_container_t* container) return child; } -#ifndef RTGUI_USING_SMALL_SIZE void rtgui_container_set_box(rtgui_container_t* container, struct rtgui_box* box) { if (container == RT_NULL || box == RT_NULL) return; - rtgui_container_add_child(RTGUI_CONTAINER(container), RTGUI_WIDGET(box)); - rtgui_widget_set_rect(RTGUI_WIDGET(box), &(RTGUI_WIDGET(container)->extent)); + container->layout_box = box; + box->container = container; } -#endif -void rtgui_container_hide(rtgui_container_t* container) +void rtgui_container_layout(struct rtgui_container* container) { - if (container == RT_NULL) + if (container == RT_NULL || container->layout_box == RT_NULL) return; - if (RTGUI_WIDGET(container)->parent == RT_NULL) - { - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(container)); - return; - } + rtgui_box_layout(container->layout_box); } diff --git a/components/rtgui/widgets/filelist_view.c b/components/rtgui/widgets/filelist_view.c index 7d70b1f104..b3bf93f3e5 100644 --- a/components/rtgui/widgets/filelist_view.c +++ b/components/rtgui/widgets/filelist_view.c @@ -15,7 +15,7 @@ #include <rtgui/rtgui_object.h> #include <rtgui/rtgui_system.h> #include <rtgui/rtgui_theme.h> -#include <rtgui/rtgui_application.h> +#include <rtgui/rtgui_app.h> #include <rtgui/list.h> #include <rtgui/image.h> @@ -235,14 +235,14 @@ static struct rtgui_listbox_item items[] = }; static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view); -static void rtgui_filelist_view_on_folder_item(rtgui_widget_t* widget, struct rtgui_event* event) +static rt_bool_t rtgui_filelist_view_on_folder_item(rtgui_object_t* object, struct rtgui_event* event) { rtgui_win_t *menu; rtgui_listbox_t *listbox; rtgui_filelist_view_t *view; - listbox = RTGUI_LISTBOX(widget); - menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget)); + listbox = RTGUI_LISTBOX(object); + menu = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object))); view = RTGUI_FILELIST_VIEW(menu->user_data); /* hide window */ @@ -273,12 +273,14 @@ static void rtgui_filelist_view_on_folder_item(rtgui_widget_t* widget, struct rt rtgui_win_destroy(menu); break; } + + return RT_TRUE; } -static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_widget_t* widget, struct rtgui_event* event) +static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_object_t* object, struct rtgui_event* event) { rtgui_win_t *menu; - menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget)); + menu = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object))); /* destroy menu window */ rtgui_win_destroy(menu); @@ -295,7 +297,7 @@ static void rtgui_filelist_view_menu_pop(rtgui_widget_t *parent) rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &screen); rtgui_rect_moveto_align(&screen, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL); - menu = rtgui_win_create(rtgui_widget_get_toplevel(parent), + menu = rtgui_win_create(RTGUI_WIN(rtgui_widget_get_toplevel(parent)), "Folder Menu", &rect, RTGUI_WIN_STYLE_DEFAULT); if (menu != RT_NULL) { @@ -533,10 +535,12 @@ static void rtgui_filelist_view_onenturn(struct rtgui_filelist_view* view) } } -rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) +rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_object* object, struct rtgui_event* event) { + struct rtgui_widget *widget; struct rtgui_filelist_view* view = RT_NULL; + widget = RTGUI_WIDGET(object); view = RTGUI_FILELIST_VIEW(widget); switch (event->type) { @@ -650,7 +654,7 @@ rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct } /* use view event handler */ - return rtgui_container_event_handler(RTGUI_OBJECT(widget), event); + return rtgui_container_event_handler(object, event); } rtgui_filelist_view_t* rtgui_filelist_view_create(const char* directory, diff --git a/components/rtgui/widgets/iconbox.c b/components/rtgui/widgets/iconbox.c index 03db07bd83..ddd058cd97 100644 --- a/components/rtgui/widgets/iconbox.c +++ b/components/rtgui/widgets/iconbox.c @@ -66,6 +66,8 @@ rt_bool_t rtgui_iconbox_event_handler(struct rtgui_object* object, struct rtgui_ } break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/label.c b/components/rtgui/widgets/label.c index db8528e139..85ea6ceb44 100644 --- a/components/rtgui/widgets/label.c +++ b/components/rtgui/widgets/label.c @@ -49,6 +49,8 @@ rt_bool_t rtgui_label_event_handler(struct rtgui_object *object, struct rtgui_ev case RTGUI_EVENT_PAINT: rtgui_theme_draw_label(label); break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/listbox.c b/components/rtgui/widgets/listbox.c index 859cbc1304..e7d0dbbffb 100644 --- a/components/rtgui/widgets/listbox.c +++ b/components/rtgui/widgets/listbox.c @@ -267,17 +267,18 @@ rt_bool_t rtgui_listbox_event_handler(struct rtgui_object* object, struct rtgui_ { rt_int16_t old_item; - if (box->current_item == -1) + if (box->current_item == -1) { /* set a initial item */ - if ((box->items_count > 0) && + if ((box->items_count > 0) && (ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN)) { box->current_item = 0; rtgui_listbox_update_current(box, -1); - break; + return RT_TRUE; } - else return RT_FALSE; + else + return RT_FALSE; } old_item = box->current_item; @@ -287,32 +288,30 @@ rt_bool_t rtgui_listbox_event_handler(struct rtgui_object* object, struct rtgui_ if (box->current_item - box->page_items >= 0) box->current_item -= box->page_items; rtgui_listbox_update_current(box, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_UP: if (box->current_item > 0) box->current_item --; rtgui_listbox_update_current(box, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_RIGHT: if (box->current_item + box->page_items < box->items_count - 1) box->current_item += box->page_items; rtgui_listbox_update_current(box, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_DOWN: if (box->current_item < box->items_count - 1) box->current_item ++; rtgui_listbox_update_current(box, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_RETURN: if (box->on_item != RT_NULL) - { box->on_item(RTGUI_OBJECT(box), RT_NULL); - } - return RT_FALSE; + return RT_TRUE; default: break; diff --git a/components/rtgui/widgets/listctrl.c b/components/rtgui/widgets/listctrl.c index 6fdc4028d6..bc3b75e0f1 100644 --- a/components/rtgui/widgets/listctrl.c +++ b/components/rtgui/widgets/listctrl.c @@ -316,13 +316,13 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui if (ctrl->current_item - ctrl->page_items >= 0) ctrl->current_item -= ctrl->page_items; rtgui_listctrl_update_current(ctrl, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_UP: if (ctrl->current_item > 0) ctrl->current_item --; rtgui_listctrl_update_current(ctrl, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_RIGHT: if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1) @@ -333,18 +333,18 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items; } rtgui_listctrl_update_current(ctrl, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_DOWN: if (ctrl->current_item < ctrl->items_count - 1) ctrl->current_item ++; rtgui_listctrl_update_current(ctrl, old_item); - return RT_FALSE; + return RT_TRUE; case RTGUIK_RETURN: if (ctrl->on_item != RT_NULL) { - ctrl->on_item(RTGUI_OBJECT(ctrl), RT_NULL); + return ctrl->on_item(RTGUI_OBJECT(ctrl), RT_NULL); } return RT_FALSE; diff --git a/components/rtgui/widgets/menu.c b/components/rtgui/widgets/menu.c index c56041db83..6ff278f71c 100644 --- a/components/rtgui/widgets/menu.c +++ b/components/rtgui/widgets/menu.c @@ -40,10 +40,12 @@ static void _rtgui_menu_destructor(rtgui_menu_t* menu) static rt_bool_t _rtgui_menu_onitem(struct rtgui_object* object, struct rtgui_event* event) { struct rtgui_menu* menu; - RTGUI_WIDGET_EVENT_HANDLER_PREPARE + + /* event will be NULL, don't check it. */ + RT_ASSERT(object); /* get menu */ - menu = RTGUI_MENU(rtgui_widget_get_toplevel(widget)); + menu = RTGUI_MENU(rtgui_widget_get_toplevel(RTGUI_WIDGET(object))); if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU) { const rtgui_menu_item_t* items; @@ -84,7 +86,7 @@ static rt_bool_t _rtgui_menu_onitem(struct rtgui_object* object, struct rtgui_ev { /* invoke action */ if (menu->items[menu->items_list->current_item].on_menuaction != RT_NULL) - menu->items[menu->items_list->current_item].on_menuaction(RTGUI_WIDGET(menu), RT_NULL); + menu->items[menu->items_list->current_item].on_menuaction(RTGUI_OBJECT(menu), RT_NULL); /* hide sub-menu */ if (menu->sub_menu != RT_NULL) diff --git a/components/rtgui/widgets/notebook.c b/components/rtgui/widgets/notebook.c index c928cd268d..6b6f9ec49f 100644 --- a/components/rtgui/widgets/notebook.c +++ b/components/rtgui/widgets/notebook.c @@ -301,12 +301,16 @@ void rtgui_notebook_set_current_by_index(struct rtgui_notebook* notebook, rt_uin if ((index < notebook->count) && (notebook->current != index)) { + struct rtgui_widget *widget; + if (notebook->current != RTGUI_NOT_FOUND) rtgui_widget_hide(notebook->childs[notebook->current].widget); notebook->current = index; - rtgui_widget_show(notebook->childs[notebook->current].widget); - rtgui_widget_update(notebook->childs[notebook->current].widget); + widget = notebook->childs[notebook->current].widget; + rtgui_widget_show(widget); + rtgui_widget_update(widget); + rtgui_widget_focus(widget); } } @@ -319,6 +323,16 @@ struct rtgui_widget* rtgui_notebook_get_widget_at(struct rtgui_notebook* noteboo return RT_NULL; } +static rt_bool_t _rtgui_notebook_current_widget_handle(struct rtgui_notebook *notebook, + struct rtgui_event *event) +{ + struct rtgui_widget *widget = rtgui_notebook_get_current(notebook); + if (widget && widget != RTGUI_WIDGET(notebook)) + return RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget), event); + else + return RT_FALSE; +} + rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui_event* event) { struct rtgui_notebook* notebook; @@ -336,17 +350,18 @@ rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui case RTGUI_EVENT_MOUSE_BUTTON: _rtgui_notebook_onmouse(notebook, (struct rtgui_event_mouse*)event); break; + case RTGUI_EVENT_SHOW: + /* show myself */ + rtgui_widget_onshow(object, event); + /* show the tab widget */ + return _rtgui_notebook_current_widget_handle(notebook, event); + case RTGUI_EVENT_HIDE: + /* hide myself */ + rtgui_widget_onhide(object, event); + /* hide the tab widget */ + return _rtgui_notebook_current_widget_handle(notebook, event); case RTGUI_EVENT_KBD: - if (notebook->current != RTGUI_NOT_FOUND) - { - if (RTGUI_OBJECT(notebook->childs[notebook->current].widget - )->event_handler != RT_NULL) - return RTGUI_OBJECT(notebook->childs[notebook->current].widget - )->event_handler( - RTGUI_OBJECT(notebook->childs[notebook->current].widget), - event); - } - break; + return _rtgui_notebook_current_widget_handle(notebook, event); default: /* use parent event handler */ return rtgui_widget_event_handler(object, event); diff --git a/components/rtgui/widgets/panel.c b/components/rtgui/widgets/panel.c new file mode 100644 index 0000000000..a2aa912cc5 --- /dev/null +++ b/components/rtgui/widgets/panel.c @@ -0,0 +1,89 @@ +/* + * File : panel.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-07-07 Bernard implement panel as a widget + */ +#include <rtgui/dc.h> +#include <rtgui/widgets/panel.h> +#include <rtgui/rtgui_system.h> +#include <rtgui/rtgui_theme.h> + +static void _rtgui_panel_constructor(rtgui_panel_t *panel) +{ + /* init widget and set event handler */ + rtgui_object_set_event_handler(RTGUI_OBJECT(panel), rtgui_panel_event_handler); + + /* set field */ + panel->border_style = RTGUI_BORDER_NONE; +} + +DEFINE_CLASS_TYPE(panel, "panel", + RTGUI_CONTAINER_TYPE, + _rtgui_panel_constructor, + RT_NULL, + sizeof(struct rtgui_panel)); + +rt_bool_t rtgui_panel_event_handler(struct rtgui_object *object, struct rtgui_event* event) +{ + struct rtgui_panel* panel; + + panel = RTGUI_PANEL(object); + switch (event->type) + { + case RTGUI_EVENT_PAINT: + { + struct rtgui_dc* dc; + struct rtgui_rect rect; + + rtgui_widget_get_rect(RTGUI_WIDGET(object), &rect); + + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(object)); + if (dc == RT_NULL) return RT_FALSE; + + rtgui_dc_fill_rect(dc, &rect); + // rtgui_rect_inflate(&rect, RTGUI_WIDGET(panel)->); + rtgui_dc_draw_border(dc, &rect, panel->border_style); + + /* paint on each child */ + rtgui_container_dispatch_event(RTGUI_CONTAINER(panel), event); + + rtgui_dc_end_drawing(dc); + } + break; + + default: + return rtgui_container_event_handler(object, event); + } + + return RT_FALSE; +} + +rtgui_panel_t* rtgui_panel_create(int border_style) +{ + struct rtgui_panel* panel; + + panel = (struct rtgui_panel*) rtgui_widget_create(RTGUI_PANEL_TYPE); + if (panel != RT_NULL) + { + rtgui_rect_t rect = {0, 0, 100, 100}; + rtgui_widget_set_rect(RTGUI_WIDGET(panel), &rect); + + panel->border_style = border_style; + } + + return panel; +} + +void rtgui_panel_destroy(rtgui_panel_t* panel) +{ + rtgui_object_destroy(RTGUI_OBJECT(panel)); +} + diff --git a/components/rtgui/widgets/progressbar.c b/components/rtgui/widgets/progressbar.c index c42f2a3688..ea8a2bece9 100644 --- a/components/rtgui/widgets/progressbar.c +++ b/components/rtgui/widgets/progressbar.c @@ -38,6 +38,8 @@ rt_bool_t rtgui_progressbar_event_handler(struct rtgui_object* object, case RTGUI_EVENT_PAINT: rtgui_theme_draw_progressbar(bar); break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/radiobox.c b/components/rtgui/widgets/radiobox.c index b1def7af01..5f67d2fcbc 100644 --- a/components/rtgui/widgets/radiobox.c +++ b/components/rtgui/widgets/radiobox.c @@ -101,7 +101,7 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui #ifndef RTGUI_USING_SMALL_SIZE if (widget->on_key != RT_NULL) - widget->on_key(RTGUI_OBJECT(widget), event); + return widget->on_key(RTGUI_OBJECT(widget), event); else #endif { @@ -116,12 +116,18 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui if (e->key == RTGUIK_UP) { if (radiobox->item_selection > 0) + { rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1); + return RT_TRUE; + } } else if (e->key == RTGUIK_DOWN) { if (radiobox->item_selection < radiobox->item_count - 1) + { rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1); + return RT_TRUE; + } } } else @@ -129,12 +135,18 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui if (e->key == RTGUIK_LEFT) { if (radiobox->item_selection > 0) + { rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1); + return RT_TRUE; + } } else if (e->key == RTGUIK_RIGHT) { if (radiobox->item_selection < radiobox->item_count - 1) + { rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1); + return RT_TRUE; + } } } } @@ -150,6 +162,8 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui rtgui_radiobox_onmouse(radiobox, (struct rtgui_event_mouse*)event); } break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/scrollbar.c b/components/rtgui/widgets/scrollbar.c index 257591a028..4a6a63e471 100644 --- a/components/rtgui/widgets/scrollbar.c +++ b/components/rtgui/widgets/scrollbar.c @@ -302,7 +302,7 @@ rt_bool_t rtgui_scrollbar_event_handler(struct rtgui_object *object, break; default: - break; + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/slider.c b/components/rtgui/widgets/slider.c index ca71fdfaad..c3631cf0d5 100644 --- a/components/rtgui/widgets/slider.c +++ b/components/rtgui/widgets/slider.c @@ -168,13 +168,10 @@ rt_bool_t rtgui_slider_event_handler(struct rtgui_object *object, struct rtgui_e #ifndef RTGUI_USING_SMALL_SIZE if (widget->on_key != RT_NULL) - widget->on_key(RTGUI_OBJECT(widget), event); + return widget->on_key(RTGUI_OBJECT(widget), event); else #endif - { return rtgui_slider_onkey(slider, (struct rtgui_event_kbd *)event); - } - break; case RTGUI_EVENT_MOUSE_BUTTON: if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE; @@ -188,6 +185,9 @@ rt_bool_t rtgui_slider_event_handler(struct rtgui_object *object, struct rtgui_e rtgui_slider_onmouse(slider, (struct rtgui_event_mouse*)event); } break; + + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/staticline.c b/components/rtgui/widgets/staticline.c index 10bdd8bad8..0a2ea20079 100644 --- a/components/rtgui/widgets/staticline.c +++ b/components/rtgui/widgets/staticline.c @@ -36,6 +36,8 @@ rt_bool_t rtgui_staticline_event_handler(struct rtgui_object* object, struct rtg #endif rtgui_theme_draw_staticline(staticline); break; + default: + return rtgui_widget_event_handler(object, event); } return RT_FALSE; diff --git a/components/rtgui/widgets/textbox.c b/components/rtgui/widgets/textbox.c index a28b3ec5f9..df56cbc9ff 100644 --- a/components/rtgui/widgets/textbox.c +++ b/components/rtgui/widgets/textbox.c @@ -11,106 +11,197 @@ * Date Author Notes * 2009-10-16 Bernard first version * 2011-01-224 Bernard fix backspace issue. + * 2012-06-09 asml refactor + * 2012-06-17 Grissiom misc cleanup and merge */ -#include <rtgui/dc.h> -#include <rtgui/rtgui_theme.h> -#include <rtgui/rtgui_system.h> +#include <string.h> #include <rtgui/widgets/textbox.h> +#include <rtgui/widgets/combobox.h> +#include <rtgui/rtgui_system.h> -#ifndef _WIN32 #include <ctype.h> -#endif - -#define RTGUI_TEXTBOX_LINE_MAX 64 -#define RTGUI_TEXTBOX_MARGIN 3 - -static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kbd* event); -static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* object, struct rtgui_event* event); -static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* object, struct rtgui_event* event); - -static void _rtgui_textbox_caret_timeout(struct rtgui_timer* timer, void* parameter) -{ - rtgui_textbox_t* box; - - box = (rtgui_textbox_t*)parameter; - /* set caret flag */ - if (box->flag & RTGUI_TEXTBOX_CARET_SHOW) - box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; - else - box->flag |= RTGUI_TEXTBOX_CARET_SHOW; - - /* re-darw textbox */ - rtgui_theme_draw_textbox(box); - return ; -} +static void rtgui_textbox_draw_caret(rtgui_textbox_t *box, rt_uint16_t position); +static rt_bool_t rtgui_textbox_onkey(struct rtgui_object* widget, rtgui_event_t* event); +static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* widget, rtgui_event_t* event); +static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* widget, rtgui_event_t* event); static void _rtgui_textbox_constructor(rtgui_textbox_t *box) { - rtgui_rect_t rect = {0, 0, RTGUI_TEXTBOX_DEFAULT_WIDTH, RTGUI_TEXTBOX_DEFAULT_HEIGHT}; - rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect); + rtgui_rect_t rect; + + RTGUI_WIDGET_FLAG(RTGUI_WIDGET(box)) |= RTGUI_WIDGET_FLAG_FOCUSABLE; - RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_textbox_event_handler); rtgui_widget_set_onfocus(RTGUI_WIDGET(box), rtgui_textbox_onfocus); rtgui_widget_set_onunfocus(RTGUI_WIDGET(box), rtgui_textbox_onunfocus); +#ifndef RTGUI_USING_SMALL_SIZE + rtgui_widget_set_onkey(RTGUI_WIDGET(box),rtgui_textbox_onkey); +#endif + RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = black; + RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white; /* set default text align */ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL; - /* set proper of control */ - box->caret_timer = rtgui_timer_create(RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC, - _rtgui_textbox_caret_timeout, box); + box->caret_timer = RT_NULL; + box->caret = RT_NULL; box->line = box->line_begin = box->position = 0; box->flag = RTGUI_TEXTBOX_SINGLE; - /* allocate default line buffer */ box->text = RT_NULL; - rtgui_font_get_metrics(RTGUI_WIDGET(box)->gc.font, "h", &rect); + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(box)), "H", &rect); box->font_width = rtgui_rect_width(rect); + box->on_enter = RT_NULL; + box->dis_length = 0; } -static void _rtgui_textbox_deconstructor(rtgui_textbox_t *box) +static void _rtgui_textbox_deconstructor(rtgui_textbox_t *textbox) { - if (box->text != RT_NULL) + if(textbox->text != RT_NULL) { - rt_free(box->text); - box->text = RT_NULL; + rtgui_free(textbox->text); + textbox->text = RT_NULL; + } + if(textbox->caret_timer != RT_NULL) + { + rtgui_timer_destory(textbox->caret_timer); + textbox->caret_timer = RT_NULL; + } + if(textbox->caret != RT_NULL) + { + rtgui_free(textbox->caret); + textbox->caret = RT_NULL; } - - rtgui_timer_destory(box->caret_timer); - box->caret_timer = RT_NULL; } -DEFINE_CLASS_TYPE(textbox, "textbox", +DEFINE_CLASS_TYPE(textbox, "textbox", RTGUI_WIDGET_TYPE, _rtgui_textbox_constructor, _rtgui_textbox_deconstructor, sizeof(struct rtgui_textbox)); -static void rtgui_textbox_onmouse(struct rtgui_textbox* box, struct rtgui_event_mouse* event) +static void rtgui_textbox_get_caret_rect(rtgui_textbox_t *box, rtgui_rect_t *rect, rt_uint16_t position) +{ + int font_h,box_h; + rtgui_rect_t item_rect; + + RT_ASSERT(box != RT_NULL); + + rtgui_widget_get_rect(RTGUI_WIDGET(box), rect); + + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(box)), "H", &item_rect); + font_h = rtgui_rect_height(item_rect); + box_h = rtgui_rect_height(*rect); + + rect->x1 += position * box->font_width + 2; + rect->x2 = rect->x1 + 2; + rect->y1 += (box_h - font_h) / 2; + rect->y2 = rect->y1 + font_h; +} + +static void rtgui_textbox_init_caret(rtgui_textbox_t *box, rt_uint16_t position) +{ + int x, y; + rtgui_color_t color; + rtgui_rect_t rect; + int ofs = 0; + + RT_ASSERT(box != RT_NULL); + + if (!RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box))) + return; + + rtgui_textbox_get_caret_rect(box, &box->caret_rect, position); + rect = box->caret_rect; + rtgui_widget_rect_to_device(RTGUI_WIDGET(box), &rect); + + if (box->caret == RT_NULL) + box->caret = rtgui_malloc(rtgui_rect_width(rect)*rtgui_rect_height(rect)*sizeof(rtgui_color_t)); + + for (x = rect.x1; x < rect.x2; x++) + { + for(y = rect.y1; y < rect.y2; y++) + { + rtgui_graphic_driver_get_default()->ops->get_pixel(&color, x, y); + *(box->caret + ofs) = color; + ofs++; + } + } +} + +/* draw caret */ +static void rtgui_textbox_draw_caret(rtgui_textbox_t *box, rt_uint16_t position) +{ + int x,y; + rtgui_color_t color; + rtgui_rect_t rect; + int ofs = 0; + struct rtgui_dc *dc; + + RT_ASSERT(box != RT_NULL); + if (box->caret == RT_NULL) + return; + + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box)); + if (dc == RT_NULL) + return; + + rect = box->caret_rect; + + for(x = rect.x1; x < rect.x2; x++) + { + for(y = rect.y1; y < rect.y2; y++) + { + color = *(box->caret + ofs); + ofs++; + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW) + { + color = ~color; + } + rtgui_dc_draw_color_point(dc, x, y, color); + } + } + + rtgui_dc_end_drawing(dc); +} + +static void rtgui_textbox_timeout(rtgui_timer_t* timer, void* parameter) +{ + rtgui_textbox_t* box; + + box = RTGUI_TEXTBOX(parameter); + /* set caret flag */ + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW) + box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; + else + box->flag |= RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box,box->position); +} + +static void rtgui_textbox_onmouse(rtgui_textbox_t* box, struct rtgui_event_mouse* event) { rt_size_t length; + rt_uint16_t posbak = box->position; RT_ASSERT(box != RT_NULL); RT_ASSERT(event != RT_NULL); - length = rt_strlen((const char*)box->text); + length = rt_strlen(box->text); - if (event->button & RTGUI_MOUSE_BUTTON_LEFT && - event->button & RTGUI_MOUSE_BUTTON_DOWN) + if(event->button & RTGUI_MOUSE_BUTTON_LEFT && event->button & RTGUI_MOUSE_BUTTON_DOWN) { rt_int32_t x; - + /* single line text */ /* set caret position */ x = event->x - RTGUI_WIDGET(box)->extent.x1; - if (x < 0) + if(x < 0) { box->position = 0; } - else if (x > length * box->font_width) + else if(x > length * box->font_width) { box->position = length; } @@ -119,30 +210,54 @@ static void rtgui_textbox_onmouse(struct rtgui_textbox* box, struct rtgui_event_ box->position = x / box->font_width; } - /* set caret to show */ - box->flag |= RTGUI_TEXTBOX_CARET_SHOW; + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW) + { + if(box->caret_timer != RT_NULL) + rtgui_timer_stop(box->caret_timer); + + box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box, posbak); - /* set widget focus */ - rtgui_widget_focus(RTGUI_WIDGET(box)); - /* re-draw text box */ - rtgui_theme_draw_textbox(box); + if(box->caret_timer != RT_NULL) + rtgui_timer_start(box->caret_timer); + } + + rtgui_textbox_init_caret(box, box->position); + box->flag |= RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box,box->position); } } -static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kbd* event) +static rt_bool_t rtgui_textbox_onkey(struct rtgui_object* widget, rtgui_event_t* event) { + rtgui_textbox_t* box = RTGUI_TEXTBOX(widget); + struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; rt_size_t length; + rt_uint16_t posbak = box->position; RT_ASSERT(box != RT_NULL); - RT_ASSERT(event != RT_NULL); + RT_ASSERT(ekbd != RT_NULL); - if (event->type != RTGUI_KEYUP) - return ; + /* handle the key at down time and nothing to do with up */ + if (RTGUI_KBD_IS_UP(ekbd)) + return RT_TRUE; - length = rt_strlen((const char*)box->text); - if (event->key == RTGUIK_DELETE) + if (box->dis_length == 0) { - if (box->position == length - 1) + rtgui_rect_t rect; + + rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect); + + if (box->font_width == 0) + return RT_FALSE; + + box->dis_length = (rtgui_rect_width(rect) - 5) / box->font_width; + } + + length = rt_strlen(box->text); + if(ekbd->key == RTGUIK_DELETE) + {/* delete latter character */ + if(box->position == length - 1) { box->text[box->position] = '\0'; } @@ -151,197 +266,278 @@ static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kb char *c; /* remove character */ - for (c = &box->text[box->position]; c[1] != '\0'; c++) + for(c = &box->text[box->position]; c[1] != '\0'; c++) *c = c[1]; *c = '\0'; } } - else if (event->key == RTGUIK_BACKSPACE) - { - if ((box->position == length - 1) && length != 1) + else if(ekbd->key == RTGUIK_BACKSPACE) + {/* delete front character */ + + if(box->position == length - 1) { box->text[box->position] = '\0'; box->position --; } - else if (box->position != 0) + else if(box->position != 0) { /* remove current character */ - char *c; + if(box->position != 0) + { + char *c; - /* remove character */ - for (c = &box->text[box->position - 1]; c[1] != '\0'; c++) - *c = c[1]; - *c = '\0'; + /* remove character */ + for(c = &box->text[box->position - 1]; c[1] != '\0'; c++) + *c = c[1]; + *c = '\0'; + } box->position --; } } - else if (event->key == RTGUIK_LEFT) - { - if (box->position > 0) box->position --; + else if(ekbd->key == RTGUIK_LEFT) + {/* move to prev */ + if(box->position > 0) + { + box->position --; + } } - else if (event->key == RTGUIK_RIGHT) - { - if (box->position < length) box->position ++; + else if(ekbd->key == RTGUIK_RIGHT) + {/* move to next */ + if(box->position < length) + { + box->position ++; + } } - else if (event->key == RTGUIK_HOME) - { + else if(ekbd->key == RTGUIK_HOME) + {/* move cursor to start */ box->position = 0; } - else if (event->key == RTGUIK_END) - { + else if(ekbd->key == RTGUIK_END) + {/* move cursor to end */ box->position = length; } - else if (event->key == RTGUIK_RETURN) + else if(ekbd->key == RTGUIK_RETURN) { - if (box->on_enter != RT_NULL) + if(box->on_enter != RT_NULL) { - box->on_enter(RTGUI_WIDGET(box), RT_NULL); + box->on_enter(box, event); } } + else if(ekbd->key == RTGUIK_NUMLOCK) + { + /* change numlock state */ + /* + extern void update_number_lock(void); + update_number_lock(); + */ + } else { - if (isprint(event->key) || isdigit(event->key)) - { + if(isprint(ekbd->key)) + {/* it's may print character */ /* no buffer on this line */ - if (length + 1 > box->line_length) return; + if(box->flag & RTGUI_TEXTBOX_DIGIT) + {/* only input digit */ + if(!isdigit(ekbd->key)) + {/* exception: '.' and '-' */ + if(ekbd->key != '.' && ekbd->key !='-')return RT_FALSE; + if(ekbd->key == '.' && strchr(box->text,'.'))return RT_FALSE; + + if(ekbd->key == '-') + { + if(length+1 > box->line_length) return RT_FALSE; + if(length+1 > box->dis_length) return RT_FALSE; - if (box->position < length - 1) + if(strchr(box->text,'-')) + { + char* c; + for(c = &box->text[0]; c != &box->text[length]; c++) + *c = *(c+1); + box->text[length] = '\0'; + box->position --; + goto _exit; + } + else + { + char* c; + for(c = &box->text[length]; c != &box->text[0]; c--) + *c = *(c-1); + box->text[0] = '-'; + box->text[length+1] = '\0'; + box->position ++; + goto _exit; + } + } + } + //rt_kprintf("%c ",ekbd->key);//debug printf + } + if(length+1 > box->line_length) return RT_FALSE; + if(length+1 > box->dis_length) return RT_FALSE; + + if(box->position <= length-1) { char* c; - for (c = &box->text[length]; c != &box->text[box->position]; c--) + for(c = &box->text[length]; c != &box->text[box->position]; c--) *c = *(c-1); - box->text[length + 1] = '\0'; + box->text[length+1] = '\0'; } - box->text[box->position] = event->key; + box->text[box->position] = ekbd->key; box->position ++; } } - /* set caret to show */ - box->flag |= RTGUI_TEXTBOX_CARET_SHOW; +_exit: + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW) + { + if(box->caret_timer != RT_NULL) + rtgui_timer_stop(box->caret_timer); - /* re-draw text box */ - rtgui_theme_draw_textbox(box); -} + box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box, posbak);/* refresh it */ + if(box->caret_timer != RT_NULL) + rtgui_timer_start(box->caret_timer); + } -static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* object, struct rtgui_event* event) -{ - struct rtgui_textbox* box; - RTGUI_WIDGET_EVENT_HANDLER_PREPARE + /* re-draw text box */ + rtgui_textbox_ondraw(box); - box = RTGUI_TEXTBOX(object); - /* set caret to show */ + rtgui_textbox_init_caret(box, box->position); box->flag |= RTGUI_TEXTBOX_CARET_SHOW; - /* start caret timer */ - rtgui_timer_start(box->caret_timer); + rtgui_textbox_draw_caret(box,box->position); return RT_TRUE; } -static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* object, struct rtgui_event* event) +static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* widget, rtgui_event_t* event) { - struct rtgui_textbox* box; - RTGUI_WIDGET_EVENT_HANDLER_PREPARE + rtgui_textbox_t* box = RTGUI_TEXTBOX(widget); - box = RTGUI_TEXTBOX(object); - /* stop caret timer */ - rtgui_timer_stop(box->caret_timer); - /* set caret to hide */ - box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; + /* if there is already a timer, don't create another one. */ + if (box->caret_timer == RT_NULL) + { + box->caret_timer = rtgui_timer_create(100, RT_TIMER_FLAG_PERIODIC,rtgui_textbox_timeout, box); + /* set caret to show */ + box->flag |= RTGUI_TEXTBOX_CARET_SHOW; + /* start caret timer */ + if(box->caret_timer != RT_NULL) + rtgui_timer_start(box->caret_timer); + } return RT_TRUE; } -rt_bool_t rtgui_textbox_event_handler(struct rtgui_object* object, struct rtgui_event* event) +static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* widget, rtgui_event_t* event) { - struct rtgui_textbox* box; - RTGUI_WIDGET_EVENT_HANDLER_PREPARE + rtgui_textbox_t* box = RTGUI_TEXTBOX(widget); - box = RTGUI_TEXTBOX(object); - switch (event->type) + /* stop caret timer */ + if(box->caret_timer != RT_NULL) { - case RTGUI_EVENT_PAINT: -#ifndef RTGUI_USING_SMALL_SIZE - if (widget->on_draw != RT_NULL) - widget->on_draw(RTGUI_OBJECT(widget), event); - else -#endif - rtgui_theme_draw_textbox(box); - break; - - case RTGUI_EVENT_MOUSE_BUTTON: - if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE; - -#ifndef RTGUI_USING_SMALL_SIZE - if (widget->on_mouseclick != RT_NULL) - widget->on_mouseclick(RTGUI_OBJECT(widget), event); - else -#endif - rtgui_textbox_onmouse(box, (struct rtgui_event_mouse*)event); - return RT_TRUE; - - case RTGUI_EVENT_KBD: - if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE; - -#ifndef RTGUI_USING_SMALL_SIZE - if (widget->on_key != RT_NULL) - widget->on_key(RTGUI_OBJECT(widget), event); - else -#endif - rtgui_textbox_onkey(box, (struct rtgui_event_kbd*)event); - return RT_TRUE; + rtgui_timer_stop(box->caret_timer); + rtgui_timer_destory(box->caret_timer); + box->caret_timer = RT_NULL; } + /* set caret to hide */ + box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; + rtgui_textbox_draw_caret(box,box->position); - return RT_FALSE; + if(box->on_enter != RT_NULL) + box->on_enter(box,event); + + return RT_TRUE; } -struct rtgui_textbox* rtgui_textbox_create(const char* text, rt_uint8_t flag) +rtgui_textbox_t* rtgui_textbox_create(const char* text, rt_uint32_t flag) { - struct rtgui_textbox* box; + rtgui_textbox_t* box; - box = (struct rtgui_textbox*) rtgui_widget_create (RTGUI_TEXTBOX_TYPE); - if (box != RT_NULL) + box = (struct rtgui_textbox*)rtgui_widget_create(RTGUI_TEXTBOX_TYPE); + if(box != RT_NULL) { - rtgui_rect_t rect = {0, 0, RTGUI_TEXTBOX_DEFAULT_WIDTH, RTGUI_TEXTBOX_DEFAULT_HEIGHT}; - /* allocate default line buffer */ rtgui_textbox_set_value(box, text); box->flag = flag; - - rtgui_font_get_metrics(RTGUI_WIDGET(box)->gc.font, "h", &rect); } return box; } -void rtgui_textbox_destroy(struct rtgui_textbox* box) +void rtgui_textbox_destroy(rtgui_textbox_t* box) { rtgui_widget_destroy(RTGUI_WIDGET(box)); } -void rtgui_textbox_set_value(struct rtgui_textbox* box, const char* text) +void rtgui_textbox_ondraw(rtgui_textbox_t* box) { - if (box->text != RT_NULL) + /* draw button */ + rtgui_rect_t rect; + struct rtgui_dc* dc; + rtgui_color_t fc; + + RT_ASSERT(box != RT_NULL); + + /* begin drawing */ + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box)); + if (dc == RT_NULL) + return; + + /* get widget rect */ + rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect); + fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)); + + rtgui_rect_inflate(&rect, -1); + + /* fill widget rect with white color */ + RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white; + rtgui_dc_fill_rect(dc,&rect); + + rtgui_rect_inflate(&rect, 1); + /* draw border */ + RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = RTGUI_RGB(123, 158, 189); + rtgui_dc_draw_rect(dc, &rect); + + /* draw text */ + RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = fc; + if(box->text != RT_NULL) { - if (box->line_length > rt_strlen(text) + 1) + rect.x1 += RTGUI_WIDGET_DEFAULT_MARGIN; + /* draw single text */ + if(box->flag & RTGUI_TEXTBOX_MASK) { - rt_memcpy(box->text, text, rt_strlen(text) + 1); - /* set current position */ - box->position = 0; - return; + /* draw '*' */ + rt_size_t len = rt_strlen(box->text); + if(len > 0) + { + char *text_mask = rtgui_malloc(len + 1); + rt_memset(text_mask, '*', len + 1); + text_mask[len] = 0; + rtgui_dc_draw_text(dc, text_mask, &rect); + rtgui_free(text_mask); + } } else { - /* free the old text */ - rtgui_free(box->text); - box->text = RT_NULL; + rtgui_dc_draw_text(dc, box->text, &rect); } } - box->line_length = RTGUI_TEXTBOX_LINE_MAX > rt_strlen(text) + 1 ? - RTGUI_TEXTBOX_LINE_MAX : rt_strlen(text) + 1; + rtgui_dc_end_drawing(dc); +} + +/* set textbox text */ +void rtgui_textbox_set_value(rtgui_textbox_t* box, const char* text) +{ + if(box->text != RT_NULL) + {/* yet exist something */ + /* free the old text */ + rtgui_free(box->text); + box->text = RT_NULL; + } + + /* no something */ + box->line_length = ((rt_strlen(text)+1)/RTGUI_TEXTBOX_LINE_MAX+1)*RTGUI_TEXTBOX_LINE_MAX; /* allocate line buffer */ box->text = rtgui_malloc(box->line_length); @@ -351,25 +547,26 @@ void rtgui_textbox_set_value(struct rtgui_textbox* box, const char* text) rt_memcpy(box->text, text, rt_strlen(text) + 1); /* set current position */ - box->position = 0; + box->position = rt_strlen(text); } -const char* rtgui_textbox_get_value(struct rtgui_textbox* box) +const char* rtgui_textbox_get_value(rtgui_textbox_t* box) { return (const char*)box->text; } -void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length) +void rtgui_textbox_set_line_length(rtgui_textbox_t* box, rt_size_t length) { rt_uint8_t* new_line; RT_ASSERT(box != RT_NULL); /* invalid length */ - if (length <= 0) return; + if(length <= 0) + return; new_line = rtgui_malloc(length); - if (length < box->line_length) + if(length < box->line_length) { rt_memcpy(new_line, box->text, length - 1); new_line[length] = '\0'; @@ -383,3 +580,51 @@ void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length) box->line_length = length; } +/* get textbox text area */ +void rtgui_textbox_get_edit_rect(rtgui_textbox_t *box,rtgui_rect_t *rect) +{ + rtgui_widget_get_rect(RTGUI_WIDGET(box), rect); + rtgui_rect_inflate(rect,-1); +} + +rt_bool_t rtgui_textbox_event_handler(struct rtgui_object *object, rtgui_event_t* event) +{ + rtgui_widget_t *widget = RTGUI_WIDGET(object); + rtgui_textbox_t* box = RTGUI_TEXTBOX(object); + + switch (event->type) + { + case RTGUI_EVENT_PAINT: +#ifndef RTGUI_USING_SMALL_SIZE + if(widget->on_draw != RT_NULL) + widget->on_draw(RTGUI_OBJECT(widget), event); + else +#endif + rtgui_textbox_ondraw(box); + break; + + case RTGUI_EVENT_MOUSE_BUTTON: +#ifndef RTGUI_USING_SMALL_SIZE + if(widget->on_mouseclick != RT_NULL) + widget->on_mouseclick(RTGUI_OBJECT(widget), event); + else +#endif + rtgui_textbox_onmouse(box, (struct rtgui_event_mouse*)event); + return RT_TRUE; + + case RTGUI_EVENT_KBD: +#ifndef RTGUI_USING_SMALL_SIZE + if(widget->on_key != RT_NULL) + widget->on_key(RTGUI_OBJECT(widget), event); + else +#endif + rtgui_textbox_onkey(RTGUI_OBJECT(box), (struct rtgui_event*)event); + return RT_TRUE; + + default: + return rtgui_widget_event_handler(RTGUI_OBJECT(widget),event); + } + + return RT_FALSE; +} + diff --git a/components/rtgui/widgets/textview.c b/components/rtgui/widgets/textview.c index fe57b82ab2..af16854198 100644 --- a/components/rtgui/widgets/textview.c +++ b/components/rtgui/widgets/textview.c @@ -307,6 +307,8 @@ rt_bool_t rtgui_textview_event_handler(struct rtgui_object* object, struct rtgui } break; } + default: + return rtgui_widget_event_handler(RTGUI_OBJECT(widget),event); } return RT_FALSE; diff --git a/components/rtgui/widgets/widget.c b/components/rtgui/widgets/widget.c index e639eb8bed..dbdd644ce2 100644 --- a/components/rtgui/widgets/widget.c +++ b/components/rtgui/widgets/widget.c @@ -14,7 +14,7 @@ */ #include <rtgui/dc_client.h> -#include <rtgui/rtgui_application.h> +#include <rtgui/rtgui_app.h> #include <rtgui/widgets/widget.h> #include <rtgui/widgets/window.h> #include <rtgui/widgets/container.h> @@ -36,9 +36,7 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget) widget->gc.font = rtgui_font_default(); widget->gc.textstyle = RTGUI_TEXTSTYLE_NORMAL; widget->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP; -#ifndef RTGUI_USING_SMALL_SIZE widget->align = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP; -#endif /* set parent and toplevel root */ widget->parent = RT_NULL; @@ -88,7 +86,7 @@ static void _rtgui_widget_destructor(rtgui_widget_t *widget) rtgui_region_fini(&(widget->clip)); } -DEFINE_CLASS_TYPE(widget, "widget", +DEFINE_CLASS_TYPE(widget, "widget", RTGUI_OBJECT_TYPE, _rtgui_widget_constructor, _rtgui_widget_destructor, @@ -114,11 +112,9 @@ void rtgui_widget_set_rect(rtgui_widget_t* widget, const rtgui_rect_t* rect) widget->extent = *rect; -#ifndef RTGUI_USING_SMALL_SIZE /* reset mini width and height */ widget->mini_width = rtgui_rect_width(widget->extent); widget->mini_height = rtgui_rect_height(widget->extent); -#endif /* it's not empty, fini it */ if (rtgui_region_not_empty(&(widget->clip))) @@ -166,7 +162,6 @@ void rtgui_widget_get_extent(rtgui_widget_t* widget, rtgui_rect_t *rect) *rect = widget->extent; } -#ifndef RTGUI_USING_SMALL_SIZE void rtgui_widget_set_miniwidth(rtgui_widget_t* widget, int width) { RT_ASSERT(widget != RT_NULL); @@ -180,7 +175,6 @@ void rtgui_widget_set_miniheight(rtgui_widget_t* widget, int height) widget->mini_height = height; } -#endif /* * This function moves widget and its children to a logic point @@ -410,16 +404,16 @@ struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget) rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* event) { -#ifndef RTGUI_USING_SMALL_SIZE - struct rtgui_widget *widget; - RT_ASSERT(object != RT_NULL); RT_ASSERT(event != RT_NULL); - widget = RTGUI_WIDGET(object); - switch (event->type) { + case RTGUI_EVENT_SHOW: + return rtgui_widget_onshow(object, event); + case RTGUI_EVENT_HIDE: + return rtgui_widget_onhide(object, event); +#ifndef RTGUI_USING_SMALL_SIZE case RTGUI_EVENT_PAINT: if (widget->on_draw != RT_NULL) return widget->on_draw(RTGUI_OBJECT(widget), event); @@ -444,8 +438,8 @@ rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* if (widget->on_size != RT_NULL) return widget->on_size(RTGUI_OBJECT(widget), event); break; - } #endif + } return RT_FALSE; } @@ -512,12 +506,26 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget) } } -void rtgui_widget_show(rtgui_widget_t* widget) +void rtgui_widget_show(struct rtgui_widget *widget) { - /* there is no parent or the parent is hide, no show at all */ - if (widget->parent == RT_NULL || - RTGUI_WIDGET_IS_HIDE(widget->parent)) - return; + struct rtgui_event_show eshow; + RT_ASSERT(widget != RT_NULL); + + if (!RTGUI_WIDGET_IS_HIDE(widget)) + return; + + RTGUI_EVENT_SHOW_INIT(&eshow); + if (RTGUI_OBJECT(widget)->event_handler != RT_NULL) + { + RTGUI_OBJECT(widget)->event_handler( + RTGUI_OBJECT(widget), + &eshow); + } +} + +rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *event) +{ + struct rtgui_widget *widget = RTGUI_WIDGET(object); /* update the clip info of widget */ RTGUI_WIDGET_UNHIDE(widget); @@ -525,10 +533,14 @@ void rtgui_widget_show(rtgui_widget_t* widget) if (widget->on_show != RT_NULL) widget->on_show(RTGUI_OBJECT(widget), RT_NULL); + + return RT_FALSE; } -void rtgui_widget_hide(rtgui_widget_t* widget) +rt_bool_t rtgui_widget_onhide(struct rtgui_object *object, struct rtgui_event *event) { + struct rtgui_widget *widget = RTGUI_WIDGET(object); + /* hide this widget */ RTGUI_WIDGET_HIDE(widget); @@ -549,12 +561,31 @@ void rtgui_widget_hide(rtgui_widget_t* widget) if (widget->on_hide != RT_NULL) widget->on_hide(RTGUI_OBJECT(widget), RT_NULL); + + return RT_FALSE; +} + +void rtgui_widget_hide(struct rtgui_widget *widget) +{ + struct rtgui_event_hide ehide; + RT_ASSERT(widget != RT_NULL); + + if (RTGUI_WIDGET_IS_HIDE(widget)) + return; + + RTGUI_EVENT_HIDE_INIT(&ehide); + if (RTGUI_OBJECT(widget)->event_handler != RT_NULL) + { + RTGUI_OBJECT(widget)->event_handler( + RTGUI_OBJECT(widget), + &ehide); + } } rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t* widget) { rtgui_widget_t* parent; - + /* get parent widget */ parent = widget->parent; while (parent->parent != RT_NULL && (RTGUI_WIDGET_FLAG(parent) & RTGUI_WIDGET_FLAG_TRANSPARENT)) @@ -591,6 +622,9 @@ void rtgui_widget_update(rtgui_widget_t* widget) RT_ASSERT(widget != RT_NULL); + if (RTGUI_WIDGET_IS_HIDE(widget)) + return; + if (RTGUI_OBJECT(widget)->event_handler != RT_NULL) { RTGUI_OBJECT(widget)->event_handler( diff --git a/components/rtgui/widgets/window.c b/components/rtgui/widgets/window.c index f8d5db3d24..515817cd21 100644 --- a/components/rtgui/widgets/window.c +++ b/components/rtgui/widgets/window.c @@ -16,7 +16,7 @@ #include <rtgui/image.h> #include <rtgui/rtgui_system.h> #include <rtgui/rtgui_server.h> -#include <rtgui/rtgui_application.h> +#include <rtgui/rtgui_app.h> #include <rtgui/widgets/window.h> #include <rtgui/widgets/button.h> @@ -108,10 +108,6 @@ DEFINE_CLASS_TYPE(win, "win", _rtgui_win_destructor, sizeof(struct rtgui_win)); -#ifdef RTGUI_USING_DESKTOP_WINDOW -static struct rtgui_win *the_desktop_window; -#endif - rtgui_win_t* rtgui_win_create(struct rtgui_win* parent_window, const char* title, rtgui_rect_t *rect, @@ -125,23 +121,7 @@ rtgui_win_t* rtgui_win_create(struct rtgui_win* parent_window, return RT_NULL; /* set parent toplevel */ -#ifdef RTGUI_USING_DESKTOP_WINDOW - if (style & RTGUI_WIN_STYLE_DESKTOP) - { - RT_ASSERT(the_desktop_window == RT_NULL); - win->parent_window = RT_NULL; - the_desktop_window = win; - } - else if (parent_window == RT_NULL) - { - RT_ASSERT(the_desktop_window != RT_NULL); - win->parent_window = the_desktop_window; - } - else - win->parent_window = parent_window; -#else win->parent_window = parent_window; -#endif /* set title, rect and style */ if (title != RT_NULL) @@ -163,25 +143,13 @@ __on_err: return RT_NULL; } -void rtgui_win_destroy(struct rtgui_win* win) -{ - if (win->flag & RTGUI_WIN_FLAG_MODAL) - { - /* set the RTGUI_WIN_STYLE_DESTROY_ON_CLOSE flag so the window will be - * destroyed after the event_loop */ - win->style |= RTGUI_WIN_STYLE_DESTROY_ON_CLOSE; - rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL); - } - else - rtgui_widget_destroy(RTGUI_WIDGET(win)); -} - static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win, - struct rtgui_event *event) + struct rtgui_event *event, + rt_bool_t force_close) { if (win->on_close != RT_NULL) { - if (win->on_close(RTGUI_OBJECT(win), event) == RT_FALSE) + if ((win->on_close(RTGUI_OBJECT(win), event) == RT_FALSE) && !force_close) return RT_FALSE; } @@ -201,6 +169,42 @@ static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win, return RT_TRUE; } +void rtgui_win_destroy(struct rtgui_win* win) +{ + /* close the window first if it's not. */ + if (!(win->flag & RTGUI_WIN_FLAG_CLOSED)) + { + struct rtgui_event_win_close eclose; + + RTGUI_EVENT_WIN_CLOSE_INIT(&eclose); + eclose.wid = win; + + if (win->style & RTGUI_WIN_STYLE_DESTROY_ON_CLOSE) + { + _rtgui_win_deal_close(win, + (struct rtgui_event*)&eclose, + RT_TRUE); + return; + } + else + _rtgui_win_deal_close(win, + (struct rtgui_event*)&eclose, + RT_TRUE); + } + + if (win->flag & RTGUI_WIN_FLAG_MODAL) + { + /* set the RTGUI_WIN_STYLE_DESTROY_ON_CLOSE flag so the window will be + * destroyed after the event_loop */ + win->style |= RTGUI_WIN_STYLE_DESTROY_ON_CLOSE; + rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL); + } + else + { + rtgui_widget_destroy(RTGUI_WIDGET(win)); + } +} + /* send a close event to myself to get a consistent behavior */ rt_bool_t rtgui_win_close(struct rtgui_win* win) { @@ -209,14 +213,17 @@ rt_bool_t rtgui_win_close(struct rtgui_win* win) RTGUI_EVENT_WIN_CLOSE_INIT(&eclose); eclose.wid = win; return _rtgui_win_deal_close(win, - (struct rtgui_event*)&eclose); + (struct rtgui_event*)&eclose, + RT_FALSE); } rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal) { - struct rtgui_event_win_show eshow; rt_base_t exit_code = -1; + struct rtgui_app *app; + struct rtgui_event_win_show eshow; + app = rtgui_app_self(); RTGUI_EVENT_WIN_SHOW_INIT(&eshow); eshow.wid = win; @@ -230,29 +237,33 @@ rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal) return exit_code; } + /* set window unhidden before notify the server */ + rtgui_widget_show(RTGUI_WIDGET(win)); + if (rtgui_server_post_event_sync(RTGUI_EVENT(&eshow), - sizeof(struct rtgui_event_win_show) - ) != RT_EOK) + sizeof(struct rtgui_event_win_show)) != RT_EOK) { - rt_kprintf("show win failed\n"); + /* It could not be shown if a parent window is hidden. */ + rtgui_widget_hide(RTGUI_WIDGET(win)); return exit_code; } - /* set window unhidden */ - RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win)); - if (win->focused_widget == RT_NULL) rtgui_widget_focus(RTGUI_WIDGET(win)); + /* set main window */ + if (app->main_object == RT_NULL) + rtgui_app_set_main_win(win); + if (is_modal == RT_TRUE) { - struct rtgui_application *app; + struct rtgui_app *app; struct rtgui_event_win_modal_enter emodal; RTGUI_EVENT_WIN_MODAL_ENTER_INIT(&emodal); emodal.wid = win; - app = rtgui_application_self(); + app = rtgui_app_self(); RT_ASSERT(app != RT_NULL); win->flag |= RTGUI_WIN_FLAG_MODAL; @@ -263,7 +274,7 @@ rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal) app->modal_object = RTGUI_OBJECT(win); - exit_code = rtgui_application_run(app); + exit_code = rtgui_app_run(app); app->modal_object = RT_NULL; win->flag &= ~RTGUI_WIN_FLAG_MODAL; @@ -282,7 +293,7 @@ void rtgui_win_end_modal(struct rtgui_win* win, rtgui_modal_code_t modal_code) if (win == RT_NULL || !(win->flag & RTGUI_WIN_FLAG_MODAL)) return; - rtgui_application_exit(rtgui_application_self(), modal_code); + rtgui_app_exit(rtgui_app_self(), modal_code); /* remove modal mode */ win->flag &= ~RTGUI_WIN_FLAG_MODAL; @@ -291,9 +302,6 @@ void rtgui_win_end_modal(struct rtgui_win* win, rtgui_modal_code_t modal_code) void rtgui_win_hiden(struct rtgui_win* win) { RT_ASSERT(win != RT_NULL); -#ifdef RTGUI_USING_DESKTOP_WINDOW - RT_ASSERT(win != the_desktop_window); -#endif if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)) && win->flag & RTGUI_WIN_FLAG_CONNECTED) @@ -310,12 +318,21 @@ void rtgui_win_hiden(struct rtgui_win* win) return; } - /* set window hide and deactivated */ - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win)); + rtgui_widget_hide(RTGUI_WIDGET(win)); win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE; } } +rt_err_t rtgui_win_activate(struct rtgui_win *win) +{ + struct rtgui_event_win_activate eact; + RTGUI_EVENT_WIN_ACTIVATE_INIT(&eact); + eact.wid = win; + + return rtgui_server_post_event_sync(RTGUI_EVENT(&eact), + sizeof(eact)); +} + rt_bool_t rtgui_win_is_activated(struct rtgui_win* win) { RT_ASSERT(win != RT_NULL); @@ -341,7 +358,7 @@ void rtgui_win_move(struct rtgui_win* win, int x, int y) if (win->flag & RTGUI_WIN_FLAG_CONNECTED) { /* set win hide firstly */ - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win)); + rtgui_widget_hide(RTGUI_WIDGET(win)); emove.wid = win; emove.x = x; @@ -354,7 +371,7 @@ void rtgui_win_move(struct rtgui_win* win, int x, int y) } /* set window visible */ - RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win)); + rtgui_widget_show(RTGUI_WIDGET(win)); return; } @@ -405,7 +422,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object* object, struct rtgui_even break; case RTGUI_EVENT_WIN_CLOSE: - _rtgui_win_deal_close(win, event); + _rtgui_win_deal_close(win, event, RT_FALSE); /* don't broadcast WIN_CLOSE event to others */ return RT_TRUE; @@ -522,20 +539,21 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object* object, struct rtgui_even /* we should dispatch key event firstly */ if (!(win->flag & RTGUI_WIN_FLAG_HANDLE_KEY)) { + struct rtgui_widget *widget; rt_bool_t res = RT_FALSE; /* we should dispatch the key event just once. Once entered the * dispatch mode, we should swtich to key handling mode. */ win->flag |= RTGUI_WIN_FLAG_HANDLE_KEY; /* dispatch the key event */ - if (win->focused_widget != RT_NULL && - RTGUI_OBJECT(win->focused_widget)->event_handler != RT_NULL) - res = RTGUI_OBJECT(win->focused_widget)->event_handler( - RTGUI_OBJECT(win->focused_widget), event); - - /* if the focused widget doesn't handle it, I will handle it. */ - if (res != RT_TRUE && win->on_key != RT_NULL) - res = win->on_key(RTGUI_OBJECT(win), event); + for (widget = win->focused_widget; + widget && !res; + widget = widget->parent) + { + if (RTGUI_OBJECT(widget)->event_handler != RT_NULL) + res = RTGUI_OBJECT(widget)->event_handler( + RTGUI_OBJECT(widget), event); + } win->flag &= ~RTGUI_WIN_FLAG_HANDLE_KEY; return res; |
