[Bf-blender-cvs] [a7e3bbabd2e] modifier-panels-ui: Cleanup: Rearrange code

Hans Goudey noreply at git.blender.org
Wed Apr 22 21:35:40 CEST 2020


Commit: a7e3bbabd2efcd0e1e6b29f36015fa2bad4b1210
Author: Hans Goudey
Date:   Wed Apr 22 14:34:59 2020 -0500
Branches: modifier-panels-ui
https://developer.blender.org/rBa7e3bbabd2efcd0e1e6b29f36015fa2bad4b1210

Cleanup: Rearrange code

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

M	source/blender/editors/interface/interface_panel.c

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

diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index f50e63690ef..ef75c7f08bd 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -106,23 +106,21 @@ typedef struct uiHandlePanelData {
   /* animation */
   wmTimer *animtimer;
   double starttime;
-  bool is_drag_drop;
 
   /* dragging */
+  bool is_drag_drop;
   int startx, starty;
   int startofsx, startofsy;
   int startsizex, startsizey;
-
-  /* Drag Scrolling */
-  double starttime_drag_scroll;
-  /* Note: There can be multiple drag scroll "sessions" if the mouse leaves the scoll zone, so we
-   * need to keep track of the total scroll separately from the scroll for each "session." */
-  float scroll_offset, scroll_offset_total;
-
 } uiHandlePanelData;
 
+typedef struct PanelSort {
+  Panel *panel, *orig;
+} PanelSort;
+
 static int get_panel_real_size_y(const Panel *panel);
 static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelState state);
+static int compare_panel(const void *a1, const void *a2);
 
 static void panel_title_color_get(bool show_background, uchar color[4])
 {
@@ -248,7 +246,250 @@ static bool panels_need_realign(ScrArea *area, ARegion *region, Panel **r_panel_
   return false;
 }
 
-/****************************** panels ******************************/
+/***** Functions for recreate list panels. ***********/
+
+/**
+ * Called in situations where panels need to be added dynamically rather than having only one panel
+ * corresponding to each PanelType.
+ */
+Panel *UI_panel_add_list(
+    ScrArea *sa, ARegion *region, ListBase *panels, PanelType *panel_type, int list_index)
+{
+  Panel *panel = MEM_callocN(sizeof(Panel), "list panel");
+  panel->type = panel_type;
+  BLI_strncpy(panel->panelname, panel_type->idname, sizeof(panel->panelname));
+
+  panel->ofsx = 0;
+  panel->ofsy = 0;
+  panel->sizex = 0;
+  panel->sizey = 0;
+  panel->blocksizex = 0;
+  panel->blocksizey = 0;
+
+  panel->runtime.list_index = list_index;
+
+  /* Add the panel's children too. Although they aren't list panels, we can still use this
+   * function to creat them, as UI_panel_begin does other things we don't need to do. */
+  for (LinkData *link = panel_type->children.first; link; link = link->next) {
+    PanelType *child = link->data;
+    UI_panel_add_list(sa, region, &panel->children, child, list_index);
+  }
+
+  /* If we're adding a recreate list panel, make sure it's added to the end of the list. Check the
+   * context string to make sure we add to the right list.
+   *
+   * We can the panel list is also the display order because the list panel list is rebuild
+   * when the order changes. */
+  if (panel_type->flag & PNL_LIST) {
+    Panel *last_list_panel = NULL;
+
+    for (Panel *list_panel = panels->first; list_panel; list_panel = list_panel->next) {
+      if (list_panel->type == NULL) {
+        continue;
+      }
+      if (list_panel->type->flag & (PNL_LIST_START | PNL_LIST)) {
+        last_list_panel = list_panel;
+      }
+    }
+
+    /* There should always be a list panel or a list panel start before this panel. */
+    BLI_assert(last_list_panel);
+
+    panel->sortorder = last_list_panel->sortorder + 1;
+
+    BLI_insertlinkafter(panels, last_list_panel, panel);
+  }
+  else {
+    BLI_addtail(panels, panel);
+  }
+
+  return panel;
+}
+
+void UI_list_panel_unique_str(Panel *panel, char *r_name)
+{
+  snprintf(r_name, LIST_PANEL_UNIQUE_STR_LEN, "%d", panel->runtime.list_index);
+}
+
+static void panel_free_block(ARegion *region, Panel *panel)
+{
+  BLI_assert(panel->type);
+
+  char block_name[BKE_ST_MAXNAME + LIST_PANEL_UNIQUE_STR_LEN];
+  strncpy(block_name, panel->type->idname, BKE_ST_MAXNAME);
+  char unique_panel_str[LIST_PANEL_UNIQUE_STR_LEN];
+  UI_list_panel_unique_str(panel, unique_panel_str);
+  strncat(block_name, unique_panel_str, LIST_PANEL_UNIQUE_STR_LEN);
+
+  LISTBASE_FOREACH (uiBlock *, block, &region->uiblocks) {
+    if (STREQ(block->name, block_name)) {
+      BLI_remlink(&region->uiblocks, block);
+      UI_block_free(NULL, block);
+      break; /* Only delete one block for this panel. */
+    }
+  }
+}
+
+void UI_panel_delete(ARegion *region, ListBase *panels, Panel *panel)
+{
+  /* Recursively delete children. */
+  Panel *child = panel->children.first;
+  while (child != NULL) {
+    Panel *child_next = child->next;
+    UI_panel_delete(region, &panel->children, child);
+    child = child_next;
+  }
+  BLI_freelistN(&panel->children);
+
+  panel_free_block(region, panel);
+
+  BLI_remlink(panels, panel);
+  if (panel->activedata) {
+    MEM_freeN(panel->activedata);
+  }
+  MEM_freeN(panel);
+}
+
+void UI_panels_free_list(bContext *C, ARegion *region)
+{
+  /* Delete panels with the recreate flag. */
+  ListBase *panels = &region->panels;
+  Panel *panel = panels->first;
+  Panel *panel_next = NULL;
+  while (panel != NULL) {
+    bool remove = false;
+    if (panel->type != NULL) { /* Some panels don't have a type.. */
+      if (panel->type->flag & PNL_LIST) {
+        remove = true;
+      }
+    }
+
+    panel_next = panel->next;
+    if (remove) {
+      if (panel->activedata != NULL) {
+        panel_activate_state(C, panel, PANEL_STATE_EXIT);
+      }
+      UI_panel_delete(region, panels, panel);
+    }
+    panel = panel_next;
+  }
+}
+
+/**
+ * Check if the list panels in the region's panel list corresponds to the list of data the panels
+ * represent. Returns false if the panels have been reordered or if the types from the list data
+ * don't match in any way.
+ *
+ * \param data: The list of data to check against the list panels.
+ * \param panel_type_func: Each type from the data list should have a corresponding panel type. For
+ * a mix of readabilty and generality, this can happen separately for each type of panel list.
+ */
+bool UI_panel_list_matches_data(ARegion *region,
+                                ListBase *data,
+                                uiListPanelTypeFromDataFunc panel_type_func)
+{
+  int data_len = BLI_listbase_count(data);
+  int i = 0;
+  Link *data_link = data->first;
+  Panel *panel = region->panels.first;
+  while (panel != NULL) {
+    if (panel->type != NULL && panel->type->flag & PNL_LIST) {
+      /* The panels were reordered by drag and drop. */
+      if (panel->flag & PNL_LIST_ORDER_CHANGED) {
+        return false;
+      }
+
+      /* We reached the last contraint before the last list panel. */
+      if (data_link == NULL) {
+        return false;
+      }
+
+      /* The types of the corresponding panel and constraint don't match. */
+      if (panel_type_func(region, data_link) != panel->type) {
+        return false;
+      }
+
+      data_link = data_link->next;
+      i++;
+    }
+    panel = panel->next;
+  }
+
+  /* If we didn't make it to the last list item, the panel list isn't complete. */
+  if (i != data_len) {
+    return false;
+  }
+
+  return true;
+}
+
+static void reorder_recreate_panel_list(bContext *C, ARegion *region, Panel *panel)
+{
+  /* Only reorder the data for list panels. */
+  if (panel->type == NULL || !(panel->type->flag & PNL_LIST)) {
+    return;
+  }
+  /* Don't reorder if this list panel doesn't support drag and drop reordering. */
+  if (panel->type->reorder == NULL) {
+    return;
+  }
+
+  char *context = panel->type->context;
+
+  /* Find how many list 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 & PNL_LIST) {
+          list_panels_len++;
+        }
+      }
+    }
+  }
+
+  /* Sort the matching list panels by their display order. */
+  PanelSort *panel_sort = MEM_callocN(list_panels_len * sizeof(PanelSort), "recreatepanelsort");
+  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 & PNL_LIST) {
+          sort_index->panel = 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;
+    }
+  }
+
+  /* Free panel sort array. */
+  int i = 0;
+  for (sort_index = panel_sort; i < list_panels_len; i++, sort_index++) {
+    MEM_freeN(sort_index->panel);
+  }
+  MEM_freeN(panel_sort);
+
+  /* Don't reorder the panel didn't change order after being dropped. */
+  if (move_to_index == panel->runtime.list_index) {
+    return;
+  }
+
+  /* Set the bit to tell the interface to recreate the list. */
+  panel->flag |= PNL_LIST_ORDER_CHANGED;
+
+  /* Finally, move this panel's list item to the new index in its list. */
+  panel->type->reorder(C, panel, move_to_index);
+}
 
 /**
  * Recursive implementation for #UI_panel_set_expand_from_list_data.
@@ -332,6 +573,8 @@ static void set_panels_list_data_expand_flag(const bContext *C, ARegion *region)
   }
 }
 
+/****************************** panels ******************************/
+
 static void panels_collapse_all(const bContext *C,
                                 ScrArea *area,
                                 ARegion *region,
@@ -463,272 +706,95 @@ Panel *UI_panel_begin(ScrArea *area,
     UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
   }
 
-  *r_open = false;
-
-  if (panel->flag & PNL_CLOSED) {
-    return panel;
-  }
-
-  *r_open = true;
-
-  return panel;
-}
-
-static float panel_region_offset_x_get(const ARegion *region, int align)
-{
-  if (UI_panel_category_is_visible(region)) {
-    if (align == BUT_VERTICAL &&
-        (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) != RGN_ALIGN_RIGHT)) {
-      return UI_PANEL_CATEGORY_MARGIN_WIDTH;
-    }
-

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list