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.
This commit is contained in:
parent
536109b4ec
commit
75fbf6f17e
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -106,26 +106,71 @@ static StringRef ui_block_view_find_idname(const uiBlock &block, const AbstractT
|
|||
return {};
|
||||
}
|
||||
|
||||
uiTreeViewHandle *ui_block_view_find_matching_in_old_block(const uiBlock *new_block,
|
||||
const uiTreeViewHandle *new_view_handle)
|
||||
static AbstractTreeView *ui_block_view_find_matching_in_old_block(const uiBlock &new_block,
|
||||
const AbstractTreeView &new_view)
|
||||
{
|
||||
const AbstractTreeView &needle_view = reinterpret_cast<const AbstractTreeView &>(
|
||||
*new_view_handle);
|
||||
|
||||
uiBlock *old_block = new_block->oldblock;
|
||||
uiBlock *old_block = new_block.oldblock;
|
||||
if (!old_block) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
StringRef idname = ui_block_view_find_idname(*new_block, needle_view);
|
||||
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 reinterpret_cast<uiTreeViewHandle *>(
|
||||
get_view_from_link<AbstractTreeView>(*old_view_link));
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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 (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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -219,7 +219,7 @@ void AssetCatalogTreeViewItem::build_row(uiLayout &row)
|
|||
{
|
||||
ui::BasicTreeViewItem::build_row(row);
|
||||
|
||||
if (!is_active()) {
|
||||
if (!is_hovered()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue