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:
-rw-r--r--source/blender/editors/include/UI_interface.h1
-rw-r--r--source/blender/editors/include/UI_tree_view.hh18
-rw-r--r--source/blender/editors/interface/interface_handlers.c38
-rw-r--r--source/blender/editors/interface/tree_view.cc31
4 files changed, 79 insertions, 9 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 12fdda2092c..0f290d4255b 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2777,6 +2777,7 @@ 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_drag_start(struct bContext *C, uiTreeViewItemHandle *item_);
bool UI_tree_view_item_can_drop(const uiTreeViewItemHandle *item_,
const struct wmDrag *drag,
const char **r_disabled_hint);
diff --git a/source/blender/editors/include/UI_tree_view.hh b/source/blender/editors/include/UI_tree_view.hh
index 905181a7251..0990d844d48 100644
--- a/source/blender/editors/include/UI_tree_view.hh
+++ b/source/blender/editors/include/UI_tree_view.hh
@@ -49,6 +49,7 @@ namespace blender::ui {
class AbstractTreeView;
class AbstractTreeViewItem;
class AbstractTreeViewItemDropController;
+class AbstractTreeViewItemDragController;
/* ---------------------------------------------------------------------- */
/** \name Tree-View Item Container
@@ -274,6 +275,11 @@ class AbstractTreeViewItem : public TreeViewItemContainer {
virtual bool matches(const AbstractTreeViewItem &other) const;
/**
+ * If an item wants to support being dragged, it has to return a drag controller here.
+ * That is an object implementing #AbstractTreeViewItemDragController.
+ */
+ virtual std::unique_ptr<AbstractTreeViewItemDragController> create_drag_controller() 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.
*
@@ -348,6 +354,18 @@ class AbstractTreeViewItem : public TreeViewItemContainer {
* \{ */
/**
+ * Class to enable dragging a tree-item. An item can return a drop controller for itself via a
+ * custom implementation of #AbstractTreeViewItem::create_drag_controller().
+ */
+class AbstractTreeViewItemDragController {
+ public:
+ virtual ~AbstractTreeViewItemDragController() = default;
+
+ virtual int get_drag_type() const = 0;
+ virtual void *create_drag_data() const = 0;
+};
+
+/**
* 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().
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index b21d2127030..6dd6f9eb359 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2145,6 +2145,12 @@ static bool ui_but_drag_init(bContext *C,
return false;
}
}
+ else if (but->type == UI_BTYPE_TREEROW) {
+ uiButTreeRow *tree_row_but = (uiButTreeRow *)but;
+ if (tree_row_but->tree_item) {
+ UI_tree_view_item_drag_start(C, tree_row_but->tree_item);
+ }
+ }
else {
wmDrag *drag = WM_event_start_drag(
C,
@@ -4821,19 +4827,33 @@ static int ui_do_but_TREEROW(bContext *C,
if (data->state == BUTTON_STATE_HIGHLIGHT) {
if (event->type == LEFTMOUSE) {
- if (event->val == KM_CLICK) {
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- return WM_UI_HANDLER_BREAK;
- }
- if (event->val == KM_DBL_CLICK) {
- data->cancel = true;
+ switch (event->val) {
+ case KM_PRESS:
+ /* Extra icons have priority, don't mess with them. */
+ if (ui_but_extra_operator_icon_mouse_over_get(but, data, event)) {
+ return WM_UI_HANDLER_BREAK;
+ }
+ button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
+ data->dragstartx = event->xy[0];
+ data->dragstarty = event->xy[1];
+ return WM_UI_HANDLER_CONTINUE;
- UI_tree_view_item_begin_rename(tree_row_but->tree_item);
- ED_region_tag_redraw(CTX_wm_region(C));
- return WM_UI_HANDLER_BREAK;
+ case KM_CLICK:
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+ return WM_UI_HANDLER_BREAK;
+
+ case KM_DBL_CLICK:
+ data->cancel = true;
+ UI_tree_view_item_begin_rename(tree_row_but->tree_item);
+ ED_region_tag_redraw(CTX_wm_region(C));
+ return WM_UI_HANDLER_BREAK;
}
}
}
+ else if (data->state == BUTTON_STATE_WAIT_DRAG) {
+ /* Let "default" button handling take care of the drag logic. */
+ return ui_do_but_EXIT(C, but, data, event);
+ }
return WM_UI_HANDLER_CONTINUE;
}
diff --git a/source/blender/editors/interface/tree_view.cc b/source/blender/editors/interface/tree_view.cc
index 04d7a066b36..c08fa51d5a5 100644
--- a/source/blender/editors/interface/tree_view.cc
+++ b/source/blender/editors/interface/tree_view.cc
@@ -29,6 +29,7 @@
#include "UI_interface.h"
+#include "WM_api.h"
#include "WM_types.h"
#include "UI_tree_view.hh"
@@ -354,6 +355,13 @@ void AbstractTreeViewItem::is_active(IsActiveFn is_active_fn)
is_active_fn_ = is_active_fn;
}
+std::unique_ptr<AbstractTreeViewItemDragController> AbstractTreeViewItem::create_drag_controller()
+ const
+{
+ /* There's no drag controller (and hence no drag support) by default. */
+ return nullptr;
+}
+
std::unique_ptr<AbstractTreeViewItemDropController> AbstractTreeViewItem::create_drop_controller()
const
{
@@ -686,6 +694,29 @@ bool UI_tree_view_item_matches(const uiTreeViewItemHandle *a_handle,
return a.matches_including_parents(b);
}
+/**
+ * Attempt to start dragging the tree-item \a item_. This will not work if the tree item doesn't
+ * support dragging, i.e. it won't create a drag-controller upon request.
+ * \return True if dragging started successfully, otherwise false.
+ */
+bool UI_tree_view_item_drag_start(bContext *C, uiTreeViewItemHandle *item_)
+{
+ const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_);
+ const std::unique_ptr<AbstractTreeViewItemDragController> drag_controller =
+ item.create_drag_controller();
+ if (!drag_controller) {
+ return false;
+ }
+
+ WM_event_start_drag(C,
+ ICON_NONE,
+ drag_controller->get_drag_type(),
+ drag_controller->create_drag_data(),
+ 0,
+ WM_DRAG_FREE_DATA);
+ return true;
+}
+
bool UI_tree_view_item_can_drop(const uiTreeViewItemHandle *item_,
const wmDrag *drag,
const char **r_disabled_hint)