Add ImageWidget and LibraryWidget from #196
Add the Image and Library widgets from #196. In this iteration they replace the image `QLabel` in the existing widgets. The `PaintWidget` in the `InstallingWidget` has been replaced by the future `LibraryWidget` that has progress indication. The `ImageWidget` was also used to replace the image `QLabel` in `GameInfo` and `GameDlc` widgets. Signed-off-by: loathingKernel <142770+loathingKernel@users.noreply.github.com>
This commit is contained in:
parent
8888cb3aee
commit
6335293eef
|
@ -87,7 +87,7 @@ class GamesTab(QStackedWidget, Ui_GamesTab):
|
||||||
logger.warning("No Unreal engine in library found")
|
logger.warning("No Unreal engine in library found")
|
||||||
self.ue_name = ""
|
self.ue_name = ""
|
||||||
|
|
||||||
self.uninstalled_info_tabs = UninstalledInfoTabs(self.ue_name, self)
|
self.uninstalled_info_tabs = UninstalledInfoTabs(self)
|
||||||
self.uninstalled_info_tabs.back_clicked.connect(lambda: self.setCurrentIndex(0))
|
self.uninstalled_info_tabs.back_clicked.connect(lambda: self.setCurrentIndex(0))
|
||||||
self.addWidget(self.uninstalled_info_tabs)
|
self.addWidget(self.uninstalled_info_tabs)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from PyQt5.QtCore import Qt, pyqtSignal
|
from PyQt5.QtCore import pyqtSignal
|
||||||
from PyQt5.QtGui import QPixmap, QResizeEvent
|
|
||||||
from PyQt5.QtWidgets import QFrame, QWidget, QMessageBox
|
from PyQt5.QtWidgets import QFrame, QWidget, QMessageBox
|
||||||
from legendary.models.game import Game
|
from legendary.models.game import Game
|
||||||
|
|
||||||
|
@ -9,6 +8,7 @@ from rare.shared.image_manager import ImageManagerSingleton, ImageSize
|
||||||
from rare.ui.components.tabs.games.game_info.game_dlc import Ui_GameDlc
|
from rare.ui.components.tabs.games.game_info.game_dlc import Ui_GameDlc
|
||||||
from rare.ui.components.tabs.games.game_info.game_dlc_widget import Ui_GameDlcWidget
|
from rare.ui.components.tabs.games.game_info.game_dlc_widget import Ui_GameDlcWidget
|
||||||
from rare.utils.models import InstallOptionsModel
|
from rare.utils.models import InstallOptionsModel
|
||||||
|
from rare.widgets.image_widget import ImageWidget
|
||||||
|
|
||||||
|
|
||||||
class GameDlc(QWidget, Ui_GameDlc):
|
class GameDlc(QWidget, Ui_GameDlc):
|
||||||
|
@ -94,13 +94,15 @@ class GameDlcWidget(QFrame, Ui_GameDlcWidget):
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.dlc = dlc
|
self.dlc = dlc
|
||||||
|
|
||||||
self.image.setFixedSize(ImageSize.Smaller.size)
|
self.image = ImageWidget(self)
|
||||||
|
self.image.setFixedSize(ImageSize.Smaller)
|
||||||
|
self.dlc_layout.insertWidget(0, self.image)
|
||||||
|
|
||||||
self.dlc_name.setText(dlc.app_title)
|
self.dlc_name.setText(dlc.app_title)
|
||||||
self.version.setText(dlc.app_version())
|
self.version.setText(dlc.app_version())
|
||||||
self.app_name.setText(dlc.app_name)
|
self.app_name.setText(dlc.app_name)
|
||||||
|
|
||||||
self.pixmap = self.image_manager.get_pixmap(dlc.app_name)
|
self.image.setPixmap(self.image_manager.get_pixmap(dlc.app_name))
|
||||||
|
|
||||||
if installed:
|
if installed:
|
||||||
self.action_button.setProperty("uninstall", 1)
|
self.action_button.setProperty("uninstall", 1)
|
||||||
|
@ -111,26 +113,6 @@ class GameDlcWidget(QFrame, Ui_GameDlcWidget):
|
||||||
self.action_button.clicked.connect(self.install_game)
|
self.action_button.clicked.connect(self.install_game)
|
||||||
self.action_button.setText(self.tr("Install DLC"))
|
self.action_button.setText(self.tr("Install DLC"))
|
||||||
|
|
||||||
def resizeEvent(self, a0: QResizeEvent) -> None:
|
|
||||||
self.image.clear()
|
|
||||||
super(GameDlcWidget, self).resizeEvent(a0)
|
|
||||||
self.setPixmap(self.pixmap)
|
|
||||||
|
|
||||||
def setPixmap(self, a0: QPixmap) -> None:
|
|
||||||
self.pixmap = a0
|
|
||||||
self.image.setPixmap(
|
|
||||||
self.pixmap.scaledToHeight(
|
|
||||||
self.dlc_info.size().height()
|
|
||||||
- (
|
|
||||||
self.image.contentsMargins().top()
|
|
||||||
+ self.image.contentsMargins().bottom()
|
|
||||||
+ self.image.lineWidth() * 2
|
|
||||||
),
|
|
||||||
Qt.SmoothTransformation,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
self.image.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
|
|
||||||
|
|
||||||
def uninstall_dlc(self):
|
def uninstall_dlc(self):
|
||||||
self.action_button.setDisabled(True)
|
self.action_button.setDisabled(True)
|
||||||
self.action_button.setText(self.tr("Uninstalling"))
|
self.action_button.setText(self.tr("Uninstalling"))
|
||||||
|
|
|
@ -40,6 +40,7 @@ from rare.utils.legendary_utils import VerifyWorker
|
||||||
from rare.utils.models import InstallOptionsModel
|
from rare.utils.models import InstallOptionsModel
|
||||||
from rare.utils.steam_grades import SteamWorker
|
from rare.utils.steam_grades import SteamWorker
|
||||||
from rare.utils.utils import get_size
|
from rare.utils.utils import get_size
|
||||||
|
from rare.widgets.image_widget import ImageWidget
|
||||||
|
|
||||||
logger = getLogger("GameInfo")
|
logger = getLogger("GameInfo")
|
||||||
|
|
||||||
|
@ -60,6 +61,10 @@ class GameInfo(QWidget, Ui_GameInfo):
|
||||||
self.image_manager = ImageManagerSingleton()
|
self.image_manager = ImageManagerSingleton()
|
||||||
self.game_utils = game_utils
|
self.game_utils = game_utils
|
||||||
|
|
||||||
|
self.image = ImageWidget(self)
|
||||||
|
self.image.setFixedSize(ImageSize.Display)
|
||||||
|
self.layout_game_info.insertWidget(0, self.image, alignment=Qt.AlignTop)
|
||||||
|
|
||||||
if platform.system() == "Windows":
|
if platform.system() == "Windows":
|
||||||
self.lbl_grade.setVisible(False)
|
self.lbl_grade.setVisible(False)
|
||||||
self.grade.setVisible(False)
|
self.grade.setVisible(False)
|
||||||
|
@ -283,11 +288,7 @@ class GameInfo(QWidget, Ui_GameInfo):
|
||||||
self.igame = self.core.get_installed_game(self.game.app_name)
|
self.igame = self.core.get_installed_game(self.game.app_name)
|
||||||
self.title.setTitle(self.game.app_title)
|
self.title.setTitle(self.game.app_title)
|
||||||
|
|
||||||
pixmap = self.image_manager.get_pixmap(self.game.app_name)
|
self.image.setPixmap(self.image_manager.get_pixmap(self.game.app_name, color=True))
|
||||||
if pixmap.isNull():
|
|
||||||
pixmap = self.image_manager.get_pixmap(self.parent().parent().parent().ue_name)
|
|
||||||
pixmap = pixmap.scaled(ImageSize.Display.size)
|
|
||||||
self.image.setPixmap(pixmap)
|
|
||||||
|
|
||||||
self.app_name.setText(self.game.app_name)
|
self.app_name.setText(self.game.app_name)
|
||||||
if self.igame:
|
if self.igame:
|
||||||
|
|
|
@ -17,16 +17,17 @@ from rare.utils.extra_widgets import SideTabWidget
|
||||||
from rare.utils.json_formatter import QJsonModel
|
from rare.utils.json_formatter import QJsonModel
|
||||||
from rare.utils.models import InstallOptionsModel
|
from rare.utils.models import InstallOptionsModel
|
||||||
from rare.utils.steam_grades import SteamWorker
|
from rare.utils.steam_grades import SteamWorker
|
||||||
|
from rare.widgets.image_widget import ImageWidget
|
||||||
|
|
||||||
|
|
||||||
class UninstalledInfoTabs(SideTabWidget):
|
class UninstalledInfoTabs(SideTabWidget):
|
||||||
def __init__(self, ue_default_name, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(UninstalledInfoTabs, self).__init__(show_back=True, parent=parent)
|
super(UninstalledInfoTabs, self).__init__(show_back=True, parent=parent)
|
||||||
self.core = LegendaryCoreSingleton()
|
self.core = LegendaryCoreSingleton()
|
||||||
self.signals = GlobalSignalsSingleton()
|
self.signals = GlobalSignalsSingleton()
|
||||||
self.args = ArgumentsSingleton()
|
self.args = ArgumentsSingleton()
|
||||||
|
|
||||||
self.info = UninstalledInfo(ue_default_name)
|
self.info = UninstalledInfo()
|
||||||
self.info.install_button.setDisabled(self.args.offline)
|
self.info.install_button.setDisabled(self.args.offline)
|
||||||
self.addTab(self.info, self.tr("Information"))
|
self.addTab(self.info, self.tr("Information"))
|
||||||
|
|
||||||
|
@ -70,7 +71,7 @@ class GameMetadataView(QTreeView):
|
||||||
class UninstalledInfo(QWidget, Ui_GameInfo):
|
class UninstalledInfo(QWidget, Ui_GameInfo):
|
||||||
game: Game
|
game: Game
|
||||||
|
|
||||||
def __init__(self, ue_default_name, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(UninstalledInfo, self).__init__(parent=parent)
|
super(UninstalledInfo, self).__init__(parent=parent)
|
||||||
self.setupUi(self)
|
self.setupUi(self)
|
||||||
self.core = LegendaryCoreSingleton()
|
self.core = LegendaryCoreSingleton()
|
||||||
|
@ -78,6 +79,10 @@ class UninstalledInfo(QWidget, Ui_GameInfo):
|
||||||
self.api_results = ApiResultsSingleton()
|
self.api_results = ApiResultsSingleton()
|
||||||
self.image_manager = ImageManagerSingleton()
|
self.image_manager = ImageManagerSingleton()
|
||||||
|
|
||||||
|
self.image = ImageWidget(self)
|
||||||
|
self.image.setFixedSize(ImageSize.Display)
|
||||||
|
self.layout_game_info.insertWidget(0, self.image, alignment=Qt.AlignTop)
|
||||||
|
|
||||||
self.install_button.clicked.connect(self.install_game)
|
self.install_button.clicked.connect(self.install_game)
|
||||||
if platform.system() != "Windows":
|
if platform.system() != "Windows":
|
||||||
self.steam_worker = SteamWorker(self.core)
|
self.steam_worker = SteamWorker(self.core)
|
||||||
|
@ -96,7 +101,6 @@ class UninstalledInfo(QWidget, Ui_GameInfo):
|
||||||
self.game_actions_stack.setCurrentIndex(1)
|
self.game_actions_stack.setCurrentIndex(1)
|
||||||
self.game_actions_stack.resize(self.game_actions_stack.minimumSize())
|
self.game_actions_stack.resize(self.game_actions_stack.minimumSize())
|
||||||
self.lbl_platform.setText(self.tr("Platforms"))
|
self.lbl_platform.setText(self.tr("Platforms"))
|
||||||
self.ue_default_name = ue_default_name
|
|
||||||
|
|
||||||
def install_game(self):
|
def install_game(self):
|
||||||
self.signals.install_game.emit(InstallOptionsModel(app_name=self.game.app_name))
|
self.signals.install_game.emit(InstallOptionsModel(app_name=self.game.app_name))
|
||||||
|
@ -111,11 +115,7 @@ class UninstalledInfo(QWidget, Ui_GameInfo):
|
||||||
available_platforms.append("macOS")
|
available_platforms.append("macOS")
|
||||||
self.platform.setText(", ".join(available_platforms))
|
self.platform.setText(", ".join(available_platforms))
|
||||||
|
|
||||||
pixmap = self.image_manager.get_pixmap(game.app_name, color=False)
|
self.image.setPixmap(self.image_manager.get_pixmap(self.game.app_name, color=True))
|
||||||
if pixmap.isNull():
|
|
||||||
pixmap = self.image_manager.get_pixmap(self.ue_default_name, color=False)
|
|
||||||
pixmap = pixmap.scaled(ImageSize.Display.size)
|
|
||||||
self.image.setPixmap(pixmap)
|
|
||||||
|
|
||||||
self.app_name.setText(self.game.app_name)
|
self.app_name.setText(self.game.app_name)
|
||||||
self.version.setText(self.game.app_version("Windows"))
|
self.version.setText(self.game.app_version("Windows"))
|
||||||
|
|
|
@ -4,12 +4,13 @@ from logging import getLogger
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, QProcess, QSettings, QStandardPaths, Qt, QByteArray
|
from PyQt5.QtCore import pyqtSignal, QProcess, QSettings, QStandardPaths, Qt, QByteArray
|
||||||
from PyQt5.QtGui import QPixmap
|
from PyQt5.QtGui import QPixmap
|
||||||
from PyQt5.QtWidgets import QGroupBox, QMessageBox, QAction, QLabel
|
from PyQt5.QtWidgets import QGroupBox, QMessageBox, QAction
|
||||||
|
|
||||||
from rare.components.tabs.games.game_utils import GameUtils
|
from rare.components.tabs.games.game_utils import GameUtils
|
||||||
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton
|
from rare.shared import LegendaryCoreSingleton, GlobalSignalsSingleton, ArgumentsSingleton
|
||||||
from rare.shared.image_manager import ImageManagerSingleton, ImageSize
|
from rare.shared.image_manager import ImageManagerSingleton, ImageSize
|
||||||
from rare.utils.utils import create_desktop_link
|
from rare.utils.utils import create_desktop_link
|
||||||
|
from rare.widgets.image_widget import ImageWidget
|
||||||
|
|
||||||
logger = getLogger("Game")
|
logger = getLogger("Game")
|
||||||
|
|
||||||
|
@ -63,11 +64,9 @@ class BaseInstalledWidget(QGroupBox):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self.image = QLabel()
|
self.image = ImageWidget(self)
|
||||||
self.image.setFixedSize(ImageSize.Display.size)
|
self.image.setFixedSize(ImageSize.Display)
|
||||||
self.image.setPixmap(
|
self.image.setPixmap(pixmap)
|
||||||
pixmap.scaled(ImageSize.Display.size, transformMode=Qt.SmoothTransformation)
|
|
||||||
)
|
|
||||||
self.game_running = False
|
self.game_running = False
|
||||||
self.offline = self.args.offline
|
self.offline = self.args.offline
|
||||||
self.update_available = False
|
self.update_available = False
|
||||||
|
@ -144,7 +143,7 @@ class BaseInstalledWidget(QGroupBox):
|
||||||
def reload_image(self):
|
def reload_image(self):
|
||||||
self.image_manager.download_image_blocking(self.game, force=True)
|
self.image_manager.download_image_blocking(self.game, force=True)
|
||||||
pm = self.image_manager.get_pixmap(self.game.app_name, color=True)
|
pm = self.image_manager.get_pixmap(self.game.app_name, color=True)
|
||||||
self.image.setPixmap(pm.scaled(ImageSize.Display.size, transformMode=Qt.SmoothTransformation))
|
self.image.setPixmap(pm)
|
||||||
|
|
||||||
def create_desktop_link(self, type_of_link):
|
def create_desktop_link(self, type_of_link):
|
||||||
if type_of_link == "desktop":
|
if type_of_link == "desktop":
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, Qt
|
from PyQt5.QtCore import pyqtSignal, Qt
|
||||||
from PyQt5.QtWidgets import QGroupBox, QLabel, QAction
|
from PyQt5.QtWidgets import QGroupBox, QAction
|
||||||
from legendary.models.game import Game
|
from legendary.models.game import Game
|
||||||
|
|
||||||
from rare.shared.image_manager import ImageManagerSingleton, ImageSize
|
from rare.shared.image_manager import ImageManagerSingleton, ImageSize
|
||||||
|
from rare.widgets.image_widget import ImageWidget
|
||||||
|
|
||||||
logger = getLogger("Uninstalled")
|
logger = getLogger("Uninstalled")
|
||||||
|
|
||||||
|
@ -21,9 +22,9 @@ class BaseUninstalledWidget(QGroupBox):
|
||||||
self.game.app_title = f"{self.game.app_title} {self.game.app_name.split('_')[-1]}"
|
self.game.app_title = f"{self.game.app_title} {self.game.app_name.split('_')[-1]}"
|
||||||
|
|
||||||
self.core = core
|
self.core = core
|
||||||
self.image = QLabel()
|
self.image = ImageWidget(self)
|
||||||
self.image.setFixedSize(ImageSize.Display.size)
|
self.image.setFixedSize(ImageSize.Display)
|
||||||
self.image.setPixmap(pixmap.scaled(ImageSize.Display.size, transformMode=Qt.SmoothTransformation))
|
self.image.setPixmap(pixmap)
|
||||||
self.installing = False
|
self.installing = False
|
||||||
self.setContextMenuPolicy(Qt.ActionsContextMenu)
|
self.setContextMenuPolicy(Qt.ActionsContextMenu)
|
||||||
self.setContentsMargins(0, 0, 0, 0)
|
self.setContentsMargins(0, 0, 0, 0)
|
||||||
|
@ -35,7 +36,7 @@ class BaseUninstalledWidget(QGroupBox):
|
||||||
def reload_image(self):
|
def reload_image(self):
|
||||||
self.image_manager.download_image_blocking(self.game, force=True)
|
self.image_manager.download_image_blocking(self.game, force=True)
|
||||||
pm = self.image_manager.get_pixmap(self.game.app_name, color=False)
|
pm = self.image_manager.get_pixmap(self.game.app_name, color=False)
|
||||||
self.image.setPixmap(pm.scaled(ImageSize.Display.size, transformMode=Qt.SmoothTransformation))
|
self.image.setPixmap(pm)
|
||||||
|
|
||||||
def install(self):
|
def install(self):
|
||||||
self.show_uninstalled_info.emit(self.game)
|
self.show_uninstalled_info.emit(self.game)
|
||||||
|
|
|
@ -1,41 +1,46 @@
|
||||||
from PyQt5.QtCore import Qt, QRect
|
from PyQt5.QtCore import Qt
|
||||||
from PyQt5.QtGui import QPaintEvent, QPainter, QPixmap, QPen, QFont, QColor
|
from PyQt5.QtGui import QPixmap
|
||||||
from PyQt5.QtWidgets import QVBoxLayout, QLabel, QHBoxLayout, QWidget
|
from PyQt5.QtWidgets import QVBoxLayout, QHBoxLayout, QGroupBox, QWidget
|
||||||
from legendary.models.game import Game
|
from legendary.models.game import Game
|
||||||
|
|
||||||
from rare.shared import LegendaryCoreSingleton
|
from rare.shared import LegendaryCoreSingleton
|
||||||
from rare.shared.image_manager import ImageManagerSingleton, ImageSize
|
from rare.shared.image_manager import ImageManagerSingleton, ImageSize
|
||||||
from rare.utils.utils import (
|
from rare.widgets.elide_label import ElideLabel
|
||||||
optimal_text_background,
|
from .library_widget import LibraryWidget
|
||||||
text_color_for_background,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class InstallingGameWidget(QWidget):
|
class InstallingGameWidget(QGroupBox):
|
||||||
game: Game = None
|
game: Game = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(InstallingGameWidget, self).__init__()
|
super(InstallingGameWidget, self).__init__()
|
||||||
|
layout = QVBoxLayout()
|
||||||
self.setObjectName("game_widget_icon")
|
self.setObjectName("game_widget_icon")
|
||||||
self.setProperty("noBorder", 1)
|
self.setContentsMargins(0, 0, 0, 0)
|
||||||
self.setLayout(QVBoxLayout())
|
|
||||||
|
|
||||||
self.core = LegendaryCoreSingleton()
|
self.core = LegendaryCoreSingleton()
|
||||||
|
self.image_manager = ImageManagerSingleton()
|
||||||
|
|
||||||
self.pixmap = QPixmap()
|
self.pixmap = QPixmap()
|
||||||
self.image_widget = PaintWidget()
|
self.image = LibraryWidget(parent=self)
|
||||||
self.setContentsMargins(0, 0, 0, 0)
|
self.image.setFixedSize(ImageSize.Display)
|
||||||
self.image_widget.setFixedSize(ImageSize.Display.size)
|
layout.addWidget(self.image)
|
||||||
self.layout().addWidget(self.image_widget)
|
|
||||||
|
|
||||||
self.title_label = QLabel(f"<h4>Error</h4>")
|
miniwidget = QWidget(self)
|
||||||
self.title_label.setAutoFillBackground(False)
|
miniwidget.setFixedWidth(ImageSize.Display.size.width())
|
||||||
self.title_label.setWordWrap(True)
|
|
||||||
self.title_label.setFixedWidth(175)
|
|
||||||
minilayout = QHBoxLayout()
|
minilayout = QHBoxLayout()
|
||||||
self.setObjectName("game_widget")
|
minilayout.setContentsMargins(0, 0, 0, 0)
|
||||||
minilayout.addWidget(self.title_label)
|
minilayout.setSpacing(0)
|
||||||
self.layout().addLayout(minilayout)
|
miniwidget.setLayout(minilayout)
|
||||||
|
|
||||||
|
self.title_label = ElideLabel(f"<h4>Error</h4>", parent=miniwidget)
|
||||||
|
self.title_label.setObjectName("game_widget")
|
||||||
|
minilayout.addWidget(self.title_label, stretch=2)
|
||||||
|
|
||||||
|
minilayout.setAlignment(Qt.AlignTop)
|
||||||
|
layout.addWidget(miniwidget)
|
||||||
|
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
def set_game(self, app_name):
|
def set_game(self, app_name):
|
||||||
if not app_name:
|
if not app_name:
|
||||||
|
@ -43,73 +48,11 @@ class InstallingGameWidget(QWidget):
|
||||||
return
|
return
|
||||||
self.game = self.core.get_game(app_name)
|
self.game = self.core.get_game(app_name)
|
||||||
self.title_label.setText(f"<h4>{self.game.app_title}</h4>")
|
self.title_label.setText(f"<h4>{self.game.app_title}</h4>")
|
||||||
|
self.image.hideProgress(True)
|
||||||
self.image_widget.set_game(self.game.app_name)
|
self.image.showProgress(
|
||||||
|
self.image_manager.get_pixmap(app_name, color=True),
|
||||||
|
self.image_manager.get_pixmap(app_name, color=False),
|
||||||
|
)
|
||||||
|
|
||||||
def set_status(self, s: int):
|
def set_status(self, s: int):
|
||||||
self.image_widget.progress = s
|
self.image.updateProgress(s)
|
||||||
self.image_widget.repaint()
|
|
||||||
|
|
||||||
|
|
||||||
class PaintWidget(QWidget):
|
|
||||||
color_image: QPixmap
|
|
||||||
bw_image: QPixmap
|
|
||||||
progress: int = 0
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super(PaintWidget, self).__init__()
|
|
||||||
self.core = LegendaryCoreSingleton()
|
|
||||||
self.image_manager = ImageManagerSingleton()
|
|
||||||
|
|
||||||
def set_game(self, app_name: str):
|
|
||||||
game = self.core.get_game(app_name, False)
|
|
||||||
self.color_image = self.image_manager.get_pixmap(game.app_name, color=False)
|
|
||||||
self.color_image = self.color_image.scaled(
|
|
||||||
ImageSize.Display.size, transformMode=Qt.SmoothTransformation
|
|
||||||
)
|
|
||||||
self.setFixedSize(ImageSize.Display.size)
|
|
||||||
self.bw_image = self.image_manager.get_pixmap(app_name, color=False)
|
|
||||||
self.bw_image = self.bw_image.scaled(
|
|
||||||
ImageSize.Display.size, transformMode=Qt.SmoothTransformation
|
|
||||||
)
|
|
||||||
self.progress = 0
|
|
||||||
|
|
||||||
pixel_list = []
|
|
||||||
for x in range(self.color_image.width()):
|
|
||||||
for y in range(self.color_image.height()):
|
|
||||||
# convert pixmap to qimage, get pixel and remove alpha channel
|
|
||||||
pixel_list.append(
|
|
||||||
self.color_image.toImage().pixelColor(x, y).getRgb()[:-1]
|
|
||||||
)
|
|
||||||
|
|
||||||
self.rgb_tuple = optimal_text_background(pixel_list)
|
|
||||||
|
|
||||||
def paintEvent(self, a0: QPaintEvent) -> None:
|
|
||||||
painter = QPainter()
|
|
||||||
painter.begin(self)
|
|
||||||
painter.setRenderHint(QPainter.Antialiasing)
|
|
||||||
painter.drawPixmap(self.rect(), self.bw_image)
|
|
||||||
|
|
||||||
w = self.bw_image.width() * self.progress // 100
|
|
||||||
|
|
||||||
painter.drawPixmap(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
w,
|
|
||||||
self.color_image.height(),
|
|
||||||
self.color_image.copy(QRect(0, 0, w, self.color_image.height())),
|
|
||||||
)
|
|
||||||
|
|
||||||
# Draw Circle
|
|
||||||
pen = QPen(QColor(*self.rgb_tuple), 3)
|
|
||||||
painter.setPen(pen)
|
|
||||||
painter.setBrush(QColor(*self.rgb_tuple))
|
|
||||||
painter.drawEllipse(
|
|
||||||
int(self.width() / 2) - 20, int(self.height() / 2) - 20, 40, 40
|
|
||||||
)
|
|
||||||
|
|
||||||
# draw text
|
|
||||||
painter.setPen(QColor(*text_color_for_background(self.rgb_tuple)))
|
|
||||||
painter.setFont(QFont(None, 16))
|
|
||||||
painter.drawText(a0.rect(), Qt.AlignCenter, f"{self.progress}%")
|
|
||||||
painter.end()
|
|
||||||
|
|
124
rare/components/tabs/games/game_widgets/library_widget.py
Normal file
124
rare/components/tabs/games/game_widgets/library_widget.py
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
from typing import Optional, Tuple, List
|
||||||
|
|
||||||
|
from PyQt5.QtCore import Qt, QRect, QEvent
|
||||||
|
from PyQt5.QtGui import QPainter, QPixmap, QResizeEvent, QFontMetrics, QImage, QBrush, QColor
|
||||||
|
from PyQt5.QtWidgets import QLabel
|
||||||
|
|
||||||
|
from rare.widgets.image_widget import ImageWidget
|
||||||
|
|
||||||
|
|
||||||
|
class ProgressLabel(QLabel):
|
||||||
|
def __init__(self, parent):
|
||||||
|
super(ProgressLabel, self).__init__(parent=parent)
|
||||||
|
self.setObjectName(type(self).__name__)
|
||||||
|
self.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
|
||||||
|
self.setFrameStyle(QLabel.StyledPanel)
|
||||||
|
|
||||||
|
def setGeometry(self, a0: QRect) -> None:
|
||||||
|
fm = QFontMetrics(self.font())
|
||||||
|
rect = fm.boundingRect(f" {self.text()} ")
|
||||||
|
rect.moveCenter(a0.center())
|
||||||
|
super(ProgressLabel, self).setGeometry(rect)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def calculateColors(image: QImage) -> Tuple[QColor, QColor]:
|
||||||
|
color: List[int] = [0, 0, 0]
|
||||||
|
# take the two diagonals of the center square section
|
||||||
|
min_d = min(image.width(), image.height())
|
||||||
|
origin_w = (image.width() - min_d) // 2
|
||||||
|
origin_h = (image.height() - min_d) // 2
|
||||||
|
for x, y in zip(range(origin_w, min_d), range(origin_h, min_d)):
|
||||||
|
pixel = image.pixelColor(x, y).getRgb()
|
||||||
|
color = list(map(lambda t: sum(t) // 2, zip(pixel[0:3], color)))
|
||||||
|
# take the V component of the HSV color
|
||||||
|
fg_color = QColor(0, 0, 0) if QColor(*color).value() < 127 else QColor(255, 255, 255)
|
||||||
|
bg_color = QColor(*map(lambda c: 255 - c, color))
|
||||||
|
return bg_color, fg_color
|
||||||
|
|
||||||
|
def setStyleSheetColors(self, bg: QColor, fg: QColor, brd: QColor):
|
||||||
|
sheet = (
|
||||||
|
f"background-color: rgba({bg.red()}, {bg.green()}, {bg.blue()}, 65%);"
|
||||||
|
f"color: rgb({fg.red()}, {fg.green()}, {fg.blue()});"
|
||||||
|
f"border-width: 1px;"
|
||||||
|
f"border-radius: 5%;"
|
||||||
|
f"border-color: rgb({brd.red()}, {brd.green()}, {brd.blue()});"
|
||||||
|
f"font-weight: bold;"
|
||||||
|
f"font-size: 16pt;"
|
||||||
|
)
|
||||||
|
self.setStyleSheet(sheet)
|
||||||
|
|
||||||
|
|
||||||
|
class LibraryWidget(ImageWidget):
|
||||||
|
_color_pixmap: Optional[QPixmap] = None
|
||||||
|
_gray_pixmap: Optional[QPixmap] = None
|
||||||
|
# lk: keep percentage to not over-generate the image
|
||||||
|
_progress: int = -1
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
parent=None,
|
||||||
|
) -> None:
|
||||||
|
super(LibraryWidget, self).__init__(parent)
|
||||||
|
self.progress_label = ProgressLabel(self)
|
||||||
|
self.progress_label.setVisible(False)
|
||||||
|
|
||||||
|
def event(self, e: QEvent) -> bool:
|
||||||
|
if e.type() == QEvent.LayoutRequest:
|
||||||
|
self.progress_label.setGeometry(self.rect())
|
||||||
|
return super(LibraryWidget, self).event(e)
|
||||||
|
|
||||||
|
def resizeEvent(self, a0: QResizeEvent) -> None:
|
||||||
|
if self.progress_label.isVisible():
|
||||||
|
self.progress_label.setGeometry(self.rect())
|
||||||
|
super(LibraryWidget, self).resizeEvent(a0)
|
||||||
|
|
||||||
|
def progressPixmap(self, color: QPixmap, gray: QPixmap, progress: int) -> QPixmap:
|
||||||
|
"""
|
||||||
|
Paints the color image over the gray images based on progress percentage
|
||||||
|
|
||||||
|
@param color:
|
||||||
|
@param gray:
|
||||||
|
@param progress:
|
||||||
|
@return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
device = QPixmap(color.size())
|
||||||
|
painter = QPainter(device)
|
||||||
|
painter.setRenderHint(QPainter.SmoothPixmapTransform, self._smooth_transform)
|
||||||
|
painter.setCompositionMode(QPainter.CompositionMode_Source)
|
||||||
|
# lk: Vertical loading
|
||||||
|
# prog_h = (device.height() * progress // 100)
|
||||||
|
# brush = QBrush(gray)
|
||||||
|
# painter.fillRect(device.rect().adjusted(0, 0, 0, -prog_h), brush)
|
||||||
|
# brush.setTexture(color)
|
||||||
|
# painter.fillRect(device.rect().adjusted(0, device.height() - prog_h, 0, 0), brush)
|
||||||
|
# lk: Horizontal loading
|
||||||
|
prog_w = device.width() * progress // 100
|
||||||
|
brush = QBrush(gray)
|
||||||
|
painter.fillRect(device.rect().adjusted(prog_w, 0, 0, 0), brush)
|
||||||
|
brush.setTexture(color)
|
||||||
|
painter.fillRect(device.rect().adjusted(0, 0, prog_w - device.width(), 0), brush)
|
||||||
|
painter.end()
|
||||||
|
device.setDevicePixelRatio(color.devicePixelRatioF())
|
||||||
|
return device
|
||||||
|
|
||||||
|
def showProgress(self, color_pm: QPixmap, gray_pm: QPixmap) -> None:
|
||||||
|
self._color_pixmap = color_pm
|
||||||
|
self._gray_pixmap = gray_pm
|
||||||
|
bg_color, fg_color = self.progress_label.calculateColors(color_pm.toImage())
|
||||||
|
self.progress_label.setStyleSheetColors(bg_color, fg_color, fg_color)
|
||||||
|
self.progress_label.setVisible(True)
|
||||||
|
self.progress_label.update()
|
||||||
|
self.updateProgress(0)
|
||||||
|
|
||||||
|
def updateProgress(self, progress: int):
|
||||||
|
if progress > self._progress:
|
||||||
|
self._progress = progress
|
||||||
|
self.progress_label.setText(f"{progress:02}%")
|
||||||
|
self.setPixmap(self.progressPixmap(self._color_pixmap, self._gray_pixmap, progress))
|
||||||
|
|
||||||
|
def hideProgress(self, stopped: bool):
|
||||||
|
self._color_pixmap = None
|
||||||
|
self._gray_pixmap = None
|
||||||
|
self.progress_label.setVisible(stopped)
|
||||||
|
self._progress = -1
|
|
@ -25,12 +25,6 @@ class Ui_GameDlcWidget(object):
|
||||||
GameDlcWidget.setFrameShadow(QtWidgets.QFrame.Plain)
|
GameDlcWidget.setFrameShadow(QtWidgets.QFrame.Plain)
|
||||||
self.dlc_layout = QtWidgets.QHBoxLayout(GameDlcWidget)
|
self.dlc_layout = QtWidgets.QHBoxLayout(GameDlcWidget)
|
||||||
self.dlc_layout.setObjectName("dlc_layout")
|
self.dlc_layout.setObjectName("dlc_layout")
|
||||||
self.image = QtWidgets.QLabel(GameDlcWidget)
|
|
||||||
self.image.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
|
||||||
self.image.setFrameShadow(QtWidgets.QFrame.Plain)
|
|
||||||
self.image.setText("image")
|
|
||||||
self.image.setObjectName("image")
|
|
||||||
self.dlc_layout.addWidget(self.image)
|
|
||||||
self.dlc_info = QtWidgets.QWidget(GameDlcWidget)
|
self.dlc_info = QtWidgets.QWidget(GameDlcWidget)
|
||||||
self.dlc_info.setObjectName("dlc_info")
|
self.dlc_info.setObjectName("dlc_info")
|
||||||
self.dlc_info_layout = QtWidgets.QFormLayout(self.dlc_info)
|
self.dlc_info_layout = QtWidgets.QFormLayout(self.dlc_info)
|
||||||
|
@ -105,7 +99,7 @@ class Ui_GameDlcWidget(object):
|
||||||
self.action_button.setText("Action")
|
self.action_button.setText("Action")
|
||||||
self.action_button.setObjectName("action_button")
|
self.action_button.setObjectName("action_button")
|
||||||
self.dlc_layout.addWidget(self.action_button, 0, QtCore.Qt.AlignTop)
|
self.dlc_layout.addWidget(self.action_button, 0, QtCore.Qt.AlignTop)
|
||||||
self.dlc_layout.setStretch(2, 1)
|
self.dlc_layout.setStretch(1, 1)
|
||||||
|
|
||||||
self.retranslateUi(GameDlcWidget)
|
self.retranslateUi(GameDlcWidget)
|
||||||
QtCore.QMetaObject.connectSlotsByName(GameDlcWidget)
|
QtCore.QMetaObject.connectSlotsByName(GameDlcWidget)
|
||||||
|
|
|
@ -25,20 +25,7 @@
|
||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>QFrame::Plain</enum>
|
<enum>QFrame::Plain</enum>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="dlc_layout" stretch="0,0,1,0">
|
<layout class="QHBoxLayout" name="dlc_layout" stretch="0,1,0">
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="image">
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::StyledPanel</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">image</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="dlc_info" native="true">
|
<widget class="QWidget" name="dlc_info" native="true">
|
||||||
<layout class="QFormLayout" name="dlc_info_layout">
|
<layout class="QFormLayout" name="dlc_info_layout">
|
||||||
|
|
|
@ -17,12 +17,6 @@ class Ui_GameInfo(object):
|
||||||
GameInfo.resize(791, 583)
|
GameInfo.resize(791, 583)
|
||||||
self.layout_game_info = QtWidgets.QHBoxLayout(GameInfo)
|
self.layout_game_info = QtWidgets.QHBoxLayout(GameInfo)
|
||||||
self.layout_game_info.setObjectName("layout_game_info")
|
self.layout_game_info.setObjectName("layout_game_info")
|
||||||
self.image = QtWidgets.QLabel(GameInfo)
|
|
||||||
self.image.setFrameShape(QtWidgets.QFrame.StyledPanel)
|
|
||||||
self.image.setFrameShadow(QtWidgets.QFrame.Sunken)
|
|
||||||
self.image.setText("")
|
|
||||||
self.image.setObjectName("image")
|
|
||||||
self.layout_game_info.addWidget(self.image, 0, QtCore.Qt.AlignTop)
|
|
||||||
self.layout_game_info_form = QtWidgets.QGridLayout()
|
self.layout_game_info_form = QtWidgets.QGridLayout()
|
||||||
self.layout_game_info_form.setContentsMargins(6, 6, 6, 6)
|
self.layout_game_info_form.setContentsMargins(6, 6, 6, 6)
|
||||||
self.layout_game_info_form.setSpacing(12)
|
self.layout_game_info_form.setSpacing(12)
|
||||||
|
|
|
@ -14,19 +14,6 @@
|
||||||
<string>Game Info</string>
|
<string>Game Info</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="layout_game_info">
|
<layout class="QHBoxLayout" name="layout_game_info">
|
||||||
<item alignment="Qt::AlignTop">
|
|
||||||
<widget class="QLabel" name="image">
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::StyledPanel</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Sunken</enum>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true"/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="layout_game_info_form">
|
<layout class="QGridLayout" name="layout_game_info_form">
|
||||||
<property name="leftMargin">
|
<property name="leftMargin">
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import math
|
|
||||||
import os
|
import os
|
||||||
import platform
|
import platform
|
||||||
import shlex
|
import shlex
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
from logging import getLogger
|
from logging import getLogger
|
||||||
from typing import List, Tuple
|
from typing import List
|
||||||
|
|
||||||
import qtawesome
|
import qtawesome
|
||||||
import requests
|
import requests
|
||||||
|
@ -306,35 +305,6 @@ def create_desktop_link(app_name=None, core: LegendaryCore = None, type_of_link=
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def optimal_text_background(image: list) -> Tuple[int, int, int]:
|
|
||||||
"""
|
|
||||||
Finds an optimal background color for text on the image by calculating the
|
|
||||||
average color of the image and inverting it.
|
|
||||||
|
|
||||||
The image list is supposed to be a one-dimensional list of arbitrary length
|
|
||||||
containing RGB tuples, ranging from 0 to 255.
|
|
||||||
"""
|
|
||||||
# cursed, I know
|
|
||||||
average = map(lambda value: value // len(image), map(sum, zip(*image)))
|
|
||||||
inverted = map(lambda value: 255 - value, average)
|
|
||||||
return tuple(inverted)
|
|
||||||
|
|
||||||
|
|
||||||
def text_color_for_background(background: Tuple[int, int, int]) -> Tuple[int, int, int]:
|
|
||||||
"""
|
|
||||||
Calculates whether a black or white text color would fit better for the
|
|
||||||
given background, and returns that color. This is done by calculating the
|
|
||||||
luminance and simple comparing of bounds
|
|
||||||
"""
|
|
||||||
# see https://alienryderflex.com/hsp.html
|
|
||||||
(red, green, blue) = background
|
|
||||||
luminance = math.sqrt(0.299 * red ** 2 + 0.587 * green ** 2 + 0.114 * blue ** 2)
|
|
||||||
if luminance < 127:
|
|
||||||
return 255, 255, 255
|
|
||||||
else:
|
|
||||||
return 0, 0, 0
|
|
||||||
|
|
||||||
|
|
||||||
class WineResolverSignals(QObject):
|
class WineResolverSignals(QObject):
|
||||||
result_ready = pyqtSignal(str)
|
result_ready = pyqtSignal(str)
|
||||||
|
|
||||||
|
|
144
rare/widgets/image_widget.py
Normal file
144
rare/widgets/image_widget.py
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
from enum import Enum
|
||||||
|
from typing import Tuple, Optional, Union
|
||||||
|
|
||||||
|
from PyQt5.QtCore import Qt, QRectF
|
||||||
|
from PyQt5.QtGui import (
|
||||||
|
QPaintEvent,
|
||||||
|
QPainter,
|
||||||
|
QPixmap,
|
||||||
|
QTransform,
|
||||||
|
QBrush,
|
||||||
|
QPalette,
|
||||||
|
QPainterPath,
|
||||||
|
QLinearGradient,
|
||||||
|
QColor,
|
||||||
|
)
|
||||||
|
from PyQt5.QtWidgets import QWidget
|
||||||
|
|
||||||
|
from rare.shared.image_manager import ImageSize
|
||||||
|
|
||||||
|
OverlayPath = Tuple[QPainterPath, Union[QColor, QLinearGradient]]
|
||||||
|
|
||||||
|
|
||||||
|
class ImageWidget(QWidget):
|
||||||
|
class Border(Enum):
|
||||||
|
Rounded = 0
|
||||||
|
Squared = 1
|
||||||
|
|
||||||
|
_pixmap: Optional[QPixmap] = None
|
||||||
|
_opacity: float = 1.0
|
||||||
|
_transform: QTransform
|
||||||
|
_smooth_transform: bool = False
|
||||||
|
_rounded_overlay: Optional[OverlayPath] = None
|
||||||
|
_squared_overlay: Optional[OverlayPath] = None
|
||||||
|
_image_size: Optional[ImageSize.Preset] = None
|
||||||
|
|
||||||
|
def __init__(self, parent=None) -> None:
|
||||||
|
super(ImageWidget, self).__init__(parent=parent)
|
||||||
|
self.setObjectName(type(self).__name__)
|
||||||
|
self.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.paint_image = self.paint_image_empty
|
||||||
|
self.paint_overlay = self.paint_overlay_rounded
|
||||||
|
|
||||||
|
def setOpacity(self, value: float) -> None:
|
||||||
|
self._opacity = value
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def setPixmap(self, pixmap: QPixmap) -> None:
|
||||||
|
if not pixmap.isNull():
|
||||||
|
self._pixmap = pixmap
|
||||||
|
self.paint_image = self.paint_image_cover
|
||||||
|
if not self._image_size:
|
||||||
|
self._transform = QTransform().scale(
|
||||||
|
1 / pixmap.devicePixelRatioF(),
|
||||||
|
1 / pixmap.devicePixelRatioF(),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self._transform = QTransform().scale(
|
||||||
|
1 / pixmap.devicePixelRatioF() / self._image_size.divisor,
|
||||||
|
1 / pixmap.devicePixelRatioF() / self._image_size.divisor,
|
||||||
|
)
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def setFixedSize(self, a0: ImageSize.Preset) -> None:
|
||||||
|
self._squared_overlay = None
|
||||||
|
self._rounded_overlay = None
|
||||||
|
self._image_size = a0
|
||||||
|
self._smooth_transform = a0.smooth
|
||||||
|
super(ImageWidget, self).setFixedSize(a0.size)
|
||||||
|
|
||||||
|
def setBorder(self, border: Border):
|
||||||
|
if border == ImageWidget.Border.Rounded:
|
||||||
|
self.paint_overlay = self.paint_overlay_rounded
|
||||||
|
else:
|
||||||
|
self.paint_overlay = self.paint_overlay_squared
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def _generate_squared_overlay(self) -> OverlayPath:
|
||||||
|
if self._image_size is not None and self._squared_overlay is not None:
|
||||||
|
return self._squared_overlay
|
||||||
|
path = QPainterPath()
|
||||||
|
path.addRect(0, 0, self.width(), self.height())
|
||||||
|
border = 2
|
||||||
|
inner_path = QPainterPath()
|
||||||
|
inner_path.addRect(
|
||||||
|
QRectF(
|
||||||
|
border,
|
||||||
|
border,
|
||||||
|
self.width() - border * 2,
|
||||||
|
self.height() - border * 2,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
gradient = QLinearGradient(0, 0, 0, self.height())
|
||||||
|
gradient.setColorAt(0.0, Qt.black)
|
||||||
|
gradient.setColorAt(1.0, Qt.transparent)
|
||||||
|
self._squared_overlay = path.subtracted(inner_path), gradient
|
||||||
|
return self._squared_overlay
|
||||||
|
|
||||||
|
def _generate_rounded_overlay(self) -> OverlayPath:
|
||||||
|
if self._image_size is not None and self._rounded_overlay is not None:
|
||||||
|
return self._rounded_overlay
|
||||||
|
# lk: the '-1' and '+1' are adjustments required for anti-aliasing
|
||||||
|
# lk: otherwise vertical lines would appear at the edges
|
||||||
|
path = QPainterPath()
|
||||||
|
path.addRect(-1, -1, self.width() + 2, self.height() + 2)
|
||||||
|
rounded_path = QPainterPath()
|
||||||
|
rounded_path.addRoundedRect(
|
||||||
|
QRectF(0, 0, self.width(), self.height()),
|
||||||
|
self.height() * 0.045,
|
||||||
|
self.height() * 0.045,
|
||||||
|
)
|
||||||
|
self._rounded_overlay = path.subtracted(rounded_path), QColor(0, 0, 0, 0)
|
||||||
|
return self._rounded_overlay
|
||||||
|
|
||||||
|
def paint_image_empty(self, painter: QPainter, a0: QPaintEvent) -> None:
|
||||||
|
# when pixmap object is not available yet, show a gray rectangle
|
||||||
|
painter.setOpacity(0.5 * self._opacity)
|
||||||
|
painter.fillRect(a0.rect(), Qt.darkGray)
|
||||||
|
|
||||||
|
def paint_image_cover(self, painter: QPainter, a0: QPaintEvent) -> None:
|
||||||
|
painter.setOpacity(self._opacity)
|
||||||
|
brush = QBrush(self._pixmap)
|
||||||
|
# downscale the image during painting to fit the pixelratio
|
||||||
|
brush.setTransform(self._transform)
|
||||||
|
painter.fillRect(a0.rect(), brush)
|
||||||
|
|
||||||
|
def paint_overlay_rounded(self, painter: QPainter, a0: QPaintEvent) -> None:
|
||||||
|
painter.setRenderHint(QPainter.Antialiasing, True)
|
||||||
|
painter.setOpacity(1.0)
|
||||||
|
painter.setCompositionMode(QPainter.CompositionMode_Source)
|
||||||
|
overlay, _ = self._generate_rounded_overlay()
|
||||||
|
painter.fillPath(overlay, self.palette().color(QPalette.Background))
|
||||||
|
|
||||||
|
def paint_overlay_squared(self, painter: QPainter, a0: QPaintEvent) -> None:
|
||||||
|
painter.setRenderHint(QPainter.Antialiasing, False)
|
||||||
|
painter.setOpacity(self._opacity)
|
||||||
|
painter.fillPath(*self._generate_squared_overlay())
|
||||||
|
|
||||||
|
def paintEvent(self, a0: QPaintEvent) -> None:
|
||||||
|
painter = QPainter(self)
|
||||||
|
# helps with better image quality
|
||||||
|
painter.setRenderHint(QPainter.SmoothPixmapTransform, self._smooth_transform)
|
||||||
|
self.paint_image(painter, a0)
|
||||||
|
self.paint_overlay(painter, a0)
|
||||||
|
painter.end()
|
Loading…
Reference in a new issue