From 2a2458bacbc657cde271cea83ac75453e9b297b7 Mon Sep 17 00:00:00 2001 From: loathingKernel <142770+loathingKernel@users.noreply.github.com> Date: Sat, 3 Feb 2024 02:28:55 +0200 Subject: [PATCH] Store: Update details page * Add a big back button in details page. * Add static CSS to render QPushButtons as flat when the `flat` property is set * Remove outer scroll areas from details page since the page is already adjustable * Remove scroll area from the requirements widget because ElideLabels are already used in it. * Fix crash when sorting the wishlist --- rare/components/tabs/store/__main__.py | 3 +- rare/components/tabs/store/landing.py | 9 +-- rare/components/tabs/store/results.py | 1 - rare/components/tabs/store/search.py | 9 +-- rare/components/tabs/store/widgets/details.py | 61 +++++++++++-------- rare/components/tabs/store/wishlist.py | 19 +++--- rare/resources/static_css/stylesheet.py | 8 +++ rare/ui/components/tabs/store/details.py | 19 ++++-- rare/ui/components/tabs/store/details.ui | 38 ++++++++---- 9 files changed, 97 insertions(+), 70 deletions(-) diff --git a/rare/components/tabs/store/__main__.py b/rare/components/tabs/store/__main__.py index ad7c13f4..c14f5874 100644 --- a/rare/components/tabs/store/__main__.py +++ b/rare/components/tabs/store/__main__.py @@ -23,13 +23,14 @@ class StoreWindow(QDialog): if __name__ == "__main__": import rare.resources.static_css - import rare.resources.stylesheets.RareStyle + # import rare.resources.stylesheets.RareStyle from rare.utils.misc import set_style_sheet app = QApplication(sys.argv) app.setApplicationName("Rare") app.setOrganizationName("Rare") + set_style_sheet("") set_style_sheet("RareStyle") window = StoreWindow() window.setWindowTitle(f"{app.applicationName()} - Store") diff --git a/rare/components/tabs/store/landing.py b/rare/components/tabs/store/landing.py index 6f570a75..a55e5124 100644 --- a/rare/components/tabs/store/landing.py +++ b/rare/components/tabs/store/landing.py @@ -48,14 +48,9 @@ class LandingPage(SlidingStackedWidget, SideTabContents): self.details_widget.set_title.connect(self.set_title) self.details_widget.back_clicked.connect(self.show_main) - self.details_scroll = QScrollArea(self) - self.details_scroll.setWidgetResizable(True) - self.details_scroll.setFrameStyle(QFrame.NoFrame | QFrame.Plain) - self.details_scroll.setWidget(self.details_widget) - self.setDirection(Qt.Horizontal) self.addWidget(self.landing_scroll) - self.addWidget(self.details_scroll) + self.addWidget(self.details_widget) @pyqtSlot() def show_main(self): @@ -64,7 +59,7 @@ class LandingPage(SlidingStackedWidget, SideTabContents): @pyqtSlot(object) def show_details(self, game: CatalogOfferModel): self.details_widget.update_game(game) - self.slideInWidget(self.details_scroll) + self.slideInWidget(self.details_widget) class LandingWidget(QWidget, SideTabContents): diff --git a/rare/components/tabs/store/results.py b/rare/components/tabs/store/results.py index f837a103..6ae53088 100644 --- a/rare/components/tabs/store/results.py +++ b/rare/components/tabs/store/results.py @@ -17,7 +17,6 @@ class ResultsWidget(QScrollArea): def __init__(self, store_api, parent=None): super(ResultsWidget, self).__init__(parent=parent) - self.implements_scrollarea = True self.store_api = store_api self.results_container = QWidget(self) diff --git a/rare/components/tabs/store/search.py b/rare/components/tabs/store/search.py index 870e9daf..7e5d6d8d 100644 --- a/rare/components/tabs/store/search.py +++ b/rare/components/tabs/store/search.py @@ -40,14 +40,9 @@ class SearchPage(SlidingStackedWidget, SideTabContents): self.details_widget.set_title.connect(self.set_title) self.details_widget.back_clicked.connect(self.show_main) - self.details_scroll = QScrollArea(self) - self.details_scroll.setWidgetResizable(True) - self.details_scroll.setFrameStyle(QFrame.NoFrame | QFrame.Plain) - self.details_scroll.setWidget(self.details_widget) - self.setDirection(Qt.Horizontal) self.addWidget(self.search_widget) - self.addWidget(self.details_scroll) + self.addWidget(self.details_widget) @pyqtSlot() def show_main(self): @@ -56,7 +51,7 @@ class SearchPage(SlidingStackedWidget, SideTabContents): @pyqtSlot(object) def show_details(self, game: CatalogOfferModel): self.details_widget.update_game(game) - self.slideInWidget(self.details_scroll) + self.slideInWidget(self.details_widget) # noinspection PyAttributeOutsideInit,PyBroadException diff --git a/rare/components/tabs/store/widgets/details.py b/rare/components/tabs/store/widgets/details.py index f3a168fd..98f8eaf0 100644 --- a/rare/components/tabs/store/widgets/details.py +++ b/rare/components/tabs/store/widgets/details.py @@ -2,7 +2,7 @@ import logging from typing import List from PyQt5.QtCore import Qt, QUrl, pyqtSignal -from PyQt5.QtGui import QFont, QDesktopServices, QFontMetrics +from PyQt5.QtGui import QFont, QDesktopServices, QKeyEvent from PyQt5.QtWidgets import ( QWidget, QLabel, @@ -12,7 +12,7 @@ from PyQt5.QtWidgets import ( ) from rare.components.tabs.store.api.debug import DebugDialog -from rare.components.tabs.store.api.models.diesel import DieselProduct, DieselProductDetail +from rare.components.tabs.store.api.models.diesel import DieselProduct, DieselProductDetail, DieselSystemDetail from rare.components.tabs.store.api.models.response import CatalogOfferModel from rare.models.image import ImageSize from rare.ui.components.tabs.store.details import Ui_DetailsWidget @@ -30,6 +30,8 @@ class DetailsWidget(QWidget, SideTabContents): # TODO Design def __init__(self, installed_titles: list, api_core, parent=None): super(DetailsWidget, self).__init__(parent=parent) + self.implements_scrollarea = True + self.ui = Ui_DetailsWidget() self.ui.setupUi(self) self.ui.main_layout.setContentsMargins(0, 0, 3, 0) @@ -55,6 +57,7 @@ class DetailsWidget(QWidget, SideTabContents): self.requirements_tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.ui.requirements_layout.addWidget(self.requirements_tabs) + self.ui.back_button.setIcon(icon("fa.chevron-left")) self.ui.back_button.clicked.connect(self.back_clicked) self.setDisabled(False) @@ -182,31 +185,10 @@ class DetailsWidget(QWidget, SideTabContents): else: self.ui.discount_price.setVisible(False) - bold_font = QFont() - bold_font.setBold(True) - - fm = QFontMetrics(self.font()) requirements = product_data.requirements if requirements and requirements.systems: for system in requirements.systems: - req_widget = QWidget(self.requirements_tabs) - req_layout = QGridLayout(req_widget) - req_widget.layout().setAlignment(Qt.AlignTop) - req_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) - min_label = QLabel(self.tr("Minimum"), parent=req_widget) - min_label.setFont(bold_font) - rec_label = QLabel(self.tr("Recommend"), parent=req_widget) - rec_label.setFont(bold_font) - req_layout.addWidget(min_label, 0, 1) - req_layout.addWidget(rec_label, 0, 2) - req_layout.setColumnStretch(1, 2) - req_layout.setColumnStretch(2, 2) - for i, detail in enumerate(system.details): - req_layout.addWidget(QLabel(detail.title, parent=req_widget), i + 1, 0) - min_label = ElideLabel(detail.minimum, parent=req_widget) - req_layout.addWidget(min_label, i + 1, 1) - rec_label = ElideLabel(detail.recommended, parent=req_widget) - req_layout.addWidget(rec_label, i + 1, 2) + req_widget = RequirementsWidget(system, self.requirements_tabs) self.requirements_tabs.addTab(req_widget, system.system_type) # self.req_group_box.layout().addWidget(req_tabs) # self.req_group_box.layout().setAlignment(Qt.AlignTop) @@ -273,6 +255,10 @@ class DetailsWidget(QWidget, SideTabContents): return QDesktopServices.openUrl(QUrl(f"https://www.epicgames.com/store/{self.core.language_code}/p/{self.slug}")) + def keyPressEvent(self, a0: QKeyEvent): + if a0.key() == Qt.Key_Escape: + self.back_clicked.emit() + class SocialButton(QPushButton): def __init__(self, icn, url, parent=None): @@ -280,3 +266,30 @@ class SocialButton(QPushButton): self.url = url self.clicked.connect(lambda: QDesktopServices.openUrl(QUrl(url))) self.setToolTip(url) + + +class RequirementsWidget(QWidget, SideTabContents): + def __init__(self, system: DieselSystemDetail, parent=None): + super().__init__(parent=parent) + self.implements_scrollarea = True + + bold_font = self.font() + bold_font.setBold(True) + + req_layout = QGridLayout(self) + min_label = QLabel(self.tr("Minimum"), parent=self) + min_label.setFont(bold_font) + rec_label = QLabel(self.tr("Recommend"), parent=self) + rec_label.setFont(bold_font) + req_layout.addWidget(min_label, 0, 1) + req_layout.addWidget(rec_label, 0, 2) + req_layout.setColumnStretch(1, 2) + req_layout.setColumnStretch(2, 2) + for i, detail in enumerate(system.details): + req_layout.addWidget(QLabel(detail.title, parent=self), i + 1, 0) + min_label = ElideLabel(detail.minimum, parent=self) + req_layout.addWidget(min_label, i + 1, 1) + rec_label = ElideLabel(detail.recommended, parent=self) + req_layout.addWidget(rec_label, i + 1, 2) + req_layout.setAlignment(Qt.AlignTop) + self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) diff --git a/rare/components/tabs/store/wishlist.py b/rare/components/tabs/store/wishlist.py index 3d9305fd..bedc2ca4 100644 --- a/rare/components/tabs/store/wishlist.py +++ b/rare/components/tabs/store/wishlist.py @@ -30,14 +30,9 @@ class WishlistPage(SlidingStackedWidget, SideTabContents): self.details_widget.set_title.connect(self.set_title) self.details_widget.back_clicked.connect(self.show_main) - self.details_scroll = QScrollArea(self) - self.details_scroll.setWidgetResizable(True) - self.details_scroll.setFrameStyle(QFrame.NoFrame | QFrame.Plain) - self.details_scroll.setWidget(self.details_widget) - self.setDirection(Qt.Horizontal) self.addWidget(self.wishlist_widget) - self.addWidget(self.details_scroll) + self.addWidget(self.details_widget) @pyqtSlot() def show_main(self): @@ -46,7 +41,7 @@ class WishlistPage(SlidingStackedWidget, SideTabContents): @pyqtSlot(object) def show_details(self, game: CatalogOfferModel): self.details_widget.update_game(game) - self.slideInWidget(self.details_scroll) + self.slideInWidget(self.details_widget) class WishlistWidget(QWidget, SideTabContents): @@ -118,19 +113,19 @@ class WishlistWidget(QWidget, SideTabContents): self.ui.list_container.layout().removeWidget(w) if sort == 0: - func = lambda x: x.game.title + func = lambda x: x.catalog_game.title reverse = self.ui.reverse.isChecked() elif sort == 1: - func = lambda x: x.game.price.total_price["fmtPrice"]["discountPrice"] + func = lambda x: x.catalog_game.price.total_price["fmtPrice"]["discountPrice"] reverse = self.ui.reverse.isChecked() elif sort == 2: - func = lambda x: x.game.seller["name"] + func = lambda x: x.catalog_game.seller["name"] reverse = self.ui.reverse.isChecked() elif sort == 3: - func = lambda x: 1 - (x.game.price.total_price["discountPrice"] / x.game.price.total_price["originalPrice"]) + func = lambda x: 1 - (x.catalog_game.price.total_price["discountPrice"] / x.catalog_game.price.total_price["originalPrice"]) reverse = not self.ui.reverse.isChecked() else: - func = lambda x: x.game.title + func = lambda x: x.catalog_game.title reverse = self.ui.reverse.isChecked() widgets = sorted(widgets, key=func, reverse=reverse) diff --git a/rare/resources/static_css/stylesheet.py b/rare/resources/static_css/stylesheet.py index 551826e7..43a7aece 100644 --- a/rare/resources/static_css/stylesheet.py +++ b/rare/resources/static_css/stylesheet.py @@ -64,6 +64,14 @@ def css_name(widget: Union[wrappertype, QObject, Type], subwidget: str = ""): css = qstylizer.style.StyleSheet() +# Generic flat button +css['QPushButton[flat="true"]'].setValues( + border="0px", + borderRadius="5px", + backgroundColor="rgba(255, 255, 255, 5%)", +) + + # InfoLabel css.QLabel["#InfoLabel"].setValues( color="#999", diff --git a/rare/ui/components/tabs/store/details.py b/rare/ui/components/tabs/store/details.py index e547df2f..5c570cb2 100644 --- a/rare/ui/components/tabs/store/details.py +++ b/rare/ui/components/tabs/store/details.py @@ -14,16 +14,23 @@ from PyQt5 import QtCore, QtGui, QtWidgets class Ui_DetailsWidget(object): def setupUi(self, DetailsWidget): DetailsWidget.setObjectName("DetailsWidget") - DetailsWidget.resize(414, 343) + DetailsWidget.resize(702, 414) DetailsWidget.setWindowTitle("DetailsWidget") self.main_layout = QtWidgets.QHBoxLayout(DetailsWidget) self.main_layout.setObjectName("main_layout") + self.back_button = QtWidgets.QPushButton(DetailsWidget) + sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding) + sizePolicy.setHorizontalStretch(0) + sizePolicy.setVerticalStretch(0) + sizePolicy.setHeightForWidth(self.back_button.sizePolicy().hasHeightForWidth()) + self.back_button.setSizePolicy(sizePolicy) + self.back_button.setText("") + self.back_button.setIconSize(QtCore.QSize(32, 32)) + self.back_button.setFlat(True) + self.back_button.setObjectName("back_button") + self.main_layout.addWidget(self.back_button) self.left_layout = QtWidgets.QVBoxLayout() self.left_layout.setObjectName("left_layout") - self.back_button = QtWidgets.QPushButton(DetailsWidget) - self.back_button.setText("") - self.back_button.setObjectName("back_button") - self.left_layout.addWidget(self.back_button) self.main_layout.addLayout(self.left_layout) self.right_layout = QtWidgets.QVBoxLayout() self.right_layout.setObjectName("right_layout") @@ -169,7 +176,7 @@ class Ui_DetailsWidget(object): self.description_label.setObjectName("description_label") self.right_layout.addWidget(self.description_label) self.main_layout.addLayout(self.right_layout) - self.main_layout.setStretch(1, 1) + self.main_layout.setStretch(2, 1) self.retranslateUi(DetailsWidget) diff --git a/rare/ui/components/tabs/store/details.ui b/rare/ui/components/tabs/store/details.ui index af07ca9f..20b21038 100644 --- a/rare/ui/components/tabs/store/details.ui +++ b/rare/ui/components/tabs/store/details.ui @@ -6,24 +6,38 @@ 0 0 - 414 - 343 + 702 + 414 DetailsWidget - + - - - - - - - - - + + + + 0 + 0 + + + + + + + + 32 + 32 + + + + true + + + + +