UI: Add Preference to Instant Search in all Menus #112925
|
@ -168,6 +168,7 @@ const UserDef U_default = {
|
|||
.animation_flag = USER_ANIM_HIGH_QUALITY_DRAWING,
|
||||
.text_render = 0,
|
||||
.navigation_mode = VIEW_NAVIGATION_WALK,
|
||||
.menu_key_behavior = USER_MENU_KEY_SEARCH,
|
||||
.view_rotate_sensitivity_turntable = DEG2RAD(0.4),
|
||||
.view_rotate_sensitivity_trackball = 1.0f,
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
|||
|
||||
class OBJECT_MT_modifier_add(ModifierAddMenu, Menu):
|
||||
bl_label = "Add Modifier"
|
||||
bl_options = {'SEARCH_ON_KEY_PRESS'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
|
|
@ -226,7 +226,6 @@ class NODE_MT_add(bpy.types.Menu):
|
|||
bl_space_type = 'NODE_EDITOR'
|
||||
bl_label = "Add"
|
||||
bl_translation_context = i18n_contexts.operator_default
|
||||
bl_options = {'SEARCH_ON_KEY_PRESS'}
|
||||
|
||||
def draw(self, context):
|
||||
import nodeitems_utils
|
||||
|
|
|
@ -310,12 +310,15 @@ class USERPREF_PT_interface_statusbar(InterfacePanel, CenterAlignMixIn, Panel):
|
|||
col.prop(view, "show_statusbar_version", text="Blender Version")
|
||||
|
||||
|
||||
class USERPREF_PT_interface_menus(InterfacePanel, Panel):
|
||||
class USERPREF_PT_interface_menus(InterfacePanel, CenterAlignMixIn, Panel):
|
||||
bl_label = "Menus"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
pass
|
||||
def draw_centered(self, context, layout):
|
||||
prefs = context.preferences
|
||||
view = prefs.view
|
||||
col = layout.column()
|
||||
col.prop(view, "menu_key_behavior")
|
||||
|
||||
|
||||
class USERPREF_PT_interface_menus_mouse_over(InterfacePanel, CenterAlignMixIn, Panel):
|
||||
|
|
|
@ -2479,7 +2479,6 @@ class VIEW3D_MT_grease_pencil_add(Menu):
|
|||
class VIEW3D_MT_add(Menu):
|
||||
bl_label = "Add"
|
||||
bl_translation_context = i18n_contexts.operator_default
|
||||
bl_options = {'SEARCH_ON_KEY_PRESS'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
|
|
@ -411,10 +411,6 @@ enum class MenuTypeFlag {
|
|||
* dependent, menu search has to scan it in different contexts.
|
||||
*/
|
||||
ContextDependent = (1 << 0),
|
||||
/**
|
||||
* Automatically start searching in the menu when pressing a key.
|
||||
*/
|
||||
SearchOnKeyPress = (1 << 1),
|
||||
};
|
||||
ENUM_OPERATORS(MenuTypeFlag, MenuTypeFlag::ContextDependent)
|
||||
|
||||
|
|
|
@ -10308,28 +10308,27 @@ static int ui_handle_menu_letter_press(
|
|||
bContext *C, ARegion *region, uiPopupBlockHandle *menu, const wmEvent *event, uiBlock *block)
|
||||
{
|
||||
/* Start menu search on key press if enabled. */
|
||||
if (menu->menu_idname[0]) {
|
||||
MenuType *mt = WM_menutype_find(menu->menu_idname, false);
|
||||
if (bool(mt->flag & MenuTypeFlag::SearchOnKeyPress)) {
|
||||
uiAfterFunc *after = ui_afterfunc_new();
|
||||
wmOperatorType *ot = WM_operatortype_find("WM_OT_search_single_menu", false);
|
||||
after->optype = ot;
|
||||
after->opcontext = WM_OP_INVOKE_DEFAULT;
|
||||
after->opptr = MEM_cnew<PointerRNA>(__func__);
|
||||
WM_operator_properties_create_ptr(after->opptr, ot);
|
||||
RNA_string_set(after->opptr, "menu_idname", menu->menu_idname);
|
||||
if (event->type != EVT_SPACEKEY) {
|
||||
const int num_bytes = BLI_str_utf8_size_or_error(event->utf8_buf);
|
||||
if (num_bytes != -1) {
|
||||
char buf[sizeof(event->utf8_buf) + 1];
|
||||
memcpy(buf, event->utf8_buf, num_bytes);
|
||||
buf[num_bytes] = '\0';
|
||||
RNA_string_set(after->opptr, "initial_query", buf);
|
||||
}
|
||||
if (menu->menu_idname[0] &&
|
||||
(eUserpref_MenuKeyBehavior(U.menu_key_behavior) == USER_MENU_KEY_SEARCH))
|
||||
{
|
||||
uiAfterFunc *after = ui_afterfunc_new();
|
||||
wmOperatorType *ot = WM_operatortype_find("WM_OT_search_single_menu", false);
|
||||
after->optype = ot;
|
||||
after->opcontext = WM_OP_INVOKE_DEFAULT;
|
||||
after->opptr = MEM_cnew<PointerRNA>(__func__);
|
||||
WM_operator_properties_create_ptr(after->opptr, ot);
|
||||
RNA_string_set(after->opptr, "menu_idname", menu->menu_idname);
|
||||
if (event->type != EVT_SPACEKEY) {
|
||||
const int num_bytes = BLI_str_utf8_size_or_error(event->utf8_buf);
|
||||
if (num_bytes != -1) {
|
||||
char buf[sizeof(event->utf8_buf) + 1];
|
||||
memcpy(buf, event->utf8_buf, num_bytes);
|
||||
buf[num_bytes] = '\0';
|
||||
RNA_string_set(after->opptr, "initial_query", buf);
|
||||
}
|
||||
menu->menuretval = UI_RETURN_OK;
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
menu->menuretval = UI_RETURN_OK;
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
|
||||
/* Handle accelerator keys that allow "pressing" a menu entry by pressing a single key. */
|
||||
|
|
|
@ -5923,9 +5923,6 @@ void UI_menutype_draw(bContext *C, MenuType *mt, uiLayout *layout)
|
|||
}
|
||||
|
||||
uiBlock *block = uiLayoutGetBlock(layout);
|
||||
if (bool(mt->flag & MenuTypeFlag::SearchOnKeyPress)) {
|
||||
UI_block_flag_enable(block, UI_BLOCK_NO_ACCELERATOR_KEYS);
|
||||
}
|
||||
if (mt->listener) {
|
||||
/* Forward the menu type listener to the block we're drawing in. */
|
||||
ui_block_add_dynamic_listener(block, mt->listener);
|
||||
|
|
|
@ -229,6 +229,11 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
|
|||
if (!pup->layout) {
|
||||
ui_popup_menu_create_block(C, pup, pup->title, __func__);
|
||||
|
||||
if (pup->popup && eUserpref_MenuKeyBehavior(U.menu_key_behavior) == USER_MENU_KEY_SEARCH) {
|
||||
pup->block->flag |= UI_BLOCK_NO_ACCELERATOR_KEYS;
|
||||
ED_workspace_status_text(C, TIP_("Type to search..."));
|
||||
}
|
||||
|
||||
if (pup->menu_func) {
|
||||
pup->block->handle = handle;
|
||||
pup->menu_func(C, pup->layout);
|
||||
|
@ -404,11 +409,13 @@ static uiPopupBlockHandle *ui_popup_menu_create(
|
|||
if (but) {
|
||||
pup->slideout = ui_block_is_menu(but->block);
|
||||
pup->but = but;
|
||||
|
||||
if (MenuType *mt = UI_but_menutype_get(but)) {
|
||||
if (bool(mt->flag & MenuTypeFlag::SearchOnKeyPress)) {
|
||||
ED_workspace_status_text(C, TIP_("Type to search..."));
|
||||
if (but->type == UI_BTYPE_PULLDOWN &&
|
||||
eUserpref_MenuKeyBehavior(U.menu_key_behavior) == USER_MENU_KEY_SEARCH)
|
||||
{
|
||||
if (but->block) {
|
||||
but->block->flag |= UI_BLOCK_NO_ACCELERATOR_KEYS;
|
||||
}
|
||||
ED_workspace_status_text(C, TIP_("Type to search..."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -624,7 +631,7 @@ static void ui_popup_menu_create_from_menutype(bContext *C,
|
|||
STRNCPY(handle->menu_idname, mt->idname);
|
||||
handle->can_refresh = true;
|
||||
|
||||
if (bool(mt->flag & MenuTypeFlag::SearchOnKeyPress)) {
|
||||
if (mt->idname[0] && eUserpref_MenuKeyBehavior(U.menu_key_behavior) == USER_MENU_KEY_SEARCH) {
|
||||
ED_workspace_status_text(C, TIP_("Type to search..."));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -820,9 +820,10 @@ uiPopupBlockHandle *ui_popup_block_create(bContext *C,
|
|||
|
||||
void ui_popup_block_free(bContext *C, uiPopupBlockHandle *handle)
|
||||
{
|
||||
/* This disables the status bar text that is set when opening a menu that supports search (see
|
||||
* #MenuTypeFlag::SearchOnKeyPress). */
|
||||
ED_workspace_status_text(C, nullptr);
|
||||
if (eUserpref_MenuKeyBehavior(U.menu_key_behavior) == USER_MENU_KEY_SEARCH) {
|
||||
/* Clear the status bar text that is set when opening a menu. */
|
||||
ED_workspace_status_text(C, nullptr);
|
||||
}
|
||||
|
||||
/* If this popup is created from a popover which does NOT have keep-open flag set,
|
||||
* then close the popover too. We could extend this to other popup types too. */
|
||||
|
|
|
@ -455,13 +455,18 @@ static MenuSearch_Data *menu_items_from_ui_create(bContext *C,
|
|||
/* Blacklist menus we don't want to show. */
|
||||
{
|
||||
const char *idname_array[] = {
|
||||
/* While we could include this, it's just showing filenames to load. */
|
||||
"TOPBAR_MT_file_open_recent",
|
||||
/* Exclude recent list unless we are specifically searching it. */
|
||||
(single_menu_idname && STREQ(single_menu_idname, "TOPBAR_MT_file_open_recent")) ?
|
||||
nullptr :
|
||||
"TOPBAR_MT_file_open_recent",
|
||||
/* Showing undo history is not helpful since users may accidentally undo
|
||||
* an action they intend to run. */
|
||||
"TOPBAR_MT_undo_history",
|
||||
};
|
||||
for (int i = 0; i < ARRAY_SIZE(idname_array); i++) {
|
||||
if (!idname_array[i]) {
|
||||
Harley marked this conversation as resolved
Outdated
|
||||
continue;
|
||||
}
|
||||
MenuType *mt = WM_menutype_find(idname_array[i], false);
|
||||
if (mt != nullptr) {
|
||||
menu_tagged.add(mt);
|
||||
|
@ -469,8 +474,8 @@ static MenuSearch_Data *menu_items_from_ui_create(bContext *C,
|
|||
}
|
||||
}
|
||||
Harley marked this conversation as resolved
Outdated
Julian Eisel
commented
"Single menu search" is an invented term that doesn't really add much. Just say "when not searching in a single menu only". "Single menu search" is an invented term that doesn't really add much. Just say "when not searching in a single menu only".
|
||||
|
||||
{
|
||||
/* Exclude context menus because:
|
||||
if (!single_menu_idname) {
|
||||
/* Exclude context menus (when not searching in a specific single menu) because:
|
||||
* - The menu items are available elsewhere (and will show up multiple times).
|
||||
* - Menu items depend on exact context, making search results unpredictable
|
||||
* (exact number of items selected for example). See design doc #74158.
|
||||
|
|
|
@ -1023,7 +1023,8 @@ typedef struct UserDef {
|
|||
|
||||
float collection_instance_empty_size;
|
||||
char text_flag;
|
||||
char _pad10[1];
|
||||
|
||||
char menu_key_behavior;
|
||||
|
||||
char file_preview_type; /* eUserpref_File_Preview_Type */
|
||||
char statusbar_flag; /* eUserpref_StatusBar_Flag */
|
||||
|
@ -1153,6 +1154,12 @@ typedef enum eViewNavigation_Method {
|
|||
VIEW_NAVIGATION_FLY = 1,
|
||||
} eViewNavigation_Method;
|
||||
|
||||
/** #UserDef.menu_key_behavior */
|
||||
typedef enum eUserpref_MenuKeyBehavior {
|
||||
USER_MENU_KEY_SEARCH = 0,
|
||||
USER_MENU_KEY_ACCELERATOR = 1,
|
||||
} eUserpref_MenuKeyBehavior;
|
||||
|
||||
/** #UserDef.uiflag */
|
||||
typedef enum eUserpref_MiniAxisType {
|
||||
USER_MINI_AXIS_TYPE_GIZMO = 0,
|
||||
|
|
|
@ -2009,15 +2009,6 @@ static void rna_def_menu(BlenderRNA *brna)
|
|||
PropertyRNA *parm;
|
||||
FunctionRNA *func;
|
||||
|
||||
static const EnumPropertyItem menu_flag_items[] = {
|
||||
{int(MenuTypeFlag::SearchOnKeyPress),
|
||||
"SEARCH_ON_KEY_PRESS",
|
||||
0,
|
||||
"Search on Key Press",
|
||||
"Open a menu search when a key pressed while the menu is open"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
srna = RNA_def_struct(brna, "Menu", nullptr);
|
||||
RNA_def_struct_ui_text(srna, "Menu", "Editor menu containing buttons");
|
||||
RNA_def_struct_sdna(srna, "Menu");
|
||||
|
@ -2082,12 +2073,6 @@ static void rna_def_menu(BlenderRNA *brna)
|
|||
RNA_def_property_string_sdna(prop, nullptr, "type->owner_id");
|
||||
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
|
||||
|
||||
prop = RNA_def_property(srna, "bl_options", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "type->flag");
|
||||
RNA_def_property_enum_items(prop, menu_flag_items);
|
||||
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
|
||||
RNA_def_property_ui_text(prop, "Options", "Options for this menu type");
|
||||
|
||||
RNA_define_verify_sdna(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -4961,6 +4961,23 @@ static void rna_def_userdef_view(BlenderRNA *brna)
|
|||
RNA_def_property_update(prop, 0, "rna_userdef_gizmo_update");
|
||||
|
||||
/* menus */
|
||||
|
||||
static const EnumPropertyItem rna_enum_menu_key_behavior_items[] = {
|
||||
{USER_MENU_KEY_SEARCH, "SEARCH", 0, "Type to Search", "Type to immediately start searching"},
|
||||
{USER_MENU_KEY_ACCELERATOR,
|
||||
"ACCELERATOR",
|
||||
0,
|
||||
"Accelerator keys",
|
||||
"Select item by accelerator"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
prop = RNA_def_property(srna, "menu_key_behavior", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "menu_key_behavior");
|
||||
RNA_def_property_enum_items(prop, rna_enum_menu_key_behavior_items);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Menu Key Behavior", "What happens when you press a key when a menu is open");
|
||||
|
||||
prop = RNA_def_property(srna, "use_mouse_over_open", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "uiflag", USER_MENUOPENAUTO);
|
||||
RNA_def_property_ui_text(
|
||||
|
|
Loading…
Reference in New Issue
Don't hide this logic inside a variable initialization. Make it explicit (above this line):