Another round of ReaderFooter fixes (#6830)

* When auto_refresh_time is enabled, don't actually refresh anything when the footer is hidden.
* Fix a bunch of state tracking related to height computations, meaning `getHeight()` is now actually accurate, always, and we don't need shitty workarounds anymore.
  * `footer_container.dimen.h` *includes* the progress bar, so, never reset it to 0 unless the progress bar is disabled (some `settings.progress_bar_position` codepaths were mistakenly doing just that).
  * More aggressively set/reset `footer_text.height` (not sure this one makes much of a difference, and/or if it's actually useful at all, but, the tracking was already there, but hella inconsistent, so, just fix it).
* Honor `settings.reclaim_height` in other bits of code that were only checking `footer_visible` to figure out the visible page area.
* Ask ReaderView to update the `visible_area` *now* when toggling the footer's visibility (for ReaderPaging).
pull/6837/head
NiLuJe 4 years ago committed by GitHub
parent c810a19040
commit a393137273
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -461,6 +461,7 @@ function ReaderFooter:init()
}
-- all width related values will be initialized in self:resetLayout()
self.text_width = 0
self.footer_text.height = 0
self.progress_bar = ProgressWidget:new{
width = nil,
height = nil,
@ -491,8 +492,10 @@ function ReaderFooter:init()
self.view.footer_visible = (self.mode ~= self.mode_list.off)
self:updateFooterTextGenerator()
if self.settings.progress_bar_position and self.has_no_mode then
self.footer_container.dimen.h = 0
self.footer_text.height = 0
if self.settings.disable_progress_bar then
self.footer_container.dimen.h = 0
end
end
else
self:applyFooterMode()
@ -500,6 +503,8 @@ function ReaderFooter:init()
if self.settings.auto_refresh_time then
self:setupAutoRefreshTime()
end
self.visibility_change = nil
end
function ReaderFooter:updateFooterContainer()
@ -581,7 +586,10 @@ function ReaderFooter:setupAutoRefreshTime()
self.autoRefreshTime = function()
-- Only actually repaint the footer if nothing's being shown over ReaderUI (#6616)
if UIManager:getTopWidget() == "ReaderUI" then
self:onUpdateFooter(true)
-- And that only if it's actually visible
if self.view.footer_visible then
self:onUpdateFooter(true)
end
else
logger.dbg("Skipping ReaderFooter repaint, because ReaderUI is not the top-level widget")
-- NOTE: We *do* keep its content up-to-date, though
@ -666,6 +674,8 @@ end
function ReaderFooter:getHeight()
if self.footer_content then
-- NOTE: self.footer_content is self.vertical_frame + self.bottom_padding,
-- self.vertical_frame includes self.text_container (which includes self.footer_text)
return self.footer_content:getSize().h
else
return 0
@ -805,7 +815,9 @@ function ReaderFooter:addToMainMenu(menu_items)
self.reclaim_height = self.settings.reclaim_height or false
-- refresh margins position
if self.has_no_mode then
self.footer_container.dimen.h = 0
if self.settings.disable_progress_bar then
self.footer_container.dimen.h = 0
end
self.footer_text.height = 0
should_signal = true
self.genFooterText = footerTextGeneratorMap.empty
@ -1777,22 +1789,27 @@ function ReaderFooter:_updateFooterText(force_repaint, force_recompute)
self.footer_text.height = 0
else
self.text_width = self.footer_text:getSize().w
self.footer_text.height = self.footer_text:getSize().h
end
self.progress_bar.width = 0
elseif self.settings.progress_bar_position then
if text == "" then
self.footer_container.dimen.h = 0
if self.has_no_mode or text == "" then
self.text_width = 0
self.footer_text.height = 0
else
self.text_width = self.footer_text:getSize().w
self.footer_text.height = self.footer_text:getSize().h
end
self.progress_bar.width = math.floor(self._saved_screen_width - 2 * self.settings.progress_margin_width)
self.text_width = self.footer_text:getSize().w
else
if self.has_no_mode or text == "" then
self.text_width = 0
self.footer_text.height = 0
else
local text_max_available_ratio = (100 - self.settings.progress_bar_min_width_pct) / 100
self.footer_text:setMaxWidth(math.floor(text_max_available_ratio * self._saved_screen_width - 2 * self.settings.progress_margin_width))
self.text_width = self.footer_text:getSize().w + self.text_left_margin
self.footer_text.height = self.footer_text:getSize().h
end
self.progress_bar.width = math.floor(
self._saved_screen_width - self.text_width - self.settings.progress_margin_width*2)
@ -1815,19 +1832,21 @@ function ReaderFooter:_updateFooterText(force_repaint, force_recompute)
-- NOTE: That's assuming using "fast" for pans was a good idea, which, it turned out, not so much ;).
-- NOTE: We skip repaints on page turns/pos update, as that's redundant (and slow).
if force_repaint then
-- If there was a visibility change, notify ReaderView
if self.visibility_change then
self.ui:handleEvent(Event:new("ReaderFooterVisibilityChange"))
self.visibility_change = nil
end
-- NOTE: Getting the dimensions of the widget is impossible without having drawn it first,
-- so, we'll fudge it if need be...
-- i.e., when it's no longer visible, because there's nothing to draw ;).
local refresh_dim = self.footer_content.dimen
-- No content yet...
if not refresh_dim then
-- So, instead, compute self.footer_content's height ourselves: i.e., self.vertical_frame + self.bottom_padding...
-- No more content...
if not self.view.footer_visible and not refresh_dim then
-- So, instead, rely on self:getHeight to compute self.footer_content's height early...
refresh_dim = self.dimen
if self.view.footer_visible then
refresh_dim.h = self.vertical_frame:getSize().h + self.bottom_padding
else
-- When going invisible, the text is no longer visible, so the frame's height is off by self.height
refresh_dim.h = self.vertical_frame:getSize().h + self.height + self.bottom_padding
end
refresh_dim.h = self:getHeight()
refresh_dim.y = self._saved_screen_height - refresh_dim.h
end
-- If we're making the footer visible (or it already is), we don't need to repaint ReaderUI behind it
@ -1835,11 +1854,13 @@ function ReaderFooter:_updateFooterText(force_repaint, force_recompute)
-- Unfortunately, it's not a modal (we never show() it), so it's not in the window stack,
-- instead, it's baked inside ReaderUI, so it gets slightly trickier...
-- NOTE: self.view.footer -> self ;).
UIManager:setDirty(self.view.footer, function()
return "ui", refresh_dim
end)
-- c.f., ReaderView:paintTo()
UIManager:widgetRepaint(self.view.footer, 0, 0)
-- We've painted it first to ensure self.footer_content.dimen is sane
UIManager:setDirty(self.view.footer, function()
return "ui", self.footer_content.dimen
end)
else
UIManager:setDirty(self.view.dialog, function()
return "ui", refresh_dim
@ -1944,6 +1965,8 @@ function ReaderFooter:applyFooterMode(mode)
self:updateFooterContainer()
-- NOTE: _updateFooterText does a resetLayout, but not a forced one!
self:resetLayout(true)
-- Flag _updateFooterText to notify ReaderView to recalculate the visible_area!
self.visibility_change = true
end
end

@ -133,7 +133,7 @@ function ReaderPageMap:updateVisibleLabels()
end
self.container:clear()
local page_labels = self.ui.document:getPageMapVisiblePageLabels()
local footer_height = (self.view.footer_visible and 1 or 0) * self.view.footer:getHeight()
local footer_height = ((self.view.footer_visible and not self.view.footer.settings.reclaim_height) and 1 or 0) * self.view.footer:getHeight()
local max_y = Screen:getHeight() - footer_height
local last_label_bottom_y = 0
for _, page in ipairs(page_labels) do

@ -693,7 +693,7 @@ end
function ReaderRolling:onGotoViewRel(diff)
logger.dbg("goto relative screen:", diff, ", in mode: ", self.view.view_mode)
if self.view.view_mode == "scroll" then
local footer_height = (self.view.footer_visible and 1 or 0) * self.view.footer:getHeight()
local footer_height = ((self.view.footer_visible and not self.view.footer.settings.reclaim_height) and 1 or 0) * self.view.footer:getHeight()
local page_visible_height = self.ui.dimen.h - footer_height
local pan_diff = diff * page_visible_height
if self.show_overlap_enable then
@ -869,7 +869,7 @@ function ReaderRolling:_gotoPos(new_pos, do_dim_area)
if new_pos > max_pos then new_pos = max_pos end
-- adjust dim_area according to new_pos
if self.view.view_mode ~= "page" and self.show_overlap_enable and do_dim_area then
local footer_height = (self.view.footer_visible and 1 or 0) * self.view.footer:getHeight()
local footer_height = ((self.view.footer_visible and not self.view.footer.settings.reclaim_height) and 1 or 0) * self.view.footer:getHeight()
local page_visible_height = self.ui.dimen.h - footer_height
local panned_step = new_pos - self.current_pos
self.view.dim_area.x = 0

@ -568,7 +568,7 @@ function ReaderView:recalculate()
self.state.rotation)
-- reset our size
self.visible_area:setSizeTo(self.dimen)
if self.ui.view.footer_visible then
if self.ui.view.footer_visible and not self.ui.view.footer.settings.reclaim_height then
self.visible_area.h = self.visible_area.h - self.ui.view.footer:getHeight()
end
if self.ui.document.configurable.writing_direction == 0 then
@ -594,7 +594,7 @@ function ReaderView:recalculate()
end
self.state.offset = Geom:new{x = 0, y = 0}
if self.dimen.h > self.visible_area.h then
if self.ui.view.footer_visible then
if self.ui.view.footer_visible and not self.ui.view.footer.settings.reclaim_height then
self.state.offset.y = (self.dimen.h - (self.visible_area.h + self.ui.view.footer:getHeight())) / 2
else
self.state.offset.y = (self.dimen.h - self.visible_area.h) / 2
@ -603,7 +603,7 @@ function ReaderView:recalculate()
if self.dimen.w > self.visible_area.w then
self.state.offset.x = (self.dimen.w - self.visible_area.w) / 2
end
-- flag a repaint so self:paintTo will be called
-- Flag a repaint so self:paintTo will be called
-- NOTE: This is also unfortunately called during panning, essentially making sure we'll never be using "fast" for pans ;).
UIManager:setDirty(self.dialog, "partial")
end
@ -791,6 +791,25 @@ function ReaderView:onRotationUpdate(rotation)
self:recalculate()
end
function ReaderView:onReaderFooterVisibilityChange()
-- Don't bother ReaderRolling with this nonsense, the footer's height is NOT handled via visible_area there ;)
if self.ui.document.info.has_pages and self.state.page then
-- NOTE: Simply relying on recalculate would be a wee bit too much: it'd reset the in-page offsets,
-- which would be wrong, and is also not necessary, since the footer is at the bottom of the screen ;).
-- So, simply mangle visible_area's height ourselves...
if not self.ui.view.footer.settings.reclaim_height then
-- NOTE: Yes, this means that toggling reclaim_height requires a page switch (for a proper recalculate).
-- Thankfully, most of the time, the quirks are barely noticeable ;).
if self.ui.view.footer_visible then
self.visible_area.h = self.visible_area.h - self.ui.view.footer:getHeight()
else
self.visible_area.h = self.visible_area.h + self.ui.view.footer:getHeight()
end
end
self.ui:handleEvent(Event:new("ViewRecalculate", self.visible_area, self.page_area))
end
end
function ReaderView:onGammaUpdate(gamma)
self.state.gamma = gamma
if self.page_scroll then

@ -263,7 +263,7 @@ function ReaderZooming:getZoom(pageno)
-- calculate zoom value:
local zoom_w = self.dimen.w
local zoom_h = self.dimen.h
if self.ui.view.footer_visible then
if self.ui.view.footer_visible and not self.ui.view.footer.settings.reclaim_height then
zoom_h = zoom_h - self.ui.view.footer:getHeight()
end
if self.rotation % 180 == 0 then

Loading…
Cancel
Save