mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
[DoubleSpinWidget, SpinWidget] change values with page-turn buttons (#13208)
This commit is contained in:
@@ -68,6 +68,20 @@ function DoubleSpinWidget:init()
|
||||
end
|
||||
if Device:hasKeys() then
|
||||
self.key_events.Close = { { Device.input.group.Back } }
|
||||
if Device:hasDPad() and Device:useDPadAsActionKeys() then
|
||||
self.key_events.LeftWidgetValueUp = { { "LPgFwd" }, event = "DoubleSpinButtonPressed", args = { true, 1 } }
|
||||
self.key_events.LeftWidgetValueDown = { { "LPgBack" }, event = "DoubleSpinButtonPressed", args = { true, -1 } }
|
||||
self.key_events.RightWidgetValueUp = { { "RPgFwd" }, event = "DoubleSpinButtonPressed", args = { false, 1 } }
|
||||
self.key_events.RightWidgetValueDown = { { "RPgBack" }, event = "DoubleSpinButtonPressed", args = { false, -1 } }
|
||||
if Device:hasScreenKB() or Device:hasKeyboard() then
|
||||
local modifier = Device:hasScreenKB() and "ScreenKB" or "Shift"
|
||||
local HOLD = true -- use hold step value
|
||||
self.key_events.LeftWidgetHoldValueUp = { { modifier, "LPgFwd" }, event = "DoubleSpinButtonPressed", args = { true, 1, HOLD } }
|
||||
self.key_events.LeftWidgetHoldValueDown = { { modifier, "LPgBack" }, event = "DoubleSpinButtonPressed", args = { true, -1, HOLD } }
|
||||
self.key_events.RightWidgetHoldValueUp = { { modifier, "RPgFwd" }, event = "DoubleSpinButtonPressed", args = { false, 1, HOLD } }
|
||||
self.key_events.RightWidgetHoldValueDown = { { modifier, "RPgBack" }, event = "DoubleSpinButtonPressed", args = { false, -1, HOLD } }
|
||||
end
|
||||
end
|
||||
end
|
||||
if Device:isTouchDevice() then
|
||||
self.ges_events.TapClose = {
|
||||
@@ -88,13 +102,22 @@ function DoubleSpinWidget:init()
|
||||
|
||||
-- Actually the widget layout
|
||||
self:update()
|
||||
|
||||
-- Move focus to OK button on devices which have key_events, saves time for users
|
||||
if Device:hasDPad() and Device:useDPadAsActionKeys() and not Device:isTouchDevice() then
|
||||
-- Since button table is the last row in our layout, and OK is the last button
|
||||
-- We need to set focus to both last row, and last column
|
||||
local last_row = #self.layout
|
||||
local last_col = #self.layout[last_row]
|
||||
self:moveFocusTo(last_col, last_row)
|
||||
end
|
||||
end
|
||||
|
||||
function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_value)
|
||||
local prev_movable_offset = self.movable and self.movable:getMovedOffset()
|
||||
local prev_movable_alpha = self.movable and self.movable.alpha
|
||||
self.layout = {}
|
||||
local left_widget = NumberPickerWidget:new{
|
||||
self.left_widget = NumberPickerWidget:new{
|
||||
show_parent = self,
|
||||
value = numberpicker_left_value or self.left_value,
|
||||
value_min = self.left_min,
|
||||
@@ -105,8 +128,8 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val
|
||||
wrap = self.left_wrap,
|
||||
unit = self.unit,
|
||||
}
|
||||
self:mergeLayoutInHorizontal(left_widget)
|
||||
local right_widget = NumberPickerWidget:new{
|
||||
self:mergeLayoutInHorizontal(self.left_widget)
|
||||
self.right_widget = NumberPickerWidget:new{
|
||||
show_parent = self,
|
||||
value = numberpicker_right_value or self.right_value,
|
||||
value_min = self.right_min,
|
||||
@@ -117,12 +140,12 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val
|
||||
wrap = self.right_wrap,
|
||||
unit = self.unit,
|
||||
}
|
||||
self:mergeLayoutInHorizontal(right_widget)
|
||||
left_widget.picker_updated_callback = function(value)
|
||||
self:update(value, right_widget:getValue())
|
||||
self:mergeLayoutInHorizontal(self.right_widget)
|
||||
self.left_widget.picker_updated_callback = function(value)
|
||||
self:update(value, self.right_widget:getValue())
|
||||
end
|
||||
right_widget.picker_updated_callback = function(value)
|
||||
self:update(left_widget:getValue(), value)
|
||||
self.right_widget.picker_updated_callback = function(value)
|
||||
self:update(self.left_widget:getValue(), value)
|
||||
end
|
||||
local separator_widget = TextWidget:new{
|
||||
text = self.is_range and "–" or "",
|
||||
@@ -133,7 +156,7 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val
|
||||
local text_max_width = math.floor(0.95 * self.width / 2)
|
||||
local left_vertical_group = VerticalGroup:new{
|
||||
align = "center",
|
||||
left_widget,
|
||||
self.left_widget,
|
||||
}
|
||||
local separator_vertical_group = VerticalGroup:new{
|
||||
align = "center",
|
||||
@@ -141,7 +164,7 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val
|
||||
}
|
||||
local right_vertical_group = VerticalGroup:new{
|
||||
align = "center",
|
||||
right_widget,
|
||||
self.right_widget,
|
||||
}
|
||||
|
||||
if self.left_text ~= "" or self.right_text ~= "" then
|
||||
@@ -211,10 +234,10 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val
|
||||
self.right_precision and string.format(self.right_precision, self.right_default) or self.right_default,
|
||||
unit, separator),
|
||||
callback = function()
|
||||
left_widget.value = self.left_default
|
||||
right_widget.value = self.right_default
|
||||
left_widget:update()
|
||||
right_widget:update()
|
||||
self.left_widget.value = self.left_default
|
||||
self.right_widget.value = self.right_default
|
||||
self.left_widget:update()
|
||||
self.right_widget:update()
|
||||
end,
|
||||
}
|
||||
})
|
||||
@@ -225,7 +248,7 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val
|
||||
text = self.extra_text,
|
||||
callback = function()
|
||||
if self.extra_callback then
|
||||
self.extra_callback(left_widget:getValue(), right_widget:getValue())
|
||||
self.extra_callback(self.left_widget:getValue(), self.right_widget:getValue())
|
||||
end
|
||||
if not self.keep_shown_on_apply then -- assume extra wants it same as ok
|
||||
self:onClose()
|
||||
@@ -246,11 +269,11 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val
|
||||
},
|
||||
{
|
||||
text = self.ok_text,
|
||||
enabled = self.ok_always_enabled or self.left_value ~= left_widget:getValue()
|
||||
or self.right_value ~= right_widget:getValue(),
|
||||
enabled = self.ok_always_enabled or self.left_value ~= self.left_widget:getValue()
|
||||
or self.right_value ~= self.right_widget:getValue(),
|
||||
callback = function()
|
||||
self.left_value = left_widget:getValue()
|
||||
self.right_value = right_widget:getValue()
|
||||
self.left_value = self.left_widget:getValue()
|
||||
self.right_value = self.right_widget:getValue()
|
||||
if self.callback then
|
||||
self.callback(self.left_value, self.right_value)
|
||||
end
|
||||
@@ -350,4 +373,23 @@ function DoubleSpinWidget:onClose()
|
||||
return true
|
||||
end
|
||||
|
||||
--[[
|
||||
This method processes value changes based on the direction of the spin, applying the appropriate
|
||||
step value to either the left or right widget component.
|
||||
|
||||
@param args {table} A table containing:
|
||||
- is_left_widget {boolean}. True for self.left_widget or False for self.right_widget
|
||||
- direction {int}. The direction of change (1 for increase, -1 for decrease)
|
||||
- is_hold_event {boolean}. True if the event is a hold event, false otherwise
|
||||
@return {boolean} Returns true to indicate the event was handled
|
||||
]]
|
||||
function DoubleSpinWidget:onDoubleSpinButtonPressed(args)
|
||||
local is_left_widget, direction, is_hold_event = unpack(args)
|
||||
local target_widget = is_left_widget and self.left_widget or self.right_widget
|
||||
local step = is_hold_event and target_widget.value_hold_step or target_widget.value_step
|
||||
target_widget.value = target_widget:changeValue(step * direction)
|
||||
target_widget:update()
|
||||
return true
|
||||
end
|
||||
|
||||
return DoubleSpinWidget
|
||||
|
||||
@@ -78,14 +78,14 @@ function NumberPickerWidget:init()
|
||||
if self.date_month and self.date_year then
|
||||
self.value_max = self:getDaysInMonth(self.date_month:getValue(), self.date_year:getValue())
|
||||
end
|
||||
self.value = self:changeValue(self.value, self.value_step, self.value_max, self.value_min, self.wrap)
|
||||
self.value = self:changeValue(self.value_step)
|
||||
self:update()
|
||||
end,
|
||||
hold_callback = function()
|
||||
if self.date_month and self.date_year then
|
||||
self.value_max = self:getDaysInMonth(self.date_month:getValue(), self.date_year:getValue())
|
||||
end
|
||||
self.value = self:changeValue(self.value, self.value_hold_step, self.value_max, self.value_min, self.wrap)
|
||||
self.value = self:changeValue(self.value_hold_step)
|
||||
self:update()
|
||||
end
|
||||
}
|
||||
@@ -102,14 +102,14 @@ function NumberPickerWidget:init()
|
||||
if self.date_month and self.date_year then
|
||||
self.value_max = self:getDaysInMonth(self.date_month:getValue(), self.date_year:getValue())
|
||||
end
|
||||
self.value = self:changeValue(self.value, self.value_step * -1, self.value_max, self.value_min, self.wrap)
|
||||
self.value = self:changeValue(-self.value_step)
|
||||
self:update()
|
||||
end,
|
||||
hold_callback = function()
|
||||
if self.date_month and self.date_year then
|
||||
self.value_max = self:getDaysInMonth(self.date_month:getValue(), self.date_year:getValue())
|
||||
end
|
||||
self.value = self:changeValue(self.value, self.value_hold_step * -1, self.value_max, self.value_min, self.wrap)
|
||||
self.value = self:changeValue(-self.value_hold_step)
|
||||
self:update()
|
||||
end
|
||||
}
|
||||
@@ -295,22 +295,22 @@ end
|
||||
--[[--
|
||||
Change value.
|
||||
--]]
|
||||
function NumberPickerWidget:changeValue(value, step, max, min, wrap)
|
||||
function NumberPickerWidget:changeValue(step)
|
||||
local value
|
||||
if self.value_index then
|
||||
self.value_index = self.value_index + step
|
||||
if self.value_index > #self.value_table then
|
||||
self.value_index = wrap and 1 or #self.value_table
|
||||
elseif
|
||||
self.value_index < 1 then
|
||||
self.value_index = wrap and #self.value_table or 1
|
||||
self.value_index = self.wrap and 1 or #self.value_table
|
||||
elseif self.value_index < 1 then
|
||||
self.value_index = self.wrap and #self.value_table or 1
|
||||
end
|
||||
value = self.value_table[self.value_index]
|
||||
else
|
||||
value = value + step
|
||||
if value > max then
|
||||
value = wrap and min or max
|
||||
elseif value < min then
|
||||
value = wrap and max or min
|
||||
value = self.value + step
|
||||
if value > self.value_max then
|
||||
value = self.wrap and self.value_min or self.value_max
|
||||
elseif value < self.value_min then
|
||||
value = self.wrap and self.value_max or self.value_min
|
||||
end
|
||||
end
|
||||
return value
|
||||
|
||||
@@ -66,6 +66,14 @@ function SpinWidget:init()
|
||||
end
|
||||
if Device:hasKeys() then
|
||||
self.key_events.Close = { { Device.input.group.Back } }
|
||||
self.key_events.WidgetValueUp = { { Device.input.group.PgFwd }, event = "SpinButtonPressed", args = { 1, false } }
|
||||
self.key_events.WidgetValueDown = { { Device.input.group.PgBack }, event = "SpinButtonPressed", args = { -1, false } }
|
||||
if Device:hasScreenKB() or Device:hasKeyboard() then
|
||||
local modifier = Device:hasScreenKB() and "ScreenKB" or "Shift"
|
||||
local HOLD = true -- use hold step value
|
||||
self.key_events.WidgetHoldValueUp = { { modifier, Device.input.group.PgFwd }, event = "SpinButtonPressed", args = { 1, HOLD } }
|
||||
self.key_events.WidgetHoldValueDown = { { modifier, Device.input.group.LPgBack }, event = "SpinButtonPressed", args = { -1, HOLD } }
|
||||
end
|
||||
end
|
||||
if Device:isTouchDevice() then
|
||||
self.ges_events.TapClose = {
|
||||
@@ -84,13 +92,22 @@ function SpinWidget:init()
|
||||
end
|
||||
-- Actually the widget layout
|
||||
self:update()
|
||||
|
||||
-- Move focus to OK button on NT devices with key_events, saves time for users
|
||||
if Device:hasDPad() and Device:useDPadAsActionKeys() and not Device:isTouchDevice() then
|
||||
-- Since button table is the last row in our layout, and OK is the last button
|
||||
-- We need to set focus to both last row, and last column
|
||||
local last_row = #self.layout
|
||||
local last_col = #self.layout[last_row]
|
||||
self:moveFocusTo(last_col, last_row)
|
||||
end
|
||||
end
|
||||
|
||||
function SpinWidget:update(numberpicker_value, numberpicker_value_index)
|
||||
local prev_movable_offset = self.movable and self.movable:getMovedOffset()
|
||||
local prev_movable_alpha = self.movable and self.movable.alpha
|
||||
self.layout = {}
|
||||
local value_widget = NumberPickerWidget:new{
|
||||
self.value_widget = NumberPickerWidget:new{
|
||||
show_parent = self,
|
||||
value = numberpicker_value or self.value,
|
||||
value_table = self.value_table,
|
||||
@@ -106,10 +123,10 @@ function SpinWidget:update(numberpicker_value, numberpicker_value_index)
|
||||
end,
|
||||
unit = self.unit,
|
||||
}
|
||||
self:mergeLayoutInVertical(value_widget)
|
||||
self:mergeLayoutInVertical(self.value_widget)
|
||||
local value_group = HorizontalGroup:new{
|
||||
align = "center",
|
||||
value_widget,
|
||||
self.value_widget,
|
||||
}
|
||||
|
||||
local title_bar = TitleBar:new{
|
||||
@@ -149,12 +166,12 @@ function SpinWidget:update(numberpicker_value, numberpicker_value_index)
|
||||
{
|
||||
text = T(_("Default value: %1%2"), value, unit),
|
||||
callback = function()
|
||||
if value_widget.value_table then
|
||||
value_widget.value_index = self.default_value
|
||||
if self.value_widget.value_table then
|
||||
self.value_widget.value_index = self.default_value
|
||||
else
|
||||
value_widget.value = self.default_value
|
||||
self.value_widget.value = self.default_value
|
||||
end
|
||||
value_widget:update()
|
||||
self.value_widget:update()
|
||||
end,
|
||||
},
|
||||
})
|
||||
@@ -164,7 +181,7 @@ function SpinWidget:update(numberpicker_value, numberpicker_value_index)
|
||||
text = self.extra_text,
|
||||
callback = function()
|
||||
if self.extra_callback then
|
||||
self.value, self.value_index = value_widget:getValue()
|
||||
self.value, self.value_index = self.value_widget:getValue()
|
||||
self.extra_callback(self)
|
||||
end
|
||||
if not self.keep_shown_on_apply then -- assume extra wants it same as ok
|
||||
@@ -176,7 +193,7 @@ function SpinWidget:update(numberpicker_value, numberpicker_value_index)
|
||||
text = self.option_text,
|
||||
callback = function()
|
||||
if self.option_callback then
|
||||
self.value, self.value_index = value_widget:getValue()
|
||||
self.value, self.value_index = self.value_widget:getValue()
|
||||
self.option_callback(self)
|
||||
end
|
||||
if not self.keep_shown_on_apply then -- assume option wants it same as ok
|
||||
@@ -203,9 +220,9 @@ function SpinWidget:update(numberpicker_value, numberpicker_value_index)
|
||||
},
|
||||
{
|
||||
text = self.ok_text,
|
||||
enabled = self.ok_always_enabled or self.original_value ~= value_widget:getValue(),
|
||||
enabled = self.ok_always_enabled or self.original_value ~= self.value_widget:getValue(),
|
||||
callback = function()
|
||||
self.value, self.value_index = value_widget:getValue()
|
||||
self.value, self.value_index = self.value_widget:getValue()
|
||||
self.original_value = self.value
|
||||
if self.callback then
|
||||
self.callback(self)
|
||||
@@ -338,4 +355,20 @@ function SpinWidget:onClose()
|
||||
return true
|
||||
end
|
||||
|
||||
--[[
|
||||
This method updates the widget's value based on the direction of the spin.
|
||||
|
||||
@param args {table} A table containing:
|
||||
- direction {number}. The direction of the spin (-1 for decrease, 1 for increase)
|
||||
- is_hold_event {boolean}. True if the event is a hold event, false otherwise
|
||||
@return boolean Always returns true to indicate the event was handled
|
||||
]]
|
||||
function SpinWidget:onSpinButtonPressed(args)
|
||||
local direction, is_hold_event = unpack(args)
|
||||
local step = is_hold_event and self.value_hold_step or self.value_step
|
||||
self.value_widget.value = self.value_widget:changeValue(step * direction)
|
||||
self.value_widget:update()
|
||||
return true
|
||||
end
|
||||
|
||||
return SpinWidget
|
||||
|
||||
Reference in New Issue
Block a user