[Bf-blender-cvs] [7fdc6c5ca68] soc-2020-outliner: Outliner: Modifier drop link and cleanup

Nathan Craddock noreply at git.blender.org
Sun Jul 5 00:51:19 CEST 2020


Commit: 7fdc6c5ca68ec38fb0df946b9ffb4b30e595c2bb
Author: Nathan Craddock
Date:   Sat Jul 4 16:37:57 2020 -0600
Branches: soc-2020-outliner
https://developer.blender.org/rB7fdc6c5ca68ec38fb0df946b9ffb4b30e595c2bb

Outliner: Modifier drop link and cleanup

Allow drag and drop from modifier base to another object to link
modifiers. Also clean up the code.

There are still issues with the modifier reorder.

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

M	source/blender/editors/space_outliner/outliner_dragdrop.c
M	source/blender/editors/space_outliner/outliner_draw.c
M	source/blender/windowmanager/WM_api.h
M	source/blender/windowmanager/intern/wm_dragdrop.c

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

diff --git a/source/blender/editors/space_outliner/outliner_dragdrop.c b/source/blender/editors/space_outliner/outliner_dragdrop.c
index 5f5ef49f6b1..a2b1c7a28d8 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -66,6 +66,32 @@
 
 #include "outliner_intern.h"
 
+/* ******************** Drop Data Functions *********************** */
+
+typedef struct OutlinerDropData {
+  Object *ob_parent;
+  TreeStoreElem *drag_tselem;
+  void *drag_directdata;
+
+  TreeElementInsertType insert_type;
+} OutlinerDropData;
+
+/*  */
+static void outliner_drop_data_init(wmDrag *drag,
+                                    Object *ob,
+                                    TreeStoreElem *tselem,
+                                    void *directdata)
+{
+  OutlinerDropData *drop_data = MEM_callocN(sizeof(OutlinerDropData), "outliner drop data");
+
+  drop_data->ob_parent = ob;
+  drop_data->drag_tselem = tselem;
+  drop_data->drag_directdata = directdata;
+
+  drag->poin = drop_data;
+  drag->flags |= WM_DRAG_FREE_DATA;
+}
+
 /* ******************** Drop Target Find *********************** */
 
 static TreeElement *outliner_dropzone_element(TreeElement *te,
@@ -619,11 +645,6 @@ void OUTLINER_OT_material_drop(wmOperatorType *ot)
 
 /* ******************** Modifier Drop Operator *********************** */
 
-typedef struct ModifierDrop {
-  ModifierData *from;
-  ModifierData *to;
-} ModiferDrop;
-
 static bool outliner_is_modifier_element(TreeElement *te)
 {
   TreeStoreElem *tselem = TREESTORE(te);
@@ -631,29 +652,69 @@ static bool outliner_is_modifier_element(TreeElement *te)
   return tselem->type == TSE_MODIFIER;
 }
 
+static bool modifier_base_drop_poll(wmDrag *drag, const Object *ob, const char **r_tooltip)
+{
+  OutlinerDropData *drop_data = drag->poin;
+
+  if (ob->type != drop_data->ob_parent->type) {
+    return false;
+  }
+
+  *r_tooltip = TIP_("Link all modifiers to object");
+  return true;
+}
+
 static bool modifier_drop_poll(bContext *C,
                                wmDrag *drag,
                                const wmEvent *event,
                                const char **r_tooltip)
 {
-  TreeStoreElem *tselem = drag->poin;
-  if (!tselem) {
+  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;
   }
 
-  TreeElementInsertType insert_type;
-  TreeElement *te_target = outliner_drop_insert_find(C, event, &insert_type);
+  /* 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;
+  }
+  else {
+    ob = (Object *)outliner_search_back(te_target, ID_OB);
+  }
+
+  if (ob != drop_data->ob_parent) {
+    return false;
+  }
+
+  /* TODO (Nathan): Add ED_object_modifier_copy_to_object(). */
   if (outliner_ID_drop_find(C, event, ID_OB)) {
     *r_tooltip = TIP_("Copy modifier to object");
-    return true;
+    return false;
   }
-  else if (tselem_target->type == TSE_MODIFIER) {
-    switch (insert_type) {
+
+  /* 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)) {
@@ -675,25 +736,46 @@ static bool modifier_drop_poll(bContext *C,
       default:
         return false;
     }
+    if (changed) {
+      ED_region_tag_redraw_no_rebuild(region);
+    }
     return true;
   }
 
+  if (changed) {
+    ED_region_tag_redraw_no_rebuild(region);
+  }
+
   return false;
 }
 
 static int modifier_drop_invoke(bContext *C, wmOperator *op, const wmEvent *event)
 {
-  SpaceOutliner *soops = CTX_wm_space_outliner(C);
-  TreeStoreElem *tselem = WM_drag_data_from_event(event);
+  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);
 
-  Object *ob = (Object *)tselem->id;
-  TreeElement *te_md = outliner_find_tree_element(&soops->tree, tselem);
-  ModifierData *md = te_md->directdata;
+  if (drop_data->drag_tselem->type == TSE_MODIFIER_BASE) {
+    Object *ob = (Object *)TREESTORE(te)->id;
+
+    BKE_object_link_modifiers(ob, drop_data->ob_parent);
+    ED_region_tag_redraw(region);
+    WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+    DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
+    return OPERATOR_FINISHED;
+  }
 
-  ED_object_modifier_move_to_index(op->reports, ob, md, te->index);
+  Object *ob = drop_data->ob_parent;
+  ED_object_modifier_move_to_index(op->reports, ob, drop_data->drag_directdata, te->index);
 
   DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
   WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
@@ -999,8 +1081,9 @@ static int outliner_item_drag_drop_invoke(bContext *C,
 
   wmDrag *drag = WM_event_start_drag(C, data.icon, WM_DRAG_ID, NULL, 0.0, WM_DRAG_NOP);
 
-  if (tselem->type == TSE_MODIFIER) {
-    drag->poin = tselem;
+  if (ELEM(tselem->type, TSE_MODIFIER, TSE_MODIFIER_BASE)) {
+    ModifierData *md = te->directdata;
+    outliner_drop_data_init(drag, (Object *)tselem->id, tselem, md);
   }
   else if (ELEM(GS(data.drag_id->name), ID_OB, ID_GR)) {
     /* For collections and objects we cheat and drag all selected. */
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index 2abdd3aee1f..8c1953064a4 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -2147,6 +2147,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
       }
       case TSE_MODIFIER_BASE:
         data.icon = ICON_MODIFIER_DATA;
+        data.drag_id = tselem->id;
         break;
       case TSE_LINKED_OB:
         data.icon = ICON_OBJECT_DATA;
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 67ba283c1f1..482589e2ccb 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -673,8 +673,6 @@ void WM_drag_add_ID(struct wmDrag *drag, struct ID *id, struct ID *from_parent);
 struct ID *WM_drag_ID(const struct wmDrag *drag, short idcode);
 struct ID *WM_drag_ID_from_event(const struct wmEvent *event, short idcode);
 
-void *WM_drag_data_from_event(const struct wmEvent *event);
-
 /* Set OpenGL viewport and scissor */
 void wmViewport(const struct rcti *rect);
 void wmPartialViewport(rcti *drawrct, const rcti *winrct, const rcti *partialrct);
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index a5018273465..ad3fc7a1302 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -285,17 +285,6 @@ void wm_drags_check_ops(bContext *C, const wmEvent *event)
   }
 }
 
-void *WM_drag_data_from_event(const struct wmEvent *event)
-{
-  if (event->custom != EVT_DATA_DRAGDROP) {
-    return NULL;
-  }
-
-  ListBase *lb = event->customdata;
-  wmDrag *drag = lb->first;
-  return drag->poin;
-}
-
 /* ************** IDs ***************** */
 
 void WM_drag_add_ID(wmDrag *drag, ID *id, ID *from_parent)



More information about the Bf-blender-cvs mailing list