diff options
author | Ton Roosendaal <ton@blender.org> | 2012-10-28 15:19:35 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2012-10-28 15:19:35 +0400 |
commit | dca3587edd155a313044ed5f2b4f94e2c4bb6bce (patch) | |
tree | 40360e52b1df1620a5e53044c0a53c81a859d41b /source | |
parent | 581983319132afa62c096ec701b28c3269c29335 (diff) |
Event system cleanup: bringing KM_CLICK back in control.
- Solved Modal Keymap hijack of event codes
(with note this should be coded better)
- Added dedicated state variable check_click in event to trigger it
All this in an attempt to get code understandable and predictable again. :)
This solves error like:
- editmode mesh
- select a vertex
- grab it, press control for grid snap
- on LMB assign, it also did an extrude.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 5 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 72 |
2 files changed, 55 insertions, 22 deletions
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 764d274bfba..6631c624a87 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -424,7 +424,7 @@ typedef struct wmEvent { char ascii; /* from ghost, fallback if utf8 isn't set */ char pad; - /* previous state */ + /* previous state, used for double click and the 'click' */ short prevtype; short prevval; int prevx, prevy; @@ -435,7 +435,8 @@ typedef struct wmEvent { short shift, ctrl, alt, oskey; /* oskey is apple or windowskey, value denotes order of pressed */ short keymodifier; /* rawkey modifier */ - short pad1; + /* set in case a KM_PRESS went by unhandled */ + short check_click; /* keymap item, set by handler (weak?) */ const char *keymap_idname; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 695c586badc..d21075c56b9 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1375,13 +1375,30 @@ static void wm_event_modalkeymap(const bContext *C, wmOperator *op, wmEvent *eve for (kmi = keymap->items.first; kmi; kmi = kmi->next) { if (wm_eventmatch(event, kmi)) { + event->prevtype = event->type; + event->prevval = event->val; event->type = EVT_MODAL_MAP; event->val = kmi->propvalue; + + break; } } } } +/* bad hacking event system... better restore event type for checking of KM_CLICK for example */ +/* XXX modal maps could use different method (ton) */ +static void wm_event_modalmap_end(wmEvent *event) +{ + if (event->type == EVT_MODAL_MAP) { + event->type = event->prevtype; + event->prevtype = 0; + event->val = event->prevval; + event->prevval = 0; + } + +} + /* Warning: this function removes a modal handler, when finished */ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHandler *handler, wmEvent *event, PointerRNA *properties) @@ -1408,7 +1425,8 @@ static int wm_handler_operator_call(bContext *C, ListBase *handlers, wmEventHand retval = ot->modal(C, op, event); OPERATOR_RETVAL_CHECK(retval); - + wm_event_modalmap_end(event); + /* when this is _not_ the case the modal modifier may have loaded * a new blend file (demo mode does this), so we have to assume * the event, operator etc have all been freed. - campbell */ @@ -1862,32 +1880,46 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) { int action = wm_handlers_do_intern(C, event, handlers); - - /* test for CLICK events */ - if (wm_action_not_handled(action)) { - wmWindow *win = CTX_wm_window(C); - if (win && win->eventstate->prevtype == event->type) { + if (!ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) && !ISTIMER(event->type)) { + + /* test for CLICK events */ + if (wm_action_not_handled(action)) { + wmWindow *win = CTX_wm_window(C); + + /* eventstate stores if previous event was a KM_PRESS, in case that + wasn't handled, the KM_RELEASE will become a KM_CLICK */ - if (event->val == KM_RELEASE && win->eventstate->prevval == KM_PRESS) { - event->val = KM_CLICK; - action |= wm_handlers_do_intern(C, event, handlers); + if (win && event->val == KM_PRESS) { + win->eventstate->check_click = TRUE; + } + + if (win && win->eventstate->prevtype == event->type) { - /* revert value if not handled */ - if (wm_action_not_handled(action)) { + if (event->val == KM_RELEASE && win->eventstate->prevval == KM_PRESS && win->eventstate->check_click == TRUE) { + event->val = KM_CLICK; + // printf("add KM_CLICK\n"); + action |= wm_handlers_do_intern(C, event, handlers); + event->val = KM_RELEASE; } - } - else if (event->val == KM_DBL_CLICK) { - event->val = KM_PRESS; - action |= wm_handlers_do_intern(C, event, handlers); - - /* revert value if not handled */ - if (wm_action_not_handled(action)) { - event->val = KM_DBL_CLICK; + else if (event->val == KM_DBL_CLICK) { + event->val = KM_PRESS; + action |= wm_handlers_do_intern(C, event, handlers); + + /* revert value if not handled */ + if (wm_action_not_handled(action)) { + event->val = KM_DBL_CLICK; + } } } } + else { + wmWindow *win = CTX_wm_window(C); + + if(win) + win->eventstate->check_click = 0; + } } return action; @@ -2792,7 +2824,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U /* copy to event state */ evt->val = event.val; evt->type = event.type; - + if (win->active == 0) { int cx, cy; |