Store: Finalize store design
This commit is contained in:
parent
fda82b17cf
commit
b4a26b5932
|
@ -1,14 +1,13 @@
|
||||||
|
from PyQt5.QtGui import QShowEvent, QHideEvent
|
||||||
from legendary.core import LegendaryCore
|
from legendary.core import LegendaryCore
|
||||||
|
|
||||||
from rare.shared import RareCore
|
|
||||||
from rare.utils.paths import cache_dir
|
|
||||||
from rare.widgets.side_tab import SideTabWidget
|
from rare.widgets.side_tab import SideTabWidget
|
||||||
from .game_info import ShopGameInfo
|
|
||||||
from .search_results import SearchResults
|
|
||||||
from .shop_api_core import ShopApiCore
|
|
||||||
from .api.models.response import CatalogOfferModel
|
from .api.models.response import CatalogOfferModel
|
||||||
from .shop_widget import ShopWidget
|
from .landing import LandingWidget, LandingPage
|
||||||
from .wishlist import WishlistWidget, Wishlist
|
from .search import SearchPage
|
||||||
|
from .store_api import StoreAPI
|
||||||
|
from .widgets.details import DetailsWidget
|
||||||
|
from .wishlist import WishlistPage
|
||||||
|
|
||||||
|
|
||||||
class StoreTab(SideTabWidget):
|
class StoreTab(SideTabWidget):
|
||||||
|
@ -19,45 +18,31 @@ class StoreTab(SideTabWidget):
|
||||||
|
|
||||||
self.core = core
|
self.core = core
|
||||||
# self.rcore = RareCore.instance()
|
# self.rcore = RareCore.instance()
|
||||||
self.api_core = ShopApiCore(
|
self.api = StoreAPI(
|
||||||
self.core.egs.session.headers["Authorization"],
|
self.core.egs.session.headers["Authorization"],
|
||||||
self.core.language_code,
|
self.core.language_code,
|
||||||
self.core.country_code,
|
self.core.country_code,
|
||||||
|
[] # [i.asset_infos["Windows"].namespace for i in self.rcore.game_list if bool(i.asset_infos)]
|
||||||
)
|
)
|
||||||
|
|
||||||
self.shop = ShopWidget(cache_dir(), self.core, self.api_core, parent=self)
|
self.landing = LandingPage(self.api, parent=self)
|
||||||
self.shop_index = self.addTab(self.shop, self.tr("Store"))
|
self.landing_index = self.addTab(self.landing, 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 = SearchPage(self.core, self.api, parent=self)
|
||||||
self.search_index = self.addTab(self.search, self.tr("Search"), self.tr("Results"))
|
self.search_index = self.addTab(self.search, self.tr("Search"))
|
||||||
self.search.show_info.connect(self.show_game)
|
|
||||||
# self.search.back_button.clicked.connect(lambda: self.setCurrentIndex(self.shop_index))
|
|
||||||
|
|
||||||
self.info = ShopGameInfo(
|
self.wishlist = WishlistPage(self.api, parent=self)
|
||||||
# [i.asset_infos["Windows"].namespace for i in self.rcore.game_list if bool(i.asset_infos)],
|
self.wishlist_index = self.addTab(self.wishlist, self.tr("Wishlist"))
|
||||||
[],
|
|
||||||
self.api_core,
|
|
||||||
parent=self
|
|
||||||
)
|
|
||||||
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.api.update_wishlist.connect(self.update_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)
|
|
||||||
|
|
||||||
self.api_core.update_wishlist.connect(self.update_wishlist)
|
self.previous_index = self.landing_index
|
||||||
|
|
||||||
self.previous_index = self.shop_index
|
|
||||||
|
|
||||||
def showEvent(self, a0: QShowEvent) -> None:
|
def showEvent(self, a0: QShowEvent) -> None:
|
||||||
if a0.spontaneous() or self.init:
|
if a0.spontaneous() or self.init:
|
||||||
return super().showEvent(a0)
|
return super().showEvent(a0)
|
||||||
self.shop.load()
|
# self.landing.load()
|
||||||
self.wishlist_widget.update_wishlist()
|
# self.wishlist.update_wishlist()
|
||||||
self.init = True
|
self.init = True
|
||||||
return super().showEvent(a0)
|
return super().showEvent(a0)
|
||||||
|
|
||||||
|
@ -68,13 +53,4 @@ class StoreTab(SideTabWidget):
|
||||||
return super().hideEvent(a0)
|
return super().hideEvent(a0)
|
||||||
|
|
||||||
def update_wishlist(self):
|
def update_wishlist(self):
|
||||||
self.shop.update_wishlist()
|
self.landing.update_wishlist()
|
||||||
|
|
||||||
def show_game(self, data: CatalogOfferModel):
|
|
||||||
self.previous_index = self.currentIndex()
|
|
||||||
self.info.update_game(data)
|
|
||||||
self.setCurrentIndex(self.info_index)
|
|
||||||
|
|
||||||
def show_search(self, text: str):
|
|
||||||
self.search.load_results(text)
|
|
||||||
self.setCurrentIndex(self.search_index)
|
|
||||||
|
|
|
@ -18,13 +18,13 @@ class StoreWindow(QDialog):
|
||||||
layout = QVBoxLayout(self)
|
layout = QVBoxLayout(self)
|
||||||
layout.addWidget(self.store_tab)
|
layout.addWidget(self.store_tab)
|
||||||
|
|
||||||
self.store_tab.load()
|
self.store_tab.show()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from rare.utils.misc import set_style_sheet
|
|
||||||
import rare.resources.static_css
|
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 = QApplication(sys.argv)
|
||||||
app.setApplicationName("Rare")
|
app.setApplicationName("Rare")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
from PyQt5.QtWidgets import QTreeView, QDialog, QVBoxLayout
|
from PyQt5.QtWidgets import QTreeView, QDialog, QVBoxLayout
|
||||||
|
|
||||||
from utils.json_formatter import QJsonModel
|
from rare.utils.json_formatter import QJsonModel
|
||||||
|
|
||||||
|
|
||||||
class DebugView(QTreeView):
|
class DebugView(QTreeView):
|
||||||
|
|
|
@ -38,4 +38,39 @@ type LineOfferRes {
|
||||||
type GetPriceRes {
|
type GetPriceRes {
|
||||||
totalPrice: TotalPrice
|
totalPrice: TotalPrice
|
||||||
lineOffers: [LineOfferRes]
|
lineOffers: [LineOfferRes]
|
||||||
|
}
|
||||||
|
|
||||||
|
type Image {
|
||||||
|
type: String
|
||||||
|
url: String
|
||||||
|
alt: String
|
||||||
|
}
|
||||||
|
|
||||||
|
type StorePageMapping {
|
||||||
|
cmsSlug: String
|
||||||
|
offerId: ID
|
||||||
|
prePurchaseOfferId: ID
|
||||||
|
}
|
||||||
|
|
||||||
|
type PageSandboxModel {
|
||||||
|
pageSlug: String
|
||||||
|
pageType: String
|
||||||
|
productId: ID
|
||||||
|
sandboxId: ID
|
||||||
|
createdDate: Date
|
||||||
|
updatedDate: Date
|
||||||
|
deletedDate: Date
|
||||||
|
mappings: [StorePageMapping]
|
||||||
|
}
|
||||||
|
|
||||||
|
type CatalogNamespace {
|
||||||
|
parent: ID
|
||||||
|
displayName: String
|
||||||
|
store: String
|
||||||
|
mappings: [PageSandboxModel]
|
||||||
|
}
|
||||||
|
|
||||||
|
type CatalogItem {
|
||||||
|
id: ID
|
||||||
|
namespace: ID
|
||||||
}
|
}
|
|
@ -6,11 +6,11 @@ from typing import List
|
||||||
@dataclass
|
@dataclass
|
||||||
class SearchDateRange:
|
class SearchDateRange:
|
||||||
start_date: datetime = datetime(year=1990, month=1, day=1, tzinfo=timezone.utc)
|
start_date: datetime = datetime(year=1990, month=1, day=1, tzinfo=timezone.utc)
|
||||||
end_date: datetime = datetime.utcnow()
|
end_date: datetime = datetime.utcnow().replace(tzinfo=timezone.utc)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
def fmt_date(date: datetime) -> str:
|
def fmt_date(date: datetime) -> str:
|
||||||
# lk: The formatting accepted by the GraphQL API is either '%Y-%m-%dT%H:%M:%S.000Z' or '%Y-%m-%dT'
|
# lk: The formatting accepted by the GraphQL API is either '%Y-%m-%dT%H:%M:%S.000Z' or '%Y-%m-%d'
|
||||||
return datetime.strftime(date, '%Y-%m-%dT%H:%M:%S.000Z')
|
return datetime.strftime(date, '%Y-%m-%dT%H:%M:%S.000Z')
|
||||||
return f"[{fmt_date(self.start_date)},{fmt_date(self.end_date)}]"
|
return f"[{fmt_date(self.start_date)},{fmt_date(self.end_date)}]"
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import logging
|
import logging
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime
|
||||||
from typing import List, Dict, Any, Type, Optional
|
from typing import List, Dict, Any, Type, Optional
|
||||||
|
|
||||||
|
from .utils import parse_date
|
||||||
|
|
||||||
logger = logging.getLogger("StoreApiModels")
|
logger = logging.getLogger("StoreApiModels")
|
||||||
|
|
||||||
# lk: Typing overloads for unimplemented types
|
# lk: Typing overloads for unimplemented types
|
||||||
|
@ -13,171 +15,11 @@ CategoryModel = Dict
|
||||||
CustomAttributeModel = Dict
|
CustomAttributeModel = Dict
|
||||||
ItemModel = Dict
|
ItemModel = Dict
|
||||||
SellerModel = Dict
|
SellerModel = Dict
|
||||||
OfferMappingModel = Dict
|
PageSandboxModel = Dict
|
||||||
TagModel = Dict
|
TagModel = Dict
|
||||||
PromotionsModel = Dict
|
PromotionsModel = Dict
|
||||||
|
|
||||||
|
|
||||||
def parse_date(date: str):
|
|
||||||
return datetime.fromisoformat(date[:-1]).replace(tzinfo=timezone.utc)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DieselSystemDetailItem:
|
|
||||||
p_type: Optional[str] = None
|
|
||||||
minimum: Optional[str] = None
|
|
||||||
recommended: Optional[str] = None
|
|
||||||
title: Optional[str] = None
|
|
||||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls: Type["DieselSystemDetailItem"], src: Dict[str, Any]) -> "DieselSystemDetailItem":
|
|
||||||
d = src.copy()
|
|
||||||
tmp = cls(
|
|
||||||
p_type=d.pop("_type", ""),
|
|
||||||
minimum=d.pop("minimum", ""),
|
|
||||||
recommended=d.pop("recommended", ""),
|
|
||||||
title=d.pop("title", ""),
|
|
||||||
)
|
|
||||||
tmp.unmapped = d
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DieselSystemDetail:
|
|
||||||
p_type: Optional[str] = None
|
|
||||||
details: Optional[List[DieselSystemDetailItem]] = None
|
|
||||||
system_type: Optional[str] = None
|
|
||||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls: Type["DieselSystemDetail"], src: Dict[str, Any]) -> "DieselSystemDetail":
|
|
||||||
d = src.copy()
|
|
||||||
_details = d.pop("details", [])
|
|
||||||
details = [] if _details else None
|
|
||||||
for item in _details:
|
|
||||||
detail = DieselSystemDetailItem.from_dict(item)
|
|
||||||
details.append(detail)
|
|
||||||
tmp = cls(
|
|
||||||
p_type=d.pop("_type", ""),
|
|
||||||
details=details,
|
|
||||||
system_type=d.pop("systemType", ""),
|
|
||||||
)
|
|
||||||
tmp.unmapped = d
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DieselSystemDetails:
|
|
||||||
p_type: Optional[str] = None
|
|
||||||
languages: Optional[List[str]] = None
|
|
||||||
rating: Optional[Dict] = None
|
|
||||||
systems: Optional[List[DieselSystemDetail]] = None
|
|
||||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls: Type["DieselSystemDetails"], src: Dict[str, Any]) -> "DieselSystemDetails":
|
|
||||||
d = src.copy()
|
|
||||||
_systems = d.pop("systems", [])
|
|
||||||
systems = [] if _systems else None
|
|
||||||
for item in _systems:
|
|
||||||
system = DieselSystemDetail.from_dict(item)
|
|
||||||
systems.append(system)
|
|
||||||
tmp = cls(
|
|
||||||
p_type=d.pop("_type", ""),
|
|
||||||
languages=d.pop("languages", []),
|
|
||||||
rating=d.pop("rating", {}),
|
|
||||||
systems=systems,
|
|
||||||
)
|
|
||||||
tmp.unmapped = d
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DieselProductAbout:
|
|
||||||
p_type: Optional[str] = None
|
|
||||||
desciption: Optional[str] = None
|
|
||||||
developer_attribution: Optional[str] = None
|
|
||||||
publisher_attribution: Optional[str] = None
|
|
||||||
short_description: Optional[str] = None
|
|
||||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls: Type["DieselProductAbout"], src: Dict[str, Any]) -> "DieselProductAbout":
|
|
||||||
d = src.copy()
|
|
||||||
tmp = cls(
|
|
||||||
p_type=d.pop("_type", ""),
|
|
||||||
desciption=d.pop("description", ""),
|
|
||||||
developer_attribution=d.pop("developerAttribution", ""),
|
|
||||||
publisher_attribution=d.pop("publisherAttribution", ""),
|
|
||||||
short_description=d.pop("shortDescription", ""),
|
|
||||||
)
|
|
||||||
tmp.unmapped = d
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DieselProductDetail:
|
|
||||||
p_type: Optional[str] = None
|
|
||||||
about: Optional[DieselProductAbout] = None
|
|
||||||
requirements: Optional[DieselSystemDetails] = None
|
|
||||||
social_links: Optional[DieselSocialLinks] = None
|
|
||||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls: Type["DieselProductDetail"], src: Dict[str, Any]) -> "DieselProductDetail":
|
|
||||||
d = src.copy()
|
|
||||||
about = DieselProductAbout.from_dict(x) if (x := d.pop("about"), {}) else None
|
|
||||||
requirements = DieselSystemDetails.from_dict(x) if (x := d.pop("requirements", {})) else None
|
|
||||||
tmp = cls(
|
|
||||||
p_type=d.pop("_type", ""),
|
|
||||||
about=about,
|
|
||||||
requirements=requirements,
|
|
||||||
social_links=d.pop("socialLinks", {}),
|
|
||||||
)
|
|
||||||
tmp.unmapped = d
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class DieselProduct:
|
|
||||||
p_id: Optional[str] = None
|
|
||||||
p_images_: Optional[List[str]] = None
|
|
||||||
p_locale: Optional[str] = None
|
|
||||||
p_slug: Optional[str] = None
|
|
||||||
p_title: Optional[str] = None
|
|
||||||
p_url_pattern: Optional[str] = None
|
|
||||||
namespace: Optional[str] = None
|
|
||||||
pages: Optional[List["DieselProduct"]] = None
|
|
||||||
data: Optional[DieselProductDetail] = None
|
|
||||||
product_name: Optional[str] = None
|
|
||||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_dict(cls: Type["DieselProduct"], src: Dict[str, Any]) -> "DieselProduct":
|
|
||||||
d = src.copy()
|
|
||||||
_pages = d.pop("pages", [])
|
|
||||||
pages = [] if _pages else None
|
|
||||||
for item in _pages:
|
|
||||||
page = DieselProduct.from_dict(item)
|
|
||||||
pages.append(page)
|
|
||||||
data = DieselProductDetail.from_dict(x) if (x := d.pop("data", {})) else None
|
|
||||||
tmp = cls(
|
|
||||||
p_id=d.pop("_id", ""),
|
|
||||||
p_images_=d.pop("_images_", []),
|
|
||||||
p_locale=d.pop("_locale", ""),
|
|
||||||
p_slug=d.pop("_slug", ""),
|
|
||||||
p_title=d.pop("_title", ""),
|
|
||||||
p_url_pattern=d.pop("_urlPattern", ""),
|
|
||||||
namespace=d.pop("namespace", ""),
|
|
||||||
pages=pages,
|
|
||||||
data=data,
|
|
||||||
product_name=d.pop("productName", ""),
|
|
||||||
)
|
|
||||||
tmp.unmapped = d
|
|
||||||
return tmp
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ImageUrlModel:
|
class ImageUrlModel:
|
||||||
type: Optional[str] = None
|
type: Optional[str] = None
|
||||||
|
@ -271,14 +113,14 @@ LineOffersModel = Dict
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class PriceModel:
|
class GetPriceResModel:
|
||||||
total_price: Optional[TotalPriceModel] = None
|
total_price: Optional[TotalPriceModel] = None
|
||||||
fmt_price: Optional[FmtPriceModel] = None
|
fmt_price: Optional[FmtPriceModel] = None
|
||||||
line_offers: Optional[LineOffersModel] = None
|
line_offers: Optional[LineOffersModel] = None
|
||||||
unmapped: Dict[str, Any] = field(default_factory=dict)
|
unmapped: Dict[str, Any] = field(default_factory=dict)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_dict(cls: Type["PriceModel"], src: Dict[str, Any]) -> "PriceModel":
|
def from_dict(cls: Type["GetPriceResModel"], src: Dict[str, Any]) -> "GetPriceResModel":
|
||||||
d = src.copy()
|
d = src.copy()
|
||||||
tmp = cls(
|
tmp = cls(
|
||||||
total_price=d.pop("totalPrice", {}),
|
total_price=d.pop("totalPrice", {}),
|
||||||
|
@ -302,9 +144,9 @@ class CatalogOfferModel:
|
||||||
items: Optional[List[ItemModel]] = None
|
items: Optional[List[ItemModel]] = None
|
||||||
key_images: Optional[KeyImagesModel] = None
|
key_images: Optional[KeyImagesModel] = None
|
||||||
namespace: Optional[str] = None
|
namespace: Optional[str] = None
|
||||||
offer_mappings: Optional[List[OfferMappingModel]] = None
|
offer_mappings: Optional[List[PageSandboxModel]] = None
|
||||||
offer_type: Optional[str] = None
|
offer_type: Optional[str] = None
|
||||||
price: Optional[PriceModel] = None
|
price: Optional[GetPriceResModel] = None
|
||||||
product_slug: Optional[str] = None
|
product_slug: Optional[str] = None
|
||||||
promotions: Optional[PromotionsModel] = None
|
promotions: Optional[PromotionsModel] = None
|
||||||
seller: Optional[SellerModel] = None
|
seller: Optional[SellerModel] = None
|
||||||
|
@ -322,7 +164,7 @@ class CatalogOfferModel:
|
||||||
effective_date = parse_date(x) if (x := d.pop("effectiveDate", "")) else None
|
effective_date = parse_date(x) if (x := d.pop("effectiveDate", "")) else None
|
||||||
expiry_date = parse_date(x) if (x := d.pop("expiryDate", "")) else None
|
expiry_date = parse_date(x) if (x := d.pop("expiryDate", "")) else None
|
||||||
key_images = KeyImagesModel.from_list(d.pop("keyImages", []))
|
key_images = KeyImagesModel.from_list(d.pop("keyImages", []))
|
||||||
price = PriceModel.from_dict(x) if (x := d.pop("price", {})) else None
|
price = GetPriceResModel.from_dict(x) if (x := d.pop("price", {})) else None
|
||||||
viewable_date = parse_date(x) if (x := d.pop("viewableDate", "")) else None
|
viewable_date = parse_date(x) if (x := d.pop("viewableDate", "")) else None
|
||||||
tmp = cls(
|
tmp = cls(
|
||||||
catalog_ns=d.pop("catalogNs", {}),
|
catalog_ns=d.pop("catalogNs", {}),
|
||||||
|
|
212
rare/components/tabs/store/landing.py
Normal file
212
rare/components/tabs/store/landing.py
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from PyQt5.QtCore import Qt, pyqtSlot, pyqtSignal
|
||||||
|
from PyQt5.QtGui import QShowEvent, QHideEvent
|
||||||
|
from PyQt5.QtWidgets import (
|
||||||
|
QHBoxLayout,
|
||||||
|
QWidget,
|
||||||
|
QSizePolicy,
|
||||||
|
QVBoxLayout,
|
||||||
|
QSpacerItem,
|
||||||
|
QScrollArea,
|
||||||
|
QFrame,
|
||||||
|
)
|
||||||
|
|
||||||
|
from rare.widgets.flow_layout import FlowLayout
|
||||||
|
from rare.widgets.side_tab import SideTabContents
|
||||||
|
from rare.widgets.sliding_stack import SlidingStackedWidget
|
||||||
|
from rare.components.tabs.store.api.models.response import CatalogOfferModel, WishlistItemModel
|
||||||
|
from .api.models.utils import parse_date
|
||||||
|
from .store_api import StoreAPI
|
||||||
|
from .widgets.details import DetailsWidget
|
||||||
|
from .widgets.items import StoreItemWidget
|
||||||
|
from .widgets.groups import StoreGroup
|
||||||
|
|
||||||
|
logger = logging.getLogger("StoreLanding")
|
||||||
|
|
||||||
|
|
||||||
|
class LandingPage(SlidingStackedWidget, SideTabContents):
|
||||||
|
|
||||||
|
def __init__(self, api: StoreAPI, parent=None):
|
||||||
|
super(LandingPage, self).__init__(parent=parent)
|
||||||
|
self.implements_scrollarea = True
|
||||||
|
|
||||||
|
self.landing_widget = LandingWidget(api, parent=self)
|
||||||
|
self.landing_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
|
self.landing_widget.set_title.connect(self.set_title)
|
||||||
|
self.landing_widget.show_details.connect(self.show_details)
|
||||||
|
|
||||||
|
self.landing_scroll = QScrollArea(self)
|
||||||
|
self.landing_scroll.setWidgetResizable(True)
|
||||||
|
self.landing_scroll.setFrameStyle(QFrame.NoFrame | QFrame.Plain)
|
||||||
|
self.landing_scroll.setWidget(self.landing_widget)
|
||||||
|
|
||||||
|
self.details_widget = DetailsWidget([], api, parent=self)
|
||||||
|
self.details_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
|
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)
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def show_main(self):
|
||||||
|
self.slideInWidget(self.landing_scroll)
|
||||||
|
|
||||||
|
@pyqtSlot(object)
|
||||||
|
def show_details(self, game: CatalogOfferModel):
|
||||||
|
self.details_widget.update_game(game)
|
||||||
|
self.slideInWidget(self.details_scroll)
|
||||||
|
|
||||||
|
|
||||||
|
class LandingWidget(QWidget, SideTabContents):
|
||||||
|
show_details = pyqtSignal(CatalogOfferModel)
|
||||||
|
|
||||||
|
def __init__(self, api: StoreAPI, parent=None):
|
||||||
|
super(LandingWidget, self).__init__(parent=parent)
|
||||||
|
self.api = api
|
||||||
|
|
||||||
|
layout = QVBoxLayout(self)
|
||||||
|
layout.setContentsMargins(0, 0, 3, 0)
|
||||||
|
self.setLayout(layout)
|
||||||
|
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
|
|
||||||
|
self.free_games_now = StoreGroup(self.tr("Free now"), layout=QHBoxLayout, parent=self)
|
||||||
|
self.free_games_now.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
|
|
||||||
|
self.free_games_next = StoreGroup(self.tr("Free next week"), layout=QHBoxLayout, parent=self)
|
||||||
|
self.free_games_next.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
|
|
||||||
|
self.discounts_group = StoreGroup(self.tr("Wishlist discounts"), layout=FlowLayout, parent=self)
|
||||||
|
self.discounts_group.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
|
|
||||||
|
self.games_group = StoreGroup(self.tr("Games"), FlowLayout, self)
|
||||||
|
self.games_group.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
|
||||||
|
self.games_group.loading(False)
|
||||||
|
self.games_group.setVisible(True)
|
||||||
|
|
||||||
|
layout.addWidget(self.free_games_now, alignment=Qt.AlignTop)
|
||||||
|
layout.addWidget(self.free_games_next, alignment=Qt.AlignTop)
|
||||||
|
layout.addWidget(self.discounts_group, alignment=Qt.AlignTop)
|
||||||
|
layout.addWidget(self.games_group, alignment=Qt.AlignTop)
|
||||||
|
layout.addItem(QSpacerItem(0, 0, QSizePolicy.Fixed, QSizePolicy.Expanding))
|
||||||
|
|
||||||
|
def showEvent(self, a0: QShowEvent) -> None:
|
||||||
|
if a0.spontaneous():
|
||||||
|
return super().showEvent(a0)
|
||||||
|
self.api.get_free_games(self.__add_free)
|
||||||
|
self.api.get_wishlist(self.__add_discounts)
|
||||||
|
return super().showEvent(a0)
|
||||||
|
|
||||||
|
def hideEvent(self, a0: QHideEvent) -> None:
|
||||||
|
if a0.spontaneous():
|
||||||
|
return super().hideEvent(a0)
|
||||||
|
# TODO: Implement tab unloading
|
||||||
|
return super().hideEvent(a0)
|
||||||
|
|
||||||
|
def __add_discounts(self, wishlist: List[WishlistItemModel]):
|
||||||
|
for w in self.discounts_group.findChildren(StoreItemWidget, options=Qt.FindDirectChildrenOnly):
|
||||||
|
self.discounts_group.layout().removeWidget(w)
|
||||||
|
w.deleteLater()
|
||||||
|
|
||||||
|
discounts = 0
|
||||||
|
for game in wishlist:
|
||||||
|
if not game:
|
||||||
|
continue
|
||||||
|
try:
|
||||||
|
if game.offer.price.total_price["discount"] > 0:
|
||||||
|
w = StoreItemWidget(self.api.cached_manager, game.offer)
|
||||||
|
w.show_details.connect(self.show_details)
|
||||||
|
self.discounts_group.layout().addWidget(w)
|
||||||
|
discounts += 1
|
||||||
|
except Exception as e:
|
||||||
|
logger.warning(f"{game} {e}")
|
||||||
|
continue
|
||||||
|
# self.discounts_group.setVisible(discounts > 0)
|
||||||
|
self.discounts_group.loading(False)
|
||||||
|
|
||||||
|
def __add_free(self, free_games: List[CatalogOfferModel]):
|
||||||
|
for w in self.free_games_now.findChildren(StoreItemWidget, options=Qt.FindDirectChildrenOnly):
|
||||||
|
self.free_games_now.layout().removeWidget(w)
|
||||||
|
w.deleteLater()
|
||||||
|
|
||||||
|
for w in self.free_games_next.findChildren(StoreItemWidget, options=Qt.FindDirectChildrenOnly):
|
||||||
|
self.free_games_next.layout().removeWidget(w)
|
||||||
|
w.deleteLater()
|
||||||
|
|
||||||
|
date = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
|
||||||
|
free_now = []
|
||||||
|
free_next = []
|
||||||
|
for game in free_games:
|
||||||
|
try:
|
||||||
|
if (
|
||||||
|
game.price.total_price["fmtPrice"]["discountPrice"] == "0"
|
||||||
|
and game.price.total_price["fmtPrice"]["originalPrice"]
|
||||||
|
!= game.price.total_price["fmtPrice"]["discountPrice"]
|
||||||
|
):
|
||||||
|
free_now.append(game)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if game.title == "Mystery Game":
|
||||||
|
free_next.append(game)
|
||||||
|
continue
|
||||||
|
except KeyError as e:
|
||||||
|
logger.warning(str(e))
|
||||||
|
|
||||||
|
try:
|
||||||
|
# parse datetime to check if game is next week or now
|
||||||
|
try:
|
||||||
|
start_date = parse_date(
|
||||||
|
game.promotions["upcomingPromotionalOffers"][0]["promotionalOffers"][0]["startDate"]
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
try:
|
||||||
|
start_date = parse_date(
|
||||||
|
game.promotions["promotionalOffers"][0]["promotionalOffers"][0]["startDate"]
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
continue
|
||||||
|
|
||||||
|
except TypeError:
|
||||||
|
print("type error")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if start_date > date:
|
||||||
|
free_next.append(game)
|
||||||
|
|
||||||
|
# free games now
|
||||||
|
self.free_games_now.setVisible(bool(len(free_now)))
|
||||||
|
for game in free_now:
|
||||||
|
w = StoreItemWidget(self.api.cached_manager, game)
|
||||||
|
w.show_details.connect(self.show_details)
|
||||||
|
self.free_games_now.layout().addWidget(w)
|
||||||
|
self.free_games_now.loading(False)
|
||||||
|
|
||||||
|
# free games next week
|
||||||
|
self.free_games_next.setVisible(bool(len(free_next)))
|
||||||
|
for game in free_next:
|
||||||
|
w = StoreItemWidget(self.api.cached_manager, game)
|
||||||
|
if game.title != "Mystery Game":
|
||||||
|
w.show_details.connect(self.show_details)
|
||||||
|
self.free_games_next.layout().addWidget(w)
|
||||||
|
self.free_games_next.loading(False)
|
||||||
|
|
||||||
|
def show_games(self, data):
|
||||||
|
for w in self.games_group.findChildren(StoreItemWidget, options=Qt.FindDirectChildrenOnly):
|
||||||
|
self.games_group.layout().removeWidget(w)
|
||||||
|
w.deleteLater()
|
||||||
|
|
||||||
|
if data:
|
||||||
|
for game in data:
|
||||||
|
w = StoreItemWidget(self.api.cached_manager, game)
|
||||||
|
w.show_details.connect(self.show_details)
|
||||||
|
self.games_group.layout().addWidget(w)
|
||||||
|
self.games_group.loading(False)
|
57
rare/components/tabs/store/results.py
Normal file
57
rare/components/tabs/store/results.py
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
from PyQt5.QtCore import Qt
|
||||||
|
from PyQt5.QtCore import pyqtSignal
|
||||||
|
from PyQt5.QtWidgets import (
|
||||||
|
QWidget,
|
||||||
|
QSizePolicy,
|
||||||
|
QLabel,
|
||||||
|
QScrollArea,
|
||||||
|
)
|
||||||
|
|
||||||
|
from rare.widgets.flow_layout import FlowLayout
|
||||||
|
from .api.models.response import CatalogOfferModel
|
||||||
|
from .widgets.items import ResultsItemWidget
|
||||||
|
|
||||||
|
|
||||||
|
class ResultsWidget(QScrollArea):
|
||||||
|
show_details = pyqtSignal(CatalogOfferModel)
|
||||||
|
|
||||||
|
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)
|
||||||
|
self.results_container.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
|
self.results_layout = FlowLayout(self.results_container)
|
||||||
|
self.setWidget(self.results_container)
|
||||||
|
self.setWidgetResizable(True)
|
||||||
|
|
||||||
|
# self.main_layout = QVBoxLayout(self)
|
||||||
|
# self.main_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
# self.main_layout.addWidget(self.results_scrollarea)
|
||||||
|
|
||||||
|
self.setEnabled(False)
|
||||||
|
|
||||||
|
def load_results(self, text: str):
|
||||||
|
self.setEnabled(False)
|
||||||
|
if text != "":
|
||||||
|
self.store_api.search_game(text, self.show_results)
|
||||||
|
|
||||||
|
def show_results(self, results: dict):
|
||||||
|
for w in self.results_container.findChildren(QLabel, options=Qt.FindDirectChildrenOnly):
|
||||||
|
self.results_layout.removeWidget(w)
|
||||||
|
w.deleteLater()
|
||||||
|
for w in self.results_container.findChildren(ResultsItemWidget, options=Qt.FindDirectChildrenOnly):
|
||||||
|
self.results_layout.removeWidget(w)
|
||||||
|
w.deleteLater()
|
||||||
|
|
||||||
|
if not results:
|
||||||
|
self.results_layout.addWidget(QLabel(self.tr("No results found")))
|
||||||
|
else:
|
||||||
|
for res in results:
|
||||||
|
w = ResultsItemWidget(self.store_api.cached_manager, res, parent=self.results_container)
|
||||||
|
w.show_details.connect(self.show_details.emit)
|
||||||
|
self.results_layout.addWidget(w)
|
||||||
|
self.results_layout.update()
|
||||||
|
self.setEnabled(True)
|
||||||
|
|
223
rare/components/tabs/store/search.py
Normal file
223
rare/components/tabs/store/search.py
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
import logging
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from PyQt5.QtCore import pyqtSignal, Qt, pyqtSlot
|
||||||
|
from PyQt5.QtWidgets import (
|
||||||
|
QCheckBox,
|
||||||
|
QWidget,
|
||||||
|
QSizePolicy,
|
||||||
|
QScrollArea,
|
||||||
|
QFrame,
|
||||||
|
)
|
||||||
|
from legendary.core import LegendaryCore
|
||||||
|
|
||||||
|
from rare.ui.components.tabs.store.search import Ui_SearchWidget
|
||||||
|
from rare.utils.extra_widgets import ButtonLineEdit
|
||||||
|
from rare.widgets.side_tab import SideTabContents
|
||||||
|
from rare.widgets.sliding_stack import SlidingStackedWidget
|
||||||
|
from .api.models.query import SearchStoreQuery
|
||||||
|
from .api.models.response import CatalogOfferModel
|
||||||
|
from .constants import Constants
|
||||||
|
from .results import ResultsWidget
|
||||||
|
from .store_api import StoreAPI
|
||||||
|
from .widgets.details import DetailsWidget
|
||||||
|
|
||||||
|
logger = logging.getLogger("Shop")
|
||||||
|
|
||||||
|
|
||||||
|
class SearchPage(SlidingStackedWidget, SideTabContents):
|
||||||
|
def __init__(self, core, api: StoreAPI, parent=None):
|
||||||
|
super(SearchPage, self).__init__(parent=parent)
|
||||||
|
self.implements_scrollarea = True
|
||||||
|
|
||||||
|
self.search_widget = SearchWidget(core, api, parent=self)
|
||||||
|
self.search_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
|
self.search_widget.set_title.connect(self.set_title)
|
||||||
|
self.search_widget.show_details.connect(self.show_details)
|
||||||
|
|
||||||
|
self.details_widget = DetailsWidget([], api, parent=self)
|
||||||
|
self.details_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
|
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)
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def show_main(self):
|
||||||
|
self.slideInWidget(self.search_widget)
|
||||||
|
|
||||||
|
@pyqtSlot(object)
|
||||||
|
def show_details(self, game: CatalogOfferModel):
|
||||||
|
self.details_widget.update_game(game)
|
||||||
|
self.slideInWidget(self.details_scroll)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyAttributeOutsideInit,PyBroadException
|
||||||
|
class SearchWidget(QWidget, SideTabContents):
|
||||||
|
show_details = pyqtSignal(CatalogOfferModel)
|
||||||
|
|
||||||
|
def __init__(self, core: LegendaryCore, api: StoreAPI, parent=None):
|
||||||
|
super(SearchWidget, self).__init__(parent=parent)
|
||||||
|
self.implements_scrollarea = True
|
||||||
|
self.ui = Ui_SearchWidget()
|
||||||
|
self.ui.setupUi(self)
|
||||||
|
self.ui.main_layout.setContentsMargins(0, 0, 3, 0)
|
||||||
|
|
||||||
|
self.core = core
|
||||||
|
self.api_core = api
|
||||||
|
self.price = ""
|
||||||
|
self.tags = []
|
||||||
|
self.types = []
|
||||||
|
self.update_games_allowed = True
|
||||||
|
|
||||||
|
self.free_game_widgets = []
|
||||||
|
self.active_search_request = False
|
||||||
|
self.next_search = ""
|
||||||
|
self.wishlist: List = []
|
||||||
|
|
||||||
|
self.search_bar = ButtonLineEdit("fa.search", placeholder_text=self.tr("Search Games"))
|
||||||
|
self.results_scrollarea = ResultsWidget(self.api_core, self)
|
||||||
|
self.results_scrollarea.show_details.connect(self.show_details)
|
||||||
|
|
||||||
|
self.ui.left_layout.addWidget(self.search_bar)
|
||||||
|
self.ui.left_layout.addWidget(self.results_scrollarea)
|
||||||
|
|
||||||
|
self.search_bar.returnPressed.connect(self.show_search_results)
|
||||||
|
self.search_bar.buttonClicked.connect(self.show_search_results)
|
||||||
|
|
||||||
|
# self.init_filter()
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
# load browse games
|
||||||
|
self.prepare_request()
|
||||||
|
|
||||||
|
def show_search_results(self):
|
||||||
|
if text := self.search_bar.text():
|
||||||
|
self.results_scrollarea.load_results(text)
|
||||||
|
# self.show_info.emit(self.search_bar.text())
|
||||||
|
|
||||||
|
def init_filter(self):
|
||||||
|
self.ui.none_price.toggled.connect(
|
||||||
|
lambda: self.prepare_request("") if self.ui.none_price.isChecked() else None
|
||||||
|
)
|
||||||
|
self.ui.free_button.toggled.connect(
|
||||||
|
lambda: self.prepare_request("free") if self.ui.free_button.isChecked() else None
|
||||||
|
)
|
||||||
|
self.ui.under10.toggled.connect(
|
||||||
|
lambda: self.prepare_request("<price>[0, 1000)") if self.ui.under10.isChecked() else None
|
||||||
|
)
|
||||||
|
self.ui.under20.toggled.connect(
|
||||||
|
lambda: self.prepare_request("<price>[0, 2000)") if self.ui.under20.isChecked() else None
|
||||||
|
)
|
||||||
|
self.ui.under30.toggled.connect(
|
||||||
|
lambda: self.prepare_request("<price>[0, 3000)") if self.ui.under30.isChecked() else None
|
||||||
|
)
|
||||||
|
self.ui.above.toggled.connect(
|
||||||
|
lambda: self.prepare_request("<price>[1499,]") 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.ui.on_discount.toggled.connect(lambda: self.prepare_request())
|
||||||
|
constants = Constants()
|
||||||
|
|
||||||
|
self.checkboxes = []
|
||||||
|
|
||||||
|
for groupbox, variables in [
|
||||||
|
(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:
|
||||||
|
checkbox = CheckBox(text, tag)
|
||||||
|
checkbox.activated.connect(lambda x: self.prepare_request(added_tag=x))
|
||||||
|
checkbox.deactivated.connect(lambda x: self.prepare_request(removed_tag=x))
|
||||||
|
groupbox.layout().addWidget(checkbox)
|
||||||
|
self.checkboxes.append(checkbox)
|
||||||
|
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.ui.none_price.setChecked(True)
|
||||||
|
|
||||||
|
self.tags = []
|
||||||
|
self.types = []
|
||||||
|
self.update_games_allowed = True
|
||||||
|
|
||||||
|
self.ui.on_discount.setChecked(False)
|
||||||
|
|
||||||
|
def prepare_request(
|
||||||
|
self,
|
||||||
|
price: str = None,
|
||||||
|
added_tag: int = 0,
|
||||||
|
removed_tag: int = 0,
|
||||||
|
added_type: str = "",
|
||||||
|
removed_type: str = "",
|
||||||
|
):
|
||||||
|
if not self.update_games_allowed:
|
||||||
|
return
|
||||||
|
if price is not None:
|
||||||
|
self.price = price
|
||||||
|
|
||||||
|
if added_tag != 0:
|
||||||
|
self.tags.append(added_tag)
|
||||||
|
if removed_tag != 0 and removed_tag in self.tags:
|
||||||
|
self.tags.remove(removed_tag)
|
||||||
|
|
||||||
|
if added_type:
|
||||||
|
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.ui.on_discount.isChecked():
|
||||||
|
# self.free_scrollarea.setVisible(False)
|
||||||
|
self.discounts_group.setVisible(False)
|
||||||
|
else:
|
||||||
|
# self.free_scrollarea.setVisible(True)
|
||||||
|
if len(self.discounts_group.layout().children()) > 0:
|
||||||
|
self.discounts_group.setVisible(True)
|
||||||
|
|
||||||
|
self.games_group.loading(True)
|
||||||
|
|
||||||
|
browse_model = SearchStoreQuery(
|
||||||
|
language=self.core.language_code,
|
||||||
|
country=self.core.country_code,
|
||||||
|
count=20,
|
||||||
|
price_range=self.price,
|
||||||
|
on_sale=self.ui.on_discount.isChecked(),
|
||||||
|
)
|
||||||
|
browse_model.tag = "|".join(self.tags)
|
||||||
|
|
||||||
|
if self.types:
|
||||||
|
browse_model.category = "|".join(self.types)
|
||||||
|
self.api_core.browse_games(browse_model, self.show_games)
|
||||||
|
|
||||||
|
|
||||||
|
class CheckBox(QCheckBox):
|
||||||
|
activated = pyqtSignal(str)
|
||||||
|
deactivated = pyqtSignal(str)
|
||||||
|
|
||||||
|
def __init__(self, text, tag):
|
||||||
|
super(CheckBox, self).__init__(text)
|
||||||
|
self.tag = tag
|
||||||
|
|
||||||
|
self.toggled.connect(self.handle_toggle)
|
||||||
|
|
||||||
|
def handle_toggle(self):
|
||||||
|
if self.isChecked():
|
||||||
|
self.activated.emit(self.tag)
|
||||||
|
else:
|
||||||
|
self.deactivated.emit(self.tag)
|
|
@ -1,98 +0,0 @@
|
||||||
from PyQt5.QtCore import Qt
|
|
||||||
from PyQt5.QtCore import pyqtSignal
|
|
||||||
from PyQt5.QtGui import QMouseEvent
|
|
||||||
from PyQt5.QtWidgets import (
|
|
||||||
QWidget,
|
|
||||||
QSizePolicy,
|
|
||||||
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
|
|
||||||
|
|
||||||
from .api.debug import DebugDialog
|
|
||||||
from .api.models.response import CatalogOfferModel
|
|
||||||
|
|
||||||
|
|
||||||
class SearchResults(QScrollArea, SideTabContents):
|
|
||||||
show_info = pyqtSignal(CatalogOfferModel)
|
|
||||||
|
|
||||||
def __init__(self, api_core, parent=None):
|
|
||||||
super(SearchResults, self).__init__(parent=parent)
|
|
||||||
self.implements_scrollarea = True
|
|
||||||
self.api_core = api_core
|
|
||||||
|
|
||||||
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)
|
|
||||||
# self.main_layout.setContentsMargins(0, 0, 0, 0)
|
|
||||||
# self.main_layout.addWidget(self.results_scrollarea)
|
|
||||||
|
|
||||||
self.setEnabled(False)
|
|
||||||
|
|
||||||
def load_results(self, text: str):
|
|
||||||
self.setEnabled(False)
|
|
||||||
if text != "":
|
|
||||||
self.api_core.search_game(text, self.show_results)
|
|
||||||
|
|
||||||
def show_results(self, results: dict):
|
|
||||||
for w in self.results_container.findChildren(QLabel, options=Qt.FindDirectChildrenOnly):
|
|
||||||
self.results_layout.removeWidget(w)
|
|
||||||
w.deleteLater()
|
|
||||||
for w in self.results_container.findChildren(SearchResultItem, options=Qt.FindDirectChildrenOnly):
|
|
||||||
self.results_layout.removeWidget(w)
|
|
||||||
w.deleteLater()
|
|
||||||
|
|
||||||
if not results:
|
|
||||||
self.results_layout.addWidget(QLabel(self.tr("No results found")))
|
|
||||||
else:
|
|
||||||
for res in results:
|
|
||||||
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(CatalogOfferModel)
|
|
||||||
|
|
||||||
def __init__(self, manager: QtRequestManager, catalog_game: CatalogOfferModel, parent=None):
|
|
||||||
super(SearchResultItem, self).__init__(manager, parent=parent)
|
|
||||||
self.setFixedSize(ImageSize.Normal)
|
|
||||||
self.ui.setupUi(self)
|
|
||||||
|
|
||||||
key_images = catalog_game.key_images
|
|
||||||
self.fetchPixmap(key_images.for_dimensions(self.width(), self.height()).url)
|
|
||||||
|
|
||||||
self.ui.title_label.setText(catalog_game.title)
|
|
||||||
|
|
||||||
price = catalog_game.price.total_price["fmtPrice"]["originalPrice"]
|
|
||||||
discount_price = catalog_game.price.total_price["fmtPrice"]["discountPrice"]
|
|
||||||
self.ui.price_label.setText(f'{price if price != "0" else self.tr("Free")}')
|
|
||||||
if price != discount_price:
|
|
||||||
font = self.ui.price_label.font()
|
|
||||||
font.setStrikeOut(True)
|
|
||||||
self.ui.price_label.setFont(font)
|
|
||||||
self.ui.discount_label.setText(f'{discount_price if discount_price != "0" else self.tr("Free")}')
|
|
||||||
else:
|
|
||||||
self.ui.discount_label.setVisible(False)
|
|
||||||
|
|
||||||
self.catalog_game = catalog_game
|
|
||||||
|
|
||||||
def mousePressEvent(self, a0: QMouseEvent) -> None:
|
|
||||||
if a0.button() == Qt.LeftButton:
|
|
||||||
a0.accept()
|
|
||||||
self.show_info.emit(self.catalog_game)
|
|
||||||
if a0.button() == Qt.RightButton:
|
|
||||||
a0.accept()
|
|
||||||
dialog = DebugDialog(self.catalog_game.__dict__, self)
|
|
||||||
dialog.show()
|
|
||||||
|
|
|
@ -1,396 +0,0 @@
|
||||||
import datetime
|
|
||||||
import logging
|
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, Qt
|
|
||||||
from PyQt5.QtWidgets import (
|
|
||||||
QGroupBox,
|
|
||||||
QCheckBox,
|
|
||||||
QLabel,
|
|
||||||
QPushButton,
|
|
||||||
QHBoxLayout,
|
|
||||||
QWidget, QSizePolicy, QStackedLayout,
|
|
||||||
)
|
|
||||||
from legendary.core import LegendaryCore
|
|
||||||
|
|
||||||
from rare.ui.components.tabs.store.store import Ui_ShopWidget
|
|
||||||
from rare.utils.extra_widgets import ButtonLineEdit
|
|
||||||
from rare.widgets.flow_layout import FlowLayout
|
|
||||||
from rare.widgets.side_tab import SideTabContents
|
|
||||||
from .api.models.query import SearchStoreQuery
|
|
||||||
from .api.models.response import CatalogOfferModel, WishlistItemModel
|
|
||||||
from .constants import Constants
|
|
||||||
from .game_widgets import GameWidget
|
|
||||||
from .image_widget import WaitingSpinner
|
|
||||||
from .shop_api_core import ShopApiCore
|
|
||||||
|
|
||||||
from .api.models.utils import parse_date
|
|
||||||
|
|
||||||
logger = logging.getLogger("Shop")
|
|
||||||
|
|
||||||
|
|
||||||
# noinspection PyAttributeOutsideInit,PyBroadException
|
|
||||||
class ShopWidget(QWidget, SideTabContents):
|
|
||||||
show_info = pyqtSignal(str)
|
|
||||||
show_game = pyqtSignal(dict)
|
|
||||||
|
|
||||||
def __init__(self, cache_dir, core: LegendaryCore, shop_api: ShopApiCore, parent=None):
|
|
||||||
super(ShopWidget, self).__init__(parent=parent)
|
|
||||||
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 = ""
|
|
||||||
self.tags = []
|
|
||||||
self.types = []
|
|
||||||
self.update_games_allowed = True
|
|
||||||
|
|
||||||
self.ui.free_scrollarea.setDisabled(True)
|
|
||||||
|
|
||||||
self.free_game_widgets = []
|
|
||||||
self.active_search_request = False
|
|
||||||
self.next_search = ""
|
|
||||||
self.wishlist: List = []
|
|
||||||
|
|
||||||
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.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.ui.main_layout.addWidget(self.search_bar, 0, 0)
|
|
||||||
|
|
||||||
# self.search_bar.textChanged.connect(self.search_games)
|
|
||||||
|
|
||||||
self.search_bar.returnPressed.connect(self.show_search_results)
|
|
||||||
self.search_bar.buttonClicked.connect(self.show_search_results)
|
|
||||||
|
|
||||||
self.init_filter()
|
|
||||||
|
|
||||||
self.search_bar.setHidden(True)
|
|
||||||
self.filter_gb.setHidden(True)
|
|
||||||
self.filter_game_gb.setHidden(True)
|
|
||||||
|
|
||||||
# self.search_bar.textChanged.connect(self.load_completer)
|
|
||||||
|
|
||||||
def load(self):
|
|
||||||
# load free games
|
|
||||||
self.api_core.get_free_games(self.add_free_games)
|
|
||||||
# load wishlist
|
|
||||||
self.api_core.get_wishlist(self.add_wishlist_items)
|
|
||||||
# load browse games
|
|
||||||
self.prepare_request()
|
|
||||||
|
|
||||||
def update_wishlist(self):
|
|
||||||
self.api_core.get_wishlist(self.add_wishlist_items)
|
|
||||||
|
|
||||||
def add_wishlist_items(self, wishlist: List[WishlistItemModel]):
|
|
||||||
for w in self.discounts_flow.findChildren(QWidget, options=Qt.FindDirectChildrenOnly):
|
|
||||||
self.discounts_flow.layout().removeWidget(w)
|
|
||||||
w.deleteLater()
|
|
||||||
|
|
||||||
# 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:
|
|
||||||
if not game:
|
|
||||||
continue
|
|
||||||
try:
|
|
||||||
if game.offer.price.total_price["discount"] > 0:
|
|
||||||
w = GameWidget(self.api_core.cached_manager, game.offer)
|
|
||||||
w.show_info.connect(self.show_game)
|
|
||||||
self.discounts_flow.layout().addWidget(w)
|
|
||||||
discounts += 1
|
|
||||||
except Exception as e:
|
|
||||||
logger.warning(f"{game} {e}")
|
|
||||||
continue
|
|
||||||
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[CatalogOfferModel]):
|
|
||||||
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.ui.free_container.layout().addWidget(
|
|
||||||
QLabel(self.tr("Failed to fetch free games: {}").format(free_games[1]))
|
|
||||||
)
|
|
||||||
btn = QPushButton(self.tr("Reload"))
|
|
||||||
self.ui.free_container.layout().addWidget(btn)
|
|
||||||
btn.clicked.connect(
|
|
||||||
lambda: self.api_core.get_free_games(self.add_free_games)
|
|
||||||
)
|
|
||||||
self.ui.free_container.setEnabled(True)
|
|
||||||
return
|
|
||||||
|
|
||||||
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.Fixed, QSizePolicy.Fixed)
|
|
||||||
self.free_games_now.setLayout(free_games_now_layout)
|
|
||||||
self.ui.free_container.layout().addWidget(self.free_games_now)
|
|
||||||
|
|
||||||
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.Fixed, QSizePolicy.Fixed)
|
|
||||||
self.free_games_next.setLayout(free_games_next_layout)
|
|
||||||
self.ui.free_container.layout().addWidget(self.free_games_next)
|
|
||||||
|
|
||||||
date = datetime.datetime.utcnow().replace(tzinfo=datetime.timezone.utc)
|
|
||||||
free_games_now = []
|
|
||||||
coming_free_games = []
|
|
||||||
for game in free_games:
|
|
||||||
try:
|
|
||||||
if (
|
|
||||||
game.price.total_price["fmtPrice"]["discountPrice"] == "0"
|
|
||||||
and game.price.total_price["fmtPrice"]["originalPrice"]
|
|
||||||
!= game.price.total_price["fmtPrice"]["discountPrice"]
|
|
||||||
):
|
|
||||||
free_games_now.append(game)
|
|
||||||
continue
|
|
||||||
|
|
||||||
if game.title == "Mystery Game":
|
|
||||||
coming_free_games.append(game)
|
|
||||||
continue
|
|
||||||
except KeyError as e:
|
|
||||||
logger.warning(str(e))
|
|
||||||
|
|
||||||
try:
|
|
||||||
# parse datetime to check if game is next week or now
|
|
||||||
try:
|
|
||||||
start_date = parse_date(
|
|
||||||
game.promotions["upcomingPromotionalOffers"][0]["promotionalOffers"][0]["startDate"]
|
|
||||||
)
|
|
||||||
except Exception:
|
|
||||||
try:
|
|
||||||
start_date = parse_date(
|
|
||||||
game.promotions["promotionalOffers"][0]["promotionalOffers"][0]["startDate"]
|
|
||||||
)
|
|
||||||
except Exception as e:
|
|
||||||
|
|
||||||
continue
|
|
||||||
|
|
||||||
except TypeError:
|
|
||||||
print("type error")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if start_date > date:
|
|
||||||
coming_free_games.append(game)
|
|
||||||
# free games now
|
|
||||||
now_free = 0
|
|
||||||
for free_game in free_games_now:
|
|
||||||
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)
|
|
||||||
now_free += 1
|
|
||||||
if now_free == 0:
|
|
||||||
self.free_games_now.layout().addWidget(
|
|
||||||
QLabel(self.tr("Could not find current free game"))
|
|
||||||
)
|
|
||||||
|
|
||||||
# free games next week
|
|
||||||
for free_game in coming_free_games:
|
|
||||||
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.ui.free_scrollarea.setMinimumHeight(
|
|
||||||
self.free_games_now.sizeHint().height()
|
|
||||||
+ self.ui.free_container.layout().contentsMargins().top()
|
|
||||||
+ self.ui.free_container.layout().contentsMargins().bottom()
|
|
||||||
+ self.ui.free_scrollarea.horizontalScrollBar().sizeHint().height()
|
|
||||||
)
|
|
||||||
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.ui.none_price.toggled.connect(
|
|
||||||
lambda: self.prepare_request("") if self.ui.none_price.isChecked() else None
|
|
||||||
)
|
|
||||||
self.ui.free_button.toggled.connect(
|
|
||||||
lambda: self.prepare_request("free")
|
|
||||||
if self.ui.free_button.isChecked()
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
self.ui.under10.toggled.connect(
|
|
||||||
lambda: self.prepare_request("<price>[0, 1000)")
|
|
||||||
if self.ui.under10.isChecked()
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
self.ui.under20.toggled.connect(
|
|
||||||
lambda: self.prepare_request("<price>[0, 2000)")
|
|
||||||
if self.ui.under20.isChecked()
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
self.ui.under30.toggled.connect(
|
|
||||||
lambda: self.prepare_request("<price>[0, 3000)")
|
|
||||||
if self.ui.under30.isChecked()
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
self.ui.above.toggled.connect(
|
|
||||||
lambda: self.prepare_request("<price>[1499,]")
|
|
||||||
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.ui.on_discount.toggled.connect(lambda: self.prepare_request())
|
|
||||||
constants = Constants()
|
|
||||||
|
|
||||||
self.checkboxes = []
|
|
||||||
|
|
||||||
for groupbox, variables in [
|
|
||||||
(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:
|
|
||||||
checkbox = CheckBox(text, tag)
|
|
||||||
checkbox.activated.connect(lambda x: self.prepare_request(added_tag=x))
|
|
||||||
checkbox.deactivated.connect(
|
|
||||||
lambda x: self.prepare_request(removed_tag=x)
|
|
||||||
)
|
|
||||||
groupbox.layout().addWidget(checkbox)
|
|
||||||
self.checkboxes.append(checkbox)
|
|
||||||
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.ui.none_price.setChecked(True)
|
|
||||||
|
|
||||||
self.tags = []
|
|
||||||
self.types = []
|
|
||||||
self.update_games_allowed = True
|
|
||||||
self.prepare_request("")
|
|
||||||
|
|
||||||
self.ui.on_discount.setChecked(False)
|
|
||||||
|
|
||||||
def prepare_request(
|
|
||||||
self,
|
|
||||||
price: str = None,
|
|
||||||
added_tag: int = 0,
|
|
||||||
removed_tag: int = 0,
|
|
||||||
added_type: str = "",
|
|
||||||
removed_type: str = "",
|
|
||||||
):
|
|
||||||
if not self.update_games_allowed:
|
|
||||||
return
|
|
||||||
if price is not None:
|
|
||||||
self.price = price
|
|
||||||
|
|
||||||
if added_tag != 0:
|
|
||||||
self.tags.append(added_tag)
|
|
||||||
if removed_tag != 0 and removed_tag in self.tags:
|
|
||||||
self.tags.remove(removed_tag)
|
|
||||||
|
|
||||||
if added_type:
|
|
||||||
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.ui.on_discount.isChecked():
|
|
||||||
self.ui.free_scrollarea.setVisible(False)
|
|
||||||
self.ui.discounts_group.setVisible(False)
|
|
||||||
else:
|
|
||||||
self.ui.free_scrollarea.setVisible(True)
|
|
||||||
if len(self.ui.discounts_group.layout().children()) > 0:
|
|
||||||
self.ui.discounts_group.setVisible(True)
|
|
||||||
|
|
||||||
self.games_layout.setCurrentWidget(self.games_spinner)
|
|
||||||
|
|
||||||
browse_model = SearchStoreQuery(
|
|
||||||
language=self.core.language_code,
|
|
||||||
country=self.core.country_code,
|
|
||||||
count=20,
|
|
||||||
price_range=self.price,
|
|
||||||
on_sale=self.ui.on_discount.isChecked(),
|
|
||||||
)
|
|
||||||
browse_model.tag = "|".join(self.tags)
|
|
||||||
|
|
||||||
if self.types:
|
|
||||||
browse_model.category = "|".join(self.types)
|
|
||||||
self.api_core.browse_games(browse_model, self.show_games)
|
|
||||||
|
|
||||||
def show_games(self, data):
|
|
||||||
for w in self.games_flow.findChildren(QWidget, options=Qt.FindDirectChildrenOnly):
|
|
||||||
self.games_flow.layout().removeWidget(w)
|
|
||||||
w.deleteLater()
|
|
||||||
|
|
||||||
if data:
|
|
||||||
for game in data:
|
|
||||||
w = GameWidget(self.api_core.cached_manager, game)
|
|
||||||
w.show_info.connect(self.show_game)
|
|
||||||
self.games_flow.layout().addWidget(w)
|
|
||||||
else:
|
|
||||||
self.games_flow.layout().addWidget(
|
|
||||||
QLabel(self.tr("Could not get games matching the filter"))
|
|
||||||
)
|
|
||||||
self.games_layout.setCurrentWidget(self.games_flow)
|
|
||||||
# FIXME: FlowLayout doesn't update on adding widget
|
|
||||||
self.games_flow.layout().update()
|
|
||||||
|
|
||||||
|
|
||||||
class CheckBox(QCheckBox):
|
|
||||||
activated = pyqtSignal(str)
|
|
||||||
deactivated = pyqtSignal(str)
|
|
||||||
|
|
||||||
def __init__(self, text, tag):
|
|
||||||
super(CheckBox, self).__init__(text)
|
|
||||||
self.tag = tag
|
|
||||||
|
|
||||||
self.toggled.connect(self.handle_toggle)
|
|
||||||
|
|
||||||
def handle_toggle(self):
|
|
||||||
if self.isChecked():
|
|
||||||
self.activated.emit(self.tag)
|
|
||||||
else:
|
|
||||||
self.deactivated.emit(self.tag)
|
|
|
@ -11,12 +11,11 @@ from rare.components.tabs.store.constants import (
|
||||||
wishlist_add_query,
|
wishlist_add_query,
|
||||||
wishlist_remove_query,
|
wishlist_remove_query,
|
||||||
)
|
)
|
||||||
from rare.components.tabs.store.shop_models import BrowseModel
|
|
||||||
from rare.utils.paths import cache_dir
|
from rare.utils.paths import cache_dir
|
||||||
from rare.utils.qt_requests import QtRequests
|
from rare.utils.qt_requests import QtRequests
|
||||||
from .api.models.query import SearchStoreQuery
|
from .api.models.query import SearchStoreQuery
|
||||||
|
from .api.models.diesel import DieselProduct
|
||||||
from .api.models.response import (
|
from .api.models.response import (
|
||||||
DieselProduct,
|
|
||||||
ResponseModel,
|
ResponseModel,
|
||||||
CatalogOfferModel,
|
CatalogOfferModel,
|
||||||
)
|
)
|
||||||
|
@ -28,11 +27,11 @@ graphql_url = "https://graphql.epicgames.com/graphql"
|
||||||
DEBUG: Callable[[], bool] = lambda: "--debug" in QApplication.arguments()
|
DEBUG: Callable[[], bool] = lambda: "--debug" in QApplication.arguments()
|
||||||
|
|
||||||
|
|
||||||
class ShopApiCore(QObject):
|
class StoreAPI(QObject):
|
||||||
update_wishlist = pyqtSignal()
|
update_wishlist = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, token, language: str, country: str):
|
def __init__(self, token, language: str, country: str, installed):
|
||||||
super(ShopApiCore, self).__init__()
|
super(StoreAPI, self).__init__()
|
||||||
self.token = token
|
self.token = token
|
||||||
self.language_code: str = language
|
self.language_code: str = language
|
||||||
self.country_code: str = country
|
self.country_code: str = country
|
||||||
|
@ -42,6 +41,8 @@ class ShopApiCore(QObject):
|
||||||
self.authed_manager = QtRequests(token=token, parent=self)
|
self.authed_manager = QtRequests(token=token, parent=self)
|
||||||
self.cached_manager = QtRequests(cache=str(cache_dir().joinpath("store")), parent=self)
|
self.cached_manager = QtRequests(cache=str(cache_dir().joinpath("store")), parent=self)
|
||||||
|
|
||||||
|
self.installed = installed
|
||||||
|
|
||||||
self.browse_active = False
|
self.browse_active = False
|
||||||
self.next_browse_request = tuple(())
|
self.next_browse_request = tuple(())
|
||||||
|
|
||||||
|
@ -153,13 +154,13 @@ class ShopApiCore(QObject):
|
||||||
"query": search_query,
|
"query": search_query,
|
||||||
"variables": browse_model.to_dict()
|
"variables": browse_model.to_dict()
|
||||||
}
|
}
|
||||||
debug = DebugDialog(payload["variables"], None)
|
# debug = DebugDialog(payload["variables"], None)
|
||||||
debug.exec()
|
# debug.exec()
|
||||||
self.manager.post(graphql_url, lambda data: self.__handle_browse_games(data, handle_func), payload)
|
self.manager.post(graphql_url, lambda data: self.__handle_browse_games(data, handle_func), payload)
|
||||||
|
|
||||||
def __handle_browse_games(self, data, handle_func):
|
def __handle_browse_games(self, data, handle_func):
|
||||||
debug = DebugDialog(data, None)
|
# debug = DebugDialog(data, None)
|
||||||
debug.exec()
|
# debug.exec()
|
||||||
self.browse_active = False
|
self.browse_active = False
|
||||||
if data is None:
|
if data is None:
|
||||||
data = {}
|
data = {}
|
||||||
|
@ -182,15 +183,29 @@ class ShopApiCore(QObject):
|
||||||
self.browse_games(*self.next_browse_request) # pylint: disable=E1120
|
self.browse_games(*self.next_browse_request) # pylint: disable=E1120
|
||||||
self.next_browse_request = tuple(())
|
self.next_browse_request = tuple(())
|
||||||
|
|
||||||
def get_game(self, slug: str, is_bundle: bool, handle_func):
|
def get_game_config_graphql(self, namespace: str, handle_func):
|
||||||
|
payload = {
|
||||||
|
"query": config_query,
|
||||||
|
"variables": {
|
||||||
|
"namespace": namespace
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
def __make_graphql_query(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __make_api_query(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def get_game_config_cms(self, slug: str, is_bundle: bool, handle_func):
|
||||||
url = "https://store-content.ak.epicgames.com/api"
|
url = "https://store-content.ak.epicgames.com/api"
|
||||||
url += f"/{self.locale}/content/{'products' if not is_bundle else 'bundles'}/{slug}"
|
url += f"/{self.locale}/content/{'products' if not is_bundle else 'bundles'}/{slug}"
|
||||||
self.manager.get(url, lambda data: self.__handle_get_game(data, handle_func))
|
self.manager.get(url, lambda data: self.__handle_get_game(data, handle_func))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def __handle_get_game(data, handle_func):
|
def __handle_get_game(data, handle_func):
|
||||||
debug = DebugDialog(data, None)
|
# debug = DebugDialog(data, None)
|
||||||
debug.exec()
|
# debug.exec()
|
||||||
try:
|
try:
|
||||||
product = DieselProduct.from_dict(data)
|
product = DieselProduct.from_dict(data)
|
||||||
handle_func(product)
|
handle_func(product)
|
||||||
|
@ -214,8 +229,8 @@ class ShopApiCore(QObject):
|
||||||
self.authed_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):
|
def _handle_add_to_wishlist(self, data, handle_func):
|
||||||
debug = DebugDialog(data, None)
|
# debug = DebugDialog(data, None)
|
||||||
debug.exec()
|
# debug.exec()
|
||||||
try:
|
try:
|
||||||
response = ResponseModel.from_dict(data)
|
response = ResponseModel.from_dict(data)
|
||||||
data = response.data.wishlist.add_to_wishlist
|
data = response.data.wishlist.add_to_wishlist
|
||||||
|
@ -240,8 +255,8 @@ class ShopApiCore(QObject):
|
||||||
payload)
|
payload)
|
||||||
|
|
||||||
def _handle_remove_from_wishlist(self, data, handle_func):
|
def _handle_remove_from_wishlist(self, data, handle_func):
|
||||||
debug = DebugDialog(data, None)
|
# debug = DebugDialog(data, None)
|
||||||
debug.exec()
|
# debug.exec()
|
||||||
try:
|
try:
|
||||||
response = ResponseModel.from_dict(data)
|
response = ResponseModel.from_dict(data)
|
||||||
data = response.data.wishlist.remove_from_wishlist
|
data = response.data.wishlist.remove_from_wishlist
|
0
rare/components/tabs/store/widgets/__init__.py
Normal file
0
rare/components/tabs/store/widgets/__init__.py
Normal file
|
@ -1,8 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
from pprint import pprint
|
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, QUrl
|
from PyQt5.QtCore import Qt, QUrl, pyqtSignal
|
||||||
from PyQt5.QtGui import QFont, QDesktopServices, QFontMetrics
|
from PyQt5.QtGui import QFont, QDesktopServices, QFontMetrics
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QWidget,
|
QWidget,
|
||||||
|
@ -12,38 +11,42 @@ from PyQt5.QtWidgets import (
|
||||||
QSizePolicy,
|
QSizePolicy,
|
||||||
)
|
)
|
||||||
|
|
||||||
from rare.components.tabs.store.api.models.response import CatalogOfferModel, DieselProduct, DieselProductDetail
|
from rare.components.tabs.store.api.debug import DebugDialog
|
||||||
from rare.shared import LegendaryCoreSingleton
|
from rare.components.tabs.store.api.models.diesel import DieselProduct, DieselProductDetail
|
||||||
from rare.shared.image_manager import ImageSize
|
from rare.components.tabs.store.api.models.response import CatalogOfferModel
|
||||||
from rare.ui.components.tabs.store.shop_game_info import Ui_ShopInfo
|
from rare.models.image import ImageSize
|
||||||
|
from rare.ui.components.tabs.store.details import Ui_DetailsWidget
|
||||||
from rare.utils.misc import icon
|
from rare.utils.misc import icon
|
||||||
from rare.widgets.side_tab import SideTabWidget, SideTabContents
|
|
||||||
from rare.widgets.elide_label import ElideLabel
|
from rare.widgets.elide_label import ElideLabel
|
||||||
from .api.debug import DebugDialog
|
from rare.widgets.side_tab import SideTabWidget, SideTabContents
|
||||||
from .image_widget import ShopImageWidget
|
from .image import LoadingImageWidget
|
||||||
|
|
||||||
logger = logging.getLogger("ShopInfo")
|
logger = logging.getLogger("StoreDetails")
|
||||||
|
|
||||||
|
|
||||||
class ShopGameInfo(QWidget, SideTabContents):
|
class DetailsWidget(QWidget, SideTabContents):
|
||||||
|
back_clicked: pyqtSignal = pyqtSignal()
|
||||||
|
|
||||||
# TODO Design
|
# TODO Design
|
||||||
def __init__(self, installed_titles: list, api_core, parent=None):
|
def __init__(self, installed_titles: list, api_core, parent=None):
|
||||||
super(ShopGameInfo, self).__init__(parent=parent)
|
super(DetailsWidget, self).__init__(parent=parent)
|
||||||
self.ui = Ui_ShopInfo()
|
self.ui = Ui_DetailsWidget()
|
||||||
self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
|
self.ui.main_layout.setContentsMargins(0, 0, 3, 0)
|
||||||
|
|
||||||
# self.core = LegendaryCoreSingleton()
|
# self.core = LegendaryCoreSingleton()
|
||||||
self.api_core = api_core
|
self.api_core = api_core
|
||||||
self.installed = installed_titles
|
self.installed = installed_titles
|
||||||
self.ui.open_store_button.clicked.connect(self.button_clicked)
|
|
||||||
self.image = ShopImageWidget(api_core.cached_manager, self)
|
|
||||||
self.image.setFixedSize(ImageSize.Normal)
|
|
||||||
self.ui.left_layout.insertWidget(0, self.image, alignment=Qt.AlignTop)
|
|
||||||
|
|
||||||
self.offer: CatalogOfferModel = None
|
self.offer: CatalogOfferModel = None
|
||||||
self.data: dict = {}
|
self.data: dict = {}
|
||||||
|
|
||||||
|
self.image = LoadingImageWidget(api_core.cached_manager, self)
|
||||||
|
self.image.setFixedSize(ImageSize.Normal)
|
||||||
|
self.ui.left_layout.insertWidget(0, self.image, alignment=Qt.AlignTop)
|
||||||
|
self.ui.left_layout.setAlignment(Qt.AlignTop)
|
||||||
|
|
||||||
self.ui.wishlist_button.clicked.connect(self.add_to_wishlist)
|
self.ui.wishlist_button.clicked.connect(self.add_to_wishlist)
|
||||||
|
self.ui.open_store_button.clicked.connect(self.button_clicked)
|
||||||
self.ui.wishlist_button.setVisible(True)
|
self.ui.wishlist_button.setVisible(True)
|
||||||
self.in_wishlist = False
|
self.in_wishlist = False
|
||||||
self.wishlist = []
|
self.wishlist = []
|
||||||
|
@ -52,7 +55,9 @@ class ShopGameInfo(QWidget, SideTabContents):
|
||||||
self.requirements_tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
self.requirements_tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
self.ui.requirements_layout.addWidget(self.requirements_tabs)
|
self.ui.requirements_layout.addWidget(self.requirements_tabs)
|
||||||
|
|
||||||
self.setDisabled(True)
|
self.ui.back_button.clicked.connect(self.back_clicked)
|
||||||
|
|
||||||
|
self.setDisabled(False)
|
||||||
|
|
||||||
def handle_wishlist_update(self, wishlist: List[CatalogOfferModel]):
|
def handle_wishlist_update(self, wishlist: List[CatalogOfferModel]):
|
||||||
if wishlist and wishlist[0] == "error":
|
if wishlist and wishlist[0] == "error":
|
||||||
|
@ -67,7 +72,6 @@ class ShopGameInfo(QWidget, SideTabContents):
|
||||||
def update_game(self, offer: CatalogOfferModel):
|
def update_game(self, offer: CatalogOfferModel):
|
||||||
debug = DebugDialog(offer.__dict__, None)
|
debug = DebugDialog(offer.__dict__, None)
|
||||||
debug.exec()
|
debug.exec()
|
||||||
self.set_title.emit(offer.title)
|
|
||||||
self.ui.title.setText(offer.title)
|
self.ui.title.setText(offer.title)
|
||||||
self.title_str = offer.title
|
self.title_str = offer.title
|
||||||
self.id_str = offer.id
|
self.id_str = offer.id
|
||||||
|
@ -107,7 +111,7 @@ class ShopGameInfo(QWidget, SideTabContents):
|
||||||
|
|
||||||
# init API request
|
# init API request
|
||||||
if slug:
|
if slug:
|
||||||
self.api_core.get_game(offer.product_slug, is_bundle, self.data_received)
|
self.api_core.get_game_config_cms(offer.product_slug, is_bundle, self.data_received)
|
||||||
# else:
|
# else:
|
||||||
# self.data_received({})
|
# self.data_received({})
|
||||||
self.offer = offer
|
self.offer = offer
|
||||||
|
@ -220,7 +224,7 @@ class ShopGameInfo(QWidget, SideTabContents):
|
||||||
|
|
||||||
# self.image_stack.setCurrentIndex(0)
|
# self.image_stack.setCurrentIndex(0)
|
||||||
about = product_data.about
|
about = product_data.about
|
||||||
self.ui.description_label.setText(about.desciption)
|
self.ui.description_label.setMarkdown(about.desciption)
|
||||||
self.ui.dev.setText(about.developer_attribution)
|
self.ui.dev.setText(about.developer_attribution)
|
||||||
# try:
|
# try:
|
||||||
# if isinstance(aboudeveloper, list):
|
# if isinstance(aboudeveloper, list):
|
18
rare/components/tabs/store/widgets/groups.py
Normal file
18
rare/components/tabs/store/widgets/groups.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
from PyQt5.QtWidgets import QGroupBox, QLayout
|
||||||
|
|
||||||
|
from rare.widgets.loading_widget import LoadingWidget
|
||||||
|
|
||||||
|
|
||||||
|
class StoreGroup(QGroupBox):
|
||||||
|
def __init__(self, title: str, layout: type[QLayout], parent=None):
|
||||||
|
super().__init__(parent=parent)
|
||||||
|
self.setTitle(title)
|
||||||
|
self.main_layout = layout(self)
|
||||||
|
self.loading_widget = LoadingWidget(autostart=True, parent=self)
|
||||||
|
|
||||||
|
def loading(self, state: bool) -> None:
|
||||||
|
if state:
|
||||||
|
self.loading_widget.start()
|
||||||
|
else:
|
||||||
|
self.loading_widget.stop()
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
from PyQt5.QtCore import QEvent, QObject
|
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
from PyQt5.QtGui import (
|
from PyQt5.QtGui import (
|
||||||
QPixmap,
|
QPixmap,
|
||||||
QImage,
|
QImage,
|
||||||
QMovie,
|
|
||||||
QShowEvent,
|
|
||||||
)
|
)
|
||||||
from PyQt5.QtWidgets import (
|
from PyQt5.QtWidgets import (
|
||||||
QWidget,
|
QWidget,
|
||||||
|
@ -15,53 +12,9 @@ from PyQt5.QtWidgets import (
|
||||||
QLabel,
|
QLabel,
|
||||||
)
|
)
|
||||||
|
|
||||||
from rare.utils.qt_requests import QtRequestManager
|
from rare.utils.qt_requests import QtRequests
|
||||||
from rare.widgets.image_widget import ImageWidget
|
from rare.widgets.image_widget import ImageWidget
|
||||||
|
from rare.widgets.loading_widget import LoadingWidget
|
||||||
|
|
||||||
class WaitingSpinner(QLabel):
|
|
||||||
def __init__(self, autostart=False, parent=None):
|
|
||||||
super(WaitingSpinner, self).__init__(parent=parent)
|
|
||||||
self.setObjectName(type(self).__name__)
|
|
||||||
self.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
|
|
||||||
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 __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()
|
|
||||||
|
|
||||||
|
|
||||||
class IconWidget(object):
|
class IconWidget(object):
|
||||||
|
@ -76,7 +29,7 @@ class IconWidget(object):
|
||||||
# on-hover popup
|
# on-hover popup
|
||||||
self.mini_widget = QWidget(parent=widget)
|
self.mini_widget = QWidget(parent=widget)
|
||||||
self.mini_widget.setObjectName(f"{type(self).__name__}MiniWidget")
|
self.mini_widget.setObjectName(f"{type(self).__name__}MiniWidget")
|
||||||
self.mini_widget.setFixedHeight(widget.height() // 4)
|
self.mini_widget.setFixedHeight(int(widget.height() // 3))
|
||||||
|
|
||||||
# game title
|
# game title
|
||||||
self.title_label = QLabel(parent=self.mini_widget)
|
self.title_label = QLabel(parent=self.mini_widget)
|
||||||
|
@ -130,11 +83,11 @@ class IconWidget(object):
|
||||||
widget.setLayout(image_layout)
|
widget.setLayout(image_layout)
|
||||||
|
|
||||||
|
|
||||||
class ShopImageWidget(ImageWidget):
|
class LoadingImageWidget(ImageWidget):
|
||||||
def __init__(self, manager: QtRequestManager, parent=None):
|
def __init__(self, manager: QtRequests, parent=None):
|
||||||
super(ShopImageWidget, self).__init__(parent=parent)
|
super(LoadingImageWidget, self).__init__(parent=parent)
|
||||||
self.ui = IconWidget()
|
self.ui = IconWidget()
|
||||||
self.spinner = WaitingSpinner(parent=self)
|
self.spinner = LoadingWidget(parent=self)
|
||||||
self.spinner.setVisible(False)
|
self.spinner.setVisible(False)
|
||||||
self.manager = manager
|
self.manager = manager
|
||||||
|
|
|
@ -3,26 +3,40 @@ import logging
|
||||||
from PyQt5.QtCore import pyqtSignal, Qt
|
from PyQt5.QtCore import pyqtSignal, Qt
|
||||||
from PyQt5.QtGui import QMouseEvent
|
from PyQt5.QtGui import QMouseEvent
|
||||||
from PyQt5.QtWidgets import QPushButton
|
from PyQt5.QtWidgets import QPushButton
|
||||||
from orjson import orjson
|
|
||||||
|
|
||||||
|
from rare.components.tabs.store.api.debug import DebugDialog
|
||||||
from rare.components.tabs.store.api.models.response import CatalogOfferModel
|
from rare.components.tabs.store.api.models.response import CatalogOfferModel
|
||||||
from rare.shared.image_manager import ImageSize
|
from rare.models.image import ImageSize
|
||||||
from rare.utils.misc import qta_icon
|
from rare.utils.misc import qta_icon
|
||||||
from rare.utils.qt_requests import QtRequestManager
|
from rare.utils.qt_requests import QtRequests
|
||||||
from .api.debug import DebugDialog
|
from .image import LoadingImageWidget
|
||||||
from .image_widget import ShopImageWidget
|
|
||||||
|
|
||||||
logger = logging.getLogger("GameWidgets")
|
logger = logging.getLogger("GameWidgets")
|
||||||
|
|
||||||
|
|
||||||
class GameWidget(ShopImageWidget):
|
class ItemWidget(LoadingImageWidget):
|
||||||
show_info = pyqtSignal(CatalogOfferModel)
|
show_details = pyqtSignal(CatalogOfferModel)
|
||||||
|
|
||||||
def __init__(self, manager: QtRequestManager, catalog_game: CatalogOfferModel = None, parent=None):
|
def __init__(self, manager: QtRequests, catalog_game: CatalogOfferModel = None, parent=None):
|
||||||
super(GameWidget, self).__init__(manager, parent=parent)
|
super(ItemWidget, self).__init__(manager, parent=parent)
|
||||||
|
self.catalog_game = catalog_game
|
||||||
|
|
||||||
|
def mousePressEvent(self, a0: QMouseEvent) -> None:
|
||||||
|
if a0.button() == Qt.LeftButton:
|
||||||
|
a0.accept()
|
||||||
|
self.show_details.emit(self.catalog_game)
|
||||||
|
if a0.button() == Qt.RightButton:
|
||||||
|
a0.accept()
|
||||||
|
print(self.catalog_game.__dict__)
|
||||||
|
dialog = DebugDialog(self.catalog_game.__dict__, self)
|
||||||
|
dialog.show()
|
||||||
|
|
||||||
|
|
||||||
|
class StoreItemWidget(ItemWidget):
|
||||||
|
def __init__(self, manager: QtRequests, catalog_game: CatalogOfferModel = None, parent=None):
|
||||||
|
super(StoreItemWidget, self).__init__(manager, catalog_game, parent=parent)
|
||||||
self.setFixedSize(ImageSize.Wide)
|
self.setFixedSize(ImageSize.Wide)
|
||||||
self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
self.catalog_game = catalog_game
|
|
||||||
if catalog_game:
|
if catalog_game:
|
||||||
self.init_ui(catalog_game)
|
self.init_ui(catalog_game)
|
||||||
|
|
||||||
|
@ -62,26 +76,38 @@ class GameWidget(ShopImageWidget):
|
||||||
# else:
|
# else:
|
||||||
# logger.info(", ".join([img["type"] for img in json_info["keyImages"]]))
|
# logger.info(", ".join([img["type"] for img in json_info["keyImages"]]))
|
||||||
|
|
||||||
def mousePressEvent(self, a0: QMouseEvent) -> None:
|
|
||||||
if a0.button() == Qt.LeftButton:
|
class ResultsItemWidget(ItemWidget):
|
||||||
a0.accept()
|
def __init__(self, manager: QtRequests, catalog_game: CatalogOfferModel, parent=None):
|
||||||
self.show_info.emit(self.catalog_game)
|
super(ResultsItemWidget, self).__init__(manager, catalog_game, parent=parent)
|
||||||
if a0.button() == Qt.RightButton:
|
self.setFixedSize(ImageSize.Normal)
|
||||||
a0.accept()
|
self.ui.setupUi(self)
|
||||||
print(self.catalog_game.__dict__)
|
|
||||||
dialog = DebugDialog(self.catalog_game.__dict__, self)
|
key_images = catalog_game.key_images
|
||||||
dialog.show()
|
self.fetchPixmap(key_images.for_dimensions(self.width(), self.height()).url)
|
||||||
|
|
||||||
|
self.ui.title_label.setText(catalog_game.title)
|
||||||
|
|
||||||
|
price = catalog_game.price.total_price["fmtPrice"]["originalPrice"]
|
||||||
|
discount_price = catalog_game.price.total_price["fmtPrice"]["discountPrice"]
|
||||||
|
self.ui.price_label.setText(f'{price if price != "0" else self.tr("Free")}')
|
||||||
|
if price != discount_price:
|
||||||
|
font = self.ui.price_label.font()
|
||||||
|
font.setStrikeOut(True)
|
||||||
|
self.ui.price_label.setFont(font)
|
||||||
|
self.ui.discount_label.setText(f'{discount_price if discount_price != "0" else self.tr("Free")}')
|
||||||
|
else:
|
||||||
|
self.ui.discount_label.setVisible(False)
|
||||||
|
|
||||||
|
|
||||||
class WishlistWidget(ShopImageWidget):
|
class WishlistItemWidget(ItemWidget):
|
||||||
open_game = pyqtSignal(CatalogOfferModel)
|
show_details = pyqtSignal(CatalogOfferModel)
|
||||||
delete_from_wishlist = pyqtSignal(CatalogOfferModel)
|
delete_from_wishlist = pyqtSignal(CatalogOfferModel)
|
||||||
|
|
||||||
def __init__(self, manager: QtRequestManager, catalog_game: CatalogOfferModel, parent=None):
|
def __init__(self, manager: QtRequests, catalog_game: CatalogOfferModel, parent=None):
|
||||||
super(WishlistWidget, self).__init__(manager, parent=parent)
|
super(WishlistItemWidget, self).__init__(manager, catalog_game, parent=parent)
|
||||||
self.setFixedSize(ImageSize.Wide)
|
self.setFixedSize(ImageSize.Wide)
|
||||||
self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
self.game = catalog_game
|
|
||||||
for attr in catalog_game.custom_attributes:
|
for attr in catalog_game.custom_attributes:
|
||||||
if attr["key"] == "developerName":
|
if attr["key"] == "developerName":
|
||||||
developer = attr["value"]
|
developer = attr["value"]
|
||||||
|
@ -109,17 +135,7 @@ class WishlistWidget(ShopImageWidget):
|
||||||
self.delete_button = QPushButton(self)
|
self.delete_button = QPushButton(self)
|
||||||
self.delete_button.setIcon(icon("mdi.delete", color="white"))
|
self.delete_button.setIcon(icon("mdi.delete", color="white"))
|
||||||
self.delete_button.clicked.connect(
|
self.delete_button.clicked.connect(
|
||||||
lambda: self.delete_from_wishlist.emit(self.game)
|
lambda: self.delete_from_wishlist.emit(self.catalog_game)
|
||||||
)
|
)
|
||||||
self.layout().insertWidget(0, self.delete_button, alignment=Qt.AlignRight)
|
self.layout().insertWidget(0, self.delete_button, alignment=Qt.AlignRight)
|
||||||
|
|
||||||
def mousePressEvent(self, a0: QMouseEvent) -> None:
|
|
||||||
# left button
|
|
||||||
if a0.button() == Qt.LeftButton:
|
|
||||||
a0.accept()
|
|
||||||
self.open_game.emit(self.game)
|
|
||||||
# right
|
|
||||||
if a0.button() == Qt.RightButton:
|
|
||||||
a0.accept()
|
|
||||||
dialog = DebugDialog(self.game.__dict__, self)
|
|
||||||
dialog.show()
|
|
|
@ -1,27 +1,65 @@
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, Qt
|
from PyQt5.QtCore import pyqtSignal, Qt, pyqtSlot
|
||||||
from PyQt5.QtWidgets import QMessageBox, QWidget
|
from PyQt5.QtGui import QShowEvent
|
||||||
|
from PyQt5.QtWidgets import QMessageBox, QWidget, QScrollArea, QFrame, QSizePolicy
|
||||||
|
|
||||||
from rare.ui.components.tabs.store.wishlist import Ui_Wishlist
|
from rare.ui.components.tabs.store.wishlist import Ui_Wishlist
|
||||||
from rare.utils.misc import icon
|
from rare.utils.misc import icon
|
||||||
from rare.widgets.side_tab import SideTabContents
|
|
||||||
from rare.widgets.flow_layout import FlowLayout
|
from rare.widgets.flow_layout import FlowLayout
|
||||||
from .shop_api_core import ShopApiCore
|
from rare.widgets.side_tab import SideTabContents
|
||||||
from .game_widgets import WishlistWidget
|
from rare.widgets.sliding_stack import SlidingStackedWidget
|
||||||
from .api.models.response import WishlistItemModel, CatalogOfferModel
|
from .api.models.response import WishlistItemModel, CatalogOfferModel
|
||||||
|
from .store_api import StoreAPI
|
||||||
|
from .widgets.details import DetailsWidget
|
||||||
|
from .widgets.items import WishlistItemWidget
|
||||||
|
|
||||||
|
|
||||||
class Wishlist(QWidget, SideTabContents):
|
class WishlistPage(SlidingStackedWidget, SideTabContents):
|
||||||
show_game_info = pyqtSignal(CatalogOfferModel)
|
def __init__(self, api: StoreAPI, parent=None):
|
||||||
|
super(WishlistPage, self).__init__(parent=parent)
|
||||||
|
self.implements_scrollarea = True
|
||||||
|
|
||||||
|
self.wishlist_widget = WishlistWidget(api, parent=self)
|
||||||
|
self.wishlist_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
|
self.wishlist_widget.set_title.connect(self.set_title)
|
||||||
|
self.wishlist_widget.show_details.connect(self.show_details)
|
||||||
|
|
||||||
|
self.details_widget = DetailsWidget([], api, parent=self)
|
||||||
|
self.details_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
|
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)
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def show_main(self):
|
||||||
|
self.slideInWidget(self.wishlist_widget)
|
||||||
|
|
||||||
|
@pyqtSlot(object)
|
||||||
|
def show_details(self, game: CatalogOfferModel):
|
||||||
|
self.details_widget.update_game(game)
|
||||||
|
self.slideInWidget(self.details_scroll)
|
||||||
|
|
||||||
|
|
||||||
|
class WishlistWidget(QWidget, SideTabContents):
|
||||||
|
show_details = pyqtSignal(CatalogOfferModel)
|
||||||
update_wishlist_signal = pyqtSignal()
|
update_wishlist_signal = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, api_core: ShopApiCore, parent=None):
|
def __init__(self, api: StoreAPI, parent=None):
|
||||||
super(Wishlist, self).__init__(parent=parent)
|
super(WishlistWidget, self).__init__(parent=parent)
|
||||||
self.implements_scrollarea = True
|
self.implements_scrollarea = True
|
||||||
self.api_core = api_core
|
self.api = api
|
||||||
self.ui = Ui_Wishlist()
|
self.ui = Ui_Wishlist()
|
||||||
self.ui.setupUi(self)
|
self.ui.setupUi(self)
|
||||||
|
self.ui.main_layout.setContentsMargins(0, 0, 3, 0)
|
||||||
self.setEnabled(False)
|
self.setEnabled(False)
|
||||||
self.wishlist = []
|
self.wishlist = []
|
||||||
self.widgets = []
|
self.widgets = []
|
||||||
|
@ -37,12 +75,16 @@ class Wishlist(QWidget, SideTabContents):
|
||||||
lambda: self.sort_wishlist(sort=self.ui.sort_cb.currentIndex())
|
lambda: self.sort_wishlist(sort=self.ui.sort_cb.currentIndex())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def showEvent(self, a0: QShowEvent) -> None:
|
||||||
|
self.update_wishlist()
|
||||||
|
return super().showEvent(a0)
|
||||||
|
|
||||||
def update_wishlist(self):
|
def update_wishlist(self):
|
||||||
self.setEnabled(False)
|
self.setEnabled(False)
|
||||||
self.api_core.get_wishlist(self.set_wishlist)
|
self.api.get_wishlist(self.set_wishlist)
|
||||||
|
|
||||||
def delete_from_wishlist(self, game: CatalogOfferModel):
|
def delete_from_wishlist(self, game: CatalogOfferModel):
|
||||||
self.api_core.remove_from_wishlist(
|
self.api.remove_from_wishlist(
|
||||||
game.namespace,
|
game.namespace,
|
||||||
game.id,
|
game.id,
|
||||||
lambda success: self.update_wishlist()
|
lambda success: self.update_wishlist()
|
||||||
|
@ -71,7 +113,7 @@ class Wishlist(QWidget, SideTabContents):
|
||||||
self.ui.no_games_label.setVisible(False)
|
self.ui.no_games_label.setVisible(False)
|
||||||
|
|
||||||
def sort_wishlist(self, sort=0):
|
def sort_wishlist(self, sort=0):
|
||||||
widgets = self.ui.list_container.findChildren(WishlistWidget, options=Qt.FindDirectChildrenOnly)
|
widgets = self.ui.list_container.findChildren(WishlistItemWidget, options=Qt.FindDirectChildrenOnly)
|
||||||
for w in widgets:
|
for w in widgets:
|
||||||
self.ui.list_container.layout().removeWidget(w)
|
self.ui.list_container.layout().removeWidget(w)
|
||||||
|
|
||||||
|
@ -113,8 +155,8 @@ class Wishlist(QWidget, SideTabContents):
|
||||||
self.ui.no_games_label.setVisible(False)
|
self.ui.no_games_label.setVisible(False)
|
||||||
|
|
||||||
for game in wishlist:
|
for game in wishlist:
|
||||||
w = WishlistWidget(self.api_core.cached_manager, game.offer, self.ui.list_container)
|
w = WishlistItemWidget(self.api.cached_manager, game.offer, self.ui.list_container)
|
||||||
w.open_game.connect(self.show_game_info)
|
w.show_details.connect(self.show_details)
|
||||||
w.delete_from_wishlist.connect(self.delete_from_wishlist)
|
w.delete_from_wishlist.connect(self.delete_from_wishlist)
|
||||||
self.widgets.append(w)
|
self.widgets.append(w)
|
||||||
self.list_layout.addWidget(w)
|
self.list_layout.addWidget(w)
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/store/shop_game_info.ui'
|
# Form implementation generated from reading ui file 'rare/ui/components/tabs/store/details.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.15.9
|
# Created by: PyQt5 UI code generator 5.15.10
|
||||||
#
|
#
|
||||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
# 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.
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
@ -11,24 +11,29 @@
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
class Ui_ShopInfo(object):
|
class Ui_DetailsWidget(object):
|
||||||
def setupUi(self, ShopInfo):
|
def setupUi(self, DetailsWidget):
|
||||||
ShopInfo.setObjectName("ShopInfo")
|
DetailsWidget.setObjectName("DetailsWidget")
|
||||||
ShopInfo.resize(443, 347)
|
DetailsWidget.resize(414, 343)
|
||||||
ShopInfo.setWindowTitle("ShopGameInfo")
|
DetailsWidget.setWindowTitle("DetailsWidget")
|
||||||
self.main_layout = QtWidgets.QHBoxLayout(ShopInfo)
|
self.main_layout = QtWidgets.QHBoxLayout(DetailsWidget)
|
||||||
self.main_layout.setObjectName("main_layout")
|
self.main_layout.setObjectName("main_layout")
|
||||||
self.left_layout = QtWidgets.QVBoxLayout()
|
self.left_layout = QtWidgets.QVBoxLayout()
|
||||||
self.left_layout.setObjectName("left_layout")
|
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.main_layout.addLayout(self.left_layout)
|
||||||
self.right_layout = QtWidgets.QVBoxLayout()
|
self.right_layout = QtWidgets.QVBoxLayout()
|
||||||
self.right_layout.setObjectName("right_layout")
|
self.right_layout.setObjectName("right_layout")
|
||||||
self.info_layout = QtWidgets.QFormLayout()
|
self.info_layout = QtWidgets.QFormLayout()
|
||||||
|
self.info_layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
|
||||||
self.info_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.info_layout.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.info_layout.setContentsMargins(6, 6, 6, 6)
|
self.info_layout.setContentsMargins(6, 6, 6, 6)
|
||||||
self.info_layout.setSpacing(12)
|
self.info_layout.setSpacing(12)
|
||||||
self.info_layout.setObjectName("info_layout")
|
self.info_layout.setObjectName("info_layout")
|
||||||
self.title_label = QtWidgets.QLabel(ShopInfo)
|
self.title_label = QtWidgets.QLabel(DetailsWidget)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setBold(True)
|
font.setBold(True)
|
||||||
font.setWeight(75)
|
font.setWeight(75)
|
||||||
|
@ -36,12 +41,12 @@ class Ui_ShopInfo(object):
|
||||||
self.title_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.title_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.title_label.setObjectName("title_label")
|
self.title_label.setObjectName("title_label")
|
||||||
self.info_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.title_label)
|
self.info_layout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.title_label)
|
||||||
self.title = QtWidgets.QLabel(ShopInfo)
|
self.title = QtWidgets.QLabel(DetailsWidget)
|
||||||
self.title.setText("title")
|
self.title.setText("title")
|
||||||
self.title.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
self.title.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||||
self.title.setObjectName("title")
|
self.title.setObjectName("title")
|
||||||
self.info_layout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.title)
|
self.info_layout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.title)
|
||||||
self.developer_label = QtWidgets.QLabel(ShopInfo)
|
self.developer_label = QtWidgets.QLabel(DetailsWidget)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setBold(True)
|
font.setBold(True)
|
||||||
font.setWeight(75)
|
font.setWeight(75)
|
||||||
|
@ -49,12 +54,12 @@ class Ui_ShopInfo(object):
|
||||||
self.developer_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.developer_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.developer_label.setObjectName("developer_label")
|
self.developer_label.setObjectName("developer_label")
|
||||||
self.info_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.developer_label)
|
self.info_layout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.developer_label)
|
||||||
self.dev = QtWidgets.QLabel(ShopInfo)
|
self.dev = QtWidgets.QLabel(DetailsWidget)
|
||||||
self.dev.setText("dev")
|
self.dev.setText("dev")
|
||||||
self.dev.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
self.dev.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||||
self.dev.setObjectName("dev")
|
self.dev.setObjectName("dev")
|
||||||
self.info_layout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.dev)
|
self.info_layout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.dev)
|
||||||
self.status_label = QtWidgets.QLabel(ShopInfo)
|
self.status_label = QtWidgets.QLabel(DetailsWidget)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setBold(True)
|
font.setBold(True)
|
||||||
font.setWeight(75)
|
font.setWeight(75)
|
||||||
|
@ -62,10 +67,10 @@ class Ui_ShopInfo(object):
|
||||||
self.status_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.status_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.status_label.setObjectName("status_label")
|
self.status_label.setObjectName("status_label")
|
||||||
self.info_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.status_label)
|
self.info_layout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.status_label)
|
||||||
self.owned_label = QtWidgets.QLabel(ShopInfo)
|
self.owned_label = QtWidgets.QLabel(DetailsWidget)
|
||||||
self.owned_label.setObjectName("owned_label")
|
self.owned_label.setObjectName("owned_label")
|
||||||
self.info_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.owned_label)
|
self.info_layout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.owned_label)
|
||||||
self.price_label = QtWidgets.QLabel(ShopInfo)
|
self.price_label = QtWidgets.QLabel(DetailsWidget)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setBold(True)
|
font.setBold(True)
|
||||||
font.setWeight(75)
|
font.setWeight(75)
|
||||||
|
@ -73,7 +78,7 @@ class Ui_ShopInfo(object):
|
||||||
self.price_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.price_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.price_label.setObjectName("price_label")
|
self.price_label.setObjectName("price_label")
|
||||||
self.info_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.price_label)
|
self.info_layout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.price_label)
|
||||||
self.price_widget = QtWidgets.QWidget(ShopInfo)
|
self.price_widget = QtWidgets.QWidget(DetailsWidget)
|
||||||
self.price_widget.setObjectName("price_widget")
|
self.price_widget.setObjectName("price_widget")
|
||||||
self.horizontalLayout = QtWidgets.QHBoxLayout(self.price_widget)
|
self.horizontalLayout = QtWidgets.QHBoxLayout(self.price_widget)
|
||||||
self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
|
self.horizontalLayout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
|
||||||
|
@ -89,7 +94,7 @@ class Ui_ShopInfo(object):
|
||||||
self.discount_price.setObjectName("discount_price")
|
self.discount_price.setObjectName("discount_price")
|
||||||
self.horizontalLayout.addWidget(self.discount_price)
|
self.horizontalLayout.addWidget(self.discount_price)
|
||||||
self.info_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.price_widget)
|
self.info_layout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.price_widget)
|
||||||
self.tags_label = QtWidgets.QLabel(ShopInfo)
|
self.tags_label = QtWidgets.QLabel(DetailsWidget)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setBold(True)
|
font.setBold(True)
|
||||||
font.setWeight(75)
|
font.setWeight(75)
|
||||||
|
@ -97,11 +102,11 @@ class Ui_ShopInfo(object):
|
||||||
self.tags_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.tags_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.tags_label.setObjectName("tags_label")
|
self.tags_label.setObjectName("tags_label")
|
||||||
self.info_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.tags_label)
|
self.info_layout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.tags_label)
|
||||||
self.tags = QtWidgets.QLabel(ShopInfo)
|
self.tags = QtWidgets.QLabel(DetailsWidget)
|
||||||
self.tags.setText("tags")
|
self.tags.setText("tags")
|
||||||
self.tags.setObjectName("tags")
|
self.tags.setObjectName("tags")
|
||||||
self.info_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.tags)
|
self.info_layout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.tags)
|
||||||
self.links_label = QtWidgets.QLabel(ShopInfo)
|
self.links_label = QtWidgets.QLabel(DetailsWidget)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setBold(True)
|
font.setBold(True)
|
||||||
font.setWeight(75)
|
font.setWeight(75)
|
||||||
|
@ -109,7 +114,7 @@ class Ui_ShopInfo(object):
|
||||||
self.links_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.links_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.links_label.setObjectName("links_label")
|
self.links_label.setObjectName("links_label")
|
||||||
self.info_layout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.links_label)
|
self.info_layout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.links_label)
|
||||||
self.social_group = QtWidgets.QWidget(ShopInfo)
|
self.social_group = QtWidgets.QWidget(DetailsWidget)
|
||||||
self.social_group.setMinimumSize(QtCore.QSize(250, 0))
|
self.social_group.setMinimumSize(QtCore.QSize(250, 0))
|
||||||
self.social_group.setObjectName("social_group")
|
self.social_group.setObjectName("social_group")
|
||||||
self.social_layout = QtWidgets.QHBoxLayout(self.social_group)
|
self.social_layout = QtWidgets.QHBoxLayout(self.social_group)
|
||||||
|
@ -117,7 +122,7 @@ class Ui_ShopInfo(object):
|
||||||
self.social_layout.setContentsMargins(0, 0, 0, 0)
|
self.social_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
self.social_layout.setObjectName("social_layout")
|
self.social_layout.setObjectName("social_layout")
|
||||||
self.info_layout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.social_group)
|
self.info_layout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.social_group)
|
||||||
self.actions_label = QtWidgets.QLabel(ShopInfo)
|
self.actions_label = QtWidgets.QLabel(DetailsWidget)
|
||||||
font = QtGui.QFont()
|
font = QtGui.QFont()
|
||||||
font.setBold(True)
|
font.setBold(True)
|
||||||
font.setWeight(75)
|
font.setWeight(75)
|
||||||
|
@ -125,7 +130,7 @@ class Ui_ShopInfo(object):
|
||||||
self.actions_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
self.actions_label.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
|
||||||
self.actions_label.setObjectName("actions_label")
|
self.actions_label.setObjectName("actions_label")
|
||||||
self.info_layout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.actions_label)
|
self.info_layout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.actions_label)
|
||||||
self.buttons_widget = QtWidgets.QWidget(ShopInfo)
|
self.buttons_widget = QtWidgets.QWidget(DetailsWidget)
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||||
sizePolicy.setHorizontalStretch(0)
|
sizePolicy.setHorizontalStretch(0)
|
||||||
sizePolicy.setVerticalStretch(0)
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
@ -146,7 +151,7 @@ class Ui_ShopInfo(object):
|
||||||
self.button_layout.addWidget(self.wishlist_button)
|
self.button_layout.addWidget(self.wishlist_button)
|
||||||
self.info_layout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.buttons_widget)
|
self.info_layout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.buttons_widget)
|
||||||
self.right_layout.addLayout(self.info_layout)
|
self.right_layout.addLayout(self.info_layout)
|
||||||
self.requirements_frame = QtWidgets.QFrame(ShopInfo)
|
self.requirements_frame = QtWidgets.QFrame(DetailsWidget)
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
||||||
sizePolicy.setHorizontalStretch(0)
|
sizePolicy.setHorizontalStretch(0)
|
||||||
sizePolicy.setVerticalStretch(0)
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
@ -159,55 +164,34 @@ class Ui_ShopInfo(object):
|
||||||
self.requirements_layout.setContentsMargins(0, 0, 0, 0)
|
self.requirements_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
self.requirements_layout.setObjectName("requirements_layout")
|
self.requirements_layout.setObjectName("requirements_layout")
|
||||||
self.right_layout.addWidget(self.requirements_frame)
|
self.right_layout.addWidget(self.requirements_frame)
|
||||||
self.description_group = QtWidgets.QGroupBox(ShopInfo)
|
self.description_label = QtWidgets.QTextBrowser(DetailsWidget)
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.description_group.sizePolicy().hasHeightForWidth())
|
|
||||||
self.description_group.setSizePolicy(sizePolicy)
|
|
||||||
self.description_group.setFlat(False)
|
|
||||||
self.description_group.setObjectName("description_group")
|
|
||||||
self.description_layout = QtWidgets.QVBoxLayout(self.description_group)
|
|
||||||
self.description_layout.setObjectName("description_layout")
|
|
||||||
self.description_label = QtWidgets.QLabel(self.description_group)
|
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.description_label.sizePolicy().hasHeightForWidth())
|
|
||||||
self.description_label.setSizePolicy(sizePolicy)
|
|
||||||
self.description_label.setText("error")
|
|
||||||
self.description_label.setTextFormat(QtCore.Qt.MarkdownText)
|
|
||||||
self.description_label.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
|
|
||||||
self.description_label.setWordWrap(True)
|
|
||||||
self.description_label.setOpenExternalLinks(True)
|
self.description_label.setOpenExternalLinks(True)
|
||||||
self.description_label.setObjectName("description_label")
|
self.description_label.setObjectName("description_label")
|
||||||
self.description_layout.addWidget(self.description_label)
|
self.right_layout.addWidget(self.description_label)
|
||||||
self.right_layout.addWidget(self.description_group)
|
|
||||||
self.main_layout.addLayout(self.right_layout)
|
self.main_layout.addLayout(self.right_layout)
|
||||||
self.main_layout.setStretch(1, 1)
|
self.main_layout.setStretch(1, 1)
|
||||||
|
|
||||||
self.retranslateUi(ShopInfo)
|
self.retranslateUi(DetailsWidget)
|
||||||
|
|
||||||
def retranslateUi(self, ShopInfo):
|
def retranslateUi(self, DetailsWidget):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
self.title_label.setText(_translate("ShopInfo", "Title"))
|
self.title_label.setText(_translate("DetailsWidget", "Title"))
|
||||||
self.developer_label.setText(_translate("ShopInfo", "Developer"))
|
self.developer_label.setText(_translate("DetailsWidget", "Developer"))
|
||||||
self.status_label.setText(_translate("ShopInfo", "Status"))
|
self.status_label.setText(_translate("DetailsWidget", "Status"))
|
||||||
self.owned_label.setText(_translate("ShopInfo", "You already own this game"))
|
self.owned_label.setText(_translate("DetailsWidget", "You already own this game"))
|
||||||
self.price_label.setText(_translate("ShopInfo", "Price"))
|
self.price_label.setText(_translate("DetailsWidget", "Price"))
|
||||||
self.tags_label.setText(_translate("ShopInfo", "Tags"))
|
self.tags_label.setText(_translate("DetailsWidget", "Tags"))
|
||||||
self.links_label.setText(_translate("ShopInfo", "Links"))
|
self.links_label.setText(_translate("DetailsWidget", "Links"))
|
||||||
self.actions_label.setText(_translate("ShopInfo", "Actions"))
|
self.actions_label.setText(_translate("DetailsWidget", "Actions"))
|
||||||
self.open_store_button.setText(_translate("ShopInfo", "Buy in Epic Games Store"))
|
self.open_store_button.setText(_translate("DetailsWidget", "Buy in Epic Games Store"))
|
||||||
self.wishlist_button.setText(_translate("ShopInfo", "Add to wishlist"))
|
self.wishlist_button.setText(_translate("DetailsWidget", "Add to wishlist"))
|
||||||
self.description_group.setTitle(_translate("ShopInfo", "Description"))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import sys
|
import sys
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
ShopInfo = QtWidgets.QWidget()
|
DetailsWidget = QtWidgets.QWidget()
|
||||||
ui = Ui_ShopInfo()
|
ui = Ui_DetailsWidget()
|
||||||
ui.setupUi(ShopInfo)
|
ui.setupUi(DetailsWidget)
|
||||||
ShopInfo.show()
|
DetailsWidget.show()
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
|
@ -1,26 +1,37 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ui version="4.0">
|
<ui version="4.0">
|
||||||
<class>ShopInfo</class>
|
<class>DetailsWidget</class>
|
||||||
<widget class="QWidget" name="ShopInfo">
|
<widget class="QWidget" name="DetailsWidget">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>443</width>
|
<width>414</width>
|
||||||
<height>347</height>
|
<height>343</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string notr="true">ShopGameInfo</string>
|
<string notr="true">DetailsWidget</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QHBoxLayout" name="main_layout" stretch="0,1">
|
<layout class="QHBoxLayout" name="main_layout" stretch="0,1">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="left_layout"/>
|
<layout class="QVBoxLayout" name="left_layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="back_button">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="right_layout">
|
<layout class="QVBoxLayout" name="right_layout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QFormLayout" name="info_layout">
|
<layout class="QFormLayout" name="info_layout">
|
||||||
|
<property name="sizeConstraint">
|
||||||
|
<enum>QLayout::SetFixedSize</enum>
|
||||||
|
</property>
|
||||||
<property name="labelAlignment">
|
<property name="labelAlignment">
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||||
</property>
|
</property>
|
||||||
|
@ -339,46 +350,10 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="description_group">
|
<widget class="QTextBrowser" name="description_label">
|
||||||
<property name="sizePolicy">
|
<property name="openExternalLinks">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
<bool>true</bool>
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="title">
|
|
||||||
<string>Description</string>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="description_layout">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="description_label">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">error</string>
|
|
||||||
</property>
|
|
||||||
<property name="textFormat">
|
|
||||||
<enum>Qt::MarkdownText</enum>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="openExternalLinks">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
|
@ -1,8 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/store/store.ui'
|
# Form implementation generated from reading ui file 'rare/ui/components/tabs/store/landing.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.15.9
|
# Created by: PyQt5 UI code generator 5.15.10
|
||||||
#
|
#
|
||||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
# 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.
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
@ -11,14 +11,22 @@
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
class Ui_ShopWidget(object):
|
class Ui_LandingWidget(object):
|
||||||
def setupUi(self, ShopWidget):
|
def setupUi(self, LandingWidget):
|
||||||
ShopWidget.setObjectName("ShopWidget")
|
LandingWidget.setObjectName("LandingWidget")
|
||||||
ShopWidget.resize(788, 662)
|
LandingWidget.resize(788, 662)
|
||||||
ShopWidget.setWindowTitle("Store")
|
LandingWidget.setWindowTitle("LandingWidget")
|
||||||
self.main_layout = QtWidgets.QGridLayout(ShopWidget)
|
self.main_layout = QtWidgets.QHBoxLayout(LandingWidget)
|
||||||
self.main_layout.setObjectName("main_layout")
|
self.main_layout.setObjectName("main_layout")
|
||||||
self.filter_scrollarea = QtWidgets.QScrollArea(ShopWidget)
|
self.left_layout = QtWidgets.QVBoxLayout()
|
||||||
|
self.left_layout.setObjectName("left_layout")
|
||||||
|
self.main_layout.addLayout(self.left_layout)
|
||||||
|
self.right_layout = QtWidgets.QVBoxLayout()
|
||||||
|
self.right_layout.setObjectName("right_layout")
|
||||||
|
self.reset_button = QtWidgets.QPushButton(LandingWidget)
|
||||||
|
self.reset_button.setObjectName("reset_button")
|
||||||
|
self.right_layout.addWidget(self.reset_button)
|
||||||
|
self.filter_scrollarea = QtWidgets.QScrollArea(LandingWidget)
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
|
||||||
sizePolicy.setHorizontalStretch(0)
|
sizePolicy.setHorizontalStretch(0)
|
||||||
sizePolicy.setVerticalStretch(0)
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
@ -89,81 +97,34 @@ class Ui_ShopWidget(object):
|
||||||
self.others_layout.setObjectName("others_layout")
|
self.others_layout.setObjectName("others_layout")
|
||||||
self.filter_container_layout.addWidget(self.others_group)
|
self.filter_container_layout.addWidget(self.others_group)
|
||||||
self.filter_scrollarea.setWidget(self.filter_container)
|
self.filter_scrollarea.setWidget(self.filter_container)
|
||||||
self.main_layout.addWidget(self.filter_scrollarea, 1, 1, 1, 1)
|
self.right_layout.addWidget(self.filter_scrollarea)
|
||||||
self.reset_button = QtWidgets.QPushButton(ShopWidget)
|
self.main_layout.addLayout(self.right_layout)
|
||||||
self.reset_button.setObjectName("reset_button")
|
self.main_layout.setStretch(0, 1)
|
||||||
self.main_layout.addWidget(self.reset_button, 0, 1, 1, 1)
|
|
||||||
self.games_scrollarea = QtWidgets.QScrollArea(ShopWidget)
|
|
||||||
self.games_scrollarea.setFrameShape(QtWidgets.QFrame.NoFrame)
|
|
||||||
self.games_scrollarea.setFrameShadow(QtWidgets.QFrame.Plain)
|
|
||||||
self.games_scrollarea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
|
|
||||||
self.games_scrollarea.setWidgetResizable(True)
|
|
||||||
self.games_scrollarea.setObjectName("games_scrollarea")
|
|
||||||
self.games_container = QtWidgets.QWidget()
|
|
||||||
self.games_container.setGeometry(QtCore.QRect(0, 0, 628, 618))
|
|
||||||
self.games_container.setObjectName("games_container")
|
|
||||||
self.games_container_layout = QtWidgets.QVBoxLayout(self.games_container)
|
|
||||||
self.games_container_layout.setContentsMargins(0, 0, 3, 0)
|
|
||||||
self.games_container_layout.setObjectName("games_container_layout")
|
|
||||||
self.free_scrollarea = QtWidgets.QScrollArea(self.games_container)
|
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.free_scrollarea.sizePolicy().hasHeightForWidth())
|
|
||||||
self.free_scrollarea.setSizePolicy(sizePolicy)
|
|
||||||
self.free_scrollarea.setFrameShape(QtWidgets.QFrame.NoFrame)
|
|
||||||
self.free_scrollarea.setFrameShadow(QtWidgets.QFrame.Plain)
|
|
||||||
self.free_scrollarea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
|
||||||
self.free_scrollarea.setWidgetResizable(True)
|
|
||||||
self.free_scrollarea.setObjectName("free_scrollarea")
|
|
||||||
self.free_container = QtWidgets.QWidget()
|
|
||||||
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)
|
|
||||||
self.free_container_layout.setObjectName("free_container_layout")
|
|
||||||
self.free_scrollarea.setWidget(self.free_container)
|
|
||||||
self.games_container_layout.addWidget(self.free_scrollarea)
|
|
||||||
self.discounts_group = QtWidgets.QGroupBox(self.games_container)
|
|
||||||
self.discounts_group.setObjectName("discounts_group")
|
|
||||||
self.games_container_layout.addWidget(self.discounts_group)
|
|
||||||
self.games_group = QtWidgets.QGroupBox(self.games_container)
|
|
||||||
self.games_group.setObjectName("games_group")
|
|
||||||
self.games_container_layout.addWidget(self.games_group)
|
|
||||||
self.games_scrollarea.setWidget(self.games_container)
|
|
||||||
self.main_layout.addWidget(self.games_scrollarea, 1, 0, 1, 1)
|
|
||||||
|
|
||||||
self.retranslateUi(ShopWidget)
|
self.retranslateUi(LandingWidget)
|
||||||
|
|
||||||
def retranslateUi(self, ShopWidget):
|
def retranslateUi(self, LandingWidget):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
self.price_group.setTitle(_translate("ShopWidget", "Price"))
|
self.reset_button.setText(_translate("LandingWidget", "Reset filters"))
|
||||||
self.none_price.setText(_translate("ShopWidget", "None"))
|
self.price_group.setTitle(_translate("LandingWidget", "Price"))
|
||||||
self.free_button.setText(_translate("ShopWidget", "Free"))
|
self.none_price.setText(_translate("LandingWidget", "None"))
|
||||||
self.under10.setText(_translate("ShopWidget", "Under 10"))
|
self.free_button.setText(_translate("LandingWidget", "Free"))
|
||||||
self.under20.setText(_translate("ShopWidget", "Under 20"))
|
self.under10.setText(_translate("LandingWidget", "Under 10"))
|
||||||
self.under30.setText(_translate("ShopWidget", "Under 30"))
|
self.under20.setText(_translate("LandingWidget", "Under 20"))
|
||||||
self.above.setText(_translate("ShopWidget", "14.99 and above"))
|
self.under30.setText(_translate("LandingWidget", "Under 30"))
|
||||||
self.on_discount.setText(_translate("ShopWidget", "Discount"))
|
self.above.setText(_translate("LandingWidget", "14.99 and above"))
|
||||||
self.platform_group.setTitle(_translate("ShopWidget", "Platform"))
|
self.on_discount.setText(_translate("LandingWidget", "Discount"))
|
||||||
self.genre_group.setTitle(_translate("ShopWidget", "Genre"))
|
self.platform_group.setTitle(_translate("LandingWidget", "Platform"))
|
||||||
self.type_group.setTitle(_translate("ShopWidget", "Type"))
|
self.genre_group.setTitle(_translate("LandingWidget", "Genre"))
|
||||||
self.others_group.setTitle(_translate("ShopWidget", "Other tags"))
|
self.type_group.setTitle(_translate("LandingWidget", "Type"))
|
||||||
self.reset_button.setText(_translate("ShopWidget", "Reset filters"))
|
self.others_group.setTitle(_translate("LandingWidget", "Other tags"))
|
||||||
self.discounts_group.setTitle(_translate("ShopWidget", "Discounts from your wishlist"))
|
|
||||||
self.games_group.setTitle(_translate("ShopWidget", "Games"))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import sys
|
import sys
|
||||||
app = QtWidgets.QApplication(sys.argv)
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
ShopWidget = QtWidgets.QWidget()
|
LandingWidget = QtWidgets.QWidget()
|
||||||
ui = Ui_ShopWidget()
|
ui = Ui_LandingWidget()
|
||||||
ui.setupUi(ShopWidget)
|
ui.setupUi(LandingWidget)
|
||||||
ShopWidget.show()
|
LandingWidget.show()
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
183
rare/ui/components/tabs/store/landing.ui
Normal file
183
rare/ui/components/tabs/store/landing.ui
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>LandingWidget</class>
|
||||||
|
<widget class="QWidget" name="LandingWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>788</width>
|
||||||
|
<height>662</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true">LandingWidget</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="main_layout" stretch="1,0">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="left_layout"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="right_layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="reset_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reset filters</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="filter_scrollarea">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="filter_container">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<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>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="price_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Price</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="price_layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="none_price">
|
||||||
|
<property name="text">
|
||||||
|
<string>None</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="free_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Free</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="under10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Under 10</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="under20">
|
||||||
|
<property name="text">
|
||||||
|
<string>Under 20</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="under30">
|
||||||
|
<property name="text">
|
||||||
|
<string>Under 30</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="above">
|
||||||
|
<property name="text">
|
||||||
|
<string>14.99 and above</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="on_discount">
|
||||||
|
<property name="text">
|
||||||
|
<string>Discount</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="platform_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Platform</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="platfrom_layout"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="genre_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Genre</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="genre_layout"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="type_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Type</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="type_layout"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="others_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Other tags</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="others_layout"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
130
rare/ui/components/tabs/store/search.py
Normal file
130
rare/ui/components/tabs/store/search.py
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Form implementation generated from reading ui file 'rare/ui/components/tabs/store/search.ui'
|
||||||
|
#
|
||||||
|
# Created by: PyQt5 UI code generator 5.15.10
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
|
class Ui_SearchWidget(object):
|
||||||
|
def setupUi(self, SearchWidget):
|
||||||
|
SearchWidget.setObjectName("SearchWidget")
|
||||||
|
SearchWidget.resize(491, 382)
|
||||||
|
SearchWidget.setWindowTitle("SearchWidget")
|
||||||
|
self.main_layout = QtWidgets.QHBoxLayout(SearchWidget)
|
||||||
|
self.main_layout.setObjectName("main_layout")
|
||||||
|
self.left_layout = QtWidgets.QVBoxLayout()
|
||||||
|
self.left_layout.setObjectName("left_layout")
|
||||||
|
self.main_layout.addLayout(self.left_layout)
|
||||||
|
self.right_layout = QtWidgets.QVBoxLayout()
|
||||||
|
self.right_layout.setObjectName("right_layout")
|
||||||
|
self.reset_button = QtWidgets.QPushButton(SearchWidget)
|
||||||
|
self.reset_button.setObjectName("reset_button")
|
||||||
|
self.right_layout.addWidget(self.reset_button)
|
||||||
|
self.filter_scrollarea = QtWidgets.QScrollArea(SearchWidget)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Expanding)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.filter_scrollarea.sizePolicy().hasHeightForWidth())
|
||||||
|
self.filter_scrollarea.setSizePolicy(sizePolicy)
|
||||||
|
self.filter_scrollarea.setFrameShape(QtWidgets.QFrame.NoFrame)
|
||||||
|
self.filter_scrollarea.setFrameShadow(QtWidgets.QFrame.Plain)
|
||||||
|
self.filter_scrollarea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
|
||||||
|
self.filter_scrollarea.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustToContents)
|
||||||
|
self.filter_scrollarea.setWidgetResizable(True)
|
||||||
|
self.filter_scrollarea.setObjectName("filter_scrollarea")
|
||||||
|
self.filter_container = QtWidgets.QWidget()
|
||||||
|
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)
|
||||||
|
self.filter_container_layout.setObjectName("filter_container_layout")
|
||||||
|
self.price_group = QtWidgets.QGroupBox(self.filter_container)
|
||||||
|
self.price_group.setObjectName("price_group")
|
||||||
|
self.price_layout = QtWidgets.QVBoxLayout(self.price_group)
|
||||||
|
self.price_layout.setObjectName("price_layout")
|
||||||
|
self.none_price = QtWidgets.QRadioButton(self.price_group)
|
||||||
|
self.none_price.setChecked(True)
|
||||||
|
self.none_price.setObjectName("none_price")
|
||||||
|
self.price_layout.addWidget(self.none_price)
|
||||||
|
self.free_button = QtWidgets.QRadioButton(self.price_group)
|
||||||
|
self.free_button.setObjectName("free_button")
|
||||||
|
self.price_layout.addWidget(self.free_button)
|
||||||
|
self.under10 = QtWidgets.QRadioButton(self.price_group)
|
||||||
|
self.under10.setObjectName("under10")
|
||||||
|
self.price_layout.addWidget(self.under10)
|
||||||
|
self.under20 = QtWidgets.QRadioButton(self.price_group)
|
||||||
|
self.under20.setObjectName("under20")
|
||||||
|
self.price_layout.addWidget(self.under20)
|
||||||
|
self.under30 = QtWidgets.QRadioButton(self.price_group)
|
||||||
|
self.under30.setObjectName("under30")
|
||||||
|
self.price_layout.addWidget(self.under30)
|
||||||
|
self.above = QtWidgets.QRadioButton(self.price_group)
|
||||||
|
self.above.setObjectName("above")
|
||||||
|
self.price_layout.addWidget(self.above)
|
||||||
|
self.on_discount = QtWidgets.QCheckBox(self.price_group)
|
||||||
|
self.on_discount.setObjectName("on_discount")
|
||||||
|
self.price_layout.addWidget(self.on_discount)
|
||||||
|
self.filter_container_layout.addWidget(self.price_group)
|
||||||
|
self.platform_group = QtWidgets.QGroupBox(self.filter_container)
|
||||||
|
self.platform_group.setObjectName("platform_group")
|
||||||
|
self.platfrom_layout = QtWidgets.QVBoxLayout(self.platform_group)
|
||||||
|
self.platfrom_layout.setObjectName("platfrom_layout")
|
||||||
|
self.filter_container_layout.addWidget(self.platform_group)
|
||||||
|
self.genre_group = QtWidgets.QGroupBox(self.filter_container)
|
||||||
|
self.genre_group.setObjectName("genre_group")
|
||||||
|
self.genre_layout = QtWidgets.QVBoxLayout(self.genre_group)
|
||||||
|
self.genre_layout.setObjectName("genre_layout")
|
||||||
|
self.filter_container_layout.addWidget(self.genre_group)
|
||||||
|
self.type_group = QtWidgets.QGroupBox(self.filter_container)
|
||||||
|
self.type_group.setObjectName("type_group")
|
||||||
|
self.type_layout = QtWidgets.QVBoxLayout(self.type_group)
|
||||||
|
self.type_layout.setObjectName("type_layout")
|
||||||
|
self.filter_container_layout.addWidget(self.type_group)
|
||||||
|
self.others_group = QtWidgets.QGroupBox(self.filter_container)
|
||||||
|
self.others_group.setObjectName("others_group")
|
||||||
|
self.others_layout = QtWidgets.QVBoxLayout(self.others_group)
|
||||||
|
self.others_layout.setObjectName("others_layout")
|
||||||
|
self.filter_container_layout.addWidget(self.others_group)
|
||||||
|
self.filter_scrollarea.setWidget(self.filter_container)
|
||||||
|
self.right_layout.addWidget(self.filter_scrollarea)
|
||||||
|
self.main_layout.addLayout(self.right_layout)
|
||||||
|
self.main_layout.setStretch(0, 1)
|
||||||
|
|
||||||
|
self.retranslateUi(SearchWidget)
|
||||||
|
|
||||||
|
def retranslateUi(self, SearchWidget):
|
||||||
|
_translate = QtCore.QCoreApplication.translate
|
||||||
|
self.reset_button.setText(_translate("SearchWidget", "Reset filters"))
|
||||||
|
self.price_group.setTitle(_translate("SearchWidget", "Price"))
|
||||||
|
self.none_price.setText(_translate("SearchWidget", "None"))
|
||||||
|
self.free_button.setText(_translate("SearchWidget", "Free"))
|
||||||
|
self.under10.setText(_translate("SearchWidget", "Under 10"))
|
||||||
|
self.under20.setText(_translate("SearchWidget", "Under 20"))
|
||||||
|
self.under30.setText(_translate("SearchWidget", "Under 30"))
|
||||||
|
self.above.setText(_translate("SearchWidget", "14.99 and above"))
|
||||||
|
self.on_discount.setText(_translate("SearchWidget", "Discount"))
|
||||||
|
self.platform_group.setTitle(_translate("SearchWidget", "Platform"))
|
||||||
|
self.genre_group.setTitle(_translate("SearchWidget", "Genre"))
|
||||||
|
self.type_group.setTitle(_translate("SearchWidget", "Type"))
|
||||||
|
self.others_group.setTitle(_translate("SearchWidget", "Other tags"))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import sys
|
||||||
|
app = QtWidgets.QApplication(sys.argv)
|
||||||
|
SearchWidget = QtWidgets.QWidget()
|
||||||
|
ui = Ui_SearchWidget()
|
||||||
|
ui.setupUi(SearchWidget)
|
||||||
|
SearchWidget.show()
|
||||||
|
sys.exit(app.exec_())
|
183
rare/ui/components/tabs/store/search.ui
Normal file
183
rare/ui/components/tabs/store/search.ui
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>SearchWidget</class>
|
||||||
|
<widget class="QWidget" name="SearchWidget">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>491</width>
|
||||||
|
<height>382</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string notr="true">SearchWidget</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QHBoxLayout" name="main_layout" stretch="1,0">
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="left_layout"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QVBoxLayout" name="right_layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="reset_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reset filters</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QScrollArea" name="filter_scrollarea">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="frameShape">
|
||||||
|
<enum>QFrame::NoFrame</enum>
|
||||||
|
</property>
|
||||||
|
<property name="frameShadow">
|
||||||
|
<enum>QFrame::Plain</enum>
|
||||||
|
</property>
|
||||||
|
<property name="horizontalScrollBarPolicy">
|
||||||
|
<enum>Qt::ScrollBarAlwaysOff</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
||||||
|
</property>
|
||||||
|
<property name="widgetResizable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="filter_container">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<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>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>3</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="price_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Price</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="price_layout">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="none_price">
|
||||||
|
<property name="text">
|
||||||
|
<string>None</string>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="free_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Free</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="under10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Under 10</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="under20">
|
||||||
|
<property name="text">
|
||||||
|
<string>Under 20</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="under30">
|
||||||
|
<property name="text">
|
||||||
|
<string>Under 30</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="above">
|
||||||
|
<property name="text">
|
||||||
|
<string>14.99 and above</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="on_discount">
|
||||||
|
<property name="text">
|
||||||
|
<string>Discount</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="platform_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Platform</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="platfrom_layout"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="genre_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Genre</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="genre_layout"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="type_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Type</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="type_layout"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox" name="others_group">
|
||||||
|
<property name="title">
|
||||||
|
<string>Other tags</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="others_layout"/>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
|
@ -1,282 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>ShopWidget</class>
|
|
||||||
<widget class="QWidget" name="ShopWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>788</width>
|
|
||||||
<height>662</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string notr="true">Store</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="main_layout">
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QScrollArea" name="filter_scrollarea">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="horizontalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeAdjustPolicy">
|
|
||||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
|
||||||
</property>
|
|
||||||
<property name="widgetResizable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="filter_container">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<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>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="price_group">
|
|
||||||
<property name="title">
|
|
||||||
<string>Price</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="price_layout">
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="none_price">
|
|
||||||
<property name="text">
|
|
||||||
<string>None</string>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="free_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Free</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="under10">
|
|
||||||
<property name="text">
|
|
||||||
<string>Under 10</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="under20">
|
|
||||||
<property name="text">
|
|
||||||
<string>Under 20</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="under30">
|
|
||||||
<property name="text">
|
|
||||||
<string>Under 30</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QRadioButton" name="above">
|
|
||||||
<property name="text">
|
|
||||||
<string>14.99 and above</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="on_discount">
|
|
||||||
<property name="text">
|
|
||||||
<string>Discount</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="platform_group">
|
|
||||||
<property name="title">
|
|
||||||
<string>Platform</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="platfrom_layout"/>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="genre_group">
|
|
||||||
<property name="title">
|
|
||||||
<string>Genre</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="genre_layout"/>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="type_group">
|
|
||||||
<property name="title">
|
|
||||||
<string>Type</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="type_layout"/>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="others_group">
|
|
||||||
<property name="title">
|
|
||||||
<string>Other tags</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="others_layout"/>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QPushButton" name="reset_button">
|
|
||||||
<property name="text">
|
|
||||||
<string>Reset filters</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QScrollArea" name="games_scrollarea">
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeAdjustPolicy">
|
|
||||||
<enum>QAbstractScrollArea::AdjustToContents</enum>
|
|
||||||
</property>
|
|
||||||
<property name="widgetResizable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="games_container">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>628</width>
|
|
||||||
<height>618</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="games_container_layout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QScrollArea" name="free_scrollarea">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="frameShape">
|
|
||||||
<enum>QFrame::NoFrame</enum>
|
|
||||||
</property>
|
|
||||||
<property name="frameShadow">
|
|
||||||
<enum>QFrame::Plain</enum>
|
|
||||||
</property>
|
|
||||||
<property name="verticalScrollBarPolicy">
|
|
||||||
<enum>Qt::ScrollBarAlwaysOff</enum>
|
|
||||||
</property>
|
|
||||||
<property name="widgetResizable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="free_container">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<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>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>3</number>
|
|
||||||
</property>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="discounts_group">
|
|
||||||
<property name="title">
|
|
||||||
<string>Discounts from your wishlist</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="games_group">
|
|
||||||
<property name="title">
|
|
||||||
<string>Games</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
0
rare/ui/components/tabs/store/widgets/__init__.py
Normal file
0
rare/ui/components/tabs/store/widgets/__init__.py
Normal file
|
@ -1,8 +1,8 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/store/wishlist_widget.ui'
|
# Form implementation generated from reading ui file 'rare/ui/components/tabs/store/widgets/wishlist_widget.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.15.9
|
# Created by: PyQt5 UI code generator 5.15.10
|
||||||
#
|
#
|
||||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
# 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.
|
# run again. Do not edit this file unless you know what you are doing.
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
# Form implementation generated from reading ui file 'rare/ui/components/tabs/store/wishlist.ui'
|
# Form implementation generated from reading ui file 'rare/ui/components/tabs/store/wishlist.ui'
|
||||||
#
|
#
|
||||||
# Created by: PyQt5 UI code generator 5.15.9
|
# Created by: PyQt5 UI code generator 5.15.10
|
||||||
#
|
#
|
||||||
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
|
# 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.
|
# run again. Do not edit this file unless you know what you are doing.
|
||||||
|
@ -16,8 +16,8 @@ class Ui_Wishlist(object):
|
||||||
Wishlist.setObjectName("Wishlist")
|
Wishlist.setObjectName("Wishlist")
|
||||||
Wishlist.resize(423, 153)
|
Wishlist.resize(423, 153)
|
||||||
Wishlist.setWindowTitle("Wishlist")
|
Wishlist.setWindowTitle("Wishlist")
|
||||||
self.verticalLayout = QtWidgets.QVBoxLayout(Wishlist)
|
self.main_layout = QtWidgets.QVBoxLayout(Wishlist)
|
||||||
self.verticalLayout.setObjectName("verticalLayout")
|
self.main_layout.setObjectName("main_layout")
|
||||||
self.tool_layout = QtWidgets.QHBoxLayout()
|
self.tool_layout = QtWidgets.QHBoxLayout()
|
||||||
self.tool_layout.setObjectName("tool_layout")
|
self.tool_layout.setObjectName("tool_layout")
|
||||||
self.sort_label = QtWidgets.QLabel(Wishlist)
|
self.sort_label = QtWidgets.QLabel(Wishlist)
|
||||||
|
@ -59,10 +59,10 @@ class Ui_Wishlist(object):
|
||||||
self.reload_button.setText("")
|
self.reload_button.setText("")
|
||||||
self.reload_button.setObjectName("reload_button")
|
self.reload_button.setObjectName("reload_button")
|
||||||
self.tool_layout.addWidget(self.reload_button)
|
self.tool_layout.addWidget(self.reload_button)
|
||||||
self.verticalLayout.addLayout(self.tool_layout)
|
self.main_layout.addLayout(self.tool_layout)
|
||||||
self.no_games_label = QtWidgets.QLabel(Wishlist)
|
self.no_games_label = QtWidgets.QLabel(Wishlist)
|
||||||
self.no_games_label.setObjectName("no_games_label")
|
self.no_games_label.setObjectName("no_games_label")
|
||||||
self.verticalLayout.addWidget(self.no_games_label)
|
self.main_layout.addWidget(self.no_games_label)
|
||||||
self.list_scrollarea = QtWidgets.QScrollArea(Wishlist)
|
self.list_scrollarea = QtWidgets.QScrollArea(Wishlist)
|
||||||
self.list_scrollarea.setWidgetResizable(True)
|
self.list_scrollarea.setWidgetResizable(True)
|
||||||
self.list_scrollarea.setObjectName("list_scrollarea")
|
self.list_scrollarea.setObjectName("list_scrollarea")
|
||||||
|
@ -70,7 +70,7 @@ class Ui_Wishlist(object):
|
||||||
self.list_container.setGeometry(QtCore.QRect(0, 0, 407, 83))
|
self.list_container.setGeometry(QtCore.QRect(0, 0, 407, 83))
|
||||||
self.list_container.setObjectName("list_container")
|
self.list_container.setObjectName("list_container")
|
||||||
self.list_scrollarea.setWidget(self.list_container)
|
self.list_scrollarea.setWidget(self.list_container)
|
||||||
self.verticalLayout.addWidget(self.list_scrollarea)
|
self.main_layout.addWidget(self.list_scrollarea)
|
||||||
|
|
||||||
self.retranslateUi(Wishlist)
|
self.retranslateUi(Wishlist)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string notr="true">Wishlist</string>
|
<string notr="true">Wishlist</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QVBoxLayout" name="main_layout">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="tool_layout">
|
<layout class="QHBoxLayout" name="tool_layout">
|
||||||
<item>
|
<item>
|
||||||
|
|
Loading…
Reference in a new issue