BookMap on devices with useDPadAsActionKeys (#11916)

as first discussed here #11908. This PR brings the book map to non-touch devices that useDPadAsActionKeys().

Book map can be accessed from the menu or by using the following shortcut: ScreenKB + Down or Shift + Down depending on whether you use a K4 device or a kindle with keyboard respectively.

Inside the book map, a user can toggle the hamburger menu by pressing the Menu key and make any adjustment from there. ScreenKB (or Shift) + Up/Down allows it to scroll and Page turn buttons to move by whole full page turns. Back key allows user to exit the map.
reviewable/pr11987/r1
David 2 weeks ago committed by GitHub
parent 21213f35af
commit 04eec52eee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -19,6 +19,7 @@ local ffiUtil = require("ffi/util")
local time = require("ui/time")
local _ = require("gettext")
local C_ = _.pgettext
local N_ = _.npgettext
local T = ffiUtil.template
local Screen = Device.screen
@ -601,11 +602,11 @@ Except when in two columns mode, where this is limited to showing only the previ
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))
return T(_("Rate of movement in content selection: %1"), G_reader_settings:readSetting("highlight_non_touch_factor") or 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 curr_val = G_reader_settings:readSetting("highlight_non_touch_factor") or 4
local spin_widget = SpinWidget:new{
value = curr_val,
value_min = 0.25,
@ -637,18 +638,15 @@ Except when in two columns mode, where this is limited to showing only the previ
})
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
local highlight_non_touch_interval = G_reader_settings:readSetting("highlight_non_touch_interval") or 1
return T(N_("Speed-up rate interval: %1 second", "Speed-up rate interval: %1 seconds", highlight_non_touch_interval), highlight_non_touch_interval)
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 curr_val = G_reader_settings:readSetting("highlight_non_touch_interval") or 1
local spin_widget = SpinWidget:new{
value = curr_val,
value_min = 0.1,
@ -2274,7 +2272,7 @@ function ReaderHighlight:onMoveHighlightIndicator(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, 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 move_distance = Size.item.height_default / (G_reader_settings:readSetting("highlight_non_touch_factor") or 4)
local rect = self._current_indicator_pos:copy()
if quick_move then
rect.x = rect.x + quick_move_distance_dx * dx
@ -2289,8 +2287,8 @@ function ReaderHighlight:onMoveHighlightIndicator(args)
-- 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
local t_inter = G_reader_settings:readSetting("highlight_non_touch_interval") or 1
if diff < time.s( t_inter ) then
move_distance = self._last_indicator_move_args.distance * 4
end
end

@ -21,10 +21,12 @@ local _ = require("gettext")
local ReaderThumbnail = WidgetContainer:extend{}
function ReaderThumbnail:init()
if not Device:isTouchDevice() then
self:registerKeyEvents()
if not Device:isTouchDevice() and not Device:useDPadAsActionKeys() then
-- The BookMap and PageBrowser widgets depend too much on gestures,
-- making them work with keys would be hard and very limited, so
-- making them work with not enough keys on Non-Touch would be hard and very limited, so
-- just don't make them available.
-- We will only let BookMap run on useDPadAsActionKeys devices.
return
end
@ -62,6 +64,16 @@ function ReaderThumbnail:init()
end
end
function ReaderThumbnail:registerKeyEvents()
if Device:hasDPad() and Device:useDPadAsActionKeys() then
if Device:hasKeyboard() then
self.key_events.ShowBookMap = { { "Shift", "Down" } }
else
self.key_events.ShowBookMap = { { "ScreenKB", "Down" } }
end
end
end
function ReaderThumbnail:addToMainMenu(menu_items)
menu_items.book_map = {
text = _("Book map"),
@ -75,6 +87,8 @@ function ReaderThumbnail:addToMainMenu(menu_items)
self:onShowBookMap(true)
end,
}
-- PageBrowser still needs some work before we can let it run on non-touch devices with useDPadAsActionKeys
if Device:hasDPad() and Device:useDPadAsActionKeys() then return end
menu_items.page_browser = {
text = _("Page browser"),
callback = function()

@ -632,13 +632,20 @@ function BookMapWidget:init()
self.covers_fullscreen = true -- hint for UIManager:_repaint()
if Device:hasKeys() then
self.key_events = {
Close = { { Input.group.Back } },
ScrollRowUp = { { "Up" } },
ScrollRowDown = { { "Down" } },
ScrollPageUp = { { Input.group.PgBack } },
ScrollPageDown = { { Input.group.PgFwd } },
}
self.key_events.Close = { { Device.input.group.Back } }
self.key_events.ShowBookMapMenu = { { "Menu" } }
self.key_events.ScrollPageUp = { { Input.group.PgBack } }
self.key_events.ScrollPageDown = { { Input.group.PgFwd } }
if Device:hasSymKey() then
self.key_events.ScrollRowUp = { { "Shift", "Up" } }
self.key_events.ScrollRowDown = { { "Shift", "Down" } }
elseif Device:hasScreenKB() then
self.key_events.ScrollRowUp = { { "ScreenKB", "Up" } }
self.key_events.ScrollRowDown = { { "ScreenKB", "Down" } }
else
self.key_events.ScrollRowUp = { { "Up" } }
self.key_events.ScrollRowDown = { { "Down" } }
end
end
if Device:isTouchDevice() then
self.ges_events = {
@ -702,7 +709,7 @@ function BookMapWidget:init()
fullscreen = true,
title = title,
left_icon = "appbar.menu",
left_icon_tap_callback = function() self:showMenu() end,
left_icon_tap_callback = function() self:onShowBookMapMenu() end,
left_icon_hold_callback = not self.overview_mode and function()
self:toggleDefaultSettings() -- toggle between user settings and default view
end,
@ -1181,7 +1188,7 @@ function BookMapWidget:update()
end
function BookMapWidget:showMenu()
function BookMapWidget:onShowBookMapMenu()
local button_dialog
-- Width of our -/+ buttons, so it looks fine with Button's default font size of 20
local plus_minus_width = Screen:scaleBySize(60)
@ -1223,7 +1230,7 @@ function BookMapWidget:showMenu()
end,
}},
not self.overview_mode and {{
text = _("Switch current/initial views"),
text = _("Switch current/initial view"),
align = "left",
enabled_func = function() return self.toc_depth > 0 end,
callback = function()
@ -1269,7 +1276,7 @@ function BookMapWidget:showMenu()
},
not self.overview_mode and {
{
text = _("Page slot width"),
text = _("Page-slot width"),
callback = function() end,
align = "left",
-- Below, minus increases page per row and plus decreases it.
@ -1324,6 +1331,10 @@ function BookMapWidget:showMenu()
}
},
}
-- remove "Page browser on tap" from non-touch devices
if not Device:isTouchDevice() then
table.remove(buttons, 3)
end
-- Remove false buttons from the list if overview_mode
for i = #buttons, 1, -1 do
if not buttons[i] then
@ -1341,13 +1352,12 @@ function BookMapWidget:showMenu()
}
UIManager:show(button_dialog)
end
function BookMapWidget:showAbout()
local text = _([[
Book map displays an overview of the book content.
Book map provides a summary of a book's content, showing chapters and pages visually. If statistics are enabled, black bars represent pages already read (gray for pages read in the current session), with varying heights based on reading time.
If statistics are enabled, black bars are shown for already read pages (gray for pages read in the current reading session). Their heights vary depending on the time spent reading the page.
Chapters are shown above the pages they encompass.
Under the pages, these indicators may be shown:
Map legend:
current page
previous locations
highlighted text
@ -1357,17 +1367,24 @@ Under the pages, these indicators may be shown:
if self.overview_mode then
text = text .. "\n\n" .. _([[
In overview mode, the book map is always in grid mode and made to fit on a single screen. Chapter levels can be changed for the most comfortable overview.]])
When in overview mode, the book map is always displayed in grid mode to fit on one screen. The chapter levels can be easily adjusted for the most convenient overview experience.]])
else
text = text .. "\n\n" .. _([[
On a newly opened book, the book map will start in grid mode showing all chapter levels, fitting on a single screen, to give the best initial overview of the book's content.]])
When you first open a book, the book map will begin in grid mode, displaying all chapter levels on one screen for a comprehensive overview of the book's content.]])
end
UIManager:show(InfoMessage:new{ text = text })
end
function BookMapWidget:showGestures()
local text
if self.overview_mode then
if not Device:isTouchDevice() then
text = _([[
Use settings in this menu to change the level of chapters to include in the book map, the view type (grid or flat) and the width of page slots.
Use "ScreenKB/Shift" + "Up/Down" to scroll or use the page turn buttons to move at a faster rate.
Press back to exit the book map.]])
elseif self.overview_mode then
text = _([[
Tap on a location in the book to browse thumbnails of the pages there.

@ -57,6 +57,7 @@ local UIManager = require("ui/uimanager")
local VerticalGroup = require("ui/widget/verticalgroup")
local VerticalSpan = require("ui/widget/verticalspan")
local Screen = Device.screen
local util = require("util")
local ButtonDialog = InputContainer:extend{
buttons = nil,
@ -91,8 +92,14 @@ function ButtonDialog:init()
end
if self.dismissable then
if Device:hasKeys() then
local close_keys = Device:hasFewKeys() and { "Back", "Left" } or Device.input.group.Back
self.key_events.Close = { { close_keys } }
local back_group = util.tableDeepCopy(Device.input.group.Back)
if Device:hasFewKeys() then
table.insert(back_group, "Left")
self.key_events.Close = { { back_group } }
else
table.insert(back_group, "Menu")
self.key_events.Close = { { back_group } }
end
end
if Device:isTouchDevice() then
self.ges_events.TapClose = {

Loading…
Cancel
Save