summaryrefslogtreecommitdiff
path: root/components/rtgui/widgets/widget.c
diff options
context:
space:
mode:
Diffstat (limited to 'components/rtgui/widgets/widget.c')
-rw-r--r--components/rtgui/widgets/widget.c152
1 files changed, 88 insertions, 64 deletions
diff --git a/components/rtgui/widgets/widget.c b/components/rtgui/widgets/widget.c
index 91a14ac27e..e639eb8bed 100644
--- a/components/rtgui/widgets/widget.c
+++ b/components/rtgui/widgets/widget.c
@@ -14,10 +14,11 @@
*/
#include <rtgui/dc_client.h>
+#include <rtgui/rtgui_application.h>
#include <rtgui/widgets/widget.h>
#include <rtgui/widgets/window.h>
-#include <rtgui/widgets/view.h>
-extern void rtgui_topwin_do_clip(rtgui_widget_t* widget);
+#include <rtgui/widgets/container.h>
+#include <rtgui/widgets/notebook.h>
static void _rtgui_widget_constructor(rtgui_widget_t *widget)
{
@@ -40,23 +41,25 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget)
#endif
/* set parent and toplevel root */
- widget->parent = RT_NULL;
- widget->toplevel = RT_NULL;
+ widget->parent = RT_NULL;
+ widget->toplevel = RT_NULL;
/* some common event handler */
- widget->on_focus_in = RT_NULL;
- widget->on_focus_out = RT_NULL;
+ widget->on_focus_in = RT_NULL;
+ widget->on_focus_out = RT_NULL;
+ widget->on_show = RT_NULL;
+ widget->on_hide = RT_NULL;
#ifndef RTGUI_USING_SMALL_SIZE
- widget->on_draw = RT_NULL;
- widget->on_mouseclick = RT_NULL;
- widget->on_key = RT_NULL;
- widget->on_size = RT_NULL;
- widget->on_command = RT_NULL;
+ widget->on_draw = RT_NULL;
+ widget->on_mouseclick = RT_NULL;
+ widget->on_key = RT_NULL;
+ widget->on_size = RT_NULL;
+ widget->on_command = RT_NULL;
#endif
/* set default event handler */
- rtgui_widget_set_event_handler(widget,rtgui_widget_event_handler);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(widget), rtgui_widget_event_handler);
/* init user data private to 0 */
widget->user_data = 0;
@@ -203,13 +206,6 @@ void rtgui_widget_move_to_logic(rtgui_widget_t* widget, int dx, int dy)
}
}
-void rtgui_widget_set_event_handler(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
-{
- RT_ASSERT(widget != RT_NULL);
-
- widget->event_handler = handler;
-}
-
void rtgui_widget_get_rect(rtgui_widget_t* widget, rtgui_rect_t *rect)
{
RT_ASSERT(widget != RT_NULL);
@@ -236,6 +232,20 @@ void rtgui_widget_set_onunfocus(rtgui_widget_t* widget, rtgui_event_handler_ptr
widget->on_focus_out = handler;
}
+void rtgui_widget_set_onshow(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
+{
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_show = handler;
+}
+
+void rtgui_widget_set_onhide(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
+{
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_hide = handler;
+}
+
#ifndef RTGUI_USING_SMALL_SIZE
void rtgui_widget_set_ondraw(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
{
@@ -280,35 +290,28 @@ void rtgui_widget_set_oncommand(rtgui_widget_t* widget, rtgui_event_handler_ptr
*/
void rtgui_widget_focus(rtgui_widget_t *widget)
{
- rtgui_container_t *parent;
+ struct rtgui_widget *old_focus;
RT_ASSERT(widget != RT_NULL);
- if (!widget->parent || !widget->toplevel) return;
if (!RTGUI_WIDGET_IS_FOCUSABLE(widget) || !RTGUI_WIDGET_IS_ENABLE(widget))
return;
- /* set widget as focused */
- widget->flag |= RTGUI_WIDGET_FLAG_FOCUS;
-
- /* get root parent container and old focused widget */
- parent = RTGUI_CONTAINER(widget->toplevel);
- if (parent->focused == widget) return ; /* it's the same focused widget */
+ old_focus = RTGUI_WIN(widget->toplevel)->focused_widget;
+ if (old_focus == widget)
+ return; /* it's the same focused widget */
/* unfocused the old widget */
- if (parent->focused != RT_NULL) rtgui_widget_unfocus(parent->focused);
+ if (old_focus != RT_NULL)
+ rtgui_widget_unfocus(old_focus);
- /* set widget as focused widget in parent link */
- parent = RTGUI_CONTAINER(widget->parent);
- do
- {
- parent->focused = widget;
- parent = RTGUI_CONTAINER(RTGUI_WIDGET(parent)->parent);
- } while ((parent != RT_NULL) && !RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(parent)));
+ /* set widget as focused */
+ widget->flag |= RTGUI_WIDGET_FLAG_FOCUS;
+ RTGUI_WIN(widget->toplevel)->focused_widget = widget;
/* invoke on focus in call back */
if (widget->on_focus_in != RT_NULL)
- widget->on_focus_in(widget, RT_NULL);
+ widget->on_focus_in(RTGUI_OBJECT(widget), RT_NULL);
}
/**
@@ -317,6 +320,7 @@ void rtgui_widget_focus(rtgui_widget_t *widget)
*/
void rtgui_widget_unfocus(rtgui_widget_t *widget)
{
+
RT_ASSERT(widget != RT_NULL);
if (!widget->toplevel || !RTGUI_WIDGET_IS_FOCUSED(widget))
@@ -325,7 +329,9 @@ void rtgui_widget_unfocus(rtgui_widget_t *widget)
widget->flag &= ~RTGUI_WIDGET_FLAG_FOCUS;
if (widget->on_focus_out != RT_NULL)
- widget->on_focus_out(widget, RT_NULL);
+ widget->on_focus_out(RTGUI_OBJECT(widget), RT_NULL);
+
+ RTGUI_WIN(widget->toplevel)->focused_widget = RT_NULL;
/* refresh widget */
rtgui_widget_update(widget);
@@ -381,47 +387,62 @@ void rtgui_widget_rect_to_logic(rtgui_widget_t* widget, rtgui_rect_t* rect)
}
}
-rtgui_widget_t* rtgui_widget_get_toplevel(rtgui_widget_t* widget)
+struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget)
{
rtgui_widget_t* r;
RT_ASSERT(widget != RT_NULL);
- if (widget->toplevel) return widget->toplevel;
+ if (widget->toplevel)
+ return widget->toplevel;
+ rt_kprintf("widget->toplevel not properly set\n");
r = widget;
/* get the toplevel widget */
- while (r->parent != RT_NULL) r = r->parent;
+ while (r->parent != RT_NULL)
+ r = r->parent;
/* set toplevel */
- widget->toplevel = r;
+ widget->toplevel = RTGUI_WIN(r);
- return r;
+ return RTGUI_WIN(r);
}
-rt_bool_t rtgui_widget_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
+rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* event)
{
#ifndef RTGUI_USING_SMALL_SIZE
+ struct rtgui_widget *widget;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ widget = RTGUI_WIDGET(object);
+
switch (event->type)
{
case RTGUI_EVENT_PAINT:
- if (widget->on_draw != RT_NULL) return widget->on_draw(widget, event);
+ if (widget->on_draw != RT_NULL)
+ return widget->on_draw(RTGUI_OBJECT(widget), event);
break;
case RTGUI_EVENT_KBD:
- if (widget->on_key != RT_NULL) return widget->on_key(widget, event);
+ if (widget->on_key != RT_NULL)
+ return widget->on_key(RTGUI_OBJECT(widget), event);
break;
case RTGUI_EVENT_MOUSE_BUTTON:
- if (widget->on_mouseclick != RT_NULL) return widget->on_mouseclick(widget, event);
+ if (widget->on_mouseclick != RT_NULL)
+ return widget->on_mouseclick(RTGUI_OBJECT(widget), event);
break;
case RTGUI_EVENT_COMMAND:
- if (widget->on_command != RT_NULL) return widget->on_command(widget, event);
+ if (widget->on_command != RT_NULL)
+ return widget->on_command(RTGUI_OBJECT(widget), event);
break;
case RTGUI_EVENT_RESIZE:
- if (widget->on_size != RT_NULL) return widget->on_size(widget, event);
+ if (widget->on_size != RT_NULL)
+ return widget->on_size(RTGUI_OBJECT(widget), event);
break;
}
#endif
@@ -441,14 +462,9 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
if (widget == RT_NULL || RTGUI_WIDGET_IS_HIDE(widget)) return;
parent = widget->parent;
- /* if there is no parent, do not update clip (please use toplevel widget API) */
+ /* if there is no parent, there is no clip to update. */
if (parent == RT_NULL)
{
- if (RTGUI_IS_TOPLEVEL(widget))
- {
- /* if it's toplevel widget, update it by toplevel function */
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(widget));
- }
return;
}
@@ -479,7 +495,7 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
* intersect.
*/
- /* if it's a container object, update the clip info of children */
+ /* if it's a view object, update the clip info of children */
if (RTGUI_IS_CONTAINER(widget))
{
rtgui_widget_t* child;
@@ -490,17 +506,25 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
rtgui_widget_update_clip(child);
}
}
+ else if (RTGUI_IS_NOTEBOOK(widget))
+ {
+ rtgui_widget_update_clip(rtgui_notebook_get_current(RTGUI_NOTEBOOK(widget)));
+ }
}
void rtgui_widget_show(rtgui_widget_t* widget)
{
/* there is no parent or the parent is hide, no show at all */
if (widget->parent == RT_NULL ||
- RTGUI_WIDGET_IS_HIDE(widget->parent)) return;
+ RTGUI_WIDGET_IS_HIDE(widget->parent))
+ return;
/* update the clip info of widget */
RTGUI_WIDGET_UNHIDE(widget);
rtgui_widget_update_clip(widget);
+
+ if (widget->on_show != RT_NULL)
+ widget->on_show(RTGUI_OBJECT(widget), RT_NULL);
}
void rtgui_widget_hide(rtgui_widget_t* widget)
@@ -521,10 +545,10 @@ void rtgui_widget_hide(rtgui_widget_t* widget)
/* union widget rect */
rtgui_region_union_rect(&(parent->clip), &(parent->clip), &(widget->extent));
-
- /* subtract the external rect */
- rtgui_topwin_do_clip(RTGUI_WIDGET(parent));
}
+
+ if (widget->on_hide != RT_NULL)
+ widget->on_hide(RTGUI_OBJECT(widget), RT_NULL);
}
rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t* widget)
@@ -567,9 +591,11 @@ void rtgui_widget_update(rtgui_widget_t* widget)
RT_ASSERT(widget != RT_NULL);
- if (widget->event_handler != RT_NULL)
+ if (RTGUI_OBJECT(widget)->event_handler != RT_NULL)
{
- widget->event_handler(widget, &paint.parent);
+ RTGUI_OBJECT(widget)->event_handler(
+ RTGUI_OBJECT(widget),
+ &paint.parent);
}
}
@@ -617,11 +643,9 @@ void rtgui_widget_dump(rtgui_widget_t* widget)
obj = RTGUI_OBJECT(widget);
rt_kprintf("widget type: %s ", obj->type->name);
- if (RTGUI_IS_VIEW(widget) == RT_TRUE)
- rt_kprintf(":%s ", RTGUI_VIEW(widget)->title);
if (RTGUI_IS_WIN(widget) == RT_TRUE)
rt_kprintf(":%s ", RTGUI_WIN(widget)->title);
- if ((RTGUI_IS_LABEL(widget) == RT_TRUE) || (RTGUI_IS_BUTTON(widget) == RT_TRUE))
+ else if ((RTGUI_IS_LABEL(widget) == RT_TRUE) || (RTGUI_IS_BUTTON(widget) == RT_TRUE))
rt_kprintf(":%s ", RTGUI_LABEL(widget)->text);
rt_kprintf("extent(%d, %d) - (%d, %d)\n", widget->extent.x1,