Explorar o código

sync with github 5892d5b7

Add update_toplevel event. As always, full log is in GitHub.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2224 bbd45198-f89e-11dd-88c7-29a3b14d5316
chaos.proton@gmail.com %!s(int64=12) %!d(string=hai) anos
pai
achega
f2503a770f

+ 1 - 0
components/rtgui/common/rtgui_system.c

@@ -332,6 +332,7 @@ const char *event_string[] =
 	"HIDE",				    /* the widget is going to be hidden */
 	"PAINT",				/* paint on screen 		*/
 	"TIMER",				/* timer 				*/
+	"UPDATE_TOPLVL",		/* update toplevel      */
 
 	/* clip rect information */
 	"CLIP_INFO",			/* clip rect info		*/

+ 14 - 0
components/rtgui/include/rtgui/event.h

@@ -52,6 +52,7 @@ enum _rtgui_event_type
 	RTGUI_EVENT_HIDE,                  /* the widget is going to be hidden */
 	RTGUI_EVENT_PAINT,                 /* paint on screen       */
 	RTGUI_EVENT_TIMER,                 /* timer                 */
+	RTGUI_EVENT_UPDATE_TOPLVL,         /* update the toplevel   */
 
 	/* clip rect information */
 	RTGUI_EVENT_CLIP_INFO,             /* clip rect info        */
@@ -255,6 +256,18 @@ struct rtgui_event_clip_info
 #define RTGUI_EVENT_SHOW_INIT(e)			RTGUI_EVENT_INIT((e), RTGUI_EVENT_SHOW)
 #define RTGUI_EVENT_HIDE_INIT(e)			RTGUI_EVENT_INIT((e), RTGUI_EVENT_HIDE)
 
+struct rtgui_event_update_toplvl
+{
+	struct rtgui_event parent;
+	struct rtgui_win   *toplvl;
+};
+
+#define RTGUI_EVENT_UPDATE_TOPLVL_INIT(e)	\
+	do { \
+		RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_UPDATE_TOPLVL); \
+		(e)->toplvl = RT_NULL; \
+	} while (0)
+
 /*
  * RTGUI Mouse and Keyboard Event
  */
@@ -388,6 +401,7 @@ union rtgui_event_generic
 	struct rtgui_event_monitor monitor;
 	struct rtgui_event_paint paint;
 	struct rtgui_event_timer timer;
+	struct rtgui_event_update_toplvl update_toplvl;
 	struct rtgui_event_clip_info clip_info;
 	struct rtgui_event_mouse mouse;
 	struct rtgui_event_kbd kbd;

+ 1 - 0
components/rtgui/include/rtgui/widgets/widget.h

@@ -184,6 +184,7 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget);
 
 /* get the toplevel widget of widget */
 struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget);
+rt_bool_t rtgui_widget_onupdate_toplvl(struct rtgui_object *object, struct rtgui_event *event);
 
 void rtgui_widget_show(rtgui_widget_t* widget);
 rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *event);

+ 29 - 27
components/rtgui/widgets/container.c

@@ -38,26 +38,6 @@ static void _rtgui_container_destructor(rtgui_container_t *container)
 		rtgui_object_destroy(RTGUI_OBJECT(container->layout_box));
 }
 
-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 = window;
-
-		if (RTGUI_IS_CONTAINER(child))
-		{
-			_rtgui_container_update_toplevel(RTGUI_CONTAINER(child));
-		}
-	}
-}
-
 DEFINE_CLASS_TYPE(container, "container",
 	RTGUI_WIDGET_TYPE,
 	_rtgui_container_constructor,
@@ -82,6 +62,24 @@ rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_eve
 	return RT_FALSE;
 }
 
+/* broadcast means that the return value of event handlers will be ignored. The
+ * events will always reach every child.*/
+rt_bool_t rtgui_container_broadcast_event(struct rtgui_container *container, struct rtgui_event *event)
+{
+	struct rtgui_list_node* node;
+
+	rtgui_list_foreach(node, &(container->children))
+	{
+		struct rtgui_widget* w;
+		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;
+	}
+
+	return RT_FALSE;
+}
+
 rt_bool_t rtgui_container_dispatch_mouse_event(rtgui_container_t *container, struct rtgui_event_mouse* event)
 {
 	/* handle in child widget */
@@ -164,6 +162,13 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object* object, struct rtgu
 		rtgui_container_dispatch_event(container, event);
 		break;
 
+	case RTGUI_EVENT_UPDATE_TOPLVL:
+		/* call parent handler */
+		rtgui_widget_onupdate_toplvl(object, event);
+		/* update the children */
+		rtgui_container_broadcast_event(container, event);
+		break;
+
 	default:
 		/* call parent widget event handler */
 		return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event);
@@ -205,13 +210,10 @@ void rtgui_container_add_child(rtgui_container_t *container, rtgui_widget_t* chi
 	if (RTGUI_WIDGET(container)->toplevel != RT_NULL &&
 		RTGUI_IS_TOPLEVEL(RTGUI_WIDGET(container)->toplevel))
 	{
-		child->toplevel = rtgui_widget_get_toplevel(RTGUI_WIDGET(container));
-
-		/* update all child toplevel */
-		if (RTGUI_IS_CONTAINER(child))
-		{
-			_rtgui_container_update_toplevel(RTGUI_CONTAINER(child));
-		}
+		struct rtgui_event_update_toplvl eup;
+		RTGUI_EVENT_UPDATE_TOPLVL_INIT(&eup);
+		eup.toplvl = RTGUI_WIDGET(container)->toplevel;
+		rtgui_container_broadcast_event(container, (struct rtgui_event*)&eup);
 	}
 }
 

+ 30 - 0
components/rtgui/widgets/notebook.c

@@ -2,6 +2,7 @@
 #include <rtgui/rtgui.h>
 #include <rtgui/rtgui_system.h>
 #include <rtgui/widgets/notebook.h>
+#include <rtgui/widgets/window.h>
 
 #define RTGUI_NOTEBOOK_TAB_WIDTH     80
 
@@ -215,6 +216,16 @@ void rtgui_notebook_add(struct rtgui_notebook* notebook, const char* label, stru
 
     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);
+	}
 }
 
 void rtgui_notebook_remove(struct rtgui_notebook* notebook, rt_uint16_t index)
@@ -333,6 +344,19 @@ static rt_bool_t _rtgui_notebook_current_widget_handle(struct rtgui_notebook *no
 		return RT_FALSE;
 }
 
+static void _rtgui_notebook_all_widget_handle(struct rtgui_notebook *notebook,
+		                                           struct rtgui_event *event)
+{
+	struct rtgui_object *object;
+	int i;
+	for (i = 0; i < notebook->count; i++)
+	{
+		object = RTGUI_OBJECT(notebook->childs[i].widget);
+		if (object->event_handler)
+			object->event_handler(object, event);
+	}
+}
+
 rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui_event* event)
 {
 	struct rtgui_notebook* notebook;
@@ -362,6 +386,12 @@ rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui
 		return _rtgui_notebook_current_widget_handle(notebook, event);
 	case RTGUI_EVENT_KBD:
 		return _rtgui_notebook_current_widget_handle(notebook, event);
+	case RTGUI_EVENT_UPDATE_TOPLVL:
+		/* update myself */
+		rtgui_widget_onupdate_toplvl(object, event);
+		/* update all the widgets in myself */
+		_rtgui_notebook_all_widget_handle(notebook, event);
+		return RT_FALSE;
 	default:
 		/* use parent event handler */
 		return rtgui_widget_event_handler(object, event);

+ 18 - 7
components/rtgui/widgets/widget.c

@@ -145,13 +145,6 @@ void rtgui_widget_set_parent(rtgui_widget_t* widget, rtgui_widget_t* parent)
 {
 	/* set parent and toplevel widget */
 	widget->parent = parent;
-
-	/* update children toplevel */
-	if (parent->toplevel != RT_NULL &&
-		RTGUI_IS_TOPLEVEL(parent->toplevel))
-	{
-		widget->toplevel = rtgui_widget_get_toplevel(parent);
-	}
 }
 
 void rtgui_widget_get_extent(rtgui_widget_t* widget, rtgui_rect_t *rect)
@@ -402,6 +395,22 @@ struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget)
 	return RTGUI_WIN(r);
 }
 
+rt_bool_t rtgui_widget_onupdate_toplvl(struct rtgui_object *object, struct rtgui_event *event)
+{
+	struct rtgui_widget *widget;
+	struct rtgui_event_update_toplvl *eup;
+
+	RT_ASSERT(object);
+	RT_ASSERT(event);
+
+	widget = RTGUI_WIDGET(object);
+	eup = (struct rtgui_event_update_toplvl*)event;
+
+	widget->toplevel = eup->toplvl;
+
+	return RT_FALSE;
+}
+
 rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* event)
 {
 	RT_ASSERT(object != RT_NULL);
@@ -413,6 +422,8 @@ rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t*
 		return rtgui_widget_onshow(object, event);
 	case RTGUI_EVENT_HIDE:
 		return rtgui_widget_onhide(object, event);
+	case RTGUI_EVENT_UPDATE_TOPLVL:
+		return rtgui_widget_onupdate_toplvl(object, event);
 #ifndef RTGUI_USING_SMALL_SIZE
 	case RTGUI_EVENT_PAINT:
 		if (widget->on_draw != RT_NULL)