[Bf-blender-cvs] [54da72d3cd5] master: Property Search: Reset panel expansion when exiting search

Hans Goudey noreply at git.blender.org
Fri Oct 16 22:17:00 CEST 2020


Commit: 54da72d3cd546ecbd2560d7d57cbed33064bbee1
Author: Hans Goudey
Date:   Fri Oct 16 15:16:44 2020 -0500
Branches: master
https://developer.blender.org/rB54da72d3cd546ecbd2560d7d57cbed33064bbee1

Property Search: Reset panel expansion when exiting search

This patch implements panel expansion saving and resetting for property
search. While search is active, the panel expansion is based on whether
or not it has a search result. When the search finishes, the panel
expansion returns to its state before the search started. However, any
panels interacted with during the search won't reset their expansion.

This requires adding a new runtime flag for panels to store whether to
use search result status as expansion. It also requires better handling
for animation when panel expansion changes with another new runtime flag.
`UI_panel_is_closed` gets the search-dependent expansion, but it is
intentionally not used to access expansion in every case-- sometimes it's
necessary to use `PNL_CLOSED` directly.

Differential Revision: https://developer.blender.org/D8984

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

M	source/blender/editors/include/UI_interface.h
M	source/blender/editors/interface/interface_panel.c
M	source/blender/editors/screen/area.c

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

diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 2c8518de700..c987a8ac13b 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1693,6 +1693,7 @@ void UI_panel_header_buttons_begin(struct Panel *panel);
 void UI_panel_header_buttons_end(struct Panel *panel);
 void UI_panel_end(struct Panel *panel, int width, int height);
 
+bool UI_panel_is_closed(const struct Panel *panel);
 bool UI_panel_is_active(const struct Panel *panel);
 void UI_panel_label_offset(struct uiBlock *block, int *r_x, int *r_y);
 int UI_panel_size_y(const struct Panel *panel);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 7e2ca776f5b..48abc1f4d82 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -78,6 +78,13 @@ typedef enum uiPanelRuntimeFlag {
   PANEL_ANIM_ALIGN = (1 << 4),
   PANEL_NEW_ADDED = (1 << 5),
   PANEL_SEARCH_FILTER_MATCH = (1 << 7),
+  /**
+   * Use the status set by property search (#PANEL_SEARCH_FILTER_MATCH)
+   * instead of #PNL_CLOSED. Set to true on every property search update.
+   */
+  PANEL_USE_CLOSED_FROM_SEARCH = (1 << 8),
+  /** The Panel was before the start of the current / latest layout pass. */
+  PANEL_WAS_CLOSED = (1 << 9),
 } uiPanelRuntimeFlag;
 
 /* The state of the mouse position relative to the panel. */
@@ -168,7 +175,13 @@ static bool panel_active_animation_changed(ListBase *lb,
       }
     }
 
-    if ((panel->runtime_flag & PANEL_ACTIVE) && !(panel->flag & PNL_CLOSED)) {
+    /* Detect changes in panel expansions. */
+    if ((bool)(panel->runtime_flag & PANEL_WAS_CLOSED) != UI_panel_is_closed(panel)) {
+      *r_panel_animation = panel;
+      return false;
+    }
+
+    if ((panel->runtime_flag & PANEL_ACTIVE) && !UI_panel_is_closed(panel)) {
       if (panel_active_animation_changed(&panel->children, r_panel_animation, r_no_animation)) {
         return true;
       }
@@ -492,7 +505,8 @@ static void reorder_instanced_panel_list(bContext *C, ARegion *region, Panel *dr
 static bool panel_set_expand_from_list_data_recursive(Panel *panel, short flag, short *flag_index)
 {
   const bool open = (flag & (1 << *flag_index));
-  bool changed = (open == (bool)(panel->flag & PNL_CLOSED));
+  bool changed = (open == UI_panel_is_closed(panel));
+
   SET_FLAG_FROM_TEST(panel->flag, !open, PNL_CLOSED);
 
   LISTBASE_FOREACH (Panel *, child, &panel->children) {
@@ -673,6 +687,7 @@ Panel *UI_panel_begin(
 
     if (pt->flag & PNL_DEFAULT_CLOSED) {
       panel->flag |= PNL_CLOSED;
+      panel->runtime_flag |= PANEL_WAS_CLOSED;
     }
 
     panel->ofsx = 0;
@@ -692,16 +707,6 @@ Panel *UI_panel_begin(
 
   panel->runtime.block = block;
 
-  /* Do not allow closed panels without headers! Else user could get "disappeared" UI! */
-  if ((pt->flag & PNL_NO_HEADER) && (panel->flag & PNL_CLOSED)) {
-    panel->flag &= ~PNL_CLOSED;
-    /* Force update of panels' positions. */
-    panel->sizex = 0;
-    panel->sizey = 0;
-    panel->blocksizex = 0;
-    panel->blocksizey = 0;
-  }
-
   BLI_strncpy(panel->drawname, drawname, sizeof(panel->drawname));
 
   /* If a new panel is added, we insert it right after the panel that was last added.
@@ -737,7 +742,7 @@ Panel *UI_panel_begin(
 
   *r_open = false;
 
-  if (panel->flag & PNL_CLOSED) {
+  if (UI_panel_is_closed(panel)) {
     return panel;
   }
 
@@ -829,7 +834,7 @@ static void panel_calculate_size_recursive(ARegion *region, Panel *panel)
     if (width != 0) {
       panel->sizex = width;
     }
-    if (height != 0 || !(panel->flag & PNL_CLOSED)) {
+    if (height != 0 || !UI_panel_is_closed(panel)) {
       panel->sizey = height;
     }
 
@@ -902,39 +907,41 @@ bool UI_panel_matches_search_filter(const Panel *panel)
 }
 
 /**
- * Expands a panel if it was tagged as having a result by property search, otherwise collapses it.
+ * Set the flag telling the panel to use its search result status for
+ * its expansion. Also activate animation if that changes the expansion.
  */
 static void panel_set_expansion_from_seach_filter_recursive(const bContext *C,
                                                             Panel *panel,
+                                                            const bool use_search_closed,
                                                             const bool use_animation)
 {
-  if (!(panel->type->flag & PNL_NO_HEADER)) {
-    short start_flag = panel->flag;
-    SET_FLAG_FROM_TEST(panel->flag, !UI_panel_matches_search_filter(panel), PNL_CLOSED);
-    if (use_animation && start_flag != panel->flag) {
-      panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
-    }
+  /* This has to run on inactive panels that may not have a type,
+   * but we can prevent running on headerless panels in some cases. */
+  if (panel->type == NULL || !(panel->type->flag & PNL_NO_HEADER)) {
+    SET_FLAG_FROM_TEST(panel->runtime_flag, use_search_closed, PANEL_USE_CLOSED_FROM_SEARCH);
   }
 
-  /* If the panel is filtered (removed) we need to check that its children are too. */
   LISTBASE_FOREACH (Panel *, child_panel, &panel->children) {
-    if (child_panel->runtime_flag & PANEL_ACTIVE) {
-      panel_set_expansion_from_seach_filter_recursive(C, child_panel, use_animation);
-    }
+    /* Don't check if the subpanel is active, otherwise the
+     * expansion won't be reset when the parent is closed. */
+    panel_set_expansion_from_seach_filter_recursive(
+        C, child_panel, use_search_closed, use_animation);
   }
 }
 
 /**
- * Uses the panel's search filter flag to set its expansion, activating animation if it was closed
- * or opened. Note that this can't be set too often, or manual interaction becomes impossible.
+ * Set the flag telling every panel to override its expansion with its search result status.
  */
 static void region_panels_set_expansion_from_seach_filter(const bContext *C,
                                                           ARegion *region,
+                                                          const bool use_search_closed,
                                                           const bool use_animation)
 {
   LISTBASE_FOREACH (Panel *, panel, &region->panels) {
+    /* Checking if the panel is active is only an optimization, it would be fine to run this on
+     * inactive panels. */
     if (panel->runtime_flag & PANEL_ACTIVE) {
-      panel_set_expansion_from_seach_filter_recursive(C, panel, use_animation);
+      panel_set_expansion_from_seach_filter_recursive(C, panel, use_search_closed, use_animation);
     }
   }
   set_panels_list_data_expand_flag(C, region);
@@ -949,14 +956,14 @@ static void panel_remove_invisible_layouts_recursive(Panel *panel, const Panel *
   uiBlock *block = panel->runtime.block;
   BLI_assert(block != NULL);
   BLI_assert(block->active);
-  if (parent_panel != NULL && parent_panel->flag & PNL_CLOSED) {
+  if (parent_panel != NULL && UI_panel_is_closed(parent_panel)) {
     /* The parent panel is closed, so this panel can be completely removed. */
     UI_block_set_search_only(block, true);
     LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
       but->flag |= UI_HIDDEN;
     }
   }
-  else if (panel->flag & PNL_CLOSED) {
+  else if (UI_panel_is_closed(panel)) {
     /* If subpanels have no search results but the parent panel does, then the parent panel open
      * and the subpanels will close. In that case there must be a way to hide the buttons in the
      * panel but keep the header buttons. */
@@ -989,6 +996,24 @@ static void region_panels_remove_invisible_layouts(ARegion *region)
   }
 }
 
+/**
+ * Get the panel's expansion state, taking into account
+ * expansion set from property search if it applies.
+ */
+bool UI_panel_is_closed(const Panel *panel)
+{
+  /* Header-less panels can never be closed, otherwise they could disappear. */
+  if (panel->type && panel->type->flag & PNL_NO_HEADER) {
+    return false;
+  }
+
+  if (panel->runtime_flag & PANEL_USE_CLOSED_FROM_SEARCH) {
+    return !UI_panel_matches_search_filter(panel);
+  }
+
+  return panel->flag & PNL_CLOSED;
+}
+
 bool UI_panel_is_active(const Panel *panel)
 {
   return panel->runtime_flag & PANEL_ACTIVE;
@@ -1135,12 +1160,12 @@ void ui_draw_aligned_panel(const uiStyle *style,
     /* Expand the top a tiny bit to give header buttons equal size above and below. */
     rcti box_rect = {rect->xmin,
                      rect->xmax,
-                     (panel->flag & PNL_CLOSED) ? headrect.ymin : rect->ymin,
+                     UI_panel_is_closed(panel) ? headrect.ymin : rect->ymin,
                      headrect.ymax + U.pixelsize};
     ui_draw_box_opaque(&box_rect, UI_CNR_ALL);
 
     /* Mimic the border between aligned box widgets for the bottom of the header. */
-    if (!(panel->flag & PNL_CLOSED)) {
+    if (!UI_panel_is_closed(panel)) {
       immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
       GPU_blend(GPU_BLEND_ALPHA);
 
@@ -1237,7 +1262,7 @@ void ui_draw_aligned_panel(const uiStyle *style,
   }
 
   /* Draw panel backdrop. */
-  if (!(panel->flag & PNL_CLOSED)) {
+  if (!UI_panel_is_closed(panel)) {
     /* in some occasions, draw a border */
     if (panel->flag & PNL_SELECT && !is_subpanel) {
       float radius;
@@ -1309,7 +1334,7 @@ void ui_draw_aligned_panel(const uiStyle *style,
     rgb_uchar_to_float(tria_color, col_title);
     tria_color[3] = 1.0f;
 
-    if (panel->flag & PNL_CLOSED) {
+    if (UI_panel_is_closed(panel)) {
       ui_draw_anti_tria_rect(&itemrect, 'h', tria_color);
     }
     else {
@@ -1581,7 +1606,7 @@ static int get_panel_size_y(const Panel *panel)
 
 static int get_panel_real_size_y(const Panel *panel)
 {
-  const int sizey = (panel->flag & PNL_CLOSED) ? 0 : panel->sizey;
+  const int sizey = UI_panel_is_closed(panel) ? 0 : panel->sizey;
 
   if (panel->type && (panel->type->flag & PNL_NO_HEADER)) {
     return sizey;
@@ -1601,7 +1626,7 @@ int UI_panel_size_y(const Panel *panel)
  */
 static int get_panel_real_ofsy(Panel *panel)
 {
-  if (panel->flag & PNL_CLOSED) {
+  if (UI_panel_is_closed(panel)) {
     return panel->ofsy + pa

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list