[Bf-blender-cvs] [23742377627] modifier-panels-ui: Only rebuild panels when modifier list changes

Hans Goudey noreply at git.blender.org
Mon Mar 30 22:53:26 CEST 2020


Commit: 237423776272b8872946064f943c44316f7897bb
Author: Hans Goudey
Date:   Mon Mar 30 15:49:51 2020 -0500
Branches: modifier-panels-ui
https://developer.blender.org/rB237423776272b8872946064f943c44316f7897bb

Only rebuild panels when modifier list changes

Benefits of this:
- Epanding and collapsing modifier panels works
- Efficiency
- Solves other handler crashes

Also renamed modifier_index to list_index for more generality

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

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_panel.c
M	source/blender/editors/interface/interface_templates.c
M	source/blender/makesdna/DNA_screen_types.h
M	source/blender/modifiers/intern/MOD_ui_common.c

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

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 58d72c92822..def9bce591a 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1668,6 +1668,7 @@ struct Panel *UI_panel_add(struct ScrArea *sa,
                            struct ListBase *panels,
                            struct PanelType *panel_type,
                            int modifier_index);
+void UI_panel_set_list_index(struct Panel *panel, int i);
 void UI_panel_delete(struct ListBase *panels, struct Panel *panel);
 
 void UI_panels_free_recreate(struct ListBase *panels);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index e14adc6322d..2bf565c8d32 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -480,7 +480,7 @@ Panel *UI_panel_add(
   panel->blocksizey = 0;
   panel->runtime_flag |= PNL_NEW_ADDED;
 
-  panel->modifier_index = modifier_index;
+  panel->list_index = modifier_index;
 
   /* Add the panel's children too. */
   for (LinkData *link = panel_type->children.first; link; link = link->next) {
@@ -493,13 +493,23 @@ Panel *UI_panel_add(
   return panel;
 }
 
+void UI_panel_set_list_index(Panel *panel, int i)
+{
+  panel->list_index = i;
+
+  Panel *child = panel->children.first;
+  while (child != NULL) {
+    UI_panel_set_list_index(child, i);
+    child = child->next;
+  }
+}
+
 void UI_panel_delete(ListBase *panels, Panel *panel)
 {
   printf("UI_PANEL_DELETE\n");
   /* Recursively delete children. */
   Panel *child = panel->children.first;
   while (child != NULL) {
-
     Panel *child_next = child->next;
     UI_panel_delete(&panel->children, child);
     child = child_next;
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 52a1e545f86..e0a073c0307 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -1926,9 +1926,10 @@ void uiTemplatePathBuilder(uiLayout *layout,
 //   }
 // }
 
-static PanelType *panel_type_from_modifier_type(ARegion *region, const ModifierTypeInfo *mti)
+static PanelType *panel_type_from_modifier_type(ARegion *region, ModifierType type)
 {
   ARegionType *region_type = region->type;
+  const ModifierTypeInfo *mti = modifierType_getInfo(type);
 
   /* Get the name of the modifier's panel type which was defined when the panel was registered. */
   char panel_idname[BKE_ST_MAXNAME];
@@ -1943,18 +1944,52 @@ void uiTemplateModifiers(uiLayout *UNUSED(layout), bContext *C)
   ScrArea *sa = CTX_wm_area(C);
   ARegion *region = CTX_wm_region(C);
   Object *ob = CTX_data_active_object(C);
+
+  /* Check if the type corresponds between each panel consecutive panel and modifier. */
+  bool modifiers_changed = false;
+  int modifiers_len = BLI_listbase_count(&ob->modifiers);
+  int i = 0;
   ModifierData *md = ob->modifiers.first;
+  Panel *panel = region->panels.first;
+  while (panel != NULL) {
+    if (panel->type != NULL && panel->type->flag & PANELTYPE_RECREATE) {
+      if (md == NULL) {
+        /* We reached the last modifier before the last recreate panel. */
+        modifiers_changed = true;
+        break;
+      }
 
-  UI_panels_free_recreate(&region->panels);
+      if (panel_type_from_modifier_type(region, md->type) != panel->type) {
+        /* The types of the corresponding panel and modifier don't match. */
+        modifiers_changed = true;
+        break;
+      }
 
-  /* Add a panel to the region corresponding to each modifier. */
-  for (int i = 0; md; i++, md = md->next) {
-    const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-    if (mti->panel) {
-      PanelType *panel_type = panel_type_from_modifier_type(region, mti);
-      BLI_assert(panel_type != NULL);
+      UI_panel_set_list_index(panel, i);
+      panel->list_index = i;
+      md = md->next;
+      i++;
+    }
+    panel = panel->next;
+  }
 
-      UI_panel_add(sa, region, &region->panels, panel_type, i);
+  /* If we didn't make it to the last modifier, the panel list isn't complete. */
+  if (i != modifiers_len) {
+    modifiers_changed = true;
+  }
+
+  /* If the modifier list has changed at all, clear all of the recreate panels and rebuild them. */
+  if (modifiers_changed) {
+    UI_panels_free_recreate(&region->panels);
+    md = ob->modifiers.first;
+    for (i = 0; md; i++, md = md->next) {
+      const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+      if (mti->panel) {
+        PanelType *panel_type = panel_type_from_modifier_type(region, md->type);
+        BLI_assert(panel_type != NULL);
+
+        UI_panel_add(sa, region, &region->panels, panel_type, i);
+      }
     }
   }
 }
@@ -2023,7 +2058,8 @@ static uiLayout *gpencil_draw_modifier(uiLayout *layout, Object *ob, GpencilModi
   uiItemO(row, "", ICON_X, "OBJECT_OT_gpencil_modifier_remove");
   UI_block_emboss_set(block, UI_EMBOSS);
 
-  /* modifier settings (under the header) --------------------------------------------------- */
+  /* modifier settings (under the header) ---------------------------------------------------
+   */
   if (md->mode & eGpencilModifierMode_Expanded) {
     /* apply/convert/copy */
     box = uiLayoutBox(column);
@@ -4691,8 +4727,8 @@ static void CurveProfile_buttons_layout(uiLayout *layout, PointerRNA *ptr, RNAUp
   uiLayoutRow(layout, false);
 
   /* Preset selector */
-  /* There is probably potential to use simpler "uiItemR" functions here, but automatic updating
-   * after a preset is selected would be more complicated. */
+  /* There is probably potential to use simpler "uiItemR" functions here, but automatic
+   * updating after a preset is selected would be more complicated. */
   bt = uiDefBlockBut(
       block, CurveProfile_buttons_presets, profile, "Preset", 0, 0, UI_UNIT_X, UI_UNIT_X, "");
   UI_but_funcN_set(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
@@ -5650,8 +5686,8 @@ static void uilist_filter_items_default(struct uiList *ui_list,
       int new_idx;
       /* note: order_idx equals either to ui_list->items_len if no filtering done,
        *       or to ui_list->items_shown if filter is enabled,
-       *       or to (ui_list->items_len - ui_list->items_shown) if filtered items are excluded.
-       *       This way, we only sort items we actually intend to draw!
+       *       or to (ui_list->items_len - ui_list->items_shown) if filtered items are
+       * excluded. This way, we only sort items we actually intend to draw!
        */
       qsort(names, order_idx, sizeof(StringCmp), cmpstringp);
 
@@ -5678,7 +5714,8 @@ typedef struct {
 } _uilist_item;
 
 typedef struct {
-  int visual_items; /* Visual number of items (i.e. number of items we have room to display). */
+  int visual_items; /* Visual number of items (i.e. number of items we have room to display).
+                     */
   int start_idx;    /* Index of first item to display. */
   int end_idx;      /* Index of last item to display + 1. */
 } uiListLayoutdata;
@@ -5751,7 +5788,8 @@ static void uilist_resize_update_cb(bContext *C, void *arg1, void *UNUSED(arg2))
   uiList *ui_list = arg1;
   uiListDyn *dyn_data = ui_list->dyn_data;
 
-  /* This way we get diff in number of additional items to show (positive) or hide (negative). */
+  /* This way we get diff in number of additional items to show (positive) or hide (negative).
+   */
   const int diff = round_fl_to_int((float)(dyn_data->resize - dyn_data->resize_prev) /
                                    (float)UI_UNIT_Y);
 
@@ -6900,7 +6938,8 @@ static struct MenuSearch_Data *menu_items_from_ui_create(bContext *C,
     UI_block_free(NULL, block);
 
     /* Add key-map items as a second pass,
-     * so all menus are accessed from the header & top-bar before key shortcuts are expanded. */
+     * so all menus are accessed from the header & top-bar before key shortcuts are expanded.
+     */
     if ((menu_stack == NULL) && (has_keymap_menu_items == false)) {
       has_keymap_menu_items = true;
       menu_types_add_from_keymap_items(C, win, sa, region, &menu_stack, menu_to_kmi, menu_tagged);
@@ -7644,8 +7683,8 @@ void uiTemplateReportsBanner(uiLayout *layout, bContext *C)
   /* icon and report message on top */
   icon = UI_icon_from_report_type(report->type);
 
-  /* XXX: temporary operator to dump all reports to a text block, but only if more than 1 report
-   * to be shown instead of icon when appropriate...
+  /* XXX: temporary operator to dump all reports to a text block, but only if more than 1
+   * report to be shown instead of icon when appropriate...
    */
   UI_block_emboss_set(block, UI_EMBOSS_NONE);
 
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index 94ea1c99d80..1095739c7f2 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -165,7 +165,7 @@ typedef struct Panel {
   void *activedata;
   /* For recreate type panels to store which instance of their panel type creator's object they
    * correspond to. */
-  int modifier_index;
+  int list_index;
   char _pad1[4];
   /** Sub panels. */
   ListBase children;
diff --git a/source/blender/modifiers/intern/MOD_ui_common.c b/source/blender/modifiers/intern/MOD_ui_common.c
index 4525390362b..384b6d91674 100644
--- a/source/blender/modifiers/intern/MOD_ui_common.c
+++ b/source/blender/modifiers/intern/MOD_ui_common.c
@@ -66,7 +66,7 @@ void modifier_panel_get_property_pointers(const bContext *C,
   Object *ob = CTX_data_active_object(C);
   ModifierData *md = ob->modifiers.first;
 
-  for (int i = 0; i < panel->modifier_index; i++) {
+  for (int i = 0; i < panel->list_index; i++) {
     md = md->next;
   }
   RNA_pointer_create(&ob->id, &RNA_Modifier, md, r_md_ptr);
@@ -106,7 +106,7 @@ static void modifier_panel_header(const bContext *C, Panel *panel)
   modifier_panel_get_property_pointers(C, panel, NULL, &ptr);
   ModifierData *md = ptr.data;
   const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-  int index = panel->modifier_in

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list