mirror of
https://github.com/koreader/koreader.git
synced 2025-12-13 20:36:53 +01:00
Reference pages: improve Toc and status bar (#14363)
This commit is contained in:
@@ -103,6 +103,15 @@ end
|
|||||||
|
|
||||||
function ReaderGoto:gotoPage()
|
function ReaderGoto:gotoPage()
|
||||||
local page_number = self.goto_dialog:getInputText()
|
local page_number = self.goto_dialog:getInputText()
|
||||||
|
if self.ui.pagemap and self.ui.pagemap:wantsPageLabels() then
|
||||||
|
local label = self.ui.pagemap:cleanPageLabel(page_number)
|
||||||
|
local _, pn = self.ui.pagemap:getPageLabelProps(label)
|
||||||
|
if pn then
|
||||||
|
self:close()
|
||||||
|
self.ui:handleEvent(Event:new("GotoPage", pn))
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
local relative_sign = page_number:sub(1, 1)
|
local relative_sign = page_number:sub(1, 1)
|
||||||
local number = tonumber(page_number)
|
local number = tonumber(page_number)
|
||||||
if number then
|
if number then
|
||||||
@@ -110,16 +119,7 @@ function ReaderGoto:gotoPage()
|
|||||||
if relative_sign == "+" or relative_sign == "-" then
|
if relative_sign == "+" or relative_sign == "-" then
|
||||||
self.ui:handleEvent(Event:new("GotoRelativePage", number))
|
self.ui:handleEvent(Event:new("GotoRelativePage", number))
|
||||||
else
|
else
|
||||||
if self.ui.pagemap and self.ui.pagemap:wantsPageLabels() then
|
|
||||||
number = self.ui.pagemap:getRenderedPageNumber(page_number, true)
|
|
||||||
if number then -- found
|
|
||||||
self.ui:handleEvent(Event:new("GotoPage", number))
|
self.ui:handleEvent(Event:new("GotoPage", number))
|
||||||
else
|
|
||||||
return -- avoid self:close()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
self.ui:handleEvent(Event:new("GotoPage", number))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
self:close()
|
self:close()
|
||||||
elseif self.ui.document:hasHiddenFlows() then
|
elseif self.ui.document:hasHiddenFlows() then
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ local ReaderPageMap = WidgetContainer:extend{
|
|||||||
label_color = Blitbuffer.COLOR_BLACK,
|
label_color = Blitbuffer.COLOR_BLACK,
|
||||||
show_page_labels = nil,
|
show_page_labels = nil,
|
||||||
use_page_labels = nil,
|
use_page_labels = nil,
|
||||||
|
page_labels_cache = nil, -- hash table
|
||||||
}
|
}
|
||||||
|
|
||||||
function ReaderPageMap:init()
|
function ReaderPageMap:init()
|
||||||
@@ -302,17 +303,28 @@ function ReaderPageMap:getXPointerPageLabel(xp, clean_label)
|
|||||||
return clean_label and self:cleanPageLabel(label) or label
|
return clean_label and self:cleanPageLabel(label) or label
|
||||||
end
|
end
|
||||||
|
|
||||||
function ReaderPageMap:getRenderedPageNumber(page_label, cleaned)
|
function ReaderPageMap:getPageLabelProps(page_label)
|
||||||
-- Only used from ReaderGoTo. As page_label is a string, no
|
if self.page_labels_cache == nil then -- fill the cache
|
||||||
-- way to use a binary search: do a full scan of the PageMap
|
|
||||||
-- here in Lua, even if it's not cheap.
|
|
||||||
local page_list = self.ui.document:getPageMap()
|
local page_list = self.ui.document:getPageMap()
|
||||||
for k, v in ipairs(page_list) do
|
self.page_labels_cache = { #page_list }
|
||||||
local label = cleaned and self:cleanPageLabel(v.label) or v.label
|
for i, v in ipairs(page_list) do
|
||||||
if label == page_label then
|
local label = self:cleanPageLabel(v.label)
|
||||||
return v.page
|
self.page_labels_cache[label] = { i, v.page }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- expects cleaned page_label
|
||||||
|
if page_label then
|
||||||
|
local props = self.page_labels_cache[page_label]
|
||||||
|
if props then
|
||||||
|
return props[1], props[2] -- index, rendered page
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return self.page_labels_cache[1] -- total number of labels
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ReaderPageMap:onDocumentRerendered()
|
||||||
|
self.page_labels_cache = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
function ReaderPageMap:addToMainMenu(menu_items)
|
function ReaderPageMap:addToMainMenu(menu_items)
|
||||||
@@ -345,6 +357,9 @@ function ReaderPageMap:addToMainMenu(menu_items)
|
|||||||
text = _("Use reference page numbers"),
|
text = _("Use reference page numbers"),
|
||||||
checked_func = function() return self.use_page_labels end,
|
checked_func = function() return self.use_page_labels end,
|
||||||
callback = function()
|
callback = function()
|
||||||
|
if self.use_page_labels then
|
||||||
|
self.page_labels_cache = nil
|
||||||
|
end
|
||||||
self.use_page_labels = not self.use_page_labels
|
self.use_page_labels = not self.use_page_labels
|
||||||
self.ui.doc_settings:saveSetting("pagemap_use_page_labels", self.use_page_labels)
|
self.ui.doc_settings:saveSetting("pagemap_use_page_labels", self.use_page_labels)
|
||||||
-- Reset a few stuff that may use page labels
|
-- Reset a few stuff that may use page labels
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ function ReaderToc:completeTocWithChapterLengths()
|
|||||||
prev_item_by_level[depth] = item
|
prev_item_by_level[depth] = item
|
||||||
end
|
end
|
||||||
-- Set the length of the last ones
|
-- Set the length of the last ones
|
||||||
local page = self.ui.document:getPageCount()
|
local page = self.ui.document:getPageCount() + 1
|
||||||
for j=#prev_item_by_level, 0, -1 do
|
for j=#prev_item_by_level, 0, -1 do
|
||||||
local prev_item = prev_item_by_level[j]
|
local prev_item = prev_item_by_level[j]
|
||||||
if prev_item then
|
if prev_item then
|
||||||
@@ -350,6 +350,40 @@ function ReaderToc:completeTocWithChapterLengths()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function ReaderToc:completeTocWithChapterLengthsFromPagemap()
|
||||||
|
local toc = self.toc
|
||||||
|
local first = 1
|
||||||
|
local last = #toc
|
||||||
|
if last == 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local prev_item_by_level = {}
|
||||||
|
for i = first, last do
|
||||||
|
local item = toc[i]
|
||||||
|
local page, chapter_starts_new_ref_page = self:getPagePagemapIndex(item.page)
|
||||||
|
local extra_page = chapter_starts_new_ref_page and 0 or 1
|
||||||
|
local depth = item.depth
|
||||||
|
for j=#prev_item_by_level, depth, -1 do
|
||||||
|
local prev_item = prev_item_by_level[j]
|
||||||
|
if prev_item then
|
||||||
|
local prev_page = self:getPagePagemapIndex(prev_item.page)
|
||||||
|
prev_item.chapter_length = page and prev_page and (page - prev_page + extra_page) or "\u{2013}"
|
||||||
|
end
|
||||||
|
prev_item_by_level[j] = nil
|
||||||
|
end
|
||||||
|
prev_item_by_level[depth] = item
|
||||||
|
end
|
||||||
|
-- Set the length of the last ones
|
||||||
|
local page = self.ui.pagemap:getPageLabelProps() -- last label index
|
||||||
|
for j=#prev_item_by_level, 0, -1 do
|
||||||
|
local prev_item = prev_item_by_level[j]
|
||||||
|
if prev_item then
|
||||||
|
local prev_page = self:getPagePagemapIndex(prev_item.page)
|
||||||
|
prev_item.chapter_length = page and prev_page and (page - prev_page + 1) or "\u{2013}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function ReaderToc:getTocIndexByPage(pn_or_xp, skip_ignored_ticks)
|
function ReaderToc:getTocIndexByPage(pn_or_xp, skip_ignored_ticks)
|
||||||
self:fillToc()
|
self:fillToc()
|
||||||
if #self.toc == 0 then return end
|
if #self.toc == 0 then return end
|
||||||
@@ -625,7 +659,48 @@ function ReaderToc:isChapterEnd(cur_pageno)
|
|||||||
return _end
|
return _end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function ReaderToc:getPagePagemapIndex(pageno)
|
||||||
|
-- for chapters, pageno is a rendered page number where the chapter title is displayed
|
||||||
|
if pageno then
|
||||||
|
local xp = self.ui.document:getPageXPointer(pageno)
|
||||||
|
if xp then
|
||||||
|
-- reference page (label) of the top of the displayed page
|
||||||
|
-- (the label itself may be displayed in one of the previous pages)
|
||||||
|
local label = self.ui.pagemap:getXPointerPageLabel(xp, true)
|
||||||
|
-- label_pn - rendered page number where the label is displayed
|
||||||
|
local index, label_pn = self.ui.pagemap:getPageLabelProps(label)
|
||||||
|
if index then
|
||||||
|
return index, label_pn == pageno -- true if chapter starts at new ref page
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ReaderToc:getPreviousChapterPagemapIndex(pageno)
|
||||||
|
local chapter_pn = self:isChapterStart(pageno) and pageno or self:getPreviousChapter(pageno)
|
||||||
|
return self:getPagePagemapIndex(chapter_pn) or 1
|
||||||
|
end
|
||||||
|
|
||||||
|
function ReaderToc:getNextChapterPagemapIndex(pageno)
|
||||||
|
local chapter_pn = self:getNextChapter(pageno)
|
||||||
|
if chapter_pn then
|
||||||
|
return self:getPagePagemapIndex(chapter_pn) -- chapter_idx, chapter_starts_new_ref_page
|
||||||
|
else -- last chapter
|
||||||
|
return self.ui.pagemap:getPageLabelProps() -- last index
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function ReaderToc:getChapterPageCount(pageno)
|
function ReaderToc:getChapterPageCount(pageno)
|
||||||
|
if self.ui.pagemap and self.ui.pagemap:wantsPageLabels() then
|
||||||
|
local prev_chapter_idx = self:getPreviousChapterPagemapIndex(pageno)
|
||||||
|
if prev_chapter_idx then
|
||||||
|
local next_chapter_idx, chapter_starts_new_ref_page = self:getNextChapterPagemapIndex(pageno)
|
||||||
|
if next_chapter_idx then
|
||||||
|
return next_chapter_idx - prev_chapter_idx + (chapter_starts_new_ref_page and 0 or 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local next_chapter = self:getNextChapter(pageno) or self.ui.document:getPageCount() + 1
|
local next_chapter = self:getNextChapter(pageno) or self.ui.document:getPageCount() + 1
|
||||||
local previous_chapter = self:isChapterStart(pageno) and pageno or self:getPreviousChapter(pageno) or 1
|
local previous_chapter = self:isChapterStart(pageno) and pageno or self:getPreviousChapter(pageno) or 1
|
||||||
local page_count = next_chapter - previous_chapter
|
local page_count = next_chapter - previous_chapter
|
||||||
@@ -642,6 +717,16 @@ function ReaderToc:getChapterPageCount(pageno)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function ReaderToc:getChapterPagesLeft(pageno)
|
function ReaderToc:getChapterPagesLeft(pageno)
|
||||||
|
if self.ui.pagemap and self.ui.pagemap:wantsPageLabels() then
|
||||||
|
local page_idx = self:getPagePagemapIndex(pageno)
|
||||||
|
if page_idx then
|
||||||
|
local next_chapter_idx, chapter_starts_new_ref_page = self:getNextChapterPagemapIndex(pageno)
|
||||||
|
if next_chapter_idx then
|
||||||
|
return next_chapter_idx - page_idx - (chapter_starts_new_ref_page and 1 or 0)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local next_chapter = self:getNextChapter(pageno)
|
local next_chapter = self:getNextChapter(pageno)
|
||||||
if not next_chapter then
|
if not next_chapter then
|
||||||
-- (ReaderFooter deals itself with nil and pageno in last chapter)
|
-- (ReaderFooter deals itself with nil and pageno in last chapter)
|
||||||
@@ -660,6 +745,17 @@ end
|
|||||||
|
|
||||||
function ReaderToc:getChapterPagesDone(pageno)
|
function ReaderToc:getChapterPagesDone(pageno)
|
||||||
if self:isChapterStart(pageno) then return 0 end
|
if self:isChapterStart(pageno) then return 0 end
|
||||||
|
|
||||||
|
if self.ui.pagemap and self.ui.pagemap:wantsPageLabels() then
|
||||||
|
local page_idx = self:getPagePagemapIndex(pageno)
|
||||||
|
if page_idx then
|
||||||
|
local prev_chapter_idx = self:getPreviousChapterPagemapIndex(pageno)
|
||||||
|
if prev_chapter_idx then
|
||||||
|
return page_idx - prev_chapter_idx
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local previous_chapter = self:getPreviousChapter(pageno)
|
local previous_chapter = self:getPreviousChapter(pageno)
|
||||||
if not previous_chapter then
|
if not previous_chapter then
|
||||||
-- (ReaderFooter deals itself with nil and pageno not yet in first chapter)
|
-- (ReaderFooter deals itself with nil and pageno not yet in first chapter)
|
||||||
@@ -727,8 +823,12 @@ function ReaderToc:onShowToc()
|
|||||||
if #self.toc > 0 and not self.toc_menu_items_built then
|
if #self.toc > 0 and not self.toc_menu_items_built then
|
||||||
self.toc_menu_items_built = true
|
self.toc_menu_items_built = true
|
||||||
if items_show_chapter_length then
|
if items_show_chapter_length then
|
||||||
|
if self.ui.pagemap and self.ui.pagemap:wantsPageLabels() then
|
||||||
|
self:completeTocWithChapterLengthsFromPagemap()
|
||||||
|
else
|
||||||
self:completeTocWithChapterLengths()
|
self:completeTocWithChapterLengths()
|
||||||
end
|
end
|
||||||
|
end
|
||||||
-- Have the width of 4 spaces be the unit of indentation
|
-- Have the width of 4 spaces be the unit of indentation
|
||||||
local tmp = TextWidget:new{
|
local tmp = TextWidget:new{
|
||||||
text = " ",
|
text = " ",
|
||||||
|
|||||||
Reference in New Issue
Block a user