diff options
| author | [email protected] <[email protected]> | 2012-04-18 15:06:12 +0000 |
|---|---|---|
| committer | [email protected] <[email protected]> | 2012-04-18 15:06:12 +0000 |
| commit | db0646020812efc16ff0beebe35f9049dcc2bfed (patch) | |
| tree | 5e949e9ba679a07b0198745853e900a016a3834e /components/rtgui/widgets/container.c | |
| parent | 06d45f0c42f2aa3678d509403fcf9cd82be106e6 (diff) | |
merge new RTGUI in to trunk
The full log is at https://github.com/RTGUI/RTGUI/commits/merge_1 and it's difficult to merge the new tree commit by commit. I also converted all the file into unix eol so there are many fake diff. Big changes are noted in rtgui/doc/road_map.txt and rtgui/doc/attention.txt. Keep an eye on them if you want to migrate your old code.
Note that the work is still in progress and the bsp is not prepared in trunk so far.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2092 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/rtgui/widgets/container.c')
| -rw-r--r-- | components/rtgui/widgets/container.c | 159 |
1 files changed, 117 insertions, 42 deletions
diff --git a/components/rtgui/widgets/container.c b/components/rtgui/widgets/container.c index c1e90f719a..3e919ba19a 100644 --- a/components/rtgui/widgets/container.c +++ b/components/rtgui/widgets/container.c @@ -10,37 +10,55 @@ * Change Logs: * Date Author Notes * 2009-10-16 Bernard first version + * 2010-09-24 Bernard fix container destroy issue */ -#include <rtgui/widgets/toplevel.h> +#include <rtgui/dc.h> +#include <rtgui/rtgui_system.h> +#include <rtgui/rtgui_application.h> #include <rtgui/widgets/container.h> +#include <rtgui/widgets/window.h> static void _rtgui_container_constructor(rtgui_container_t *container) { - /* set event handler and init field */ - rtgui_widget_set_event_handler(RTGUI_WIDGET(container), rtgui_container_event_handler); + /* init container */ + rtgui_object_set_event_handler(RTGUI_OBJECT(container), + rtgui_container_event_handler); + rtgui_list_init(&(container->children)); - - /* set focused widget to itself */ - container->focused = RTGUI_WIDGET(container); - /* set container as focusable widget */ - RTGUI_WIDGET(container)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE; + + /* container is used to 'contain'(show) widgets and dispatch events to + * them, not interact with user. So no need to grab focus. If we did it, + * some widget inherited from container(e.g. notebook) will grab the focus + * annoyingly. + * + * For example, a focusable notebook N has a widget W. When the user press + * W, N will gain the focus and W will lose it at first. Then N will set + * focus to W because it is W that eventually interact with people. N will + * yield focus and W will gain the focus again. This loop will make W + * repaint twice every time user press it. + * + * Just eliminate it. + */ + RTGUI_WIDGET(container)->flag &= ~RTGUI_WIDGET_FLAG_FOCUSABLE; } static void _rtgui_container_destructor(rtgui_container_t *container) { - /* destroy children of container */ rtgui_container_destroy_children(container); } static void _rtgui_container_update_toplevel(rtgui_container_t* container) { + struct rtgui_win *window; struct rtgui_list_node* node; + window = rtgui_widget_get_toplevel(RTGUI_WIDGET(container)); + rtgui_list_foreach(node, &(container->children)) { rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling); /* set child toplevel */ - child->toplevel = rtgui_widget_get_toplevel(RTGUI_WIDGET(container)); + child->toplevel = window; if (RTGUI_IS_CONTAINER(child)) { @@ -49,7 +67,7 @@ static void _rtgui_container_update_toplevel(rtgui_container_t* container) } } -DEFINE_CLASS_TYPE(container, "container", +DEFINE_CLASS_TYPE(container, "container", RTGUI_WIDGET_TYPE, _rtgui_container_constructor, _rtgui_container_destructor, @@ -65,7 +83,8 @@ rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_eve struct rtgui_widget* w; w = rtgui_list_entry(node, struct rtgui_widget, sibling); - if (w->event_handler(w, event) == RT_TRUE) return RT_TRUE; + if (RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w), event) == RT_TRUE) + return RT_TRUE; } return RT_FALSE; @@ -75,64 +94,106 @@ rt_bool_t rtgui_container_dispatch_mouse_event(rtgui_container_t *container, str { /* handle in child widget */ struct rtgui_list_node* node; - rtgui_widget_t *focus; + struct rtgui_widget *old_focus; + + old_focus = RTGUI_WIDGET(container)->toplevel->focused_widget; - /* get focus widget on toplevel */ - focus = RTGUI_CONTAINER(RTGUI_WIDGET(container)->toplevel)->focused; rtgui_list_foreach(node, &(container->children)) { struct rtgui_widget* w; w = rtgui_list_entry(node, struct rtgui_widget, sibling); - if (rtgui_rect_contains_point(&(w->extent), event->x, event->y) == RT_EOK) + if (rtgui_rect_contains_point(&(w->extent), + event->x, event->y) == RT_EOK) { - if ((focus != w) && RTGUI_WIDGET_IS_FOCUSABLE(w)) + if ((old_focus != w) && RTGUI_WIDGET_IS_FOCUSABLE(w)) rtgui_widget_focus(w); - if (w->event_handler(w, (rtgui_event_t*)event) == RT_TRUE) return RT_TRUE; + if (RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w), + (rtgui_event_t*)event) == RT_TRUE) + return RT_TRUE; } } return RT_FALSE; } -rt_bool_t rtgui_container_event_handler(rtgui_widget_t* widget, rtgui_event_t* event) +rt_bool_t rtgui_container_event_handler(struct rtgui_object* object, struct rtgui_event* event) { - rtgui_container_t *container = RTGUI_CONTAINER(widget); + struct rtgui_container *container; + struct rtgui_widget *widget; + + RT_ASSERT(object != RT_NULL); + RT_ASSERT(event != RT_NULL); + + container = RTGUI_CONTAINER(object); + widget = RTGUI_WIDGET(object); switch (event->type) { case RTGUI_EVENT_PAINT: - case RTGUI_EVENT_COMMAND: - case RTGUI_EVENT_RESIZE: - rtgui_container_dispatch_event(container, event); + { + struct rtgui_dc* dc; + struct rtgui_rect rect; + + dc = rtgui_dc_begin_drawing(widget); + if (dc == RT_NULL) + return RT_FALSE; + rtgui_widget_get_rect(widget, &rect); + + /* fill container with background */ + rtgui_dc_fill_rect(dc, &rect); + + /* paint on each child */ + rtgui_container_dispatch_event(container, event); + + rtgui_dc_end_drawing(dc); + } break; case RTGUI_EVENT_KBD: + /* let parent to handle keyboard event */ + if (widget->parent != RT_NULL && + widget->parent != RTGUI_WIDGET(widget->toplevel)) { - /* let parent to handle keyboard event */ - if (widget->parent != RT_NULL && widget->parent != widget->toplevel) - { - return widget->parent->event_handler(widget->parent, event); - } + return RTGUI_OBJECT(widget->parent)->event_handler( + RTGUI_OBJECT(widget->parent), + event); } break; case RTGUI_EVENT_MOUSE_BUTTON: + case RTGUI_EVENT_MOUSE_MOTION: /* handle in child widget */ return rtgui_container_dispatch_mouse_event(container, (struct rtgui_event_mouse*)event); - case RTGUI_EVENT_MOUSE_MOTION: - return rtgui_container_dispatch_mouse_event(container, - (struct rtgui_event_mouse*)event); + case RTGUI_EVENT_COMMAND: + case RTGUI_EVENT_RESIZE: + rtgui_container_dispatch_event(container, event); + break; default: /* call parent widget event handler */ - return rtgui_widget_event_handler(widget, event); + return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event); } return RT_FALSE; } +rtgui_container_t* rtgui_container_create(void) +{ + struct rtgui_container* container; + + /* allocate container */ + container = (struct rtgui_container*) rtgui_widget_create (RTGUI_CONTAINER_TYPE); + return container; +} + +void rtgui_container_destroy(rtgui_container_t* container) +{ + rtgui_container_hide(container); + rtgui_widget_destroy(RTGUI_WIDGET(container)); +} + /* * This function will add a child to a container widget * Note: this function will not change the widget layout @@ -168,13 +229,7 @@ void rtgui_container_remove_child(rtgui_container_t *container, rtgui_widget_t* RT_ASSERT(container != RT_NULL); RT_ASSERT(child != RT_NULL); - if (child == container->focused) - { - /* set focused to itself */ - container->focused = RTGUI_WIDGET(container); - - rtgui_widget_focus(RTGUI_WIDGET(container)); - } + rtgui_widget_unfocus(child); /* remove widget from parent's children list */ rtgui_list_remove(&(container->children), &(child->sibling)); @@ -218,9 +273,6 @@ void rtgui_container_destroy_children(rtgui_container_t *container) } container->children.next = RT_NULL; - container->focused = RTGUI_WIDGET(container); - if (RTGUI_WIDGET(container)->parent != RT_NULL) - rtgui_widget_focus(RTGUI_WIDGET(container)); /* update widget clip */ rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(RTGUI_WIDGET(container)->toplevel)); @@ -237,3 +289,26 @@ rtgui_widget_t* rtgui_container_get_first_child(rtgui_container_t* container) return child; } + +#ifndef RTGUI_USING_SMALL_SIZE +void rtgui_container_set_box(rtgui_container_t* container, struct rtgui_box* box) +{ + if (container == RT_NULL || box == RT_NULL) + return; + + rtgui_container_add_child(RTGUI_CONTAINER(container), RTGUI_WIDGET(box)); + rtgui_widget_set_rect(RTGUI_WIDGET(box), &(RTGUI_WIDGET(container)->extent)); +} +#endif + +void rtgui_container_hide(rtgui_container_t* container) +{ + if (container == RT_NULL) return; + + if (RTGUI_WIDGET(container)->parent == RT_NULL) + { + RTGUI_WIDGET_HIDE(RTGUI_WIDGET(container)); + return; + } +} + |
