mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
Allow following links and footnotes with keys (#6619)
Only with CreDocuments (as no way currently to highlight links in PDFs). Tab or Shift-Tab to select next or previous links. Press to follow (or show footnote in popup, and in there Press to follow), back to go back.
This commit is contained in:
@@ -24,6 +24,29 @@ local ReaderLink = InputContainer:new{
|
||||
}
|
||||
|
||||
function ReaderLink:init()
|
||||
if Device:hasKeys() then
|
||||
self.key_events.SelectNextPageLink = {
|
||||
{"Tab" },
|
||||
doc = "select next page link",
|
||||
event = "SelectNextPageLink",
|
||||
}
|
||||
self.key_events.SelectPrevPageLink = {
|
||||
{"Shift", "Tab" },
|
||||
{"Sym", "Tab" }, -- Right Shift + Tab
|
||||
doc = "select previous page link",
|
||||
event = "SelectPrevPageLink",
|
||||
}
|
||||
self.key_events.GotoSelectedPageLink = {
|
||||
{ "Press" },
|
||||
doc = "go to selected page link",
|
||||
event = "GotoSelectedPageLink",
|
||||
}
|
||||
self.key_events.GoBackLink = {
|
||||
{ "Back" },
|
||||
doc = "go back from link",
|
||||
event = "GoBackLink",
|
||||
}
|
||||
end
|
||||
if Device:isTouchDevice() then
|
||||
self.ui:registerTouchZones({
|
||||
{
|
||||
@@ -937,6 +960,101 @@ function ReaderLink:onGoToInternalPageLink(ges)
|
||||
self:onGoToPageLink(ges, true)
|
||||
end
|
||||
|
||||
function ReaderLink:onSelectNextPageLink()
|
||||
return self:selectRelPageLink(1)
|
||||
end
|
||||
|
||||
function ReaderLink:onSelectPrevPageLink()
|
||||
return self:selectRelPageLink(-1)
|
||||
end
|
||||
|
||||
function ReaderLink:selectRelPageLink(rel)
|
||||
if self.ui.document.info.has_pages then
|
||||
-- not implemented for now (see at doing like in showLinkBox()
|
||||
-- to highlight the link before jumping to it)
|
||||
return
|
||||
end
|
||||
-- Follow swipe_ignore_external_links setting to allow
|
||||
-- skipping external links when using keys
|
||||
local links = self.ui.document:getPageLinks(isSwipeIgnoreExternalLinksEnabled())
|
||||
if not links or #links == 0 then
|
||||
return
|
||||
end
|
||||
if self.cur_selected_page_link_num then
|
||||
self.cur_selected_page_link_num = self.cur_selected_page_link_num + rel
|
||||
-- When reaching end of list, don't immediately jump to
|
||||
-- the other side: allow one step with no link selected
|
||||
if self.cur_selected_page_link_num > #links then
|
||||
self.cur_selected_page_link_num = nil
|
||||
elseif self.cur_selected_page_link_num <= 0 then
|
||||
self.cur_selected_page_link_num = nil
|
||||
end
|
||||
else
|
||||
if rel > 0 then
|
||||
self.cur_selected_page_link_num = 1
|
||||
elseif rel < 0 then
|
||||
self.cur_selected_page_link_num = #links
|
||||
end
|
||||
end
|
||||
if not self.cur_selected_page_link_num then
|
||||
self.cur_selected_link = nil
|
||||
self.ui.document:highlightXPointer()
|
||||
UIManager:setDirty(self.dialog, "ui")
|
||||
return
|
||||
end
|
||||
local selected_link = links[self.cur_selected_page_link_num]
|
||||
logger.dbg("selected_link", selected_link)
|
||||
-- Check a_xpointer is coherent, use it as from_xpointer only if it is
|
||||
local from_xpointer = nil
|
||||
if selected_link.a_xpointer and self:isXpointerCoherent(selected_link.a_xpointer) then
|
||||
from_xpointer = selected_link.a_xpointer
|
||||
end
|
||||
local link_y
|
||||
if selected_link.segments and #selected_link.segments > 0 then
|
||||
link_y = selected_link.segments[#selected_link.segments].y1
|
||||
else
|
||||
link_y = selected_link.end_y
|
||||
end
|
||||
-- Make it a link as expected by onGotoLink
|
||||
self.cur_selected_link = {
|
||||
xpointer = selected_link.section or selected_link.uri,
|
||||
marker_xpointer = selected_link.section,
|
||||
from_xpointer = from_xpointer,
|
||||
-- (keep a_xpointer even if incoherent, might be needed for
|
||||
-- footnote detection (better than nothing if incoherent)
|
||||
a_xpointer = selected_link.a_xpointer,
|
||||
-- keep the link y position, so we can keep its highlight shown
|
||||
-- a bit more time if it was hidden by the footnote popup
|
||||
link_y = link_y,
|
||||
}
|
||||
self.ui.document:highlightXPointer() -- clear any previous one
|
||||
self.ui.document:highlightXPointer(self.cur_selected_link.from_xpointer)
|
||||
UIManager:setDirty(self.dialog, "ui")
|
||||
return true
|
||||
end
|
||||
|
||||
function ReaderLink:onGotoSelectedPageLink()
|
||||
if self.cur_selected_link then
|
||||
return self:onGotoLink(self.cur_selected_link, false, isFootnoteLinkInPopupEnabled())
|
||||
end
|
||||
end
|
||||
|
||||
function ReaderLink:onPageUpdate()
|
||||
if self.cur_selected_link then
|
||||
self.ui.document:highlightXPointer()
|
||||
self.cur_selected_page_link_num = nil
|
||||
self.cur_selected_link = nil
|
||||
end
|
||||
end
|
||||
|
||||
function ReaderLink:onPosUpdate()
|
||||
if self.cur_selected_link then
|
||||
self.ui.document:highlightXPointer()
|
||||
self.cur_selected_page_link_num = nil
|
||||
self.cur_selected_link = nil
|
||||
end
|
||||
end
|
||||
|
||||
function ReaderLink:onGoToLatestBookmark(ges)
|
||||
local latest_bookmark = self.ui.bookmark:getLatestBookmark()
|
||||
if latest_bookmark then
|
||||
|
||||
@@ -132,6 +132,7 @@ local Input = {
|
||||
Alt = false,
|
||||
Ctrl = false,
|
||||
Shift = false,
|
||||
Sym = false,
|
||||
},
|
||||
|
||||
-- repeat state:
|
||||
|
||||
@@ -6,6 +6,7 @@ return {
|
||||
[28] = "Y", [29] = "Z", [30] = "1", [31] = "2", [32] = "3", [33] = "4",
|
||||
[34] = "5", [35] = "6", [36] = "7", [37] = "8", [38] = "9", [39] = "0",
|
||||
|
||||
[43] = "Tab", -- Tab
|
||||
[42] = "Backspace", -- Backspace
|
||||
[41] = "Back", -- Escape
|
||||
[40] = "Press", -- Enter
|
||||
|
||||
@@ -195,7 +195,8 @@ function FootnoteWidget:init()
|
||||
end
|
||||
if Device:hasKeys() then
|
||||
self.key_events = {
|
||||
Close = { {"Back"}, doc = "cancel" }
|
||||
Close = { {"Back"}, doc = "cancel" },
|
||||
Follow = { {"Press"}, doc = "follow link" },
|
||||
}
|
||||
end
|
||||
|
||||
@@ -344,6 +345,15 @@ function FootnoteWidget:onClose()
|
||||
return true
|
||||
end
|
||||
|
||||
function FootnoteWidget:onFollow()
|
||||
if self.follow_callback then
|
||||
if self.close_callback then
|
||||
self.close_callback(self.height)
|
||||
end
|
||||
return self.follow_callback()
|
||||
end
|
||||
end
|
||||
|
||||
function FootnoteWidget:onTapClose(arg, ges)
|
||||
if ges.pos:notIntersectWith(self.container.dimen) then
|
||||
UIManager:close(self)
|
||||
|
||||
Reference in New Issue
Block a user