mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
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.
This commit is contained in:
@@ -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 = {
|
||||
|
||||
Reference in New Issue
Block a user