[UX] Make the reader bottom menu compatible with key navigation (#3785)

* [toggleswitch] Add support for key navigation to this widget

Add the onFocus an onUnfocus event handler
add a new function that just circle the switch if not touch event is
detected

* Add key navigation to the readermenu

The shortcut is still Alt-gr on sdl, to be defined on Kindle

* Remove the old method of handling the Press key.

Now the event is handled by the main widget who implement focusmanager
and then dispatched to the currently focused item.
Modify the fine font tuning only for non touch-devices

See : https://github.com/koreader/koreader/pull/3785#issuecomment-375306466
pull/3795/head
onde2rock 6 years ago committed by Frans de Jonge
parent 7e6de30889
commit dfd87447da

@ -14,7 +14,7 @@ function ReaderConfig:init()
if not self.dimen then self.dimen = Geom:new{} end
if Device:hasKeyboard() then
self.key_events = {
ShowConfigMenu = { { "AA" }, doc = "show config dialog" },
ShowConfigMenu = { {{"Press","AA"}}, doc = "show config dialog" },
}
end
if Device:isTouchDevice() then

@ -1,5 +1,6 @@
local Device = require("device")
local S = require("ui/data/strings")
local Screen = require("device").screen
local Screen = Device.screen
local _ = require("gettext")
@ -101,7 +102,8 @@ local CreOptions = {
{
name = "font_fine_tune",
name_text = S.FONTSIZE_FINE_TUNING,
toggle = {S.DECREASE, S.INCREASE},
toggle = Device:isTouchDevice() and {S.DECREASE, S.INCREASE} or nil,
item_text = not Device:isTouchDevice() and {S.DECREASE, S.INCREASE} or nil,
event = "ChangeSize",
args = {"decrease", "increase"},
alternate = false,

@ -1,6 +1,7 @@
local Device = require("device")
local S = require("ui/data/strings")
local _ = require("gettext")
local Screen = require("device").screen
local Screen = Device.screen
local function enable_if_equals(configurable, option, value)
return configurable[option] == value
@ -33,6 +34,7 @@ local KoptOptions = {
alternate = false,
values = {0, 1, 2},
default_value = DKOPTREADER_CONFIG_TRIM_PAGE,
enabled_func = Device.isTouchDevice,
event = "PageCrop",
args = {"manual", "auto", "semi-auto"},
}
@ -129,7 +131,8 @@ local KoptOptions = {
{
name = "font_fine_tune",
name_text = S.FONTSIZE_FINE_TUNING,
toggle = {S.DECREASE, S.INCREASE},
toggle = Device:isTouchDevice() and {S.DECREASE, S.INCREASE} or nil,
item_text = not Device:isTouchDevice() and {S.DECREASE, S.INCREASE} or nil,
values = {-0.05, 0.05},
default_value = 0.05,
event = "FineTuningFontSize",

@ -7,6 +7,7 @@ local ConfirmBox = require("ui/widget/confirmbox")
local Device = require("device")
local Event = require("ui/event")
local FixedTextWidget = require("ui/widget/fixedtextwidget")
local FocusManager = require("ui/widget/focusmanager")
local Font = require("ui/font")
local FrameContainer = require("ui/widget/container/framecontainer")
local Geom = require("ui/geometry")
@ -59,13 +60,17 @@ function OptionTextItem:init()
doc = "Hold Option Item",
},
}
else
self.active_key_events = {
Select = { {"Press"}, doc = "chose selected item" },
}
end
end
function OptionTextItem:onFocus()
self[1].color = Blitbuffer.COLOR_BLACK
end
function OptionTextItem:onUnfocus()
self[1].color = Blitbuffer.COLOR_WHITE
end
function OptionTextItem:onTapSelect()
if not self.enabled then return true end
for _, item in pairs(self.items) do
@ -119,6 +124,14 @@ function OptionIconItem:init()
end
end
function OptionIconItem:onFocus()
self.icon.invert = true
end
function OptionIconItem:onUnfocus()
self.icon.invert = false
end
function OptionIconItem:onTapSelect()
if not self.enabled then return true end
for _, item in pairs(self.items) do
@ -455,6 +468,8 @@ function ConfigOption:init()
table.insert(option_items_group, switch)
end
table.insert(option_items_container, option_items_group)
--add line of item to the second last place in the focusmanager so the menubar stay at the bottom
table.insert(self.config.layout, #self.config.layout,self:_itemGroupToLayoutLine(option_items_group))
table.insert(horizontal_group, option_items_container)
table.insert(vertical_group, horizontal_group)
end -- if
@ -464,6 +479,23 @@ function ConfigOption:init()
self.dimen = vertical_group:getSize()
end
function ConfigOption:_itemGroupToLayoutLine(option_items_group)
local layout_line = {}
for k, v in pairs(option_items_group) do
--pad the beginning of the line in the layout to align it with the current selected tab
if type(k) == "number" then
layout_line[k + self.config.panel_index-1] = v
end
end
for k, v in pairs(layout_line) do
--remove item_spacing (all widget have the name property)
if not v.name then
table.remove(layout_line,k)
end
end
return layout_line
end
local ConfigPanel = FrameContainer:new{ background = Blitbuffer.COLOR_WHITE, bordersize = 0, }
function ConfigPanel:init()
local config_options = self.config_dialog.config_options
@ -504,7 +536,7 @@ function MenuBar:init()
}
menu_items[c] = menu_icon
end
table.insert(self.config_dialog.layout,menu_items) --for the focusmanager
local available_width = Screen:getWidth() - icons_width
-- local padding = math.floor(available_width / #menu_items / 2) -- all for padding
-- local padding = math.floor(available_width / #menu_items / 2 / 2) -- half padding, half spacing ?
@ -612,7 +644,7 @@ Widget that displays config menubar and config panel
--]]
local ConfigDialog = InputContainer:new{
local ConfigDialog = FocusManager:new{
--is_borderless = false,
panel_index = 1,
}
@ -650,10 +682,8 @@ function ConfigDialog:init()
if Device:hasKeys() then
-- set up keyboard events
self.key_events.Close = { {"Back"}, doc = "close config menu" }
-- we won't catch presses to "Right"
self.key_events.FocusRight = nil
self.key_events.Select = { {"Press"}, doc = "select current menu item" }
end
self.key_events.Select = { {"Press"}, doc = "select current menu item" }
end
function ConfigDialog:updateConfigPanel(index)
@ -661,6 +691,7 @@ function ConfigDialog:updateConfigPanel(index)
end
function ConfigDialog:update()
self.layout = {}
self.config_menubar = MenuBar:new{
config_dialog = self,
panel_index = self.panel_index,
@ -676,6 +707,9 @@ function ConfigDialog:update()
self.config_menubar,
},
}
--reset the focusmanager cursor
self.selected.y=#self.layout
self.selected.x=self.panel_index
self[1] = BottomContainer:new{
dimen = Screen:getSize(),
@ -791,4 +825,9 @@ function ConfigDialog:onClose()
return true
end
function ConfigDialog:onSelect()
self:getFocusItem():handleEvent(Event:new("TapSelect"))
return true
end
return ConfigDialog

@ -171,11 +171,6 @@ function MenuItem:init()
},
}
end
if Device:hasKeys() then
self.active_key_events = {
Select = { {"Press"}, doc = "chose selected item" },
}
end
local text_mandatory_padding = 0
local text_ellipsis_mandatory_padding = 0
@ -203,11 +198,6 @@ function MenuItem:init()
local my_text = self.text and ""..self.text or ""
local w = RenderText:sizeUtf8Text(0, self.dimen.w, self.face, my_text, true, self.bold).x
if w + mandatory_w + state_button_width + text_mandatory_padding >= self.content_width then
if Device:hasKeyboard() then
self.active_key_events.ShowItemDetail = {
{"Right"}, doc = "show item detail"
}
end
local indicator = "\226\128\166 " -- an ellipsis
local indicator_w = RenderText:sizeUtf8Text(0, self.dimen.w, self.face,
indicator, true, self.bold).x
@ -382,13 +372,11 @@ function MenuItem:onFocus(initial_focus)
else
self._underline_container.color = Blitbuffer.COLOR_BLACK
end
self.key_events = self.active_key_events
return true
end
function MenuItem:onUnfocus()
self._underline_container.color = self.line_color
self.key_events = {}
return true
end

@ -154,6 +154,14 @@ function ToggleSwitch:togglePosition(position)
self:update()
end
function ToggleSwitch:circlePosition()
if self.position then
self.position = (self.position+1)%self.n_pos
self.position = self.position == 0 and self.n_pos or self.position
self:update()
end
end
function ToggleSwitch:calculatePosition(gev)
local x = (gev.pos.x - self.dimen.x) / self.dimen.w * self.n_pos
local y = (gev.pos.y - self.dimen.y) / self.dimen.h * self.row_count
@ -168,8 +176,13 @@ function ToggleSwitch:onTapSelect(arg, gev)
return
end
end
local position = self:calculatePosition(gev)
self:togglePosition(position)
if gev then
local position = self:calculatePosition(gev)
self:togglePosition(position)
else
self:circlePosition()
end
--[[
if self.values then
self.values = self.values or {}
@ -198,4 +211,14 @@ 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

@ -1,5 +1,6 @@
local Device = require("device")
local DocumentRegistry = require("document/documentregistry")
local Event = require("ui/event")
local FileManagerBookInfo = require("apps/filemanager/filemanagerbookinfo")
local ImageViewer = require("ui/widget/imageviewer")
local Menu = require("ui/widget/menu")
@ -93,7 +94,7 @@ function CoverMenu:updateItems(select_number)
-- reset focus manager accordingly
self.selected = { x = 1, y = select_number }
-- set focus to requested menu item
self.item_group[select_number]:onFocus()
self:getFocusItem():handleEvent(Event:new("Focus"))
-- This will not work with our MosaicMenu, as a MosaicMenuItem is
-- not a direct child of item_group (which contains VerticalSpans
-- and HorizontalGroup...)

@ -146,11 +146,6 @@ function ListMenuItem:init()
},
}
end
if Device:hasKeys() then
self.active_key_events = {
Select = { {"Press"}, doc = "chose selected item" },
}
end
-- We now build the minimal widget container that won't change after udpate()
@ -654,13 +649,11 @@ end
-- As done in MenuItem
function ListMenuItem:onFocus()
self._underline_container.color = Blitbuffer.COLOR_BLACK
self.key_events = self.active_key_events
return true
end
function ListMenuItem:onUnfocus()
self._underline_container.color = Blitbuffer.COLOR_WHITE
self.key_events = {}
return true
end

@ -334,11 +334,6 @@ function MosaicMenuItem:init()
},
}
end
if Device:hasKeys() then
self.active_key_events = {
Select = { {"Press"}, doc = "chose selected item" },
}
end
-- We now build the minimal widget container that won't change after udpate()
@ -642,13 +637,11 @@ end
-- As done in MenuItem
function MosaicMenuItem:onFocus()
self._underline_container.color = Blitbuffer.COLOR_BLACK
self.key_events = self.active_key_events
return true
end
function MosaicMenuItem:onUnfocus()
self._underline_container.color = Blitbuffer.COLOR_WHITE
self.key_events = {}
return true
end

Loading…
Cancel
Save