[Bf-blender-cvs] [5699058e542] modifier-panels-ui: Drag and drop modifiers from panels

Hans Goudey noreply at git.blender.org
Thu Apr 2 19:59:34 CEST 2020


Commit: 5699058e542ffa0cd8334fd6ce99d8ae3cbb4843
Author: Hans Goudey
Date:   Thu Apr 2 12:56:33 2020 -0500
Branches: modifier-panels-ui
https://developer.blender.org/rB5699058e542ffa0cd8334fd6ce99d8ae3cbb4843

Drag and drop modifiers from panels

When the panel animation finishes, a new move modifier to index
operator is called, reordering the modifier stack. Then on the next
draw, the panel types mismatch and the stack is redrawn (or new
indices are set if the types match).

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

M	source/blender/editors/interface/interface_panel.c
M	source/blender/editors/object/object_intern.h
M	source/blender/editors/object/object_modifier.c
M	source/blender/editors/object/object_ops.c

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

diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 35fc118d450..c2367d7b03f 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -39,7 +39,9 @@
 
 #include "BLT_translation.h"
 
+#include "DNA_modifier_types.h"
 #include "DNA_userdef_types.h"
+/* HANS-TODO: Generalize this and move re-ordering code elsewhere. */
 
 #include "BKE_context.h"
 #include "BKE_screen.h"
@@ -59,6 +61,8 @@
 #include "GPU_immediate.h"
 #include "GPU_state.h"
 
+#include "RNA_access.h"
+
 #include "interface_intern.h"
 
 /*********************** defines and structs ************************/
@@ -98,6 +102,7 @@ typedef struct uiHandlePanelData {
   /* animation */
   wmTimer *animtimer;
   double starttime;
+  bool is_drag_drop;
 
   /* dragging */
   int startx, starty;
@@ -506,7 +511,6 @@ void UI_panel_set_list_index(Panel *panel, int i)
 
 void UI_panel_delete(ListBase *panels, Panel *panel)
 {
-  printf("UI_PANEL_DELETE\n");
   /* Recursively delete children. */
   Panel *child = panel->children.first;
   while (child != NULL) {
@@ -526,7 +530,7 @@ void UI_panel_delete(ListBase *panels, Panel *panel)
 void UI_panels_free_recreate(ListBase *panels)
 {
   /* Delete panels with the recreate flag. */
-  printf("UI_PANELS_FREE_RECREATE\n");
+  // printf("UI_PANELS_FREE_RECREATE\n");
   Panel *panel = panels->first;
   Panel *panel_next = NULL;
   while (panel != NULL) {
@@ -1129,7 +1133,6 @@ static bool uiAlignPanelStep(ScrArea *sa, ARegion *region, const float fac, cons
       tot++;
     }
   }
-
   if (tot == 0) {
     return 0;
   }
@@ -1438,6 +1441,61 @@ static void check_panel_overlap(ARegion *region, Panel *panel)
 
 /************************ panel dragging ****************************/
 
+static void reorder_recreate_panel_list(bContext *C, ARegion *region, Panel *panel)
+{
+  if (panel->type == NULL) {
+    return;
+  }
+  char *context = panel->type->context;
+
+  /* Find how many recreate panels with this context string. */
+  int list_panels_len = 0;
+  for (Panel *list_panel = region->panels.first; list_panel; list_panel = list_panel->next) {
+    if (list_panel->type) {
+      if ((strcmp(list_panel->type->context, context) == 0)) {
+        if (list_panel->type->flag & PANELTYPE_RECREATE) {
+          list_panels_len++;
+        }
+      }
+    }
+  }
+
+  /* Sort the matching recreate panels by their display order. */
+  PanelSort *panel_sort = MEM_callocN(list_panels_len * sizeof(PanelSort), "panelsort");
+  PanelSort *sort_index = panel_sort;
+  for (Panel *list_panel = region->panels.first; list_panel; list_panel = list_panel->next) {
+    if (list_panel->type) {
+      if ((strcmp(list_panel->type->context, context) == 0)) {
+        if (list_panel->type->flag & PANELTYPE_RECREATE) {
+          sort_index->pa = MEM_dupallocN(list_panel);
+          sort_index->orig = list_panel;
+          sort_index++;
+        }
+      }
+    }
+  }
+  qsort(panel_sort, list_panels_len, sizeof(PanelSort), compare_panel);
+
+  /* Find how many of those panels are above this panel. */
+  int move_to_index = 0;
+  for (; move_to_index < list_panels_len; move_to_index++) {
+    if (panel_sort[move_to_index].orig == panel) {
+      break;
+    }
+  }
+
+  /* Move this panel's list item to the corresponding index in its list. */
+  Object *ob = CTX_data_active_object(C);
+  ModifierData *md = BLI_findlink(&ob->modifiers, panel->list_index);
+  PointerRNA props_ptr;
+  wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_modifier_move_to_index", false);
+  WM_operator_properties_create_ptr(&props_ptr, ot);
+  RNA_string_set(&props_ptr, "modifier", md->name);
+  RNA_int_set(&props_ptr, "index", move_to_index);
+  WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &props_ptr);
+  WM_operator_properties_free(&props_ptr);
+}
+
 static void ui_do_drag(const bContext *C, const wmEvent *event, Panel *panel)
 {
   uiHandlePanelData *data = panel->activedata;
@@ -2557,6 +2615,7 @@ static int ui_handler_panel(bContext *C, const wmEvent *event, void *userdata)
     int align = panel_aligned(sa, region);
 
     if (align) {
+      data->is_drag_drop = true;
       panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
     }
     else {
@@ -2631,6 +2690,10 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
     MEM_freeN(data);
     pa->activedata = NULL;
 
+    if (data->is_drag_drop) {
+      reorder_recreate_panel_list(C, region, pa);
+    }
+
     WM_event_remove_ui_handler(
         &win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, false);
   }
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index e43942bb35f..41cd4fb010e 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -151,6 +151,7 @@ bool edit_modifier_poll_generic(struct bContext *C,
                                 struct StructRNA *rna_type,
                                 int obtype_flag,
                                 const bool is_editmode_allowed);
+bool edit_active_modifier_poll_generic(bContext *C, const bool is_editmode_allowed);
 bool edit_modifier_poll(struct bContext *C);
 void edit_modifier_properties(struct wmOperatorType *ot);
 int edit_modifier_invoke_properties(struct bContext *C, struct wmOperator *op);
@@ -164,6 +165,7 @@ void OBJECT_OT_modifier_active_remove(struct wmOperatorType *ot);
 void OBJECT_OT_modifier_move_up(struct wmOperatorType *ot);
 void OBJECT_OT_modifier_move_down(struct wmOperatorType *ot);
 void OBJECT_OT_modifier_active_move(struct wmOperatorType *ot);
+void OBJECT_OT_modifier_move_to_index(struct wmOperatorType *ot);
 void OBJECT_OT_modifier_apply(struct wmOperatorType *ot);
 void OBJECT_OT_modifier_convert(struct wmOperatorType *ot);
 void OBJECT_OT_modifier_copy(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 37e361f111c..a9f37bccb2e 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -1384,6 +1384,68 @@ void OBJECT_OT_modifier_active_move(wmOperatorType *ot)
 
 /** \} */
 
+/* ------------------------------------------------------------------- */
+/** \name Move to Index Modifier Operator
+ * \{ */
+
+static bool OBJECT_OT_modifier_move_to_index_poll(bContext *C)
+{
+  return edit_active_modifier_poll_generic(C, true);
+}
+
+static int OBJECT_OT_modifier_move_to_index_exec(bContext *C, wmOperator *op)
+{
+  Object *ob = ED_object_active_context(C);
+  ModifierData *md = edit_modifier_property_get(op, ob, 0);
+  int index = RNA_enum_get(op->ptr, "index");
+
+  if (!ED_object_modifier_move_to_index(op->reports, ob, md, index)) {
+    return OPERATOR_CANCELLED;
+  }
+
+  DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
+  WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+  return OPERATOR_FINISHED;
+}
+
+static int OBJECT_OT_modifier_move_to_index_invoke(bContext *C,
+                                                   wmOperator *op,
+                                                   const wmEvent *UNUSED(event))
+{
+  if (edit_modifier_active_invoke_properties(C, op)) {
+    return OBJECT_OT_modifier_move_to_index_exec(C, op);
+  }
+  else {
+    return OPERATOR_CANCELLED;
+  }
+}
+
+void OBJECT_OT_modifier_move_to_index(wmOperatorType *ot)
+{
+  static const EnumPropertyItem modifier_active_move[] = {
+      {-1, "UP", 0, "Up", ""},
+      {1, "DOWN", 0, "Down", ""},
+      {0, NULL, 0, NULL, NULL},
+  };
+
+  ot->name = "Move Active Modifier to Index";
+  ot->description = "Move the active modifier to an index in the stack";
+  ot->idname = "OBJECT_OT_modifier_move_to_index";
+
+  ot->invoke = OBJECT_OT_modifier_move_to_index_invoke;
+  ot->exec = OBJECT_OT_modifier_move_to_index_exec;
+  ot->poll = OBJECT_OT_modifier_move_to_index_poll;
+
+  /* flags */
+  ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+  edit_modifier_properties(ot);
+  RNA_def_int(
+      ot->srna, "index", 0, 0, INT_MAX, "Index", "The index to move the modifier to", 0, INT_MAX);
+}
+
+/** \} */
+
 /* ------------------------------------------------------------------- */
 /** \name Apply Modifier Operator
  * \{ */
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 64f977ce304..5b168e69d90 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -132,6 +132,7 @@ void ED_operatortypes_object(void)
   WM_operatortype_append(OBJECT_OT_modifier_move_up);
   WM_operatortype_append(OBJECT_OT_modifier_move_down);
   WM_operatortype_append(OBJECT_OT_modifier_active_move);
+  WM_operatortype_append(OBJECT_OT_modifier_move_to_index);
   WM_operatortype_append(OBJECT_OT_modifier_apply);
   WM_operatortype_append(OBJECT_OT_modifier_convert);
   WM_operatortype_append(OBJECT_OT_modifier_copy);



More information about the Bf-blender-cvs mailing list