diff --git a/src/calibre/gui2/library/bookshelf_view.py b/src/calibre/gui2/library/bookshelf_view.py index 0e0584636a..0eace2405a 100644 --- a/src/calibre/gui2/library/bookshelf_view.py +++ b/src/calibre/gui2/library/bookshelf_view.py @@ -3,7 +3,6 @@ # Copyright: Andy C , un_pogaz , Kovid Goyal # 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