From abcd989ec4ebc068501bfdd803ae4adde15f5a1f Mon Sep 17 00:00:00 2001 From: zwim <36999612+zwim@users.noreply.github.com> Date: Tue, 9 Nov 2021 18:04:44 +0100 Subject: [PATCH] [Status bar] Add custom text to footer (#8419) Allows to add any text to the status bar. Can be a placeholder (empty space) for better positioning of the indicators. --- frontend/apps/reader/modules/readerfooter.lua | 117 +++++++++++++++++- frontend/ui/widget/touchmenu.lua | 2 +- 2 files changed, 114 insertions(+), 5 deletions(-) diff --git a/frontend/apps/reader/modules/readerfooter.lua b/frontend/apps/reader/modules/readerfooter.lua index 34f05c906..13c9391d7 100644 --- a/frontend/apps/reader/modules/readerfooter.lua +++ b/frontend/apps/reader/modules/readerfooter.lua @@ -11,6 +11,7 @@ local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalSpan = require("ui/widget/horizontalspan") local LeftContainer = require("ui/widget/container/leftcontainer") local LineWidget = require("ui/widget/linewidget") +local MultiInputDialog = require("ui/widget/multiinputdialog") local ProgressWidget = require("ui/widget/progresswidget") local RightContainer = require("ui/widget/container/rightcontainer") local Size = require("ui/size") @@ -44,6 +45,7 @@ local MODE = { bookmark_count = 14, chapter_progress = 15, frontlight_warmth = 16, + custom_text = 17, } local symbol_prefix = { @@ -69,6 +71,8 @@ local symbol_prefix = { mem_usage = C_("FooterLetterPrefix", "M:"), -- @translators This is the footer letter prefix for Wi-Fi status. wifi_status = C_("FooterLetterPrefix", "W:"), + -- no prefix for custom text + custom_text = C_("FooterLetterPrefix", ""), }, icons = { time = "⌚", @@ -84,6 +88,7 @@ local symbol_prefix = { mem_usage = "", wifi_status = "", wifi_status_off = "", + custom_text = "", }, compact_items = { time = nil, @@ -101,6 +106,7 @@ local symbol_prefix = { mem_usage = C_("FooterCompactItemsPrefix", "M"), wifi_status = "", wifi_status_off = "", + custom_text = "", } } if BD.mirroredUILayout() then @@ -346,7 +352,7 @@ local footerTextGeneratorMap = { if statm then local dummy, rss = statm:read("*number", "*number") statm:close() - -- we got the nb of 4Kb-pages used, that we convert to Mb + -- we got the nb of 4Kb-pages used, that we convert to MiB rss = math.floor(rss * 4096 / 1024 / 1024) return (prefix .. " %d"):format(rss) end @@ -418,7 +424,15 @@ local footerTextGeneratorMap = { else return "" end - end + end, + custom_text = function(footer) + local symbol_type = footer.settings.item_prefix + local prefix = symbol_prefix[symbol_type].custom_text + -- if custom_text contains only spaces, request to merge it with the text before and after, + -- in other words, don't add a separator then. + local merge = footer.custom_text:gsub(" ", ""):len() == 0 + return (prefix .. footer.custom_text:rep(footer.custom_text_repetitions)), merge + end, } local ReaderFooter = WidgetContainer:extend{ @@ -605,8 +619,77 @@ function ReaderFooter:init() end self.visibility_change = nil + + self.custom_text = G_reader_settings:readSetting("reader_footer_custom_text", "KOReader") + self.custom_text_repetitions = + tonumber(G_reader_settings:readSetting("reader_footer_custom_text_repetitions", "1")) +end + +function ReaderFooter:set_custom_text(touchmenu_instance) + local text_dialog + text_dialog = MultiInputDialog:new{ + title = "Enter a custom text", + fields = { + { + text = self.custom_text or "", + description = _("Custom string:"), + input_type = "string", + }, + { + text = self.custom_text_repetitions, + description =_("Number of repetitions:"), + input_type = "number", + }, + }, + buttons = { + { + { + text = _("Cancel"), + callback = function() + UIManager:close(text_dialog) + end, + }, + { + text = _("Set"), + callback = function() + local inputs = MultiInputDialog:getFields() + local new_text, new_repetitions = inputs[1], inputs[2] + if new_text == "" then + new_text = " " + end + if self.custom_text ~= new_text then + self.custom_text = new_text + G_reader_settings:saveSetting("reader_footer_custom_text", + self.custom_text) + end + new_repetitions = tonumber(new_repetitions) or 1 + if new_repetitions < 1 then + new_repetitions = 1 + end + if new_repetitions and self.custom_text_repetitions ~= new_repetitions then + self.custom_text_repetitions = new_repetitions + G_reader_settings:saveSetting("reader_footer_custom_text_repetitions", + self.custom_text_repetitions) + end + UIManager:close(text_dialog) + self:refreshFooter(true, true) + if touchmenu_instance then touchmenu_instance:updateItems() end + end, + }, + }, + }, + } + UIManager:show(text_dialog) + text_dialog:onShowKeyboard() end +-- Help text string, or function, to be shown, or executed, on a long press on menu item +local option_help_text = {} +option_help_text[MODE.pages_left_book] = _("Can be configured to include or exclude the current page.") +option_help_text[MODE.percentage] = _("Progress percentage can be shown with zero, one or two decimal places.") +option_help_text[MODE.mem_usage] = _("Show memory usage in MiB.") +option_help_text[MODE.custom_text] = ReaderFooter.set_custom_text + function ReaderFooter:updateFooterContainer() local margin_span = HorizontalSpan:new{ width = self.horizontal_margin } self.vertical_frame = VerticalGroup:new{} @@ -896,6 +979,9 @@ function ReaderFooter:textOptionTitles(option) wifi_status = T(_("Wi-Fi status (%1)"), symbol_prefix[symbol].wifi_status), book_title = _("Book title"), book_chapter = _("Current chapter"), + custom_text = T(_("Custom text: \'%1\'%2"), self.custom_text, + self.custom_text_repetitions > 1 and + string.format(" × %d", self.custom_text_repetitions) or ""), } return option_titles[option] end @@ -930,6 +1016,12 @@ function ReaderFooter:addToMainMenu(menu_items) text_func = function() return self:textOptionTitles(option) end, + help_text = type(option_help_text[MODE[option]]) == "string" + and option_help_text[MODE[option]], + help_text_func = type(option_help_text[MODE[option]]) == "function" and + function(touchmenu_instance) + option_help_text[MODE[option]](self, touchmenu_instance) + end, checked_func = function() return self.settings[option] == true end, @@ -1812,6 +1904,7 @@ With this enabled, the current page is included, so the count goes from n to 1 i end table.insert(sub_items, getMinibarOption("book_title")) table.insert(sub_items, getMinibarOption("book_chapter")) + table.insert(sub_items, getMinibarOption("custom_text")) -- Settings menu: keep the same parent page for going up from submenu for i = 1, #sub_items[settings_submenu_num].sub_item_table do @@ -1841,16 +1934,28 @@ function ReaderFooter:genAllFooterText() -- 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 for _, gen in ipairs(self.footerTextGenerators) do -- Skip empty generators, so they don't generate bogus separators - local text = gen(self) + local text, merge = gen(self) if text and text ~= "" then 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 text = text:gsub("%s", "\xE2\x80\x8A") end - table.insert(info, BD.wrap(text)) + -- if generator request a merge of this item, add it directly, + -- i.e. no separator before and after the text then. + if merge then + local merge_pos = #info == 0 and 1 or #info + info[merge_pos] = (info[merge_pos] or "") .. text + prev_had_merge = true + elseif prev_had_merge then + info[#info] = info[#info] .. text + prev_had_merge = false + else + table.insert(info, BD.wrap(text)) + end end end return table.concat(info, BD.wrap(separator)) @@ -2336,4 +2441,8 @@ function ReaderFooter:onScreenResize() self:resetLayout(true) end +function ReaderFooter:onTimeFormatChanged() + self:refreshFooter(true, true) +end + return ReaderFooter diff --git a/frontend/ui/widget/touchmenu.lua b/frontend/ui/widget/touchmenu.lua index 59b8cc293..5dd63beb3 100644 --- a/frontend/ui/widget/touchmenu.lua +++ b/frontend/ui/widget/touchmenu.lua @@ -925,7 +925,7 @@ function TouchMenu:onMenuHold(item, text_truncated) elseif item.help_text or type(item.help_text_func) == "function" then local help_text = item.help_text if item.help_text_func then - help_text = item.help_text_func() + help_text = item.help_text_func(self) end if help_text then UIManager:show(InfoMessage:new{ text = help_text, })