From 512281ac4bd42fd8938d03c7e04ca6b48ca17f6a Mon Sep 17 00:00:00 2001 From: christoph-heinrich Date: Sat, 30 Sep 2023 17:11:37 +0200 Subject: [PATCH] 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. --- README.md | 12 +++++++++--- scripts/uosc/elements/Menu.lua | 4 ++-- scripts/uosc/main.lua | 9 +++++---- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index bcec721..bd2c75c 100644 --- a/README.md +++ b/README.md @@ -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 ` -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 ` Tell **uosc** to set an external property to this value. Currently, this is only used to set/display control button active state and badges: diff --git a/scripts/uosc/elements/Menu.lua b/scripts/uosc/elements/Menu.lua index c085fc0..d6bf2cc 100644 --- a/scripts/uosc/elements/Menu.lua +++ b/scripts/uosc/elements/Menu.lua @@ -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()` diff --git a/scripts/uosc/main.lua b/scripts/uosc/main.lua index af310d3..5b88351 100644 --- a/scripts/uosc/main.lua +++ b/scripts/uosc/main.lua @@ -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