diff --git a/lib/widget/dialog.c b/lib/widget/dialog.c index 8054b5e72..cf6270ac2 100644 --- a/lib/widget/dialog.c +++ b/lib/widget/dialog.c @@ -205,75 +205,6 @@ dlg_handle_key (WDialog * h, int d_key) return MSG_NOT_HANDLED; } -/* --------------------------------------------------------------------------------------------- */ -/** - * This is the low-level mouse handler. - * It receives a Gpm_Event event and translates it into a higher level protocol. - */ -static int -dlg_mouse_translator (Gpm_Event * event, Widget * w) -{ - mouse_event_t me; - - me = mouse_translate_event (w, event); - - return mouse_process_event (w, &me); -} - -/* --------------------------------------------------------------------------------------------- */ - -static int -dlg_mouse_event (WDialog * h, Gpm_Event * event) -{ - Widget *wh = WIDGET (h); - - GList *p; - - /* close the dialog by mouse left click out of dialog area */ - if (mouse_close_dialog && (wh->pos_flags & WPOS_FULLSCREEN) == 0 - && ((event->buttons & GPM_B_LEFT) != 0) && ((event->type & GPM_DOWN) != 0) - && !mouse_global_in_widget (event, wh)) - { - h->ret_value = B_CANCEL; - dlg_stop (h); - return MOU_NORMAL; - } - - if (wh->mouse_callback != NULL) - { - int mou; - - mou = dlg_mouse_translator (event, wh); - if (mou != MOU_UNHANDLED) - return mou; - } - - if (GROUP (h)->widgets == NULL) - return MOU_UNHANDLED; - - /* send the event to widgets in reverse Z-order */ - p = g_list_last (GROUP (h)->widgets); - do - { - Widget *w = WIDGET (p->data); - - if (!widget_get_state (w, WST_DISABLED) && w->mouse_callback != NULL) - { - /* put global cursor position to the widget */ - int ret; - - ret = dlg_mouse_translator (event, w); - if (ret != MOU_UNHANDLED) - return ret; - } - - p = g_list_previous (p); - } - while (p != NULL); - - return MOU_UNHANDLED; -} - /* --------------------------------------------------------------------------------------------- */ static cb_ret_t @@ -398,6 +329,23 @@ dlg_key_event (WDialog * h, int d_key) /* --------------------------------------------------------------------------------------------- */ +static int +dlg_handle_mouse_event (Widget * w, Gpm_Event * event) +{ + if (w->mouse_callback != NULL) + { + int mou; + + mou = mouse_handle_event (w, event); + if (mou != MOU_UNHANDLED) + return mou; + } + + return group_handle_mouse_event (w, event); +} + +/* --------------------------------------------------------------------------------------------- */ + static void frontend_dlg_run (WDialog * h) { @@ -437,7 +385,7 @@ frontend_dlg_run (WDialog * h) /* Clear interrupt flag */ tty_got_interrupt (); - d_key = tty_get_event (&event, h->mouse_status == MOU_REPEAT, TRUE); + d_key = tty_get_event (&event, GROUP (h)->mouse_status == MOU_REPEAT, TRUE); dlg_process_event (h, d_key, &event); @@ -468,6 +416,28 @@ dlg_default_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, v /* --------------------------------------------------------------------------------------------- */ +void +dlg_default_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event) +{ + switch (msg) + { + case MSG_MOUSE_CLICK: + if (event->y < 0 || event->y >= w->lines || event->x < 0 || event->x >= w->cols) + { + DIALOG (w)->ret_value = B_CANCEL; + dlg_stop (DIALOG (w)); + } + break; + + default: + /* return MOU_UNHANDLED */ + event->result.abort = TRUE; + break; + } +} + +/* --------------------------------------------------------------------------------------------- */ + WDialog * dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flags_t pos_flags, gboolean compact, const int *colors, widget_cb_fn callback, @@ -482,7 +452,7 @@ dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flag g = GROUP (new_d); widget_adjust_position (pos_flags, &y1, &x1, &lines, &cols); group_init (g, y1, x1, lines, cols, callback != NULL ? callback : dlg_default_callback, - mouse_callback); + mouse_callback != NULL ? mouse_callback : dlg_default_mouse_callback); w->pos_flags = pos_flags; w->options |= WOP_SELECTABLE | WOP_TOP_SELECT; @@ -490,13 +460,14 @@ dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flag /* Temporary hack: dialog doesn't have an owner, own itself. */ w->owner = g; + w->mouse_handler = dlg_handle_mouse_event; + w->mouse.forced_capture = mouse_close_dialog && (w->pos_flags & WPOS_FULLSCREEN) == 0; + new_d->color = colors; new_d->help_ctx = help_ctx; new_d->compact = compact; new_d->data = NULL; - new_d->mouse_status = MOU_UNHANDLED; - if (modal) { frame_colors_t frame_colors; @@ -632,8 +603,12 @@ dlg_process_event (WDialog * h, int key, Gpm_Event * event) break; case EV_MOUSE: - h->mouse_status = dlg_mouse_event (h, event); - break; + { + Widget *w = WIDGET (h); + + GROUP (h)->mouse_status = w->mouse_handler (w, event); + break; + } default: dlg_key_event (h, key); diff --git a/lib/widget/dialog.h b/lib/widget/dialog.h index 9417c4bee..2af15ea27 100644 --- a/lib/widget/dialog.h +++ b/lib/widget/dialog.h @@ -70,9 +70,6 @@ struct WDialog /* Set and received by the user */ int ret_value; /* Result of dlg_run() */ - /* Internal flags */ - int mouse_status; /* For the autorepeat status of the mouse */ - /* Internal variables */ void *data; /* Data can be passed to dialog */ char *event_group; /* Name of event group for this dialog */ @@ -119,8 +116,9 @@ void dlg_process_event (WDialog * h, int key, Gpm_Event * event); char *dlg_get_title (const WDialog * h, size_t len); -/* Default callback for dialogs */ +/* Default callbacks for dialogs */ cb_ret_t dlg_default_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data); +void dlg_default_mouse_callback (Widget * w, mouse_msg_t msg, mouse_event_t * event); void dlg_stop (WDialog * h); diff --git a/lib/widget/group.c b/lib/widget/group.c index ee0e7d962..1d55478b0 100644 --- a/lib/widget/group.c +++ b/lib/widget/group.c @@ -430,9 +430,13 @@ group_init (WGroup * g, int y1, int x1, int lines, int cols, widget_cb_fn callba widget_init (w, y1, x1, lines, cols, callback != NULL ? callback : group_default_callback, mouse_callback); + w->mouse_handler = group_handle_mouse_event; + w->find = group_default_find; w->find_by_type = group_default_find_by_type; w->find_by_id = group_default_find_by_id; + + g->mouse_status = MOU_UNHANDLED; } /* --------------------------------------------------------------------------------------------- */ @@ -471,6 +475,49 @@ group_default_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, /* --------------------------------------------------------------------------------------------- */ +/** + * Handling mouse events. + * + * @param g WGroup object + * @param event GPM mouse event + * + * @return result of mouse event handling + */ +int +group_handle_mouse_event (Widget * w, Gpm_Event * event) +{ + WGroup *g = GROUP (w); + + if (g->widgets != NULL) + { + GList *p; + + /* send the event to widgets in reverse Z-order */ + p = g_list_last (g->widgets); + do + { + Widget *wp = WIDGET (p->data); + + if (!widget_get_state (wp, WST_DISABLED)) + { + /* put global cursor position to the widget */ + int ret; + + ret = wp->mouse_handler (wp, event); + if (ret != MOU_UNHANDLED) + return ret; + } + + p = g_list_previous (p); + } + while (p != NULL); + } + + return MOU_UNHANDLED; +} + +/* --------------------------------------------------------------------------------------------- */ + /** * Insert widget to group before specified widget with specified positioning. * Make the inserted widget current. diff --git a/lib/widget/group.h b/lib/widget/group.h index 5dcb25442..ea129c6e2 100644 --- a/lib/widget/group.h +++ b/lib/widget/group.h @@ -31,6 +31,7 @@ struct WGroup GList *current; /* Currently active widget */ gboolean winch_pending; /* SIGWINCH signal has been got. Resize group after rise */ + int mouse_status; /* For the autorepeat status of the mouse */ }; /*** global variables defined in .c file *********************************************************/ @@ -42,6 +43,7 @@ void group_init (WGroup * g, int y1, int x1, int lines, int cols, widget_cb_fn c /* Default callback for groups */ cb_ret_t group_default_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *data); +int group_handle_mouse_event (Widget * w, Gpm_Event * event); unsigned long group_add_widget_autopos (WGroup * g, void *w, widget_pos_flags_t pos_flags, const void *before); diff --git a/lib/widget/mouse.c b/lib/widget/mouse.c index 82b561f58..1123738c9 100644 --- a/lib/widget/mouse.c +++ b/lib/widget/mouse.c @@ -69,8 +69,6 @@ init_mouse_event (mouse_event_t * event, mouse_msg_t msg, const Gpm_Event * glob event->result.repeat = FALSE; } -/* --------------------------------------------------------------------------------------------- */ -/*** public functions ****************************************************************************/ /* --------------------------------------------------------------------------------------------- */ /** @@ -81,7 +79,7 @@ init_mouse_event (mouse_event_t * event, mouse_msg_t msg, const Gpm_Event * glob * * @return high level mouse event */ -mouse_event_t +static mouse_event_t mouse_translate_event (Widget * w, Gpm_Event * event) { gboolean in_widget; @@ -172,7 +170,7 @@ mouse_translate_event (Widget * w, Gpm_Event * event) * * @return result of mouse event handling */ -int +static int mouse_process_event (Widget * w, mouse_event_t * event) { int ret = MOU_UNHANDLED; @@ -201,4 +199,27 @@ mouse_process_event (Widget * w, mouse_event_t * event) return ret; } + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +/** + * Translate GPM event to high-level event and process it + * + * @param w Widget object + * @param event GPM event + * + * @return result of mouse event handling + */ +int +mouse_handle_event (Widget * w, Gpm_Event * event) +{ + mouse_event_t me; + + me = mouse_translate_event (w, event); + + return mouse_process_event (w, &me); +} + /* --------------------------------------------------------------------------------------------- */ diff --git a/lib/widget/mouse.h b/lib/widget/mouse.h index b0c8c1f7b..44e7b238b 100644 --- a/lib/widget/mouse.h +++ b/lib/widget/mouse.h @@ -57,10 +57,8 @@ typedef struct /*** declarations of public functions ************************************************************/ -/* Translate GPM event to high-level event */ -mouse_event_t mouse_translate_event (Widget * w, Gpm_Event * event); -/* Process high-level mouse event */ -int mouse_process_event (Widget * w, mouse_event_t * event); +/* Translate GPM event to high-level event and process it */ +int mouse_handle_event (Widget * w, Gpm_Event * event); /*** inline functions ****************************************************************************/ diff --git a/lib/widget/widget-common.c b/lib/widget/widget-common.c index f97b42839..5ee020450 100644 --- a/lib/widget/widget-common.c +++ b/lib/widget/widget-common.c @@ -299,6 +299,7 @@ widget_init (Widget * w, int y, int x, int lines, int cols, w->callback = callback; w->mouse_callback = mouse_callback; w->owner = NULL; + w->mouse_handler = mouse_handle_event; w->mouse.forced_capture = FALSE; w->mouse.capture = FALSE; w->mouse.last_msg = MSG_MOUSE_NONE; diff --git a/lib/widget/widget-common.h b/lib/widget/widget-common.h index c58edaa56..357e91eef 100644 --- a/lib/widget/widget-common.h +++ b/lib/widget/widget-common.h @@ -122,6 +122,8 @@ typedef cb_ret_t (*widget_cb_fn) (Widget * widget, Widget * sender, widget_msg_t void *data); /* Widget mouse callback */ typedef void (*widget_mouse_cb_fn) (Widget * w, mouse_msg_t msg, mouse_event_t * event); +/* translate mouse event and process it */ +typedef int (*widget_mouse_handle_fn) (Widget * w, Gpm_Event * event); /* Every Widget must have this as its first element */ struct Widget @@ -135,7 +137,9 @@ struct Widget widget_cb_fn callback; widget_mouse_cb_fn mouse_callback; WGroup *owner; + /* Mouse-related fields. */ + widget_mouse_handle_fn mouse_handler; struct { /* Public members: */ diff --git a/src/filemanager/find.c b/src/filemanager/find.c index 4975a1ad8..81cf95aa7 100644 --- a/src/filemanager/find.c +++ b/src/filemanager/find.c @@ -958,7 +958,7 @@ check_find_events (WDialog * h) int c; event.x = -1; - c = tty_get_event (&event, h->mouse_status == MOU_REPEAT, FALSE); + c = tty_get_event (&event, GROUP (h)->mouse_status == MOU_REPEAT, FALSE); if (c != EV_NONE) { dlg_process_event (h, c, &event);