diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index 59bbac801671..254462b58836 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -380,6 +380,9 @@ function FileManager:registerKeyEvents() self.key_events.Home = { { "Home" } } -- Override the menu.lua way of handling the back key self.file_chooser.key_events.Back = { { Device.input.group.Back } } + if Device:hasFiveWay() and not Device:hasKeyboard() then + self.key_events.KeyToggleWifi = { { "ScreenKB", "Home" }, event = "ToggleWifi" } + end if not Device:hasFewKeys() then -- Also remove the handler assigned to the "Back" key by menu.lua self.file_chooser.key_events.Close = nil diff --git a/frontend/apps/filemanager/filemanagermenu.lua b/frontend/apps/filemanager/filemanagermenu.lua index 328412ad0a09..ba060d72eebb 100644 --- a/frontend/apps/filemanager/filemanagermenu.lua +++ b/frontend/apps/filemanager/filemanagermenu.lua @@ -61,6 +61,9 @@ end function FileManagerMenu:registerKeyEvents() if Device:hasKeys() then self.key_events.ShowMenu = { { "Menu" } } + if Device:hasFiveWay() and not Device:hasKeyboard() then + self.key_events.OpenLastDoc = { { "ScreenKB", "Back" } } + end end end diff --git a/frontend/apps/reader/modules/readerbookmark.lua b/frontend/apps/reader/modules/readerbookmark.lua index 2327ff0ba123..98cc61c5627a 100644 --- a/frontend/apps/reader/modules/readerbookmark.lua +++ b/frontend/apps/reader/modules/readerbookmark.lua @@ -66,6 +66,9 @@ function ReaderBookmark:onGesture() end function ReaderBookmark:registerKeyEvents() if Device:hasKeyboard() then self.key_events.ShowBookmark = { { "B" } } + elseif Device:hasFiveWay() then + self.key_events.ShowBookmark = { { "ScreenKB", "Left" } } + self.key_events.ToggleBookmark = { { "ScreenKB", "Right" } } end end diff --git a/frontend/apps/reader/modules/readerhighlight.lua b/frontend/apps/reader/modules/readerhighlight.lua index fe2d028ba678..9df8aa220376 100644 --- a/frontend/apps/reader/modules/readerhighlight.lua +++ b/frontend/apps/reader/modules/readerhighlight.lua @@ -229,7 +229,16 @@ end function ReaderHighlight:onGesture() end function ReaderHighlight:registerKeyEvents() - if Device:hasKeys() then + if Device:hasDPad() then + self.key_events.StopHighlightIndicator = { { Device.input.group.Back }, args = true } -- true: clear highlight selection + self.key_events.UpHighlightIndicator = { { "Up" }, event = "MoveHighlightIndicator", args = {0, -1} } + self.key_events.DownHighlightIndicator = { { "Down" }, event = "MoveHighlightIndicator", args = {0, 1} } + -- let hasFewKeys device move the indicator left + self.key_events.LeftHighlightIndicator = { { "Left" }, event = "MoveHighlightIndicator", args = {-1, 0} } + self.key_events.RightHighlightIndicator = { { "Right" }, event = "MoveHighlightIndicator", args = {1, 0} } + self.key_events.HighlightPress = { { "Press" } } + end + if Device:hasKeyboard() then -- Used for text selection with dpad/keys local QUICK_INDICATOR_MOVE = true self.key_events.QuickUpHighlightIndicator = { { "Shift", "Up" }, event = "MoveHighlightIndicator", args = {0, -1, QUICK_INDICATOR_MOVE} } @@ -237,15 +246,16 @@ function ReaderHighlight:registerKeyEvents() self.key_events.QuickLeftHighlightIndicator = { { "Shift", "Left" }, event = "MoveHighlightIndicator", args = {-1, 0, QUICK_INDICATOR_MOVE} } self.key_events.QuickRightHighlightIndicator = { { "Shift", "Right" }, event = "MoveHighlightIndicator", args = {1, 0, QUICK_INDICATOR_MOVE} } self.key_events.StartHighlightIndicator = { { "H" } } - if Device:hasDPad() then - self.key_events.StopHighlightIndicator = { { Device.input.group.Back }, args = true } -- true: clear highlight selection - self.key_events.UpHighlightIndicator = { { "Up" }, event = "MoveHighlightIndicator", args = {0, -1} } - self.key_events.DownHighlightIndicator = { { "Down" }, event = "MoveHighlightIndicator", args = {0, 1} } - -- let hasFewKeys device move the indicator left - self.key_events.LeftHighlightIndicator = { { "Left" }, event = "MoveHighlightIndicator", args = {-1, 0} } - self.key_events.RightHighlightIndicator = { { "Right" }, event = "MoveHighlightIndicator", args = {1, 0} } - self.key_events.HighlightPress = { { "Press" } } + if Device:hasFiveWay() then + self.key_events.KeyContentSelection = { { { "Up", "Down" } }, event = "StartHighlightIndicator" } end + elseif Device:hasFiveWay() then + local QUICK_INDICATOR_MOVE = true + self.key_events.QuickUpHighlightIndicator = { { "ScreenKB", "Up" }, event = "MoveHighlightIndicator", args = {0, -1, QUICK_INDICATOR_MOVE} } + self.key_events.QuickDownHighlightIndicator = { { "ScreenKB", "Down" }, event = "MoveHighlightIndicator", args = {0, 1, QUICK_INDICATOR_MOVE} } + self.key_events.QuickLeftHighlightIndicator = { { "ScreenKB", "Left" }, event = "MoveHighlightIndicator", args = {-1, 0, QUICK_INDICATOR_MOVE} } + self.key_events.QuickRightHighlightIndicator = { { "ScreenKB", "Right" }, event = "MoveHighlightIndicator", args = {1, 0, QUICK_INDICATOR_MOVE} } + self.key_events.KeyContentSelection = { { { "Up", "Down" } }, event = "StartHighlightIndicator" } end end @@ -367,7 +377,7 @@ local highlight_dialog_position = { function ReaderHighlight:addToMainMenu(menu_items) -- insert table to main reader menu - if not Device:isTouchDevice() and Device:hasDPad() then + if not Device:isTouchDevice() and Device:hasDPad() and not Device:hasFiveWay() then menu_items.start_content_selection = { text = _("Start content selection"), callback = function() @@ -575,6 +585,7 @@ function ReaderHighlight:addToMainMenu(menu_items) help_text = _([[ Auto-scroll to show part of the previous page when your text selection reaches the top left corner, or of the next page when it reaches the bottom right corner. Except when in two columns mode, where this is limited to showing only the previous or next column.]]), + separator = true, checked_func = function() if self.ui.paging then return false end return not self.view.highlight.disabled and G_reader_settings:nilOrTrue("highlight_corner_scroll") @@ -588,6 +599,76 @@ Except when in two columns mode, where this is limited to showing only the previ self.allow_corner_scroll = G_reader_settings:nilOrTrue("highlight_corner_scroll") end, }) + -- we allow user to select the rate at which the content selection tool moves through screen + if not Device:isTouchDevice() and Device:hasDPad() then + table.insert(menu_items.long_press.sub_item_table, { + text_func = function() + return T(_("Rate of movement in content selection: %1"), G_reader_settings:readSetting("highlight_non_touch_factor", 4)) + end, + callback = function(touchmenu_instance) + local SpinWidget = require("ui/widget/spinwidget") + local curr_val = G_reader_settings:readSetting("highlight_non_touch_factor", 4) + local spin_widget = SpinWidget:new{ + value = curr_val, + value_min = 0.25, + value_max = 5, + precision = "%.2f", + value_step = 0.25, + default_value = 4, + title_text = _("Rate of movement"), + info_text = _("Select a decimal value from 0.25 to 5. A smaller value results in a larger travel distance per keystroke. Font size and this value are inversely correlated, meaning a smaller font size requires a larger value and vice versa."), + callback = function(spin) + G_reader_settings:saveSetting("highlight_non_touch_factor", spin.value) + if touchmenu_instance then touchmenu_instance:updateItems() end + end + } + UIManager:show(spin_widget) + end, + }) + table.insert(menu_items.long_press.sub_item_table, { + text = _("Speed-up rate on multiple keystrokes"), + checked_func = function() + return G_reader_settings:nilOrTrue("highlight_non_touch_spedup") + end, + enabled_func = function() + return not self.view.highlight.disabled + end, + callback = function() + G_reader_settings:flipNilOrTrue("highlight_non_touch_spedup") + end, + }) + table.insert(menu_items.long_press.sub_item_table, { + text_func = function() + if G_reader_settings:readSetting("highlight_non_touch_interval") == 1 then + return T(_("Interval to speed-up rate: %1 second"), G_reader_settings:readSetting("highlight_non_touch_interval", 1)) + else + return T(_("Interval to speed-up rate: %1 seconds"), G_reader_settings:readSetting("highlight_non_touch_interval", 1)) + end + end, + enabled_func = function() + return not self.view.highlight.disabled and G_reader_settings:nilOrTrue("highlight_non_touch_spedup") + end, + callback = function(touchmenu_instance) + local SpinWidget = require("ui/widget/spinwidget") + local curr_val = G_reader_settings:readSetting("highlight_non_touch_interval", 1) + local spin_widget = SpinWidget:new{ + value = curr_val, + value_min = 0.1, + value_max = 1, + precision = "%.1f", + value_step = 0.1, + default_value = 1, + title_text = _("Time interval"), + info_text = _("Select a decimal value up to 1 second. This is the period of time within which multiple keystrokes will speed-up rate of travel."), + callback = function(spin) + G_reader_settings:saveSetting("highlight_non_touch_interval", spin.value) + if touchmenu_instance then touchmenu_instance:updateItems() end + end + } + UIManager:show(spin_widget) + end, + }) + end -- long_press setting is under taps_and_gestures menu which is not available for non-touch devices -- Clone long_press setting and change its label, making it much more meaningful for non-touch device users. @@ -2153,6 +2234,8 @@ function ReaderHighlight:onHighlightPress() end function ReaderHighlight:onStartHighlightIndicator() + -- disable long-press icon (poke-ball), as it is triggered constantly due to NT devices needing a workaround for text selection to work. + self.long_hold_reached_action = function() end if self.view.visible_area and not self._current_indicator_pos then -- set start position to centor of page local rect = self._previous_indicator_pos @@ -2192,8 +2275,8 @@ function ReaderHighlight:onMoveHighlightIndicator(args) local dx, dy, quick_move = unpack(args) local quick_move_distance_dx = self.view.visible_area.w * (1/5) -- quick move distance: fifth of visible_area local quick_move_distance_dy = self.view.visible_area.h * (1/5) - -- single move distance, small and capable to move on word with small font size and narrow line height - local move_distance = Size.item.height_default / 4 + -- single move distance, user adjustable, default value (4) capable to move on word with small font size and narrow line height + local move_distance = Size.item.height_default / G_reader_settings:readSetting("highlight_non_touch_factor") local rect = self._current_indicator_pos:copy() if quick_move then rect.x = rect.x + quick_move_distance_dx * dx @@ -2202,12 +2285,16 @@ function ReaderHighlight:onMoveHighlightIndicator(args) local now = time:now() if dx == self._last_indicator_move_args.dx and dy == self._last_indicator_move_args.dy then local diff = now - self._last_indicator_move_args.time - -- if press same arrow key in 1 second, speed up + -- if user presses same arrow key within 1 second (default, user adjustable), speed up -- double press: 4 single move distances, usually move to next word or line -- triple press: 16 single distances, usually skip several words or lines - -- quadruple press: 54 single distances, almost move to screen edge - if diff < time.s(1) then - move_distance = self._last_indicator_move_args.distance * 4 + -- quadruple press: 64 single distances, almost move to screen edge + if G_reader_settings:nilOrTrue("highlight_non_touch_spedup") then + -- user selects whether to use 'constant' or [this] 'sped up' rate (speed-up on by default) + local x_inter = G_reader_settings:readSetting("highlight_non_touch_interval") + if diff < time.s( x_inter ) then + move_distance = self._last_indicator_move_args.distance * 4 + end end end rect.x = rect.x + move_distance * dx diff --git a/frontend/apps/reader/modules/readerlink.lua b/frontend/apps/reader/modules/readerlink.lua index 8722c9ebc1fd..a7b1abe4b44f 100644 --- a/frontend/apps/reader/modules/readerlink.lua +++ b/frontend/apps/reader/modules/readerlink.lua @@ -228,7 +228,7 @@ end function ReaderLink:onGesture() end function ReaderLink:registerKeyEvents() - if Device:hasKeys() then + if Device:hasKeys() and not Device:hasFiveWay() then self.key_events = { SelectNextPageLink = { { "Tab" }, @@ -247,6 +247,18 @@ function ReaderLink:registerKeyEvents() -- when G_reader_settings:readSetting("back_in_reader") == "previous_location" } end + if Device:hasFiveWay() then + self.key_events.GotoSelectedPageLink = { { "Press" }, event = "GotoSelectedPageLink" } + if Device:hasKeyboard() then + self.key_events.AddCurrentLocationToStack = { { "Shift", "Down" } } + self.key_events.SelectNextPageLink = { { "Shift", "LPgFwd" }, event = "SelectNextPageLink" } + self.key_events.SelectPrevPageLink = { { "Shift", "LPgBack" }, event = "SelectPrevPageLink" } + else + self.key_events.AddCurrentLocationToStack = { { "ScreenKB", "Down" } } + self.key_events.SelectNextPageLink = { { "ScreenKB", "LPgFwd" }, event = "SelectNextPageLink" } + self.key_events.SelectPrevPageLink = { { "ScreenKB", "LPgBack" }, event = "SelectPrevPageLink" } + end + end end ReaderLink.onPhysicalKeyboardConnected = ReaderLink.registerKeyEvents diff --git a/frontend/apps/reader/modules/readerpaging.lua b/frontend/apps/reader/modules/readerpaging.lua index 3bf67199e1a9..256d96f31446 100644 --- a/frontend/apps/reader/modules/readerpaging.lua +++ b/frontend/apps/reader/modules/readerpaging.lua @@ -51,7 +51,29 @@ end function ReaderPaging:onGesture() end function ReaderPaging:registerKeyEvents() - if Device:hasKeys() then + if Device:hasFiveWay() then + -- this targets all devices (kindles) non-touch with dPads (i.e dx, kk, k4 and others) + self.key_events.GotoNextPos = { + { { "RPgFwd", "LPgFwd" } }, + event = "GotoPosRel", + args = 1, + } + self.key_events.GotoPrevPos = { + { { "RPgBack", "LPgBack" } }, + event = "GotoPosRel", + args = -1, + } + self.key_events.GotoNextChapter = { + { "Right" }, + event = "GotoNextChapter", + args = 1, + } + self.key_events.GotoPrevChapter = { + { "Left" }, + event = "GotoPrevChapter", + args = -1, + } + elseif Device:hasKeys() then self.key_events.GotoNextPage = { { { "RPgFwd", "LPgFwd", not Device:hasFewKeys() and "Right" } }, event = "GotoViewRel", diff --git a/frontend/apps/reader/modules/readerrolling.lua b/frontend/apps/reader/modules/readerrolling.lua index 205c72cff4f4..a665a3865cb1 100644 --- a/frontend/apps/reader/modules/readerrolling.lua +++ b/frontend/apps/reader/modules/readerrolling.lua @@ -116,7 +116,30 @@ end function ReaderRolling:onGesture() end function ReaderRolling:registerKeyEvents() - if Device:hasKeys() then + if Device:hasFiveWay() then + self.key_events.GotoNextView = { + { { "RPgFwd", "LPgFwd" } }, + event = "GotoViewRel", + args = 1, + } + self.key_events.GotoPrevView = { + { { "RPgBack", "LPgBack" } }, + event = "GotoViewRel", + args = -1, + } + if Device:hasKeyboard() then + self.key_events.MoveUp = { + { "Shift", "RPgBack" }, + event = "Panning", + args = {0, -1}, + } + self.key_events.MoveDown = { + { "Shift", "RPgFwd" }, + event = "Panning", + args = {0, 1}, + } + end + elseif Device:hasKeys() then self.key_events.GotoNextView = { { { "RPgFwd", "LPgFwd", "Right" } }, event = "GotoViewRel", @@ -128,7 +151,18 @@ function ReaderRolling:registerKeyEvents() args = -1, } end - if Device:hasDPad() then + if Device:hasFiveWay() then + self.key_events.GotoNextChapter = { + { "Right" }, + event = "GotoNextChapter", + args = 1, + } + self.key_events.GotoPrevChapter = { + { "Left" }, + event = "GotoPrevChapter", + args = -1, + } + elseif Device:hasDPad() then self.key_events.MoveUp = { { "Up" }, event = "Panning", @@ -140,6 +174,18 @@ function ReaderRolling:registerKeyEvents() args = {0, 1}, } end + if Device:hasFiveWay() and not Device:hasKeyboard() then + self.key_events.MoveUp = { + { "ScreenKB", "RPgBack" }, + event = "Panning", + args = {0, -1}, + } + self.key_events.MoveDown = { + { "ScreenKB", "RPgFwd" }, + event = "Panning", + args = {0, 1}, + } + end if Device:hasKeyboard() then self.key_events.GotoFirst = { { "1" }, diff --git a/frontend/apps/reader/modules/readertoc.lua b/frontend/apps/reader/modules/readertoc.lua index aaae68833877..dd6be45c84f7 100644 --- a/frontend/apps/reader/modules/readertoc.lua +++ b/frontend/apps/reader/modules/readertoc.lua @@ -62,6 +62,8 @@ function ReaderToc:onGesture() end function ReaderToc:registerKeyEvents() if Device:hasKeyboard() then self.key_events.ShowToc = { { "T" } } + elseif Device:hasFiveWay() then + self.key_events.ShowToc = { { "ScreenKB", "Up" } } end end diff --git a/frontend/apps/reader/readerui.lua b/frontend/apps/reader/readerui.lua index 40d0b09e6eaa..fa3c99435559 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -523,6 +523,15 @@ function ReaderUI:registerKeyEvents() if Device:hasKeys() then self.key_events.Home = { { "Home" } } self.key_events.Reload = { { "F5" } } + if Device:hasFiveWay() then + if Device:hasKeyboard() then + self.key_events.KeyToggleWifi = { { "Shift", "Home" }, event = "ToggleWifi" } + self.key_events.OpenLastDoc = { { "Shift", "Back" } } + else -- Currently exclusively targets Kindle 4. + self.key_events.KeyToggleWifi = { { "ScreenKB", "Home" }, event = "ToggleWifi" } + self.key_events.OpenLastDoc = { { "ScreenKB", "Back" } } + end + end end end diff --git a/frontend/device/generic/device.lua b/frontend/device/generic/device.lua index d998ba2f9bc2..ff451ebaf4b8 100644 --- a/frontend/device/generic/device.lua +++ b/frontend/device/generic/device.lua @@ -41,6 +41,7 @@ local Device = { hasAuxBattery = no, hasKeyboard = no, hasKeys = no, + hasFiveWay = no, canKeyRepeat = no, hasDPad = no, hasExitOptions = yes, diff --git a/frontend/device/input.lua b/frontend/device/input.lua index be906ac20d31..3e57020b19f6 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -819,6 +819,16 @@ function Input:handlePowerManagementOnlyEv(ev) end end + -- Make sure we don't leave modifiers in an inconsistent state + if self.modifiers[keycode] ~= nil then + if ev.value == KEY_PRESS then + self.modifiers[keycode] = true + elseif ev.value == KEY_RELEASE then + self.modifiers[keycode] = false + end + return + end + -- Nothing to see, move along! return end diff --git a/frontend/device/kindle/device.lua b/frontend/device/kindle/device.lua index 6fd9933b8dd6..0121ebcff6e9 100644 --- a/frontend/device/kindle/device.lua +++ b/frontend/device/kindle/device.lua @@ -518,6 +518,7 @@ local Kindle2 = Kindle:extend{ isREAGL = no, hasKeyboard = yes, hasKeys = yes, + hasFiveWay = yes, hasDPad = yes, canHWInvert = no, canModifyFBInfo = no, @@ -531,6 +532,7 @@ local KindleDXG = Kindle:extend{ isREAGL = no, hasKeyboard = yes, hasKeys = yes, + hasFiveWay = yes, hasDPad = yes, canHWInvert = no, canModifyFBInfo = no, @@ -544,6 +546,7 @@ local Kindle3 = Kindle:extend{ isREAGL = no, hasKeyboard = yes, hasKeys = yes, + hasFiveWay = yes, hasDPad = yes, canHWInvert = no, canModifyFBInfo = no, @@ -555,6 +558,7 @@ local Kindle4 = Kindle:extend{ model = "Kindle4", isREAGL = no, hasKeys = yes, + hasFiveWay = yes, hasDPad = yes, canHWInvert = no, canModifyFBInfo = no, diff --git a/frontend/ui/widget/touchmenu.lua b/frontend/ui/widget/touchmenu.lua index 28cce7f49f44..2d6d8ddde97a 100644 --- a/frontend/ui/widget/touchmenu.lua +++ b/frontend/ui/widget/touchmenu.lua @@ -511,6 +511,7 @@ function TouchMenu:init() } self.key_events.Back = { { Input.group.Back } } + self.key_events.Close = { { "Menu" } } if Device:hasFewKeys() then self.key_events.Back = { { "Left" } } end