feat: change game card size only on slider released
Signed-off-by: Boris Yumankulov <boria138@altlinux.org>
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
import numpy as np
|
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.QtCore import Qt, Signal, QRect, QPoint, QSize
|
||||||
from PySide6.QtGui import QFont, QFontMetrics, QPainter
|
from PySide6.QtGui import QFont, QFontMetrics, QPainter
|
||||||
|
|
||||||
@ -133,18 +133,7 @@ class FlowLayout(QLayout):
|
|||||||
class ClickableLabel(QLabel):
|
class ClickableLabel(QLabel):
|
||||||
clicked = Signal()
|
clicked = Signal()
|
||||||
|
|
||||||
def __init__(self, *args, icon=None, icon_size=16, icon_space=5, change_cursor=True, **kwargs):
|
def __init__(self, *args, icon=None, icon_size=16, icon_space=5, change_cursor=True, font_scale_factor=0.06, **kwargs):
|
||||||
"""
|
|
||||||
Поддерживаются вызовы:
|
|
||||||
- ClickableLabel("текст", parent=...) – первый аргумент строка,
|
|
||||||
- ClickableLabel(parent, text="...") – если первым аргументом передается родитель.
|
|
||||||
|
|
||||||
Аргументы:
|
|
||||||
icon: QIcon или None – иконка, которая будет отрисована вместе с текстом.
|
|
||||||
icon_size: int – размер иконки (ширина и высота).
|
|
||||||
icon_space: int – отступ между иконкой и текстом.
|
|
||||||
change_cursor: bool – изменять ли курсор на PointingHandCursor при наведении (по умолчанию True).
|
|
||||||
"""
|
|
||||||
if args and isinstance(args[0], str):
|
if args and isinstance(args[0], str):
|
||||||
text = args[0]
|
text = args[0]
|
||||||
parent = kwargs.get("parent", None)
|
parent = kwargs.get("parent", None)
|
||||||
@ -162,20 +151,38 @@ class ClickableLabel(QLabel):
|
|||||||
self._icon = icon
|
self._icon = icon
|
||||||
self._icon_size = icon_size
|
self._icon_size = icon_size
|
||||||
self._icon_space = icon_space
|
self._icon_space = icon_space
|
||||||
|
self._font_scale_factor = font_scale_factor
|
||||||
|
self._card_width = 250 # Значение по умолчанию
|
||||||
if change_cursor:
|
if change_cursor:
|
||||||
self.setCursor(Qt.CursorShape.PointingHandCursor)
|
self.setCursor(Qt.CursorShape.PointingHandCursor)
|
||||||
|
self.updateFontSize()
|
||||||
|
|
||||||
def setIcon(self, icon):
|
def setIcon(self, icon):
|
||||||
"""Устанавливает иконку и перерисовывает виджет."""
|
|
||||||
self._icon = icon
|
self._icon = icon
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
def icon(self):
|
def icon(self):
|
||||||
"""Возвращает текущую иконку."""
|
|
||||||
return self._icon
|
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):
|
def paintEvent(self, event):
|
||||||
"""Переопределяем отрисовку: рисуем иконку и текст в одном лейбле."""
|
|
||||||
painter = QPainter(self)
|
painter = QPainter(self)
|
||||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
||||||
|
|
||||||
@ -190,7 +197,6 @@ class ClickableLabel(QLabel):
|
|||||||
text = self.text()
|
text = self.text()
|
||||||
|
|
||||||
if self._icon:
|
if self._icon:
|
||||||
# Получаем QPixmap нужного размера
|
|
||||||
pixmap = self._icon.pixmap(icon_size, icon_size)
|
pixmap = self._icon.pixmap(icon_size, icon_size)
|
||||||
icon_rect = QRect(0, 0, icon_size, icon_size)
|
icon_rect = QRect(0, 0, icon_size, icon_size)
|
||||||
icon_rect.moveTop(rect.top() + (rect.height() - icon_size) // 2)
|
icon_rect.moveTop(rect.top() + (rect.height() - icon_size) // 2)
|
||||||
@ -214,13 +220,8 @@ class ClickableLabel(QLabel):
|
|||||||
if pixmap:
|
if pixmap:
|
||||||
icon_rect.moveLeft(x)
|
icon_rect.moveLeft(x)
|
||||||
text_rect = QRect(x + icon_size + spacing, y, text_width, text_height)
|
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)
|
painter.drawPixmap(icon_rect, pixmap)
|
||||||
|
|
||||||
self.style().drawItemText(
|
self.style().drawItemText(
|
||||||
painter,
|
painter,
|
||||||
text_rect,
|
text_rect,
|
||||||
|
@ -255,6 +255,42 @@ class GameCard(QFrame):
|
|||||||
nameLabel.setStyleSheet(self.theme.GAME_CARD_NAME_LABEL_STYLE)
|
nameLabel.setStyleSheet(self.theme.GAME_CARD_NAME_LABEL_STYLE)
|
||||||
layout.addWidget(nameLabel)
|
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):
|
def update_badge_visibility(self, display_filter: str):
|
||||||
"""Update badge visibility based on the provided display_filter."""
|
"""Update badge visibility based on the provided display_filter."""
|
||||||
self.display_filter = display_filter
|
self.display_filter = display_filter
|
||||||
|
@ -535,11 +535,13 @@ class MainWindow(QMainWindow):
|
|||||||
def startSearchDebounce(self, text):
|
def startSearchDebounce(self, text):
|
||||||
self.searchDebounceTimer.start()
|
self.searchDebounceTimer.start()
|
||||||
|
|
||||||
def on_slider_value_changed(self, value: int):
|
def on_slider_released(self):
|
||||||
self.card_width = value
|
self.card_width = self.sizeSlider.value()
|
||||||
self.sizeSlider.setToolTip(f"{value} px")
|
self.sizeSlider.setToolTip(f"{self.card_width} px")
|
||||||
save_card_size(value)
|
save_card_size(self.card_width)
|
||||||
self.updateGameGrid()
|
for card in self.game_card_cache.values():
|
||||||
|
card.update_card_size(self.card_width)
|
||||||
|
self.updateGameGrid()
|
||||||
|
|
||||||
def filterGamesDelayed(self):
|
def filterGamesDelayed(self):
|
||||||
"""Filters games based on search text and updates the grid."""
|
"""Filters games based on search text and updates the grid."""
|
||||||
@ -581,7 +583,7 @@ class MainWindow(QMainWindow):
|
|||||||
self.sizeSlider.setFixedWidth(150)
|
self.sizeSlider.setFixedWidth(150)
|
||||||
self.sizeSlider.setToolTip(f"{self.card_width} px")
|
self.sizeSlider.setToolTip(f"{self.card_width} px")
|
||||||
self.sizeSlider.setStyleSheet(self.theme.SLIDER_SIZE_STYLE)
|
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)
|
sliderLayout.addWidget(self.sizeSlider)
|
||||||
layout.addLayout(sliderLayout)
|
layout.addLayout(sliderLayout)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user