feat: change game card size only on slider released

Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
2025-06-14 11:14:22 +05:00
parent dbf3a30119
commit 66b4b82d49
3 changed files with 68 additions and 29 deletions

View File

@ -1,5 +1,5 @@
import numpy as np
from PySide6.QtWidgets import QLabel, QPushButton, QWidget, QLayout, QStyleOption, QLayoutItem
from PySide6.QtWidgets import QLabel, QPushButton, QWidget, QLayout, QLayoutItem
from PySide6.QtCore import Qt, Signal, QRect, QPoint, QSize
from PySide6.QtGui import QFont, QFontMetrics, QPainter
@ -133,18 +133,7 @@ class FlowLayout(QLayout):
class ClickableLabel(QLabel):
clicked = Signal()
def __init__(self, *args, icon=None, icon_size=16, icon_space=5, change_cursor=True, **kwargs):
"""
Поддерживаются вызовы:
- ClickableLabel("текст", parent=...) первый аргумент строка,
- ClickableLabel(parent, text="...") если первым аргументом передается родитель.
Аргументы:
icon: QIcon или None иконка, которая будет отрисована вместе с текстом.
icon_size: int размер иконки (ширина и высота).
icon_space: int отступ между иконкой и текстом.
change_cursor: bool изменять ли курсор на PointingHandCursor при наведении (по умолчанию True).
"""
def __init__(self, *args, icon=None, icon_size=16, icon_space=5, change_cursor=True, font_scale_factor=0.06, **kwargs):
if args and isinstance(args[0], str):
text = args[0]
parent = kwargs.get("parent", None)
@ -162,20 +151,38 @@ class ClickableLabel(QLabel):
self._icon = icon
self._icon_size = icon_size
self._icon_space = icon_space
self._font_scale_factor = font_scale_factor
self._card_width = 250 # Значение по умолчанию
if change_cursor:
self.setCursor(Qt.CursorShape.PointingHandCursor)
self.updateFontSize()
def setIcon(self, icon):
"""Устанавливает иконку и перерисовывает виджет."""
self._icon = icon
self.update()
def icon(self):
"""Возвращает текущую иконку."""
return self._icon
def setIconSize(self, icon_size: int, icon_space: int):
self._icon_size = icon_size
self._icon_space = icon_space
self.update()
def setCardWidth(self, card_width: int):
"""Обновляет ширину карточки и пересчитывает размер шрифта."""
self._card_width = card_width
self.updateFontSize()
def updateFontSize(self):
"""Обновляет размер шрифта на основе card_width и font_scale_factor."""
font = self.font()
font_size = int(self._card_width * self._font_scale_factor)
font.setPointSize(max(8, font_size)) # Минимальный размер шрифта 8
self.setFont(font)
self.update()
def paintEvent(self, event):
"""Переопределяем отрисовку: рисуем иконку и текст в одном лейбле."""
painter = QPainter(self)
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
@ -190,7 +197,6 @@ class ClickableLabel(QLabel):
text = self.text()
if self._icon:
# Получаем QPixmap нужного размера
pixmap = self._icon.pixmap(icon_size, icon_size)
icon_rect = QRect(0, 0, icon_size, icon_size)
icon_rect.moveTop(rect.top() + (rect.height() - icon_size) // 2)
@ -214,13 +220,8 @@ class ClickableLabel(QLabel):
if pixmap:
icon_rect.moveLeft(x)
text_rect = QRect(x + icon_size + spacing, y, text_width, text_height)
else:
text_rect = QRect(x, y, text_width, text_height)
option = QStyleOption()
option.initFrom(self)
if pixmap:
painter.drawPixmap(icon_rect, pixmap)
self.style().drawItemText(
painter,
text_rect,

View File

@ -255,6 +255,42 @@ class GameCard(QFrame):
nameLabel.setStyleSheet(self.theme.GAME_CARD_NAME_LABEL_STYLE)
layout.addWidget(nameLabel)
def update_card_size(self, new_width: int):
self.card_width = new_width
extra_margin = 20
self.setFixedSize(new_width + extra_margin, int(new_width * 1.6) + extra_margin)
if self.coverLabel is None:
return
coverWidget = self.coverLabel.parentWidget()
if coverWidget is None:
return
coverWidget.setFixedSize(new_width, int(new_width * 1.2))
self.coverLabel.setFixedSize(new_width, int(new_width * 1.2))
label_ref = weakref.ref(self.coverLabel)
def on_cover_loaded(pixmap):
label = label_ref()
if label:
scaled_pixmap = pixmap.scaled(new_width, int(new_width * 1.2), Qt.AspectRatioMode.KeepAspectRatioByExpanding, Qt.TransformationMode.SmoothTransformation)
rounded_pixmap = round_corners(scaled_pixmap, 15)
label.setPixmap(rounded_pixmap)
load_pixmap_async(self.cover_path or "", new_width, int(new_width * 1.2), on_cover_loaded)
badge_width = int(new_width * 2/3)
icon_size = int(new_width * 0.06)
icon_space = int(new_width * 0.012)
for label in [self.steamLabel, self.egsLabel, self.portprotonLabel, self.protondbLabel, self.anticheatLabel]:
if label is not None:
label.setFixedWidth(badge_width)
label.setIconSize(icon_size, icon_space)
label.setCardWidth(new_width)
self.update()
def update_badge_visibility(self, display_filter: str):
"""Update badge visibility based on the provided display_filter."""
self.display_filter = display_filter

View File

@ -535,11 +535,13 @@ class MainWindow(QMainWindow):
def startSearchDebounce(self, text):
self.searchDebounceTimer.start()
def on_slider_value_changed(self, value: int):
self.card_width = value
self.sizeSlider.setToolTip(f"{value} px")
save_card_size(value)
self.updateGameGrid()
def on_slider_released(self):
self.card_width = self.sizeSlider.value()
self.sizeSlider.setToolTip(f"{self.card_width} px")
save_card_size(self.card_width)
for card in self.game_card_cache.values():
card.update_card_size(self.card_width)
self.updateGameGrid()
def filterGamesDelayed(self):
"""Filters games based on search text and updates the grid."""
@ -581,7 +583,7 @@ class MainWindow(QMainWindow):
self.sizeSlider.setFixedWidth(150)
self.sizeSlider.setToolTip(f"{self.card_width} px")
self.sizeSlider.setStyleSheet(self.theme.SLIDER_SIZE_STYLE)
self.sizeSlider.valueChanged.connect(self.on_slider_value_changed)
self.sizeSlider.sliderReleased.connect(self.on_slider_released)
sliderLayout.addWidget(self.sizeSlider)
layout.addLayout(sliderLayout)