diff --git a/frontend/ui/elements/filemanager_menu_order.lua b/frontend/ui/elements/filemanager_menu_order.lua index d84bcf08b..0715a65f0 100644 --- a/frontend/ui/elements/filemanager_menu_order.lua +++ b/frontend/ui/elements/filemanager_menu_order.lua @@ -36,6 +36,7 @@ local order = { "battery_statistics", "storage_stat", "cloud_storage", + "read_timer", "----------------------------", "advanced_settings", "developer_options", diff --git a/frontend/ui/elements/reader_menu_order.lua b/frontend/ui/elements/reader_menu_order.lua index 151875e6c..c3cfcc48f 100644 --- a/frontend/ui/elements/reader_menu_order.lua +++ b/frontend/ui/elements/reader_menu_order.lua @@ -23,6 +23,7 @@ local order = { "highlight_options", "change_font", "hyphenation", + "read_timer", }, setting = { "read_from_right_to_left", diff --git a/frontend/ui/widget/inputdialog.lua b/frontend/ui/widget/inputdialog.lua index 8e21c2f89..b86783254 100644 --- a/frontend/ui/widget/inputdialog.lua +++ b/frontend/ui/widget/inputdialog.lua @@ -11,6 +11,7 @@ Example: input = "default value", input_hint = "hint text", input_type = "string", + description = "Some more description", -- text_type = "password", buttons = { { @@ -38,36 +39,39 @@ Example: ]] -local InputContainer = require("ui/widget/container/inputcontainer") -local FrameContainer = require("ui/widget/container/framecontainer") -local CenterContainer = require("ui/widget/container/centercontainer") -local VerticalGroup = require("ui/widget/verticalgroup") +local Blitbuffer = require("ffi/blitbuffer") local ButtonTable = require("ui/widget/buttontable") -local TextWidget = require("ui/widget/textwidget") -local LineWidget = require("ui/widget/linewidget") +local CenterContainer = require("ui/widget/container/centercontainer") +local Font = require("ui/font") +local FrameContainer = require("ui/widget/container/framecontainer") +local Geom = require("ui/geometry") +local InputContainer = require("ui/widget/container/inputcontainer") local InputText = require("ui/widget/inputtext") +local LineWidget = require("ui/widget/linewidget") local RenderText = require("ui/rendertext") +local TextBoxWidget = require("ui/widget/textboxwidget") +local TextWidget = require("ui/widget/textwidget") +local VerticalGroup = require("ui/widget/verticalgroup") +local Widget = require("ui/widget/widget") local UIManager = require("ui/uimanager") local Screen = require("device").screen -local Geom = require("ui/geometry") -local Font = require("ui/font") -local Blitbuffer = require("ffi/blitbuffer") local InputDialog = InputContainer:new{ title = "", input = "", input_hint = "", + description = nil, buttons = nil, input_type = nil, enter_callback = nil, width = nil, - height = nil, text_width = nil, text_height = nil, title_face = Font:getFace("tfont", 22), + description_face = Font:getFace("cfont", 20), input_face = Font:getFace("cfont", 20), title_padding = Screen:scaleBySize(5), @@ -99,6 +103,21 @@ function InputDialog:init() } } + if self.description then + self.description = FrameContainer:new{ + padding = self.title_padding, + margin = self.title_margin, + bordersize = 0, + TextBoxWidget:new{ + text = self.description, + face = self.description_face, + width = self.width, + } + } + else + self.description = Widget:new() + end + self._input_widget = InputText:new{ text = self.input, hint = self.input_hint, @@ -120,6 +139,7 @@ function InputDialog:init() scroll = false, parent = self, } + self.button_table = ButtonTable:new{ width = self.width, button_font_face = "cfont", @@ -128,6 +148,7 @@ function InputDialog:init() zero_sep = true, show_parent = self, } + self.title_bar = LineWidget:new{ dimen = Geom:new{ w = self.button_table:getSize().w + self.button_padding, @@ -145,6 +166,7 @@ function InputDialog:init() align = "left", self.title, self.title_bar, + self.description, -- input CenterContainer:new{ dimen = Geom:new{ diff --git a/plugins/readtimer.koplugin/main.lua b/plugins/readtimer.koplugin/main.lua new file mode 100644 index 000000000..a259990bc --- /dev/null +++ b/plugins/readtimer.koplugin/main.lua @@ -0,0 +1,98 @@ + +local InfoMessage = require("ui/widget/infomessage") +local InputDialog = require("ui/widget/inputdialog") +local UIManager = require("ui/uimanager") +local WidgetContainer = require("ui/widget/container/widgetcontainer") +local T = require("ffi/util").template +local _ = require("gettext") + +local ReadTimer = WidgetContainer:new{ + name = "readtimer", + time = 0, -- The expected time of alarm if enabled, or 0. +} + +function ReadTimer:init() + self.alarm_callback = function() + if self.time == 0 then return end -- How could this happen? + self.time = 0 + UIManager:show(InfoMessage:new{ + text = T(_("Read timer alarm\nTime's up. It's %1 now."), os.date("%c")), + timeout = 10, + }) + end + self.ui.menu:registerToMainMenu(self) +end + +function ReadTimer:scheduled() + return self.time ~= 0 +end + +function ReadTimer:remainingMinutes() + if self:scheduled() then + return os.difftime(self.time, os.time()) / 60 + else + return math.huge + end +end + +function ReadTimer:unschedule() + if self:scheduled() then + UIManager:unschedule(self.alarm_callback) + self.time = 0 + end +end + +function ReadTimer:addToMainMenu(menu_items) + menu_items.read_timer = { + text = _("Read timer"), + checked_func = function() + -- TODO (hzj-jie): Find a way to refresh the menu items after the buttons callbacks. + return self:scheduled() + end, + callback = function() + local description = _("When will the countdown timer notify you?") + local buttons = {{ + text = _("Close"), + callback = function() + UIManager:close(self.input) + end, + }, { + text = _("Start"), + callback = function() + self:unschedule() + local seconds = self.input:getInputValue() * 60 + if seconds > 0 then + self.time = os.time() + seconds + UIManager:scheduleIn(seconds, self.alarm_callback) + end + UIManager:close(self.input) + end, + }} + if self:scheduled() then + description = description .. + T(_("\n\nYou have already set up a timer for %1 minutes from now. Setting a new one will overwrite it."), + string.format("%.2f", self:remainingMinutes())) + table.insert(buttons, { + text = _("Stop"), + callback = function() + self:unschedule() + UIManager:close(self.input) + end, + }) + end + description = description .. _("\n\n - Positive number is required.") + + self.input = InputDialog:new{ + title = _("Read timer"), + description = description, + input_type = "number", + input_hint = _("time in minutes"), + buttons = { buttons }, + } + self.input:onShowKeyboard() + UIManager:show(self.input) + end, + } +end + +return ReadTimer