ProgressWidget: Add an optional marker on the initial position (#10114)

* Enable it on SkimToWidget
* Optional on ReaderFooter (toggle in the progress bar > style submenu)
pull/8739/head
NiLuJe 1 year ago committed by GitHub
parent 81f2aed086
commit c5d606a7f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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

@ -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

@ -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()

@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
width="48"
height="48"
viewBox="0 0 48 48"
enable-background="new 0 0 76.00 76.00"
xml:space="preserve"
id="svg4"
sodipodi:docname="position.marker.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata
id="metadata10"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
id="defs8" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1381"
id="namedview6"
showgrid="true"
inkscape:zoom="21"
inkscape:cx="22.404762"
inkscape:cy="24.047619"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:document-rotation="0"
inkscape:snap-page="true"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"><inkscape:grid
type="xygrid"
id="grid835"
originx="0"
originy="0" /></sodipodi:namedview>
<path
sodipodi:type="star"
style="fill:#000000;fill-opacity:0.80000001;fill-rule:evenodd"
id="path1002"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="6"
sodipodi:cy="6"
sodipodi:r1="16.552944"
sodipodi:r2="8.276473"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 20.33527,14.276472 -28.6705402,0 14.3352703,-24.829416 z"
inkscape:transform-center-y="-4.0000005"
transform="matrix(0.96659542,0,0,0.96659542,18.200427,43.200428)" /><path
sodipodi:type="star"
style="fill:#000000;fill-opacity:0.80000001;fill-rule:evenodd"
id="path1136"
inkscape:flatsided="true"
sodipodi:sides="3"
sodipodi:cx="6"
sodipodi:cy="6"
sodipodi:r1="16.552944"
sodipodi:r2="8.276473"
sodipodi:arg1="0.52359878"
sodipodi:arg2="1.5707963"
inkscape:rounded="0"
inkscape:randomized="0"
d="m 20.33527,14.276472 -28.6705402,0 14.3352703,-24.829416 z"
transform="matrix(-0.96659542,0,0,-0.96659542,29.799573,4.7995726)"
inkscape:transform-center-y="4.000001" /></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
version="1.1"
width="48"
height="48"
viewBox="0 0 48 48"
enable-background="new 0 0 76.00 76.00"
xml:space="preserve"
id="svg4"
sodipodi:docname="position.marker.top.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"><metadata
id="metadata10"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs8" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1381"
id="namedview6"
showgrid="true"
inkscape:zoom="22.627417"
inkscape:cx="22.561126"
inkscape:cy="24.925514"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg4"
inkscape:document-rotation="0"
inkscape:snap-page="true"
inkscape:showpageshadow="2"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"><inkscape:grid
type="xygrid"
id="grid835"
originx="0"
originy="0" /></sodipodi:namedview>
<path
style="fill:#000000;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1"
d="M 0,0 24,48 48,0 Z"
id="path298" /></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

Loading…
Cancel
Save