From c5d606a7f4ade12b79c4dcb3a2ebc37d962f2ba6 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Fri, 17 Feb 2023 00:37:30 +0100 Subject: [PATCH] ProgressWidget: Add an optional marker on the initial position (#10114) * Enable it on SkimToWidget * Optional on ReaderFooter (toggle in the progress bar > style submenu) --- frontend/apps/reader/modules/readerfooter.lua | 28 ++++-- frontend/ui/widget/progresswidget.lua | 71 +++++++++++++++ frontend/ui/widget/skimtowidget.lua | 3 + resources/icons/mdlight/position.marker.svg | 86 +++++++++++++++++++ .../icons/mdlight/position.marker.top.svg | 57 ++++++++++++ 5 files changed, 240 insertions(+), 5 deletions(-) create mode 100644 resources/icons/mdlight/position.marker.svg create mode 100644 resources/icons/mdlight/position.marker.top.svg diff --git a/frontend/apps/reader/modules/readerfooter.lua b/frontend/apps/reader/modules/readerfooter.lua index 0a23a5ba5..8cf06c6dd 100644 --- a/frontend/apps/reader/modules/readerfooter.lua +++ b/frontend/apps/reader/modules/readerfooter.lua @@ -437,7 +437,6 @@ local ReaderFooter = WidgetContainer:extend{ mode = MODE.page_progress, pageno = nil, pages = nil, - progress_percentage = 0.0, footer_text = nil, text_font_face = "ffont", height = Screen:scaleBySize(G_defaults:readSetting("DMINIBAR_CONTAINER_HEIGHT")), @@ -496,6 +495,7 @@ ReaderFooter.default_settings = { progress_pct_format = "0", progress_margin = false, pages_left_includes_current_page = false, + initial_marker = false, } function ReaderFooter:init() @@ -584,10 +584,11 @@ function ReaderFooter:init() self.progress_bar = ProgressWidget:new{ width = nil, height = nil, - percentage = self.progress_percentage, + percentage = nil, tick_width = Screen:scaleBySize(self.settings.toc_markers_width), ticks = nil, -- ticks will be populated in self:updateFooterText last = nil, -- last will be initialized in self:updateFooterText + initial_pos_marker = self.settings.initial_marker, } if self.settings.progress_style_thin then @@ -1840,6 +1841,17 @@ With this enabled, the current page is included, so the count goes from n to 1 i }, }, }, + { + text = _("Show initial position marker"), + checked_func = function() + return self.settings.initial_marker == true + end, + callback = function() + self.settings.initial_marker = not self.settings.initial_marker + self.progress_bar.initial_pos_marker = self.settings.initial_marker + self:refreshFooter(true) + end + }, }, }, { @@ -2120,16 +2132,16 @@ function ReaderFooter:updateFooterPage(force_repaint, full_repaint) local flow = self.ui.document:getPageFlow(self.pageno) local page = self.ui.document:getPageNumberInFlow(self.pageno) local pages = self.ui.document:getTotalPagesInFlow(flow) - self.progress_bar.percentage = page / pages + self.progress_bar:setPercentage(page / pages) else - self.progress_bar.percentage = self.pageno / self.pages + self.progress_bar:setPercentage(self.pageno / self.pages) end self:updateFooterText(force_repaint, full_repaint) end function ReaderFooter:updateFooterPos(force_repaint, full_repaint) if type(self.position) ~= "number" then return end - self.progress_bar.percentage = self.position / self.doc_height + self.progress_bar:setPercentage(self.position / self.doc_height) self:updateFooterText(force_repaint, full_repaint) end @@ -2466,6 +2478,8 @@ end function ReaderFooter:onSuspend() self:unscheduleFooterAutoRefresh() + -- Reset the initial marker + self.progress_bar.inital_percentage = nil end ReaderFooter.onEnterStandby = ReaderFooter.onSuspend @@ -2527,4 +2541,8 @@ function ReaderFooter:onTimeFormatChanged() self:refreshFooter(true, true) end +function ReaderFooter:onCloseWidget() + self:free() +end + return ReaderFooter diff --git a/frontend/ui/widget/progresswidget.lua b/frontend/ui/widget/progresswidget.lua index 1b31e0860..fbd00a47f 100644 --- a/frontend/ui/widget/progresswidget.lua +++ b/frontend/ui/widget/progresswidget.lua @@ -31,9 +31,14 @@ Example: local BD = require("ui/bidi") local Blitbuffer = require("ffi/blitbuffer") local Geom = require("ui/geometry") +local IconWidget = require("ui/widget/iconwidget") +local Math = require("optmath") local Widget = require("ui/widget/widget") local Screen = require("device").screen +-- Somewhat empirically chosen threshold to switch between the two designs ;o) +local INITIAL_MARKER_HEIGHT_THRESHOLD = Screen:scaleBySize(12) + local ProgressWidget = Widget:extend{ width = nil, height = nil, @@ -54,8 +59,51 @@ local ProgressWidget = Widget:extend{ alt = nil, -- table with alternate pages to mark with different color (in the form {{ini1, len1}, {ini2, len2}, ...}) _orig_margin_v = nil, _orig_bordersize = nil, + initial_pos_marker = false, -- overlay a marker at the initial percentage position + inital_percentage = nil, } +function ProgressWidget:init() + if self.initial_pos_marker then + if not self.inital_percentage then + self.inital_percentage = self.percentage + end + + self:renderMarkerIcon() + end +end + +function ProgressWidget:renderMarkerIcon() + if not self.initial_pos_marker then + return + end + + if self.initial_pos_icon then + self.initial_pos_icon:free() + end + + -- Can't do anything if we don't have a proper height yet... + if not self.height then + return + end + + if self.height <= INITIAL_MARKER_HEIGHT_THRESHOLD then + self.initial_pos_icon = IconWidget:new{ + icon = "position.marker.top", + width = Math.round(self.height / 2), + height = Math.round(self.height / 2), + alpha = true, + } + else + self.initial_pos_icon = IconWidget:new{ + icon = "position.marker", + width = self.height, + height = self.height, + alpha = true, + } + end +end + function ProgressWidget:getSize() return { w = self.width, h = self.height } end @@ -127,6 +175,15 @@ function ProgressWidget:paintTo(bb, x, y) math.ceil(fill_width * self.percentage), math.ceil(fill_height), self.fillcolor) + + -- Overlay the initial position marker on top of that + if self.initial_pos_marker then + if self.height <= INITIAL_MARKER_HEIGHT_THRESHOLD then + self.initial_pos_icon:paintTo(bb, Math.round(fill_x + math.ceil(fill_width * self.inital_percentage) - self.height / 4), y - Math.round(self.height / 6)) + else + self.initial_pos_icon:paintTo(bb, Math.round(fill_x + math.ceil(fill_width * self.inital_percentage) - self.height / 2), y) + end + end end -- ...then the tick(s). @@ -149,6 +206,11 @@ end function ProgressWidget:setPercentage(percentage) self.percentage = percentage + if self.initial_pos_marker then + if not self.inital_percentage then + self.inital_percentage = self.percentage + end + end end function ProgressWidget:getPercentageFromPosition(pos) @@ -178,6 +240,9 @@ function ProgressWidget:setHeight(height) self.margin_v = math.max(self.margin_v, margin_v_min) self.bordersize = math.min(self._orig_bordersize, math.floor((self.height - 2*self.margin_v - 1) / 2)) self.bordersize = math.max(self.bordersize, bordersize_min) + + -- Re-render marker, if any + self:renderMarkerIcon() end function ProgressWidget:updateStyle(thick, height) @@ -209,4 +274,10 @@ function ProgressWidget:updateStyle(thick, height) end end +function ProgressWidget:free() + if self.initial_pos_icon then + self.initial_pos_icon:free() + end +end + return ProgressWidget diff --git a/frontend/ui/widget/skimtowidget.lua b/frontend/ui/widget/skimtowidget.lua index b870fe853..720918dc9 100644 --- a/frontend/ui/widget/skimtowidget.lua +++ b/frontend/ui/widget/skimtowidget.lua @@ -71,6 +71,7 @@ function SkimToWidget:init() tick_width = Size.line.medium, last = self.page_count, alt = self.ui.document.flows, + initial_pos_marker = true, } -- Bottom row buttons @@ -335,6 +336,8 @@ function SkimToWidget:onCloseWidget() UIManager:setDirty(nil, function() return "ui", self.skimto_frame.dimen end) + + self:free() end function SkimToWidget:onShow() diff --git a/resources/icons/mdlight/position.marker.svg b/resources/icons/mdlight/position.marker.svg new file mode 100644 index 000000000..d017ed851 --- /dev/null +++ b/resources/icons/mdlight/position.marker.svg @@ -0,0 +1,86 @@ + +image/svg+xml + + diff --git a/resources/icons/mdlight/position.marker.top.svg b/resources/icons/mdlight/position.marker.top.svg new file mode 100644 index 000000000..cff5d8cac --- /dev/null +++ b/resources/icons/mdlight/position.marker.top.svg @@ -0,0 +1,57 @@ + +image/svg+xml + +