touchmenu: optimize (#14027)
Some checks failed
macos / macOS 13 x86-64 🔨15.2 🎯10.15 (push) Has been cancelled
macos / macOS 14 ARM64 🔨15.4 🎯11.0 (push) Has been cancelled

This commit is contained in:
hius07
2025-07-08 09:50:59 +03:00
committed by GitHub
parent 07845f29a3
commit 6a567406e2

View File

@@ -471,7 +471,6 @@ local TouchMenu = FocusManager:extend{
fface = Font:getFace("ffont"),
width = nil,
height = nil,
page = 1,
max_per_page_default = 10,
-- for UIManager:setDirty
show_parent = nil,
@@ -481,6 +480,7 @@ local TouchMenu = FocusManager:extend{
}
function TouchMenu:init()
self.screen_size = Screen:getSize()
-- We won't include self.bordersize in our width calculations, so that
-- borders are pushed off-(screen-)width and so not visible.
-- We'll then be similar to bottom menu ConfigDialog (where this
@@ -500,8 +500,8 @@ function TouchMenu:init()
ges = "tap",
range = Geom:new{
x = 0, y = 0,
w = Screen:getWidth(),
h = Screen:getHeight(),
w = self.screen_size.w,
h = self.screen_size.h,
}
}
}
@@ -624,7 +624,7 @@ function TouchMenu:init()
-- This CenterContainer will make the left and right borders drawn
-- off-screen
self[1] = CenterContainer:new{
dimen = Screen:getSize(),
dimen = self.screen_size,
ignore = "height",
self.menu_frame
}
@@ -643,51 +643,30 @@ function TouchMenu:init()
HorizontalSpan:new{width = Size.span.horizontal_default},
}
self.footer_top_margin = VerticalSpan:new{width = Size.span.vertical_default}
local menu_height = self.height and math.min(self.height, self.screen_size.h) or self.screen_size.h
local items_height = menu_height - self.bar:getSize().h - self.footer_top_margin:getSize().h - self.footer:getSize().h
self.max_per_page = math.floor(items_height / (self.item_height + self.split_line:getSize().h))
self.bar:switchToTab(self.last_index or 1)
end
function TouchMenu:onCloseWidget()
-- NOTE: We don't pass a region in order to ensure a full-screen flash to avoid ghosting,
-- but we only need to do that if we actually have a FM or RD below us.
-- Don't do anything when we're switching between the two, or if we don't actually have a live instance of 'em...
local FileManager = require("apps/filemanager/filemanager")
local ReaderUI = require("apps/reader/readerui")
if (FileManager.instance and not FileManager.instance.tearing_down)
or (ReaderUI.instance and not ReaderUI.instance.tearing_down) then
UIManager:setDirty(nil, "flashui")
end
end
function TouchMenu:_recalculatePageLayout()
local content_height -- content == item_list + footer
local bar_height = self.bar:getSize().h
local footer_height = self.footer:getSize().h
if self.height then
content_height = self.height - bar_height
else
content_height = #self.item_table * self.item_height + footer_height
-- split line height
content_height = content_height + (#self.item_table - 1)
content_height = content_height + self.footer_top_margin:getSize().h
end
if content_height + bar_height > Screen:getHeight() then
content_height = Screen:getHeight() - bar_height
end
local item_list_content_height = content_height - footer_height
self.perpage = math.floor(item_list_content_height / self.item_height)
local max_per_page = self.item_table.max_per_page or self.max_per_page_default
if self.perpage > max_per_page then
self.perpage = max_per_page
end
function TouchMenu:updateItems(target_page, target_item_id)
self.perpage = math.min(self.max_per_page, self.item_table.max_per_page or self.max_per_page_default)
self.page_num = math.ceil(#self.item_table / self.perpage)
end
if target_item_id ~= nil then -- show menu page with target item
for i, v in ipairs(self.item_table) do
if v.menu_item_id == target_item_id then
target_page = math.floor( (i - 1) / self.perpage ) + 1
break
end
end
end
self.page = target_page or self.page
if self.page > self.page_num then
self.page = self.page_num
end
function TouchMenu:updateItems()
local old_dimen = self.dimen and self.dimen:copy()
self:_recalculatePageLayout()
self.item_group:clear()
self.layout = {}
table.insert(self.item_group, self.bar)
@@ -708,14 +687,12 @@ function TouchMenu:updateItems()
h = self.item_height,
},
show_parent = self.show_parent,
item_visible_index = c,
}
table.insert(self.item_group, item_tmp)
if item_tmp:isEnabled() then
table.insert(self.layout, {[self.cur_tab] = item_tmp}) -- for the focusmanager
end
if item.separator and c ~= self.perpage and i ~= #self.item_table then
-- insert split line
table.insert(self.item_group, self.split_line)
end
else
@@ -743,7 +720,6 @@ function TouchMenu:updateItems()
local batt_lvl = powerd:getCapacity()
local batt_symbol = powerd:getBatterySymbol(powerd:isCharged(), powerd:isCharging(), batt_lvl)
time_info_txt = BD.wrap(time_info_txt) .. " " .. BD.wrap("") .. BD.wrap(batt_symbol) .. BD.wrap(batt_lvl .. "%")
if Device:hasAuxBattery() and powerd:isAuxBatteryConnected() then
local aux_batt_lvl = powerd:getAuxCapacity()
local aux_batt_symbol = powerd:getBatterySymbol(powerd:isAuxCharged(), powerd:isAuxCharging(), aux_batt_lvl)
@@ -753,6 +729,7 @@ function TouchMenu:updateItems()
self.time_info:setText(time_info_txt)
-- recalculate dimen based on new layout
local old_dimen = self.dimen:copy()
self.dimen.w = self.width
self.dimen.h = self.item_group:getSize().h + self.bordersize*2 + self.padding -- (no padding at top)
self:moveFocusTo(self.cur_tab, 1, FocusManager.NOT_FOCUS) -- reset the position of the focusmanager
@@ -791,13 +768,11 @@ function TouchMenu:switchMenuTab(tab_num)
-- It's like getting a new menu every time we switch tab!
-- Also, switching to the _same_ tab resets the stack and takes us back to
-- the top of the menu tree
self.page = 1
-- clear item table stack
self.item_table_stack = {}
self.parent_id = nil
self.cur_tab = tab_num
self.item_table = self.tab_item_table[tab_num]
self:updateItems()
self:updateItems(1)
end
function TouchMenu:backToUpperMenu(no_close)
@@ -808,68 +783,40 @@ function TouchMenu:backToUpperMenu(no_close)
if self.item_table.needs_refresh and self.item_table.refresh_func then
self.item_table = self.item_table.refresh_func()
end
self.page = 1
if self.parent_id then
self:_recalculatePageLayout() -- we need an accurate self.perpage
for i = 1, #self.item_table do
if self.item_table[i].menu_item_id == self.parent_id then
self.page = math.floor( (i - 1) / self.perpage ) + 1
break
end
end
self.parent_id = nil
end
self:updateItems()
self:updateItems(1, self.parent_id)
self.parent_id = nil
elseif not no_close then
self:closeMenu()
end
end
function TouchMenu:closeMenu()
self.close_callback()
function TouchMenu:onBack()
self:backToUpperMenu()
end
function TouchMenu:onNextPage()
if self.page < self.page_num then
self.page = self.page + 1
elseif self.page == self.page_num then
self.page = 1
end
self:updateItems()
return true
return self:onGotoPage(self.page + 1)
end
function TouchMenu:onPrevPage()
if self.page > 1 then
self.page = self.page - 1
elseif self.page == 1 then
self.page = self.page_num
end
self:updateItems()
return true
return self:onGotoPage(self.page - 1)
end
function TouchMenu:onFirstPage()
self.page = 1
self:updateItems()
return true
return self:onGotoPage(1)
end
function TouchMenu:onLastPage()
self.page = self.page_num
self:updateItems()
return true
return self:onGotoPage(self.page_num)
end
function TouchMenu:onGotoPage(nb)
if nb > self.page_num then
self.page = self.page_num
if nb > self.page_num then -- cycle by swipes only
nb = 1
elseif nb < 1 then
self.page = 1
else
self.page = nb
nb = self.page_num
end
self:updateItems()
self:updateItems(nb)
return true
end
@@ -937,18 +884,7 @@ function TouchMenu:onMenuSelect(item, tap_on_checkmark)
item.menu_item_id = item.menu_item_id or tostring(item) -- unique id
self.parent_id = item.menu_item_id
self.item_table = sub_item_table
self.page = 1
if self.item_table.open_on_menu_item_id_func then
self:_recalculatePageLayout() -- we need an accurate self.perpage
local open_id = self.item_table.open_on_menu_item_id_func()
for i = 1, #self.item_table do
if self.item_table[i].menu_item_id == open_id then
self.page = math.floor( (i - 1) / self.perpage ) + 1
break
end
end
end
self:updateItems()
self:updateItems(1, self.item_table.open_on_menu_item_id_func and self.item_table.open_on_menu_item_id_func())
end
end
return true
@@ -1000,6 +936,10 @@ function TouchMenu:onMenuHold(item, text_truncated)
return true
end
function TouchMenu:closeMenu()
self.close_callback()
end
function TouchMenu:onTapCloseAllMenus(arg, ges_ev)
if ges_ev.pos:notIntersectWith(self.dimen) then
self:closeMenu()
@@ -1010,8 +950,16 @@ function TouchMenu:onClose()
self:closeMenu()
end
function TouchMenu:onBack()
self:backToUpperMenu()
function TouchMenu:onCloseWidget()
-- NOTE: We don't pass a region in order to ensure a full-screen flash to avoid ghosting,
-- but we only need to do that if we actually have a FM or RD below us.
-- Don't do anything when we're switching between the two, or if we don't actually have a live instance of 'em...
local FileManager = require("apps/filemanager/filemanager")
local ReaderUI = require("apps/reader/readerui")
if (FileManager.instance and not FileManager.instance.tearing_down)
or (ReaderUI.instance and not ReaderUI.instance.tearing_down) then
UIManager:setDirty(nil, "flashui")
end
end
-- Menu search feature
@@ -1019,7 +967,7 @@ function TouchMenu:search(search_for)
local found_menu_items = {}
local MAX_MENU_DEPTH = 10 -- our menu max depth is currently 6
local function recurse(item_table, path, text, icon, depth, is_disabled)
local function recurse(item_table, path, text, icon, depth)
if item_table.ignored_by_menu_search then
return
end
@@ -1031,8 +979,7 @@ function TouchMenu:search(search_for)
if type(v) == "table" and not v.ignored_by_menu_search then
local entry_text = v.text_func and v.text_func() or v.text
local entry_displayed_text = entry_text
is_disabled = is_disabled or v.enabled == false or (v.enabled_func and v.enabled_func() == false)
if is_disabled then
if v.enabled == false or (v.enabled_func and v.enabled_func() == false) then
entry_displayed_text = "\u{2592}\u{200A}" .. entry_displayed_text -- Medium Shade (▒) + Hair Space
end
local indent = "\u{2192}\u{200A}" -- Rightwards Arrow (→) + Hair Space
@@ -1049,7 +996,7 @@ function TouchMenu:search(search_for)
sub_item_table = v.sub_item_table_func()
end
if sub_item_table and not sub_item_table.ignored_by_menu_search then
recurse(sub_item_table, walk_path, walk_text, icon, depth, is_disabled)
recurse(sub_item_table, walk_path, walk_text, icon, depth)
end
end
end
@@ -1171,10 +1118,9 @@ function TouchMenu:openMenu(path, with_animation)
end
end
elseif step == STEPS.MENU_ITEM_HIGHLIGHT then
local item_visible_index = (item_nb - 1) % self.perpage + 1
local item_widget
for i, w in ipairs(self.item_group) do
if w.item_visible_index == item_visible_index then
for _, w in ipairs(self.item_group) do
if w.item and w.item.idx == item_nb then
item_widget = w
break
end
@@ -1312,8 +1258,8 @@ function TouchMenu:onShowMenuSearch()
title = _("Search results"),
subtitle = T(_("Query: %1"), search_string),
item_table = get_current_search_results(),
width = math.floor(Screen:getWidth() * 0.9),
height = math.floor(Screen:getHeight() * 0.9),
width = math.floor(self.screen_size.w * 0.9),
height = math.floor(self.screen_size.h * 0.9),
single_line = true,
items_per_page = 10,
items_font_size = Menu.getItemFontSize(10),
@@ -1330,7 +1276,7 @@ function TouchMenu:onShowMenuSearch()
-- build container
self.results_menu_container = CenterContainer:new{
dimen = Screen:getSize(),
dimen = self.screen_size,
results_menu,
}