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:
authorCampbell Barton <ideasman42@gmail.com>2020-05-07 16:16:22 +0300
committerCampbell Barton <ideasman42@gmail.com>2020-05-07 16:38:44 +0300
commit82704ac3edf0e37d9eea2860bc565bcf521ae593 (patch)
treef5a1f73cca5b0399f92247fac030163213cbd79a /source/blender/editors/interface/interface_template_search_menu.c
parentdaf10d17f46c933341be12bc9a9baf359d3280f7 (diff)
UI: support context menu in menu search popup
Diffstat (limited to 'source/blender/editors/interface/interface_template_search_menu.c')
-rw-r--r--source/blender/editors/interface/interface_template_search_menu.c104
1 files changed, 103 insertions, 1 deletions
diff --git a/source/blender/editors/interface/interface_template_search_menu.c b/source/blender/editors/interface/interface_template_search_menu.c
index 1e8d32abf67..8bd61ccd038 100644
--- a/source/blender/editors/interface/interface_template_search_menu.c
+++ b/source/blender/editors/interface/interface_template_search_menu.c
@@ -137,6 +137,12 @@ struct MenuSearch_Data {
ListBase items;
/** Use for all small allocations. */
MemArena *memarena;
+
+ /** Use for context menu, to fake a button to create a context menu. */
+ struct {
+ uiBut but;
+ uiBlock block;
+ } context_menu_data;
};
static int menu_item_sort_by_drawstr_full(const void *menu_item_a_v, const void *menu_item_b_v)
@@ -208,7 +214,8 @@ static bool menu_items_from_ui_create_item_from_button(struct MenuSearch_Data *d
/* Handle shared settings. */
item->drawstr = strdup_memarena(memarena, but->drawstr);
item->icon = ui_but_icon(but);
- item->state = (but->flag & (UI_BUT_DISABLED | UI_BUT_INACTIVE | UI_BUT_REDALERT));
+ item->state = (but->flag &
+ (UI_BUT_DISABLED | UI_BUT_INACTIVE | UI_BUT_REDALERT | UI_BUT_HAS_SEP_CHAR));
item->mt = mt;
item->drawstr_submenu = drawstr_submenu ? strdup_memarena(memarena, drawstr_submenu) : NULL;
@@ -222,6 +229,51 @@ static bool menu_items_from_ui_create_item_from_button(struct MenuSearch_Data *d
}
/**
+ * Populate a fake button from a menu item (use for context menu).
+ */
+static bool menu_items_to_ui_button(struct MenuSearch_Item *item, uiBut *but)
+{
+ bool changed = false;
+ switch (item->type) {
+ case MENU_SEARCH_TYPE_OP: {
+ but->optype = item->op.type;
+ but->opcontext = item->op.opcontext;
+ but->context = item->op.context;
+ but->opptr = item->op.opptr;
+ changed = true;
+ break;
+ }
+ case MENU_SEARCH_TYPE_RNA: {
+ const int prop_type = RNA_property_type(item->rna.prop);
+
+ but->rnapoin = item->rna.ptr;
+ but->rnaprop = item->rna.prop;
+ but->rnaindex = item->rna.index;
+
+ if (prop_type == PROP_ENUM) {
+ but->hardmax = item->rna.enum_value;
+ }
+ changed = true;
+ break;
+ }
+ }
+
+ if (changed) {
+ STRNCPY(but->drawstr, item->drawstr);
+ char *drawstr_sep = (item->state & UI_BUT_HAS_SEP_CHAR) ? strrchr(but->drawstr, UI_SEP_CHAR) :
+ NULL;
+ if (drawstr_sep) {
+ *drawstr_sep = '\0';
+ }
+
+ but->icon = item->icon;
+ but->str = but->strdata;
+ }
+
+ return changed;
+}
+
+/**
* Populate \a menu_stack with menus from inspecting active key-maps for this context.
*/
static void menu_types_add_from_keymap_items(bContext *C,
@@ -318,6 +370,7 @@ static void menu_items_from_all_operators(bContext *C, struct MenuSearch_Data *d
SNPRINTF(uiname, "%s " MENU_SEP "%s", idname_as_py, ot_ui_name);
item->drawwstr_full = strdup_memarena(memarena, uiname);
+ item->drawstr = ot_ui_name;
item->wm_context = NULL;
@@ -896,6 +949,53 @@ static void menu_search_cb(const bContext *UNUSED(C),
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Context Menu
+ *
+ * This uses a fake button to create a context menu,
+ * if this ever causes hard to solve bugs we may need to create
+ * a separate context menu just for the search, however this is fairly involved.
+ * \{ */
+
+static bool menu_search_context_menu_fn(struct bContext *C,
+ void *arg,
+ void *active,
+ const struct wmEvent *UNUSED(event))
+{
+ struct MenuSearch_Data *data = arg;
+ struct MenuSearch_Item *item = active;
+ bool has_menu = false;
+
+ memset(&data->context_menu_data, 0x0, sizeof(data->context_menu_data));
+ uiBut *but = &data->context_menu_data.but;
+ uiBlock *block = &data->context_menu_data.block;
+
+ but->block = block;
+
+ if (menu_items_to_ui_button(item, but)) {
+ ScrArea *area_prev = CTX_wm_area(C);
+ ARegion *region_prev = CTX_wm_region(C);
+
+ if (item->wm_context != NULL) {
+ CTX_wm_area_set(C, item->wm_context->area);
+ CTX_wm_region_set(C, item->wm_context->region);
+ }
+
+ if (ui_popup_context_menu_for_button(C, but)) {
+ has_menu = true;
+ }
+
+ if (item->wm_context != NULL) {
+ CTX_wm_area_set(C, area_prev);
+ CTX_wm_region_set(C, region_prev);
+ }
+ }
+
+ return has_menu;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Menu Search Template Public API
* \{ */
@@ -916,6 +1016,8 @@ void UI_but_func_menu_search(uiBut *but)
menu_items_from_ui_destroy,
menu_call_fn,
NULL);
+
+ UI_but_func_search_set_context_menu(but, menu_search_context_menu_fn);
UI_but_func_search_set_sep_string(but, MENU_SEP);
}