mirror of
https://github.com/kovidgoyal/calibre.git
synced 2026-03-09 11:23:43 -04:00
Cover grid: Option to draw emblems on top of cover in Preferences->Look & feel->Cover grid->Emblems
Fixes #3019 (Cover grid: replace show_emblems/draw_emblems_on_cover with emblem_style enum; add on-cover emblem rendering)
This commit is contained in:
parent
203a76edfe
commit
deeb08929c
@ -451,9 +451,9 @@ def create_defs():
|
||||
defs['cb_preserve_aspect_ratio'] = False
|
||||
defs['cb_double_click_to_activate'] = False
|
||||
defs['gpm_template_editor_font_size'] = 10
|
||||
defs['show_emblems'] = False
|
||||
defs['emblem_size'] = 32
|
||||
defs['emblem_position'] = 'left'
|
||||
defs['emblem_style'] = 'none'
|
||||
defs['metadata_diff_mark_rejected'] = False
|
||||
defs['tag_browser_show_counts'] = True
|
||||
defs['tag_browser_show_tooltips'] = True
|
||||
@ -551,6 +551,15 @@ def create_defs():
|
||||
migrate_tweak('metadata_edit_single_cc_label_length', 'edit_metadata_single_cc_label_length')
|
||||
migrate_tweak('metadata_single_use_2_cols_for_custom_fields', 'edit_metadata_single_use_2_cols_for_custom_fields')
|
||||
|
||||
# Migrate show_emblems and draw_emblems_on_cover to emblem_style
|
||||
show_emblems = gprefs.pop('show_emblems', None)
|
||||
draw_emblems_on_cover = gprefs.pop('draw_emblems_on_cover', None)
|
||||
if show_emblems is not None or draw_emblems_on_cover is not None:
|
||||
if show_emblems:
|
||||
gprefs['emblem_style'] = 'emboss' if draw_emblems_on_cover else 'gutter'
|
||||
else:
|
||||
gprefs['emblem_style'] = 'none'
|
||||
|
||||
|
||||
create_defs()
|
||||
del create_defs
|
||||
|
||||
@ -617,10 +617,10 @@ class CoverDelegate(QStyledItemDelegate):
|
||||
height = self.original_height = gprefs['cover_grid_height']
|
||||
self.original_show_title = show_title = gprefs['cover_grid_show_title']
|
||||
self.original_flush_bottom = self.flush_bottom = gprefs['cover_grid_text_flush_bottom']
|
||||
self.original_show_emblems = gprefs['show_emblems']
|
||||
self.original_emblem_style = gprefs['emblem_style']
|
||||
self.orginal_emblem_size = gprefs['emblem_size']
|
||||
self.orginal_emblem_position = gprefs['emblem_position']
|
||||
self.emblem_size = gprefs['emblem_size'] if self.original_show_emblems else 0
|
||||
self.emblem_size = gprefs['emblem_size'] if self.original_emblem_style != 'none' else 0
|
||||
try:
|
||||
self.gutter_position = getattr(self, self.orginal_emblem_position.upper())
|
||||
except Exception:
|
||||
@ -644,7 +644,7 @@ class CoverDelegate(QStyledItemDelegate):
|
||||
sz = f.pointSize() * self.parent().logicalDpiY() / 72.0
|
||||
self.title_height = int(max(25, sz + 10))
|
||||
self.item_size = self.cover_size + QSize(2 * self.MARGIN, (2 * self.MARGIN) + self.title_height)
|
||||
if self.emblem_size > 0:
|
||||
if self.emblem_size > 0 and self.original_emblem_style == 'gutter':
|
||||
extra = self.emblem_size + self.MARGIN
|
||||
self.item_size += QSize(extra, 0) if self.gutter_position in (self.LEFT, self.RIGHT) else QSize(0, extra)
|
||||
self.calculate_spacing()
|
||||
@ -732,10 +732,11 @@ class CoverDelegate(QStyledItemDelegate):
|
||||
|
||||
painter.save()
|
||||
right_adjust = 0
|
||||
emblem_rect = None
|
||||
try:
|
||||
rect = option.rect
|
||||
rect.adjust(self.MARGIN, self.MARGIN, -self.MARGIN, -self.MARGIN)
|
||||
if self.emblem_size > 0:
|
||||
if self.emblem_size > 0 and self.original_emblem_style == 'gutter':
|
||||
self.paint_emblems(painter, rect, emblems)
|
||||
orect = QRect(rect)
|
||||
trect = QRect(rect)
|
||||
@ -749,6 +750,7 @@ class CoverDelegate(QStyledItemDelegate):
|
||||
painter.drawText(rect, Qt.AlignmentFlag.AlignCenter|Qt.TextFlag.TextWordWrap, f'{title}\n\n{authors}')
|
||||
if self.title_height != 0:
|
||||
self.paint_title(painter, trect, db, book_id)
|
||||
emblem_rect = QRect(rect)
|
||||
else:
|
||||
if self.animating is not None and self.animating.row() == index.row():
|
||||
cover = cover.scaled(cover.size() * self._animated_size)
|
||||
@ -764,6 +766,10 @@ class CoverDelegate(QStyledItemDelegate):
|
||||
if self.flush_bottom:
|
||||
trect.setTop(rect.bottom() + 5)
|
||||
self.paint_title(painter, trect, db, book_id, align_top=self.flush_bottom)
|
||||
emblem_rect = QRect(rect)
|
||||
if self.original_emblem_style == 'emboss' and emblems:
|
||||
self.paint_emblems_on_cover(painter, emblem_rect, emblems)
|
||||
return
|
||||
if self.emblem_size > 0:
|
||||
# We don't draw embossed emblems as the ondevice/marked emblems are drawn in the gutter
|
||||
return
|
||||
@ -831,6 +837,37 @@ class CoverDelegate(QStyledItemDelegate):
|
||||
finally:
|
||||
painter.restore()
|
||||
|
||||
def paint_emblems_on_cover(self, painter, rect, emblems):
|
||||
esz = self.emblem_size
|
||||
if not esz:
|
||||
return
|
||||
margin = self.MARGIN
|
||||
r = gprefs['cover_corner_radius']
|
||||
if r > 0:
|
||||
if gprefs['cover_corner_radius_unit'] == '%':
|
||||
corner_inset = int(r / 100 * min(rect.width(), rect.height()))
|
||||
else:
|
||||
corner_inset = int(r)
|
||||
else:
|
||||
corner_inset = 0
|
||||
available_height = rect.height() - corner_inset
|
||||
max_per_edge = max(1, available_height // (esz + margin))
|
||||
with painter:
|
||||
painter.setClipRect(rect)
|
||||
for i, emblem in enumerate(emblems):
|
||||
if i < max_per_edge:
|
||||
x = rect.left() + margin
|
||||
y = rect.top() + corner_inset + i * (esz + margin)
|
||||
else:
|
||||
j = i - max_per_edge
|
||||
if j >= max_per_edge:
|
||||
break
|
||||
x = rect.right() - esz - margin
|
||||
y = rect.top() + corner_inset + j * (esz + margin)
|
||||
ew = int(emblem.width() / emblem.devicePixelRatio())
|
||||
eh = int(emblem.height() / emblem.devicePixelRatio())
|
||||
painter.drawPixmap(QRect(x, y, ew, eh), emblem)
|
||||
|
||||
def paint_embossed_emblem(self, pixmap, painter, orect, right_adjust, left=True):
|
||||
drect = QRect(orect)
|
||||
pw = int(pixmap.width() / pixmap.devicePixelRatio())
|
||||
@ -1030,7 +1067,7 @@ class GridView(MomentumScrollMixin, QListView):
|
||||
)
|
||||
if (size_changed or gprefs[
|
||||
'cover_grid_show_title'] != self.delegate.original_show_title or gprefs[
|
||||
'show_emblems'] != self.delegate.original_show_emblems or gprefs[
|
||||
'emblem_style'] != self.delegate.original_emblem_style or gprefs[
|
||||
'emblem_size'] != self.delegate.orginal_emblem_size or gprefs[
|
||||
'emblem_position'] != self.delegate.orginal_emblem_position or gprefs[
|
||||
'cover_grid_text_flush_bottom'] != self.delegate.original_flush_bottom):
|
||||
|
||||
@ -38,6 +38,10 @@ class CoverGridTab(QTabWidget, LazyConfigWidgetBase, Ui_cover_grid_tab):
|
||||
r('emblem_size', gprefs)
|
||||
r('emblem_position', gprefs, choices=[
|
||||
(_('Left'), 'left'), (_('Top'), 'top'), (_('Right'), 'right'), (_('Bottom'), 'bottom')])
|
||||
r('emblem_style', gprefs, choices=[
|
||||
(_('Do not show emblems'), 'none'),
|
||||
(_('Show in a gutter next to the cover'), 'gutter'),
|
||||
(_('Draw on the cover'), 'emboss')])
|
||||
|
||||
fm = db.field_metadata
|
||||
choices = sorted((('{} ({})'.format(fm[k]['name'], k), k) for k in fm.displayable_field_keys() if fm[k]['name']),
|
||||
|
||||
@ -288,10 +288,45 @@ A value of zero means calculate automatically.</string>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="EditRulesWidget" name="opt_cover_grid_icon_rules">
|
||||
<widget class="QWidget" name="tab_emblems">
|
||||
<attribute name="title">
|
||||
<string>&Emblems</string>
|
||||
</attribute>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_emblems">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_emblems">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_emblem_style">
|
||||
<property name="text">
|
||||
<string>Emblem &style:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>opt_emblem_style</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="opt_emblem_style"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_emblems">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="EditRulesWidget" name="opt_cover_grid_icon_rules"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="CoverCacheConfig" name="config_cache">
|
||||
<attribute name="title">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user