mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 20:36:50 +03:00
WGroup: support mouse events.
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
4b3b49faad
commit
c2aadb2ad5
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -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 ****************************************************************************/
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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: */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user