Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2017-07-23 20:28:57 +0300
committerCampbell Barton <ideasman42@gmail.com>2017-07-24 10:19:36 +0300
commitc7bc2f5e870c8074ed639a3b33c52df19679ca41 (patch)
tree6d36ad59f827f691e74129f336d1ef79a11c18d4 /source/blender
parent392b6a303ec21fe6edef6386280d0d6fb94e7f90 (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')
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c112
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_api.h8
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c14
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c19
-rw-r--r--source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h4
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 */