[Bf-blender-cvs] [75fbf6f17e6] master: Asset Browser: Show catalog add & delete icons on mouse hover (only)

Julian Eisel noreply at git.blender.org
Wed Oct 6 16:36:57 CEST 2021


Commit: 75fbf6f17e69ee9c6487173ae5957cfff5193d1f
Author: Julian Eisel
Date:   Wed Oct 6 16:29:10 2021 +0200
Branches: master
https://developer.blender.org/rB75fbf6f17e69ee9c6487173ae5957cfff5193d1f

Asset Browser: Show catalog add & delete icons on mouse hover (only)

Now the icons to add or delete catalogs are only shown when mouse hovering a
catalog item in the tree. This is convenient for quick creation of catalogs,
and doesn't require activating a catalog to edit it first.

Determining if a tree item is hovered isn't trivial actually. The UI tree-view
code has to find the matching tree-row button in the previous layout to do so,
since the new layout isn't calculated yet.

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

M	source/blender/editors/include/UI_tree_view.hh
M	source/blender/editors/interface/interface_intern.h
M	source/blender/editors/interface/interface_view.cc
M	source/blender/editors/interface/tree_view.cc
M	source/blender/editors/space_file/asset_catalog_tree_view.cc

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

diff --git a/source/blender/editors/include/UI_tree_view.hh b/source/blender/editors/include/UI_tree_view.hh
index 8f8681896fe..7693a833210 100644
--- a/source/blender/editors/include/UI_tree_view.hh
+++ b/source/blender/editors/include/UI_tree_view.hh
@@ -185,6 +185,7 @@ class AbstractTreeView : public TreeViewItemContainer {
                                                  const TreeViewItemContainer &old_items);
   static AbstractTreeViewItem *find_matching_child(const AbstractTreeViewItem &lookup_item,
                                                    const TreeViewItemContainer &items);
+
   /**
    * Items may want to do additional work when state changes. But these state changes can only be
    * reliably detected after the tree has completed reconstruction (see #is_reconstructed()). So
@@ -290,6 +291,12 @@ class AbstractTreeViewItem : public TreeViewItemContainer {
    * can't be sure about the item state.
    */
   bool is_active() const;
+  /**
+   * Can be called from the #AbstractTreeViewItem::build_row() implementation, but not earlier. The
+   * hovered state can't be queried reliably otherwise.
+   * Note that this does a linear lookup in the old block, so isn't too great performance-wise.
+   */
+  bool is_hovered() const;
   void toggle_collapsed();
   /**
    * Requires the tree to have completed reconstruction, see #is_reconstructed(). Otherwise we
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 8e69ac40a34..5c06f8cfd13 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -1293,6 +1293,8 @@ void ui_interface_tag_script_reload_queries(void);
 void ui_block_free_views(struct uiBlock *block);
 uiTreeViewHandle *ui_block_view_find_matching_in_old_block(const uiBlock *new_block,
                                                            const uiTreeViewHandle *new_view);
+uiButTreeRow *ui_block_view_find_treerow_in_old_block(const uiBlock *new_block,
+                                                      const uiTreeViewItemHandle *new_item_handle);
 
 #ifdef __cplusplus
 }
diff --git a/source/blender/editors/interface/interface_view.cc b/source/blender/editors/interface/interface_view.cc
index b199ce9562e..8122b965892 100644
--- a/source/blender/editors/interface/interface_view.cc
+++ b/source/blender/editors/interface/interface_view.cc
@@ -106,26 +106,71 @@ static StringRef ui_block_view_find_idname(const uiBlock &block, const AbstractT
   return {};
 }
 
+static AbstractTreeView *ui_block_view_find_matching_in_old_block(const uiBlock &new_block,
+                                                                  const AbstractTreeView &new_view)
+{
+  uiBlock *old_block = new_block.oldblock;
+  if (!old_block) {
+    return nullptr;
+  }
+
+  StringRef idname = ui_block_view_find_idname(new_block, new_view);
+  if (idname.is_empty()) {
+    return nullptr;
+  }
+
+  LISTBASE_FOREACH (ViewLink *, old_view_link, &old_block->views) {
+    if (old_view_link->idname == idname) {
+      return get_view_from_link<AbstractTreeView>(*old_view_link);
+    }
+  }
+
+  return nullptr;
+}
+
 uiTreeViewHandle *ui_block_view_find_matching_in_old_block(const uiBlock *new_block,
                                                            const uiTreeViewHandle *new_view_handle)
 {
-  const AbstractTreeView &needle_view = reinterpret_cast<const AbstractTreeView &>(
-      *new_view_handle);
+  BLI_assert(new_block && new_view_handle);
+  const AbstractTreeView &new_view = reinterpret_cast<const AbstractTreeView &>(*new_view_handle);
 
+  AbstractTreeView *old_view = ui_block_view_find_matching_in_old_block(*new_block, new_view);
+  return reinterpret_cast<uiTreeViewHandle *>(old_view);
+}
+
+uiButTreeRow *ui_block_view_find_treerow_in_old_block(const uiBlock *new_block,
+                                                      const uiTreeViewItemHandle *new_item_handle)
+{
   uiBlock *old_block = new_block->oldblock;
   if (!old_block) {
     return nullptr;
   }
 
-  StringRef idname = ui_block_view_find_idname(*new_block, needle_view);
-  if (idname.is_empty()) {
+  const AbstractTreeViewItem &new_item = *reinterpret_cast<const AbstractTreeViewItem *>(
+      new_item_handle);
+  const AbstractTreeView *old_tree_view = ui_block_view_find_matching_in_old_block(
+      *new_block, new_item.get_tree_view());
+  if (!old_tree_view) {
     return nullptr;
   }
 
-  LISTBASE_FOREACH (ViewLink *, old_view_link, &old_block->views) {
-    if (old_view_link->idname == idname) {
-      return reinterpret_cast<uiTreeViewHandle *>(
-          get_view_from_link<AbstractTreeView>(*old_view_link));
+  LISTBASE_FOREACH (uiBut *, old_but, &old_block->buttons) {
+    if (old_but->type != UI_BTYPE_TREEROW) {
+      continue;
+    }
+    uiButTreeRow *old_treerow_but = (uiButTreeRow *)old_but;
+    if (!old_treerow_but->tree_item) {
+      continue;
+    }
+    AbstractTreeViewItem &old_item = *reinterpret_cast<AbstractTreeViewItem *>(
+        old_treerow_but->tree_item);
+    /* Check if the row is from the expected tree-view. */
+    if (&old_item.get_tree_view() != old_tree_view) {
+      continue;
+    }
+
+    if (UI_tree_view_item_matches(new_item_handle, old_treerow_but->tree_item)) {
+      return old_treerow_but;
     }
   }
 
diff --git a/source/blender/editors/interface/tree_view.cc b/source/blender/editors/interface/tree_view.cc
index d2971f791c2..7bcf679a5ea 100644
--- a/source/blender/editors/interface/tree_view.cc
+++ b/source/blender/editors/interface/tree_view.cc
@@ -385,6 +385,21 @@ bool AbstractTreeViewItem::is_active() const
   return is_active_;
 }
 
+bool AbstractTreeViewItem::is_hovered() const
+{
+  BLI_assert_msg(get_tree_view().is_reconstructed(),
+                 "State can't be queried until reconstruction is completed");
+  BLI_assert_msg(tree_row_but_ != nullptr,
+                 "Hovered state can't be queried before the tree row is being built");
+
+  const uiTreeViewItemHandle *this_handle = reinterpret_cast<const uiTreeViewItemHandle *>(this);
+  /* The new layout hasn't finished construction yet, so the final state of the button is unknown.
+   * Get the matching button from the previous redraw instead. */
+  uiButTreeRow *old_treerow_but = ui_block_view_find_treerow_in_old_block(tree_row_but_->but.block,
+                                                                          this_handle);
+  return old_treerow_but && (old_treerow_but->but.flag & UI_ACTIVE);
+}
+
 bool AbstractTreeViewItem::is_collapsed() const
 {
   BLI_assert_msg(get_tree_view().is_reconstructed(),
diff --git a/source/blender/editors/space_file/asset_catalog_tree_view.cc b/source/blender/editors/space_file/asset_catalog_tree_view.cc
index 552a0a7acd0..fac38e71220 100644
--- a/source/blender/editors/space_file/asset_catalog_tree_view.cc
+++ b/source/blender/editors/space_file/asset_catalog_tree_view.cc
@@ -219,7 +219,7 @@ void AssetCatalogTreeViewItem::build_row(uiLayout &row)
 {
   ui::BasicTreeViewItem::build_row(row);
 
-  if (!is_active()) {
+  if (!is_hovered()) {
     return;
   }



More information about the Bf-blender-cvs mailing list