1
0
mirror of git://projects.qi-hardware.com/eda-tools.git synced 2024-11-17 22:46:15 +02:00

eeshow/gui/input.c: support hover -> drag; set state to idle after cleanup

This commit is contained in:
Werner Almesberger 2016-08-18 04:56:39 -03:00
parent f2c8693a77
commit 4ffdeeb910

View File

@ -34,6 +34,7 @@ static struct input {
input_clicking, input_clicking,
input_ignoring, /* click rejected by moving the cursor */ input_ignoring, /* click rejected by moving the cursor */
input_hovering, input_hovering,
input_hovering_down, /* mouse button is pressed */
input_dragging, input_dragging,
} state; } state;
@ -58,6 +59,8 @@ static const char *state(void)
return "IGNORING"; return "IGNORING";
case input_hovering: case input_hovering:
return "HOVERING"; return "HOVERING";
case input_hovering_down:
return "HOVERING_DOWN";
case input_dragging: case input_dragging:
return "DRAGGING"; return "DRAGGING";
default: default:
@ -69,6 +72,22 @@ static const char *state(void)
/* ----- Mouse button ------------------------------------------------------ */ /* ----- Mouse button ------------------------------------------------------ */
static bool begin_drag(const GdkEventMotion *event)
{
const struct input *old_sp = sp;
if (hypot(event->x - clicked_x, event->y - clicked_y) < DRAG_RADIUS)
return 0;
if (sp->ops->drag_begin &&
sp->ops->drag_begin(sp->user, clicked_x, clicked_y))
sp->state = input_dragging;
else
sp->state = input_ignoring;
assert(sp == old_sp);
return 1;
}
static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event, static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
gpointer data) gpointer data)
{ {
@ -90,18 +109,17 @@ static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
assert(sp == old_sp); assert(sp == old_sp);
break; break;
case input_clicking: case input_clicking:
if (hypot(event->x - clicked_x, event->y - clicked_y) < begin_drag(event);
DRAG_RADIUS)
break;
if (sp->ops->drag_begin &&
sp->ops->drag_begin(sp->user, clicked_x, clicked_y))
sp->state = input_dragging;
else
sp->state = input_ignoring;
assert(sp == old_sp);
break; break;
case input_ignoring: case input_ignoring:
break; break;
case input_hovering_down:
if (begin_drag(event)) {
if (sp->ops->hover_end)
sp->ops->hover_end(sp->user);
break;
}
/* fall through */
case input_hovering: case input_hovering:
if (!sp->ops->hover_update) if (!sp->ops->hover_update)
break; break;
@ -109,7 +127,8 @@ static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
/* Caution: hover_update may switch input layers */ /* Caution: hover_update may switch input layers */
if (!sp->ops->hover_update(sp->user, event->x, event->y) && if (!sp->ops->hover_update(sp->user, event->x, event->y) &&
sp == old_sp) { sp == old_sp) {
sp->state = input_idle; sp->state = sp->state == input_hovering ? input_idle :
input_clicking;
if (sp->ops->hover_end) if (sp->ops->hover_end)
sp->ops->hover_end(sp->user); sp->ops->hover_end(sp->user);
} }
@ -131,8 +150,6 @@ static gboolean motion_notify_event(GtkWidget *widget, GdkEventMotion *event,
static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event, static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event,
gpointer data) gpointer data)
{ {
const struct input *old_sp = sp;
if (event->button != 1) if (event->button != 1)
return TRUE; return TRUE;
@ -147,16 +164,13 @@ static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event,
case input_clicking: case input_clicking:
case input_ignoring: case input_ignoring:
case input_dragging: case input_dragging:
case input_hovering_down:
/* ignore double-click */ /* ignore double-click */
break; break;
case input_hovering: case input_hovering:
if (sp->ops->hover_click && sp->state = input_hovering_down;
sp->ops->hover_click(sp->user, event->x, event->y) && clicked_x = event->x;
sp == old_sp) { clicked_y = event->y;
sp->state = input_ignoring;
if (sp->ops->hover_end)
sp->ops->hover_end(sp->user);
}
break; break;
default: default:
abort(); abort();
@ -169,6 +183,8 @@ static gboolean button_press_event(GtkWidget *widget, GdkEventButton *event,
static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event, static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event,
gpointer data) gpointer data)
{ {
const struct input *old_sp = sp;
if (event->button != 1) if (event->button != 1)
return TRUE; return TRUE;
@ -193,6 +209,15 @@ static gboolean button_release_event(GtkWidget *widget, GdkEventButton *event,
break; break;
case input_hovering: case input_hovering:
break; break;
case input_hovering_down:
if (sp->ops->hover_click &&
sp->ops->hover_click(sp->user, event->x, event->y) &&
sp == old_sp) {
sp->state = input_ignoring;
if (sp->ops->hover_end)
sp->ops->hover_end(sp->user);
}
break;
default: default:
abort(); abort();
} }
@ -264,6 +289,8 @@ static void cleanup(void)
default: default:
; ;
} }
sp->state = input_idle;
} }