mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
touchmenu: optimize (#14027)
This commit is contained in:
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user