From a69172aa4efa4675a826f85a62245b3c58eec568 Mon Sep 17 00:00:00 2001 From: "bernard.xiong" Date: Wed, 29 Jun 2011 09:57:28 +0000 Subject: [PATCH] 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 --- .../rtgui/include/rtgui/widgets/toplevel.h | 6 ++++ components/rtgui/widgets/button.c | 32 ++++++++++++------- components/rtgui/widgets/toplevel.c | 4 ++- components/rtgui/widgets/window.c | 19 +++++++++++ components/rtgui/widgets/workbench.c | 19 +++++++++++ 5 files changed, 68 insertions(+), 12 deletions(-) diff --git a/components/rtgui/include/rtgui/widgets/toplevel.h b/components/rtgui/include/rtgui/widgets/toplevel.h index 1382626805..3b46aeaa5c 100644 --- a/components/rtgui/include/rtgui/widgets/toplevel.h +++ b/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; diff --git a/components/rtgui/widgets/button.c b/components/rtgui/widgets/button.c index 9d28221b8a..ecd4e24e87 100644 --- a/components/rtgui/widgets/button.c +++ b/components/rtgui/widgets/button.c @@ -12,8 +12,9 @@ * 2009-10-16 Bernard first version */ #include -#include #include +#include +#include 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 */ diff --git a/components/rtgui/widgets/toplevel.c b/components/rtgui/widgets/toplevel.c index ee29015dd8..eeabcf09a8 100644 --- a/components/rtgui/widgets/toplevel.c +++ b/components/rtgui/widgets/toplevel.c @@ -13,7 +13,7 @@ */ #include #include -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) diff --git a/components/rtgui/widgets/window.c b/components/rtgui/widgets/window.c index 99d419c27e..7edba22a82 100644 --- a/components/rtgui/widgets/window.c +++ b/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) diff --git a/components/rtgui/widgets/workbench.c b/components/rtgui/widgets/workbench.c index a10663d091..1e57df70a9 100644 --- a/components/rtgui/widgets/workbench.c +++ b/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) {