Add an installing game widget to icon list
This commit is contained in:
parent
82627a799e
commit
b3cc412142
|
@ -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 ""))
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue