[Bf-blender-cvs] [b7b2386cffc] soc-2020-outliner: Outliner: Add generic UI Stack drop operator

Nathan Craddock noreply at git.blender.org
Sun Jul 19 05:52:13 CEST 2020


Commit: b7b2386cffca5cf75b0a2b49d8274621c5c674e4
Author: Nathan Craddock
Date:   Sat Jul 18 21:49:39 2020 -0600
Branches: soc-2020-outliner
https://developer.blender.org/rBb7b2386cffca5cf75b0a2b49d8274621c5c674e4

Outliner: Add generic UI Stack drop operator

Replaces the modifier drop operator and works for modifiers,
constraints, and shader fx. Because these three elements share common
traits, it made the code simpler to combine the operator for all three.
Three types of actions are supported depending on where the element is
dropped:
* Drop within the same list to reorder.
* Drop on another object to copy.
* Drop the base (parent) element to link all to another object.

A few cases are yet unsupported but will be added to blenkernel.

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

M	source/blender/editors/include/ED_object.h
M	source/blender/editors/object/object_constraint.c
M	source/blender/editors/space_outliner/outliner_dragdrop.c
M	source/blender/editors/space_outliner/outliner_draw.c
M	source/blender/editors/space_outliner/outliner_intern.h
M	source/blender/editors/space_outliner/outliner_ops.c

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

diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index d8f55a0f60a..4d6aebd350a 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -330,6 +330,11 @@ void ED_object_constraint_dependency_tag_update(struct Main *bmain,
                                                 struct Object *ob,
                                                 struct bConstraint *con);
 
+bool ED_object_constraint_move_to_index(struct ReportList *reports,
+                                        struct Object *ob,
+                                        struct bConstraint *con,
+                                        const int index);
+
 /* object_modes.c */
 bool ED_object_mode_compat_test(const struct Object *ob, eObjectMode mode);
 bool ED_object_mode_compat_set(struct bContext *C,
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index bcb1b8afbdd..dae3728e950 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -1409,6 +1409,23 @@ void ED_object_constraint_dependency_tag_update(Main *bmain, Object *ob, bConstr
   DEG_relations_tag_update(bmain);
 }
 
+bool ED_object_constraint_move_to_index(ReportList *reports,
+                                        Object *ob,
+                                        bConstraint *con,
+                                        const int index)
+{
+  BLI_assert(con != NULL);
+  BLI_assert(index >= 0);
+
+  ListBase *conlist = ED_object_constraint_list_from_constraint(ob, con, NULL);
+  int current_index = BLI_findindex(conlist, con);
+  BLI_assert(current_index >= 0);
+
+  BLI_listbase_link_move(conlist, con, index - current_index);
+
+  return true;
+}
+
 /** \} */
 
 /* ------------------------------------------------------------------- */
@@ -1601,11 +1618,7 @@ static int constraint_move_to_index_exec(bContext *C, wmOperator *op)
   }
 
   if (con) {
-    ListBase *conlist = ED_object_constraint_list_from_constraint(ob, con, NULL);
-    int current_index = BLI_findindex(conlist, con);
-    BLI_assert(current_index >= 0);
-
-    BLI_listbase_link_move(conlist, con, new_index - current_index);
+    ED_object_constraint_move_to_index(op->reports, ob, con, new_index);
 
     WM_event_add_notifier(C, NC_OBJECT | ND_CONSTRAINT, ob);
 
diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index 87be29f0e27..d22cb4cf0c3 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -37,6 +37,7 @@
 #include "BLT_translation.h"
 
 #include "BKE_collection.h"
+#include "BKE_constraint.h"
 #include "BKE_context.h"
 #include "BKE_layer.h"
 #include "BKE_lib_id.h"
@@ -75,7 +76,10 @@ typedef struct OutlinerDropData {
   TreeStoreElem *drag_tselem;
   void *drag_directdata;
   int drag_index;
+  TreeElement *drag_te;
 
+  int drop_action;
+  TreeElement *drop_te;
   TreeElementInsertType insert_type;
 } OutlinerDropData;
 
@@ -89,6 +93,7 @@ static void outliner_drop_data_init(
   drop_data->drag_tselem = tselem;
   drop_data->drag_directdata = directdata;
   drop_data->drag_index = te->index;
+  drop_data->drag_te = te;
 
   drag->poin = drop_data;
   drag->flags |= WM_DRAG_FREE_DATA;
@@ -258,6 +263,20 @@ static TreeElement *outliner_drop_insert_collection_find(bContext *C,
   return collection_te;
 }
 
+static Object *outliner_object_from_tree_element_and_parents(TreeElement *te, TreeElement **r_te)
+{
+  TreeStoreElem *tselem;
+  while (te != NULL) {
+    tselem = TREESTORE(te);
+    if (tselem->type == 0 && te->idcode == ID_OB) {
+      *r_te = te;
+      return (Object *)tselem->id;
+    }
+    te = te->parent;
+  }
+  return NULL;
+}
+
 /* ******************** Parent Drop Operator *********************** */
 
 static bool parent_drop_allowed(bContext *C,
@@ -710,163 +729,216 @@ void OUTLINER_OT_material_drop(wmOperatorType *ot)
   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
 }
 
-/* ******************** Modifier Drop Operator *********************** */
-
-static bool outliner_is_modifier_element(TreeElement *te)
-{
-  TreeStoreElem *tselem = TREESTORE(te);
+/* ******************** UI Stack Drop Operator *********************** */
 
-  return tselem->type == TSE_MODIFIER;
-}
-
-static bool modifier_base_drop_poll(wmDrag *drag, const Object *ob, const char **r_tooltip)
+/* A generic operator to allow drag and drop for modifiers, constraints,
+ * and shader effects which all share the same UI stack layout.
+ *
+ * The following operations are allowed:
+ * - Reordering within an object.
+ * - Copying a single modifier/constraint/effect to another object.
+ * - Copying (linking) an object's modifiers/constraints/effects to another. */
+
+enum eUIStackDropAction {
+  UI_STACK_DROP_REORDER,
+  UI_STACK_DROP_COPY,
+  UI_STACK_DROP_LINK,
+};
+
+static bool uistack_drop_poll(bContext *C,
+                              wmDrag *drag,
+                              const wmEvent *event,
+                              const char **r_tooltip)
 {
   OutlinerDropData *drop_data = drag->poin;
-
-  if (ob->type != drop_data->ob_parent->type) {
+  if (!drop_data) {
     return false;
   }
 
-  *r_tooltip = TIP_("Link all modifiers to object");
-  return true;
-}
+  if (!ELEM(drop_data->drag_tselem->type,
+            TSE_MODIFIER,
+            TSE_MODIFIER_BASE,
+            TSE_CONSTRAINT,
+            TSE_CONSTRAINT_BASE,
+            TSE_EFFECT,
+            TSE_EFFECT_BASE)) {
+    return false;
+  }
 
-static bool modifier_drop_poll(bContext *C,
-                               wmDrag *drag,
-                               const wmEvent *event,
-                               const char **r_tooltip)
-{
   SpaceOutliner *soops = CTX_wm_space_outliner(C);
   ARegion *region = CTX_wm_region(C);
-  OutlinerDropData *drop_data = drag->poin;
   bool changed = outliner_flag_set(&soops->tree, TSE_HIGHLIGHTED | TSE_DRAG_ANY, false);
 
-  if (!drop_data) {
-    return false;
-  }
-
-  /* Drag all modifiers */
-  if (drop_data->drag_tselem->type == TSE_MODIFIER_BASE) {
-    Object *ob = (Object *)outliner_ID_drop_find(C, event, ID_OB);
-    if (!ob || ob == drop_data->ob_parent) {
-      return false;
-    }
-
-    return modifier_base_drop_poll(drag, ob, r_tooltip);
-  }
-
   TreeElement *te_target = outliner_drop_insert_find(C, event, &drop_data->insert_type);
   if (!te_target) {
     return false;
   }
   TreeStoreElem *tselem_target = TREESTORE(te_target);
 
-  Object *ob;
-  if (tselem_target->type == 0 && te_target->idcode == ID_OB) {
-    ob = (Object *)tselem_target->id;
+  TreeElement *object_te;
+  Object *ob = outliner_object_from_tree_element_and_parents(te_target, &object_te);
+
+  /* Drag a base. */
+  if (ELEM(
+          drop_data->drag_tselem->type, TSE_MODIFIER_BASE, TSE_CONSTRAINT_BASE, TSE_EFFECT_BASE)) {
+    if (ob && ob != drop_data->ob_parent) {
+      *r_tooltip = TIP_("Link all to object");
+      drop_data->insert_type = TE_INSERT_INTO;
+      drop_data->drop_action = UI_STACK_DROP_LINK;
+      drop_data->drop_te = object_te;
+      tselem_target = TREESTORE(object_te);
+    }
+    else {
+      return false;
+    }
   }
-  else {
-    ob = (Object *)outliner_search_back(te_target, ID_OB);
+  else if (ob) {
+    /* Drag a single item. */
+    if (ob != drop_data->ob_parent) {
+      *r_tooltip = TIP_("Copy to object");
+      drop_data->insert_type = TE_INSERT_INTO;
+      drop_data->drop_action = UI_STACK_DROP_COPY;
+      drop_data->drop_te = object_te;
+      tselem_target = TREESTORE(object_te);
+    }
+    else if (tselem_target->type == drop_data->drag_tselem->type) {
+      *r_tooltip = TIP_("Reorder");
+      drop_data->drop_action = UI_STACK_DROP_REORDER;
+      drop_data->drop_te = te_target;
+    }
+    else {
+      return false;
+    }
   }
-
-  if (outliner_ID_drop_find(C, event, ID_OB)) {
-    *r_tooltip = TIP_("Copy modifier to object");
-    return true;
+  else {
+    return false;
   }
 
-  /* Reorder modifiers. */
-  if (tselem_target->type == TSE_MODIFIER) {
-    switch (drop_data->insert_type) {
-      case TE_INSERT_BEFORE:
-        tselem_target->flag |= TSE_DRAG_BEFORE;
-        if (te_target->prev && outliner_is_modifier_element(te_target->prev)) {
-          *r_tooltip = TIP_("Move between modifiers");
-        }
-        else {
-          *r_tooltip = TIP_("Move before modifier");
-        }
-        break;
-      case TE_INSERT_AFTER:
-        tselem_target->flag |= TSE_DRAG_AFTER;
-        if (te_target->next && outliner_is_modifier_element(te_target->next)) {
-          *r_tooltip = TIP_("Move between modifiers");
-        }
-        else {
-          *r_tooltip = TIP_("Move after modifier");
-        }
-        break;
-      default:
-        return false;
-    }
-    if (changed) {
-      ED_region_tag_redraw_no_rebuild(region);
-    }
-    return true;
+  switch (drop_data->insert_type) {
+    case TE_INSERT_BEFORE:
+      tselem_target->flag |= TSE_DRAG_BEFORE;
+      break;
+    case TE_INSERT_AFTER:
+      tselem_target->flag |= TSE_DRAG_AFTER;
+      break;
+    case TE_INSERT_INTO:
+      tselem_target->flag |= TSE_DRAG_INTO;
+      break;
   }
 
   if (changed) {
     ED_region_tag_redraw_no_rebuild(region);
   }
 
-  return false;
+  return true;
 }
 
-static int modifier_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static void uistack_drop_link(bContext *C, OutlinerDropData *drop_data)
 {
-  ARegion *region = CTX_wm_region(C);
-
-  if (event->custom != EVT_DATA_DRAGDROP) {
-    return OPERATOR_CANCELLED;
-  }
-
-  ListBase *lb = event->customdata;
-  wmDrag *drag = lb->first;
-  OutlinerDropData *drop_data = drag->poin;
-
-  TreeElementInsertType insert_type;
-  TreeElement *te = outliner_drop_insert_find(C, event, &insert_type);
-  TreeStoreElem *tselem = TREESTORE(te);
+  TreeStoreElem *tselem = TREESTORE(drop_data->drop_te);
+  Object *ob_dst = (Object *)tselem->id;
 
   if (drop_data->drag_tselem->type == TSE_MODIFIER_BASE) {
-    Object *ob = (Object *)TREESTORE(te)->id;


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list