diff options
author | Campbell Barton <ideasman42@gmail.com> | 2017-07-23 20:28:57 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2017-07-24 10:19:36 +0300 |
commit | c7bc2f5e870c8074ed639a3b33c52df19679ca41 (patch) | |
tree | 6d36ad59f827f691e74129f336d1ef79a11c18d4 /source/blender | |
parent | 392b6a303ec21fe6edef6386280d0d6fb94e7f90 (diff) |
Manipulator: handle keymaps for selected items
Was only handling keymap items when the cursor
was hovering over a manipulator.
Diffstat (limited to 'source/blender')
5 files changed, 122 insertions, 35 deletions
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 0604297e7b3..e95dc43bbbe 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -2172,44 +2172,88 @@ static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers wm_manipulatormap_highlight_set(mmap, C, mpr, part); } /* handle user configurable manipulator-map keymap */ - else if (mpr) { - /* get user customized keymap from default one */ - const wmManipulatorGroup *highlightgroup = mpr->parent_mgroup; - const wmKeyMap *keymap = WM_keymap_active(wm, highlightgroup->type->keymap); - wmKeyMapItem *kmi; - - PRINT("%s: checking '%s' ...", __func__, keymap->idname); - - if (!keymap->poll || keymap->poll(C)) { - PRINT("pass\n"); - for (kmi = keymap->items.first; kmi; kmi = kmi->next) { - if (wm_eventmatch(event, kmi)) { - wmOperator *op = handler->op; - - PRINT("%s: item matched '%s'\n", __func__, kmi->idname); - - /* weak, but allows interactive callback to not use rawkey */ - event->keymap_idname = kmi->idname; - - /* handler->op is called later, we want keymap op to be triggered here */ - handler->op = NULL; - action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); - handler->op = op; - - if (action & WM_HANDLER_BREAK) { - if (action & WM_HANDLER_HANDLED) { - if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) - printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname); - } - else { - PRINT("%s: un-handled '%s'\n", __func__, kmi->idname); + else { + /* Either we operate on a single highlighted item + * or groups attached to the selected manipulators. + * To simplify things both cases loop over an array of items. */ + wmManipulatorGroup *mgroup_first; + bool is_mgroup_single; + + if (ISMOUSE(event->type)) { + /* Keep mpr set as-is, just fake single selection. */ + if (mpr) { + mgroup_first = mpr->parent_mgroup; + } + else { + mgroup_first = NULL; + } + is_mgroup_single = true; + } + else { + if (WM_manipulatormap_is_any_selected(mmap)) { + const ListBase *groups = WM_manipulatormap_group_list(mmap); + mgroup_first = groups->first; + } + else { + mgroup_first = NULL; + } + is_mgroup_single = false; + } + + /* Don't use from now on. */ + mpr = NULL; + + for (wmManipulatorGroup *mgroup = mgroup_first; mgroup; mgroup = mgroup->next) { + /* get user customized keymap from default one */ + + if ((is_mgroup_single == false) && + /* We might want to change the logic here and use some kind of manipulator edit-mode. + * For now just use keymap when a selection exists. */ + wm_manipulatorgroup_is_any_selected(mgroup) == false) + { + continue; + } + + const wmKeyMap *keymap = WM_keymap_active(wm, mgroup->type->keymap); + wmKeyMapItem *kmi; + + PRINT("%s: checking '%s' ...", __func__, keymap->idname); + + if (!keymap->poll || keymap->poll(C)) { + PRINT("pass\n"); + for (kmi = keymap->items.first; kmi; kmi = kmi->next) { + if (wm_eventmatch(event, kmi)) { + wmOperator *op = handler->op; + + PRINT("%s: item matched '%s'\n", __func__, kmi->idname); + + /* weak, but allows interactive callback to not use rawkey */ + event->keymap_idname = kmi->idname; + + /* handler->op is called later, we want keymap op to be triggered here */ + handler->op = NULL; + action |= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); + handler->op = op; + + if (action & WM_HANDLER_BREAK) { + if (action & WM_HANDLER_HANDLED) { + if (G.debug & (G_DEBUG_EVENTS | G_DEBUG_HANDLERS)) + printf("%s: handled - and pass on! '%s'\n", __func__, kmi->idname); + } + else { + PRINT("%s: un-handled '%s'\n", __func__, kmi->idname); + } } } } } - } - else { - PRINT("fail\n"); + else { + PRINT("fail\n"); + } + + if (is_mgroup_single) { + break; + } } } diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h index 43a5af3bbc4..f6b430d5f45 100644 --- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h +++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h @@ -206,6 +206,7 @@ void WM_manipulatormap_draw(struct wmManipulatorMap *mmap, const struct bContext void WM_manipulatormap_add_handlers(struct ARegion *ar, struct wmManipulatorMap *mmap); bool WM_manipulatormap_select_all(struct bContext *C, struct wmManipulatorMap *mmap, const int action); bool WM_manipulatormap_cursor_set(const struct wmManipulatorMap *mmap, struct wmWindow *win); +bool WM_manipulatormap_is_any_selected(const struct wmManipulatorMap *mmap); /* -------------------------------------------------------------------- */ /* wmManipulatorMapType */ @@ -238,7 +239,9 @@ void WM_manipulatormaptype_group_unlink( void WM_manipulatormaptype_group_free(struct wmManipulatorGroupTypeRef *wgt); /* -------------------------------------------------------------------- */ -/* Manipulator Add/Remove (High level API) */ +/* ManipulatorGroup */ + +/* Add/Remove (High level API) */ void WM_manipulator_group_add_ptr_ex( struct wmManipulatorGroupType *wgt, @@ -261,4 +264,7 @@ void WM_manipulator_group_remove_ptr_delayed( struct wmManipulatorGroupType *wgt); void WM_manipulator_group_remove_delayed(const char *idname); +/* Utilities */ +void WM_manipulator_group_is_any_selected(const char *idname); + #endif /* __WM_MANIPULATOR_API_H__ */ diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c index 126c866d600..c61392b500c 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c @@ -202,6 +202,20 @@ bool wm_manipulatorgroup_is_visible_in_drawstep(const wmManipulatorGroup *mgroup } } +bool wm_manipulatorgroup_is_any_selected(const wmManipulatorGroup *mgroup) +{ + if (mgroup->type->flag & WM_MANIPULATORGROUPTYPE_SELECT) { + for (const wmManipulator *mpr = mgroup->manipulators.first; mpr; mpr = mpr->next) { + if (mpr->state & WM_MANIPULATOR_STATE_SELECT) { + return true; + } + } + } + return false; +} + +/** \} */ + /** \name Manipulator operators * * Basic operators for manipulator interaction with user configurable keymaps. diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c index e149a7192bc..7eb48c1c726 100644 --- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c +++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c @@ -135,11 +135,19 @@ const ListBase *WM_manipulatormap_group_list(wmManipulatorMap *mmap) return &mmap->groups; } +bool WM_manipulatormap_is_any_selected(const wmManipulatorMap *mmap) +{ + return mmap->mmap_context.selected_len != 0; +} + /** * Creates and returns idname hash table for (visible) manipulators in \a mmap * * \param poll Polling function for excluding manipulators. * \param data Custom data passed to \a poll + * + * TODO(campbell): this uses unreliable order, + * best we use an iterator function instead of a hash. */ static GHash *WM_manipulatormap_manipulator_hash_new( const bContext *C, wmManipulatorMap *mmap, @@ -754,6 +762,17 @@ wmManipulator *wm_manipulatormap_active_get(wmManipulatorMap *mmap) return mmap->mmap_context.active; } +wmManipulator **wm_manipulatormap_selected_get(wmManipulatorMap *mmap, int *r_selected_len) +{ + *r_selected_len = mmap->mmap_context.selected_len; + return mmap->mmap_context.selected; +} + +ListBase *wm_manipulatormap_groups_get(wmManipulatorMap *mmap) +{ + return &mmap->groups; +} + /** \} */ /* wmManipulatorMap */ diff --git a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h index 61489b6a730..2658fee275a 100644 --- a/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h +++ b/source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h @@ -61,6 +61,8 @@ void wm_manipulatorgrouptype_init(void); void MANIPULATORGROUP_OT_manipulator_select(struct wmOperatorType *ot); void MANIPULATORGROUP_OT_manipulator_tweak(struct wmOperatorType *ot); +bool wm_manipulatorgroup_is_any_selected(const struct wmManipulatorGroup *mgroup); + /* -------------------------------------------------------------------- */ /* wmManipulatorMap */ @@ -83,6 +85,8 @@ void wm_manipulatormap_active_set( struct wmManipulatorMap *mmap, bContext *C, const struct wmEvent *event, struct wmManipulator *mpr); struct wmManipulator *wm_manipulatormap_active_get(struct wmManipulatorMap *mmap); +struct wmManipulator **wm_manipulatormap_selected_get(wmManipulatorMap *mmap, int *r_selected_len); +struct ListBase *wm_manipulatormap_groups_get(wmManipulatorMap *mmap); /* -------------------------------------------------------------------- */ /* wmManipulatorMapType */ |