WM: add support for drag events

This allows for a single key to be mapped to both release and drag,
useful for pie menus to share a key with a different action.
This commit is contained in:
Campbell Barton 2018-06-07 17:05:49 +02:00
parent df4525d1d9
commit d274c64d22
4 changed files with 39 additions and 3 deletions

View File

@ -150,8 +150,16 @@ uiPieMenu *UI_pie_menu_begin(struct bContext *C, const char *title, int icon, co
}
pie->layout = UI_block_layout(pie->block_radial, UI_LAYOUT_VERTICAL, UI_LAYOUT_PIEMENU, 0, 0, 200, 0, 0, style);
pie->mx = event->x;
pie->my = event->y;
/* Open from where we started dragging. */
if (event->val == KM_CLICK_DRAG) {
pie->mx = event->prevclickx;
pie->my = event->prevclicky;
}
else {
pie->mx = event->x;
pie->my = event->y;
}
/* create title button */
if (title[0]) {

View File

@ -51,6 +51,7 @@ static const EnumPropertyItem event_keymouse_value_items[] = {
{KM_RELEASE, "RELEASE", 0, "Release", ""},
{KM_CLICK, "CLICK", 0, "Click", ""},
{KM_DBL_CLICK, "DOUBLE_CLICK", 0, "Double Click", ""},
{KM_CLICK_DRAG, "CLICK_DRAG", 0, "Click Drag", ""},
{0, NULL, 0, NULL, NULL}
};
@ -389,6 +390,7 @@ const EnumPropertyItem rna_enum_event_value_items[] = {
{KM_RELEASE, "RELEASE", 0, "Release", ""},
{KM_CLICK, "CLICK", 0, "Click", ""},
{KM_DBL_CLICK, "DOUBLE_CLICK", 0, "Double Click", ""},
{KM_CLICK_DRAG, "CLICK_DRAG", 0, "Click Drag", ""},
{EVT_GESTURE_N, "NORTH", 0, "North", ""},
{EVT_GESTURE_NE, "NORTH_EAST", 0, "North-East", ""},
{EVT_GESTURE_E, "EAST", 0, "East", ""},

View File

@ -188,6 +188,7 @@ enum {
#define KM_RELEASE 2
#define KM_CLICK 3
#define KM_DBL_CLICK 4
#define KM_CLICK_DRAG 5
/* ************** UI Handler ***************** */
@ -462,6 +463,7 @@ typedef struct wmEvent {
/* set in case a KM_PRESS went by unhandled */
char check_click;
char check_drag;
char is_motion_absolute;
/* keymap item, set by handler (weak?) */

View File

@ -2221,8 +2221,30 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
if (CTX_wm_window(C) == NULL)
return action;
if (!ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE, EVENT_NONE) && !ISTIMER(event->type)) {
if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
if (event->check_drag) {
wmWindow *win = CTX_wm_window(C);
if ((abs(event->x - win->eventstate->prevclickx)) >= U.tweak_threshold ||
(abs(event->y - win->eventstate->prevclicky)) >= U.tweak_threshold)
{
short val = event->val;
short type = event->type;
event->val = KM_CLICK_DRAG;
event->type = win->eventstate->type;
CLOG_INFO(WM_LOG_HANDLERS, 1, "handling PRESS_DRAG");
action |= wm_handlers_do_intern(C, event, handlers);
event->val = val;
event->type = type;
win->eventstate->check_click = 0;
win->eventstate->check_drag = 0;
}
}
}
else if (!ELEM(event->type, EVENT_NONE) && !ISTIMER(event->type)) {
/* test for CLICK events */
if (wm_action_not_handled(action)) {
wmWindow *win = CTX_wm_window(C);
@ -2232,6 +2254,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
if (win && event->val == KM_PRESS) {
win->eventstate->check_click = true;
win->eventstate->check_drag = true;
}
if (win && win->eventstate->prevtype == event->type) {
@ -2253,6 +2276,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
}
else {
win->eventstate->check_click = 0;
win->eventstate->check_drag = 0;
}
}
else if (event->val == KM_DBL_CLICK) {