Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <julian@blender.org>2021-10-06 17:29:10 +0300
committerJulian Eisel <julian@blender.org>2021-10-06 17:36:20 +0300
commit75fbf6f17e69ee9c6487173ae5957cfff5193d1f (patch)
treee27584eb4440d0280cd65a805c8a546966fb9d83
parent536109b4ec336e86de5a7e22e51804584bca74f5 (diff)
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.
-rw-r--r--source/blender/editors/include/UI_tree_view.hh7
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_view.cc61
-rw-r--r--source/blender/editors/interface/tree_view.cc15
-rw-r--r--source/blender/editors/space_file/asset_catalog_tree_view.cc2
5 files changed, 78 insertions, 9 deletions
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;
}