[Bf-blender-cvs] [83c53d1bee2] asset-browser-poselib: Support custom context menu entries for UI-lists, e.g. for pose assets
Julian Eisel
noreply at git.blender.org
Thu Apr 1 17:38:58 CEST 2021
Commit: 83c53d1bee2544f52d5b685d94fb89c73c476c19
Author: Julian Eisel
Date: Thu Apr 1 17:32:49 2021 +0200
Branches: asset-browser-poselib
https://developer.blender.org/rB83c53d1bee2544f52d5b685d94fb89c73c476c19
Support custom context menu entries for UI-lists, e.g. for pose assets
Makes it possible to add custom entries to the context menu of UI List items, by doing the following:
`bpy.types.UI_MT_list_item_context_menu.prepend(some_draw_function)`/`append(...)`.
The given draw function must check if the list is of the correct type. For that
to work I made it possible to get the hovered UI List using `context.ui_list`
and the list-ID via `ui_list.list_id`.
===================================================================
M release/scripts/addons
M release/scripts/addons_contrib
M release/scripts/startup/bl_ui/__init__.py
M source/blender/editors/include/UI_interface.h
M source/blender/editors/interface/interface_context_menu.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_template_asset_view.cc
M source/blender/editors/interface/interface_template_search_menu.c
M source/blender/editors/interface/interface_templates.c
M source/blender/editors/screen/screen_context.c
M source/blender/makesrna/intern/rna_ui.c
M source/blender/windowmanager/WM_api.h
M source/blender/windowmanager/intern/wm_uilist_type.c
===================================================================
diff --git a/release/scripts/addons b/release/scripts/addons
index 66e77b34fa1..c294704a0f9 160000
--- a/release/scripts/addons
+++ b/release/scripts/addons
@@ -1 +1 @@
-Subproject commit 66e77b34fa13dcab57ff4552c87a6450a6b73c42
+Subproject commit c294704a0f9430ccd1f4d1f16534d741b2209826
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
index f948f658ba3..5523cbaed60 160000
--- a/release/scripts/addons_contrib
+++ b/release/scripts/addons_contrib
@@ -1 +1 @@
-Subproject commit f948f658ba33eb670a65e0bba058d43138abea7e
+Subproject commit 5523cbaed60719960f5f7b2486925145ecbe81e5
diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py
index c282b3f281d..c539b9d8499 100644
--- a/release/scripts/startup/bl_ui/__init__.py
+++ b/release/scripts/startup/bl_ui/__init__.py
@@ -253,3 +253,21 @@ class UI_UL_list(bpy.types.UIList):
bpy.utils.register_class(UI_UL_list)
+
+
+class UI_MT_list_item_context_menu(bpy.types.Menu):
+ """
+ UI List item context menu definition. Scripts can append/prepend this to
+ add own operators to the context menu. They must check context though, so
+ their items only draw in a valid context and for the correct UI list.
+ """
+
+ bl_label = "List Item"
+ bl_idname = "UI_MT_list_item_context_menu"
+
+ def draw(self, context):
+ # Dummy function. This type is just for scripts to append their own
+ # context menu items.
+ pass
+
+bpy.utils.register_class(UI_MT_list_item_context_menu)
\ No newline at end of file
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index cb6b6686cef..99f53a81636 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -550,6 +550,8 @@ bool UI_block_is_empty_ex(const uiBlock *block, const bool skip_title);
bool UI_block_is_empty(const uiBlock *block);
bool UI_block_can_add_separator(const uiBlock *block);
+struct uiList *UI_list_find_mouse_over(struct ARegion *region, const struct wmEvent *event);
+
/* interface_region_menu_popup.c */
/**
* Popup Menus
diff --git a/source/blender/editors/interface/interface_context_menu.c b/source/blender/editors/interface/interface_context_menu.c
index 91c19ff2850..6b35f9cba8a 100644
--- a/source/blender/editors/interface/interface_context_menu.c
+++ b/source/blender/editors/interface/interface_context_menu.c
@@ -20,6 +20,7 @@
* Generic context popup menus.
*/
+#include <stdio.h>
#include <string.h>
#include "MEM_guardedalloc.h"
@@ -494,7 +495,7 @@ static void ui_but_menu_add_path_operators(uiLayout *layout, PointerRNA *ptr, Pr
RNA_string_set(&props_ptr, "filepath", dir);
}
-bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
+bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *event)
{
/* ui_but_is_interactive() may let some buttons through that should not get a context menu - it
* doesn't make sense for them. */
@@ -1234,6 +1235,20 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but)
}
}
+ /* UI List item context menu. Scripts can add items to it, by default there's nothing shown. */
+ ARegion *region = CTX_wm_region(C);
+ const bool is_inside_listbox = ui_list_find_mouse_over(region, event) != NULL;
+ const bool is_inside_listrow = is_inside_listbox ?
+ ui_list_row_find_mouse_over(region, event->x, event->y) !=
+ NULL :
+ false;
+ if (is_inside_listrow) {
+ MenuType *mt = WM_menutype_find("UI_MT_list_item_context_menu", true);
+ if (mt) {
+ UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
+ }
+ }
+
MenuType *mt = WM_menutype_find("WM_MT_button_context", true);
if (mt) {
UI_menutype_draw(C, mt, uiLayoutColumn(layout, false));
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index e38a7438214..cf938d3d0e1 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -7668,7 +7668,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
if ((event->type == RIGHTMOUSE) && !IS_EVENT_MOD(event, shift, ctrl, alt, oskey) &&
(event->val == KM_PRESS)) {
/* RMB has two options now */
- if (ui_popup_context_menu_for_button(C, but)) {
+ if (ui_popup_context_menu_for_button(C, but, event)) {
return WM_UI_HANDLER_BREAK;
}
}
@@ -9082,11 +9082,6 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
return retval;
}
-static bool ui_but_is_listrow(const uiBut *but)
-{
- return but->type == UI_BTYPE_LISTROW;
-}
-
/**
* Activate the underlying list-row button, so the row is highlighted.
* Early exits if \a activate_dragging is true, but the custom drag operator fails to execute.
@@ -9112,8 +9107,7 @@ static int ui_list_activate_hovered_row(bContext *C,
}
const int *mouse_xy = ISTWEAK(event->type) ? &event->prevclickx : &event->x;
- uiBut *listrow = ui_but_find_mouse_over_ex(
- region, mouse_xy[0], mouse_xy[1], false, ui_but_is_listrow);
+ uiBut *listrow = ui_list_row_find_mouse_over(region, mouse_xy[0], mouse_xy[1]);
if (listrow) {
wmOperatorType *custom_activate_optype = ui_list->dyn_data->custom_activate_optype;
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 80a8260787b..ed0631ce8c8 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -1117,6 +1117,9 @@ bool ui_but_contains_point_px(const uiBut *but, const struct ARegion *region, in
uiBut *ui_list_find_mouse_over(struct ARegion *region,
const struct wmEvent *event) ATTR_WARN_UNUSED_RESULT;
+uiBut *ui_list_row_find_mouse_over(const struct ARegion *region,
+ int x,
+ int y) ATTR_WARN_UNUSED_RESULT;
typedef bool (*uiButFindPoll)(const uiBut *but);
uiBut *ui_but_find_mouse_over_ex(const struct ARegion *region,
@@ -1168,7 +1171,7 @@ struct ARegion *ui_screen_region_find_mouse_over(struct bScreen *screen,
const struct wmEvent *event);
/* interface_context_menu.c */
-bool ui_popup_context_menu_for_button(struct bContext *C, uiBut *but);
+bool ui_popup_context_menu_for_button(struct bContext *C, uiBut *but, const struct wmEvent *event);
void ui_popup_context_menu_for_panel(struct bContext *C,
struct ARegion *region,
struct Panel *panel);
diff --git a/source/blender/editors/interface/interface_query.c b/source/blender/editors/interface/interface_query.c
index dbff486e0d1..bb3dd6218e8 100644
--- a/source/blender/editors/interface/interface_query.c
+++ b/source/blender/editors/interface/interface_query.c
@@ -265,11 +265,8 @@ bool ui_but_contains_point_px_icon(const uiBut *but, ARegion *region, const wmEv
}
/* x and y are only used in case event is NULL... */
-uiBut *ui_but_find_mouse_over_ex(const ARegion *region,
- const int x,
- const int y,
- const bool labeledit,
- uiButFindPoll find_poll)
+uiBut *ui_but_find_mouse_over_ex(
+ const ARegion *region, const int x, const int y, const bool labeledit, uiButFindPoll find_poll)
{
uiBut *butover = NULL;
@@ -376,6 +373,26 @@ uiBut *ui_list_find_mouse_over(ARegion *region, const wmEvent *event)
return ui_list_find_mouse_over_ex(region, event->x, event->y);
}
+uiList *UI_list_find_mouse_over(ARegion *region, const wmEvent *event)
+{
+ uiBut *list_but = ui_list_find_mouse_over(region, event);
+ if (!list_but) {
+ return NULL;
+ }
+
+ return list_but->custom_data;
+}
+
+static bool ui_but_is_listrow(const uiBut *but)
+{
+ return but->type == UI_BTYPE_LISTROW;
+}
+
+uiBut *ui_list_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_listrow);
+}
+
/** \} */
/* -------------------------------------------------------------------- */
diff --git a/source/blender/editors/interface/interface_template_asset_view.cc b/source/blender/editors/interface/interface_template_asset_view.cc
index 66947928711..8eff15fe765 100644
--- a/source/blender/editors/interface/interface_template_asset_view.cc
+++ b/source/blender/editors/interface/interface_template_asset_view.cc
@@ -140,6 +140,7 @@ static uiListType *UI_UL_asset_view()
return list_type;
}
+/* TODO move to a proper place. */
void ED_uilisttypes_ui()
{
WM_uilisttype_add(UI_UL_asset_view());
diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index ff42d434f29..8e3b1a307c1 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -1030,7 +1030,7 @@ static void menu_search_update_fn(const bContext *UNUSED(C),
static bool ui_search_menu_create_context_menu(struct bContext *C,
void *arg,
void *active,
- const struct wmEvent *UNUSED(event))
+ const struct wmEvent *event)
{
struct MenuSearch_Data *data = arg;
struct MenuSearch_Item *item = active;
@@ -1051,7 +1051,7 @@ static bool ui_search_menu_create_context_menu(struct bContext *C,
CTX_wm_region_set(C, item->wm_context->region);
}
- if (ui_popup_context_menu_for_button(C, but)) {
+ if (ui_popup_context_menu_for_button(C, but, event)) {
has_menu = true;
}
diff --git a/source/blender/editors/interface/interface_templates.c b/sou
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list