feat: add update-menu API

closes #171
This commit is contained in:
tomasklaen
2022-09-13 00:11:30 +02:00
parent 9b64c529ac
commit aeac6523d6
2 changed files with 98 additions and 8 deletions

View File

@@ -408,6 +408,8 @@ When command value is a string, it'll be passed to `mp.command(value)`. If it's
Menu `type` controls what happens when opening a menu when some other menu is already open. When the new menu type is different, it'll replace the currently opened menu. When it's the same, the currently open menu will simply be closed. This is used to implement toggling of menus with the same type.
`item.icon` property accepts icon names you can pick from here: https://fonts.google.com/icons?selected=Material+Icons
When `keep_open` is `true`, activating the item will not close the menu. This property can be defined on both menus and items, and is inherited from parent to child. Set to `false` to override the parent.
It's usually not necessary to define `selected` as it'll default to `active` item, or 1st item in the list.
@@ -427,3 +429,81 @@ local menu = {
local json = utils.format_json(menu)
mp.commandv('script-message-to', 'uosc', 'show-menu', json)
```
### `update-menu <menu_json>`
Updates currently opened menu with the same `type`. If the menu isn't open, it will be opened.
The difference between this and `open-menu` is that if the same type menu is already open, `open-menu` will close it (facilitating menu toggling with the same key/command), while `update-menu` will update it's data.
`update-menu`, along with `{menu/item}.keep_open` property and `item.command` that sends a message back can be used to create a self updating menu with some limited UI. Example:
```lua
local script_name = mp.get_script_name()
local state = {
checkbox = 'no',
radio = 'bar'
}
function command(str)
return string.format('script-message-to %s %s', script_name, str)
end
function create_menu_data()
return {
type = 'test_menu',
title = 'Test menu',
keep_open = true,
items = {
{
title = 'Checkbox',
icon = state.checkbox == 'yes' and 'check_box' or 'check_box_outline_blank',
value = command('set-state checkbox ' .. (state.checkbox == 'yes' and 'no' or 'yes'))
},
{
title = 'Radio',
hint = state.radio,
items = {
{
title = 'Foo',
icon = state.radio == 'foo' and 'radio_button_checked' or 'radio_button_unchecked',
value = command('set-state radio foo')
},
{
title = 'Bar',
icon = state.radio == 'bar' and 'radio_button_checked' or 'radio_button_unchecked',
value = command('set-state radio bar')
},
{
title = 'Baz',
icon = state.radio == 'baz' and 'radio_button_checked' or 'radio_button_unchecked',
value = command('set-state radio baz')
},
},
},
{
title = 'Submit',
icon = 'check',
value = command('submit'),
keep_open = false
},
}
}
end
mp.add_forced_key_binding('v', 'foo', function()
local json = utils.format_json(create_menu_data())
mp.commandv('script-message-to', 'uosc', 'open-menu', json)
end)
mp.register_script_message('set-state', function(prop, value)
state[prop] = value
-- Update currently opened menu
local json = utils.format_json(create_menu_data())
mp.commandv('script-message-to', 'uosc', 'update-menu', json)
end)
mp.register_script_message('submit', function(prop, value)
-- Do something with state
end)
```

View File

@@ -3752,7 +3752,7 @@ function create_select_tracklist_type_menu_opener(menu_title, track_type, track_
if load_command then
items[#items + 1] = {
title = 'Load', bold = true, italic = true, hint = 'open file', value = '{load}', separator = true
title = 'Load', bold = true, italic = true, hint = 'open file', value = '{load}', separator = true,
}
end
@@ -4411,3 +4411,13 @@ mp.register_script_message('open-menu', function(json, submenu_id)
else open_command_menu(data, submenu_id) end
end
end)
mp.register_script_message('update-menu', function(json)
local data = utils.parse_json(json)
if type(data) ~= 'table' or type(data.items) ~= 'table' then
msg.error('update-menu: received json didn\'t produce a table with menu configuration')
else
local menu = data.type and Menu:is_open(data.type)
if menu then menu:update(data)
else open_command_menu(data) end
end
end)