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.h5
-rw-r--r--source/blender/editors/include/UI_tree_view.hh1
-rw-r--r--source/blender/editors/interface/interface_context_menu.c12
-rw-r--r--source/blender/editors/interface/interface_handlers.c8
-rw-r--r--source/blender/editors/interface/interface_intern.h1
-rw-r--r--source/blender/editors/interface/interface_ops.c44
-rw-r--r--source/blender/editors/interface/interface_query.c15
-rw-r--r--source/blender/editors/interface/interface_view.cc10
-rw-r--r--source/blender/editors/interface/tree_view.cc13
9 files changed, 109 insertions, 0 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index c536eff771d..ddd5e77cbb6 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -2783,7 +2783,12 @@ char *UI_tree_view_item_drop_tooltip(const uiTreeViewItemHandle *item,
bool UI_tree_view_item_can_rename(const uiTreeViewItemHandle *item_handle);
void UI_tree_view_item_begin_rename(uiTreeViewItemHandle *item_handle);
+void UI_tree_view_item_context_menu_build(struct bContext *C,
+ const uiTreeViewItemHandle *item,
+ uiLayout *column);
+
uiTreeViewItemHandle *UI_block_tree_view_find_item_at(const struct ARegion *region, int x, int y);
+uiTreeViewItemHandle *UI_block_tree_view_find_active_item(const struct ARegion *region);
#ifdef __cplusplus
}
diff --git a/source/blender/editors/include/UI_tree_view.hh b/source/blender/editors/include/UI_tree_view.hh
index 272439a2ae9..ae85375ed2f 100644
--- a/source/blender/editors/include/UI_tree_view.hh
+++ b/source/blender/editors/include/UI_tree_view.hh
@@ -234,6 +234,7 @@ class AbstractTreeViewItem : public TreeViewItemContainer {
virtual ~AbstractTreeViewItem() = default;
virtual void build_row(uiLayout &row) = 0;
+ virtual void build_context_menu(bContext &C, uiLayout &column) const;
virtual void on_activate();
/**
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index bb9e813ea50..d327124484b 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -925,6 +925,18 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
}
}
+ {
+ const ARegion *region = CTX_wm_region(C);
+ uiButTreeRow *treerow_but = (uiButTreeRow *)ui_tree_row_find_mouse_over(
+ region, event->x, event->y);
+ if (treerow_but) {
+ BLI_assert(treerow_but->but.type == UI_BTYPE_TREEROW);
+ UI_tree_view_item_context_menu_build(
+ C, treerow_but->tree_item, uiLayoutColumn(layout, false));
+ uiItemS(layout);
+ }
+ }
+
/* If the button represents an id, it can set the "id" context pointer. */
if (U.experimental.use_extended_asset_browser && ED_asset_can_mark_single_from_context(C)) {
ID *id = CTX_data_pointer_get_type(C, "id", &RNA_ID).data;
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index bf9b37c00fa..e1f8d18ce35 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -7961,6 +7961,14 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
/* handle menu */
if ((event->type == RIGHTMOUSE) && !IS_EVENT_MOD(event, shift, ctrl, alt, oskey) &&
(event->val == KM_PRESS)) {
+ /* For some button types that are typically representing entire sets of data, right-clicking
+ * to spawn the context menu should also activate the item. This makes it clear which item
+ * will be operated on.
+ * Apply the button immediately, so context menu polls get the right active item. */
+ if (ELEM(but->type, UI_BTYPE_TREEROW)) {
+ ui_apply_but(C, but->block, but, but->active, true);
+ }
+
/* RMB has two options now */
if (ui_popup_context_menu_for_button(C, but, event)) {
return WM_UI_HANDLER_BREAK;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index e7a728efce1..c7781d65058 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -1177,6 +1177,7 @@ 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);
+uiBut *ui_tree_row_find_active(const struct ARegion *region);
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 1fc07bce341..423950d4dbd 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1963,6 +1963,49 @@ static void UI_OT_tree_view_drop(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name UI Tree-View Item Rename Operator
+ *
+ * General purpose renaming operator for tree-views. Thanks to this, to add a rename button to
+ * context menus for example, tree-view API users don't have to implement own renaming operators
+ * with the same logic as they already have for their #ui::AbstractTreeViewItem::rename() override.
+ *
+ * \{ */
+
+static bool ui_tree_view_item_rename_poll(bContext *C)
+{
+ const ARegion *region = CTX_wm_region(C);
+ const uiTreeViewItemHandle *active_item = UI_block_tree_view_find_active_item(region);
+ return active_item != NULL && UI_tree_view_item_can_rename(active_item);
+}
+
+static int ui_tree_view_item_rename_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ ARegion *region = CTX_wm_region(C);
+ uiTreeViewItemHandle *active_item = UI_block_tree_view_find_active_item(region);
+
+ UI_tree_view_item_begin_rename(active_item);
+ ED_region_tag_redraw(region);
+
+ return OPERATOR_FINISHED;
+}
+
+static void UI_OT_tree_view_item_rename(wmOperatorType *ot)
+{
+ ot->name = "Rename Tree-View Item";
+ ot->idname = "UI_OT_tree_view_item_rename";
+ ot->description = "Rename the active item in the tree";
+
+ ot->exec = ui_tree_view_item_rename_exec;
+ ot->poll = ui_tree_view_item_rename_poll;
+ /* Could get a custom tooltip via the `get_description()` callback and another overridable
+ * function of the tree-view. */
+
+ ot->flag = OPTYPE_INTERNAL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Operator & Keymap Registration
* \{ */
@@ -1990,6 +2033,7 @@ void ED_operatortypes_ui(void)
WM_operatortype_append(UI_OT_list_start_filter);
WM_operatortype_append(UI_OT_tree_view_drop);
+ WM_operatortype_append(UI_OT_tree_view_item_rename);
/* external */
WM_operatortype_append(UI_OT_eyedropper_color);
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index 2f6bda3252d..8674f1e435a 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -473,6 +473,21 @@ uiBut *ui_tree_row_find_mouse_over(const ARegion *region, const int x, const int
return ui_but_find_mouse_over_ex(region, x, y, false, ui_but_is_treerow, NULL);
}
+static bool ui_but_is_active_treerow(const uiBut *but, const void *customdata)
+{
+ if (!ui_but_is_treerow(but, customdata)) {
+ return false;
+ }
+
+ const uiButTreeRow *treerow_but = (const uiButTreeRow *)but;
+ return UI_tree_view_item_is_active(treerow_but->tree_item);
+}
+
+uiBut *ui_tree_row_find_active(const ARegion *region)
+{
+ return ui_but_find(region, ui_but_is_active_treerow, NULL);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/interface/interface_view.cc b/source/blender/editors/interface/interface_view.cc
index 8122b965892..fdd8eb0cc71 100644
--- a/source/blender/editors/interface/interface_view.cc
+++ b/source/blender/editors/interface/interface_view.cc
@@ -94,6 +94,16 @@ uiTreeViewItemHandle *UI_block_tree_view_find_item_at(const ARegion *region,
return tree_row_but->tree_item;
}
+uiTreeViewItemHandle *UI_block_tree_view_find_active_item(const ARegion *region)
+{
+ uiButTreeRow *tree_row_but = (uiButTreeRow *)ui_tree_row_find_active(region);
+ if (!tree_row_but) {
+ return nullptr;
+ }
+
+ return tree_row_but->tree_item;
+}
+
static StringRef ui_block_view_find_idname(const uiBlock &block, const AbstractTreeView &view)
{
/* First get the idname the of the view we're looking for. */
diff --git a/source/blender/editors/interface/tree_view.cc b/source/blender/editors/interface/tree_view.cc
index 3f66810b7f6..3f3a8c5bce5 100644
--- a/source/blender/editors/interface/tree_view.cc
+++ b/source/blender/editors/interface/tree_view.cc
@@ -369,6 +369,11 @@ bool AbstractTreeViewItem::rename(StringRefNull new_name)
return true;
}
+void AbstractTreeViewItem::build_context_menu(bContext & /*C*/, uiLayout & /*column*/) const
+{
+ /* No context menu by default. */
+}
+
void AbstractTreeViewItem::update_from_old(const AbstractTreeViewItem &old)
{
is_open_ = old.is_open_;
@@ -707,3 +712,11 @@ void UI_tree_view_item_begin_rename(uiTreeViewItemHandle *item_handle)
AbstractTreeViewItem &item = reinterpret_cast<AbstractTreeViewItem &>(*item_handle);
item.begin_renaming();
}
+
+void UI_tree_view_item_context_menu_build(bContext *C,
+ const uiTreeViewItemHandle *item_handle,
+ uiLayout *column)
+{
+ const AbstractTreeViewItem &item = reinterpret_cast<const AbstractTreeViewItem &>(*item_handle);
+ item.build_context_menu(*C, *column);
+}