瀏覽代碼

fix button status issue, which caused by mouse released outside of button but button handled the mouse press event last time.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1547 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 14 年之前
父節點
當前提交
a69172aa4e

+ 6 - 0
components/rtgui/include/rtgui/widgets/toplevel.h

@@ -24,6 +24,9 @@ DECLARE_CLASS_TYPE(toplevel);
 /** Checks if the object is an rtgui_toplevel */
 #define RTGUI_IS_TOPLEVEL(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_TOPLEVEL_TYPE))
 
+/* last mouse event handled widget */
+#define RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(obj)	(RTGUI_TOPLEVEL(obj)->last_mevent_widget)
+
 struct rtgui_toplevel
 {
 	/* inherit from container */
@@ -38,6 +41,9 @@ struct rtgui_toplevel
 
 	/* server thread id */
 	rt_thread_t server;
+
+	/* last mouse event handled widget */
+	rtgui_widget_t* last_mevent_widget;
 };
 typedef struct rtgui_toplevel rtgui_toplevel_t;
 

+ 21 - 11
components/rtgui/widgets/button.c

@@ -12,8 +12,9 @@
  * 2009-10-16     Bernard      first version
  */
 #include <rtgui/dc.h>
-#include <rtgui/widgets/button.h>
 #include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/button.h>
+#include <rtgui/widgets/toplevel.h>
 
 static void _rtgui_button_constructor(rtgui_button_t *button)
 {
@@ -102,6 +103,17 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_e
 		{
 			struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;
 
+			/* it's not this widget event, clean status */
+			if (rtgui_rect_contains_point(&(RTGUI_WIDGET(btn)->extent), 
+				emouse->x, emouse->y) != RT_EOK)
+			{
+				btn->flag &= ~RTGUI_BUTTON_FLAG_PRESS;
+				/* draw button */
+				rtgui_theme_draw_button(btn);
+
+				break;
+			}
+
 			if (btn->flag & RTGUI_BUTTON_TYPE_PUSH)
 			{
 				/* it's a push button */
@@ -117,11 +129,7 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_e
 					}
 
 					/* draw button */
-#ifndef RTGUI_USING_SMALL_SIZE
-					if (widget->on_draw != RT_NULL ) widget->on_draw(widget, event);
-					else 
-#endif
-						rtgui_theme_draw_button(btn);
+					rtgui_theme_draw_button(btn);
 
 					if (btn->on_button != RT_NULL)
 					{
@@ -141,6 +149,12 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_e
 			{
 				if (emouse->button & RTGUI_MOUSE_BUTTON_LEFT)
 				{
+					/* set the last mouse event handled widget */
+					rtgui_toplevel_t* toplevel;
+
+					toplevel = RTGUI_TOPLEVEL(RTGUI_WIDGET(btn)->toplevel);
+					toplevel->last_mevent_widget = RTGUI_WIDGET(btn);
+
 					/* it's a normal button */
 					if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
 					{
@@ -152,11 +166,7 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_e
 					}
 
 					/* draw button */
-#ifndef RTGUI_USING_SMALL_SIZE					
-					if (widget->on_draw != RT_NULL ) widget->on_draw(widget, event);
-					else
-#endif
-						rtgui_theme_draw_button(btn);
+					rtgui_theme_draw_button(btn);
 
 #ifndef RTGUI_USING_SMALL_SIZE
 					/* invokes call back */

+ 3 - 1
components/rtgui/widgets/toplevel.c

@@ -13,7 +13,7 @@
  */
 #include <rtgui/rtgui_system.h>
 #include <rtgui/widgets/toplevel.h>
-extern void rtgui_topwin_do_clip(rtgui_widget_t* widget);
+extern void rtgui_topwin_do_clip(rtgui_widget_t* widget);
 
 static void _rtgui_toplevel_constructor(rtgui_toplevel_t *toplevel)
 {
@@ -31,6 +31,8 @@ static void _rtgui_toplevel_constructor(rtgui_toplevel_t *toplevel)
 
 	/* set server as RT_NULL (no connected) */
 	toplevel->server = RT_NULL;
+	/* initialize last mouse event handled widget */
+	toplevel->last_mevent_widget = RT_NULL;
 }
 
 static void _rtgui_toplevel_destructor(rtgui_toplevel_t* toplevel)

+ 19 - 0
components/rtgui/widgets/window.c

@@ -459,6 +459,25 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
 		break;
 
 	case RTGUI_EVENT_MOUSE_BUTTON:
+		/* check whether has widget which handled mouse event before */
+		if (RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win) != RT_NULL)
+		{
+			struct rtgui_event_mouse* emouse;
+
+			emouse = (struct rtgui_event_mouse*)event;
+			
+			RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win)->event_handler(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win), event);
+			if (rtgui_rect_contains_point(&(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win)->extent), 
+				emouse->x, emouse->y) == RT_EOK)
+			{
+				RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win) = RT_NULL;
+				break; /* mouse event is inside of widget, do not handle it anymore */
+			}
+
+			/* clean last mouse event handled widget */
+			RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win) = RT_NULL;
+		}
+
 		if (win->style & RTGUI_WIN_STYLE_UNDER_MODAL)
 		{
 			if (win->modal_widget != RT_NULL)

+ 19 - 0
components/rtgui/widgets/workbench.c

@@ -321,6 +321,25 @@ rt_bool_t rtgui_workbench_event_handler(rtgui_widget_t* widget, rtgui_event_t* e
 			struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;
 			struct rtgui_toplevel* top = RTGUI_TOPLEVEL(emouse->wid);
 
+			/* check whether has widget which handled mouse event before */
+			if (RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench) != RT_NULL)
+			{
+				struct rtgui_event_mouse* emouse;
+
+				emouse = (struct rtgui_event_mouse*)event;
+
+				RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench)->event_handler(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench), event);
+				if (rtgui_rect_contains_point(&(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench)->extent), 
+					emouse->x, emouse->y) == RT_EOK)
+				{
+					RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench) = RT_NULL;
+					break; /* mouse event is inside of widget, do not handle it anymore */
+				}
+
+				/* clean last mouse event handled widget */
+				RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench) = RT_NULL;
+			}
+
 			/* check the destination window */
 			if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
 			{