mirror of
https://github.com/koreader/koreader
synced 2024-11-04 12:00:25 +00:00
PageBrowser: show page number alongside thumbnails
Add a top left menu item -/+ to show none, only on the first thumbnail of a row, or on all thumbnails. Also make the page slot separator longer in the bottom ribbon before pages that start a thumbnails row. Also show a little spike in the bottom ribbon below page slots that get their page number displayed, to ease figuring out the connection.
This commit is contained in:
parent
7bae2ed920
commit
04fba2205d
@ -304,6 +304,7 @@ function BookMapRow:init()
|
||||
self.indicators = {}
|
||||
self.bottom_texts = {}
|
||||
local prev_page_was_read = true -- avoid one at start of row
|
||||
local extended_marker_h = math.ceil(self.span_height * 0.3)
|
||||
local unread_marker_h = math.ceil(self.span_height * 0.05)
|
||||
local read_min_h = math.max(math.ceil(self.span_height * 0.1), unread_marker_h+Size.line.thick)
|
||||
if self.page_slot_width >= 5 * unread_marker_h then
|
||||
@ -359,6 +360,35 @@ function BookMapRow:init()
|
||||
end
|
||||
prev_page_was_read = false
|
||||
end
|
||||
-- Extended separators below the baseline if requested (by PageBrowser
|
||||
-- to show the start of thumbnail rows)
|
||||
if self.extended_sep_pages and self.extended_sep_pages[page] then
|
||||
local w = Size.line.thin
|
||||
local x
|
||||
if _mirroredUI then
|
||||
x = self:getPageX(page, true) - w
|
||||
else
|
||||
x = self:getPageX(page)
|
||||
end
|
||||
local y = self.pages_frame_height - self.pages_frame_border
|
||||
table.insert(self.pages_markers, {
|
||||
x = x, y = y,
|
||||
w = w, h = extended_marker_h,
|
||||
color = Blitbuffer.COLOR_BLACK,
|
||||
})
|
||||
end
|
||||
-- Add a little spike below the baseline above each page number displayed, so we
|
||||
-- can more easily associate the (possibly wider) page number to its page slot.
|
||||
if self.page_texts and self.page_texts[page] then
|
||||
local w = Screen:scaleBySize(2)
|
||||
local x = math.floor((self:getPageX(page) + self:getPageX(page, true) + 0.5)/2 - w/2)
|
||||
local y = self.pages_frame_height - self.pages_frame_border + 2
|
||||
table.insert(self.pages_markers, {
|
||||
x = x, y = y,
|
||||
w = w, h = math.ceil(w*1.5),
|
||||
color = Blitbuffer.COLOR_BLACK,
|
||||
})
|
||||
end
|
||||
-- Indicator for bookmark/highlight type, and current page
|
||||
if self.bookmarked_pages[page] then
|
||||
local page_bookmark_types = self.bookmarked_pages[page]
|
||||
|
@ -13,6 +13,7 @@ local InfoMessage = require("ui/widget/infomessage")
|
||||
local InputContainer = require("ui/widget/container/inputcontainer")
|
||||
local OverlapGroup = require("ui/widget/overlapgroup")
|
||||
local Size = require("ui/size")
|
||||
local TextBoxWidget = require("ui/widget/textboxwidget")
|
||||
local TextWidget = require("ui/widget/textwidget")
|
||||
local TitleBar = require("ui/widget/titlebar")
|
||||
local UIManager = require("ui/uimanager")
|
||||
@ -21,6 +22,7 @@ local VerticalSpan = require("ui/widget/verticalspan")
|
||||
local Input = Device.input
|
||||
local Screen = Device.screen
|
||||
local logger = require("logger")
|
||||
local util = require("util")
|
||||
local _ = require("gettext")
|
||||
|
||||
-- We use the BookMapRow widget, a local widget defined in bookmapwidget.lua,
|
||||
@ -134,6 +136,21 @@ function PageBrowserWidget:init()
|
||||
self.span_height = test_w:getSize().h + BookMapRow.toc_span_border
|
||||
test_w:free()
|
||||
|
||||
-- For page numbers alongside thumbnails, use the same font size
|
||||
-- we use for them in the ribbon
|
||||
self.page_num_font_face = Font:getFace("infofont", 10)
|
||||
if not self.page_num_width then
|
||||
-- We'll be displaying the number vertically, so get the width we'd need
|
||||
-- to display some wide single char (this will influence side and inter
|
||||
-- thumbnails margins).
|
||||
test_w = TextWidget:new{
|
||||
text = "W",
|
||||
face = self.page_num_font_face,
|
||||
}
|
||||
self.page_num_width = test_w:getWidth()
|
||||
test_w:free()
|
||||
end
|
||||
|
||||
self.min_nb_rows = 1
|
||||
self.max_nb_rows = 6
|
||||
self.min_nb_cols = 1
|
||||
@ -245,7 +262,9 @@ function PageBrowserWidget:updateLayout()
|
||||
end
|
||||
self.nb_grid_items = self.nb_rows * self.nb_cols
|
||||
-- Set our items target size
|
||||
self.grid_item_margin = Screen:scaleBySize(10) -- borders will eat into this, it should be larger than borders thin+thick
|
||||
-- Borders may eat into the margin, and the horizontal margin should be able to contain the page number
|
||||
-- (let's use this computed margin also vertically)
|
||||
self.grid_item_margin = self.page_num_width + Size.padding.small + Size.border.thick + Size.border.thin
|
||||
self.grid_item_height = math.floor((self.grid_height - (self.nb_rows)*self.grid_item_margin) / self.nb_rows) -- no need for top margin, title bottom padding is enough
|
||||
self.grid_item_width = math.floor((self.grid_width - (1+self.nb_cols)*self.grid_item_margin) / self.nb_cols)
|
||||
self.grid_item_dimen = Geom:new{
|
||||
@ -255,9 +274,17 @@ function PageBrowserWidget:updateLayout()
|
||||
|
||||
self.grid:clear()
|
||||
|
||||
self.thumbnails_pagenums = self.ui.doc_settings:readSetting("page_browser_thumbnails_pagenums")
|
||||
or G_reader_settings:readSetting("page_browser_thumbnails_pagenums") or 2
|
||||
for idx = 1, self.nb_grid_items do
|
||||
local row = math.floor((idx-1)/self.nb_cols) -- start from 0
|
||||
local col = (idx-1) % self.nb_cols
|
||||
local show_pagenum -- no page number shown on the left side of a thumbnail, unless:
|
||||
if self.thumbnails_pagenums == 1 then -- only for the first thumbnail of each row
|
||||
show_pagenum = col == 0
|
||||
elseif self.thumbnails_pagenums == 2 then -- for all thumnbnails
|
||||
show_pagenum = true
|
||||
end
|
||||
if BD.mirroredUILayout() then
|
||||
col = self.nb_cols - col - 1
|
||||
end
|
||||
@ -267,6 +294,7 @@ function PageBrowserWidget:updateLayout()
|
||||
dimen = self.grid_item_dimen:copy(),
|
||||
}
|
||||
table.insert(self.grid, FrameContainer:new{
|
||||
show_pagenum = show_pagenum,
|
||||
overlap_offset = {offset_x, offset_y},
|
||||
margin = 0,
|
||||
padding = 0,
|
||||
@ -305,6 +333,14 @@ function PageBrowserWidget:update()
|
||||
end
|
||||
self.requests_batch_id = "PageBrowserWidget"..tostring(os.time())
|
||||
|
||||
for i=#self.grid, 1, -1 do
|
||||
if self.grid[i].is_page_num_widget then
|
||||
-- Remove page_num_widgets, as we'll be recreating them
|
||||
local widget = table.remove(self.grid, i)
|
||||
widget:free()
|
||||
end
|
||||
end
|
||||
|
||||
if not self.focus_page then
|
||||
self.focus_page = self.cur_page or 1
|
||||
end
|
||||
@ -326,64 +362,96 @@ function PageBrowserWidget:update()
|
||||
p_start = 1
|
||||
end
|
||||
|
||||
-- Extended separators below the baseline for pages starting thumbnail rows
|
||||
local extended_sep_pages = {}
|
||||
for p=grid_page_start+self.nb_cols, grid_page_end, self.nb_cols do
|
||||
extended_sep_pages[p] = true
|
||||
end
|
||||
|
||||
-- Show the page number or label at the bottom page slot every N slots, with N
|
||||
-- the nb of thumbnails so we get at least one page label in our viewport.
|
||||
local page_texts_cycle = math.min(self.nb_grid_items, 10) -- but max 10
|
||||
local next_p = p_start
|
||||
local cur_page_label_idx = 1
|
||||
local page_texts = {}
|
||||
local page_texts = {} -- to be provided to the bottom ribbon BookMapRow
|
||||
self.pagenum_page_texts = {} -- to be displayed alongside thumbnails
|
||||
for p=p_start, p_end do
|
||||
-- This may be expensive, so compute only the ones we need for display
|
||||
local show_at_bottom
|
||||
if p >= next_p then
|
||||
-- Only show a page text if there is no indicator on that slot
|
||||
if p ~= self.cur_page and not self.bookmarked_pages[p] and not self.previous_locations[p] then
|
||||
local page_text
|
||||
if self.page_labels then
|
||||
local page_label
|
||||
for idx=cur_page_label_idx, #self.page_labels do
|
||||
local item = self.page_labels[idx]
|
||||
if item.page >= p then
|
||||
if item.page == p then
|
||||
page_label = item.label
|
||||
end
|
||||
break
|
||||
show_at_bottom = true
|
||||
end
|
||||
end
|
||||
local show_near_thumbnail
|
||||
if p >= grid_page_start and p <= grid_page_end then
|
||||
show_near_thumbnail = self.grid[p - grid_page_start + 1].show_pagenum
|
||||
end
|
||||
if show_at_bottom or show_near_thumbnail then
|
||||
local page_text, thumbnail_page_text
|
||||
if self.page_labels then
|
||||
local page_label
|
||||
for idx=cur_page_label_idx, #self.page_labels do
|
||||
local item = self.page_labels[idx]
|
||||
if item.page >= p then
|
||||
if item.page == p then
|
||||
page_label = item.label
|
||||
end
|
||||
cur_page_label_idx = idx
|
||||
end
|
||||
if page_label then
|
||||
page_text = self.ui.pagemap:cleanPageLabel(page_label)
|
||||
end
|
||||
elseif self.has_hidden_flows then
|
||||
local flow = self.ui.document:getPageFlow(p)
|
||||
if flow == 0 then
|
||||
page_text = tostring(self.ui.document:getPageNumberInFlow(p))
|
||||
else
|
||||
page_text = string.format("[%d]%d", self.ui.document:getPageNumberInFlow(p), self.ui.document:getPageFlow(p))
|
||||
break
|
||||
end
|
||||
cur_page_label_idx = idx
|
||||
end
|
||||
if page_label then
|
||||
page_text = self.ui.pagemap:cleanPageLabel(page_label)
|
||||
elseif show_near_thumbnail then
|
||||
-- When reference pages may span multiple screen pages, the above may not get
|
||||
-- a page_text for some pages, which is fine for the bottom ribbon: it will
|
||||
-- display it for the next slot where a new reference page starts.
|
||||
-- But for thumbnails, we want to show some page number text, so fetch
|
||||
-- the previous one (that started on a previous screen page).
|
||||
thumbnail_page_text = self.ui.pagemap:cleanPageLabel(self.page_labels[cur_page_label_idx].label)
|
||||
end
|
||||
elseif self.has_hidden_flows then
|
||||
local flow = self.ui.document:getPageFlow(p)
|
||||
if flow == 0 then
|
||||
page_text = tostring(self.ui.document:getPageNumberInFlow(p))
|
||||
else
|
||||
page_text = tostring(p)
|
||||
local page_number_in_flow = self.ui.document:getPageNumberInFlow(p)
|
||||
local page_flow = self.ui.document:getPageFlow(p)
|
||||
page_text = string.format("[%d]%d", page_number_in_flow, page_flow)
|
||||
-- Use something that will feel alike brackets when vertically
|
||||
-- (Harfbuzz will properly mirror these if the UI is RTL)
|
||||
thumbnail_page_text = string.format("\u{2E1D}%d\u{2E0C}%d", page_number_in_flow, page_flow)
|
||||
end
|
||||
if page_text then
|
||||
local page_block, page_block_dx -- centered by default
|
||||
if p == p_start or p == grid_page_start or p == grid_page_end+1 then
|
||||
page_block = "left"
|
||||
page_block_dx = Size.padding.tiny
|
||||
if p == grid_page_start then
|
||||
page_block_dx = page_block_dx + self.view_finder_bw + 1
|
||||
end
|
||||
elseif p == p_end or p == grid_page_end or p == grid_page_start-1 then
|
||||
page_block = "right"
|
||||
page_block_dx = Size.padding.tiny
|
||||
if p == grid_page_end then
|
||||
page_block_dx = page_block_dx + self.view_finder_bw + 1
|
||||
end
|
||||
else
|
||||
page_text = tostring(p)
|
||||
end
|
||||
if page_text and show_at_bottom then
|
||||
local page_block, page_block_dx -- centered by default
|
||||
if p == p_start or p == grid_page_start or p == grid_page_end+1 then
|
||||
page_block = "left"
|
||||
page_block_dx = Size.padding.tiny
|
||||
if p == grid_page_start then
|
||||
page_block_dx = page_block_dx + self.view_finder_bw + 1
|
||||
end
|
||||
elseif p == p_end or p == grid_page_end or p == grid_page_start-1 then
|
||||
page_block = "right"
|
||||
page_block_dx = Size.padding.tiny
|
||||
if p == grid_page_end then
|
||||
page_block_dx = page_block_dx + self.view_finder_bw + 1
|
||||
end
|
||||
page_texts[p] = {
|
||||
text = page_text,
|
||||
block = page_block,
|
||||
block_dx = page_block_dx,
|
||||
}
|
||||
next_p = p + page_texts_cycle
|
||||
end
|
||||
page_texts[p] = {
|
||||
text = page_text,
|
||||
block = page_block,
|
||||
block_dx = page_block_dx,
|
||||
}
|
||||
next_p = p + page_texts_cycle
|
||||
end
|
||||
if show_near_thumbnail then
|
||||
-- Dedicated thumbnail_page_text, or the default one
|
||||
self.pagenum_page_texts[p] = thumbnail_page_text or page_text
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -477,6 +545,7 @@ function PageBrowserWidget:update()
|
||||
read_pages = self.read_pages,
|
||||
current_session_duration = self.current_session_duration,
|
||||
page_texts = page_texts,
|
||||
extended_sep_pages = extended_sep_pages,
|
||||
}
|
||||
self.row[1] = row
|
||||
|
||||
@ -601,6 +670,36 @@ function PageBrowserWidget:showTile(grid_idx, page, tile, do_refresh)
|
||||
-- thumb_frame will overflow its CenterContainer because of the added borders,
|
||||
-- but CenterContainer handles that well. We will refresh the outer dimensions.
|
||||
|
||||
local page_num_widget
|
||||
if item_frame.show_pagenum and self.pagenum_page_texts[page] then
|
||||
local page_text = table.concat(util.splitToChars(self.pagenum_page_texts[page]), "\n")
|
||||
page_num_widget = TextBoxWidget:new{
|
||||
text = page_text,
|
||||
width = self.page_num_width,
|
||||
face = self.page_num_font_face,
|
||||
line_height = 0, -- no additional line height
|
||||
alignment = BD.mirroredUILayout() and "left" or "right",
|
||||
alignment_strict = true,
|
||||
is_page_num_widget = true, -- so we can clear them in :update()
|
||||
}
|
||||
-- Only now that we know the thumbnail size, we can position this vertical
|
||||
-- page number widget alongside and at the top of the thumbnail left edge
|
||||
local thumb_frame_dimen = thumb_frame:getSize()
|
||||
local dw = self.grid_item_width - thumb_frame_dimen.w
|
||||
local dh = self.grid_item_height - thumb_frame_dimen.h
|
||||
local dx = math.floor(dw/2)
|
||||
local dy = math.floor(dh/2)
|
||||
local offset_y = item_frame.overlap_offset[2] + dy
|
||||
local offset_x
|
||||
if BD.mirroredUILayout() then
|
||||
offset_x = item_frame.overlap_offset[1] + self.grid_item_width - dx + Size.padding.small
|
||||
else
|
||||
offset_x = item_frame.overlap_offset[1] + dx - page_num_widget:getSize().w - Size.padding.small
|
||||
end
|
||||
page_num_widget.overlap_offset = {offset_x, offset_y}
|
||||
table.insert(self.grid, page_num_widget)
|
||||
end
|
||||
|
||||
if do_refresh then
|
||||
if self.wait_for_refresh_on_show_tile then
|
||||
self.wait_for_refresh_on_show_tile = nil
|
||||
@ -609,6 +708,9 @@ function PageBrowserWidget:showTile(grid_idx, page, tile, do_refresh)
|
||||
UIManager:waitForVSync()
|
||||
end
|
||||
UIManager:setDirty(self, function()
|
||||
if page_num_widget then
|
||||
return "ui", thumb_frame.dimen:combine(page_num_widget.dimen)
|
||||
end
|
||||
return "ui", thumb_frame.dimen
|
||||
end)
|
||||
end
|
||||
@ -687,6 +789,33 @@ function PageBrowserWidget:showMenu()
|
||||
width = plus_minus_width,
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
text = _("Thumbnail page numbers"),
|
||||
callback = function() end,
|
||||
align = "left",
|
||||
},
|
||||
{
|
||||
text = "\u{2796}", -- Heavy minus sign
|
||||
enabled_func = function() return self.thumbnails_pagenums > 0 end,
|
||||
callback = function()
|
||||
if self:updateThumbnailPageNumsDisplayType(-1, true) then
|
||||
self:updateLayout()
|
||||
end
|
||||
end,
|
||||
width = plus_minus_width,
|
||||
},
|
||||
{
|
||||
text = "\u{2795}", -- Heavy plus sign
|
||||
enabled_func = function() return self.thumbnails_pagenums < 2 end,
|
||||
callback = function()
|
||||
if self:updateThumbnailPageNumsDisplayType(1, true) then
|
||||
self:updateLayout()
|
||||
end
|
||||
end,
|
||||
width = plus_minus_width,
|
||||
}
|
||||
},
|
||||
{
|
||||
{
|
||||
text = _("Chapters in bottom ribbon"),
|
||||
@ -809,10 +938,12 @@ function PageBrowserWidget:saveSettings(reset)
|
||||
self.ui.doc_settings:saveSetting("page_browser_toc_depth", self.nb_toc_spans)
|
||||
self.ui.doc_settings:saveSetting("page_browser_nb_rows", self.nb_rows)
|
||||
self.ui.doc_settings:saveSetting("page_browser_nb_cols", self.nb_cols)
|
||||
self.ui.doc_settings:saveSetting("page_browser_thumbnails_pagenums", self.thumbnails_pagenums)
|
||||
-- We also save nb_rows/nb_cols as global settings, so they will apply on other books
|
||||
-- where they were not already set
|
||||
G_reader_settings:saveSetting("page_browser_nb_rows", self.nb_rows)
|
||||
G_reader_settings:saveSetting("page_browser_nb_cols", self.nb_cols)
|
||||
G_reader_settings:saveSetting("page_browser_thumbnails_pagenums", self.thumbnails_pagenums)
|
||||
end
|
||||
|
||||
function PageBrowserWidget:updateNbTocSpans(value, relative, rollover)
|
||||
@ -886,6 +1017,27 @@ function PageBrowserWidget:updateNbRows(value, relative)
|
||||
return true
|
||||
end
|
||||
|
||||
function PageBrowserWidget:updateThumbnailPageNumsDisplayType(value, relative)
|
||||
local new_thumbnails_pagenums
|
||||
if relative then
|
||||
new_thumbnails_pagenums = self.thumbnails_pagenums + value
|
||||
else
|
||||
new_thumbnails_pagenums = value
|
||||
end
|
||||
if new_thumbnails_pagenums < 0 then
|
||||
new_thumbnails_pagenums = 0
|
||||
end
|
||||
if new_thumbnails_pagenums > 2 then
|
||||
new_thumbnails_pagenums = 2
|
||||
end
|
||||
if new_thumbnails_pagenums == self.thumbnails_pagenums then
|
||||
return false
|
||||
end
|
||||
self.thumbnails_pagenums = new_thumbnails_pagenums
|
||||
self:saveSettings()
|
||||
return true
|
||||
end
|
||||
|
||||
function PageBrowserWidget:updateFocusPage(value, relative)
|
||||
local new_focus_page
|
||||
if relative then
|
||||
|
Loading…
Reference in New Issue
Block a user