feat: **back** in file menus now navigates up the directory tree
closes #367
This commit is contained in:
@@ -4,7 +4,7 @@ local Element = require('uosc_shared/elements/Element')
|
||||
---@alias MenuData {type?: string; title?: string; hint?: string; keep_open?: boolean; separator?: boolean; items?: MenuDataItem[]; selected_index?: integer;}
|
||||
---@alias MenuDataItem MenuDataValue|MenuData
|
||||
---@alias MenuDataValue {title?: string; hint?: string; icon?: string; value: any; bold?: boolean; italic?: boolean; muted?: boolean; active?: boolean; keep_open?: boolean; separator?: boolean;}
|
||||
---@alias MenuOptions {mouse_nav?: boolean; on_open?: fun(), on_close?: fun()}
|
||||
---@alias MenuOptions {mouse_nav?: boolean; on_open?: fun(); on_close?: fun(); on_back?: fun()}
|
||||
|
||||
-- Internal data structure created from `Menu`.
|
||||
---@alias MenuStack {id?: string; type?: string; title?: string; hint?: string; selected_index?: number; keep_open?: boolean; separator?: boolean; items: MenuStackItem[]; parent_menu?: MenuStack; 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}
|
||||
@@ -98,7 +98,7 @@ function Menu:init(data, callback, opts)
|
||||
self.by_id = {}
|
||||
self.key_bindings = {}
|
||||
self.is_being_replaced = false
|
||||
self.is_closing = false
|
||||
self.is_closing, self.is_closed = false, false
|
||||
---@type {y: integer, time: number}[]
|
||||
self.drag_data = nil
|
||||
self.is_dragging = false
|
||||
@@ -120,6 +120,7 @@ end
|
||||
function Menu:destroy()
|
||||
Element.destroy(self)
|
||||
self:disable_key_bindings()
|
||||
self.is_closed = true
|
||||
if not self.is_being_replaced then Elements.curtain:unregister('menu') end
|
||||
if self.opts.on_close then self.opts.on_close() end
|
||||
end
|
||||
@@ -439,16 +440,23 @@ function Menu:next(menu)
|
||||
end
|
||||
|
||||
function Menu:back()
|
||||
if self.opts.on_back then
|
||||
self.opts.on_back()
|
||||
if self.is_closed then return end
|
||||
end
|
||||
|
||||
local menu = self.current
|
||||
local parent = menu.parent_menu
|
||||
|
||||
if not parent then return self:close() end
|
||||
|
||||
menu.selected_index = nil
|
||||
self.current = parent
|
||||
self:update_dimensions()
|
||||
self:tween(self.offset_x - menu.width / 2, 0, function(offset) self:set_offset_x(offset) end)
|
||||
self.opacity = 1 -- in case tween above canceled fade in animation
|
||||
if parent then
|
||||
menu.selected_index = nil
|
||||
self.current = parent
|
||||
self:update_dimensions()
|
||||
self:tween(self.offset_x - menu.width / 2, 0, function(offset) self:set_offset_x(offset) end)
|
||||
self.opacity = 1 -- in case tween above canceled fade in animation
|
||||
else
|
||||
self:close()
|
||||
end
|
||||
end
|
||||
|
||||
---@param opts? {keep_open?: boolean, preselect_submenu_item?: boolean}
|
||||
|
@@ -178,6 +178,7 @@ function open_file_navigation_menu(directory_path, handle_select, opts)
|
||||
items[#items + 1] = {title = '..', hint = 'parent dir', value = directory.dirname, separator = true}
|
||||
end
|
||||
|
||||
local back_path = items[#items] and items[#items].value
|
||||
local selected_index = #items + 1
|
||||
|
||||
for _, dir in ipairs(directories) do
|
||||
@@ -197,13 +198,7 @@ function open_file_navigation_menu(directory_path, handle_select, opts)
|
||||
if opts.selected_path == item.value then selected_index = index end
|
||||
end
|
||||
|
||||
local menu_data = {
|
||||
type = opts.type, title = opts.title or directory.basename .. path_separator, items = items,
|
||||
selected_index = selected_index,
|
||||
}
|
||||
local menu_options = {on_open = opts.on_open, on_close = opts.on_close}
|
||||
|
||||
return Menu:open(menu_data, function(path)
|
||||
local function open_path(path)
|
||||
local is_drives = path == '{drives}'
|
||||
local is_to_parent = is_drives or #path < #directory_path
|
||||
local inheritable_options = {
|
||||
@@ -237,7 +232,19 @@ function open_file_navigation_menu(directory_path, handle_select, opts)
|
||||
else
|
||||
handle_select(path)
|
||||
end
|
||||
end, menu_options)
|
||||
end
|
||||
|
||||
local function handle_back()
|
||||
if back_path then open_path(back_path) end
|
||||
end
|
||||
|
||||
local menu_data = {
|
||||
type = opts.type, title = opts.title or directory.basename .. path_separator, items = items,
|
||||
selected_index = selected_index,
|
||||
}
|
||||
local menu_options = {on_open = opts.on_open, on_close = opts.on_close, on_back = handle_back}
|
||||
|
||||
return Menu:open(menu_data, open_path, menu_options)
|
||||
end
|
||||
|
||||
-- Opens a file navigation menu with Windows drives as items.
|
||||
|
Reference in New Issue
Block a user