2
0
mirror of https://github.com/koreader/koreader synced 2024-11-10 01:10:34 +00:00

CoverBrowser: select nb of items in Detailed list mode

New menu options:
- Detailed list mode: select nb of items per page
- Series: new option to show it on a separate line
This commit is contained in:
Jörg Derungs 2019-10-22 23:49:04 +02:00 committed by poire-z
parent c7ecd08d9d
commit 946595fa46
3 changed files with 163 additions and 68 deletions

View File

@ -44,6 +44,9 @@ local BookInfoManager = require("bookinfomanager")
local corner_mark_size = -1 local corner_mark_size = -1
local corner_mark local corner_mark
local scale_by_size = Screen:scaleBySize(1000000) / 1000000
local max_fontsize_fileinfo
-- ItemShortCutIcon (for keyboard navigation) is private to menu.lua and can't be accessed, -- ItemShortCutIcon (for keyboard navigation) is private to menu.lua and can't be accessed,
-- so we need to redefine it -- so we need to redefine it
local ItemShortCutIcon = WidgetContainer:new{ local ItemShortCutIcon = WidgetContainer:new{
@ -185,6 +188,13 @@ function ListMenuItem:update()
h = self.height - 2 * self.underline_h h = self.height - 2 * self.underline_h
} }
local function _fontSize(nominal)
-- nominal font size is based on 64px ListMenuItem height
-- keep ratio of font size to item height
local font_size = nominal * dimen.h / 64 / scale_by_size
return math.floor(font_size)
end
-- We'll draw a border around cover images, it may not be -- We'll draw a border around cover images, it may not be
-- needed with some covers, but it's nicer when cover is -- needed with some covers, but it's nicer when cover is
-- a pure white background (like rendered text page) -- a pure white background (like rendered text page)
@ -192,7 +202,7 @@ function ListMenuItem:update()
local max_img_w = dimen.h - 2*border_size -- width = height, squared local max_img_w = dimen.h - 2*border_size -- width = height, squared
local max_img_h = dimen.h - 2*border_size local max_img_h = dimen.h - 2*border_size
local cover_specs = { local cover_specs = {
sizetag = "s", sizetag = "s"..max_img_h,
max_cover_w = max_img_w, max_cover_w = max_img_w,
max_cover_h = max_img_h, max_cover_h = max_img_h,
} }
@ -210,12 +220,12 @@ function ListMenuItem:update()
-- nb items on the right, directory name on the left -- nb items on the right, directory name on the left
local wright = TextWidget:new{ local wright = TextWidget:new{
text = self.mandatory, text = self.mandatory,
face = Font:getFace("infont", 15), face = Font:getFace("infont", math.min(max_fontsize_fileinfo, _fontSize(15))),
} }
local wleft_width = dimen.w - wright:getSize().w local wleft_width = dimen.w - wright:getSize().w
local wleft = TextBoxWidget:new{ local wleft = TextBoxWidget:new{
text = self.text, text = self.text,
face = Font:getFace("cfont", 20), face = Font:getFace("cfont", _fontSize(20)),
width = wleft_width, width = wleft_width,
alignment = "left", alignment = "left",
bold = true, bold = true,
@ -245,7 +255,15 @@ function ListMenuItem:update()
local bookinfo = BookInfoManager:getBookInfo(self.filepath, self.do_cover_image) local bookinfo = BookInfoManager:getBookInfo(self.filepath, self.do_cover_image)
if bookinfo and self.do_cover_image and not bookinfo.ignore_cover then if bookinfo and self.do_cover_image and not bookinfo.ignore_cover then
if not bookinfo.cover_fetched then if bookinfo.cover_fetched then
-- trigger recalculation of thumbnail if size changed
if bookinfo.has_cover and bookinfo.cover_sizetag ~= "M" and bookinfo.cover_sizetag ~= cover_specs.sizetag then
if bookinfo.cover_bb then
bookinfo.cover_bb:free()
end
bookinfo = nil
end
else
-- cover was not fetched previously, do as if not found -- cover was not fetched previously, do as if not found
-- to force a new extraction -- to force a new extraction
bookinfo = nil bookinfo = nil
@ -388,14 +406,16 @@ function ListMenuItem:update()
-- Build the right widget -- Build the right widget
local fontsize_info = math.min(max_fontsize_fileinfo, _fontSize(14))
local wfileinfo = TextWidget:new{ local wfileinfo = TextWidget:new{
text = fileinfo_str, text = fileinfo_str,
face = Font:getFace("cfont", 14), face = Font:getFace("cfont", fontsize_info),
fgcolor = self.file_deleted and Blitbuffer.COLOR_DARK_GRAY or nil, fgcolor = self.file_deleted and Blitbuffer.COLOR_DARK_GRAY or nil,
} }
local wpageinfo = TextWidget:new{ local wpageinfo = TextWidget:new{
text = pages_str, text = pages_str,
face = Font:getFace("cfont", 14), face = Font:getFace("cfont", fontsize_info),
fgcolor = self.file_deleted and Blitbuffer.COLOR_DARK_GRAY or nil, fgcolor = self.file_deleted and Blitbuffer.COLOR_DARK_GRAY or nil,
} }
@ -419,11 +439,10 @@ function ListMenuItem:update()
} }
-- Create or replace corner_mark if needed -- Create or replace corner_mark if needed
local wright_bottom_pad_available = math.ceil( (dimen.h - wright[1]:getSize().h) *2/3 ) local mark_size = math.floor(dimen.h / 6)
-- We should normally use 1/2 because of CenterContainer, but there's -- Just fits under the page info text, which in turn adapts to the ListMenuItem height.
-- some space inside the text widget that we can use for a larger marker if mark_size ~= corner_mark_size then
if wright_bottom_pad_available ~= corner_mark_size then corner_mark_size = mark_size
corner_mark_size = wright_bottom_pad_available
if corner_mark then if corner_mark then
corner_mark:free() corner_mark:free()
end end
@ -447,10 +466,12 @@ function ListMenuItem:update()
local fontname_title = "cfont" local fontname_title = "cfont"
local fontname_authors = "cfont" local fontname_authors = "cfont"
local fontsize_title = 20 local fontsize_title = _fontSize(20)
local fontsize_authors = 18 local fontsize_authors = _fontSize(18)
local wtitle, wauthors local wtitle, wauthors
local title, authors local title, authors
local series_mode = BookInfoManager:getSetting("series_mode")
-- whether to use or not title and authors -- whether to use or not title and authors
if self.do_filename_only or bookinfo.ignore_meta then if self.do_filename_only or bookinfo.ignore_meta then
title = filename_without_suffix -- made out above title = filename_without_suffix -- made out above
@ -463,30 +484,41 @@ function ListMenuItem:update()
-- append "et al." to the 2nd if there are more -- append "et al." to the 2nd if there are more
if authors and authors:find("\n") then if authors and authors:find("\n") then
authors = util.splitToArray(authors, "\n") authors = util.splitToArray(authors, "\n")
if #authors > 2 then if #authors > 1 and bookinfo.series and series_mode == "series_in_separate_line" then
authors = { T(_("%1 et al."), authors[1]) }
elseif #authors > 2 then
authors = { authors[1], T(_("%1 et al."), authors[2]) } authors = { authors[1], T(_("%1 et al."), authors[2]) }
end end
authors = table.concat(authors, "\n") authors = table.concat(authors, "\n")
-- as we'll fit 3 lines instead of 2, we can avoid some loops by starting from a lower font size
fontsize_title = _fontSize(17)
fontsize_authors = _fontSize(15)
end end
end end
-- add Series metadata if requested -- add Series metadata if requested
if bookinfo.series then if bookinfo.series then
if BookInfoManager:getSetting("append_series_to_title") then
-- Shorten calibre series decimal number (#4.0 => #4) -- Shorten calibre series decimal number (#4.0 => #4)
bookinfo.series = bookinfo.series:gsub("(#%d+)%.0$", "%1") bookinfo.series = bookinfo.series:gsub("(#%d+)%.0$", "%1")
if series_mode == "append_series_to_title" then
if title then if title then
title = title .. " - " .. bookinfo.series title = title .. " - " .. bookinfo.series
else else
title = bookinfo.series title = bookinfo.series
end end
end end
if BookInfoManager:getSetting("append_series_to_authors") then if not authors then
bookinfo.series = bookinfo.series:gsub("(#%d+)%.0$", "%1") if series_mode == "append_series_to_authors" or series_mode == "series_in_separate_line" then
if authors then
authors = authors .. " - " .. bookinfo.series
else
authors = bookinfo.series authors = bookinfo.series
end end
else
if series_mode == "append_series_to_authors" then
authors = authors .. " - " .. bookinfo.series
elseif series_mode == "series_in_separate_line" then
authors = bookinfo.series .. "\n" .. authors
-- as we'll fit 3 lines instead of 2, we can avoid some loops by starting from a lower font size
fontsize_title = _fontSize(17)
fontsize_authors = _fontSize(15)
end
end end
end end
if bookinfo.unsupported then if bookinfo.unsupported then
@ -527,6 +559,8 @@ function ListMenuItem:update()
end end
if height < dimen.h then -- we fit ! if height < dimen.h then -- we fit !
break break
else
logger.dbg(title, "recalculate title/author with", fontsize_title - 1)
end end
-- If we don't fit, decrease both font sizes -- If we don't fit, decrease both font sizes
fontsize_title = fontsize_title - 1 fontsize_title = fontsize_title - 1
@ -606,17 +640,24 @@ function ListMenuItem:update()
if self.file_deleted then -- unless file was deleted (can happen with History) if self.file_deleted then -- unless file was deleted (can happen with History)
hint = " " .. _("(deleted)") hint = " " .. _("(deleted)")
end end
widget = LeftContainer:new{ local text_widget
dimen = dimen, local fontsize_no_bookinfo = _fontSize(18)
HorizontalGroup:new{ repeat
HorizontalSpan:new{ width = Screen:scaleBySize(10) }, text_widget = TextBoxWidget:new{
TextBoxWidget:new{
text = self.text .. hint, text = self.text .. hint,
face = Font:getFace("cfont", 18), face = Font:getFace("cfont", fontsize_no_bookinfo),
width = dimen.w - 2 * Screen:scaleBySize(10), width = dimen.w - 2 * Screen:scaleBySize(10),
alignment = "left", alignment = "left",
fgcolor = self.file_deleted and Blitbuffer.COLOR_DARK_GRAY or nil, fgcolor = self.file_deleted and Blitbuffer.COLOR_DARK_GRAY or nil,
} }
-- reduce font size for next loop, in case text widget is too large to fit into ListMenuItem
fontsize_no_bookinfo = fontsize_no_bookinfo - 1
until text_widget:getSize().h <= dimen.h
widget = LeftContainer:new{
dimen = dimen,
HorizontalGroup:new{
HorizontalSpan:new{ width = Screen:scaleBySize(10) },
text_widget
}, },
} }
end end
@ -743,25 +784,27 @@ function ListMenu:_recalculateDimen()
self.itemnum_orig = self.path_items[self.path] self.itemnum_orig = self.path_items[self.path]
self.focused_path_orig = self.focused_path self.focused_path_orig = self.focused_path
end end
local available_height = self.dimen.h - self.others_height local available_height = self.dimen.h - self.others_height - Size.line.thin
-- 64 hardcoded for now, gives 10 items both in filemanager -- default is 64px per ListMenuItem, gives 10 items both in filemanager
-- and history on kobo glo hd -- and history on kobo glo hd
local item_height_min = Screen:scaleBySize(64) self.perpage = BookInfoManager:getSetting("files_per_page") or math.floor(available_height / scale_by_size / 64)
self.perpage = math.floor(available_height / item_height_min)
self.page_num = math.ceil(#self.item_table / self.perpage) self.page_num = math.ceil(#self.item_table / self.perpage)
-- fix current page if out of range -- fix current page if out of range
if self.page_num > 0 and self.page > self.page_num then self.page = self.page_num end if self.page_num > 0 and self.page > self.page_num then self.page = self.page_num end
local height_remaining = available_height - self.perpage * item_height_min -- menu item height based on number of items per page
height_remaining = height_remaining - (self.perpage+1) -- N+1 LineWidget separators -- add space for the separator
self.item_height = item_height_min + math.floor(height_remaining / self.perpage) self.item_height = math.floor(available_height / self.perpage) - Size.line.thin
self.item_width = self.dimen.w self.item_width = self.dimen.w
self.item_dimen = Geom:new{ self.item_dimen = Geom:new{
w = self.item_width, w = self.item_width,
h = self.item_height h = self.item_height
} }
-- upper limit for file info font to leave enough space for title and author
max_fontsize_fileinfo = available_height / scale_by_size / 32
if self.page_recalc_needed then if self.page_recalc_needed then
-- self.page has probably been set to a wrong value, we recalculate -- self.page has probably been set to a wrong value, we recalculate
-- it here as done in Menu:init() or Menu:switchItemTable() -- it here as done in Menu:init() or Menu:switchItemTable()

View File

@ -3,6 +3,7 @@ local UIManager = require("ui/uimanager")
local logger = require("logger") local logger = require("logger")
local _ = require("gettext") local _ = require("gettext")
local BookInfoManager = require("bookinfomanager") local BookInfoManager = require("bookinfomanager")
local Screen = require("device").screen
--[[ --[[
This plugin provides additional display modes to file browsers (File Manager This plugin provides additional display modes to file browsers (File Manager
@ -39,6 +40,7 @@ local DISPLAY_MODES = {
local init_done = false local init_done = false
local filemanager_display_mode = false -- not initialized yet local filemanager_display_mode = false -- not initialized yet
local history_display_mode = false -- not initialized yet local history_display_mode = false -- not initialized yet
local series_mode = nil -- defaults to not display series
local CoverBrowser = InputContainer:new{ local CoverBrowser = InputContainer:new{
name = "coverbrowser", name = "coverbrowser",
@ -73,6 +75,8 @@ function CoverBrowser:init()
self:setupFileManagerDisplayMode(BookInfoManager:getSetting("filemanager_display_mode")) self:setupFileManagerDisplayMode(BookInfoManager:getSetting("filemanager_display_mode"))
self:setupHistoryDisplayMode(BookInfoManager:getSetting("history_display_mode")) self:setupHistoryDisplayMode(BookInfoManager:getSetting("history_display_mode"))
series_mode = BookInfoManager:getSetting("series_mode")
init_done = true init_done = true
BookInfoManager:closeDbConnection() -- will be re-opened if needed BookInfoManager:closeDbConnection() -- will be re-opened if needed
end end
@ -291,6 +295,73 @@ function CoverBrowser:addToMainMenu(menu_items)
self:refreshFileManagerInstance() self:refreshFileManagerInstance()
end, end,
}, },
{
text = _("Series "),
sub_item_table = {
{
text = _("Append series metadata to authors"),
checked_func = function() return series_mode == "append_series_to_authors" end,
callback = function()
if series_mode == "append_series_to_authors" then
series_mode = nil
else
series_mode = "append_series_to_authors"
end
BookInfoManager:saveSetting("series_mode", series_mode)
self:refreshFileManagerInstance()
end,
},
{
text = _("Append series metadata to title"),
checked_func = function() return series_mode == "append_series_to_title" end,
callback = function()
if series_mode == "append_series_to_title" then
series_mode = nil
else
series_mode = "append_series_to_title"
end
BookInfoManager:saveSetting("series_mode", series_mode)
self:refreshFileManagerInstance()
end,
},
{
text = _("Show series metadata in separate line"),
checked_func = function() return series_mode == "series_in_separate_line" end,
callback = function()
if series_mode == "series_in_separate_line" then
series_mode = nil
else
series_mode = "series_in_separate_line"
end
BookInfoManager:saveSetting("series_mode", series_mode)
self:refreshFileManagerInstance()
end,
},
},
separator = true
},
{
text = _("(Detailed list) Files per page"),
help_text = _([[This sets the number of files and directories per page in non-'classic' display modes.]]),
keep_menu_open = true,
callback = function()
local SpinWidget = require("ui/widget/spinwidget")
local curr_items = BookInfoManager:getSetting("files_per_page") or 10
local items = SpinWidget:new{
width = Screen:getWidth() * 0.6,
value = curr_items,
value_min = 4,
value_max = 20,
ok_text = _("Set files"),
title_text = _("Files per page"),
callback = function(spin)
BookInfoManager:saveSetting("files_per_page", spin.value)
self.ui:onRefresh()
end
}
UIManager:show(items)
end,
},
{ {
text = _("Show number of pages read instead of progress %"), text = _("Show number of pages read instead of progress %"),
checked_func = function() return BookInfoManager:getSetting("show_pages_read_as_progress") end, checked_func = function() return BookInfoManager:getSetting("show_pages_read_as_progress") end,
@ -314,30 +385,7 @@ function CoverBrowser:addToMainMenu(menu_items)
end end
self:refreshFileManagerInstance() self:refreshFileManagerInstance()
end, end,
}, separator = true
{
text = _("Append series metadata to authors"),
checked_func = function() return BookInfoManager:getSetting("append_series_to_authors") end,
callback = function()
if BookInfoManager:getSetting("append_series_to_authors") then
BookInfoManager:saveSetting("append_series_to_authors", false)
else
BookInfoManager:saveSetting("append_series_to_authors", true)
end
self:refreshFileManagerInstance()
end,
},
{
text = _("Append series metadata to title"),
checked_func = function() return BookInfoManager:getSetting("append_series_to_title") end,
callback = function()
if BookInfoManager:getSetting("append_series_to_title") then
BookInfoManager:saveSetting("append_series_to_title", false)
else
BookInfoManager:saveSetting("append_series_to_title", true)
end
self:refreshFileManagerInstance()
end,
}, },
-- generic_items will be inserted here -- generic_items will be inserted here
}, },

View File

@ -503,23 +503,27 @@ function MosaicMenuItem:update()
self._has_cover_image = true self._has_cover_image = true
else else
-- add Series metadata if requested -- add Series metadata if requested
local series_mode = BookInfoManager:getSetting("series_mode")
if bookinfo.series then if bookinfo.series then
if BookInfoManager:getSetting("append_series_to_title") then
-- Shorten calibre series decimal number (#4.0 => #4) -- Shorten calibre series decimal number (#4.0 => #4)
bookinfo.series = bookinfo.series:gsub("(#%d+)%.0$", "%1") bookinfo.series = bookinfo.series:gsub("(#%d+)%.0$", "%1")
if series_mode == "append_series_to_title" then
if bookinfo.title then if bookinfo.title then
bookinfo.title = bookinfo.title .. " - " .. bookinfo.series bookinfo.title = bookinfo.title .. " - " .. bookinfo.series
else else
bookinfo.title = bookinfo.series bookinfo.title = bookinfo.series
end end
end end
if BookInfoManager:getSetting("append_series_to_authors") then if not bookinfo.authors then
bookinfo.series = bookinfo.series:gsub("(#%d+)%.0$", "%1") if series_mode == "append_series_to_authors" or series_mode == "series_in_separate_line" then
if bookinfo.authors then
bookinfo.authors = bookinfo.authors .. " - " .. bookinfo.series
else
bookinfo.authors = bookinfo.series bookinfo.authors = bookinfo.series
end end
else
if series_mode == "append_series_to_authors" then
bookinfo.authors = bookinfo.authors .. " - " .. bookinfo.series
elseif series_mode == "series_in_separate_line" then
bookinfo.authors = bookinfo.authors .. "\n \n" .. bookinfo.series
end
end end
end end
widget = CenterContainer:new{ widget = CenterContainer:new{