Skip to content

Commit

Permalink
[autosuspend, plugin] Switch to datetimewidget and provide default va…
Browse files Browse the repository at this point in the history
…lues (#8480)
  • Loading branch information
zwim committed Nov 28, 2021
1 parent 372dd9e commit b029a6a
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 117 deletions.
23 changes: 23 additions & 0 deletions frontend/optmath.lua
Expand Up @@ -3,6 +3,7 @@ Simple math helper functions
]]

local bit = require("bit")
local dbg = require("dbg")

local Math = {}

Expand Down Expand Up @@ -102,4 +103,26 @@ function Math.tmax(tab, func)
return tmin_max(tab, func, "max")
end

--[[--
Restricts a value within an interval.
@number value
@number min
@number max
@treturn number value clamped to the interval [min,max]
]]
function Math.clamp(value, min, max)
if value <= min then
return min
elseif value >= max then
return max
end
return value
end
dbg:guard(Math, "minmax",
function(value, min, max)
assert(min ~= nil and max ~= nil, "Math.clamp: min " .. min .. " and max " .. nil .. " must not be nil")
assert(min < max, "Math.clamp: min .. " .. min .. " must be less than max " .. max)
end)

return Math
105 changes: 63 additions & 42 deletions frontend/ui/widget/datetimewidget.lua
Expand Up @@ -19,6 +19,7 @@ local VerticalSpan = require("ui/widget/verticalspan")
local WidgetContainer = require("ui/widget/container/widgetcontainer")
local _ = require("gettext")
local Screen = Device.screen
local T = require("ffi/util").template

local DateTimeWidget = InputContainer:new{
title_face = Font:getFace("x_smalltfont"),
Expand Down Expand Up @@ -64,33 +65,34 @@ function DateTimeWidget:init()
end

-- Actually the widget layout
self:update()
self:layout()
end

function DateTimeWidget:update()
local year_widget = NumberPickerWidget:new{
local year_widget, month_hour_widget, day_min_widget
function DateTimeWidget:layout()
year_widget = NumberPickerWidget:new{
show_parent = self,
value = self.year,
value_min = 2021,
value_max = 2041,
value_step = 1,
value_hold_step = 4,
value_hold_step = self.year_hold_step or 4,
}
local month_hour_widget = NumberPickerWidget:new{
month_hour_widget = NumberPickerWidget:new{
show_parent = self,
value = self.is_date and self.month or self.hour,
value_min = self.is_date and 1 or 0,
value_max = self.is_date and 12 or self.hour_max,
value_min = self.hour_min or self.month_min or (self.is_date and 1 or 0),
value_max = self.hour_max or self.month_max or (self.is_date and 12 or 24),
value_step = 1,
value_hold_step = 3,
value_hold_step = self.hour_hold_step or self.month_hold_step or 3,
}
local day_min_widget = NumberPickerWidget:new{
day_min_widget = NumberPickerWidget:new{
show_parent = self,
value = self.is_date and self.day or self.min,
value_min = self.is_date and 1 or 0,
value_max = self.is_date and 31 or 59,
value_min = self.min_min or self.day_min or (self.is_date and 1 or 0),
value_max = self.min_max or self.day_max or (self.is_date and 31 or 59),
value_step = 1,
value_hold_step = self.is_date and 5 or 10,
value_hold_step = self.day_hold_step or self.min_hold_step or (self.is_date and 5 or 10),
date_month_hour = month_hour_widget,
date_year = year_widget,
}
Expand Down Expand Up @@ -146,49 +148,59 @@ function DateTimeWidget:update()
else
date_info = VerticalSpan:new{ width = 0 }
end
local buttons = {
{
{
text = self.cancel_text,
callback = function()
self:onClose()
end,
},

local buttons = {}
if self.default_value then
table.insert(buttons, {
{
text = self.ok_text,
text = self.default_text or T(_("Default value: %1"), self.default_value),
callback = function()
if self.callback then
self.year = year_widget:getValue()
if self.is_date then
self.month = month_hour_widget:getValue()
self.day = day_min_widget:getValue()
else
self.hour = month_hour_widget:getValue()
self.min = day_min_widget:getValue()
end
self:callback(self)
if self.default_callback then
self.default_callback(year_widget:getValue(), month_hour_widget:getValue(),
day_min_widget:getValue())
end
if not self.keep_shown_on_apply then -- assume extra wants it same as ok
self:onClose()
end
self:onClose()
end,
},
}
}
})
end
if self.extra_text then
table.insert(buttons,{
table.insert(buttons, {
{
text = self.extra_text,
callback = function()
if self.extra_callback then
self.extra_callback(year_widget:getValue(), month_hour_widget:getValue(),
day_min_widget:getValue())
end
if not self.keep_shown_on_apply then -- assume extra wants it same as ok
self:onClose()
end
self.extra_callback(self)
end,
},
})
end
table.insert(buttons, {
{
text = self.cancel_text,
callback = function()
self:onClose()
end,
},
{
text = self.ok_text,
callback = function()
if self.callback then
self.year = year_widget:getValue()
if self.is_date then
self.month = month_hour_widget:getValue()
self.day = day_min_widget:getValue()
else
self.hour = month_hour_widget:getValue()
self.min = day_min_widget:getValue()
end
self:callback(self)
end
self:onClose()
end,
},
})

local ok_cancel_buttons = ButtonTable:new{
width = self.width - 2*Size.padding.default,
Expand Down Expand Up @@ -242,6 +254,15 @@ function DateTimeWidget:update()
end)
end

function DateTimeWidget:update(left, mid, right)
year_widget.value = left
year_widget:update()
month_hour_widget.value = mid
month_hour_widget:update()
day_min_widget.value = right
day_min_widget:update()
end

function DateTimeWidget:onCloseWidget()
UIManager:setDirty(nil, function()
return "ui", self.date_frame.dimen
Expand Down
33 changes: 21 additions & 12 deletions frontend/util.lua
Expand Up @@ -111,7 +111,7 @@ Source: <a href="https://gist.github.com/jesseadams/791673">https://gist.github.
---- @int seconds number of seconds
---- @bool withoutSeconds if true 00:00, if false 00:00:00
---- @treturn string clock string in the form of 00:00 or 00:00:00
function util.secondsToClock(seconds, withoutSeconds)
function util.secondsToClock(seconds, withoutSeconds, withDays)
seconds = tonumber(seconds)
if not seconds then
if withoutSeconds then
Expand All @@ -127,18 +127,25 @@ function util.secondsToClock(seconds, withoutSeconds)
end
else
local round = withoutSeconds and require("optmath").round or passthrough
local hours = string.format("%02d", seconds / 3600)
local days = "0"
local hours
if withDays then
days = string.format("%d", seconds / (24*3600)) -- implicit math.floor for string.format
hours = string.format("%02d", (seconds / 3600) % 24)
else
hours = string.format("%02d", seconds / 3600)
end
local mins = string.format("%02d", round(seconds % 3600 / 60))
if withoutSeconds then
if mins == "60" then
-- Can only happen because of rounding, which only happens if withoutSeconds...
mins = string.format("%02d", 0)
hours = string.format("%02d", hours + 1)
end
return hours .. ":" .. mins
return (days ~= "0" and (days .. "d") or "") .. hours .. ":" .. mins
else
local secs = string.format("%02d", seconds % 60)
return hours .. ":" .. mins .. ":" .. secs
return (days ~= "0" and (days .. "d") or "") .. hours .. ":" .. mins .. ":" .. secs
end
end
end
Expand All @@ -147,8 +154,9 @@ end
---- @int seconds number of seconds
---- @bool withoutSeconds if true 1h30', if false 1h30'10''
---- @bool hmsFormat, if true format 1h30m10s
---- @bool withDays, if true format 1d12h30m10s
---- @treturn string clock string in the form of 1h30'10'' or 1h30m10s
function util.secondsToHClock(seconds, withoutSeconds, hmsFormat)
function util.secondsToHClock(seconds, withoutSeconds, hmsFormat, withDays)
local SECONDS_SYMBOL = "\""
seconds = tonumber(seconds)
if seconds == 0 then
Expand Down Expand Up @@ -189,7 +197,7 @@ function util.secondsToHClock(seconds, withoutSeconds, hmsFormat)
end
end
else
local time_string = util.secondsToClock(seconds, withoutSeconds)
local time_string = util.secondsToClock(seconds, withoutSeconds, withDays)
if withoutSeconds then
time_string = time_string .. ":"
end
Expand All @@ -198,15 +206,15 @@ function util.secondsToHClock(seconds, withoutSeconds, hmsFormat)
time_string = time_string:gsub(":", _("h"), 1)
-- @translators This is the 'm' for minute, like in 1h30m30s. This is a duration.
time_string = time_string:gsub(":", _("m"), 1)
-- @translators This is the 's' for second, like in 1h30m30s. This is a duration.
time_string = time_string:gsub("00" .. _("h"), "") -- delete leading "00h"
time_string = time_string:gsub("^00" .. _("h"), "") -- delete leading "00h"
time_string = time_string:gsub("^0", "") -- delete leading "0"
-- @translators This is the 's' for second, like in 1h30m30s. This is a duration.
return withoutSeconds and time_string or (time_string .. _("s"))
else
-- @translators This is the 'h' for hour, like in 1h30m30s. This is a duration.
time_string = time_string:gsub(":", _("h"), 1)
time_string = time_string:gsub(":", "'", 1)
time_string = time_string:gsub("00" .. _("h"), "") -- delete leading "00h"
time_string = time_string:gsub("^00" .. _("h"), "") -- delete leading "00h"
time_string = time_string:gsub("^0", "") -- delete leading "0"
return withoutSeconds and time_string or (time_string .. SECONDS_SYMBOL)
end
Expand All @@ -218,13 +226,14 @@ end
---- @string Either "modern" for 1h30'10" or "classic" for 1:30:10
---- @bool withoutSeconds if true 1h30' or 1h30m, if false 1h30'10" or 1h30m10s
---- @bool hmsFormat, modern format only, if true format 1h30m or 1h30m10s
---- @bool withDays, if hours>=24 include days in clock string 1d12h10m10s
---- @treturn string clock string in the specific format of 1h30', 1h30'10" resp. 1h30m, 1h30m10s
function util.secondsToClockDuration(format, seconds, withoutSeconds, hmsFormat)
function util.secondsToClockDuration(format, seconds, withoutSeconds, hmsFormat, withDays)
if format == "modern" then
return util.secondsToHClock(seconds, withoutSeconds, hmsFormat)
return util.secondsToHClock(seconds, withoutSeconds, hmsFormat, withDays)
else
-- Assume "classic" to give safe default
return util.secondsToClock(seconds, withoutSeconds)
return util.secondsToClock(seconds, withoutSeconds, withDays)
end
end

Expand Down

0 comments on commit b029a6a

Please sign in to comment.