[Bf-blender-cvs] [4ee2d9df428] master: UI: Support easy dropping into/onto rows in new tree-view API
Julian Eisel
noreply at git.blender.org
Thu Sep 30 16:39:33 CEST 2021
Commit: 4ee2d9df428d16f07e351f5554b951ae75804ea0
Author: Julian Eisel
Date: Thu Sep 30 16:26:56 2021 +0200
Branches: master
https://developer.blender.org/rB4ee2d9df428d16f07e351f5554b951ae75804ea0
UI: Support easy dropping into/onto rows in new tree-view API
Adds an easy way to add drop support for tree-view rows.
Most of the work is handled by the tree-view UI code. The tree items can
simply override a few functions (`can_drop()`, `on_drop()`,
`drop_tooltip()`) to implement their custom drop behavior.
While dragging over a tree-view item that can be dropped into/onto, the
item can show a custom and dynamic tooltip explaining what's gonna
happen on drop.
This isn't used yet, but will soon be for asset catalogs.
See documentation here:
https://wiki.blender.org/wiki/Source/Interface/Views#Further_Customizations
===================================================================
M source/blender/editors/include/UI_interface.h
M source/blender/editors/include/UI_tree_view.hh
M source/blender/editors/interface/CMakeLists.txt
A source/blender/editors/interface/interface_dropboxes.cc
M source/blender/editors/interface/interface_intern.h
M source/blender/editors/interface/interface_ops.c
M source/blender/editors/interface/interface_query.c
M source/blender/editors/interface/interface_view.cc
M source/blender/editors/interface/tree_view.cc
M source/blender/editors/screen/area.c
M source/blender/editors/space_api/spacetypes.c
===================================================================
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 106f6166760..f642895f64e 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2593,6 +2593,7 @@ typedef struct uiDragColorHandle {
void ED_operatortypes_ui(void);
void ED_keymap_ui(struct wmKeyConfig *keyconf);
+void ED_dropboxes_ui(void);
void ED_uilisttypes_ui(void);
void UI_drop_color_copy(struct wmDrag *drag, struct wmDropBox *drop);
@@ -2763,6 +2764,14 @@ 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);
+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);
+
+uiTreeViewItemHandle *UI_block_tree_view_find_item_at(const struct ARegion *region, int x, int y);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/include/UI_tree_view.hh b/source/blender/editors/include/UI_tree_view.hh
index 81a614cd195..d36e688dd65 100644
--- a/source/blender/editors/include/UI_tree_view.hh
+++ b/source/blender/editors/include/UI_tree_view.hh
@@ -29,11 +29,14 @@
#include "UI_resources.h"
+struct bContext;
struct PointerRNA;
struct uiBlock;
struct uiBut;
struct uiButTreeRow;
struct uiLayout;
+struct wmEvent;
+struct wmDrag;
namespace blender::ui {
@@ -185,10 +188,19 @@ class AbstractTreeViewItem : public TreeViewItemContainer {
virtual void build_row(uiLayout &row) = 0;
virtual void on_activate();
-
- /** Copy persistent state (e.g. is-collapsed flag, selection, etc.) from a matching item of the
- * last redraw to this item. If sub-classes introduce more advanced state they should override
- * this and make it update their state accordingly. */
+ 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;
+
+ /** Copy persistent state (e.g. is-collapsed flag, selection, etc.) from a matching item of
+ * the last redraw to this item. If sub-classes introduce more advanced state they should
+ * override this and make it update their state accordingly. */
virtual void update_from_old(const AbstractTreeViewItem &old);
/** Compare this item to \a other to check if they represent the same data. This is critical for
* being able to recognize an item from a previous redraw, to be able to keep its state (e.g.
diff --git a/source/blender/editors/interface/CMakeLists.txt b/source/blender/editors/interface/CMakeLists.txt
index 79e08f46292..8fcc704a301 100644
--- a/source/blender/editors/interface/CMakeLists.txt
+++ b/source/blender/editors/interface/CMakeLists.txt
@@ -42,6 +42,7 @@ set(SRC
interface_button_group.c
interface_context_menu.c
interface_draw.c
+ interface_dropboxes.cc
interface_eyedropper.c
interface_eyedropper_color.c
interface_eyedropper_colorband.c
diff --git a/source/blender/editors/interface/interface_dropboxes.cc b/source/blender/editors/interface/interface_dropboxes.cc
new file mode 100644
index 00000000000..cb33e7f736e
--- /dev/null
+++ b/source/blender/editors/interface/interface_dropboxes.cc
@@ -0,0 +1,66 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup edinterface
+ */
+
+#include "BKE_context.h"
+
+#include "DNA_space_types.h"
+
+#include "WM_api.h"
+
+#include "UI_interface.h"
+
+static bool ui_tree_view_drop_poll(bContext *C, wmDrag *drag, const wmEvent *event)
+{
+ const ARegion *region = CTX_wm_region(C);
+ const uiTreeViewItemHandle *hovered_tree_item = UI_block_tree_view_find_item_at(
+ region, event->x, event->y);
+ if (!hovered_tree_item) {
+ return false;
+ }
+
+ return UI_tree_view_item_can_drop(hovered_tree_item, drag);
+}
+
+static char *ui_tree_view_drop_tooltip(bContext *C,
+ wmDrag *drag,
+ const wmEvent *event,
+ wmDropBox *UNUSED(drop))
+{
+ const ARegion *region = CTX_wm_region(C);
+ const uiTreeViewItemHandle *hovered_tree_item = UI_block_tree_view_find_item_at(
+ region, event->x, event->y);
+ if (!hovered_tree_item) {
+ return nullptr;
+ }
+
+ return UI_tree_view_item_drop_tooltip(hovered_tree_item, C, drag, event);
+}
+
+void ED_dropboxes_ui()
+{
+ ListBase *lb = WM_dropboxmap_find("User Interface", SPACE_EMPTY, 0);
+
+ WM_dropbox_add(lb,
+ "UI_OT_tree_view_drop",
+ ui_tree_view_drop_poll,
+ nullptr,
+ nullptr,
+ ui_tree_view_drop_tooltip);
+}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 95e6791b359..8b45d9faae6 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -1171,6 +1171,7 @@ uiBut *ui_list_row_find_mouse_over(const struct ARegion *region,
uiBut *ui_list_row_find_from_index(const struct ARegion *region,
const int index,
uiBut *listbox) ATTR_WARN_UNUSED_RESULT;
+uiBut *ui_tree_row_find_mouse_over(const struct ARegion *region, const int x, const int y);
typedef bool (*uiButFindPollFn)(const uiBut *but, const void *customdata);
uiBut *ui_but_find_mouse_over_ex(const struct ARegion *region,
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 7b59a6f7263..1fc07bce341 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1917,6 +1917,51 @@ static void UI_OT_list_start_filter(wmOperatorType *ot)
/** \} */
+/* -------------------------------------------------------------------- */
+/** \name UI Tree-View Drop Operator
+ * \{ */
+
+static bool ui_tree_view_drop_poll(bContext *C)
+{
+ const wmWindow *win = CTX_wm_window(C);
+ const ARegion *region = CTX_wm_region(C);
+ const uiTreeViewItemHandle *hovered_tree_item = UI_block_tree_view_find_item_at(
+ region, win->eventstate->x, win->eventstate->y);
+
+ return hovered_tree_item != NULL;
+}
+
+static int ui_tree_view_drop_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
+{
+ if (event->custom != EVT_DATA_DRAGDROP) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
+
+ const ARegion *region = CTX_wm_region(C);
+ uiTreeViewItemHandle *hovered_tree_item = UI_block_tree_view_find_item_at(
+ region, event->x, event->y);
+
+ if (!UI_tree_view_item_drop_handle(hovered_tree_item, event->customdata)) {
+ return OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH;
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+static void UI_OT_tree_view_drop(wmOperatorType *ot)
+{
+ ot->name = "Tree View drop";
+ ot->idname = "UI_OT_tree_view_drop";
+ ot->description = "Drag and drop items onto a tree item";
+
+ ot->invoke = ui_tree_view_drop_invoke;
+ ot->poll = ui_tree_view_drop_poll;
+
+ ot->flag = OPTYPE_INTERNAL;
+}
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Operator & Keymap Registration
* \{ */
@@ -1944,6 +1989,8 @@ void ED_operatortypes_ui(void)
WM_operatortype_append(UI_OT_list_start_filter);
+ WM_operatortype_append(UI_OT_tree_view_drop);
+
/* external */
WM_operatortype_append(UI_OT_eyedropper_color);
WM_operatortype_append(UI_OT_eyedropper_colorramp);
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index 15d1d2f2eec..2f6bda3252d 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -463,6 +463,16 @@ uiBut *ui_list_row_find_from_index(const ARegion *region, const int index, uiBut
return ui_but_find(region, ui_but_is_listrow_at_index, &data);
}
+static bool ui_but_is_treerow(const uiBut *but, const void *UNUSED(customdata))
+{
+ return but->type == UI_BTYPE_TREEROW;
+}
+
+uiBut *ui_tree_row_find_mouse_over(const ARegion *region, const int x, const int y)
+{
+ return ui_but_find_mouse_over_ex(region, x, y, false, ui_but_is_treerow, NULL);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/interface/interface_view.cc b/source/blender/editors/interface/interface_view.cc
index 7419f21cbc6..b199ce9562e 100644
--- a/source/blender/editors/interface/interface_view.cc
+++ b/source/blender/editors/interface/interface_view.cc
@@ -26,6 +26,8 @@
#incl
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list