[Bf-blender-cvs] [c7bc2f5e870] blender2.8: Manipulator: handle keymaps for selected items

Campbell Barton noreply at git.blender.org
Mon Jul 24 09:17:24 CEST 2017


Commit: c7bc2f5e870c8074ed639a3b33c52df19679ca41
Author: Campbell Barton
Date:   Mon Jul 24 03:28:57 2017 +1000
Branches: blender2.8
https://developer.blender.org/rBc7bc2f5e870c8074ed639a3b33c52df19679ca41

Manipulator: handle keymaps for selected items

Was only handling keymap items when the cursor
was hovering over a manipulator.

===================================================================

M	source/blender/windowmanager/intern/wm_event_system.c
M	source/blender/windowmanager/manipulators/WM_manipulator_api.h
M	source/blender/windowmanager/manipulators/intern/wm_manipulator_group.c
M	source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
M	source/blender/windowmanager/manipulators/wm_manipulator_wmapi.h

===================================================================

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 */




More information about the Bf-blender-cvs mailing list