diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index cbf535e1e803..e1f63f38b77a 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -379,6 +379,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 1f328e82d2b2..e793ea2c7bc4 100644 --- a/frontend/apps/reader/modules/readerbookmark.lua +++ b/frontend/apps/reader/modules/readerbookmark.lua @@ -61,6 +61,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 77579c40111f..992b54a83468 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 menu is under taps_and_gestures menu which is not available for non touch device -- Clone long_press menu and change label making much meaning for non touch devices @@ -2131,6 +2212,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 @@ -2170,8 +2253,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 @@ -2180,12 +2263,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 88ce4b29ffac..b5f04379a00f 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 a77619e4928f..be01701ce07c 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 abc346a3a724..3b671a854698 100644 --- a/frontend/apps/reader/readerui.lua +++ b/frontend/apps/reader/readerui.lua @@ -524,6 +524,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 a2f24426c1df..4a0137f2a7f2 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 0f84c3c6918e..bb08ad0ed905 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -732,6 +732,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 f93bb17f74dd..2ac7baf2066b 100644 --- a/frontend/device/kindle/device.lua +++ b/frontend/device/kindle/device.lua @@ -458,6 +458,7 @@ local Kindle2 = Kindle:extend{ isREAGL = no, hasKeyboard = yes, hasKeys = yes, + hasFiveWay = yes, hasDPad = yes, canHWInvert = no, canModifyFBInfo = no, @@ -471,6 +472,7 @@ local KindleDXG = Kindle:extend{ isREAGL = no, hasKeyboard = yes, hasKeys = yes, + hasFiveWay = yes, hasDPad = yes, canHWInvert = no, canModifyFBInfo = no, @@ -484,6 +486,7 @@ local Kindle3 = Kindle:extend{ isREAGL = no, hasKeyboard = yes, hasKeys = yes, + hasFiveWay = yes, hasDPad = yes, canHWInvert = no, canModifyFBInfo = no, @@ -495,6 +498,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