Implement marked and ondevice emblems for shelf view

This commit is contained in:
Kovid Goyal 2025-12-24 17:30:00 +05:30
parent 43464ab3ee
commit 8b716ce1b2
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C

View File

@ -3,7 +3,6 @@
# Copyright: Andy C <achuongdev@gmail.com>, un_pogaz <un.pogaz@gmail.com>, Kovid Goyal <kovid@kovidgoyal.net>
# TODO:
# implement marks and ondevice indicators
# improve rendering of shelf and background with options for dark/light
# fix drag and drop
# Remove py_dominant_color after beta release
@ -36,6 +35,7 @@ from qt.core import (
QEvent,
QFont,
QFontMetrics,
QIcon,
QImage,
QItemSelection,
QItemSelectionModel,
@ -346,6 +346,7 @@ class CachedCoverRenderer:
# }}}
# Layout {{{
GROUPINGS = {
'authors',
'series',
@ -792,6 +793,7 @@ class BookCase(QObject):
if not (target_si := target_shelf.book_or_divider_at_xpos(si.start_x, self.layout_constraints)):
return 0
return ans.book_id if (ans := target_shelf.closest_book_to(target_si.idx)) else 0
# }}}
class ExpandedCover(QObject):
@ -1205,6 +1207,38 @@ class BookshelfView(MomentumScrollMixin, QAbstractScrollArea):
return
self.viewport().update()
def draw_emblems_above(self, painter: QPainter, item: ShelfItem, scroll_y: int) -> None:
book_id = item.book_id
emblems = []
if m := self.model():
from calibre.gui2.ui import get_gui
db = m.db
marked = db.data.get_marked(book_id)
if marked:
emblems.append(m.marked_icon if marked == 'true' else m.marked_text_icon_for(marked))
db = db.new_api
device_connected = get_gui().device_connected is not None
on_device = device_connected and db.field_for('ondevice', book_id)
if on_device:
if getattr(self, 'on_device_icon', None) is None:
self.on_device_icon = QIcon.ic('ok.png')
emblems.append(self.on_device_icon)
if not emblems:
return
gap = 2
max_width = (item.width - gap) // len(emblems)
max_height = self.layout_constraints.shelf_gap
sz = min(max_width, max_height)
width = sz
if len(emblems) > 1:
width += gap + sz
x = max(0, (item.width - width) // 2) + item.start_x + self.layout_constraints.side_margin
y = item.case_start_y + self.layout_constraints.shelf_gap - sz + item.reduce_height_by
for ic in emblems:
p = ic.pixmap(sz, sz)
painter.drawPixmap(QPoint(x, y), p)
x += sz + gap
def paintEvent(self, ev: QPaintEvent):
'''Paint the bookshelf view.'''
if not self.view_is_visible():
@ -1242,6 +1276,7 @@ class BookshelfView(MomentumScrollMixin, QAbstractScrollArea):
# Draw a book spine at this position
row = self.bookcase.book_id_to_row_map[item.book_id]
self._draw_spine(painter, item, scroll_y, sm.isRowSelected(row), row == current_row)
self.draw_emblems_above(painter, item, scroll_y)
if hovered_item is not None:
row = self.bookcase.book_id_to_row_map[hovered_item.book_id]
is_selected, is_current = sm.isRowSelected(row), row == current_row