diff --git a/frontend/apps/reader/modules/readerconfig.lua b/frontend/apps/reader/modules/readerconfig.lua index c3a94651e..2376c9bf6 100644 --- a/frontend/apps/reader/modules/readerconfig.lua +++ b/frontend/apps/reader/modules/readerconfig.lua @@ -26,9 +26,7 @@ function ReaderConfig:init() ShowConfigMenu = { {{"Press","AA"}}, doc = "show config dialog" }, } end - if Device:isTouchDevice() then - self:initGesListener() - end + self:initGesListener() if G_reader_settings:has("activate_menu") then self.activation_menu = G_reader_settings:readSetting("activate_menu") else diff --git a/frontend/ui/widget/button.lua b/frontend/ui/widget/button.lua index 92c8654a1..c49711b44 100644 --- a/frontend/ui/widget/button.lua +++ b/frontend/ui/widget/button.lua @@ -165,31 +165,29 @@ function Button:init() end self.dimen = self.frame:getSize() self[1] = self.frame - if Device:isTouchDevice() then - self.ges_events = { - TapSelectButton = { - GestureRange:new{ - ges = "tap", - range = self.dimen, - }, - doc = "Tap Button", + self.ges_events = { + TapSelectButton = { + GestureRange:new{ + ges = "tap", + range = self.dimen, }, - HoldSelectButton = { - GestureRange:new{ - ges = "hold", - range = self.dimen, - }, - doc = "Hold Button", + doc = "Tap Button", + }, + HoldSelectButton = { + GestureRange:new{ + ges = "hold", + range = self.dimen, + }, + doc = "Hold Button", + }, + -- Safe-guard for when used inside a MovableContainer + HoldReleaseSelectButton = { + GestureRange:new{ + ges = "hold_release", + range = self.dimen, }, - -- Safe-guard for when used inside a MovableContainer - HoldReleaseSelectButton = { - GestureRange:new{ - ges = "hold_release", - range = self.dimen, - }, - } } - end + } end function Button:setText(text, width) diff --git a/frontend/ui/widget/buttonprogresswidget.lua b/frontend/ui/widget/buttonprogresswidget.lua index 1eeb3048d..f33ef2d50 100644 --- a/frontend/ui/widget/buttonprogresswidget.lua +++ b/frontend/ui/widget/buttonprogresswidget.lua @@ -1,17 +1,17 @@ local Blitbuffer = require("ffi/blitbuffer") local Button = require("ui/widget/button") local Device = require("device") +local FocusManager = require("ui/widget/focusmanager") local Geom = require("ui/geometry") local HorizontalGroup = require("ui/widget/horizontalgroup") local HorizontalSpan = require("ui/widget/horizontalspan") -local InputContainer = require("ui/widget/container/inputcontainer") local FrameContainer = require("ui/widget/container/framecontainer") local Size = require("ui/size") local UIManager = require("ui/uimanager") local _ = require("gettext") local Screen = Device.screen -local ButtonProgressWidget = InputContainer:new{ +local ButtonProgressWidget = FocusManager:new{ width = Screen:scaleBySize(216), height = Size.item.height_default, padding = Size.padding.small, @@ -27,6 +27,8 @@ local ButtonProgressWidget = InputContainer:new{ } function ButtonProgressWidget:init() + self.current_button_index = self.position + self.buttonprogress_frame = FrameContainer:new{ background = Blitbuffer.COLOR_WHITE, color = Blitbuffer.COLOR_DARK_GRAY, @@ -46,12 +48,17 @@ function ButtonProgressWidget:init() self.horizontal_span_width = self.horizontal_span.width end self:update() + if self.fine_tune then + self.current_button_index = self.current_button_index + 1 + end self.buttonprogress_frame[1] = self.buttonprogress_content self[1] = self.buttonprogress_frame self.dimen = Geom:new(self.buttonprogress_frame:getSize()) end function ButtonProgressWidget:update() + self.layout = {{}} + self.buttonprogress_content:clear() local button_margin = Size.margin.tiny local button_padding = Size.padding.button @@ -91,7 +98,6 @@ function ButtonProgressWidget:update() self.callback("-") self:update() end, - no_focus = true, hold_callback = function() self.hold_callback("-") end, @@ -100,6 +106,7 @@ function ButtonProgressWidget:update() button.frame.color = Blitbuffer.COLOR_DARK_GRAY end table.insert(self.buttonprogress_content, button) + table.insert(self.layout[1], button) table.insert(self.buttonprogress_content, self.horizontal_span) end @@ -139,7 +146,7 @@ function ButtonProgressWidget:update() self.position = i self:update() end, - no_focus = true, + no_focus = highlighted, hold_callback = function() self.hold_callback(i) end, @@ -161,11 +168,14 @@ function ButtonProgressWidget:update() margin = button_margin, padding = 0, bordersize = 0, + focusable = true, + focus_border_size = Size.border.thin, button, } end end table.insert(self.buttonprogress_content, button) + table.insert(self.layout[1], button) end -- Plus button on the right @@ -194,16 +204,17 @@ function ButtonProgressWidget:update() self.callback("+") self:update() end, - no_focus = true, hold_callback = function() self.hold_callback("+") end, } + if self.thin_grey_style then button.frame.color = Blitbuffer.COLOR_DARK_GRAY end table.insert(self.buttonprogress_content, self.horizontal_span) table.insert(self.buttonprogress_content, button) + table.insert(self.layout[1], button) end -- More option button on the right if self.more_options then @@ -230,7 +241,6 @@ function ButtonProgressWidget:update() self.callback("⋮") self:update() end, - no_focus = true, hold_callback = function() self.hold_callback("⋮") end, @@ -240,6 +250,7 @@ function ButtonProgressWidget:update() end table.insert(self.buttonprogress_content, self.horizontal_span) table.insert(self.buttonprogress_content, button) + table.insert(self.layout[1], button) end UIManager:setDirty(self.show_parrent, function() @@ -253,16 +264,6 @@ function ButtonProgressWidget:setPosition(position, default_position) self:update() end -function ButtonProgressWidget:onFocus() - self.buttonprogress_frame.background = Blitbuffer.COLOR_BLACK - return true -end - -function ButtonProgressWidget:onUnfocus() - self.buttonprogress_frame.background = Blitbuffer.COLOR_WHITE - return true -end - function ButtonProgressWidget:onTapSelect(arg, gev) if gev == nil then self:circlePosition() diff --git a/frontend/ui/widget/buttontable.lua b/frontend/ui/widget/buttontable.lua index 084793f20..ac817c609 100644 --- a/frontend/ui/widget/buttontable.lua +++ b/frontend/ui/widget/buttontable.lua @@ -24,6 +24,7 @@ local ButtonTable = FocusManager:new{ zero_sep = false, button_font_face = "cfont", button_font_size = 20, + auto_focus_first_button = true, } function ButtonTable:init() @@ -99,7 +100,9 @@ function ButtonTable:init() self:addHorizontalSep(true, false, false) if Device:hasDPad() then self.layout = self.buttons_layout - self.layout[1][1]:onFocus() + if self.auto_focus_first_button then + self.layout[1][1]:onFocus() + end self.key_events.SelectByKeyPress = { {{"Press"}} } else self.key_events = {} -- deregister all key press event listeners @@ -128,9 +131,11 @@ end function ButtonTable:onSelectByKeyPress() local item = self:getFocusItem() - if item.enabled then + if item and item.enabled then item.callback() + return true end + return false end function ButtonTable:getButtonById(id) diff --git a/frontend/ui/widget/configdialog.lua b/frontend/ui/widget/configdialog.lua index 5181b5511..17776a43b 100644 --- a/frontend/ui/widget/configdialog.lua +++ b/frontend/ui/widget/configdialog.lua @@ -52,24 +52,22 @@ function OptionTextItem:init() } self.dimen = self[1]:getSize() -- we need this table per-instance, so we declare it here - if Device:isTouchDevice() then - self.ges_events = { - TapSelect = { - GestureRange:new{ - ges = "tap", - range = self.dimen, - }, - doc = "Select Option Item", + self.ges_events = { + TapSelect = { + GestureRange:new{ + ges = "tap", + range = self.dimen, }, - HoldSelect = { - GestureRange:new{ - ges = "hold", - range = self.dimen, - }, - doc = "Hold Option Item", + doc = "Select Option Item", + }, + HoldSelect = { + GestureRange:new{ + ges = "hold", + range = self.dimen, }, - } - end + doc = "Hold Option Item", + }, + } end function OptionTextItem:onFocus() @@ -128,25 +126,23 @@ function OptionIconItem:init() } self.dimen = self[1]:getSize() -- we need this table per-instance, so we declare it here - if Device:isTouchDevice() then - self.ges_events = { - TapSelect = { - GestureRange:new{ - ges = "tap", - range = self.dimen, - }, - doc = "Select Option Item", + self.ges_events = { + TapSelect = { + GestureRange:new{ + ges = "tap", + range = self.dimen, }, - HoldSelect = { - GestureRange:new{ - ges = "hold", - range = self.dimen, - }, - doc = "Hold Option Item", + doc = "Select Option Item", + }, + HoldSelect = { + GestureRange:new{ + ges = "hold", + range = self.dimen, }, + doc = "Hold Option Item", + }, - } - end + } end function OptionIconItem:onFocus() @@ -674,8 +670,21 @@ function ConfigOption:_itemGroupToLayoutLine(option_items_group) local j = self.config.panel_index for i, v in ipairs(option_items_group) do if v.name then - layout_line[j] = v - j = j + 1 + if v.layout and v.disableFocusManagement then -- it is a FocusManager + -- merge child layout to one row layout + -- currently child widgets are all one row + -- need improved if two or more rows widget existed + for _, row in ipairs(v.layout) do + for _, widget in ipairs(row) do + layout_line[j] = widget + j = j + 1 + end + end + v:disableFocusManagement() + else + layout_line[j] = v + j = j + 1 + end end end return layout_line @@ -849,28 +858,26 @@ function ConfigDialog:init() ------------------------------------------ -- start to set up input event callback -- ------------------------------------------ - if Device:isTouchDevice() then - self.ges_events.TapCloseMenu = { - GestureRange:new{ - ges = "tap", - range = Geom:new{ - x = 0, y = 0, - w = Screen:getWidth(), - h = Screen:getHeight(), - } + self.ges_events.TapCloseMenu = { + GestureRange:new{ + ges = "tap", + range = Geom:new{ + x = 0, y = 0, + w = Screen:getWidth(), + h = Screen:getHeight(), } } - self.ges_events.SwipeCloseMenu = { - GestureRange:new{ - ges = "swipe", - range = Geom:new{ - x = 0, y = 0, - w = Screen:getWidth(), - h = Screen:getHeight(), - } + } + self.ges_events.SwipeCloseMenu = { + GestureRange:new{ + ges = "swipe", + range = Geom:new{ + x = 0, y = 0, + w = Screen:getWidth(), + h = Screen:getHeight(), } } - end + } if Device:hasKeys() then -- set up keyboard events local close_keys = Device:hasFewKeys() and { "Back", "Left" } or Device.input.group.Back @@ -1457,8 +1464,7 @@ function ConfigDialog:onClose() end function ConfigDialog:onSelect() - self:getFocusItem():handleEvent(Event:new("TapSelect")) - return true + return self:sendTapEventToFocusedWidget() end return ConfigDialog diff --git a/frontend/ui/widget/container/framecontainer.lua b/frontend/ui/widget/container/framecontainer.lua index cb1a04fc5..5c40b7bd1 100644 --- a/frontend/ui/widget/container/framecontainer.lua +++ b/frontend/ui/widget/container/framecontainer.lua @@ -41,6 +41,9 @@ local FrameContainer = WidgetContainer:new{ invert = false, allow_mirroring = true, _mirroredUI = BD.mirroredUILayout(), + focusable = false, + focus_border_size = Size.border.window * 2, + focus_border_color = Blitbuffer.COLOR_BLACK, } function FrameContainer:getSize() @@ -58,6 +61,27 @@ function FrameContainer:getSize() } end +function FrameContainer:onFocus() + if not self.focusable then + return + end + self._origin_bordersize = self.bordersize + self._origin_border_color = self.color + self.bordersize = self.focus_border_size + self.color = self.focus_border_color + return true +end + +function FrameContainer:onUnfocus() + if not self.focusable then + return + end + self.bordersize = self._origin_bordersize + self.color = self._origin_border_color + return true +end + + function FrameContainer:paintTo(bb, x, y) local my_size = self:getSize() self.dimen = Geom:new{ diff --git a/frontend/ui/widget/doublespinwidget.lua b/frontend/ui/widget/doublespinwidget.lua index ddd978256..0624aa18a 100644 --- a/frontend/ui/widget/doublespinwidget.lua +++ b/frontend/ui/widget/doublespinwidget.lua @@ -2,12 +2,12 @@ local Blitbuffer = require("ffi/blitbuffer") local ButtonTable = require("ui/widget/buttontable") local CenterContainer = require("ui/widget/container/centercontainer") local Device = require("device") +local FocusManager = require("ui/widget/focusmanager") local FrameContainer = require("ui/widget/container/framecontainer") local Geom = require("ui/geometry") local GestureRange = require("ui/gesturerange") local Font = require("ui/font") local HorizontalGroup = require("ui/widget/horizontalgroup") -local InputContainer = require("ui/widget/container/inputcontainer") local MovableContainer = require("ui/widget/container/movablecontainer") local NumberPickerWidget = require("ui/widget/numberpickerwidget") local Size = require("ui/size") @@ -20,7 +20,7 @@ local _ = require("gettext") local Screen = Device.screen local T = require("ffi/util").template -local DoubleSpinWidget = InputContainer:new{ +local DoubleSpinWidget = FocusManager:new{ title_text = "", title_face = Font:getFace("x_smalltfont"), info_text = nil, @@ -65,9 +65,8 @@ function DoubleSpinWidget:init() self.width = math.floor(math.min(self.screen_width, self.screen_height) * self.width_factor) end if Device:hasKeys() then - self.key_events = { - Close = { {Device.input.group.Back}, doc = "close doublespin widget" } - } + self.key_events.Close = { {Device.input.group.Back}, doc = "close doublespin widget" } + self.key_events.Press = { {"Press"}, doc = "press button" } end if Device:isTouchDevice() then self.ges_events = { @@ -88,6 +87,7 @@ function DoubleSpinWidget:init() end function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_value) + self.layout = {} local left_widget = NumberPickerWidget:new{ show_parent = self, value = numberpicker_left_value or self.left_value, @@ -98,6 +98,7 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val precision = self.left_precision, wrap = self.left_wrap, } + self:mergeLayoutInHorizontal(left_widget) local right_widget = NumberPickerWidget:new{ show_parent = self, value = numberpicker_right_value or self.right_value, @@ -108,6 +109,7 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val precision = self.right_precision, wrap = self.right_wrap, } + self:mergeLayoutInHorizontal(right_widget) left_widget.picker_updated_callback = function(value) self:update(value, right_widget:getValue()) end @@ -227,7 +229,9 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val buttons = buttons, zero_sep = true, show_parent = self, + auto_focus_first_button = false, } + self:mergeLayoutInVertical(button_table) self.widget_frame = FrameContainer:new{ radius = Size.radius.window, @@ -265,6 +269,7 @@ function DoubleSpinWidget:update(numberpicker_left_value, numberpicker_right_val }, self.movable, } + self:focusTopLeftWidget() UIManager:setDirty(self, function() return "ui", self.widget_frame.dimen end) @@ -308,4 +313,8 @@ function DoubleSpinWidget:onClose() return true end +function DoubleSpinWidget:onPress() + return self:sendTapEventToFocusedWidget() +end + return DoubleSpinWidget diff --git a/frontend/ui/widget/focusmanager.lua b/frontend/ui/widget/focusmanager.lua index f329ebb17..e64140caf 100644 --- a/frontend/ui/widget/focusmanager.lua +++ b/frontend/ui/widget/focusmanager.lua @@ -27,7 +27,7 @@ it rather defines an abstract layout. local FocusManager = InputContainer:new{ selected = nil, -- defaults to x=1, y=1 layout = nil, -- mandatory - movement_allowed = { x = true, y = true } + movement_allowed = { x = true, y = true }, } function FocusManager:init() @@ -50,6 +50,9 @@ function FocusManager:init() end function FocusManager:onFocusMove(args) + if not self.layout then -- allow parent focus manger to handle the event + return false + end local dx, dy = unpack(args) if (dx ~= 0 and not self.movement_allowed.x) @@ -57,7 +60,7 @@ function FocusManager:onFocusMove(args) return true end - if not self.layout or not self.layout[self.selected.y] or not self.layout[self.selected.y][self.selected.x] then + if not self.layout[self.selected.y] or not self.layout[self.selected.y][self.selected.x] then return true end local current_item = self.layout[self.selected.y][self.selected.x] @@ -159,7 +162,64 @@ function FocusManager:_verticalStep(dy) end function FocusManager:getFocusItem() + if not self.layout then + return nil + end return self.layout[self.selected.y][self.selected.x] end +function FocusManager:sendTapEventToFocusedWidget() + local focused_widget = self:getFocusItem() + if focused_widget then + -- center of widget position + local point = focused_widget.dimen:copy() + point.x = point.x + point.w / 2 + point.y = point.y + point.h / 2 + point.w = 0 + point.h = 0 + UIManager:sendEvent(Event:new("Gesture", { + ges = "tap", + pos = point, + })) + return true + end + return false +end + +function FocusManager:mergeLayoutInVertical(child) + if not child.layout then + return + end + for _, row in ipairs(child.layout) do + table.insert(self.layout, row) + end + child:disableFocusManagement() +end + +function FocusManager:mergeLayoutInHorizontal(child) + if not child.layout then + return + end + for i, row in ipairs(child.layout) do + local prow = self.layout[i] + if not prow then + prow = {} + self.layout[i] = prow + end + for _, widget in ipairs(row) do + table.insert(prow, widget) + end + end + child:disableFocusManagement() +end + +function FocusManager:disableFocusManagement() + self.layout = nil -- turn off focus feature +end + +--- Container call this method after init to let first widget render in focus style +function FocusManager:focusTopLeftWidget() + self:onFocusMove({0, 0}) +end + return FocusManager diff --git a/frontend/ui/widget/iconbutton.lua b/frontend/ui/widget/iconbutton.lua index 90d2460ee..5f2bf1acd 100644 --- a/frontend/ui/widget/iconbutton.lua +++ b/frontend/ui/widget/iconbutton.lua @@ -73,31 +73,29 @@ function IconButton:update() end function IconButton:initGesListener() - if Device:isTouchDevice() then - self.ges_events = { - TapIconButton = { - GestureRange:new{ - ges = "tap", - range = self.dimen, - }, - doc = "Tap IconButton", + self.ges_events = { + TapIconButton = { + GestureRange:new{ + ges = "tap", + range = self.dimen, }, - HoldIconButton = { - GestureRange:new{ - ges = "hold", - range = self.dimen, - }, - doc = "Hold IconButton", + doc = "Tap IconButton", + }, + HoldIconButton = { + GestureRange:new{ + ges = "hold", + range = self.dimen, }, - HoldReleaseIconButton = { - GestureRange:new{ - ges = "hold_release", - range = self.dimen, - }, - doc = "Hold Release IconButton", - } + doc = "Hold IconButton", + }, + HoldReleaseIconButton = { + GestureRange:new{ + ges = "hold_release", + range = self.dimen, + }, + doc = "Hold Release IconButton", } - end + } end function IconButton:onTapIconButton() diff --git a/frontend/ui/widget/numberpickerwidget.lua b/frontend/ui/widget/numberpickerwidget.lua index 6cd6b605e..9ebd937c3 100644 --- a/frontend/ui/widget/numberpickerwidget.lua +++ b/frontend/ui/widget/numberpickerwidget.lua @@ -18,11 +18,11 @@ Example: local Button = require("ui/widget/button") local CenterContainer = require("ui/widget/container/centercontainer") local Device = require("device") +local FocusManager = require("ui/widget/focusmanager") local FrameContainer = require("ui/widget/container/framecontainer") local Geom = require("ui/geometry") local Font = require("ui/font") local InfoMessage = require("ui/widget/infomessage") -local InputContainer = require("ui/widget/container/inputcontainer") local InputDialog = require("ui/widget/inputdialog") local Size = require("ui/size") local UIManager = require("ui/uimanager") @@ -32,7 +32,7 @@ local _ = require("gettext") local T = require("ffi/util").template local Screen = Device.screen -local NumberPickerWidget = InputContainer:new{ +local NumberPickerWidget = FocusManager:new{ spinner_face = Font:getFace("smalltfont"), precision = "%02d", width = nil, @@ -60,6 +60,7 @@ function NumberPickerWidget:init() self.value_index = self.value_index or 1 self.value = self.value_table[self.value_index] end + self.layout = {} -- Widget layout local bordersize = Size.border.default @@ -87,6 +88,7 @@ function NumberPickerWidget:init() self:update() end } + table.insert(self.layout, {button_up}) local button_down = Button:new{ text = "▼", bordersize = bordersize, @@ -110,6 +112,7 @@ function NumberPickerWidget:init() self:update() end } + table.insert(self.layout, {button_down}) local empty_space = VerticalSpan:new{ width = Size.padding.large } @@ -207,6 +210,9 @@ function NumberPickerWidget:init() } self.dimen = self.frame:getSize() self[1] = self.frame + if Device:hasDPad() then + self.key_events.Press = { {"Press"}, doc = "press button" } + end UIManager:setDirty(self.show_parent, function() return "ui", self.dimen end) @@ -283,4 +289,8 @@ function NumberPickerWidget:getValue() return self.value, self.value_index end +function NumberPickerWidget:onPress() + return self:sendTapEventToFocusedWidget() +end + return NumberPickerWidget diff --git a/frontend/ui/widget/radiobuttontable.lua b/frontend/ui/widget/radiobuttontable.lua index f4a17d8ea..829811fd5 100644 --- a/frontend/ui/widget/radiobuttontable.lua +++ b/frontend/ui/widget/radiobuttontable.lua @@ -147,7 +147,12 @@ function RadioButtonTable:addHorizontalSep(vspan_before, add_line, vspan_after, end function RadioButtonTable:onSelectByKeyPress() - self:getFocusItem().callback() + local item = self:getFocusItem() + if item then + item.callback() + return true + end + return false end function RadioButtonTable:_checkButton(button) diff --git a/frontend/ui/widget/skimtowidget.lua b/frontend/ui/widget/skimtowidget.lua index dae01df30..eedccc106 100644 --- a/frontend/ui/widget/skimtowidget.lua +++ b/frontend/ui/widget/skimtowidget.lua @@ -380,7 +380,11 @@ end function SkimToWidget:onSelectByKeyPress() local item = self:getFocusItem() - item.callback() + if item then + item.callback() + return true + end + return false end function SkimToWidget:onFirstRowKeyPress(percent) diff --git a/frontend/ui/widget/spinwidget.lua b/frontend/ui/widget/spinwidget.lua index 248780c8e..aecd73c30 100644 --- a/frontend/ui/widget/spinwidget.lua +++ b/frontend/ui/widget/spinwidget.lua @@ -2,11 +2,11 @@ local Blitbuffer = require("ffi/blitbuffer") local ButtonTable = require("ui/widget/buttontable") local CenterContainer = require("ui/widget/container/centercontainer") local Device = require("device") +local FocusManager = require("ui/widget/focusmanager") local FrameContainer = require("ui/widget/container/framecontainer") local Geom = require("ui/geometry") local GestureRange = require("ui/gesturerange") local HorizontalGroup = require("ui/widget/horizontalgroup") -local InputContainer = require("ui/widget/container/inputcontainer") local MovableContainer = require("ui/widget/container/movablecontainer") local NumberPickerWidget = require("ui/widget/numberpickerwidget") local Size = require("ui/size") @@ -18,7 +18,7 @@ local _ = require("gettext") local Screen = Device.screen local T = require("ffi/util").template -local SpinWidget = InputContainer:new{ +local SpinWidget = FocusManager:new{ title_text = "", info_text = nil, width = nil, @@ -64,9 +64,8 @@ function SpinWidget:init() self.width = math.floor(math.min(self.screen_width, self.screen_height) * self.width_factor) end if Device:hasKeys() then - self.key_events = { - Close = { {Device.input.group.Back}, doc = "close spin widget" } - } + self.key_events.Close = { {Device.input.group.Back}, doc = "close spin widget" } + self.key_events.Press = { {"Press"}, doc = "press button" } end if Device:isTouchDevice() then self.ges_events = { @@ -87,6 +86,7 @@ function SpinWidget:init() end function SpinWidget:update(numberpicker_value, numberpicker_value_index) + self.layout = {} local value_widget = NumberPickerWidget:new{ show_parent = self, value = numberpicker_value or self.value, @@ -102,6 +102,7 @@ function SpinWidget:update(numberpicker_value, numberpicker_value_index) self:update(value, value_index) end, } + self:mergeLayoutInVertical(value_widget) local value_group = HorizontalGroup:new{ align = "center", value_widget, @@ -195,8 +196,9 @@ function SpinWidget:update(numberpicker_value, numberpicker_value_index) buttons = buttons, zero_sep = true, show_parent = self, + auto_focus_first_button = false, } - + self:mergeLayoutInVertical(ok_cancel_buttons) local vgroup = VerticalGroup:new{ align = "left", title_bar, @@ -234,6 +236,7 @@ function SpinWidget:update(numberpicker_value, numberpicker_value_index) }, self.movable, } + self:focusTopLeftWidget() UIManager:setDirty(self, function() return "ui", self.spin_frame.dimen end) @@ -277,4 +280,8 @@ function SpinWidget:onClose() return true end +function SpinWidget:onPress() + return self:sendTapEventToFocusedWidget() +end + return SpinWidget diff --git a/frontend/ui/widget/toggleswitch.lua b/frontend/ui/widget/toggleswitch.lua index e22b5f70c..15d7f6d72 100644 --- a/frontend/ui/widget/toggleswitch.lua +++ b/frontend/ui/widget/toggleswitch.lua @@ -9,11 +9,11 @@ local BD = require("ui/bidi") local Blitbuffer = require("ffi/blitbuffer") local CenterContainer = require("ui/widget/container/centercontainer") local Device = require("device") +local FocusManager = require("ui/widget/focusmanager") local Font = require("ui/font") local Geom = require("ui/geometry") local GestureRange = require("ui/gesturerange") local HorizontalGroup = require("ui/widget/horizontalgroup") -local InputContainer = require("ui/widget/container/inputcontainer") local FrameContainer = require("ui/widget/container/framecontainer") local Notification = require("ui/widget/notification") local Size = require("ui/size") @@ -29,7 +29,7 @@ local ToggleLabel = TextWidget:new{ fgcolor = Blitbuffer.COLOR_BLACK, } -local ToggleSwitch = InputContainer:new{ +local ToggleSwitch = FocusManager:new{ width = Screen:scaleBySize(216), height = Size.item.height_default, bgcolor = Blitbuffer.COLOR_WHITE, -- unfocused item color @@ -41,6 +41,7 @@ local ToggleSwitch = InputContainer:new{ } function ToggleSwitch:init() + self.layout = {{}} -- Item count per row self.n_pos = math.ceil(#self.toggle / self.row_count) self.position = nil @@ -100,31 +101,33 @@ function ToggleSwitch:init() radius = Size.radius.window, bordersize = item_border_size, padding = 0, + focusable = true, + focus_border_size = item_border_size, + focus_border_color = Blitbuffer.COLOR_BLACK, content, } table.insert(self.toggle_content[math.ceil(i / self.n_pos)], button) + table.insert(self.layout[1], button) end self.toggle_frame[1] = self.toggle_content self[1] = self.toggle_frame self.dimen = Geom:new(self.toggle_frame:getSize()) - if Device:isTouchDevice() then - self.ges_events = { - TapSelect = { - GestureRange:new{ - ges = "tap", - range = self.dimen, - }, - doc = "Toggle switch", + self.ges_events = { + TapSelect = { + GestureRange:new{ + ges = "tap", + range = self.dimen, }, - HoldSelect = { - GestureRange:new{ - ges = "hold", - range = self.dimen, - }, - doc = "Hold switch", + doc = "Toggle switch", + }, + HoldSelect = { + GestureRange:new{ + ges = "hold", + range = self.dimen, }, - } - end + doc = "Hold switch", + }, + } end function ToggleSwitch:update() @@ -250,14 +253,4 @@ function ToggleSwitch:onHoldSelect(arg, gev) return true end -function ToggleSwitch:onFocus() - self.toggle_frame.background = Blitbuffer.COLOR_BLACK - return true -end - -function ToggleSwitch:onUnfocus() - self.toggle_frame.background = Blitbuffer.COLOR_WHITE - return true -end - return ToggleSwitch diff --git a/frontend/ui/widget/touchmenu.lua b/frontend/ui/widget/touchmenu.lua index c8067dc5f..61b6516c7 100644 --- a/frontend/ui/widget/touchmenu.lua +++ b/frontend/ui/widget/touchmenu.lua @@ -963,7 +963,12 @@ function TouchMenu:onBack() end function TouchMenu:onPress() - self:getFocusItem():handleEvent(Event:new("TapSelect")) + local item = self:getFocusItem() + if item then + item:handleEvent(Event:new("TapSelect")) + return true + end + return false end return TouchMenu diff --git a/frontend/ui/widget/virtualkeyboard.lua b/frontend/ui/widget/virtualkeyboard.lua index b7835534f..f95582ed6 100644 --- a/frontend/ui/widget/virtualkeyboard.lua +++ b/frontend/ui/widget/virtualkeyboard.lua @@ -472,8 +472,12 @@ function VirtualKeyPopup:onCloseWidget() end function VirtualKeyPopup:onPressKey() - self:getFocusItem():handleEvent(Event:new("TapSelect")) - return true + local item = self:getFocusItem() + if item then + item:handleEvent(Event:new("TapSelect")) + return true + end + return false end function VirtualKeyPopup:init() @@ -848,8 +852,12 @@ function VirtualKeyboard:onClose() end function VirtualKeyboard:onPressKey() - self:getFocusItem():handleEvent(Event:new("TapSelect")) - return true + local item = self:getFocusItem() + if item then + item:handleEvent(Event:new("TapSelect")) + return true + end + return false end function VirtualKeyboard:_refresh(want_flash, fullscreen)