[Bf-blender-cvs] [b0741e1dcbc] master: Outliner: Use right click target element for context menu

Nathan Craddock noreply at git.blender.org
Thu Sep 10 17:56:02 CEST 2020


Commit: b0741e1dcbc5e4549e95745b1f1b501f8cd33add
Author: Nathan Craddock
Date:   Thu Sep 10 09:49:35 2020 -0600
Branches: master
https://developer.blender.org/rBb0741e1dcbc5e4549e95745b1f1b501f8cd33add

Outliner: Use right click target element for context menu

When opening the outliner context menu with multiple data types
selected, the menu did not show operators related to the target of the
cursor. For example, if a modifier and object are selected, a right
click on the modifier does not show the modifier options, rather it
shows the object context menu.

Now the data type of the right-click element is used to determine the
context menu to draw. For this to work properly the active element is
now set on right click.

Part of T77408

Manifest Task: https://developer.blender.org/T77770

Differential Revision: https://developer.blender.org/D8647

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

M	source/blender/editors/space_outliner/outliner_edit.c
M	source/blender/editors/space_outliner/outliner_tools.c

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

diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 7cd27ae3321..dea67a8678d 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -437,7 +437,8 @@ static void id_delete(bContext *C, ReportList *reports, TreeElement *te, TreeSto
   Main *bmain = CTX_data_main(C);
   ID *id = tselem->id;
 
-  BLI_assert(te->idcode != 0 && id != NULL);
+  BLI_assert(id != NULL);
+  BLI_assert((tselem->type == 0 && te->idcode != 0) || tselem->type == TSE_LAYER_COLLECTION);
   UNUSED_VARS_NDEBUG(te);
 
   if (te->idcode == ID_LI && ((Library *)id)->parent != NULL) {
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index b6c5d860457..0743e841794 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -95,110 +95,105 @@
 /** \name ID/Library/Data Set/Un-link Utilities
  * \{ */
 
-static void set_operation_types(SpaceOutliner *space_outliner,
-                                ListBase *lb,
-                                int *scenelevel,
-                                int *objectlevel,
-                                int *idlevel,
-                                int *datalevel)
+static void get_element_operation_type(
+    TreeElement *te, int *scenelevel, int *objectlevel, int *idlevel, int *datalevel)
 {
-  TreeElement *te;
-  TreeStoreElem *tselem;
+  TreeStoreElem *tselem = TREESTORE(te);
+  if (tselem->flag & TSE_SELECTED) {
+    /* Layer collection points to collection ID. */
+    if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
+      if (*datalevel == 0) {
+        *datalevel = tselem->type;
+      }
+      else if (*datalevel != tselem->type) {
+        *datalevel = -1;
+      }
+    }
+    else {
+      const int idcode = (int)GS(tselem->id->name);
+      bool is_standard_id = false;
+      switch ((ID_Type)idcode) {
+        case ID_SCE:
+          *scenelevel = 1;
+          break;
+        case ID_OB:
+          *objectlevel = 1;
+          break;
 
-  for (te = lb->first; te; te = te->next) {
-    tselem = TREESTORE(te);
-    if (tselem->flag & TSE_SELECTED) {
-      /* Layer collection points to collection ID. */
-      if (!ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
-        if (*datalevel == 0) {
-          *datalevel = tselem->type;
-        }
-        else if (*datalevel != tselem->type) {
-          *datalevel = -1;
-        }
+        case ID_ME:
+        case ID_CU:
+        case ID_MB:
+        case ID_LT:
+        case ID_LA:
+        case ID_AR:
+        case ID_CA:
+        case ID_SPK:
+        case ID_MA:
+        case ID_TE:
+        case ID_IP:
+        case ID_IM:
+        case ID_SO:
+        case ID_KE:
+        case ID_WO:
+        case ID_AC:
+        case ID_TXT:
+        case ID_GR:
+        case ID_LS:
+        case ID_LI:
+        case ID_VF:
+        case ID_NT:
+        case ID_BR:
+        case ID_PA:
+        case ID_GD:
+        case ID_MC:
+        case ID_MSK:
+        case ID_PAL:
+        case ID_PC:
+        case ID_CF:
+        case ID_WS:
+        case ID_LP:
+        case ID_HA:
+        case ID_PT:
+        case ID_VO:
+        case ID_SIM:
+          is_standard_id = true;
+          break;
+        case ID_WM:
+        case ID_SCR:
+          /* Those are ignored here. */
+          /* Note: while Screens should be manageable here, deleting a screen used by a workspace
+           * will cause crashes when trying to use that workspace, so for now let's play minimal,
+           * safe change. */
+          break;
+      }
+      if (idcode == ID_NLA) {
+        /* Fake one, not an actual ID type... */
+        is_standard_id = true;
       }
-      else {
-        const int idcode = (int)GS(tselem->id->name);
-        bool is_standard_id = false;
-        switch ((ID_Type)idcode) {
-          case ID_SCE:
-            *scenelevel = 1;
-            break;
-          case ID_OB:
-            *objectlevel = 1;
-            break;
 
-          case ID_ME:
-          case ID_CU:
-          case ID_MB:
-          case ID_LT:
-          case ID_LA:
-          case ID_AR:
-          case ID_CA:
-          case ID_SPK:
-          case ID_MA:
-          case ID_TE:
-          case ID_IP:
-          case ID_IM:
-          case ID_SO:
-          case ID_KE:
-          case ID_WO:
-          case ID_AC:
-          case ID_TXT:
-          case ID_GR:
-          case ID_LS:
-          case ID_LI:
-          case ID_VF:
-          case ID_NT:
-          case ID_BR:
-          case ID_PA:
-          case ID_GD:
-          case ID_MC:
-          case ID_MSK:
-          case ID_PAL:
-          case ID_PC:
-          case ID_CF:
-          case ID_WS:
-          case ID_LP:
-          case ID_HA:
-          case ID_PT:
-          case ID_VO:
-          case ID_SIM:
-            is_standard_id = true;
-            break;
-          case ID_WM:
-          case ID_SCR:
-            /* Those are ignored here. */
-            /* Note: while Screens should be manageable here, deleting a screen used by a workspace
-             * will cause crashes when trying to use that workspace, so for now let's play minimal,
-             * safe change. */
-            break;
+      if (is_standard_id) {
+        if (*idlevel == 0) {
+          *idlevel = idcode;
         }
-        if (idcode == ID_NLA) {
-          /* Fake one, not an actual ID type... */
-          is_standard_id = true;
+        else if (*idlevel != idcode) {
+          *idlevel = -1;
         }
-
-        if (is_standard_id) {
-          if (*idlevel == 0) {
-            *idlevel = idcode;
-          }
-          else if (*idlevel != idcode) {
-            *idlevel = -1;
-          }
-          if (ELEM(*datalevel, TSE_VIEW_COLLECTION_BASE, TSE_SCENE_COLLECTION_BASE)) {
-            *datalevel = 0;
-          }
+        if (ELEM(*datalevel, TSE_VIEW_COLLECTION_BASE, TSE_SCENE_COLLECTION_BASE)) {
+          *datalevel = 0;
         }
       }
     }
-    if (TSELEM_OPEN(tselem, space_outliner)) {
-      set_operation_types(
-          space_outliner, &te->subtree, scenelevel, objectlevel, idlevel, datalevel);
-    }
   }
 }
 
+static TreeElement *get_target_element(SpaceOutliner *space_outliner)
+{
+  TreeElement *te = outliner_find_element_with_flag(&space_outliner->tree, TSE_ACTIVE);
+  BLI_assert(te);
+
+  return te;
+}
+
 static void unlink_action_fn(bContext *C,
                              ReportList *UNUSED(reports),
                              Scene *UNUSED(scene),
@@ -405,7 +400,7 @@ static void outliner_do_libdata_operation(bContext *C,
   for (te = lb->first; te; te = te->next) {
     tselem = TREESTORE(te);
     if (tselem->flag & TSE_SELECTED) {
-      if (ELEM(tselem->type, 0, TSE_LAYER_COLLECTION)) {
+      if ((tselem->type == 0 && te->idcode != 0) || tselem->type == TSE_LAYER_COLLECTION) {
         TreeStoreElem *tsep = te->parent ? TREESTORE(te->parent) : NULL;
         operation_fn(C, reports, scene, te, tsep, tselem, user_data);
       }
@@ -1796,18 +1791,16 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op)
   Scene *scene = CTX_data_scene(C);
   SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
   int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
-  eOutlinerIdOpTypes event;
 
   /* check for invalid states */
   if (space_outliner == NULL) {
     return OPERATOR_CANCELLED;
   }
 
-  set_operation_types(
-      space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
-  event = RNA_enum_get(op->ptr, "type");
+  TreeElement *te = get_target_element(space_outliner);
+  get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
 
+  eOutlinerIdOpTypes event = RNA_enum_get(op->ptr, "type");
   switch (event) {
     case OUTLINER_IDOP_UNLINK: {
       /* unlink datablock from its parent */
@@ -2128,18 +2121,16 @@ static int outliner_lib_operation_exec(bContext *C, wmOperator *op)
   Scene *scene = CTX_data_scene(C);
   SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
   int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
-  eOutlinerLibOpTypes event;
 
   /* check for invalid states */
   if (space_outliner == NULL) {
     return OPERATOR_CANCELLED;
   }
 
-  set_operation_types(
-      space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
-
-  event = RNA_enum_get(op->ptr, "type");
+  TreeElement *te = get_target_element(space_outliner);
+  get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
 
+  eOutlinerLibOpTypes event = RNA_enum_get(op->ptr, "type");
   switch (event) {
     case OL_LIB_RENAME: {
       outliner_do_libdata_operation(
@@ -2261,8 +2252,9 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op)
   if (space_outliner == NULL) {
     return OPERATOR_CANCELLED;
   }
-  set_operation_types(
-      space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+
+  TreeElement *te = get_target_element(space_outliner);
+  get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
 
   /* get action to use */
   act = BLI_findlink(&bmain->actions, RNA_enum_get(op->ptr, "action"));
@@ -2369,22 +2361,21 @@ static int outliner_animdata_operation_exec(bContext *C, wmOperator *op)
   wmWindowManager *wm = CTX_wm_manager(C);
   SpaceOutliner *space_outliner = CTX_wm_space_outliner(C);
   int scenelevel = 0, objectlevel = 0, idlevel = 0, datalevel = 0;
-  eOutliner_AnimDataOps event;
 
   /* check for invalid states */
   if (space_outliner == NULL) {
     return OPERATOR_CANCELLED;
   }
 
-  event = RNA_enum_get(op->ptr, "type");
-  set_operation_types(
-      space_outliner, &space_outliner->tree, &scenelevel, &objectlevel, &idlevel, &datalevel);
+  TreeElement *te = get_target_element(space_outliner);
+  get_element_operation_type(te, &scenelevel, &objectlevel, &idlevel, &datalevel);
 
   if (datalevel != TSE_ANIM_DATA) {
     return OPERATOR_CANCELLED;
   }
 
   /* perform the core operation */
+  eOutli

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list