From ce7fcff3608cd3f4ee24898b82a3c2e680f202c3 Mon Sep 17 00:00:00 2001 From: hius07 <62179190+hius07@users.noreply.github.com> Date: Sun, 13 Oct 2024 18:02:51 +0300 Subject: [PATCH] Menu widget: draw focus on focused item (#12583) --- frontend/ui/widget/focusmanager.lua | 8 +++++- frontend/ui/widget/menu.lua | 28 +++++++++++++++----- plugins/coverbrowser.koplugin/covermenu.lua | 7 +---- plugins/coverbrowser.koplugin/listmenu.lua | 5 ++++ plugins/coverbrowser.koplugin/mosaicmenu.lua | 5 ++++ 5 files changed, 40 insertions(+), 13 deletions(-) diff --git a/frontend/ui/widget/focusmanager.lua b/frontend/ui/widget/focusmanager.lua index 9968d022f..ad0b6c9de 100644 --- a/frontend/ui/widget/focusmanager.lua +++ b/frontend/ui/widget/focusmanager.lua @@ -299,6 +299,8 @@ FocusManager.NOT_UNFOCUS = 1 FocusManager.NOT_FOCUS = 2 -- In some cases, we may only want to send Focus events on non-Touch devices FocusManager.FOCUS_ONLY_ON_NT = (Device:hasDPad() and not Device:isTouchDevice()) and 0 or FocusManager.NOT_FOCUS +-- And in some cases, we may want to send both events *regardless* of heuristics or device caps +FocusManager.FORCED_FOCUS = 4 --- Move focus to specified widget function FocusManager:moveFocusTo(x, y, focus_flags) @@ -319,7 +321,11 @@ function FocusManager:moveFocusTo(x, y, focus_flags) self.selected.x = x self.selected.y = y -- widget create new layout on update, previous may be removed from new layout. - if Device:hasDPad() then + if bit.band(focus_flags, FocusManager.FORCED_FOCUS) == FocusManager.FORCED_FOCUS or Device:hasDPad() then + -- If FORCED_FOCUS was requested, we want *all* the events: mask out both NOT_ bits + if bit.band(focus_flags, FocusManager.FORCED_FOCUS) == FocusManager.FORCED_FOCUS then + focus_flags = bit.band(focus_flags, bit.bnot(bit.bor(FocusManager.NOT_UNFOCUS, FocusManager.NOT_FOCUS))) + end if bit.band(focus_flags, FocusManager.NOT_UNFOCUS) ~= FocusManager.NOT_UNFOCUS then -- NOTE: We can't necessarily guarantee the integrity of self.layout, -- as some callers *will* mangle it and call us expecting to fix things ;). diff --git a/frontend/ui/widget/menu.lua b/frontend/ui/widget/menu.lua index 2fa344a77..348fc71eb 100644 --- a/frontend/ui/widget/menu.lua +++ b/frontend/ui/widget/menu.lua @@ -995,11 +995,23 @@ end function Menu:updatePageInfo(select_number) if #self.item_table > 0 then - if Device:hasDPad() then + local is_focused = self.itemnumber and self.itemnumber > 0 + if is_focused or Device:hasDPad() then + self.itemnumber = nil -- focus only once + select_number = select_number or 1 -- default to select the first item + local x, y + local nb_cols = self.layout[1] and #self.layout[1] or 1 + if nb_cols == 1 then + x = 1 + y = select_number + else -- mosaic + x = select_number % nb_cols + y = (select_number - x) / nb_cols + 1 + end -- Reset focus manager accordingly. -- NOTE: Since this runs automatically on init, -- we use FOCUS_ONLY_ON_NT as we don't want to see the initial underline on Touch devices. - self:moveFocusTo(1, select_number, FocusManager.FOCUS_ONLY_ON_NT) + self:moveFocusTo(x, y, is_focused and FocusManager.FORCED_FOCUS or FocusManager.FOCUS_ONLY_ON_NT) end -- update page information self.page_info_text:setText(T(_("Page %1 of %2"), self.page, self.page_num)) @@ -1040,10 +1052,6 @@ function Menu:updateItems(select_number, no_recalculate_dimen) self.return_button:resetLayout() self.content_group:resetLayout() self:_recalculateDimen(no_recalculate_dimen) - -- default to select the first item - if not select_number then - select_number = 1 - end local items_nb -- number of items in the visible page local idx_offset, multilines_show_more_text @@ -1063,6 +1071,9 @@ function Menu:updateItems(select_number, no_recalculate_dimen) local item = self.item_table[index] if item == nil then break end item.idx = index -- index is valid only for items that have been displayed + if index == self.itemnumber then -- focused item + select_number = idx + end local item_shortcut, shortcut_style if self.is_enable_shortcut then item_shortcut = self.item_shortcuts[idx] @@ -1189,7 +1200,12 @@ function Menu:switchItemTable(new_title, new_item_table, itemnumber, itemmatch, if itemnumber == nil then self.page = 1 elseif itemnumber >= 0 then + itemnumber = math.min(itemnumber, #self.item_table) self.page = self:getPageNumber(itemnumber) + -- Draw the focus in FileChooser when it has focused_path (i.e. itemmatch) + if self.path ~= nil and type(itemmatch) == "table" then + self.itemnumber = itemnumber + end end self:updateItems(1, no_recalculate_dimen) diff --git a/plugins/coverbrowser.koplugin/covermenu.lua b/plugins/coverbrowser.koplugin/covermenu.lua index 88a70ee0f..8e924b320 100644 --- a/plugins/coverbrowser.koplugin/covermenu.lua +++ b/plugins/coverbrowser.koplugin/covermenu.lua @@ -91,10 +91,6 @@ function CoverMenu:updateItems(select_number, no_recalculate_dimen) self.page_info:resetLayout() self.return_button:resetLayout() self.content_group:resetLayout() - -- default to select the first item - if not select_number then - select_number = 1 - end -- Reset the list of items not found in db that will need to -- be updated by a scheduled action @@ -131,8 +127,7 @@ function CoverMenu:updateItems(select_number, no_recalculate_dimen) -- Specific UI building implementation (defined in some other module) self._has_cover_images = false - self:_updateItemsBuildUI() - + select_number = self:_updateItemsBuildUI() or select_number -- Set the local variables with the things we know -- These are used only by extractBooksInDirectory(), which should -- use the cover_specs set for FileBrowser, and not those from History. diff --git a/plugins/coverbrowser.koplugin/listmenu.lua b/plugins/coverbrowser.koplugin/listmenu.lua index da8f838b7..ba43e42eb 100644 --- a/plugins/coverbrowser.koplugin/listmenu.lua +++ b/plugins/coverbrowser.koplugin/listmenu.lua @@ -981,11 +981,15 @@ function ListMenu:_updateItemsBuildUI() } table.insert(self.item_group, line_widget) local idx_offset = (self.page - 1) * self.perpage + local select_number for idx = 1, self.perpage do local index = idx_offset + idx local entry = self.item_table[index] if entry == nil then break end entry.idx = index + if index == self.itemnumber then -- focused item + select_number = idx + end -- Keyboard shortcuts, as done in Menu local item_shortcut, shortcut_style if self.is_enable_shortcut then @@ -1020,6 +1024,7 @@ function ListMenu:_updateItemsBuildUI() end end + return select_number end return ListMenu diff --git a/plugins/coverbrowser.koplugin/mosaicmenu.lua b/plugins/coverbrowser.koplugin/mosaicmenu.lua index 796951539..511f08ed9 100644 --- a/plugins/coverbrowser.koplugin/mosaicmenu.lua +++ b/plugins/coverbrowser.koplugin/mosaicmenu.lua @@ -959,11 +959,15 @@ function MosaicMenu:_updateItemsBuildUI() local cur_row = nil local idx_offset = (self.page - 1) * self.perpage local line_layout = {} + local select_number for idx = 1, self.perpage do local index = idx_offset + idx local entry = self.item_table[index] if entry == nil then break end entry.idx = index + if index == self.itemnumber then -- focused item + select_number = idx + end -- Keyboard shortcuts, as done in Menu local item_shortcut, shortcut_style if self.is_enable_shortcut then @@ -1017,6 +1021,7 @@ function MosaicMenu:_updateItemsBuildUI() end table.insert(self.layout, line_layout) table.insert(self.item_group, VerticalSpan:new{ width = self.item_margin }) -- bottom padding + return select_number end return MosaicMenu