Files
koreader/frontend/apps/reader/modules/readerfooter.lua
Hans-Werner Hilse 745e3837e0 updating the screen in tap handler of readerfooter is not needed
Was a hack anyway, c.f.
https://github.com/koreader/koreader/pull/1306#discussion_r21057461

Seems to be not needed anymore. If some areas are now not refreshed
anymore, that ought to be fixed in another place.

This also gets rid of redundant screen flashes.
2014-11-30 18:38:02 +00:00

292 lines
9.1 KiB
Lua

local InputContainer = require("ui/widget/container/inputcontainer")
local CenterContainer = require("ui/widget/container/centercontainer")
local RightContainer = require("ui/widget/container/rightcontainer")
local BottomContainer = require("ui/widget/container/bottomcontainer")
local FrameContainer = require("ui/widget/container/framecontainer")
local ProgressWidget = require("ui/widget/progresswidget")
local HorizontalGroup = require("ui/widget/horizontalgroup")
local TextWidget = require("ui/widget/textwidget")
local GestureRange = require("ui/gesturerange")
local UIManager = require("ui/uimanager")
local Device = require("device")
local Screen = require("device").screen
local Geom = require("ui/geometry")
local Event = require("ui/event")
local Font = require("ui/font")
local DEBUG = require("dbg")
local Blitbuffer = require("ffi/blitbuffer")
local ReaderFooter = InputContainer:new{
mode = 1,
visible = true,
pageno = nil,
pages = nil,
toc_level = 0,
max_ticks = 100,
progress_percentage = 0.0,
progress_text = nil,
text_font_face = "ffont",
text_font_size = DMINIBAR_FONT_SIZE,
bar_height = Screen:scaleBySize(DMINIBAR_HEIGHT),
height = Screen:scaleBySize(DMINIBAR_CONTAINER_HEIGHT),
padding = Screen:scaleBySize(10),
}
function ReaderFooter:init()
self.pageno = self.view.state.page
self.pages = self.view.document:getPageCount()
local text_default = ""
if DMINIBAR_ALL_AT_ONCE then
local info = {}
if DMINIBAR_BATTERY then
table.insert(info, "B:100%")
end
if DMINIBAR_TIME then
table.insert(info, "WW:WW")
end
if DMINIBAR_PAGES then
table.insert(info, "0000 / 0000")
end
if DMINIBAR_NEXT_CHAPTER then
table.insert(info, "=> 000")
end
text_default = table.concat(info, " | ")
else
text_default = string.format(" %d / %d ", self.pages, self.pages)
end
self.progress_text = TextWidget:new{
text = text_default,
face = Font:getFace(self.text_font_face, self.text_font_size),
}
local text_width = self.progress_text:getSize().w
local ticks_candidates = {}
if self.ui.toc and DMINIBAR_PROGRESS_MARKER then
local max_level = self.ui.toc:getMaxDepth()
for i = 0, -max_level, -1 do
local ticks = self.ui.toc:getTocTicks(i)
if #ticks < self.max_ticks then
table.insert(ticks_candidates, ticks)
end
end
-- find the finest toc ticks by sorting out the largest one
table.sort(ticks_candidates, function(a, b) return #a > #b end)
end
self.progress_bar = ProgressWidget:new{
width = math.floor(Screen:getWidth() - text_width - self.padding),
height = self.bar_height,
percentage = self.progress_percentage,
ticks = ticks_candidates[1] or {},
tick_width = DMINIBAR_TOC_MARKER_WIDTH,
last = self.pages,
}
local horizontal_group = HorizontalGroup:new{}
local bar_container = RightContainer:new{
dimen = Geom:new{ w = Screen:getWidth() - text_width, h = self.height },
self.progress_bar,
}
local text_container = CenterContainer:new{
dimen = Geom:new{ w = text_width, h = self.height },
self.progress_text,
}
if DMINIBAR_PROGRESSBAR then
table.insert(horizontal_group, bar_container)
end
table.insert(horizontal_group, text_container)
self[1] = BottomContainer:new{
dimen = Screen:getSize(),
BottomContainer:new{
dimen = Geom:new{w = Screen:getWidth(), h = self.height*2},
FrameContainer:new{
horizontal_group,
background = Blitbuffer.COLOR_WHITE,
bordersize = 0,
padding = 0,
}
}
}
self.dimen = self[1]:getSize()
self:updateFooterPage()
local range = Geom:new{
x = Screen:getWidth()*DTAP_ZONE_MINIBAR.x,
y = Screen:getHeight()*DTAP_ZONE_MINIBAR.y,
w = Screen:getWidth()*DTAP_ZONE_MINIBAR.w,
h = Screen:getHeight()*DTAP_ZONE_MINIBAR.h
}
if Device:isTouchDevice() then
self.ges_events = {
TapFooter = {
GestureRange:new{
ges = "tap",
range = range,
},
},
HoldFooter = {
GestureRange:new{
ges = "hold",
range = range,
},
},
}
end
self.mode = G_reader_settings:readSetting("reader_footer_mode") or self.mode
self:applyFooterMode()
end
function ReaderFooter:getBatteryInfo()
local powerd = Device:getPowerDevice()
--local state = powerd:isCharging() and -1 or powerd:getCapacity()
return "B:" .. powerd:getCapacity() .. "%"
end
function ReaderFooter:getTimeInfo()
return os.date("%H:%M")
end
function ReaderFooter:getProgressInfo()
return string.format("%d / %d", self.pageno, self.pages)
end
function ReaderFooter:getNextChapterInfo()
local left = self.ui.toc:getChapterPagesLeft(self.pageno, self.toc_level)
return "=> " .. (left and left or self.pages - self.pageno)
end
function ReaderFooter:updateFooterPage()
if type(self.pageno) ~= "number" then return end
self.progress_bar.percentage = self.pageno / self.pages
if DMINIBAR_ALL_AT_ONCE then
local info = {}
if DMINIBAR_BATTERY then
table.insert(info, self:getBatteryInfo())
end
if DMINIBAR_TIME then
table.insert(info, self:getTimeInfo())
end
if DMINIBAR_PAGES then
table.insert(info, self:getProgressInfo())
end
if DMINIBAR_NEXT_CHAPTER then
table.insert(info, self:getNextChapterInfo())
end
self.progress_text.text = table.concat(info, " | ")
else
local info = ""
if self.mode == 1 then
info = self:getProgressInfo()
elseif self.mode == 2 then
info = self:getTimeInfo()
elseif self.mode == 3 then
info = self:getNextChapterInfo()
elseif self.mode == 4 then
info = self:getBatteryInfo()
end
self.progress_text.text = info
end
end
function ReaderFooter:updateFooterPos()
if type(self.position) ~= "number" then return end
self.progress_bar.percentage = self.position / self.doc_height
if self.show_time then
self.progress_text.text = self:getTimeInfo()
else
local percentage = self.progress_bar.percentage
self.progress_text.text = string.format("%1.f", percentage*100) .. "%"
end
end
function ReaderFooter:onPageUpdate(pageno)
self.pageno = pageno
self.pages = self.view.document.info.number_of_pages
self:updateFooterPage()
end
function ReaderFooter:onPosUpdate(pos)
self.position = pos
self.doc_height = self.view.document.info.doc_height
self:updateFooterPos()
end
-- recalculate footer sizes when document page count is updated
function ReaderFooter:onUpdatePos()
UIManager:scheduleIn(0.1, function() self:init() end)
end
function ReaderFooter:applyFooterMode(mode)
-- three modes switcher for reader footer
-- 0 for footer off
-- 1 for footer page info
-- 2 for footer time info
-- 3 for footer next_chapter info
-- 4 for battery status
if mode ~= nil then self.mode = mode end
if self.mode == 0 then
self.view.footer_visible = false
else
self.view.footer_visible = true
end
end
function ReaderFooter:onEnterFlippingMode()
self.orig_mode = self.mode
self:applyFooterMode(1)
end
function ReaderFooter:onExitFlippingMode()
self:applyFooterMode(self.orig_mode)
end
function ReaderFooter:onTapFooter(arg, ges)
if self.view.flipping_visible then
local pos = ges.pos
local dimen = self.progress_bar.dimen
-- if reader footer is not drawn before the dimen value should be nil
if dimen then
local percentage = (pos.x - dimen.x)/dimen.w
self.ui:handleEvent(Event:new("GotoPercentage", percentage))
end
else
self.mode = (self.mode + 1) % 5
if DMINIBAR_ALL_AT_ONCE and (self.mode > 1) then
self.mode = 0
end
if (self.mode == 1) and not DMINIBAR_PAGES then
self.mode = 2
end
if (self.mode == 2) and not DMINIBAR_TIME then
self.mode = 3
end
if (self.mode == 3) and not DMINIBAR_NEXT_CHAPTER then
self.mode = 4
end
if (self.mode == 4) and not DMINIBAR_BATTERY then
self.mode = 0
end
self:applyFooterMode()
G_reader_settings:saveSetting("reader_footer_mode", self.mode)
end
if self.pageno then
self:updateFooterPage()
else
self:updateFooterPos()
end
return true
end
function ReaderFooter:onHoldFooter(arg, ges)
self.ui:handleEvent(Event:new("ShowGotoDialog"))
return true
end
function ReaderFooter:onSetStatusLine(status_line)
self.view.footer_visible = status_line == 1 and true or false
self.ui.document:setStatusLineProp(status_line)
self.ui:handleEvent(Event:new("UpdatePos"))
end
return ReaderFooter