From e55b60175bfbf88e21403e6a14887cb7c5a08000 Mon Sep 17 00:00:00 2001
From: melyux <10296053+melyux@users.noreply.github.com>
Date: Fri, 17 Feb 2023 12:29:53 -0800
Subject: [PATCH] CoverBrowser Mosaic: improve book status, floating progress
bar (#9939)
- New dogear icons in Mosaic cover view to indicate each
possible book status: 'Reading', 'On hold', 'Finished'
- Progress bar redesigned to be floating, taller, thicker
bordered in Mosaic cover view
- Don't show progress bar if book is finished
- FakeCover bottom text (filename) adjusted to not overlap
with progress bar and dogear if they exist
- Mosaic book shortcut letter moved from bottom left to
top left
---
plugins/coverbrowser.koplugin/main.lua | 4 +-
plugins/coverbrowser.koplugin/mosaicmenu.lua | 152 +++++++++++-------
.../icons/mdlight/dogear.abandoned.rtl.svg | 7 +
resources/icons/mdlight/dogear.abandoned.svg | 7 +
.../icons/mdlight/dogear.complete.rtl.svg | 5 +
resources/icons/mdlight/dogear.complete.svg | 5 +
resources/icons/mdlight/dogear.reading.svg | 5 +
7 files changed, 128 insertions(+), 57 deletions(-)
create mode 100644 resources/icons/mdlight/dogear.abandoned.rtl.svg
create mode 100644 resources/icons/mdlight/dogear.abandoned.svg
create mode 100644 resources/icons/mdlight/dogear.complete.rtl.svg
create mode 100644 resources/icons/mdlight/dogear.complete.svg
create mode 100644 resources/icons/mdlight/dogear.reading.svg
diff --git a/plugins/coverbrowser.koplugin/main.lua b/plugins/coverbrowser.koplugin/main.lua
index 78f2b25ee..e45001aaa 100644
--- a/plugins/coverbrowser.koplugin/main.lua
+++ b/plugins/coverbrowser.koplugin/main.lua
@@ -278,7 +278,7 @@ function CoverBrowser:addToMainMenu(menu_items)
end,
},
{
- text = _("Show hint for opened books in history"),
+ text = _("Show hint for book status in history"),
checked_func = function() return BookInfoManager:getSetting("history_hint_opened") end,
callback = function()
if BookInfoManager:getSetting("history_hint_opened") then
@@ -290,7 +290,7 @@ function CoverBrowser:addToMainMenu(menu_items)
end,
},
{
- text = _("Show hint for opened books in favorites"),
+ text = _("Show hint for book status in favorites"),
checked_func = function() return BookInfoManager:getSetting("collections_hint_opened") end,
callback = function()
if BookInfoManager:getSetting("collections_hint_opened") then
diff --git a/plugins/coverbrowser.koplugin/mosaicmenu.lua b/plugins/coverbrowser.koplugin/mosaicmenu.lua
index ad8ae857d..6adef8ba8 100644
--- a/plugins/coverbrowser.koplugin/mosaicmenu.lua
+++ b/plugins/coverbrowser.koplugin/mosaicmenu.lua
@@ -44,6 +44,9 @@ local BookInfoManager = require("bookinfomanager")
-- recreated if height changes)
local corner_mark_size = -1
local corner_mark
+local reading_mark
+local abandoned_mark
+local complete_mark
local progress_widget
-- ItemShortCutIcon (for keyboard navigation) is private to menu.lua and can't be accessed,
@@ -102,6 +105,7 @@ local FakeCover = FrameContainer:extend{
padding = 0,
bordersize = Size.border.thin,
dim = nil,
+ bottom_right_compensate = false,
-- Provided filename, title and authors should not be BD wrapped
filename = nil,
file_deleted = nil,
@@ -251,7 +255,7 @@ function FakeCover:init()
text = filename,
lang = self.book_lang, -- might as well use it for filename
face = Font:getFace("cfont", math.max(self.filename_font_max - sizedec, self.filename_font_min)),
- width = text_width,
+ width = self.bottom_right_compensate and width - 2 * corner_mark_size or text_width,
alignment = "center",
}
texts_height = texts_height + filename_wg:getSize().h
@@ -383,6 +387,7 @@ function MosaicMenuItem:init()
self.detail = self.text
self.percent_finished = nil
+ self.status = nil
-- we need this table per-instance, so we declare it here
self.ges_events = {
@@ -559,6 +564,42 @@ function MosaicMenuItem:update()
end
if bookinfo then -- This book is known
+ -- Current page / pages are available or more accurate in .sdr/metadata.lua
+ -- We use a cache (cleaned at end of this browsing session) to store
+ -- page, percent read and book status from sidecar files, to avoid
+ -- re-parsing them when re-rendering a visited page
+ -- This cache is shared with ListMenu, so we need to fill it with the same
+ -- info here than there, even if we don't need them all here.
+ if not self.menu.cover_info_cache then
+ self.menu.cover_info_cache = {}
+ end
+ local percent_finished, status
+ local pages = bookinfo.pages
+ if DocSettings:hasSidecarFile(self.filepath) then
+ self.been_opened = true
+ if self.menu.cover_info_cache[self.filepath] then
+ pages, percent_finished, status = unpack(self.menu.cover_info_cache[self.filepath]) -- luacheck: no unused
+ else
+ local docinfo = DocSettings:open(self.filepath)
+ -- We can get nb of page in the new 'doc_pages' setting, or from the old 'stats.page'
+ if docinfo.data.doc_pages then
+ pages = docinfo.data.doc_pages
+ elseif docinfo.data.stats and docinfo.data.stats.pages then
+ if docinfo.data.stats.pages ~= 0 then -- crengine with statistics disabled stores 0
+ pages = docinfo.data.stats.pages
+ end
+ end
+ if docinfo.data.summary and docinfo.data.summary.status then
+ status = docinfo.data.summary.status
+ end
+ percent_finished = docinfo.data.percent_finished
+ self.menu.cover_info_cache[self.filepath] = {pages, percent_finished, status}
+ end
+ end
+ self.percent_finished = percent_finished
+ self.status = status
+ self.show_progress_bar = self.status ~= "complete" and BookInfoManager:getSetting("show_progress_in_mosaic") and self.percent_finished
+
local cover_bb_used = false
self.bookinfo_found = true
-- For wikipedia saved as epub, we made a cover from the 1st pic of the page,
@@ -622,6 +663,12 @@ function MosaicMenuItem:update()
end
end
end
+ local bottom_pad = Size.padding.default
+ if self.show_progress_bar and self.do_hint_opened then
+ bottom_pad = corner_mark_size + Screen:scaleBySize(2)
+ elseif self.show_progress_bar then
+ bottom_pad = corner_mark_size - Screen:scaleBySize(2)
+ end
widget = CenterContainer:new{
dimen = dimen,
FakeCover:new{
@@ -636,6 +683,8 @@ function MosaicMenuItem:update()
authors_add = not bookinfo.ignore_meta and authors_add,
book_lang = not bookinfo.ignore_meta and bookinfo.language,
file_deleted = self.file_deleted,
+ bottom_pad = bottom_pad,
+ bottom_right_compensate = not self.show_progress_bar and self.do_hint_opened,
}
}
end
@@ -647,43 +696,6 @@ function MosaicMenuItem:update()
if bookinfo.description then
self.has_description = true
end
-
- -- Current page / pages are available or more accurate in .sdr/metadata.lua
- -- We use a cache (cleaned at end of this browsing session) to store
- -- page, percent read and book status from sidecar files, to avoid
- -- re-parsing them when re-rendering a visited page
- -- This cache is shared with ListMenu, so we need to fill it with the same
- -- info here than there, even if we don't need them all here.
- if not self.menu.cover_info_cache then
- self.menu.cover_info_cache = {}
- end
- local percent_finished, status
- local pages = bookinfo.pages
- if DocSettings:hasSidecarFile(self.filepath) then
- self.been_opened = true
- if self.menu.cover_info_cache[self.filepath] then
- pages, percent_finished, status = unpack(self.menu.cover_info_cache[self.filepath]) -- luacheck: no unused
- else
- local docinfo = DocSettings:open(self.filepath)
- -- We can get nb of page in the new 'doc_pages' setting, or from the old 'stats.page'
- if docinfo.data.doc_pages then
- pages = docinfo.data.doc_pages
- elseif docinfo.data.stats and docinfo.data.stats.pages then
- if docinfo.data.stats.pages ~= 0 then -- crengine with statistics disabled stores 0
- pages = docinfo.data.stats.pages
- end
- end
- if docinfo.data.summary and docinfo.data.summary.status then
- status = docinfo.data.summary.status
- end
- percent_finished = docinfo.data.percent_finished
- self.menu.cover_info_cache[self.filepath] = {pages, percent_finished, status}
- end
- end
- if status == "completed" then
- percent_finished = 100
- end
- self.percent_finished = percent_finished
else -- bookinfo not found
if self.init_done then
-- Non-initial update(), but our widget is still not found:
@@ -740,7 +752,7 @@ function MosaicMenuItem:paintTo(bb, x, y)
-- to which we paint over the shortcut icon
if self.shortcut_icon then
- -- align it on bottom left corner of widget
+ -- align it on top left corner of widget
local target = self
local ix
if BD.mirroredUILayout() then
@@ -748,13 +760,11 @@ function MosaicMenuItem:paintTo(bb, x, y)
else
ix = 0
end
- local iy = target.dimen.h - self.shortcut_icon.dimen.h
+ local iy = 0
self.shortcut_icon:paintTo(bb, x+ix, y+iy)
end
- local show_progress_in_mosaic = BookInfoManager:getSetting("show_progress_in_mosaic")
- -- to which we paint over a dogear if needed
- if not show_progress_in_mosaic and corner_mark and self.do_hint_opened and self.been_opened then
+ if self.do_hint_opened and self.been_opened then
-- align it on bottom right corner of sub-widget
local target = self[1][1][1]
local ix
@@ -765,15 +775,33 @@ function MosaicMenuItem:paintTo(bb, x, y)
end
local iy = self.height - math.ceil((self.height - target.dimen.h)/2) - corner_mark:getSize().h
-- math.ceil() makes it looks better than math.floor()
+ if self.status == "abandoned" then
+ corner_mark = abandoned_mark
+ elseif self.status == "complete" then
+ corner_mark = complete_mark
+ else
+ corner_mark = reading_mark
+ end
corner_mark:paintTo(bb, x+ix, y+iy)
end
- if show_progress_in_mosaic and self.percent_finished then
+ if self.show_progress_bar then
local cover_item = self[1][1][1]
- local width = math.min(self.width * 0.60, cover_item.width)
- progress_widget.width = width
- local pos_x = x + self.width - progress_widget.width - math.ceil((self.width - cover_item.width) / 2) - progress_widget.bordersize
- local pos_y = y + self.height - progress_widget.height - math.ceil((self.height - cover_item.height) / 2)
+ local progress_widget_margin = math.floor((corner_mark_size - progress_widget.height) / 2)
+ progress_widget.width = cover_item.width - 2*progress_widget_margin
+ local pos_x = x + math.ceil((self.width - progress_widget.width) / 2)
+ if self.do_hint_opened then
+ progress_widget.width = progress_widget.width - corner_mark_size
+ if BD.mirroredUILayout() then
+ pos_x = pos_x + corner_mark_size
+ end
+ end
+ local pos_y = y + self.height - math.ceil((self.height - cover_item.height) / 2) - corner_mark_size + progress_widget_margin
+ if self.status == "abandoned" then
+ progress_widget.fillcolor = Blitbuffer.COLOR_GRAY_6
+ else
+ progress_widget.fillcolor = Blitbuffer.COLOR_BLACK
+ end
progress_widget:setPercentage(self.percent_finished)
progress_widget:paintTo(bb, pos_x, pos_y)
end
@@ -886,18 +914,32 @@ function MosaicMenu:_recalculateDimen()
-- Create or replace corner_mark if needed
-- 1/12 (larger) or 1/16 (smaller) of cover looks allright
- local mark_size = math.floor(math.min(self.item_width, self.item_height) / 16)
+ local mark_size = math.floor(math.min(self.item_width, self.item_height) / 8)
if mark_size ~= corner_mark_size then
corner_mark_size = mark_size
if corner_mark then
- corner_mark:free()
+ reading_mark:free()
+ abandoned_mark:free()
+ complete_mark:free()
end
- corner_mark = IconWidget:new{
- icon = "dogear.opaque",
- rotation_angle = BD.mirroredUILayout() and 180 or 270,
+ reading_mark = IconWidget:new{
+ icon = "dogear.reading",
+ rotation_angle = BD.mirroredUILayout() and 270 or 0,
+ width = corner_mark_size,
+ height = corner_mark_size,
+ }
+ abandoned_mark = IconWidget:new{
+ icon = BD.mirroredUILayout() and "dogear.abandoned.rtl" or "dogear.abandoned",
+ width = corner_mark_size,
+ height = corner_mark_size,
+ }
+ complete_mark = IconWidget:new{
+ icon = BD.mirroredUILayout() and "dogear.complete.rtl" or "dogear.complete",
+ alpha = true,
width = corner_mark_size,
height = corner_mark_size,
}
+ corner_mark = reading_mark
end
-- Create or replace progress_widget if needed
@@ -907,11 +949,11 @@ function MosaicMenu:_recalculateDimen()
bgcolor = Blitbuffer.COLOR_WHITE,
fillcolor = Blitbuffer.COLOR_BLACK,
bordercolor = Blitbuffer.COLOR_BLACK,
- height = Screen:scaleBySize(6),
+ height = Screen:scaleBySize(8),
margin_h = Screen:scaleBySize(1),
width = progress_bar_width,
radius = Size.border.thin,
- bordersize = Size.border.thin,
+ bordersize = Size.border.default,
}
end
end
diff --git a/resources/icons/mdlight/dogear.abandoned.rtl.svg b/resources/icons/mdlight/dogear.abandoned.rtl.svg
new file mode 100644
index 000000000..3afee8b8b
--- /dev/null
+++ b/resources/icons/mdlight/dogear.abandoned.rtl.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/resources/icons/mdlight/dogear.abandoned.svg b/resources/icons/mdlight/dogear.abandoned.svg
new file mode 100644
index 000000000..5c83b7652
--- /dev/null
+++ b/resources/icons/mdlight/dogear.abandoned.svg
@@ -0,0 +1,7 @@
+
+
diff --git a/resources/icons/mdlight/dogear.complete.rtl.svg b/resources/icons/mdlight/dogear.complete.rtl.svg
new file mode 100644
index 000000000..a4ab7deb8
--- /dev/null
+++ b/resources/icons/mdlight/dogear.complete.rtl.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/resources/icons/mdlight/dogear.complete.svg b/resources/icons/mdlight/dogear.complete.svg
new file mode 100644
index 000000000..58244aad2
--- /dev/null
+++ b/resources/icons/mdlight/dogear.complete.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/resources/icons/mdlight/dogear.reading.svg b/resources/icons/mdlight/dogear.reading.svg
new file mode 100644
index 000000000..b15a519e6
--- /dev/null
+++ b/resources/icons/mdlight/dogear.reading.svg
@@ -0,0 +1,5 @@
+
+