[Bf-blender-cvs] [cd3d261e3c8] soc-2020-outliner: Outliner modifier drop

Nathan Craddock noreply at git.blender.org
Sat Jul 4 04:57:33 CEST 2020


Commit: cd3d261e3c86d75af93cdd66f30b620b2a5f7c5a
Author: Nathan Craddock
Date:   Mon Jun 29 16:20:51 2020 -0600
Branches: soc-2020-outliner
https://developer.blender.org/rBcd3d261e3c86d75af93cdd66f30b620b2a5f7c5a

Outliner modifier drop

Initial implementation. Experimentation to see what types of data
are needed.

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

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
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 09d7f889bde..5f5ef49f6b1 100644
--- a/source/blender/editors/space_outliner/outliner_dragdrop.c
+++ b/source/blender/editors/space_outliner/outliner_dragdrop.c
@@ -27,6 +27,7 @@
 
 #include "DNA_collection_types.h"
 #include "DNA_material_types.h"
+#include "DNA_modifier_types.h"
 #include "DNA_object_types.h"
 #include "DNA_space_types.h"
 
@@ -616,6 +617,106 @@ void OUTLINER_OT_material_drop(wmOperatorType *ot)
   ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
 }
 
+/* ******************** Modifier Drop Operator *********************** */
+
+typedef struct ModifierDrop {
+  ModifierData *from;
+  ModifierData *to;
+} ModiferDrop;
+
+static bool outliner_is_modifier_element(TreeElement *te)
+{
+  TreeStoreElem *tselem = TREESTORE(te);
+
+  return tselem->type == TSE_MODIFIER;
+}
+
+static bool modifier_drop_poll(bContext *C,
+                               wmDrag *drag,
+                               const wmEvent *event,
+                               const char **r_tooltip)
+{
+  TreeStoreElem *tselem = drag->poin;
+  if (!tselem) {
+    return false;
+  }
+
+  TreeElementInsertType insert_type;
+  TreeElement *te_target = outliner_drop_insert_find(C, event, &insert_type);
+  if (!te_target) {
+    return false;
+  }
+  TreeStoreElem *tselem_target = TREESTORE(te_target);
+
+  if (outliner_ID_drop_find(C, event, ID_OB)) {
+    *r_tooltip = TIP_("Copy modifier to object");
+    return true;
+  }
+  else if (tselem_target->type == TSE_MODIFIER) {
+    switch (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;
+    }
+    return true;
+  }
+
+  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);
+
+  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;
+
+  ED_object_modifier_move_to_index(op->reports, ob, md, te->index);
+
+  DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+  WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+  return OPERATOR_FINISHED;
+}
+
+void OUTLINER_OT_modifier_drop(wmOperatorType *ot)
+{
+  /* identifiers */
+  ot->name = "Move Modifier";
+  ot->description = "Drag modifier to object in Outliner";
+  ot->idname = "OUTLINER_OT_modifier_drop";
+
+  /* api callbacks */
+  ot->invoke = modifier_drop_invoke;
+
+  ot->poll = ED_operator_outliner_active;
+
+  /* flags */
+  ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+}
+
 /* ******************** Collection Drop Operator *********************** */
 
 typedef struct CollectionDrop {
@@ -880,7 +981,8 @@ static int outliner_item_drag_drop_invoke(bContext *C,
     return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
   }
 
-  TreeElementIcon data = tree_element_get_icon(TREESTORE(te), te);
+  TreeStoreElem *tselem = TREESTORE(te);
+  TreeElementIcon data = tree_element_get_icon(tselem, te);
   if (!data.drag_id) {
     return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
   }
@@ -897,13 +999,16 @@ 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 (ELEM(GS(data.drag_id->name), ID_OB, ID_GR)) {
+  if (tselem->type == TSE_MODIFIER) {
+    drag->poin = tselem;
+  }
+  else if (ELEM(GS(data.drag_id->name), ID_OB, ID_GR)) {
     /* For collections and objects we cheat and drag all selected. */
 
     /* Only drag element under mouse if it was not selected before. */
-    if ((TREESTORE(te)->flag & TSE_SELECTED) == 0) {
+    if ((tselem->flag & TSE_SELECTED) == 0) {
       outliner_flag_set(&soops->tree, TSE_SELECTED, 0);
-      TREESTORE(te)->flag |= TSE_SELECTED;
+      tselem->flag |= TSE_SELECTED;
     }
 
     /* Gather all selected elements. */
@@ -1004,5 +1109,6 @@ void outliner_dropboxes(void)
   WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", parent_clear_poll, NULL);
   WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", scene_drop_poll, NULL);
   WM_dropbox_add(lb, "OUTLINER_OT_material_drop", material_drop_poll, NULL);
+  WM_dropbox_add(lb, "OUTLINER_OT_modifier_drop", modifier_drop_poll, NULL);
   WM_dropbox_add(lb, "OUTLINER_OT_collection_drop", collection_drop_poll, NULL);
 }
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index b077ad3d300..9f3760af3d7 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -2156,6 +2156,8 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
         break;
       case TSE_MODIFIER: {
         Object *ob = (Object *)tselem->id;
+        data.drag_id = tselem->id;
+
         if (ob->type != OB_GPENCIL) {
           ModifierData *md = BLI_findlink(&ob->modifiers, tselem->nr);
           switch ((ModifierType)md->type) {
diff --git a/source/blender/editors/space_outliner/outliner_intern.h b/source/blender/editors/space_outliner/outliner_intern.h
index 868067958ff..5450c0fcb56 100644
--- a/source/blender/editors/space_outliner/outliner_intern.h
+++ b/source/blender/editors/space_outliner/outliner_intern.h
@@ -393,6 +393,7 @@ void OUTLINER_OT_parent_drop(struct wmOperatorType *ot);
 void OUTLINER_OT_parent_clear(struct wmOperatorType *ot);
 void OUTLINER_OT_scene_drop(struct wmOperatorType *ot);
 void OUTLINER_OT_material_drop(struct wmOperatorType *ot);
+void OUTLINER_OT_modifier_drop(struct wmOperatorType *ot);
 void OUTLINER_OT_collection_drop(struct wmOperatorType *ot);
 
 /* ...................................................... */
diff --git a/source/blender/editors/space_outliner/outliner_ops.c b/source/blender/editors/space_outliner/outliner_ops.c
index 22541a0ab1f..0760159f61a 100644
--- a/source/blender/editors/space_outliner/outliner_ops.c
+++ b/source/blender/editors/space_outliner/outliner_ops.c
@@ -88,6 +88,7 @@ void outliner_operatortypes(void)
   WM_operatortype_append(OUTLINER_OT_parent_clear);
   WM_operatortype_append(OUTLINER_OT_scene_drop);
   WM_operatortype_append(OUTLINER_OT_material_drop);
+  WM_operatortype_append(OUTLINER_OT_modifier_drop);
   WM_operatortype_append(OUTLINER_OT_collection_drop);
 
   /* collections */
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 482589e2ccb..67ba283c1f1 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -673,6 +673,8 @@ 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 ad3fc7a1302..a5018273465 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -285,6 +285,17 @@ 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