[Bf-blender-cvs] [a01244cade1] blender2.8: Outliner: support toggling non-active edit/pose mode objects

Campbell Barton noreply at git.blender.org
Wed May 30 10:31:05 CEST 2018


Commit: a01244cade1c210df2921f44be842e5c6a6c011e
Author: Campbell Barton
Date:   Wed May 30 10:19:09 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBa01244cade1c210df2921f44be842e5c6a6c011e

Outliner: support toggling non-active edit/pose mode objects

Support switching non-active objects in/out of a mode from the outliner.

- This allows users to change which objects are in a mode w/o
  having to exit the mode and change seleciton.
- Changing the mode of the active object applies to all other objects.
- By convention setting a mode selects, removing de-selects,
  this is done for convenience so switching to a mode from object mode
  maintains the set of objects in the current mode.

See: T55246

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

M	source/blender/editors/space_outliner/outliner_select.c

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

diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 2f88cb4469f..65cf08d87df 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -72,6 +72,82 @@
 
 #include "outliner_intern.h"
 
+static void do_outliner_activate_obdata(bContext *C, Scene *scene, ViewLayer *view_layer, Base *base)
+{
+	Object *obact = OBACT(view_layer);
+	bool use_all = false;
+
+	if (obact == NULL) {
+		ED_object_base_activate(C, base);
+		WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+		obact = base->object;
+		use_all = true;
+	}
+	else if (obact->data == base->object->data) {
+		use_all = true;
+	}
+
+	if (use_all) {
+		WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
+	}
+	else {
+		Object *ob = base->object;
+		if (ob->type == obact->type) {
+			bool ok;
+			if (BKE_object_is_in_editmode(ob)) {
+				ok = ED_object_editmode_exit_ex(scene, ob, EM_FREEDATA | EM_WAITCURSOR);
+			}
+			else {
+				ok = ED_object_editmode_enter_ex(scene, ob, EM_WAITCURSOR | EM_NO_CONTEXT);
+			}
+			if (ok) {
+				ED_object_base_select(base, (ob->mode & OB_MODE_EDIT) ? BA_SELECT : BA_DESELECT);
+				WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+			}
+		}
+	}
+}
+
+static void do_outliner_activate_pose(bContext *C, ViewLayer *view_layer, Base *base)
+{
+	Object *obact = OBACT(view_layer);
+	bool use_all = false;
+
+	if (obact == NULL) {
+		ED_object_base_activate(C, base);
+		Scene *scene = CTX_data_scene(C);
+		WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+		obact = base->object;
+		use_all = true;
+	}
+	else if (obact->data == base->object->data) {
+		use_all = true;
+	}
+
+	if (use_all) {
+		WM_operator_name_call(C, "OBJECT_OT_posemode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
+	}
+	else {
+		Object *ob = base->object;
+		if (ob->type == obact->type) {
+			struct Main *bmain = CTX_data_main(C);
+			bool ok = false;
+			if (ob->mode & OB_MODE_POSE) {
+				ok = ED_object_posemode_exit_ex(bmain, ob);
+			}
+			else {
+				ok = ED_object_posemode_enter_ex(bmain, ob);
+			}
+			if (ok) {
+				ED_object_base_select(base, (ob->mode & OB_MODE_POSE) ? BA_SELECT : BA_DESELECT);
+
+				Scene *scene = CTX_data_scene(C);
+				WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
+				WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+			}
+		}
+	}
+}
 
 /* ****************************************************** */
 /* Outliner Element Selection/Activation on Click */
@@ -584,16 +660,7 @@ static eOLDrawState tree_element_active_pose(
 	}
 
 	if (set != OL_SETSEL_NONE) {
-		if (OBEDIT_FROM_VIEW_LAYER(view_layer)) {
-			ED_object_editmode_exit(C, EM_FREEDATA | EM_WAITCURSOR);
-		}
-
-		if (ob->mode & OB_MODE_POSE) {
-			ED_object_posemode_exit(C, ob);
-		}
-		else {
-			ED_object_posemode_enter(C, ob);
-		}
+		do_outliner_activate_pose(C, view_layer, base);
 	}
 	else {
 		if (ob->mode & OB_MODE_POSE) {
@@ -817,10 +884,18 @@ static void do_outliner_item_activate_tree_element(
         TreeElement *te, TreeStoreElem *tselem,
         const bool extend, const bool recursive)
 {
-	/* always makes active object, except for some specific types.
-	 * Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects, we do not want
-	 * to switch out of edit mode (see T48328 for details). */
-	if (!ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, TSE_EBONE, TSE_LAYER_COLLECTION)) {
+	/* Always makes active object, except for some specific types. */
+	if (ELEM(tselem->type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP, TSE_EBONE, TSE_LAYER_COLLECTION)) {
+		/* Note about TSE_EBONE: In case of a same ID_AR datablock shared among several objects, we do not want
+		 * to switch out of edit mode (see T48328 for details). */
+	}
+	else if (tselem->id && OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
+		/* Support edit-mode toggle, keeping the active object as is. */
+	}
+	else if (tselem->type == TSE_POSE_BASE) {
+		/* Support pose mode toggle, keeping the active object as is. */
+	}
+	else {
 		tree_element_set_active_object(
 		        C, scene, view_layer, soops, te,
 		        (extend && tselem->type == 0) ? OL_SETSEL_EXTEND : OL_SETSEL_NORMAL,
@@ -873,7 +948,13 @@ static void do_outliner_item_activate_tree_element(
 			WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
 		}
 		else if (OB_DATA_SUPPORT_EDITMODE(te->idcode)) {
-			WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL);
+			Object *ob = (Object *)outliner_search_back(soops, te, ID_OB);
+			if ((ob != NULL) && (ob->data == tselem->id)) {
+				Base *base = BKE_view_layer_base_find(view_layer, ob);
+				if ((base != NULL) && (base->flag & BASE_VISIBLED)) {
+					do_outliner_activate_obdata(C, scene, view_layer, base);
+				}
+			}
 		}
 		else {  // rest of types
 			tree_element_active(C, scene, view_layer, soops, te, OL_SETSEL_NORMAL, false);



More information about the Bf-blender-cvs mailing list