1
0
mirror of https://github.com/MidnightCommander/mc synced 2025-04-04 22:22:54 +03:00

WGroup: support mouse events.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2016-11-15 09:33:34 +03:00
parent 4b3b49faad
commit c2aadb2ad5
9 changed files with 134 additions and 88 deletions

@ -205,75 +205,6 @@ dlg_handle_key (WDialog * h, int d_key)
return MSG_NOT_HANDLED; 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 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 static void
frontend_dlg_run (WDialog * h) frontend_dlg_run (WDialog * h)
{ {
@ -437,7 +385,7 @@ frontend_dlg_run (WDialog * h)
/* Clear interrupt flag */ /* Clear interrupt flag */
tty_got_interrupt (); 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); 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 * WDialog *
dlg_create (gboolean modal, int y1, int x1, int lines, int cols, widget_pos_flags_t pos_flags, 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, 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); g = GROUP (new_d);
widget_adjust_position (pos_flags, &y1, &x1, &lines, &cols); widget_adjust_position (pos_flags, &y1, &x1, &lines, &cols);
group_init (g, y1, x1, lines, cols, callback != NULL ? callback : dlg_default_callback, 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->pos_flags = pos_flags;
w->options |= WOP_SELECTABLE | WOP_TOP_SELECT; 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. */ /* Temporary hack: dialog doesn't have an owner, own itself. */
w->owner = g; 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->color = colors;
new_d->help_ctx = help_ctx; new_d->help_ctx = help_ctx;
new_d->compact = compact; new_d->compact = compact;
new_d->data = NULL; new_d->data = NULL;
new_d->mouse_status = MOU_UNHANDLED;
if (modal) if (modal)
{ {
frame_colors_t frame_colors; frame_colors_t frame_colors;
@ -632,8 +603,12 @@ dlg_process_event (WDialog * h, int key, Gpm_Event * event)
break; break;
case EV_MOUSE: 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: default:
dlg_key_event (h, key); dlg_key_event (h, key);

@ -70,9 +70,6 @@ struct WDialog
/* Set and received by the user */ /* Set and received by the user */
int ret_value; /* Result of dlg_run() */ int ret_value; /* Result of dlg_run() */
/* Internal flags */
int mouse_status; /* For the autorepeat status of the mouse */
/* Internal variables */ /* Internal variables */
void *data; /* Data can be passed to dialog */ void *data; /* Data can be passed to dialog */
char *event_group; /* Name of event group for this 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); 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); 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); void dlg_stop (WDialog * h);

@ -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, widget_init (w, y1, x1, lines, cols, callback != NULL ? callback : group_default_callback,
mouse_callback); mouse_callback);
w->mouse_handler = group_handle_mouse_event;
w->find = group_default_find; w->find = group_default_find;
w->find_by_type = group_default_find_by_type; w->find_by_type = group_default_find_by_type;
w->find_by_id = group_default_find_by_id; 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. * Insert widget to group before specified widget with specified positioning.
* Make the inserted widget current. * Make the inserted widget current.

@ -31,6 +31,7 @@ struct WGroup
GList *current; /* Currently active widget */ GList *current; /* Currently active widget */
gboolean winch_pending; /* SIGWINCH signal has been got. Resize group after rise */ 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 *********************************************************/ /*** 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 */ /* Default callback for groups */
cb_ret_t group_default_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, cb_ret_t group_default_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm,
void *data); 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, unsigned long group_add_widget_autopos (WGroup * g, void *w, widget_pos_flags_t pos_flags,
const void *before); const void *before);

@ -69,8 +69,6 @@ init_mouse_event (mouse_event_t * event, mouse_msg_t msg, const Gpm_Event * glob
event->result.repeat = FALSE; 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 * @return high level mouse event
*/ */
mouse_event_t static mouse_event_t
mouse_translate_event (Widget * w, Gpm_Event * event) mouse_translate_event (Widget * w, Gpm_Event * event)
{ {
gboolean in_widget; gboolean in_widget;
@ -172,7 +170,7 @@ mouse_translate_event (Widget * w, Gpm_Event * event)
* *
* @return result of mouse event handling * @return result of mouse event handling
*/ */
int static int
mouse_process_event (Widget * w, mouse_event_t * event) mouse_process_event (Widget * w, mouse_event_t * event)
{ {
int ret = MOU_UNHANDLED; int ret = MOU_UNHANDLED;
@ -201,4 +199,27 @@ mouse_process_event (Widget * w, mouse_event_t * event)
return ret; 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);
}
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */

@ -57,10 +57,8 @@ typedef struct
/*** declarations of public functions ************************************************************/ /*** declarations of public functions ************************************************************/
/* Translate GPM event to high-level event */ /* Translate GPM event to high-level event and process it */
mouse_event_t mouse_translate_event (Widget * w, Gpm_Event * event); int mouse_handle_event (Widget * w, Gpm_Event * event);
/* Process high-level mouse event */
int mouse_process_event (Widget * w, mouse_event_t * event);
/*** inline functions ****************************************************************************/ /*** inline functions ****************************************************************************/

@ -299,6 +299,7 @@ widget_init (Widget * w, int y, int x, int lines, int cols,
w->callback = callback; w->callback = callback;
w->mouse_callback = mouse_callback; w->mouse_callback = mouse_callback;
w->owner = NULL; w->owner = NULL;
w->mouse_handler = mouse_handle_event;
w->mouse.forced_capture = FALSE; w->mouse.forced_capture = FALSE;
w->mouse.capture = FALSE; w->mouse.capture = FALSE;
w->mouse.last_msg = MSG_MOUSE_NONE; w->mouse.last_msg = MSG_MOUSE_NONE;

@ -122,6 +122,8 @@ typedef cb_ret_t (*widget_cb_fn) (Widget * widget, Widget * sender, widget_msg_t
void *data); void *data);
/* Widget mouse callback */ /* Widget mouse callback */
typedef void (*widget_mouse_cb_fn) (Widget * w, mouse_msg_t msg, mouse_event_t * event); 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 */ /* Every Widget must have this as its first element */
struct Widget struct Widget
@ -135,7 +137,9 @@ struct Widget
widget_cb_fn callback; widget_cb_fn callback;
widget_mouse_cb_fn mouse_callback; widget_mouse_cb_fn mouse_callback;
WGroup *owner; WGroup *owner;
/* Mouse-related fields. */ /* Mouse-related fields. */
widget_mouse_handle_fn mouse_handler;
struct struct
{ {
/* Public members: */ /* Public members: */

@ -958,7 +958,7 @@ check_find_events (WDialog * h)
int c; int c;
event.x = -1; 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) if (c != EV_NONE)
{ {
dlg_process_event (h, c, &event); dlg_process_event (h, c, &event);