[Bf-blender-cvs] [d16e7326386] master: UI: Refactor dropping support for the tree-view API
Julian Eisel
noreply at git.blender.org
Mon Oct 25 10:47:01 CEST 2021
Commit: d16e7326386d055fc5cdfa9f60bcd3d75bcbbed5
Author: Julian Eisel
Date: Sun Oct 24 18:51:12 2021 +0200
Branches: master
https://developer.blender.org/rBd16e7326386d055fc5cdfa9f60bcd3d75bcbbed5
UI: Refactor dropping support for the tree-view API
Introduces a dropping-controller API for the tree-view items,
`AbstractTreeViewItemDropController`. This reduces responsibilities of the main
tree-view item classes, which are already getting quite big. As I expect even
more functionality to be needed for it (e.g. drag support), it's better to
start introducing such controller types already.
===================================================================
M source/blender/editors/include/UI_interface.h
M source/blender/editors/include/UI_tree_view.hh
M source/blender/editors/interface/interface_dropboxes.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_interface.h b/source/blender/editors/include/UI_interface.h
index 67d034f4ab6..de6b975a910 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2781,11 +2781,8 @@ void UI_interface_tag_script_reload(void);
bool UI_tree_view_item_is_active(const uiTreeViewItemHandle *item);
bool UI_tree_view_item_matches(const uiTreeViewItemHandle *a, const uiTreeViewItemHandle *b);
bool UI_tree_view_item_can_drop(const uiTreeViewItemHandle *item_, const struct wmDrag *drag);
+char *UI_tree_view_item_drop_tooltip(const uiTreeViewItemHandle *item, const struct wmDrag *drag);
bool UI_tree_view_item_drop_handle(uiTreeViewItemHandle *item_, const struct ListBase *drags);
-char *UI_tree_view_item_drop_tooltip(const uiTreeViewItemHandle *item,
- const struct bContext *C,
- const struct wmDrag *drag,
- const struct wmEvent *event);
bool UI_tree_view_item_can_rename(const uiTreeViewItemHandle *item_handle);
void UI_tree_view_item_begin_rename(uiTreeViewItemHandle *item_handle);
diff --git a/source/blender/editors/include/UI_tree_view.hh b/source/blender/editors/include/UI_tree_view.hh
index b1ec22c57a6..f565c80193f 100644
--- a/source/blender/editors/include/UI_tree_view.hh
+++ b/source/blender/editors/include/UI_tree_view.hh
@@ -48,6 +48,7 @@ namespace blender::ui {
class AbstractTreeView;
class AbstractTreeViewItem;
+class AbstractTreeViewItemDropController;
/* ---------------------------------------------------------------------- */
/** \name Tree-View Item Container
@@ -242,17 +243,7 @@ class AbstractTreeViewItem : public TreeViewItemContainer {
* arguments for checking if the item is currently in an active state.
*/
virtual void is_active(IsActiveFn is_active_fn);
- virtual bool on_drop(const wmDrag &drag);
- virtual bool can_drop(const wmDrag &drag) const;
- /**
- * Custom text to display when dragging over a tree item. Should explain what happens when
- * dropping the data onto this item. Will only be used if #AbstractTreeViewItem::can_drop()
- * returns true, so the implementing override doesn't have to check that again.
- * The returned value must be a translated string.
- */
- virtual std::string drop_tooltip(const bContext &C,
- const wmDrag &drag,
- const wmEvent &event) const;
+
/**
* Queries if the tree-view item supports renaming in principle. Renaming may still fail, e.g. if
* another item is already being renamed.
@@ -282,6 +273,15 @@ class AbstractTreeViewItem : public TreeViewItemContainer {
*/
virtual bool matches(const AbstractTreeViewItem &other) const;
+ /**
+ * If an item wants to support dropping data into it, it has to return a drop controller here.
+ * That is an object implementing #AbstractTreeViewItemDropController.
+ *
+ * \note This drop controller may be requested for each event. The tree-view doesn't keep a drop
+ * controller around currently. So it can not contain persistent state.
+ */
+ virtual std::unique_ptr<AbstractTreeViewItemDropController> create_drop_controller() const;
+
void begin_renaming();
void end_renaming();
@@ -343,6 +343,45 @@ class AbstractTreeViewItem : public TreeViewItemContainer {
/** \} */
+/* ---------------------------------------------------------------------- */
+/** \name Drag 'n Drop
+ * \{ */
+
+/**
+ * Class to customize the drop behavior of a tree-item, plus the behavior when dragging over this
+ * item. An item can return a drop controller for itself via a custom implementation of
+ * #AbstractTreeViewItem::create_drop_controller().
+ */
+class AbstractTreeViewItemDropController {
+ protected:
+ AbstractTreeView &tree_view_;
+
+ public:
+ AbstractTreeViewItemDropController(AbstractTreeView &tree_view);
+ virtual ~AbstractTreeViewItemDropController() = default;
+
+ /**
+ * Check if the data dragged with \a drag can be dropped on the item this controller is for.
+ */
+ virtual bool can_drop(const wmDrag &drag) const = 0;
+ /**
+ * Custom text to display when dragging over a tree item. Should explain what happens when
+ * dropping the data onto this item. Will only be used if #AbstractTreeViewItem::can_drop()
+ * returns true, so the implementing override doesn't have to check that again.
+ * The returned value must be a translated string.
+ */
+ virtual std::string drop_tooltip(const wmDrag &drag) const = 0;
+ /**
+ * Execute the logic to apply a drop of the data dragged with \a drag onto/into the item this
+ * controller is for.
+ */
+ virtual bool on_drop(const wmDrag &drag) = 0;
+
+ template<class TreeViewType> inline TreeViewType &tree_view() const;
+};
+
+/** \} */
+
/* ---------------------------------------------------------------------- */
/** \name Predefined Tree-View Item Types
*
@@ -390,4 +429,9 @@ inline ItemT &TreeViewItemContainer::add_tree_item(Args &&...args)
add_tree_item(std::make_unique<ItemT>(std::forward<Args>(args)...)));
}
+template<class TreeViewType> TreeViewType &AbstractTreeViewItemDropController::tree_view() const
+{
+ return static_cast<TreeViewType &>(tree_view_);
+}
+
} // namespace blender::ui
diff --git a/source/blender/editors/interface/interface_dropboxes.cc b/source/blender/editors/interface/interface_dropboxes.cc
index 62250a34cf4..ae626080a9a 100644
--- a/source/blender/editors/interface/interface_dropboxes.cc
+++ b/source/blender/editors/interface/interface_dropboxes.cc
@@ -50,7 +50,7 @@ static char *ui_tree_view_drop_tooltip(bContext *C,
return nullptr;
}
- return UI_tree_view_item_drop_tooltip(hovered_tree_item, C, drag, event);
+ return UI_tree_view_item_drop_tooltip(hovered_tree_item, drag);
}
void ED_dropboxes_ui()
diff --git a/source/blender/editors/interface/tree_view.cc b/source/blender/editors/interface/tree_view.cc
index 88aa362deb5..946699d5115 100644
--- a/source/blender/editors/interface/tree_view.cc
+++ b/source/blender/editors/interface/tree_view.cc
@@ -354,22 +354,11 @@ void AbstractTreeViewItem::is_active(IsActiveFn is_active_fn)
is_active_fn_ = is_active_fn;
}
-bool AbstractTreeViewItem::on_drop(const wmDrag & /*drag*/)
+std::unique_ptr<AbstractTreeViewItemDropController> AbstractTreeViewItem::create_drop_controller()
+ const
{
- /* Do nothing by default. */
- return false;
-}
-
-bool AbstractTreeViewItem::can_drop(const wmDrag & /*drag*/) const
-{
- return false;
-}
-
-std::string AbstractTreeViewItem::drop_tooltip(const bContext & /*C*/,
- const wmDrag & /*drag*/,
- const wmEvent & /*event*/) const
-{
- return TIP_("Drop into/onto tree item");
+ /* There's no drop controller (and hence no drop support) by default. */
+ return nullptr;
}
bool AbstractTreeViewItem::can_rename() const
@@ -553,6 +542,12 @@ void AbstractTreeViewItem::change_state_delayed()
activate();
}
}
+/* ---------------------------------------------------------------------- */
+
+AbstractTreeViewItemDropController::AbstractTreeViewItemDropController(AbstractTreeView &tree_view)
+ : tree_view_(tree_view)
+{
+}
/* ---------------------------------------------------------------------- */
@@ -683,16 +678,25 @@ bool UI_tree_view_item_matches(const uiTreeViewItemHandle *a_handle,
bool UI_tree_view_item_can_drop(const uiTreeViewItemHandle *item_, const wmDrag *drag)
{
const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_);
- return item.can_drop(*drag);
+ const std::unique_ptr<AbstractTreeViewItemDropController> drop_controller =
+ item.create_drop_controller();
+ if (!drop_controller) {
+ return false;
+ }
+
+ return drop_controller->can_drop(*drag);
}
-char *UI_tree_view_item_drop_tooltip(const uiTreeViewItemHandle *item_,
- const bContext *C,
- const wmDrag *drag,
- const wmEvent *event)
+char *UI_tree_view_item_drop_tooltip(const uiTreeViewItemHandle *item_, const wmDrag *drag)
{
const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_);
- return BLI_strdup(item.drop_tooltip(*C, *drag, *event).c_str());
+ const std::unique_ptr<AbstractTreeViewItemDropController> drop_controller =
+ item.create_drop_controller();
+ if (!drop_controller) {
+ return NULL;
+ }
+
+ return BLI_strdup(drop_controller->drop_tooltip(*drag).c_str());
}
/**
@@ -702,10 +706,12 @@ char *UI_tree_view_item_drop_tooltip(const uiTreeViewItemHandle *item_,
bool UI_tree_view_item_drop_handle(uiTreeViewItemHandle *item_, const ListBase *drags)
{
AbstractTreeViewItem &item = reinterpret_cast<AbstractTreeViewItem &>(*item_);
+ std::unique_ptr<AbstractTreeViewItemDropController> drop_controller =
+ item.create_drop_controller();
LISTBASE_FOREACH (const wmDrag *, drag, drags) {
- if (item.can_drop(*drag)) {
- return item.on_drop(*drag);
+ if (drop_controller->can_drop(*drag)) {
+ return drop_controller->on_drop(*drag);
}
}
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 c305a11daf4..68df4cc0544 100644
--- a/source/blender/editors/space_file/asset_catalog_tree_view.cc
+++ b/source/blender/editors/space_file/asset_catalog_tree_view.cc
@@ -60,6 +60,7 @@ class AssetCatalogTreeView : public ui::AbstractTreeView {
SpaceFile &space_file_;
friend class AssetCatalogTreeViewItem;
+ friend class AssetCatalogDropController;
public:
AssetCatalogTreeView(::AssetLibrary *library,
@@ -86,25 +87,34 @@ class AssetCatalogTreeViewItem : public ui::BasicTreeViewItem {
public:
AssetCatalogTreeViewItem(AssetCatalogTreeItem *catalog_item);
- static bool has_droppable_item(const wmDrag &drag);
- static bool drop_into_catalog(const AssetCatalogTreeView &tree_view,
- const wmDrag &drag
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list