[Bf-blender-cvs] [400d7235c3a] asset-browser-grid-view: Mouse hover highlight for grid items
Julian Eisel
noreply at git.blender.org
Wed Feb 9 18:05:24 CET 2022
Commit: 400d7235c3a50669c8d1b0ed6c22f14a3dde10ea
Author: Julian Eisel
Date: Wed Feb 9 14:41:11 2022 +0100
Branches: asset-browser-grid-view
https://developer.blender.org/rB400d7235c3a50669c8d1b0ed6c22f14a3dde10ea
Mouse hover highlight for grid items
Like the tree-view rows, grid items use an overlapping layout to draw
the background and a custom layout on top. There is a new dedicated
button type for the grid view items.
Adds some related bits needed for persistent view-item state storage.
Also a bunch of code for the grid item button type can be shared with
the tree-row one, but I prefer doing that separately.
===================================================================
M source/blender/editors/include/UI_grid_view.hh
M source/blender/editors/include/UI_interface.h
M source/blender/editors/include/UI_tree_view.hh
M source/blender/editors/interface/grid_view.cc
M source/blender/editors/interface/interface.c
M source/blender/editors/interface/interface_handlers.c
M source/blender/editors/interface/interface_intern.h
M source/blender/editors/interface/interface_query.c
M source/blender/editors/interface/interface_widgets.c
===================================================================
diff --git a/source/blender/editors/include/UI_grid_view.hh b/source/blender/editors/include/UI_grid_view.hh
index 99aff838593..4c39f2f00ba 100644
--- a/source/blender/editors/include/UI_grid_view.hh
+++ b/source/blender/editors/include/UI_grid_view.hh
@@ -27,8 +27,10 @@
#include "BLI_vector.hh"
#include "UI_resources.h"
+struct bContext;
struct PreviewImage;
struct uiBlock;
+struct uiButGridTile;
struct uiLayout;
struct wmNotifier;
@@ -41,10 +43,17 @@ class AbstractGridView;
* \{ */
class AbstractGridViewItem {
- friend AbstractGridView;
+ friend class AbstractGridView;
+ friend class GridViewLayoutBuilder;
const AbstractGridView *view_;
+ protected:
+ /** This label is used as the default way to identifying an item in the view. */
+ std::string label_{};
+ /** Every visible item gets a button of type #UI_BTYPE_GRID_TILE during the layout building. */
+ uiButGridTile *grid_tile_but_ = nullptr;
+
public:
virtual ~AbstractGridViewItem() = default;
@@ -52,8 +61,20 @@ class AbstractGridViewItem {
const AbstractGridView &get_view() const;
+ /**
+ * Compare this item to \a other to check if they represent the same data.
+ * Used to recognize an item from a previous redraw, to be able to keep its state (e.g. active,
+ * renaming, etc.). By default this just matches the item's label. If that isn't good enough for
+ * a sub-class, that can override it.
+ */
+ virtual bool matches(const AbstractGridViewItem &other) const;
+
protected:
AbstractGridViewItem() = default;
+
+ private:
+ static void grid_tile_click_fn(bContext *, void *but_arg1, void *);
+ void add_grid_tile_button(uiBlock &block);
};
/** \} */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 607df5df934..b6c274401a2 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -94,6 +94,8 @@ typedef struct uiTreeViewHandle uiTreeViewHandle;
typedef struct uiTreeViewItemHandle uiTreeViewItemHandle;
/* C handle for C++ #ui::AbstractGridView type. */
typedef struct uiGridViewHandle uiGridViewHandle;
+/* C handle for C++ #ui::AbstractGridViewItem type. */
+typedef struct uiGridViewItemHandle uiGridViewItemHandle;
/* Defines */
@@ -407,6 +409,8 @@ typedef enum {
UI_BTYPE_DECORATOR = 58 << 9,
/* An item in a tree view. Parent items may be collapsible. */
UI_BTYPE_TREEROW = 59 << 9,
+ /* An item in a grid view. */
+ UI_BTYPE_GRID_TILE = 60 << 9,
} eButType;
#define BUTTYPE (63 << 9)
@@ -3178,6 +3182,7 @@ void UI_block_views_listen(const uiBlock *block,
const struct wmRegionListenerParams *listener_params);
bool UI_tree_view_item_is_active(const uiTreeViewItemHandle *item);
+bool UI_grid_view_item_matches(const uiGridViewItemHandle *a, const uiGridViewItemHandle *b);
bool UI_tree_view_item_matches(const uiTreeViewItemHandle *a, const uiTreeViewItemHandle *b);
/**
* Attempt to start dragging the tree-item \a item_. This will not work if the tree item doesn't
diff --git a/source/blender/editors/include/UI_tree_view.hh b/source/blender/editors/include/UI_tree_view.hh
index 7002754b934..47c99d3e12b 100644
--- a/source/blender/editors/include/UI_tree_view.hh
+++ b/source/blender/editors/include/UI_tree_view.hh
@@ -203,7 +203,7 @@ class AbstractTreeViewItem : public TreeViewItemContainer {
bool is_renaming_ = false;
protected:
- /** This label is used for identifying an item within its parent. */
+ /** This label is used as the default way to identifying an item within its parent. */
std::string label_{};
/** Every visible item gets a button of type #UI_BTYPE_TREEROW during the layout building. */
uiButTreeRow *tree_row_but_ = nullptr;
diff --git a/source/blender/editors/interface/grid_view.cc b/source/blender/editors/interface/grid_view.cc
index ae7f527f817..4994aad267c 100644
--- a/source/blender/editors/interface/grid_view.cc
+++ b/source/blender/editors/interface/grid_view.cc
@@ -68,6 +68,44 @@ GridViewStyle::GridViewStyle(int width, int height) : tile_width(width), tile_he
/* ---------------------------------------------------------------------- */
+bool AbstractGridViewItem::matches(const AbstractGridViewItem &other) const
+{
+ return label_ == other.label_;
+}
+
+void AbstractGridViewItem::grid_tile_click_fn(struct bContext * /*C*/,
+ void *but_arg1,
+ void * /*arg2*/)
+{
+ uiButGridTile *grid_tile_but = (uiButGridTile *)but_arg1;
+ AbstractGridViewItem &grid_item = reinterpret_cast<AbstractGridViewItem &>(
+ *grid_tile_but->view_item);
+
+ // tree_item.activate();
+}
+
+void AbstractGridViewItem::add_grid_tile_button(uiBlock &block)
+{
+ const GridViewStyle &style = get_view().get_style();
+ grid_tile_but_ = (uiButGridTile *)uiDefBut(&block,
+ UI_BTYPE_GRID_TILE,
+ 0,
+ "",
+ 0,
+ 0,
+ style.tile_width,
+ style.tile_height,
+ nullptr,
+ 0,
+ 0,
+ 0,
+ 0,
+ "");
+
+ grid_tile_but_->view_item = reinterpret_cast<uiGridViewItemHandle *>(this);
+ UI_but_func_set(&grid_tile_but_->but, grid_tile_click_fn, grid_tile_but_, nullptr);
+}
+
const AbstractGridView &AbstractGridViewItem::get_view() const
{
if (UNLIKELY(!view_)) {
@@ -87,7 +125,9 @@ class GridViewLayoutBuilder {
public:
GridViewLayoutBuilder(uiBlock &block);
- void build_from_view(const AbstractGridView &grid_view);
+ void build_from_view(const AbstractGridView &grid_view) const;
+ void build_grid_tile(uiLayout &grid_layout, AbstractGridViewItem &item) const;
+
uiLayout *current_layout() const;
};
@@ -95,8 +135,19 @@ GridViewLayoutBuilder::GridViewLayoutBuilder(uiBlock &block) : block_(block)
{
}
-void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view)
+void GridViewLayoutBuilder::build_grid_tile(uiLayout &grid_layout,
+ AbstractGridViewItem &item) const
{
+ uiLayout *overlap = uiLayoutOverlap(&grid_layout);
+
+ item.add_grid_tile_button(block_);
+ item.build_grid_tile(*uiLayoutRow(overlap, false));
+}
+
+void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view) const
+{
+ uiLayout *prev_layout = current_layout();
+
uiLayout &layout = *uiLayoutColumn(current_layout(), false);
const GridViewStyle &style = grid_view.get_style();
@@ -108,7 +159,7 @@ void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view)
int item_count = 0;
grid_view.foreach_item([&](AbstractGridViewItem &item) {
- item.build_grid_tile(*grid_layout);
+ build_grid_tile(*grid_layout, item);
item_count++;
});
@@ -120,6 +171,8 @@ void GridViewLayoutBuilder::build_from_view(const AbstractGridView &grid_view)
uiItemS(grid_layout);
}
}
+
+ UI_block_layout_set_current(&block_, prev_layout);
}
uiLayout *GridViewLayoutBuilder::current_layout() const
@@ -183,6 +236,9 @@ void PreviewGridItem::build_grid_tile(uiLayout &layout) const
using namespace blender::ui;
/* ---------------------------------------------------------------------- */
+/* C-API */
+
+using namespace blender::ui;
bool UI_grid_view_listen_should_redraw(const uiGridViewHandle *view_handle,
const wmNotifier *notifier)
@@ -190,3 +246,11 @@ bool UI_grid_view_listen_should_redraw(const uiGridViewHandle *view_handle,
const AbstractGridView &view = *reinterpret_cast<const AbstractGridView *>(view_handle);
return view.listen(*notifier);
}
+
+bool UI_grid_view_item_matches(const uiGridViewItemHandle *a_handle,
+ const uiGridViewItemHandle *b_handle)
+{
+ const AbstractGridViewItem &a = reinterpret_cast<const AbstractGridViewItem &>(*a_handle);
+ const AbstractGridViewItem &b = reinterpret_cast<const AbstractGridViewItem &>(*b_handle);
+ return a.matches(b);
+}
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 3cbea922bed..4838bb1fa8c 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -781,6 +781,15 @@ static bool ui_but_equals_old(const uiBut *but, const uiBut *oldbut)
}
}
+ if ((but->type == UI_BTYPE_GRID_TILE) && (oldbut->type == UI_BTYPE_GRID_TILE)) {
+ uiButGridTile *but_gridtile = (uiButGridTile *)but;
+ uiButGridTile *oldbut_gridtile = (uiButGridTile *)oldbut;
+ if (!but_gridtile->view_item || !oldbut_gridtile->view_item ||
+ !UI_grid_view_item_matches(but_gridtile->view_item, oldbut_gridtile->view_item)) {
+ return false;
+ }
+ }
+
return true;
}
@@ -907,6 +916,12 @@ static void ui_but_update_old_active_from_new(uiBut *oldbut, uiBut *but)
SWAP(uiTreeViewItemHandle *, treerow_newbut->tree_item, treerow_oldbut->tree_item);
break;
}
+ case UI_BTYPE_GRID_TILE: {
+ uiButGridTile *gridtile_oldbut = (uiButGridTile *)oldbut;
+ uiButGridTile *gridtile_newbut = (uiButGridTile *)but;
+ SWAP(uiGridViewItemHandle *, gridtile_newbut->view_item, gridtile_oldbut->view_item);
+ break;
+ }
default:
break;
}
@@ -996,9 +1011,9 @@ static bool ui_but_update_from_old_block(const bContext *C,
else {
int flag_copy = UI_BUT_DRAG_MULTI;
- /* Stupid special case: The active button may be inside (as in, overlapped on top) a tree-row
+ /* Stupid special case: The active button may be inside (as in, overlapped on top) a view-item
* button which we also want to keep highlighted then. */
- if (but->type == UI_BTYPE_TREEROW
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list