Skip to content

Commit 580ceee

Browse files
committed
feat(api): added Menu.bind_keys option
When menu was open, it was taking over too many keys that people had keybinds for. This didn't seem like a problem because they were only active while the menu was open, but there were complains anyway. Since this commit, if you want to listen for non-common keys that are not bound by default like `f1-f12`, you need to tell the menu to bind the listeners for them with `bind_keys` option. It accepts a table with keybinds such as `{'f1', 'alt+f2'}` etc. closes #996, #1127
1 parent 9d3c356 commit 580ceee

2 files changed

Lines changed: 18 additions & 17 deletions

File tree

src/uosc/elements/Menu.lua

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ local Element = require('elements/Element')
33
---@alias MenuAction {name: string; icon: string; label?: string; filter_hidden?: boolean;}
44

55
-- Menu data structure accepted by `Menu:open(menu)`.
6-
---@alias MenuData {id?: string; type?: string; title?: string; hint?: string; footnote: string; search_style?: 'on_demand' | 'palette' | 'disabled'; item_actions?: MenuAction[]; item_actions_place?: 'inside' | 'outside'; callback?: string[]; keep_open?: boolean; bold?: boolean; italic?: boolean; muted?: boolean; separator?: boolean; align?: 'left'|'center'|'right'; items?: MenuDataChild[]; selected_index?: integer; on_search?: string|string[]; on_paste?: string|string[]; on_move?: string|string[]; on_close?: string|string[]; search_debounce?: number|string; search_submenus?: boolean; search_suggestion?: string; search_submit?: boolean}
6+
---@alias MenuData {id?: string; type?: string; title?: string; hint?: string; footnote: string; search_style?: 'on_demand' | 'palette' | 'disabled'; item_actions?: MenuAction[]; item_actions_place?: 'inside' | 'outside'; callback?: string[]; keep_open?: boolean; bold?: boolean; italic?: boolean; muted?: boolean; separator?: boolean; align?: 'left'|'center'|'right'; items?: MenuDataChild[]; selected_index?: integer; on_search?: string|string[]; on_paste?: string|string[]; on_move?: string|string[]; on_close?: string|string[]; search_debounce?: number|string; search_submenus?: boolean; search_suggestion?: string; search_submit?: boolean; bind_keys?: string[]}
77
---@alias MenuDataChild MenuDataItem|MenuData
88
---@alias MenuDataItem {title?: string; hint?: string; icon?: string; value: any; actions?: MenuAction[]; actions_place?: 'inside' | 'outside'; active?: boolean; keep_open?: boolean; selectable?: boolean; bold?: boolean; italic?: boolean; muted?: boolean; separator?: boolean; align?: 'left'|'center'|'right'}
99
---@alias MenuOptions {mouse_nav?: boolean;}
1010

1111
-- Internal data structure created from `MenuData`.
12-
---@alias MenuStack {id?: string; type?: string; title?: string; hint?: string; footnote: string; search_style?: 'on_demand' | 'palette' | 'disabled'; item_actions?: MenuAction[]; item_actions_place?: 'inside' | 'outside'; callback?: string[]; selected_index?: number; action_index?: number; keep_open?: boolean; bold?: boolean; italic?: boolean; muted?: boolean; separator?: boolean; align?: 'left'|'center'|'right'; items: MenuStackChild[]; on_search?: string|string[]; on_paste?: string|string[]; on_move?: string|string[]; on_close?: string|string[]; search_debounce?: number|string; search_submenus?: boolean; search_suggestion?: string; search_submit?: boolean; parent_menu?: MenuStack; submenu_path: integer[]; active?: boolean; width: number; height: number; top: number; scroll_y: number; scroll_height: number; title_width: number; hint_width: number; max_width: number; is_root?: boolean; fling?: Fling, search?: Search, ass_safe_title?: string}
12+
---@alias MenuStack {id?: string; type?: string; title?: string; hint?: string; footnote: string; search_style?: 'on_demand' | 'palette' | 'disabled'; item_actions?: MenuAction[]; item_actions_place?: 'inside' | 'outside'; callback?: string[]; selected_index?: number; action_index?: number; keep_open?: boolean; bold?: boolean; italic?: boolean; muted?: boolean; separator?: boolean; align?: 'left'|'center'|'right'; items: MenuStackChild[]; on_search?: string|string[]; on_paste?: string|string[]; on_move?: string|string[]; on_close?: string|string[]; search_debounce?: number|string; search_submenus?: boolean; search_suggestion?: string; search_submit?: boolean; bind_keys?: string[]; parent_menu?: MenuStack; submenu_path: integer[]; active?: boolean; width: number; height: number; top: number; scroll_y: number; scroll_height: number; title_width: number; hint_width: number; max_width: number; is_root?: boolean; fling?: Fling, search?: Search, ass_safe_title?: string}
1313
---@alias MenuStackChild MenuStackItem|MenuStack
1414
---@alias MenuStackItem {title?: string; hint?: string; icon?: string; value: any; actions?: MenuAction[]; actions_place?: 'inside' | 'outside'; active?: boolean; keep_open?: boolean; selectable?: boolean; bold?: boolean; italic?: boolean; muted?: boolean; separator?: boolean; align?: 'left'|'center'|'right'; title_width: number; hint_width: number; ass_safe_hint?: string}
1515
---@alias Fling {y: number, distance: number, time: number, easing: fun(x: number), duration: number, update_cursor?: boolean}
@@ -1120,27 +1120,22 @@ function Menu:search_ensure_key_bindings()
11201120
end
11211121

11221122
function Menu:enable_key_bindings()
1123+
local standalone_keys = {'/', 'kp_divide', 'mbtn_back', 'ctrl+f', 'ctrl+v', 'ctrl+c'}
1124+
if type(self.root.bind_keys) == 'table' then itable_append(standalone_keys, self.root.bind_keys) end
11231125
-- `+` at the end enables `repeatable` flag
1124-
local standalone_keys = {
1125-
'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7', 'f8', 'f9', 'f10', 'f11', 'f12', '/', 'kp_divide', 'mbtn_back',
1126-
{'f', 'ctrl'}, {'v', 'ctrl'}, {'c', 'ctrl'},
1127-
}
11281126
local modifiable_keys = {'up+', 'down+', 'left', 'right', 'enter', 'kp_enter', 'bs', 'tab', 'esc', 'pgup+',
11291127
'pgdwn+', 'home', 'end', 'del'}
11301128
local modifiers = {nil, 'alt', 'alt+ctrl', 'alt+shift', 'alt+ctrl+shift', 'ctrl', 'ctrl+shift', 'shift'}
1131-
local normalized = {kp_enter = 'enter'}
11321129

1133-
local function bind(key, modifier, flags)
1134-
local binding = modifier and modifier .. '+' .. key or key
1135-
local shortcut = create_shortcut(normalized[key] or key, modifier)
1130+
---@param shortcut Shortcut
1131+
---@param flags table<string, boolean>
1132+
local function bind(shortcut, flags)
11361133
local handler = self:create_action(function(info) self:handle_shortcut(shortcut, info) end)
1137-
self:add_key_binding(binding, {handler, flags})
1134+
self:add_key_binding(shortcut.id, {handler, flags})
11381135
end
11391136

1140-
for i, key_mods in ipairs(standalone_keys) do
1141-
local is_table = type(key_mods) == 'table'
1142-
local key, mods = is_table and key_mods[1] or key_mods, is_table and key_mods[2] or nil
1143-
bind(key, mods, {repeatable = false, complex = true})
1137+
for i, key in ipairs(standalone_keys) do
1138+
bind(create_shortcut(key), {repeatable = false, complex = true})
11441139
end
11451140

11461141
for i, key in ipairs(modifiable_keys) do
@@ -1152,7 +1147,7 @@ function Menu:enable_key_bindings()
11521147
end
11531148

11541149
for j = 1, #modifiers do
1155-
bind(key, modifiers[j], flags)
1150+
bind(create_shortcut(key, modifiers[j]), flags)
11561151
end
11571152
end
11581153

src/uosc/lib/std.lua

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,12 +282,18 @@ function serialize_key_value_list(input, value_sanitizer)
282282
return result
283283
end
284284

285-
---@param key string
285+
---@param key string Key or a combination of a `modifiers+key`. If this includes modifiers, the `modifiers` param is ignored.
286286
---@param modifiers? string
287287
---@return Shortcut
288288
function create_shortcut(key, modifiers)
289289
key = key:lower()
290290

291+
local last_plus_in_key = string_last_index_of(key, '+')
292+
if last_plus_in_key then
293+
modifiers = string.sub(key, 1, last_plus_in_key - 1)
294+
key = string.sub(key, last_plus_in_key + 1)
295+
end
296+
291297
local id_parts, modifiers_set
292298
if modifiers then
293299
id_parts = split(modifiers:lower(), '+')

0 commit comments

Comments
 (0)