1
0
Fork 0
mirror of synced 2024-06-26 18:20:50 +12:00

Add an installing game widget to icon list

This commit is contained in:
Dummerle 2021-08-28 00:16:17 +02:00
parent 82627a799e
commit b3cc412142
5 changed files with 137 additions and 1 deletions

View file

@ -114,6 +114,9 @@ class TabWidget(QTabWidget):
QShortcut("Alt+3", self).activated.connect(lambda: self.setCurrentIndex(2))
QShortcut("Alt+4", self).activated.connect(lambda: self.setCurrentIndex(5))
self.downloadTab.dl_status.connect(
self.games_tab.default_widget.game_list.installing_widget.image_widget.set_status)
# TODO; maybe pass InstallOptionsModel only, not split arguments
def install_game(self, options: InstallOptionsModel, update=False, silent=False):
install_dialog = InstallDialog(self.core,
@ -132,6 +135,7 @@ class TabWidget(QTabWidget):
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))
self.setCurrentIndex(1)
self.downloadTab.install_game(download_item)
self.games_tab.default_widget.game_list.start_download(download_item.options.app_name)
def game_imported(self, app_name: str):
igame = self.core.get_installed_game(app_name)
@ -167,6 +171,7 @@ class TabWidget(QTabWidget):
if update_list[0]:
self.games_tab.default_widget.game_list.update_list(update_list[1])
self.cloud_saves.reload(update_list[1])
self.games_tab.default_widget.game_list.installing_widget.setVisible(False)
downloads = len(self.downloadTab.dl_queue) + len(self.downloadTab.update_widgets.keys())
self.setTabText(1, "Downloads" + ((" (" + str(downloads) + ")") if downloads != 0 else ""))

View file

@ -21,6 +21,7 @@ class DownloadTab(QWidget):
finished = pyqtSignal(tuple)
thread: QThread
dl_queue = []
dl_status = pyqtSignal(int)
def __init__(self, core: LegendaryCore, updates: list, parent):
super(DownloadTab, self).__init__(parent=parent)
@ -184,6 +185,7 @@ class DownloadTab(QWidget):
self.downloaded.setText(
self.tr("Downloaded") + f": {get_size(ui_update.total_downloaded)} / {get_size(self.analysis.dl_size)}")
self.time_left.setText(self.tr("Time left: ") + self.get_time(ui_update.estimated_time_left))
self.dl_status.emit(int(100 * ui_update.total_downloaded / self.analysis.dl_size))
def get_time(self, seconds: int) -> str:
return str(datetime.timedelta(seconds=seconds))

View file

@ -8,6 +8,7 @@ from custom_legendary.core import LegendaryCore
from rare.components.tabs.games.game_widgets.base_installed_widget import BaseInstalledWidget
from rare.components.tabs.games.game_widgets.installed_icon_widget import GameWidgetInstalled
from rare.components.tabs.games.game_widgets.installed_list_widget import InstalledListWidget
from rare.components.tabs.games.game_widgets.installing_game_widget import InstallingGameWidget
from rare.components.tabs.games.game_widgets.uninstalled_icon_widget import IconWidgetUninstalled
from rare.components.tabs.games.game_widgets.uninstalled_list_widget import ListWidgetUninstalled
from rare.utils.extra_widgets import FlowLayout
@ -33,7 +34,7 @@ class GameList(QStackedWidget):
self.core = core
self.setObjectName("list_widget")
self.offline = offline
self.installing_widget = InstallingGameWidget(self.core.get_game("CrabEA"))
self.settings = QSettings()
icon_view = self.settings.value("icon_view", True, bool)
self.procs = []
@ -81,6 +82,10 @@ class GameList(QStackedWidget):
self.mac_games = []
self.installed = sorted(self.core.get_installed_list(), key=lambda x: x.title)
self.installing_widget = InstallingGameWidget(self.core.get_game("CrabEA"))
self.icon_layout.addWidget(self.installing_widget)
self.installing_widget.setVisible(False)
# Installed Games
for igame in self.installed:
icon_widget, list_widget = self.add_installed_widget(igame)
@ -123,6 +128,10 @@ class GameList(QStackedWidget):
if filter_games := self.settings.value("filter", "", str):
self.filter(filter_games)
def start_download(self, app_name):
self.installing_widget.set_game(self.core.get_game(app_name))
self.installing_widget.setVisible(True)
def add_uninstalled_widget(self, game):
pixmap = get_uninstalled_pixmap(game.app_name)
if pixmap.isNull():
@ -347,6 +356,7 @@ class GameList(QStackedWidget):
i_widget, list_widget = self.widgets[name]
self.icon_layout.addWidget(i_widget)
self.list_layout.addWidget(list_widget)
self.installing_widget.setVisible(False)
def _update_games(self):
# new layouts to remove from old layout
@ -354,6 +364,7 @@ class GameList(QStackedWidget):
# QWidget().setLayout(self.list_layout)
list_layout = QVBoxLayout()
icon_layout.addWidget(self.installing_widget)
for igame in sorted(self.core.get_installed_list(), key=lambda x: x.title):
i_widget, l_widget = self.widgets[igame.app_name]
icon_layout.addWidget(i_widget)

View file

@ -0,0 +1,82 @@
from PyQt5.QtCore import Qt, QRect
from PyQt5.QtGui import QPaintEvent, QPainter, QPixmap, QPen, QFont, QColor
from PyQt5.QtWidgets import QGroupBox, QVBoxLayout, QLabel, QHBoxLayout, QWidget
from custom_legendary.models.game import Game
from rare.utils.utils import get_pixmap, get_uninstalled_pixmap, optimal_text_background, text_color_for_background
class InstallingGameWidget(QGroupBox):
def __init__(self, game: Game):
super(InstallingGameWidget, self).__init__()
self.setObjectName("game_widget_icon")
self.setLayout(QVBoxLayout())
self.pixmap = get_pixmap(game.app_name)
w = 200
self.pixmap = self.pixmap.scaled(w, int(w * 4 / 3), transformMode=Qt.SmoothTransformation)
self.image_widget = PaintWidget(self.pixmap, game.app_name)
self.image_widget.setFixedSize(w, int(w * 4 / 3))
self.layout().addWidget(self.image_widget)
self.title_label = QLabel(f"<h4>{game.app_title}</h4>")
self.title_label.setAutoFillBackground(False)
self.title_label.setWordWrap(True)
self.title_label.setFixedWidth(175)
minilayout = QHBoxLayout()
self.title_label.setObjectName("game_widget")
minilayout.addWidget(self.title_label)
self.layout().addLayout(minilayout)
def set_game(self, game: Game):
self.title_label.setText(f"<h4>{game.app_title}</h4>")
self.pixmap = get_pixmap(game.app_name)
w = 200
self.pixmap = self.pixmap.scaled(w, int(w * 4 / 3), transformMode=Qt.SmoothTransformation)
self.image_widget.set_game(self.pixmap, game.app_name)
class PaintWidget(QWidget):
def __init__(self, image: QPixmap, app_name):
super(PaintWidget, self).__init__()
self.set_game(image, app_name)
def set_game(self, pixmap: QPixmap, app_name):
self.image = pixmap
self.setFixedSize(self.image.size())
self.new_image = get_uninstalled_pixmap(app_name)
self.status = 0
pixel_list = []
for x in range(self.image.width()):
for y in range(self.image.height()):
# convert pixmap to qimage, get pixel and remove alpha channel
pixel_list.append(self.image.toImage().pixelColor(x, y).getRgb()[:-1])
self.rgb_tuple = optimal_text_background(pixel_list)
def paintEvent(self, a0: QPaintEvent) -> None:
painter = QPainter()
painter.begin(self)
painter.drawPixmap(self.rect(), self.image)
w = self.image.width() * (1 - self.status / 100)
painter.drawPixmap(self.image.width() - w, 0, w, self.image.height(),
self.new_image.copy(QRect(self.image.width() - w, 0, w, self.image.height())))
# Draw Circle
pen = QPen(QColor(*self.rgb_tuple), 3)
painter.setPen(pen)
painter.setBrush(QColor(*self.rgb_tuple))
painter.drawEllipse(int(self.width() / 2) - 20, int(self.height() / 2) - 20, 40, 40)
# draw text
painter.setPen(QColor(*text_color_for_background(self.rgb_tuple)))
painter.setFont(QFont(None, 16))
painter.drawText(a0.rect(), Qt.AlignCenter, str(self.status) + "%")
painter.end()
def set_status(self, s: int):
self.status = s
self.repaint()

View file

@ -1,9 +1,11 @@
import json
import math
import os
import platform
import shutil
import sys
from logging import getLogger
from typing import Tuple
import requests
from PIL import Image, UnidentifiedImageError
@ -376,3 +378,37 @@ def get_uninstalled_pixmap(app_name: str) -> QPixmap:
else:
pixmap = QPixmap()
return pixmap
def optimal_text_background(image: list) -> Tuple[int, int, int]:
"""
Finds an optimal background color for text on the image by calculating the
average color of the image and inverting it.
The image list is supposed to be a one-dimensional list of arbitrary length
containing RGB tuples, ranging from 0 to 255.
"""
# cursed, I know
average = map(lambda value: value / len(image), map(sum, zip(*image)))
inverted = map(lambda value: 255 - value, average)
return tuple(inverted)
def text_color_for_background(background: Tuple[int, int, int]) -> Tuple[int,
int,
int]:
"""
Calculates whether a black or white text color would fit better for the
given background, and returns that color. This is done by calculating the
luminance and simple comparing of bounds
"""
# see https://alienryderflex.com/hsp.html
(red, green, blue) = background
luminance = math.sqrt(
0.299 * red ** 2 +
0.587 * green ** 2 +
0.114 * blue ** 2)
if luminance < 127:
return 255, 255, 255
else:
return 0, 0, 0