1
0
Fork 0
mirror of synced 2024-09-14 16:38:00 +12:00
Rare/rare/components/tabs/games/game_widgets/__init__.py
2023-12-03 17:11:47 +02:00

168 lines
7 KiB
Python

from enum import IntEnum
from typing import Tuple, List, Union
from PyQt5.QtCore import QObject, pyqtSlot
from PyQt5.QtWidgets import QWidget
from rare.lgndr.core import LegendaryCore
from rare.models.game import RareGame
from rare.models.signals import GlobalSignals
from rare.shared import RareCore
from .icon_game_widget import IconGameWidget
from .list_game_widget import ListGameWidget
class LibraryFilter(IntEnum):
ALL = 1
INSTALLED = 2
OFFLINE = 3
HIDDEN = 4
WIN32 = 5
MAC = 6
INSTALLABLE = 7
INCLUDE_UE = 8
class LibraryOrder(IntEnum):
TITLE = 1
RECENT = 2
NEWEST = 3
OLDEST = 4
class LibraryWidgetController(QObject):
def __init__(self, icon_container: QWidget, list_container: QWidget, parent: QWidget = None):
super(LibraryWidgetController, self).__init__(parent=parent)
self._icon_container: QWidget = icon_container
self._list_container: QWidget = list_container
self.rcore = RareCore.instance()
self.core: LegendaryCore = self.rcore.core()
self.signals: GlobalSignals = self.rcore.signals()
self.signals.game.installed.connect(self.order_game_views)
self.signals.game.uninstalled.connect(self.order_game_views)
def add_game(self, rgame: RareGame):
return self.add_widgets(rgame)
def add_widgets(self, rgame: RareGame) -> Tuple[IconGameWidget, ListGameWidget]:
icon_widget = IconGameWidget(rgame, self._icon_container)
list_widget = ListGameWidget(rgame, self._list_container)
return icon_widget, list_widget
@staticmethod
def __visibility(
widget: Union[IconGameWidget, ListGameWidget], library_filter, search_text
) -> Tuple[bool, float]:
if library_filter == LibraryFilter.HIDDEN:
visible = "hidden" in widget.rgame.metadata.tags
elif "hidden" in widget.rgame.metadata.tags:
visible = False
elif library_filter == LibraryFilter.INSTALLED:
visible = widget.rgame.is_installed
elif library_filter == LibraryFilter.OFFLINE:
visible = widget.rgame.can_run_offline
elif library_filter == LibraryFilter.WIN32:
visible = widget.rgame.is_win32
elif library_filter == LibraryFilter.MAC:
visible = widget.rgame.is_mac
elif library_filter == LibraryFilter.INSTALLABLE:
visible = not widget.rgame.is_non_asset
elif library_filter == LibraryFilter.INCLUDE_UE:
visible = True
elif library_filter == LibraryFilter.ALL:
visible = not widget.rgame.is_unreal
else:
visible = True
if (
search_text not in widget.rgame.app_name.lower()
and search_text not in widget.rgame.app_title.lower()
):
opacity = 0.25
else:
opacity = 1.0
return visible, opacity
def filter_game_views(self, filter_name="all", search_text: str = ""):
icon_widgets = self._icon_container.findChildren(IconGameWidget)
list_widgets = self._list_container.findChildren(ListGameWidget)
for iw in icon_widgets:
visibility, opacity = self.__visibility(iw, filter_name, search_text)
iw.setOpacity(opacity)
iw.setVisible(visibility)
for lw in list_widgets:
visibility, opacity = self.__visibility(lw, filter_name, search_text)
lw.setOpacity(opacity)
lw.setVisible(visibility)
self.order_game_views(search_text=search_text)
@pyqtSlot()
def order_game_views(self, order_by: LibraryOrder = LibraryOrder.TITLE, search_text: str = ""):
list_widgets = self._list_container.findChildren(ListGameWidget)
if search_text:
self._icon_container.layout().sort(
lambda x: (search_text not in x.widget().rgame.app_title.lower(),)
)
list_widgets.sort(key=lambda x: (search_text not in x.rgame.app_title.lower(),))
else:
if (newest := order_by == LibraryOrder.NEWEST) or order_by == LibraryOrder.OLDEST:
# Sort by grant date
self._icon_container.layout().sort(
key=lambda x: (x.widget().rgame.is_installed, not x.widget().rgame.is_non_asset, x.widget().rgame.grant_date()),
reverse=newest,
)
list_widgets.sort(
key=lambda x: (x.rgame.is_installed, not x.rgame.is_non_asset, x.rgame.grant_date()),
reverse=newest,
)
elif order_by == LibraryOrder.RECENT:
# Sort by recently played
self._icon_container.layout().sort(
key=lambda x: (not x.widget().rgame.is_installed, x.widget().rgame.is_non_asset, x.widget().rgame.metadata.last_played),
reverse=True,
)
list_widgets.sort(
key=lambda x: (not x.rgame.is_installed, x.rgame.is_non_asset, x.rgame.metadata.last_played),
reverse=True,
)
else:
# Sort by title
self._icon_container.layout().sort(
key=lambda x: (not x.widget().rgame.is_installed, x.widget().rgame.is_non_asset, x.widget().rgame.app_title)
)
list_widgets.sort(
key=lambda x: (not x.rgame.is_installed, x.rgame.is_non_asset, x.rgame.app_title)
)
for idx, wl in enumerate(list_widgets):
self._list_container.layout().insertWidget(idx, wl)
@pyqtSlot()
@pyqtSlot(list)
def update_game_views(self, app_names: List[str] = None):
if not app_names:
# lk: base it on icon widgets, the two lists should be identical
icon_widgets = self._icon_container.findChildren(IconGameWidget)
list_widgets = self._list_container.findChildren(ListGameWidget)
icon_app_names = set([iw.rgame.app_name for iw in icon_widgets])
list_app_names = set([lw.rgame.app_name for lw in list_widgets])
games = list(self.rcore.games)
game_app_names = set([g.app_name for g in games])
new_icon_app_names = game_app_names.difference(icon_app_names)
new_list_app_names = game_app_names.difference(list_app_names)
for app_name in new_icon_app_names:
game = self.rcore.get_game(app_name)
iw = IconGameWidget(game)
self._icon_container.layout().addWidget(iw)
for app_name in new_list_app_names:
game = self.rcore.get_game(app_name)
lw = ListGameWidget(game)
self._list_container.layout().addWidget(lw)
self.order_game_views()
def __find_widget(self, app_name: str) -> Tuple[Union[IconGameWidget, None], Union[ListGameWidget, None]]:
iw = self._icon_container.findChild(IconGameWidget, app_name)
lw = self._list_container.findChild(ListGameWidget, app_name)
return iw, lw