1
0
Fork 0
mirror of synced 2024-05-04 20:52:58 +12:00

Store: Exploratory changes to the store page

Important changes:
* Refactored QtRequests to accept parameters for `GET` operations
* Infer response data type from content-type header
* Support caching to disk, a manager with this set prefers the cache
* Support multiple handlers for a single request (unused, possibly pointeless)

* Subclass `ShopImageWidget` for all widgets used in the shop
* Request a resized image instead of the original one
* Fix the search and browse functions
This commit is contained in:
loathingKernel 2023-04-04 14:46:02 +03:00
parent 7246078df3
commit f6396f488a
No known key found for this signature in database
GPG key ID: CE0C72D0B53821FD
18 changed files with 441 additions and 424 deletions

View file

@ -25,12 +25,12 @@ class StoreTab(SideTabWidget):
)
self.shop = ShopWidget(cache_dir(), self.core, self.api_core, parent=self)
self.shop_index = self.addTab(self.shop, self.tr("Games"))
self.shop_index = self.addTab(self.shop, self.tr("Store"))
self.shop.show_game.connect(self.show_game)
self.shop.show_info.connect(self.show_search)
self.search = SearchResults(self.api_core, parent=self)
self.search_index = self.addTab(self.search, self.tr("Search"))
self.search_index = self.addTab(self.search, self.tr("Search"), self.tr("Results"))
self.search.show_info.connect(self.show_game)
# self.search.back_button.clicked.connect(lambda: self.setCurrentIndex(self.shop_index))
@ -40,11 +40,11 @@ class StoreTab(SideTabWidget):
self.api_core,
parent=self
)
self.info_index = self.addTab(self.info, self.tr("Information"))
self.info_index = self.addTab(self.info, self.tr("Information"), self.tr("Information"))
# self.info.back_button.clicked.connect(lambda: self.setCurrentIndex(self.previous_index))
self.wishlist = Wishlist(self.api_core, parent=self)
self.wishlist_index = self.addTab(self.wishlist, self.tr("Wishlist"))
self.wishlist_index = self.addTab(self.wishlist, self.tr("Wishlist"), self.tr("Wishlist"))
self.wishlist.update_wishlist_signal.connect(self.update_wishlist)
self.wishlist.show_game_info.connect(self.show_game)

View file

@ -27,9 +27,12 @@ if __name__ == "__main__":
import rare.resources.stylesheets.RareStyle
app = QApplication(sys.argv)
app.setApplicationName("Rare")
app.setOrganizationName("Rare")
set_style_sheet("RareStyle")
window = StoreWindow()
window.setWindowTitle(f"{app.applicationName()} - Store")
window.resize(QSize(1280, 800))
window.show()
app.exec()

View file

@ -33,7 +33,7 @@ class ShopGameInfo(QWidget, SideTabContents):
self.api_core = api_core
self.installed = installed_titles
self.ui.open_store_button.clicked.connect(self.button_clicked)
self.image = ShopImageWidget(self)
self.image = ShopImageWidget(api_core.cached_manager, self)
self.image.setFixedSize(ImageSize.Normal)
self.ui.left_layout.insertWidget(0, self.image, alignment=Qt.AlignTop)
@ -139,7 +139,7 @@ class ShopGameInfo(QWidget, SideTabContents):
"VaultClosed",
"ProductLogo",
]:
self.image.fetchPixmap(img["url"], self.id_str, self.title_str)
self.image.fetchPixmap(img["url"])
break
self.price.setText("")
self.discount_price.setText("")
@ -207,7 +207,7 @@ class ShopGameInfo(QWidget, SideTabContents):
img_url = self.game.image_urls.product_logo
else:
img_url = ""
self.image.fetchPixmap(img_url, self.game.id, self.game.title)
self.image.fetchPixmap(img_url)
# self.image_stack.setCurrentIndex(0)
try:

View file

@ -1,15 +1,13 @@
import logging
from PyQt5 import QtGui
from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtGui import QFont, QMouseEvent
from PyQt5.QtWidgets import QWidget
from PyQt5.QtGui import QMouseEvent
from PyQt5.QtWidgets import QPushButton
from rare.components.tabs.store.shop_models import ImageUrlModel
from rare.shared.image_manager import ImageSize
from rare.ui.components.tabs.store.wishlist_widget import Ui_WishlistWidget
from rare.utils.extra_widgets import ImageLabel
from rare.utils.misc import qta_icon
from rare.utils.qt_requests import QtRequestManager
from .image_widget import ShopImageWidget
logger = logging.getLogger("GameWidgets")
@ -18,11 +16,10 @@ logger = logging.getLogger("GameWidgets")
class GameWidget(ShopImageWidget):
show_info = pyqtSignal(dict)
def __init__(self, path, json_info=None, parent=None):
super(GameWidget, self).__init__(parent=parent)
def __init__(self, manager: QtRequestManager, json_info=None, parent=None):
super(GameWidget, self).__init__(manager, parent=parent)
self.setFixedSize(ImageSize.Wide)
self.ui.setupUi(self)
self.path = path
self.json_info = json_info
if json_info:
self.init_ui(json_info)
@ -33,6 +30,13 @@ class GameWidget(ShopImageWidget):
return
self.ui.title_label.setText(json_info.get("title"))
for attr in json_info["customAttributes"]:
if attr["key"] == "developerName":
developer = attr["value"]
break
else:
developer = json_info["seller"]["name"]
self.ui.developer_label.setText(developer)
price = json_info["price"]["totalPrice"]["fmtPrice"]["originalPrice"]
discount_price = json_info["price"]["totalPrice"]["fmtPrice"]["discountPrice"]
self.ui.price_label.setText(f'{price if price != "0" else self.tr("Free")}')
@ -51,7 +55,7 @@ class GameWidget(ShopImageWidget):
if img["type"] in ["DieselStoreFrontWide", "OfferImageWide", "VaultClosed", "ProductLogo",]:
if img["type"] == "VaultClosed" and json_info["title"] != "Mystery Game":
continue
self.fetchPixmap(img["url"], json_info["id"], json_info["title"])
self.fetchPixmap(img["url"])
break
else:
logger.info(", ".join([img["type"] for img in json_info["keyImages"]]))
@ -62,52 +66,52 @@ class GameWidget(ShopImageWidget):
self.show_info.emit(self.json_info)
class WishlistWidget(QWidget, Ui_WishlistWidget):
class WishlistWidget(ShopImageWidget):
open_game = pyqtSignal(dict)
delete_from_wishlist = pyqtSignal(dict)
def __init__(self, game: dict):
super(WishlistWidget, self).__init__()
self.setupUi(self)
def __init__(self, manager: QtRequestManager, game: dict, parent=None):
super(WishlistWidget, self).__init__(manager, parent=parent)
self.setFixedSize(ImageSize.Wide)
self.ui.setupUi(self)
self.game = game
self.title_label.setText(game.get("title"))
for attr in game["customAttributes"]:
if attr["key"] == "developerName":
self.developer.setText(attr["value"])
developer = attr["value"]
break
else:
self.developer.setText(game["seller"]["name"])
developer = game["seller"]["name"]
original_price = game["price"]["totalPrice"]["fmtPrice"]["originalPrice"]
discount_price = game["price"]["totalPrice"]["fmtPrice"]["discountPrice"]
self.price.setText(original_price if original_price != "0" else self.tr("Free"))
# if discount
self.ui.title_label.setText(game.get("title"))
self.ui.developer_label.setText(developer)
self.ui.price_label.setText(f'{original_price if original_price != "0" else self.tr("Free")}')
if original_price != discount_price:
self.discount = True
font = QFont()
font = self.ui.price_label.font()
font.setStrikeOut(True)
self.price.setFont(font)
self.discount_price.setText(discount_price)
self.ui.price_label.setFont(font)
self.ui.discount_label.setText(f'{discount_price if discount_price != "0" else self.tr("Free")}')
else:
self.discount = False
self.discount_price.setVisible(False)
self.image = ImageLabel()
self.layout().insertWidget(0, self.image)
self.ui.discount_label.setVisible(False)
image_model = ImageUrlModel.from_json(game["keyImages"])
url = image_model.front_wide
if not url:
url = image_model.offer_image_wide
self.image.update_image(url, game.get("title"), (240, 135))
self.fetchPixmap(url)
self.delete_button = QPushButton(self)
self.delete_button.setIcon(icon("mdi.delete", color="white"))
self.delete_button.clicked.connect(
lambda: self.delete_from_wishlist.emit(self.game)
)
self.layout().insertWidget(0, self.delete_button, alignment=Qt.AlignRight)
def mousePressEvent(self, e: QtGui.QMouseEvent) -> None:
def mousePressEvent(self, a0: QMouseEvent) -> None:
# left button
if e.button() == 1:
if a0.button() == Qt.LeftButton:
a0.accept()
self.open_game.emit(self.game)
# right
elif e.button() == 2:
elif a0.button() == Qt.RightButton:
pass # self.showMenu(e)

View file

@ -1,10 +1,10 @@
from typing import Dict
from PyQt5.QtCore import QRect
from PyQt5.QtCore import QEvent, QObject
from PyQt5.QtCore import Qt
from PyQt5.QtGui import (
QPixmap,
QImage, QMovie,
QImage,
QMovie,
QShowEvent,
)
from PyQt5.QtWidgets import (
QWidget,
@ -24,19 +24,43 @@ class WaitingSpinner(QLabel):
super(WaitingSpinner, self).__init__(parent=parent)
self.setObjectName(type(self).__name__)
self.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
self.movie = QMovie(":/images/loader.gif")
self.movie = QMovie(":/images/loader.gif", parent=self)
self.setFixedSize(128, 128)
self.setMovie(self.movie)
if self.parent() is not None:
self.parent().installEventFilter(self)
if autostart:
self.movie.start()
def setGeometry(self, a0: QRect) -> None:
self.rect().moveCenter(self.parent().rect().center())
super(WaitingSpinner, self).setGeometry(self.rect())
def __center_on_parent(self):
rect = self.rect()
rect.moveCenter(self.parent().contentsRect().center())
self.setGeometry(rect)
def event(self, e: QEvent) -> bool:
if e.type() == QEvent.ParentAboutToChange:
if self.parent() is not None:
self.parent().removeEventFilter(self)
if e.type() == QEvent.ParentChange:
if self.parent() is not None:
self.parent().installEventFilter(self)
return super().event(e)
def showEvent(self, a0: QShowEvent) -> None:
self.__center_on_parent()
def eventFilter(self, a0: QObject, a1: QEvent) -> bool:
if a0 is self.parent() and a1.type() == QEvent.Resize:
self.__center_on_parent()
return a0.event(a1)
return False
def start(self):
self.setVisible(True)
self.movie.start()
def stop(self):
self.setVisible(False)
self.movie.stop()
@ -44,6 +68,7 @@ class IconWidget(object):
def __init__(self):
self.mini_widget: QWidget = None
self.title_label: QLabel = None
self.developer_label: QLabel = None
self.price_label: QLabel = None
self.discount_label: QLabel = None
@ -57,19 +82,24 @@ class IconWidget(object):
self.title_label = QLabel(parent=self.mini_widget)
self.title_label.setObjectName(f"{type(self).__name__}TitleLabel")
self.title_label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.title_label.setAlignment(Qt.AlignVCenter)
self.title_label.setAlignment(Qt.AlignTop)
self.title_label.setAutoFillBackground(False)
self.title_label.setWordWrap(True)
# information below title
self.developer_label = QLabel(parent=self.mini_widget)
self.developer_label.setObjectName(f"{type(self).__name__}TooltipLabel")
self.developer_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
self.developer_label.setAutoFillBackground(False)
self.price_label = QLabel(parent=self.mini_widget)
self.price_label.setObjectName(f"{type(self).__name__}TooltipLabel")
self.price_label.setAlignment(Qt.AlignRight)
self.price_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.price_label.setAutoFillBackground(False)
self.discount_label = QLabel(parent=self.mini_widget)
self.discount_label.setObjectName(f"{type(self).__name__}TooltipLabel")
self.discount_label.setAlignment(Qt.AlignRight)
self.discount_label.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.discount_label.setAutoFillBackground(False)
# Create layouts
@ -88,7 +118,8 @@ class IconWidget(object):
# Layout the widgets
# (from inner to outer)
row_layout.addWidget(self.price_label, stretch=2)
row_layout.addWidget(self.developer_label, stretch=2)
row_layout.addWidget(self.price_label)
row_layout.addWidget(self.discount_label)
mini_layout.addWidget(self.title_label)
mini_layout.addLayout(row_layout)
@ -100,45 +131,29 @@ class IconWidget(object):
class ShopImageWidget(ImageWidget):
__image_cache: Dict[str, Dict[str, QPixmap]] = {}
def __init__(self, parent=None):
def __init__(self, manager: QtRequestManager, parent=None):
super(ShopImageWidget, self).__init__(parent=parent)
self.ui = IconWidget()
self.spinner = WaitingSpinner(parent=self)
self.spinner.setVisible(False)
self.manager = QtRequestManager("bytes")
self.app_id = ""
self.orientation = ""
self.manager = manager
def fetchPixmap(self, url, app_id: str, title: str = ""):
def fetchPixmap(self, url):
self.setPixmap(QPixmap())
self.app_id = app_id
if self._image_size.size.width() > self._image_size.size.height():
self.orientation = "wide"
else:
self.orientation = "tall"
if ShopImageWidget.__image_cache.get(self.app_id, None) is not None:
if pixmap := ShopImageWidget.__image_cache[self.app_id].get(self.orientation, None):
self.setPixmap(pixmap)
return
self.spinner.setFixedSize(self._image_size.size)
self.spinner.setVisible(True)
self.spinner.start()
self.manager.get(
url, self.__on_image_ready, payload={
"resize": 1, "w": self._image_size.size.width(), "h": self._image_size.size.height()
}
)
self.manager.get(url, self.__on_image_ready, params={
"resize": 1,
"w": self._image_size.base.size.width(),
"h": self._image_size.base.size.height(),
})
def __on_image_ready(self, data):
cover = QImage()
cover.loadFromData(data)
cover = cover.scaled(self._image_size.size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
# cover = cover.scaled(self._image_size.size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
cover.setDevicePixelRatio(self._image_size.base.pixel_ratio)
cover = cover.convertToFormat(QImage.Format_ARGB32_Premultiplied)
cover = QPixmap(cover)
ShopImageWidget.__image_cache.update({self.app_id: {self.orientation: cover}})
super(ShopImageWidget, self).setPixmap(cover)
self.setPixmap(cover)
self.spinner.stop()
self.spinner.setVisible(False)

View file

@ -2,36 +2,36 @@ from PyQt5.QtCore import Qt
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QMouseEvent
from PyQt5.QtWidgets import (
QFrame,
QWidget,
QVBoxLayout,
QSizePolicy,
QLabel,
QLabel, QScrollArea,
)
from rare.shared.image_manager import ImageSize
from rare.utils.qt_requests import QtRequestManager
from rare.widgets.flow_layout import FlowLayout
from rare.widgets.side_tab import SideTabContents
from .image_widget import ShopImageWidget
class SearchResults(QWidget):
class SearchResults(QScrollArea, SideTabContents):
show_info = pyqtSignal(dict)
def __init__(self, api_core, parent=None):
super(SearchResults, self).__init__(parent=parent)
self.implements_scrollarea = True
self.api_core = api_core
self.results_frame = QFrame(self)
self.results_frame.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.results_frame.setFrameStyle(QFrame.StyledPanel)
self.results_layout = FlowLayout(self.results_frame)
self.results_frame.setLayout(self.results_layout)
self.results_container = QWidget(self)
self.results_container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.results_layout = FlowLayout(self.results_container)
self.setWidget(self.results_container)
self.setWidgetResizable(True)
self.main_layout = QVBoxLayout()
self.main_layout.setContentsMargins(0, 0, 0, 0)
self.main_layout.addWidget(self.results_frame)
# self.main_layout = QVBoxLayout(self)
# self.main_layout.setContentsMargins(0, 0, 0, 0)
# self.main_layout.addWidget(self.results_scrollarea)
self.setLayout(self.main_layout)
self.setEnabled(False)
def load_results(self, text: str):
@ -40,10 +40,10 @@ class SearchResults(QWidget):
self.api_core.search_game(text, self.show_results)
def show_results(self, results: dict):
for w in self.results_frame.findChildren(QLabel, options=Qt.FindDirectChildrenOnly):
for w in self.results_container.findChildren(QLabel, options=Qt.FindDirectChildrenOnly):
self.results_layout.removeWidget(w)
w.deleteLater()
for w in self.results_frame.findChildren(SearchResultItem, options=Qt.FindDirectChildrenOnly):
for w in self.results_container.findChildren(SearchResultItem, options=Qt.FindDirectChildrenOnly):
self.results_layout.removeWidget(w)
w.deleteLater()
@ -51,22 +51,23 @@ class SearchResults(QWidget):
self.results_layout.addWidget(QLabel(self.tr("No results found")))
else:
for res in results:
w = SearchResultItem(res, parent=self.results_frame)
w = SearchResultItem(self.api_core.cached_manager, res, parent=self.results_container)
w.show_info.connect(self.show_info.emit)
self.results_layout.addWidget(w)
self.results_layout.update()
self.setEnabled(True)
class SearchResultItem(ShopImageWidget):
show_info = pyqtSignal(dict)
def __init__(self, result: dict, parent=None):
super(SearchResultItem, self).__init__(parent=parent)
def __init__(self, manager: QtRequestManager, result: dict, parent=None):
super(SearchResultItem, self).__init__(manager, parent=parent)
self.setFixedSize(ImageSize.Normal)
self.ui.setupUi(self)
for img in result["keyImages"]:
if img["type"] in ["DieselStoreFrontTall", "OfferImageTall", "Thumbnail", "ProductLogo"]:
self.fetchPixmap(img["url"], result["id"], result["title"])
self.fetchPixmap(img["url"])
break
else:
print("No image found")

View file

@ -1,4 +1,3 @@
import urllib.parse
from logging import getLogger
from PyQt5.QtCore import pyqtSignal, QObject
@ -10,31 +9,37 @@ from rare.components.tabs.store.constants import (
remove_from_wishlist_query,
)
from rare.components.tabs.store.shop_models import BrowseModel
from rare.utils.paths import cache_dir
from rare.utils.qt_requests import QtRequests
logger = getLogger("ShopAPICore")
graphql_url = "https://www.epicgames.com/graphql"
graphql_url = "https://graphql.epicgames.com/graphql"
class ShopApiCore(QObject):
update_wishlist = pyqtSignal()
def __init__(self, auth_token, lc: str, cc: str):
def __init__(self, token, language: str, country: str):
super(ShopApiCore, self).__init__()
self.token = auth_token
self.language_code: str = lc
self.country_code: str = cc
self.token = token
self.language_code: str = language
self.country_code: str = country
self.locale = f"{self.language_code}-{self.country_code}"
self.manager = QtRequests(parent=self)
self.auth_manager = QtRequests(token=auth_token, parent=self)
self.authed_manager = QtRequests(token=token, parent=self)
self.cached_manager = QtRequests(cache=str(cache_dir().joinpath("store")), parent=self)
self.browse_active = False
self.next_browse_request = tuple(())
def get_free_games(self, handle_func: callable):
url = f"https://store-site-backend-static-ipv4.ak.epicgames.com/freeGamesPromotions?locale={self.language_code}&country={self.country_code}&allowCountries={self.country_code}"
self.manager.get(url, lambda data: self._handle_free_games(data, handle_func))
url = "https://store-site-backend-static-ipv4.ak.epicgames.com/freeGamesPromotions"
params = {
"locale": self.locale,
"country": self.country_code,
"allowCountries": self.country_code,
}
self.manager.get(url, lambda data: self._handle_free_games(data, handle_func), params=params)
def _handle_free_games(self, data, handle_func):
try:
@ -50,14 +55,14 @@ class ShopApiCore(QObject):
handle_func(results)
def get_wishlist(self, handle_func):
self.auth_manager.post(
self.authed_manager.post(
graphql_url,
lambda data: self._handle_wishlist(data, handle_func),
{
"query": wishlist_query,
"variables": {
"country": self.country_code,
"locale": f"{self.language_code}-{self.country_code}",
"locale": self.locale,
},
},
)
@ -94,9 +99,7 @@ class ShopApiCore(QObject):
},
}
self.manager.post(
graphql_url, lambda data: self._handle_search(data, handle_func), payload,
)
self.manager.post(graphql_url, lambda data: self._handle_search(data, handle_func), payload)
def _handle_search(self, data, handle_func):
try:
@ -114,37 +117,11 @@ class ShopApiCore(QObject):
self.next_browse_request = (browse_model, handle_func)
return
self.browse_active = True
url = "https://www.epicgames.com/graphql?operationName=searchStoreQuery&variables={}&extensions={}"
variables = urllib.parse.quote_plus(str(
dict(browse_model.__dict__))
)
extensions = urllib.parse.quote_plus(str(
dict(
persistedQuery=dict(
version=1,
sha256Hash="6e7c4dd0177150eb9a47d624be221929582df8648e7ec271c821838ff4ee148e"
)
)
)
)
for old, new in [
("%26", "&"),
("%27", "%22"),
("+", ""),
("%3A", ":"),
("%2C", ","),
("%5B", "["),
("%5D", "]"),
("True", "true"),
]:
variables = variables.replace(old, new)
extensions = extensions.replace(old, new)
url = url.format(variables, extensions)
self.auth_manager.get(
url, lambda data: self._handle_browse_games(data, handle_func)
)
payload = {
"query": search_query,
"variables": browse_model.__dict__
}
self.manager.post(graphql_url, lambda data: self._handle_browse_games(data, handle_func), payload)
def _handle_browse_games(self, data, handle_func):
self.browse_active = False
@ -188,11 +165,7 @@ class ShopApiCore(QObject):
},
"query": add_to_wishlist_query,
}
self.auth_manager.post(
graphql_url,
lambda data: self._handle_add_to_wishlist(data, handle_func),
payload,
)
self.authed_manager.post(graphql_url, lambda data: self._handle_add_to_wishlist(data, handle_func), payload)
def _handle_add_to_wishlist(self, data, handle_func):
try:
@ -215,11 +188,8 @@ class ShopApiCore(QObject):
},
"query": remove_from_wishlist_query,
}
self.auth_manager.post(
graphql_url,
lambda data: self._handle_remove_from_wishlist(data, handle_func),
payload,
)
self.authed_manager.post(graphql_url, lambda data: self._handle_remove_from_wishlist(data, handle_func),
payload)
def _handle_remove_from_wishlist(self, data, handle_func):
try:

View file

@ -1,6 +1,7 @@
import datetime
from dataclasses import dataclass
from typing import List, Dict
import epicstore_api.queries as egs_query
class ImageUrlModel:
@ -158,22 +159,26 @@ class BrowseModel:
price: str = ""
onSale: bool = False
def __post_init__(self):
self.locale = f"{self.language_code}-{self.country_code}"
@property
def __dict__(self):
payload = {
"allowCountries": self.country_code,
"category": self.category,
"count": self.count,
"country": self.country_code,
"keywords": self.keywords,
"locale": self.language_code,
"priceRange": self.price,
"releaseDate": self.date,
"category": self.category,
"allowCountries": self.country_code,
"namespace": "",
"sortBy": "releaseDate",
"sortDir": self.sortDir,
"start": self.start,
"keywords": self.keywords,
"tag": self.tag,
"priceRange": self.price,
"releaseDate": self.date,
"withPrice": self.withPrice,
"locale": self.locale,
"country": self.country_code,
}
if self.price == "free":
payload["freeGame"] = True
@ -187,5 +192,4 @@ class BrowseModel:
payload["effectiveDate"] = self.date
else:
payload.pop("priceRange")
return payload

View file

@ -9,15 +9,17 @@ from PyQt5.QtWidgets import (
QLabel,
QPushButton,
QHBoxLayout,
QWidget, QSizePolicy,
QWidget, QSizePolicy, QStackedLayout,
)
from legendary.core import LegendaryCore
from rare.ui.components.tabs.store.store import Ui_ShopWidget
from rare.utils.extra_widgets import WaitingSpinner, ButtonLineEdit
from rare.utils.extra_widgets import ButtonLineEdit
from rare.widgets.flow_layout import FlowLayout
from rare.widgets.side_tab import SideTabContents
from .constants import Constants
from .game_widgets import GameWidget
from .image_widget import WaitingSpinner
from .shop_api_core import ShopApiCore
from .shop_models import BrowseModel
@ -25,14 +27,16 @@ logger = logging.getLogger("Shop")
# noinspection PyAttributeOutsideInit,PyBroadException
class ShopWidget(QWidget, Ui_ShopWidget):
class ShopWidget(QWidget, SideTabContents):
show_info = pyqtSignal(str)
show_game = pyqtSignal(dict)
def __init__(self, path, core: LegendaryCore, shop_api: ShopApiCore, parent=None):
def __init__(self, cache_dir, core: LegendaryCore, shop_api: ShopApiCore, parent=None):
super(ShopWidget, self).__init__(parent=parent)
self.setupUi(self)
self.path = path
self.implements_scrollarea = True
self.ui = Ui_ShopWidget()
self.ui.setupUi(self)
self.cache_dir = cache_dir
self.core = core
self.api_core = shop_api
self.price = ""
@ -40,25 +44,39 @@ class ShopWidget(QWidget, Ui_ShopWidget):
self.types = []
self.update_games_allowed = True
self.free_scrollarea.setDisabled(True)
self.ui.free_scrollarea.setDisabled(True)
self.free_game_widgets = []
self.active_search_request = False
self.next_search = ""
self.wishlist: List = []
self.discount_widget.setLayout(FlowLayout(self.discount_widget))
self.discount_stack.addWidget(WaitingSpinner(self.discount_stack))
self.discount_stack.setCurrentIndex(1)
self.discounts_layout = QStackedLayout(self.ui.discounts_group)
self.discounts_spinner = WaitingSpinner(self.ui.discounts_group)
self.discounts_flow = QWidget(self.ui.discounts_group)
self.discounts_flow.setLayout(FlowLayout(self.discounts_flow))
self.discounts_flow.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.discounts_layout.addWidget(self.discounts_spinner)
self.discounts_layout.addWidget(self.discounts_flow)
self.game_widget.setLayout(FlowLayout(self.game_widget))
self.game_stack.addWidget(WaitingSpinner(self.game_stack))
self.game_stack.setCurrentIndex(1)
self.discounts_spinner.start()
self.discounts_layout.setCurrentWidget(self.discounts_spinner)
self.games_layout = QStackedLayout(self.ui.games_group)
self.games_spinner = WaitingSpinner(self.ui.games_group)
self.games_flow = QWidget(self.ui.games_group)
self.games_flow.setLayout(FlowLayout(self.games_flow))
self.games_flow.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.games_layout.addWidget(self.games_spinner)
self.games_layout.addWidget(self.games_flow)
self.games_spinner.start()
self.games_layout.setCurrentWidget(self.games_spinner)
self.search_bar = ButtonLineEdit(
"fa.search", placeholder_text=self.tr("Search Games")
)
self.left_layout.insertWidget(0, self.search_bar)
self.ui.left_layout.insertWidget(0, self.search_bar)
# self.search_bar.textChanged.connect(self.search_games)
@ -85,22 +103,21 @@ class ShopWidget(QWidget, Ui_ShopWidget):
self.api_core.get_wishlist(self.add_wishlist_items)
def add_wishlist_items(self, wishlist):
for i in range(self.discount_widget.layout().count()):
item = self.discount_widget.layout().itemAt(i)
if item:
item.widget().deleteLater()
for w in self.discounts_flow.findChildren(QGroupBox, options=Qt.FindDirectChildrenOnly):
self.discounts_flow.layout().removeWidget(w)
w.deleteLater()
if wishlist and wishlist[0] == "error":
self.discount_widget.layout().addWidget(
QLabel(self.tr("Failed to get wishlist: {}").format(wishlist[1]))
)
btn = QPushButton(self.tr("Reload"))
self.discount_widget.layout().addWidget(btn)
btn.clicked.connect(
lambda: self.api_core.get_wishlist(self.add_wishlist_items)
)
self.discount_stack.setCurrentIndex(0)
return
# if wishlist and wishlist[0] == "error":
# self.discounts_group.layout().addWidget(
# QLabel(self.tr("Failed to get wishlist: {}").format(wishlist[1]))
# )
# btn = QPushButton(self.tr("Reload"))
# self.discount_widget.layout().addWidget(btn)
# btn.clicked.connect(
# lambda: self.api_core.get_wishlist(self.add_wishlist_items)
# )
# self.discount_stack.setCurrentIndex(0)
# return
discounts = 0
for game in wishlist:
@ -108,48 +125,48 @@ class ShopWidget(QWidget, Ui_ShopWidget):
continue
try:
if game["offer"]["price"]["totalPrice"]["discount"] > 0:
w = GameWidget(self.path, game["offer"])
w = GameWidget(self.api_core.cached_manager, game["offer"])
w.show_info.connect(self.show_game)
self.discount_widget.layout().addWidget(w)
self.discounts_flow.layout().addWidget(w)
discounts += 1
except Exception as e:
logger.warning(f"{game} {e}")
continue
self.discounts_group.setVisible(discounts > 0)
self.discount_stack.setCurrentIndex(0)
# fix widget overlay
self.discount_widget.layout().update()
self.ui.discounts_group.setVisible(discounts > 0)
self.discounts_layout.setCurrentWidget(self.discounts_flow)
# FIXME: FlowLayout doesn't update on adding widget
self.discounts_flow.layout().update()
def add_free_games(self, free_games: list):
for w in self.free_container.layout().findChildren(QGroupBox, options=Qt.FindDirectChildrenOnly):
self.free_container.layout().removeWidget(w)
for w in self.ui.free_container.layout().findChildren(QGroupBox, options=Qt.FindDirectChildrenOnly):
self.ui.free_container.layout().removeWidget(w)
w.deleteLater()
if free_games and free_games[0] == "error":
self.free_container.layout().addWidget(
self.ui.free_container.layout().addWidget(
QLabel(self.tr("Failed to fetch free games: {}").format(free_games[1]))
)
btn = QPushButton(self.tr("Reload"))
self.free_container.layout().addWidget(btn)
self.ui.free_container.layout().addWidget(btn)
btn.clicked.connect(
lambda: self.api_core.get_free_games(self.add_free_games)
)
self.free_container.setEnabled(True)
self.ui.free_container.setEnabled(True)
return
self.free_games_now = QGroupBox(self.tr("Free now"), parent=self.free_container)
self.free_games_now = QGroupBox(self.tr("Free now"), parent=self.ui.free_container)
free_games_now_layout = QHBoxLayout(self.free_games_now)
# free_games_now_layout.setContentsMargins(0, 0, 0, 0)
self.free_games_now.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.free_games_now.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self.free_games_now.setLayout(free_games_now_layout)
self.free_container.layout().addWidget(self.free_games_now)
self.ui.free_container.layout().addWidget(self.free_games_now)
self.free_games_next = QGroupBox(self.tr("Free next week"), parent=self.free_container)
self.free_games_next = QGroupBox(self.tr("Free next week"), parent=self.ui.free_container)
free_games_next_layout = QHBoxLayout(self.free_games_next)
# free_games_next_layout.setContentsMargins(0, 0, 0, 0)
self.free_games_next.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.free_games_next.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
self.free_games_next.setLayout(free_games_next_layout)
self.free_container.layout().addWidget(self.free_games_next)
self.ui.free_container.layout().addWidget(self.free_games_next)
date = datetime.datetime.now()
free_games_now = []
@ -200,7 +217,7 @@ class ShopWidget(QWidget, Ui_ShopWidget):
# free games now
now_free = 0
for free_game in free_games_now:
w = GameWidget(self.path, free_game)
w = GameWidget(self.api_core.cached_manager, free_game)
w.show_info.connect(self.show_game)
self.free_games_now.layout().addWidget(w)
self.free_game_widgets.append(w)
@ -212,64 +229,64 @@ class ShopWidget(QWidget, Ui_ShopWidget):
# free games next week
for free_game in coming_free_games:
w = GameWidget(self.path, free_game)
w = GameWidget(self.api_core.cached_manager, free_game)
if free_game["title"] != "Mystery Game":
w.show_info.connect(self.show_game)
self.free_games_next.layout().addWidget(w)
# self.coming_free_games.setFixedWidth(int(40 + len(coming_free_games) * 300))
self.free_scrollarea.setMinimumHeight(
self.ui.free_scrollarea.setMinimumHeight(
self.free_games_now.sizeHint().height()
+ self.free_container.layout().contentsMargins().top()
+ self.free_container.layout().contentsMargins().bottom()
+ self.free_scrollarea.horizontalScrollBar().sizeHint().height()
+ self.ui.free_container.layout().contentsMargins().top()
+ self.ui.free_container.layout().contentsMargins().bottom()
+ self.ui.free_scrollarea.horizontalScrollBar().sizeHint().height()
)
self.free_scrollarea.setEnabled(True)
self.ui.free_scrollarea.setEnabled(True)
def show_search_results(self):
if self.search_bar.text():
self.show_info.emit(self.search_bar.text())
def init_filter(self):
self.none_price.toggled.connect(
lambda: self.prepare_request("") if self.none_price.isChecked() else None
self.ui.none_price.toggled.connect(
lambda: self.prepare_request("") if self.ui.none_price.isChecked() else None
)
self.free_button.toggled.connect(
self.ui.free_button.toggled.connect(
lambda: self.prepare_request("free")
if self.free_button.isChecked()
if self.ui.free_button.isChecked()
else None
)
self.under10.toggled.connect(
self.ui.under10.toggled.connect(
lambda: self.prepare_request("<price>[0, 1000)")
if self.under10.isChecked()
if self.ui.under10.isChecked()
else None
)
self.under20.toggled.connect(
self.ui.under20.toggled.connect(
lambda: self.prepare_request("<price>[0, 2000)")
if self.under20.isChecked()
if self.ui.under20.isChecked()
else None
)
self.under30.toggled.connect(
self.ui.under30.toggled.connect(
lambda: self.prepare_request("<price>[0, 3000)")
if self.under30.isChecked()
if self.ui.under30.isChecked()
else None
)
self.above.toggled.connect(
self.ui.above.toggled.connect(
lambda: self.prepare_request("<price>[1499,]")
if self.above.isChecked()
if self.ui.above.isChecked()
else None
)
# self.on_discount.toggled.connect(lambda: self.prepare_request("sale") if self.on_discount.isChecked() else None)
self.on_discount.toggled.connect(lambda: self.prepare_request())
self.ui.on_discount.toggled.connect(lambda: self.prepare_request())
constants = Constants()
self.checkboxes = []
for groupbox, variables in [
(self.genre_group, constants.categories),
(self.platform_group, constants.platforms),
(self.others_group, constants.others),
(self.type_group, constants.types),
(self.ui.genre_group, constants.categories),
(self.ui.platform_group, constants.platforms),
(self.ui.others_group, constants.others),
(self.ui.type_group, constants.types),
]:
for text, tag in variables:
@ -280,26 +297,26 @@ class ShopWidget(QWidget, Ui_ShopWidget):
)
groupbox.layout().addWidget(checkbox)
self.checkboxes.append(checkbox)
self.reset_button.clicked.connect(self.reset_filters)
self.filter_scrollarea.setMinimumWidth(
self.filter_container.sizeHint().width()
+ self.filter_container.layout().contentsMargins().left()
+ self.filter_container.layout().contentsMargins().right()
+ self.filter_scrollarea.verticalScrollBar().sizeHint().width()
self.ui.reset_button.clicked.connect(self.reset_filters)
self.ui.filter_scrollarea.setMinimumWidth(
self.ui.filter_container.sizeHint().width()
+ self.ui.filter_container.layout().contentsMargins().left()
+ self.ui.filter_container.layout().contentsMargins().right()
+ self.ui.filter_scrollarea.verticalScrollBar().sizeHint().width()
)
def reset_filters(self):
self.update_games_allowed = False
for cb in self.checkboxes:
cb.setChecked(False)
self.none_price.setChecked(True)
self.ui.none_price.setChecked(True)
self.tags = []
self.types = []
self.update_games_allowed = True
self.prepare_request("")
self.on_discount.setChecked(False)
self.ui.on_discount.setChecked(False)
def prepare_request(
self,
@ -323,22 +340,22 @@ class ShopWidget(QWidget, Ui_ShopWidget):
self.types.append(added_type)
if removed_type and removed_type in self.types:
self.types.remove(removed_type)
if (self.types or self.price) or self.tags or self.on_discount.isChecked():
self.free_scrollarea.setVisible(False)
self.discounts_group.setVisible(False)
if (self.types or self.price) or self.tags or self.ui.on_discount.isChecked():
self.ui.free_scrollarea.setVisible(False)
self.ui.discounts_group.setVisible(False)
else:
self.free_scrollarea.setVisible(True)
if len(self.discounts_group.layout().children()) > 0:
self.discounts_group.setVisible(True)
self.ui.free_scrollarea.setVisible(True)
if len(self.ui.discounts_group.layout().children()) > 0:
self.ui.discounts_group.setVisible(True)
self.game_stack.setCurrentIndex(1)
self.games_layout.setCurrentWidget(self.games_spinner)
browse_model = BrowseModel(
language_code=self.core.language_code,
country_code=self.core.country_code,
count=20,
price=self.price,
onSale=self.on_discount.isChecked(),
onSale=self.ui.on_discount.isChecked(),
)
browse_model.tag = "|".join(self.tags)
@ -347,24 +364,22 @@ class ShopWidget(QWidget, Ui_ShopWidget):
self.api_core.browse_games(browse_model, self.show_games)
def show_games(self, data):
for item in (
self.game_widget.layout().itemAt(i)
for i in range(self.game_widget.layout().count())
):
item.widget().deleteLater()
for w in self.games_flow.layout().findChildren(GameWidget, options=Qt.FindDirectChildrenOnly):
self.games_flow.layout().removeWidget(w)
w.deleteLater()
if data:
for game in data:
w = GameWidget(self.path, game)
self.game_widget.layout().addWidget(w)
w = GameWidget(self.api_core.cached_manager, game)
w.show_info.connect(self.show_game.emit)
self.games_flow.layout().addWidget(w)
else:
self.game_widget.layout().addWidget(
self.games_flow.layout().addWidget(
QLabel(self.tr("Could not get games matching the filter"))
)
self.game_stack.setCurrentIndex(0)
self.game_widget.layout().update()
self.games_layout.setCurrentWidget(self.games_flow)
# FIXME: FlowLayout doesn't update on adding widget
self.games_flow.layout().update()
class CheckBox(QCheckBox):

View file

@ -1,9 +1,10 @@
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtCore import pyqtSignal, Qt
from PyQt5.QtWidgets import QMessageBox, QWidget
from rare.ui.components.tabs.store.wishlist import Ui_Wishlist
from rare.utils.misc import icon
from rare.widgets.side_tab import SideTabContents
from rare.widgets.flow_layout import FlowLayout
from .shop_api_core import ShopApiCore
from .game_widgets import WishlistWidget
@ -14,6 +15,7 @@ class Wishlist(QWidget, SideTabContents):
def __init__(self, api_core: ShopApiCore, parent=None):
super(Wishlist, self).__init__(parent=parent)
self.implements_scrollarea = True
self.api_core = api_core
self.ui = Ui_Wishlist()
self.ui.setupUi(self)
@ -21,20 +23,19 @@ class Wishlist(QWidget, SideTabContents):
self.wishlist = []
self.widgets = []
self.ui.sort_cb.currentIndexChanged.connect(
lambda i: self.set_wishlist(self.wishlist, i)
)
self.list_layout = FlowLayout(self.ui.list_container)
self.ui.sort_cb.currentIndexChanged.connect(self.sort_wishlist)
self.ui.filter_cb.currentIndexChanged.connect(self.set_filter)
self.ui.reload_button.clicked.connect(self.update_wishlist)
self.ui.reload_button.setIcon(icon("fa.refresh", color="white"))
self.ui.reverse.stateChanged.connect(
lambda: self.set_wishlist(sort=self.ui.sort_cb.currentIndex())
lambda: self.sort_wishlist(sort=self.ui.sort_cb.currentIndex())
)
def update_wishlist(self):
self.setEnabled(False)
self.set_title.emit("Wishlist")
self.api_core.get_wishlist(self.set_wishlist)
def delete_from_wishlist(self, game):
@ -66,6 +67,32 @@ class Wishlist(QWidget, SideTabContents):
else:
self.ui.no_games_label.setVisible(False)
def sort_wishlist(self, sort=0):
widgets = self.ui.list_container.findChildren(WishlistWidget, options=Qt.FindDirectChildrenOnly)
for w in widgets:
self.ui.list_container.layout().removeWidget(w)
if sort == 0:
func = lambda x: x.game["title"]
reverse = self.ui.reverse.isChecked()
elif sort == 1:
func = lambda x: x.game["price"]["totalPrice"]["fmtPrice"]["discountPrice"]
reverse = self.ui.reverse.isChecked()
elif sort == 2:
func = lambda x: x.game["seller"]["name"]
reverse = self.ui.reverse.isChecked()
elif sort == 3:
func = lambda x: 1 - (x.game["price"]["totalPrice"]["discountPrice"] / x.game["price"]["totalPrice"]["originalPrice"])
reverse = not self.ui.reverse.isChecked()
else:
func = lambda x: x.game["title"]
reverse = self.ui.reverse.isChecked()
widgets = sorted(widgets, key=func, reverse=reverse)
for w in widgets:
self.ui.list_container.layout().addWidget(w)
def set_wishlist(self, wishlist=None, sort=0):
if wishlist and wishlist[0] == "error":
return
@ -76,45 +103,18 @@ class Wishlist(QWidget, SideTabContents):
for i in self.widgets:
i.deleteLater()
if sort == 0:
sorted_list = sorted(self.wishlist, key=lambda x: x["offer"]["title"])
elif sort == 1:
sorted_list = sorted(
self.wishlist,
key=lambda x: x["offer"]["price"]["totalPrice"]["fmtPrice"][
"discountPrice"
],
)
elif sort == 2:
sorted_list = sorted(
self.wishlist, key=lambda x: x["offer"]["seller"]["name"]
)
elif sort == 3:
sorted_list = sorted(
self.wishlist,
reverse=True,
key=lambda x: 1
- (
x["offer"]["price"]["totalPrice"]["discountPrice"]
/ x["offer"]["price"]["totalPrice"]["originalPrice"]
),
)
else:
sorted_list = self.wishlist
self.widgets.clear()
if len(sorted_list) == 0:
if len(wishlist) == 0:
self.ui.no_games_label.setVisible(True)
else:
self.ui.no_games_label.setVisible(False)
if self.ui.reverse.isChecked():
sorted_list.reverse()
for game in sorted_list:
w = WishlistWidget(game["offer"])
self.widgets.append(w)
self.ui.list_layout.addWidget(w)
for game in wishlist:
w = WishlistWidget(self.api_core.cached_manager, game["offer"], self.ui.list_container)
w.open_game.connect(self.show_game_info.emit)
w.delete_from_wishlist.connect(self.delete_from_wishlist)
self.widgets.append(w)
self.list_layout.addWidget(w)
self.list_layout.update()
self.setEnabled(True)

View file

@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_ShopInfo(object):
def setupUi(self, ShopInfo):
ShopInfo.setObjectName("ShopInfo")
ShopInfo.resize(434, 250)
ShopInfo.resize(747, 442)
ShopInfo.setWindowTitle("ShopGameInfo")
self.main_layout = QtWidgets.QHBoxLayout(ShopInfo)
self.main_layout.setObjectName("main_layout")

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>434</width>
<height>250</height>
<width>747</width>
<height>442</height>
</rect>
</property>
<property name="windowTitle">

View file

@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_ShopWidget(object):
def setupUi(self, ShopWidget):
ShopWidget.setObjectName("ShopWidget")
ShopWidget.resize(750, 588)
ShopWidget.resize(350, 382)
ShopWidget.setWindowTitle("Store")
self.shop_layout = QtWidgets.QHBoxLayout(ShopWidget)
self.shop_layout.setObjectName("shop_layout")
@ -27,7 +27,7 @@ class Ui_ShopWidget(object):
self.games_scrollarea.setWidgetResizable(True)
self.games_scrollarea.setObjectName("games_scrollarea")
self.games_container = QtWidgets.QWidget()
self.games_container.setGeometry(QtCore.QRect(0, 0, 583, 574))
self.games_container.setGeometry(QtCore.QRect(0, 0, 186, 368))
self.games_container.setObjectName("games_container")
self.games_container_layout = QtWidgets.QVBoxLayout(self.games_container)
self.games_container_layout.setContentsMargins(0, 0, 3, 0)
@ -44,7 +44,12 @@ class Ui_ShopWidget(object):
self.free_scrollarea.setWidgetResizable(True)
self.free_scrollarea.setObjectName("free_scrollarea")
self.free_container = QtWidgets.QWidget()
self.free_container.setGeometry(QtCore.QRect(0, 0, 580, 83))
self.free_container.setGeometry(QtCore.QRect(0, 0, 16, 16))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.free_container.sizePolicy().hasHeightForWidth())
self.free_container.setSizePolicy(sizePolicy)
self.free_container.setObjectName("free_container")
self.free_container_layout = QtWidgets.QHBoxLayout(self.free_container)
self.free_container_layout.setContentsMargins(0, 0, 0, 3)
@ -53,25 +58,9 @@ class Ui_ShopWidget(object):
self.games_container_layout.addWidget(self.free_scrollarea)
self.discounts_group = QtWidgets.QGroupBox(self.games_container)
self.discounts_group.setObjectName("discounts_group")
self.discounts_layout = QtWidgets.QVBoxLayout(self.discounts_group)
self.discounts_layout.setObjectName("discounts_layout")
self.discount_stack = QtWidgets.QStackedWidget(self.discounts_group)
self.discount_stack.setObjectName("discount_stack")
self.discount_widget = QtWidgets.QWidget()
self.discount_widget.setObjectName("discount_widget")
self.discount_stack.addWidget(self.discount_widget)
self.discounts_layout.addWidget(self.discount_stack)
self.games_container_layout.addWidget(self.discounts_group)
self.games_group = QtWidgets.QGroupBox(self.games_container)
self.games_group.setObjectName("games_group")
self.games_layout = QtWidgets.QVBoxLayout(self.games_group)
self.games_layout.setObjectName("games_layout")
self.game_stack = QtWidgets.QStackedWidget(self.games_group)
self.game_stack.setObjectName("game_stack")
self.game_widget = QtWidgets.QWidget()
self.game_widget.setObjectName("game_widget")
self.game_stack.addWidget(self.game_widget)
self.games_layout.addWidget(self.game_stack)
self.games_container_layout.addWidget(self.games_group)
self.games_scrollarea.setWidget(self.games_container)
self.left_layout.addWidget(self.games_scrollarea)
@ -94,7 +83,12 @@ class Ui_ShopWidget(object):
self.filter_scrollarea.setWidgetResizable(True)
self.filter_scrollarea.setObjectName("filter_scrollarea")
self.filter_container = QtWidgets.QWidget()
self.filter_container.setGeometry(QtCore.QRect(0, 0, 145, 542))
self.filter_container.setGeometry(QtCore.QRect(0, 0, 142, 390))
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.filter_container.sizePolicy().hasHeightForWidth())
self.filter_container.setSizePolicy(sizePolicy)
self.filter_container.setObjectName("filter_container")
self.filter_container_layout = QtWidgets.QVBoxLayout(self.filter_container)
self.filter_container_layout.setContentsMargins(0, 0, 3, 0)

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>750</width>
<height>588</height>
<width>679</width>
<height>329</height>
</rect>
</property>
<property name="windowTitle">
@ -35,8 +35,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>583</width>
<height>574</height>
<width>515</width>
<height>315</height>
</rect>
</property>
<layout class="QVBoxLayout" name="games_container_layout">
@ -77,10 +77,16 @@
<rect>
<x>0</x>
<y>0</y>
<width>580</width>
<height>83</height>
<width>16</width>
<height>16</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QHBoxLayout" name="free_container_layout">
<property name="leftMargin">
<number>0</number>
@ -103,13 +109,6 @@
<property name="title">
<string>Discounts from your wishlist</string>
</property>
<layout class="QVBoxLayout" name="discounts_layout">
<item>
<widget class="QStackedWidget" name="discount_stack">
<widget class="QWidget" name="discount_widget"/>
</widget>
</item>
</layout>
</widget>
</item>
<item>
@ -117,13 +116,6 @@
<property name="title">
<string>Games</string>
</property>
<layout class="QVBoxLayout" name="games_layout">
<item>
<widget class="QStackedWidget" name="game_stack">
<widget class="QWidget" name="game_widget"/>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
@ -169,10 +161,16 @@
<rect>
<x>0</x>
<y>0</y>
<width>145</width>
<height>542</height>
<width>142</width>
<height>390</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="filter_container_layout">
<property name="leftMargin">
<number>0</number>

View file

@ -14,12 +14,12 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Wishlist(object):
def setupUi(self, Wishlist):
Wishlist.setObjectName("Wishlist")
Wishlist.resize(527, 328)
Wishlist.resize(423, 153)
Wishlist.setWindowTitle("Wishlist")
self.verticalLayout = QtWidgets.QVBoxLayout(Wishlist)
self.verticalLayout.setObjectName("verticalLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.tool_layout = QtWidgets.QHBoxLayout()
self.tool_layout.setObjectName("tool_layout")
self.sort_label = QtWidgets.QLabel(Wishlist)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
@ -27,29 +27,29 @@ class Ui_Wishlist(object):
sizePolicy.setHeightForWidth(self.sort_label.sizePolicy().hasHeightForWidth())
self.sort_label.setSizePolicy(sizePolicy)
self.sort_label.setObjectName("sort_label")
self.horizontalLayout.addWidget(self.sort_label)
self.tool_layout.addWidget(self.sort_label)
self.sort_cb = QtWidgets.QComboBox(Wishlist)
self.sort_cb.setObjectName("sort_cb")
self.sort_cb.addItem("")
self.sort_cb.addItem("")
self.sort_cb.addItem("")
self.sort_cb.addItem("")
self.horizontalLayout.addWidget(self.sort_cb)
self.tool_layout.addWidget(self.sort_cb)
self.reverse = QtWidgets.QCheckBox(Wishlist)
self.reverse.setObjectName("reverse")
self.horizontalLayout.addWidget(self.reverse)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem)
self.tool_layout.addWidget(self.reverse)
spacerItem = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.tool_layout.addItem(spacerItem)
self.filter_label = QtWidgets.QLabel(Wishlist)
self.filter_label.setObjectName("filter_label")
self.horizontalLayout.addWidget(self.filter_label)
self.tool_layout.addWidget(self.filter_label)
self.filter_cb = QtWidgets.QComboBox(Wishlist)
self.filter_cb.setObjectName("filter_cb")
self.filter_cb.addItem("")
self.filter_cb.addItem("")
self.horizontalLayout.addWidget(self.filter_cb)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout.addItem(spacerItem1)
self.tool_layout.addWidget(self.filter_cb)
spacerItem1 = QtWidgets.QSpacerItem(0, 0, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.tool_layout.addItem(spacerItem1)
self.reload_button = QtWidgets.QPushButton(Wishlist)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
@ -58,16 +58,19 @@ class Ui_Wishlist(object):
self.reload_button.setSizePolicy(sizePolicy)
self.reload_button.setText("")
self.reload_button.setObjectName("reload_button")
self.horizontalLayout.addWidget(self.reload_button)
self.verticalLayout.addLayout(self.horizontalLayout)
self.list_layout = QtWidgets.QVBoxLayout()
self.list_layout.setObjectName("list_layout")
self.verticalLayout.addLayout(self.list_layout)
self.tool_layout.addWidget(self.reload_button)
self.verticalLayout.addLayout(self.tool_layout)
self.no_games_label = QtWidgets.QLabel(Wishlist)
self.no_games_label.setObjectName("no_games_label")
self.verticalLayout.addWidget(self.no_games_label)
spacerItem2 = QtWidgets.QSpacerItem(379, 218, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout.addItem(spacerItem2)
self.list_scrollarea = QtWidgets.QScrollArea(Wishlist)
self.list_scrollarea.setWidgetResizable(True)
self.list_scrollarea.setObjectName("list_scrollarea")
self.list_container = QtWidgets.QWidget()
self.list_container.setGeometry(QtCore.QRect(0, 0, 407, 83))
self.list_container.setObjectName("list_container")
self.list_scrollarea.setWidget(self.list_container)
self.verticalLayout.addWidget(self.list_scrollarea)
self.retranslateUi(Wishlist)

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>527</width>
<height>328</height>
<width>423</width>
<height>153</height>
</rect>
</property>
<property name="windowTitle">
@ -15,7 +15,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<layout class="QHBoxLayout" name="tool_layout">
<item>
<widget class="QLabel" name="sort_label">
<property name="sizePolicy">
@ -61,14 +61,14 @@
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<spacer name="tool_hspacer_1">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
@ -95,14 +95,14 @@
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<spacer name="tool_hspacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
@ -122,9 +122,6 @@
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="list_layout"/>
</item>
<item>
<widget class="QLabel" name="no_games_label">
<property name="text">
@ -133,17 +130,21 @@
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
<widget class="QScrollArea" name="list_scrollarea">
<property name="widgetResizable">
<bool>true</bool>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>379</width>
<height>218</height>
</size>
</property>
</spacer>
<widget class="QWidget" name="list_container">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>407</width>
<height>83</height>
</rect>
</property>
</widget>
</widget>
</item>
</layout>
</widget>

View file

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'rare/ui/components/tabs/store/wishlist_widget.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
@ -14,20 +14,26 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_WishlistWidget(object):
def setupUi(self, WishlistWidget):
WishlistWidget.setObjectName("WishlistWidget")
WishlistWidget.resize(523, 172)
WishlistWidget.resize(202, 94)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(WishlistWidget.sizePolicy().hasHeightForWidth())
WishlistWidget.setSizePolicy(sizePolicy)
WishlistWidget.setWindowTitle("WishlistWIdget")
self.horizontalLayout = QtWidgets.QHBoxLayout(WishlistWidget)
self.horizontalLayout.setObjectName("horizontalLayout")
self.widget = QtWidgets.QWidget(WishlistWidget)
self.main_layout = QtWidgets.QHBoxLayout(WishlistWidget)
self.main_layout.setContentsMargins(0, 0, 0, 0)
self.main_layout.setObjectName("main_layout")
self.info_widget = QtWidgets.QWidget(WishlistWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.widget.sizePolicy().hasHeightForWidth())
self.widget.setSizePolicy(sizePolicy)
self.widget.setObjectName("widget")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.widget)
sizePolicy.setHeightForWidth(self.info_widget.sizePolicy().hasHeightForWidth())
self.info_widget.setSizePolicy(sizePolicy)
self.info_widget.setObjectName("info_widget")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.info_widget)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.title_label = QtWidgets.QLabel(self.widget)
self.title_label = QtWidgets.QLabel(self.info_widget)
font = QtGui.QFont()
font.setPointSize(16)
self.title_label.setFont(font)
@ -35,16 +41,16 @@ class Ui_WishlistWidget(object):
self.title_label.setWordWrap(True)
self.title_label.setObjectName("title_label")
self.verticalLayout_2.addWidget(self.title_label)
self.developer = QtWidgets.QLabel(self.widget)
self.developer = QtWidgets.QLabel(self.info_widget)
font = QtGui.QFont()
font.setPointSize(12)
self.developer.setFont(font)
self.developer.setText("TextLabel")
self.developer.setObjectName("developer")
self.verticalLayout_2.addWidget(self.developer)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.discount_price = QtWidgets.QLabel(self.widget)
self.price_layout = QtWidgets.QHBoxLayout()
self.price_layout.setObjectName("price_layout")
self.discount_price = QtWidgets.QLabel(self.info_widget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Preferred)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
@ -52,15 +58,13 @@ class Ui_WishlistWidget(object):
self.discount_price.setSizePolicy(sizePolicy)
self.discount_price.setText("TextLabel")
self.discount_price.setObjectName("discount_price")
self.horizontalLayout_2.addWidget(self.discount_price)
self.price = QtWidgets.QLabel(self.widget)
self.price_layout.addWidget(self.discount_price)
self.price = QtWidgets.QLabel(self.info_widget)
self.price.setText("TextLabel")
self.price.setObjectName("price")
self.horizontalLayout_2.addWidget(self.price)
self.verticalLayout_2.addLayout(self.horizontalLayout_2)
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_2.addItem(spacerItem)
self.horizontalLayout.addWidget(self.widget)
self.price_layout.addWidget(self.price)
self.verticalLayout_2.addLayout(self.price_layout)
self.main_layout.addWidget(self.info_widget, 0, QtCore.Qt.AlignTop)
self.delete_button = QtWidgets.QPushButton(WishlistWidget)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Maximum)
sizePolicy.setHorizontalStretch(0)
@ -69,7 +73,7 @@ class Ui_WishlistWidget(object):
self.delete_button.setSizePolicy(sizePolicy)
self.delete_button.setText("")
self.delete_button.setObjectName("delete_button")
self.horizontalLayout.addWidget(self.delete_button)
self.main_layout.addWidget(self.delete_button)
self.retranslateUi(WishlistWidget)

View file

@ -6,16 +6,34 @@
<rect>
<x>0</x>
<y>0</y>
<width>523</width>
<height>172</height>
<width>202</width>
<height>94</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="windowTitle">
<string notr="true">WishlistWIdget</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="main_layout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item alignment="Qt::AlignTop">
<widget class="QWidget" name="info_widget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
@ -51,7 +69,7 @@
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<layout class="QHBoxLayout" name="price_layout">
<item>
<widget class="QLabel" name="discount_price">
<property name="sizePolicy">
@ -74,19 +92,6 @@
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>