UI: support searching in menus #110855
|
@ -2409,7 +2409,7 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C);
|
|||
void UI_but_func_operator_search(uiBut *but);
|
||||
void uiTemplateOperatorSearch(uiLayout *layout);
|
||||
|
||||
void UI_but_func_menu_search(uiBut *but);
|
||||
void UI_but_func_menu_search(uiBut *but, const char *single_menu_idname);
|
||||
void uiTemplateMenuSearch(uiLayout *layout);
|
||||
|
||||
/**
|
||||
JacquesLucke marked this conversation as resolved
Outdated
|
||||
|
|
|
@ -426,8 +426,12 @@ static void menu_items_from_all_operators(bContext *C, MenuSearch_Data *data)
|
|||
* - Look up predefined editor-menus.
|
||||
* - Look up key-map items which call menus.
|
||||
*/
|
||||
static MenuSearch_Data *menu_items_from_ui_create(
|
||||
bContext *C, wmWindow *win, ScrArea *area_init, ARegion *region_init, bool include_all_areas)
|
||||
static MenuSearch_Data *menu_items_from_ui_create(bContext *C,
|
||||
wmWindow *win,
|
||||
ScrArea *area_init,
|
||||
ARegion *region_init,
|
||||
bool include_all_areas,
|
||||
const char *single_menu_idname)
|
||||
{
|
||||
MemArena *memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
|
||||
/** Map (#MenuType to #MenuSearch_Parent) */
|
||||
|
@ -597,11 +601,18 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
region = region_init;
|
||||
}
|
||||
|
||||
/* Populate menus from the editors,
|
||||
* note that we could create a fake header, draw the header and extract the menus
|
||||
* from the buttons, however this is quite involved and can be avoided as by convention
|
||||
* each space-type has a single root-menu that headers use. */
|
||||
{
|
||||
if (single_menu_idname) {
|
||||
if (MenuType *mt = WM_menutype_find(single_menu_idname, false)) {
|
||||
if (BLI_gset_add(menu_tagged, mt)) {
|
||||
BLI_linklist_prepend(&menu_stack, mt);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Populate menus from the editors,
|
||||
* note that we could create a fake header, draw the header and extract the menus
|
||||
* from the buttons, however this is quite involved and can be avoided as by convention
|
||||
* each space-type has a single root-menu that headers use. */
|
||||
const char *idname_array[2] = {nullptr};
|
||||
int idname_array_len = 0;
|
||||
|
||||
|
@ -649,6 +660,8 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
SPACE_MENU_NOP(SPACE_SPREADSHEET);
|
||||
}
|
||||
}
|
||||
#undef SPACE_MENU_MAP
|
||||
#undef SPACE_MENU_NOP
|
||||
for (int i = 0; i < idname_array_len; i++) {
|
||||
MenuType *mt = WM_menutype_find(idname_array[i], false);
|
||||
if (mt != nullptr) {
|
||||
|
@ -659,8 +672,6 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
}
|
||||
}
|
||||
}
|
||||
#undef SPACE_MENU_MAP
|
||||
#undef SPACE_MENU_NOP
|
||||
|
||||
bool has_keymap_menu_items = false;
|
||||
|
||||
|
@ -792,12 +803,15 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
}
|
||||
UI_block_free(nullptr, block);
|
||||
|
||||
/* Add key-map items as a second pass,
|
||||
* so all menus are accessed from the header & top-bar before key shortcuts are expanded. */
|
||||
if ((menu_stack == nullptr) && (has_keymap_menu_items == false)) {
|
||||
has_keymap_menu_items = true;
|
||||
menu_types_add_from_keymap_items(
|
||||
C, win, area, region, &menu_stack, menu_to_kmi, menu_tagged);
|
||||
if (single_menu_idname == nullptr) {
|
||||
/* Add key-map items as a second pass, so all menus are accessed from the header & top-bar
|
||||
* before key shortcuts are expanded.
|
||||
*/
|
||||
if ((menu_stack == nullptr) && (has_keymap_menu_items == false)) {
|
||||
has_keymap_menu_items = true;
|
||||
menu_types_add_from_keymap_items(
|
||||
C, win, area, region, &menu_stack, menu_to_kmi, menu_tagged);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -904,7 +918,7 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
* - Many operators need options to be set to give useful results, see: #74157.
|
||||
* - User who really prefer to list all operators can use #WM_OT_search_operator.
|
||||
*/
|
||||
if (U.flag & USER_DEVELOPER_UI) {
|
||||
if ((U.flag & USER_DEVELOPER_UI) && single_menu_idname == nullptr) {
|
||||
menu_items_from_all_operators(C, data);
|
||||
}
|
||||
|
||||
|
@ -1128,15 +1142,17 @@ static ARegion *ui_search_menu_create_tooltip(
|
|||
/** \name Menu Search Template Public API
|
||||
* \{ */
|
||||
|
||||
void UI_but_func_menu_search(uiBut *but)
|
||||
void UI_but_func_menu_search(uiBut *but, const char *single_menu_idname)
|
||||
{
|
||||
bContext *C = (bContext *)but->block->evil_C;
|
||||
wmWindow *win = CTX_wm_window(C);
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
/* When run from top-bar scan all areas in the current window. */
|
||||
const bool include_all_areas = (area && (area->spacetype == SPACE_TOPBAR));
|
||||
MenuSearch_Data *data = menu_items_from_ui_create(C, win, area, region, include_all_areas);
|
||||
const bool include_all_areas = (area && (area->spacetype == SPACE_TOPBAR)) &&
|
||||
!single_menu_idname;
|
||||
MenuSearch_Data *data = menu_items_from_ui_create(
|
||||
C, win, area, region, include_all_areas, single_menu_idname);
|
||||
UI_but_func_search_set(but,
|
||||
/* Generic callback. */
|
||||
ui_searchbox_create_menu,
|
||||
|
@ -1163,7 +1179,7 @@ void uiTemplateMenuSearch(uiLayout *layout)
|
|||
|
||||
but = uiDefSearchBut(
|
||||
block, search, 0, ICON_VIEWZOOM, sizeof(search), 0, 0, UI_UNIT_X * 6, UI_UNIT_Y, 0, 0, "");
|
||||
UI_but_func_menu_search(but);
|
||||
UI_but_func_menu_search(but, nullptr);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -1745,6 +1745,7 @@ enum SearchType {
|
|||
struct SearchPopupInit_Data {
|
||||
SearchType search_type;
|
||||
int size[2];
|
||||
std::string single_menu_idname;
|
||||
};
|
||||
|
||||
static uiBlock *wm_block_search_menu(bContext *C, ARegion *region, void *userdata)
|
||||
|
@ -1773,7 +1774,10 @@ static uiBlock *wm_block_search_menu(bContext *C, ARegion *region, void *userdat
|
|||
UI_but_func_operator_search(but);
|
||||
}
|
||||
else if (init_data->search_type == SEARCH_TYPE_MENU) {
|
||||
UI_but_func_menu_search(but);
|
||||
UI_but_func_menu_search(but, nullptr);
|
||||
}
|
||||
else if (init_data->search_type == SEARCH_TYPE_SINGLE_MENU) {
|
||||
UI_but_func_menu_search(but, init_data->single_menu_idname.c_str());
|
||||
}
|
||||
else {
|
||||
BLI_assert_unreachable();
|
||||
|
@ -1836,7 +1840,7 @@ static int wm_search_menu_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
|||
}
|
||||
}
|
||||
|
||||
int search_type;
|
||||
SearchType search_type;
|
||||
if (STREQ(op->type->idname, "WM_OT_search_menu")) {
|
||||
search_type = SEARCH_TYPE_MENU;
|
||||
}
|
||||
|
@ -1847,15 +1851,15 @@ static int wm_search_menu_invoke(bContext *C, wmOperator *op, const wmEvent *eve
|
|||
search_type = SEARCH_TYPE_OPERATOR;
|
||||
}
|
||||
|
||||
static SearchPopupInit_Data data{};
|
||||
|
||||
if (search_type == SEARCH_TYPE_SINGLE_MENU) {
|
||||
char buffer[MAX_NAME + 1];
|
||||
RNA_string_get(op->ptr, "menu_idname", buffer);
|
||||
std::cout << buffer << "\n";
|
||||
return OPERATOR_FINISHED;
|
||||
char *buffer = RNA_string_get_alloc(op->ptr, "menu_idname", nullptr, 0, nullptr);
|
||||
data.single_menu_idname = buffer;
|
||||
MEM_freeN(buffer);
|
||||
}
|
||||
|
||||
static SearchPopupInit_Data data{};
|
||||
data.search_type = SearchType(search_type);
|
||||
data.search_type = search_type;
|
||||
data.size[0] = UI_searchbox_size_x() * 2;
|
||||
data.size[1] = UI_searchbox_size_y();
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Would make
single_menu_idname
optional (with a default value).