feat(api)!: menu script-message changes (#653)

- `open-menu` now only opens the menu, while closing any existing one first, even if it has the same `type`.
- `update-menu` will only update a currently opened menu of the same type. If no menu is open, or current menu's type is different, it doesn't do anything.
- `close-menu [type]` can be used to close any currently opened menu when called without a `[type]` argument, or only a menu of `[type]` type.
- uosc now keeps track of a currently opened menu type on the `user-data/uosc/menu/type` property, accessible via `mp.get_property_native('user-data/uosc/menu/type')`. This property is `nil` if no uosc menu is opened.

This is to achieve a predictable and granular control of menus with no implicit magic going on in the background.

The main difference is that `open-menu` can no longer be used to toggle the menu. You have to implement toggling manually by calling `open-menu` or `close-menu [type]` when appropriate. You can check if your menu is still opened either by getting or observing the `user-data/uosc/menu/type` property, or using the `on_close` menu callback.
This commit is contained in:
christoph-heinrich
2023-09-30 17:11:37 +02:00
committed by GitHub
parent c88c476ec7
commit 512281ac4b
3 changed files with 16 additions and 9 deletions

View File

@@ -458,7 +458,8 @@ Command {
When `Command.value` is a string, it'll be passed to `mp.command(value)`. If it's a table (array) of strings, it'll be used as `mp.commandv(table.unpack(value))`. The same goes for `Menu.on_close` and `on_search`. `on_search` additionally appends the current search string as the last parameter.
`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.
`Menu.type` is used to refer to this menu in `update-menu` and `close-menu`.
While the menu is open this value will be available in `user-data/uosc/menu/type`. Keep in mind that `nil` is a valid value. If the menu is closed `mp.get_property_native()` will return an error as the second return value.
`palette` specifies that this menu's primarily mode of interaction is through a search input. When enabled, search input will be visible at all times (doesn't have to be enabled and can't be disabled), and `title` will be used as input placeholder while search query is empty.
@@ -491,9 +492,9 @@ mp.commandv('script-message-to', 'uosc', 'open-menu', json)
### `update-menu <menu_json>`
Updates currently opened menu with the same `type`. If the menu isn't open, it will be opened.
Updates currently opened menu with the same `type`.
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.
The difference between this and `open-menu` is that if the same type menu is already open, `open-menu` will reset the menu as if it was newly opened, 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:
@@ -568,6 +569,11 @@ mp.register_script_message('submit', function(prop, value)
end)
```
### `close-menu [type]`
Closes the menu. If the optional parameter `type` is provided, then the menu only
closes if it matches `Menu.type` of the currently open menu.
### `set <prop> <value>`
Tell **uosc** to set an external property to this value. Currently, this is only used to set/display control button active state and badges:

View File

@@ -112,6 +112,7 @@ function Menu:init(data, callback, opts)
self.drag_last_y = nil
self.is_dragging = false
mp.set_property_native('user-data/uosc/menu/type', self.type)
self:update(data)
if self.mouse_nav then
@@ -131,13 +132,12 @@ function Menu:destroy()
self:disable_key_bindings()
self.is_closed = true
if not self.is_being_replaced then Elements.curtain:unregister('menu') end
mp.del_property('user-data/uosc/menu/type')
if self.opts.on_close then self.opts.on_close() end
end
---@param data MenuData
function Menu:update(data)
self.type = data.type
local new_root = {is_root = true, submenu_path = {}}
local new_all = {}
local new_menus = {} -- menus that didn't exist before this `update()`

View File

@@ -1283,8 +1283,7 @@ mp.register_script_message('open-menu', function(json, submenu_id)
if type(data) ~= 'table' or type(data.items) ~= 'table' then
msg.error('open-menu: received json didn\'t produce a table with menu configuration')
else
if data.type and Menu:is_open(data.type) then Menu:close()
else open_command_menu(data, {submenu = submenu_id, on_close = data.on_close}) end
open_command_menu(data, {submenu = submenu_id, on_close = data.on_close})
end
end)
mp.register_script_message('update-menu', function(json)
@@ -1293,10 +1292,12 @@ mp.register_script_message('update-menu', function(json)
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
if menu then menu:update(data) end
end
end)
mp.register_script_message('close-menu', function(type)
if Menu:is_open(type) then Menu:close() end
end)
mp.register_script_message('thumbfast-info', function(json)
local data = utils.parse_json(json)
if type(data) ~= 'table' or not data.width or not data.height then