From 4cdc3ab99bc88d09cbf0f47b7f299a8126a1cfaf Mon Sep 17 00:00:00 2001 From: Frans de Jonge Date: Sun, 1 Sep 2019 21:30:19 +0200 Subject: [PATCH] [feat, plugin] Add AutoTurn (#5295) Fixes . --- .../apps/reader/modules/readerrolling.lua | 6 + frontend/ui/elements/reader_menu_order.lua | 1 + frontend/ui/uimanager.lua | 5 + frontend/ui/widget/spinwidget.lua | 4 + plugins/autoturn.koplugin/_meta.lua | 10 + plugins/autoturn.koplugin/main.lua | 178 ++++++++++++++++++ 6 files changed, 204 insertions(+) create mode 100644 plugins/autoturn.koplugin/_meta.lua create mode 100644 plugins/autoturn.koplugin/main.lua diff --git a/frontend/apps/reader/modules/readerrolling.lua b/frontend/apps/reader/modules/readerrolling.lua index b3a17d8c0..49933ed44 100644 --- a/frontend/apps/reader/modules/readerrolling.lua +++ b/frontend/apps/reader/modules/readerrolling.lua @@ -645,6 +645,12 @@ function ReaderRolling:onGotoViewRel(diff) elseif self.view.view_mode == "page" then local page_count = self.ui.document:getVisiblePageCount() local old_page = self.current_page + -- we're in paged mode, so round up + if diff > 0 then + diff = math.ceil(diff) + else + diff = math.floor(diff) + end self:_gotoPage(self.current_page + diff*page_count) if diff > 0 and old_page == self.current_page then self.ui:handleEvent(Event:new("EndOfBook")) diff --git a/frontend/ui/elements/reader_menu_order.lua b/frontend/ui/elements/reader_menu_order.lua index 78339f956..678b91833 100644 --- a/frontend/ui/elements/reader_menu_order.lua +++ b/frontend/ui/elements/reader_menu_order.lua @@ -18,6 +18,7 @@ local order = { "----------------------------", "go_to", "skim_to", + "autoturn", "----------------------------", "go_to_previous_location", }, diff --git a/frontend/ui/uimanager.lua b/frontend/ui/uimanager.lua index 81792c67e..3b58ac75e 100644 --- a/frontend/ui/uimanager.lua +++ b/frontend/ui/uimanager.lua @@ -621,6 +621,11 @@ function UIManager:getRefreshRate(rate) return self.FULL_REFRESH_COUNT end +--- Get top widget. +function UIManager:getTopWidget() + return ((self._window_stack[#self._window_stack] or {}).widget or {}).name +end + --- Signals to quit. function UIManager:quit() if not self._running then return end diff --git a/frontend/ui/widget/spinwidget.lua b/frontend/ui/widget/spinwidget.lua index 29900c0c2..ec348cac3 100644 --- a/frontend/ui/widget/spinwidget.lua +++ b/frontend/ui/widget/spinwidget.lua @@ -110,6 +110,10 @@ function SpinWidget:update() { text = self.cancel_text, callback = function() + if self.cancel_callback then + self.value = value_widget:getValue() + self:cancel_callback(self) + end self:onClose() end, }, diff --git a/plugins/autoturn.koplugin/_meta.lua b/plugins/autoturn.koplugin/_meta.lua new file mode 100644 index 000000000..43dafcc1e --- /dev/null +++ b/plugins/autoturn.koplugin/_meta.lua @@ -0,0 +1,10 @@ +local _ = require("gettext") +return { + name = "autoturn", + fullname = _("Autoturn"), + description = _([[ +Automatically turns the page after a set period of time. + +Hold to set the scrolling distance.]]), + sorting_hint = "navi", +} diff --git a/plugins/autoturn.koplugin/main.lua b/plugins/autoturn.koplugin/main.lua new file mode 100644 index 000000000..432e8656a --- /dev/null +++ b/plugins/autoturn.koplugin/main.lua @@ -0,0 +1,178 @@ +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 logger = require("logger") +local _ = require("gettext") +local T = require("ffi/util").template + +local AutoTurn = WidgetContainer:new{ + name = 'autoturn', + is_doc_only = true, + autoturn_sec = G_reader_settings:readSetting("autoturn_timeout_seconds") or 0, + autoturn_distance = G_reader_settings:readSetting("autoturn_distance") or 1, + enabled = G_reader_settings:isTrue("autoturn_enabled"), + settings_id = 0, + last_action_sec = os.time(), +} + +function AutoTurn:_enabled() + return self.enabled and self.autoturn_sec > 0 +end + +function AutoTurn:_schedule(settings_id) + if not self:_enabled() then + logger.dbg("AutoTurn:_schedule is disabled") + return + end + if self.settings_id ~= settings_id then + logger.dbg("AutoTurn:_schedule registered settings_id ", + settings_id, + " does not equal to current one ", + self.settings_id) + return + end + + local delay = self.last_action_sec + self.autoturn_sec - os.time() + + if delay <= 0 then + if UIManager:getTopWidget() == "ReaderUI"then + logger.dbg("AutoTurn: go to next page") + self.ui:handleEvent(Event:new("GotoViewRel", self.autoturn_distance)) + end + logger.dbg("AutoTurn: schedule at ", os.time() + self.autoturn_sec) + UIManager:scheduleIn(self.autoturn_sec, function() self:_schedule(settings_id) end) + else + logger.dbg("AutoTurn: schedule at ", os.time() + delay) + UIManager:scheduleIn(delay, function() self:_schedule(settings_id) end) + end +end + +function AutoTurn:_deprecateLastTask() + PluginShare.pause_auto_suspend = false + self.settings_id = self.settings_id + 1 + logger.dbg("AutoTurn: deprecateLastTask ", self.settings_id) +end + +function AutoTurn:_start() + if self:_enabled() then + logger.dbg("AutoTurn: start at ", os.time()) + PluginShare.pause_auto_suspend = true + self.last_action_sec = os.time() + self:_schedule(self.settings_id) + + local text + if self.autoturn_distance == 1 then + text = T(_("Autoturn is now active and will automatically turn the page every %1 seconds."), + self.autoturn_sec) + 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 = self.settings + self.ui.menu:registerToMainMenu(self) + self:_deprecateLastTask() + self:_start() +end + +function AutoTurn:onCloseDocument() + logger.dbg("AutoTurn: onCloseDocument") + self:_deprecateLastTask() +end + +function AutoTurn:onInputEvent() + logger.dbg("AutoTurn: onInputEvent") + self.last_action_sec = os.time() +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:_deprecateLastTask() +end + +function AutoTurn:onResume() + logger.dbg("AutoTurn: onResume") + self:_start() +end + +function AutoTurn:addToMainMenu(menu_items) + menu_items.autoturn = { + text_func = function() return self:_enabled() and T(_("Autoturn (%1 s)"), self.autoturn_sec) + or _("Autoturn") end, + checked_func = function() return self:_enabled() end, + callback = function(menu) + local Screen = Device.screen + local SpinWidget = require("ui/widget/spinwidget") + local curr_items = G_reader_settings:readSetting("autoturn_timeout_seconds") or 30 + local autoturn_spin = SpinWidget:new { + width = Screen:getWidth() * 0.6, + value = curr_items, + value_min = 0, + value_max = 240, + value_hold_step = 5, + ok_text = _("Set timeout"), + cancel_text = _("Disable"), + title_text = _("Timeout in seconds"), + cancel_callback = function() + self.enabled = false + G_reader_settings:flipFalse("autoturn_enabled") + self:_deprecateLastTask() + menu:updateItems() + end, + callback = function(autoturn_spin) + self.autoturn_sec = autoturn_spin.value + G_reader_settings:saveSetting("autoturn_timeout_seconds", autoturn_spin.value) + self.enabled = true + G_reader_settings:flipTrue("autoturn_enabled") + self:_deprecateLastTask() + self:_start() + menu:updateItems() + end, + } + UIManager:show(autoturn_spin) + end, + hold_callback = function(menu) + local Screen = Device.screen + local SpinWidget = require("ui/widget/spinwidget") + local curr_items = G_reader_settings:readSetting("autoturn_distance") or 1 + local autoturn_spin = SpinWidget:new { + width = Screen:getWidth() * 0.6, + 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:_deprecateLastTask() + self:_start() + end + menu:updateItems() + end, + } + UIManager:show(autoturn_spin) + end, + } +end + +return AutoTurn