From 75f49b135f3dbd8af543f6dd47fd1094bbb75643 Mon Sep 17 00:00:00 2001 From: hius07 <62179190+hius07@users.noreply.github.com> Date: Thu, 1 May 2025 16:50:23 +0300 Subject: [PATCH] Status bar: dynamic filler (#13702) --- frontend/apps/reader/modules/readerfooter.lua | 61 +++++++++++++++++-- 1 file changed, 57 insertions(+), 4 deletions(-) diff --git a/frontend/apps/reader/modules/readerfooter.lua b/frontend/apps/reader/modules/readerfooter.lua index c63a8e797..36f73976e 100644 --- a/frontend/apps/reader/modules/readerfooter.lua +++ b/frontend/apps/reader/modules/readerfooter.lua @@ -49,6 +49,7 @@ local MODE = { custom_text = 17, book_author = 18, page_turning_inverted = 19, -- includes both page-turn-button and swipe-and-tap inversion + dynamic_filler = 20, } local symbol_prefix = { @@ -133,7 +134,8 @@ if BD.mirroredUILayout() then end -- functions that generates footer text for each mode -local footerTextGeneratorMap = { +local footerTextGeneratorMap +footerTextGeneratorMap = { empty = function() return "" end, frontlight = function(footer) local symbol_type = footer.settings.item_prefix @@ -412,6 +414,42 @@ local footerTextGeneratorMap = { local merge = footer.custom_text:gsub(" ", ""):len() == 0 return footer.custom_text:rep(footer.custom_text_repetitions), merge end, + dynamic_filler = function(footer) + local max_width = footer[1]:getSize().w - 2 * footer.horizontal_margin + -- when the filler is between other items, it replaces the separator + local text, is_filler_inside = footer:genAllFooterText(footerTextGeneratorMap.dynamic_filler) + local tmp = TextWidget:new{ + text = text, + face = footer.footer_text_face, + bold = footer.settings.text_font_bold, + } + local text_width = tmp:getSize().w + tmp:free() + if footer.separator_width == nil then + tmp = TextWidget:new{ + text = footer:genSeparator(), + face = footer.footer_text_face, + bold = footer.settings.text_font_bold, + } + footer.separator_width = tmp:getSize().w + tmp:free() + end + local separator_width = is_filler_inside and footer.separator_width or 0 + local filler_space = "\u{200A}" -- HAIR SPACE + if footer.filler_space_width == nil then + tmp = TextWidget:new{ + text = filler_space, + face = footer.footer_text_face, + bold = footer.settings.text_font_bold, + } + footer.filler_space_width = tmp:getSize().w + tmp:free() + end + local filler_nb = math.floor((max_width - text_width + separator_width) / footer.filler_space_width) + if filler_nb > 0 then + return filler_space:rep(filler_nb), true + end + end, } local ReaderFooter = WidgetContainer:extend{ @@ -980,6 +1018,7 @@ function ReaderFooter:textOptionTitles(option) custom_text = T(_("Custom text (long-press to edit): \'%1\'%2"), self.custom_text, self.custom_text_repetitions > 1 and string.format(" × %d", self.custom_text_repetitions) or ""), + dynamic_filler = _("Dynamic filler"), } return option_titles[option] end @@ -1372,6 +1411,7 @@ function ReaderFooter:addToMainMenu(menu_items) table.insert(footer_items, getMinibarOption("book_title")) table.insert(footer_items, getMinibarOption("book_chapter")) table.insert(footer_items, getMinibarOption("custom_text")) + table.insert(footer_items, getMinibarOption("dynamic_filler")) -- configure footer_items table.insert(sub_items, { @@ -1500,6 +1540,8 @@ With this feature enabled, the current page is factored in, resulting in the cou bold = self.settings.text_font_bold, } self.text_container[1] = self.footer_text + self.separator_width = nil + self.filler_space_width = nil self:refreshFooter(true, true) if touchmenu_instance then touchmenu_instance:updateItems() end end, @@ -1522,6 +1564,8 @@ With this feature enabled, the current page is factored in, resulting in the cou bold = self.settings.text_font_bold, } self.text_container[1] = self.footer_text + self.separator_width = nil + self.filler_space_width = nil self:refreshFooter(true, true) end, }, @@ -1823,6 +1867,7 @@ function ReaderFooter:genItemSeparatorMenuItems(value) end, callback = function() self.settings.items_separator = value + self.separator_width = nil self:refreshFooter(true) end, } @@ -1922,16 +1967,23 @@ function ReaderFooter:genSeparator() or (self.settings.item_prefix == "compact_items" and " " or " ") end -function ReaderFooter:genAllFooterText() +function ReaderFooter:genAllFooterText(gen_to_skip) local info = {} -- We need to BD.wrap() all items and separators, so we're -- sure they are laid out in our order (reversed in RTL), -- without ordering by the RTL Bidi algorithm. - local prev_had_merge + local count = 0 -- total number of visible items + local skipped_idx, prev_had_merge for _, gen in ipairs(self.footerTextGenerators) do + if gen == gen_to_skip then + count = count + 1 + skipped_idx = count + goto continue + end -- Skip empty generators, so they don't generate bogus separators local text, merge = gen(self) if text and text ~= "" then + count = count + 1 if self.settings.item_prefix == "compact_items" then -- remove whitespace from footer items if symbol_type is compact_items -- use a hair-space to avoid issues with RTL display @@ -1950,8 +2002,9 @@ function ReaderFooter:genAllFooterText() table.insert(info, BD.wrap(text)) end end + ::continue:: end - return table.concat(info, BD.wrap(self:genSeparator())) + return table.concat(info, BD.wrap(self:genSeparator())), skipped_idx ~= 1 and skipped_idx ~= count end function ReaderFooter:setTocMarkers(reset)