mirror of
https://github.com/koreader/koreader
synced 2024-11-16 06:12:56 +00:00
21210800c1
Use both a whitelist for targeted widget repaints, a blacklist for no repaint at all, and a fallback for a full in-order ReaderUI repaint when unsure. Use a similar approach in ReaderHeader (i.e., prevent explicit refreshes while ReaderMenu is open). Re #9979, re #9768
216 lines
7.4 KiB
Lua
216 lines
7.4 KiB
Lua
local Device = require("device")
|
|
local Event = require("ui/event")
|
|
local PluginShare = require("pluginshare")
|
|
local UIManager = require("ui/uimanager")
|
|
local WidgetContainer = require("ui/widget/container/widgetcontainer")
|
|
local datetime = require("datetime")
|
|
local logger = require("logger")
|
|
local time = require("ui/time")
|
|
local _ = require("gettext")
|
|
local T = require("ffi/util").template
|
|
|
|
local AutoTurn = WidgetContainer:extend{
|
|
name = "autoturn",
|
|
is_doc_only = true,
|
|
autoturn_sec = 0,
|
|
autoturn_distance = 1,
|
|
enabled = false,
|
|
last_action_time = 0,
|
|
task = nil,
|
|
}
|
|
|
|
function AutoTurn:_enabled()
|
|
return self.enabled and self.autoturn_sec > 0
|
|
end
|
|
|
|
function AutoTurn:_schedule()
|
|
if not self:_enabled() then
|
|
logger.dbg("AutoTurn:_schedule is disabled")
|
|
return
|
|
end
|
|
|
|
local delay = self.last_action_time + time.s(self.autoturn_sec) - UIManager:getTime()
|
|
|
|
if delay <= 0 then
|
|
local top_wg = UIManager:getTopmostVisibleWidget() or {}
|
|
if top_wg.name == "ReaderUI" then
|
|
logger.dbg("AutoTurn: go to next page")
|
|
self.ui:handleEvent(Event:new("GotoViewRel", self.autoturn_distance))
|
|
self.last_action_time = UIManager:getTime()
|
|
end
|
|
logger.dbg("AutoTurn: schedule in", self.autoturn_sec)
|
|
UIManager:scheduleIn(self.autoturn_sec, self.task)
|
|
self.scheduled = true
|
|
else
|
|
local delay_s = time.to_number(delay)
|
|
logger.dbg("AutoTurn: schedule in", delay_s, "s")
|
|
UIManager:scheduleIn(delay_s, self.task)
|
|
self.scheduled = true
|
|
end
|
|
end
|
|
|
|
function AutoTurn:_unschedule()
|
|
PluginShare.pause_auto_suspend = false
|
|
if self.scheduled then
|
|
logger.dbg("AutoTurn: unschedule")
|
|
UIManager:unschedule(self.task)
|
|
self.scheduled = false
|
|
end
|
|
end
|
|
|
|
function AutoTurn:_start()
|
|
if self:_enabled() then
|
|
local now = UIManager:getTime()
|
|
logger.dbg("AutoTurn: start at", time.format_time(now))
|
|
PluginShare.pause_auto_suspend = true
|
|
self.last_action_time = now
|
|
self:_schedule()
|
|
|
|
local text
|
|
if self.autoturn_distance == 1 then
|
|
local time_string = datetime.secondsToClockDuration("modern", self.autoturn_sec, false, true, true, true)
|
|
text = T(_("Autoturn is now active and will automatically turn the page every %1."), time_string)
|
|
else
|
|
text = T(_("Autoturn is now active and will automatically scroll %1 % of the page every %2 seconds."),
|
|
self.autoturn_distance * 100,
|
|
self.autoturn_sec)
|
|
end
|
|
|
|
local InfoMessage = require("ui/widget/infomessage")
|
|
UIManager:show(InfoMessage:new{
|
|
text = text,
|
|
timeout = 3,
|
|
})
|
|
end
|
|
end
|
|
|
|
function AutoTurn:init()
|
|
UIManager.event_hook:registerWidget("InputEvent", self)
|
|
self.autoturn_sec = G_reader_settings:readSetting("autoturn_timeout_seconds", 0)
|
|
self.autoturn_distance = G_reader_settings:readSetting("autoturn_distance", 1)
|
|
self.enabled = G_reader_settings:isTrue("autoturn_enabled")
|
|
self.ui.menu:registerToMainMenu(self)
|
|
self.task = function()
|
|
self:_schedule()
|
|
end
|
|
self:_start()
|
|
end
|
|
|
|
function AutoTurn:onCloseWidget()
|
|
logger.dbg("AutoTurn: onCloseWidget")
|
|
self:_unschedule()
|
|
self.task = nil
|
|
end
|
|
|
|
function AutoTurn:onCloseDocument()
|
|
logger.dbg("AutoTurn: onCloseDocument")
|
|
self:_unschedule()
|
|
end
|
|
|
|
function AutoTurn:onInputEvent()
|
|
logger.dbg("AutoTurn: onInputEvent")
|
|
self.last_action_time = UIManager:getTime()
|
|
end
|
|
|
|
function AutoTurn:onEnterStandby()
|
|
self:_unschedule()
|
|
end
|
|
|
|
-- We do not want autoturn to turn pages during the suspend process.
|
|
-- Unschedule it and restart after resume.
|
|
function AutoTurn:onSuspend()
|
|
logger.dbg("AutoTurn: onSuspend")
|
|
self:_unschedule()
|
|
end
|
|
|
|
function AutoTurn:_onLeaveStandby()
|
|
self.last_action_time = self.last_action_time - Device.last_standby_time
|
|
|
|
-- We messed with last_action_time, so a complete reschedule has to be done.
|
|
if self:_enabled() then
|
|
self:_unschedule()
|
|
self:_schedule()
|
|
end
|
|
end
|
|
|
|
function AutoTurn:_onResume()
|
|
logger.dbg("AutoTurn: onResume")
|
|
self:_start()
|
|
end
|
|
|
|
function AutoTurn:addToMainMenu(menu_items)
|
|
menu_items.autoturn = {
|
|
sorting_hint = "navi",
|
|
text_func = function()
|
|
local time_string = datetime.secondsToClockDuration("modern", self.autoturn_sec, false, true, true, true)
|
|
return self:_enabled() and T(_("Autoturn: %1"), time_string) or _("Autoturn")
|
|
end,
|
|
checked_func = function() return self:_enabled() end,
|
|
callback = function(menu)
|
|
local DateTimeWidget = require("ui/widget/datetimewidget")
|
|
local autoturn_seconds = G_reader_settings:readSetting("autoturn_timeout_seconds", 30)
|
|
local autoturn_minutes = math.floor(autoturn_seconds * (1/60))
|
|
autoturn_seconds = autoturn_seconds % 60
|
|
local autoturn_spin = DateTimeWidget:new {
|
|
title_text = _("Autoturn time"),
|
|
info_text = _("Enter time in minutes and seconds."),
|
|
min = autoturn_minutes,
|
|
min_max = 60 * 24, -- maximum one day
|
|
min_default = 0,
|
|
sec = autoturn_seconds,
|
|
sec_default = 30,
|
|
keep_shown_on_apply = true,
|
|
ok_text = _("Set timeout"),
|
|
cancel_text = _("Disable"),
|
|
cancel_callback = function()
|
|
self.enabled = false
|
|
G_reader_settings:makeFalse("autoturn_enabled")
|
|
self:_unschedule()
|
|
menu:updateItems()
|
|
self.onResume = nil
|
|
self.onLeaveStandby = nil
|
|
end,
|
|
ok_always_enabled = true,
|
|
callback = function(t)
|
|
self.autoturn_sec = t.min * 60 + t.sec
|
|
G_reader_settings:saveSetting("autoturn_timeout_seconds", self.autoturn_sec)
|
|
self.enabled = true
|
|
G_reader_settings:makeTrue("autoturn_enabled")
|
|
self:_unschedule()
|
|
self:_start()
|
|
menu:updateItems()
|
|
self.onResume = self._onResume
|
|
self.onLeaveStandby = self._onLeaveStandby
|
|
end,
|
|
}
|
|
UIManager:show(autoturn_spin)
|
|
end,
|
|
hold_callback = function(menu)
|
|
local SpinWidget = require("ui/widget/spinwidget")
|
|
local curr_items = G_reader_settings:readSetting("autoturn_distance") or 1
|
|
local autoturn_spin = SpinWidget:new {
|
|
value = curr_items,
|
|
value_min = -20,
|
|
value_max = 20,
|
|
precision = "%.2f",
|
|
value_step = .1,
|
|
value_hold_step = .5,
|
|
ok_text = _("Set distance"),
|
|
title_text = _("Scrolling distance"),
|
|
callback = function(autoturn_spin)
|
|
self.autoturn_distance = autoturn_spin.value
|
|
G_reader_settings:saveSetting("autoturn_distance", autoturn_spin.value)
|
|
if self.enabled then
|
|
self:_unschedule()
|
|
self:_start()
|
|
end
|
|
menu:updateItems()
|
|
end,
|
|
}
|
|
UIManager:show(autoturn_spin)
|
|
end,
|
|
}
|
|
end
|
|
|
|
return AutoTurn
|