mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
ReaderToc: add option to show chapter lengths (#11546)
This commit is contained in:
@@ -104,6 +104,7 @@ end
|
||||
|
||||
function ReaderToc:resetToc()
|
||||
self.toc = nil
|
||||
self.toc_menu_items_built = false
|
||||
self.toc_depth = nil
|
||||
self.ticks = nil
|
||||
self.ticks_flattened = nil
|
||||
@@ -314,6 +315,37 @@ function ReaderToc:validateAndFixToc()
|
||||
self.toc_depth = max_depth
|
||||
end
|
||||
|
||||
function ReaderToc:completeTocWithChapterLengths()
|
||||
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 = item.page
|
||||
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
|
||||
prev_item.chapter_length = page - prev_item.page
|
||||
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.document:getPageCount()
|
||||
for j=#prev_item_by_level, 0, -1 do
|
||||
local prev_item = prev_item_by_level[j]
|
||||
if prev_item then
|
||||
prev_item.chapter_length = page - prev_item.page
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ReaderToc:getTocIndexByPage(pn_or_xp, skip_ignored_ticks)
|
||||
self:fillToc()
|
||||
if #self.toc == 0 then return end
|
||||
@@ -661,11 +693,16 @@ function ReaderToc:onShowToc()
|
||||
|
||||
local items_per_page = G_reader_settings:readSetting("toc_items_per_page") or self.toc_items_per_page_default
|
||||
local items_font_size = G_reader_settings:readSetting("toc_items_font_size") or Menu.getItemFontSize(items_per_page)
|
||||
local items_show_chapter_length = G_reader_settings:isTrue("toc_items_show_chapter_length")
|
||||
local items_with_dots = G_reader_settings:nilOrTrue("toc_items_with_dots")
|
||||
|
||||
self:fillToc()
|
||||
-- build menu items
|
||||
if #self.toc > 0 and not self.toc[1].text then
|
||||
if #self.toc > 0 and not self.toc_menu_items_built then
|
||||
self.toc_menu_items_built = true
|
||||
if items_show_chapter_length then
|
||||
self:completeTocWithChapterLengths()
|
||||
end
|
||||
-- Have the width of 4 spaces be the unit of indentation
|
||||
local tmp = TextWidget:new{
|
||||
text = " ",
|
||||
@@ -679,6 +716,11 @@ function ReaderToc:onShowToc()
|
||||
v.index = k
|
||||
v.indent = toc_indent * (v.depth-1)
|
||||
v.text = self:cleanUpTocTitle(v.title, true)
|
||||
if items_show_chapter_length then
|
||||
v.post_text = T("(%1)", v.chapter_length)
|
||||
else
|
||||
v.post_text = nil
|
||||
end
|
||||
v.bidi_wrap_func = BD.auto
|
||||
v.mandatory = v.page
|
||||
if has_hidden_flows then
|
||||
@@ -1147,6 +1189,17 @@ Enabling this option will restrict display to the chapter titles of progress bar
|
||||
UIManager:show(items_font)
|
||||
end,
|
||||
}
|
||||
menu_items.toc_items_show_chapter_length = {
|
||||
text = _("Show chapter length"),
|
||||
keep_menu_open = true,
|
||||
checked_func = function()
|
||||
return not G_reader_settings:nilOrFalse("toc_items_show_chapter_length")
|
||||
end,
|
||||
callback = function()
|
||||
G_reader_settings:flipNilOrFalse("toc_items_show_chapter_length")
|
||||
self.toc_menu_items_built = false
|
||||
end
|
||||
}
|
||||
menu_items.toc_items_with_dots = {
|
||||
text = _("With dots"),
|
||||
keep_menu_open = true,
|
||||
|
||||
@@ -35,6 +35,7 @@ local order = {
|
||||
"----------------------------",
|
||||
"toc_items_per_page",
|
||||
"toc_items_font_size",
|
||||
"toc_items_show_chapter_length",
|
||||
"toc_items_with_dots",
|
||||
"----------------------------",
|
||||
"toc_alt_toc",
|
||||
|
||||
@@ -184,6 +184,12 @@ function MenuItem:init()
|
||||
self.face = Font:getFace(self.font, self.font_size)
|
||||
-- Font for "mandatory" on the right
|
||||
self.info_face = Font:getFace(self.infont, self.infont_size)
|
||||
-- Font for post_text if any: for now, this is only used with TOC, showing
|
||||
-- the chapter length: if feels best to use the face of the main text, but
|
||||
-- with the size of the mandatory font (which shows some number too).
|
||||
if self.post_text then
|
||||
self.post_text_face = Font:getFace(self.font, self.infont_size)
|
||||
end
|
||||
|
||||
-- "mandatory" is the text on the right: file size, page number...
|
||||
-- Padding before mandatory
|
||||
@@ -219,10 +225,23 @@ function MenuItem:init()
|
||||
text = self.bidi_wrap_func(text)
|
||||
end
|
||||
|
||||
-- Note: support for post_text is currently implemented only when single_line=true
|
||||
local post_text_widget
|
||||
local post_text_left_padding = Size.padding.large
|
||||
local post_text_right_padding = self.with_dots and 0 or Size.padding.large
|
||||
local dots_widget
|
||||
local dots_left_padding = Size.padding.small
|
||||
local dots_right_padding = Size.padding.small
|
||||
if self.single_line then -- items only in single line
|
||||
if self.post_text then
|
||||
post_text_widget = TextWidget:new{
|
||||
text = self.post_text,
|
||||
face = self.post_text_face,
|
||||
bold = self.bold,
|
||||
fgcolor = self.dim and Blitbuffer.COLOR_DARK_GRAY or nil,
|
||||
}
|
||||
available_width = available_width - post_text_widget:getWidth() - post_text_left_padding - post_text_right_padding
|
||||
end
|
||||
-- No font size change: text will be truncated if it overflows
|
||||
item_name = TextWidget:new{
|
||||
text = text,
|
||||
@@ -271,6 +290,9 @@ function MenuItem:init()
|
||||
if dots_widget then
|
||||
dots_widget.forced_height = self.dimen.h
|
||||
end
|
||||
if post_text_widget then
|
||||
post_text_widget.forced_height = self.dimen.h
|
||||
end
|
||||
-- And adjust their baselines for proper centering and alignment
|
||||
-- (We made sure the font sizes wouldn't exceed self.dimen.h, so we
|
||||
-- get only non-negative pad_top here, and we're moving them down.)
|
||||
@@ -289,6 +311,9 @@ function MenuItem:init()
|
||||
if dots_widget then
|
||||
dots_widget.forced_baseline = mdtr_baseline
|
||||
end
|
||||
if post_text_widget then
|
||||
post_text_widget.forced_baseline = mdtr_baseline
|
||||
end
|
||||
end
|
||||
|
||||
elseif self.multilines_show_more_text then
|
||||
@@ -374,6 +399,8 @@ function MenuItem:init()
|
||||
width = state_width,
|
||||
},
|
||||
item_name,
|
||||
post_text_widget and HorizontalSpan:new{ width = post_text_left_padding },
|
||||
post_text_widget,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1083,6 +1110,7 @@ function Menu:updateItems(select_number)
|
||||
state_w = self.state_w or 0,
|
||||
text = Menu.getMenuText(self.item_table[i]),
|
||||
bidi_wrap_func = self.item_table[i].bidi_wrap_func,
|
||||
post_text = self.item_table[i].post_text,
|
||||
mandatory = self.item_table[i].mandatory,
|
||||
mandatory_func = self.item_table[i].mandatory_func,
|
||||
mandatory_dim = self.item_table[i].mandatory_dim or self.item_table[i].dim,
|
||||
|
||||
Reference in New Issue
Block a user