updates and toggle button
This commit is contained in:
parent
fc1c8ec031
commit
d3eabac818
|
@ -17,6 +17,7 @@ class TabWidget(QTabWidget):
|
|||
self.setTabBar(TabBar(disabled_tab))
|
||||
self.settings = SettingsTab(core)
|
||||
self.game_list = GameTab(core)
|
||||
self.game_list.default_widget.game_list.update_game.connect(lambda: self.setCurrentIndex(1))
|
||||
updates = self.game_list.default_widget.game_list.updates
|
||||
self.addTab(self.game_list, self.tr("Games"))
|
||||
self.downloadTab = DownloadTab(core, updates)
|
||||
|
|
|
@ -10,6 +10,7 @@ from legendary.models.game import Game
|
|||
from notifypy import Notify
|
||||
|
||||
from Rare.Components.Dialogs.InstallDialog import InstallInfoDialog
|
||||
from Rare.utils.Models import InstallOptions
|
||||
|
||||
logger = getLogger("Download")
|
||||
|
||||
|
@ -37,6 +38,7 @@ class DownloadThread(QThread):
|
|||
else:
|
||||
self.status.emit("dl_finished")
|
||||
end_t = time.time()
|
||||
|
||||
game = self.core.get_game(self.igame.app_name)
|
||||
postinstall = self.core.install_game(self.igame)
|
||||
if postinstall:
|
||||
|
@ -129,13 +131,34 @@ class DownloadTab(QWidget):
|
|||
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def install_game(self, options: {}):
|
||||
game = self.core.get_game(options["app_name"])
|
||||
def install_game(self, options: InstallOptions):
|
||||
game = self.core.get_game(options.app_name, update_meta=True)
|
||||
if self.core.is_installed(options.app_name):
|
||||
igame = self.core.get_installed_game(options.app_name)
|
||||
if igame.needs_verification and not options.repair:
|
||||
options.repair = True
|
||||
|
||||
if not game:
|
||||
QMessageBox.warning(self, "Error", "Could not find Game in your library")
|
||||
return
|
||||
|
||||
if game.is_dlc:
|
||||
return
|
||||
|
||||
if options.repair:
|
||||
repair_file = os.path.join(self.core.lgd.get_tmp_path(), f'{options.app_name}.repair')
|
||||
|
||||
if not self.core.is_installed(game.app_name):
|
||||
return
|
||||
if not os.path.exists(repair_file):
|
||||
logger.info("Game has not been verified yet")
|
||||
return
|
||||
self.repair()
|
||||
|
||||
dlm, analysis, igame = self.core.prepare_download(
|
||||
game=game,
|
||||
base_path=options["options"]["path"],
|
||||
max_workers=options["options"]["max_workers"])
|
||||
base_path=options.path,
|
||||
max_workers=options.max_workers)
|
||||
if not analysis.dl_size:
|
||||
QMessageBox.information(self, "Warning", self.tr("Download size is 0. Game already exists"))
|
||||
return
|
||||
|
@ -146,7 +169,7 @@ class DownloadTab(QWidget):
|
|||
self.installing_game_widget.setText("")
|
||||
self.installing_game.setText("Installing Game: " + game.app_title)
|
||||
res = self.core.check_installation_conditions(analysis=analysis, install=igame, game=game,
|
||||
updating=self.core.is_installed(options["app_name"]),
|
||||
updating=self.core.is_installed(options.app_name),
|
||||
)
|
||||
if res.warnings:
|
||||
for w in sorted(res.warnings):
|
||||
|
@ -179,6 +202,11 @@ class DownloadTab(QWidget):
|
|||
|
||||
def update_game(self, app_name: str):
|
||||
print("Update ", app_name)
|
||||
self.install_game(InstallOptions(app_name))
|
||||
|
||||
|
||||
def repair(self):
|
||||
pass
|
||||
|
||||
|
||||
class UpdateWidget(QWidget):
|
||||
|
|
|
@ -12,7 +12,7 @@ from Rare.utils.QtExtensions import FlowLayout
|
|||
class GameList(QScrollArea):
|
||||
install_game = pyqtSignal(dict)
|
||||
show_game_info = pyqtSignal(str)
|
||||
|
||||
update_game = pyqtSignal()
|
||||
def __init__(self, core: LegendaryCore):
|
||||
super(GameList, self).__init__()
|
||||
self.core = core
|
||||
|
@ -45,6 +45,7 @@ class GameList(QScrollArea):
|
|||
widget = GameWidget(game, self.core)
|
||||
if widget.update_available:
|
||||
self.updates.append(widget.game.app_name)
|
||||
widget.update_game.connect(self.update_game.emit)
|
||||
self.layout.addWidget(widget)
|
||||
widget.update_list.connect(self.update_list)
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ logger = getLogger("GameWidgetInstalled")
|
|||
class GameWidgetInstalled(QWidget):
|
||||
update_list = pyqtSignal()
|
||||
show_info = pyqtSignal(str)
|
||||
update_game = pyqtSignal()
|
||||
|
||||
def __init__(self, core: LegendaryCore, game: InstalledGame):
|
||||
super(GameWidgetInstalled, self).__init__()
|
||||
|
@ -79,7 +80,9 @@ class GameWidgetInstalled(QWidget):
|
|||
self.setFixedWidth(self.sizeHint().width())
|
||||
|
||||
def enterEvent(self, a0: QEvent) -> None:
|
||||
if not self.running:
|
||||
if self.update_available:
|
||||
self.info_label.setText("Please update Game")
|
||||
elif not self.running:
|
||||
self.info_label.setText("Start Game")
|
||||
|
||||
def leaveEvent(self, a0: QEvent) -> None:
|
||||
|
@ -89,7 +92,7 @@ class GameWidgetInstalled(QWidget):
|
|||
self.launch()
|
||||
|
||||
def launch(self, offline=False):
|
||||
if not self.running:
|
||||
if not self.running and not self.update_available:
|
||||
logger.info("Launching " + self.game.title)
|
||||
self.proc = LegendaryApi.launch_game(self.core, self.game.app_name, offline)
|
||||
if not self.proc:
|
||||
|
@ -98,6 +101,8 @@ class GameWidgetInstalled(QWidget):
|
|||
self.proc.finished.connect(self.finished)
|
||||
self.info_label.setText(self.tr("Game running"))
|
||||
self.running = True
|
||||
if self.update_available:
|
||||
self.update_game.emit()
|
||||
|
||||
def finished(self):
|
||||
self.info_label.setText("")
|
||||
|
@ -121,4 +126,3 @@ class Menu(QMenu):
|
|||
super(Menu, self).__init__()
|
||||
self.addAction(self.tr("Game info"), lambda: self.action.emit("info"))
|
||||
self.addAction(self.tr("Uninstall"), lambda: self.action.emit("uninstall"))
|
||||
|
||||
|
|
|
@ -8,12 +8,14 @@ from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QVBoxLayout, QPushButt
|
|||
from legendary.core import LegendaryCore
|
||||
|
||||
from Rare.Components.Dialogs.InstallDialog import InstallDialog
|
||||
from Rare.utils.Models import InstallOptions
|
||||
|
||||
logger = getLogger("Game")
|
||||
|
||||
|
||||
class UninstalledGameWidget(QWidget):
|
||||
install_game = pyqtSignal(dict)
|
||||
install_game = pyqtSignal(InstallOptions)
|
||||
|
||||
def __init__(self, core: LegendaryCore, game):
|
||||
super(UninstalledGameWidget, self).__init__()
|
||||
self.title = game.app_title
|
||||
|
@ -57,11 +59,9 @@ class UninstalledGameWidget(QWidget):
|
|||
infos = InstallDialog().get_information()
|
||||
if infos != 0:
|
||||
path, max_workers = infos
|
||||
self.install_game.emit({
|
||||
"app_name": self.game.app_name,
|
||||
"options": {
|
||||
"path": path,
|
||||
"max_workers": max_workers
|
||||
}
|
||||
})
|
||||
self.install_game.emit(InstallOptions(
|
||||
app_name=self.game.app_name,
|
||||
path=path,
|
||||
max_workers=max_workers,
|
||||
repair=False))
|
||||
# wait for update of legendary to get progress
|
||||
|
|
|
@ -4,6 +4,7 @@ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QCheckBox, QLineE
|
|||
|
||||
from Rare.Components.Tabs.Games.GameInfo.GameInfo import InfoTabs
|
||||
from Rare.Components.Tabs.Games.GameList import GameList
|
||||
from Rare.utils.QtExtensions import Switch
|
||||
|
||||
|
||||
class GameTab(QWidget):
|
||||
|
@ -43,7 +44,7 @@ class Games(QWidget):
|
|||
self.layout.addWidget(self.head_bar)
|
||||
self.layout.addWidget(self.game_list)
|
||||
# self.layout.addStretch(1)
|
||||
self.head_bar.view.stateChanged.connect(
|
||||
self.head_bar.view.toggled.connect(
|
||||
lambda: self.game_list.update_list(not self.head_bar.view.isChecked()))
|
||||
self.setLayout(self.layout)
|
||||
|
||||
|
@ -64,10 +65,16 @@ class GameListHeadBar(QWidget):
|
|||
|
||||
self.layout.addStretch()
|
||||
self.list_view = QLabel(self.tr("List view"))
|
||||
self.layout.addWidget(self.list_view)
|
||||
self.view = QCheckBox(self.tr("Icon view"))
|
||||
self.view.setChecked(not QSettings().value("icon_view", True, bool))
|
||||
|
||||
self.icon_view = QLabel(self.tr("Icon view"))
|
||||
|
||||
self.view = Switch()
|
||||
checked = not QSettings().value("icon_view", True, bool)
|
||||
self.view.setChecked(checked)
|
||||
self.layout.addWidget(self.icon_view)
|
||||
self.layout.addWidget(self.view)
|
||||
self.layout.addWidget(self.list_view)
|
||||
|
||||
self.refresh_list = QPushButton()
|
||||
self.refresh_list.setIcon(self.style().standardIcon(getattr(QStyle, "SP_BrowserReload"))) # Reload icon
|
||||
self.layout.addWidget(self.refresh_list)
|
||||
|
|
12
Rare/utils/Models.py
Normal file
12
Rare/utils/Models.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
import os
|
||||
|
||||
|
||||
class InstallOptions:
|
||||
def __init__(self, app_name: str, path: str = os.path.expanduser("~/legendary"),
|
||||
max_workers: int = os.cpu_count() * 2, repair: bool = False,
|
||||
download_only: bool = False):
|
||||
self.app_name = app_name
|
||||
self.path = path
|
||||
self.max_workers = max_workers
|
||||
self.repair = repair
|
||||
self.download_only = download_only
|
|
@ -1,9 +1,10 @@
|
|||
import os
|
||||
|
||||
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal
|
||||
from PyQt5.QtGui import QMovie
|
||||
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal, QPropertyAnimation, pyqtSlot, QPointF, QEasingCurve, \
|
||||
QObject, pyqtProperty
|
||||
from PyQt5.QtGui import QMovie, QPainter, QPalette, QLinearGradient, QGradient
|
||||
from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLabel, QFileDialog, QHBoxLayout, QWidget, QLineEdit, \
|
||||
QPushButton, QStyleOptionTab, QStylePainter, QTabBar
|
||||
QPushButton, QStyleOptionTab, QStylePainter, QTabBar, QAbstractButton, QCheckBox
|
||||
|
||||
from Rare import style_path
|
||||
|
||||
|
@ -191,3 +192,89 @@ class WaitingSpinner(QLabel):
|
|||
self.movie = QMovie(style_path+"Icons/loader.gif")
|
||||
self.setMovie(self.movie)
|
||||
self.movie.start()
|
||||
|
||||
|
||||
class SwitchPrivate(QObject):
|
||||
def __init__(self, q, parent=None):
|
||||
QObject.__init__(self, parent=parent)
|
||||
self.mPointer = q
|
||||
self.mPosition = 0.0
|
||||
self.mGradient = QLinearGradient()
|
||||
self.mGradient.setSpread(QGradient.PadSpread)
|
||||
|
||||
self.animation = QPropertyAnimation(self)
|
||||
self.animation.setTargetObject(self)
|
||||
self.animation.setPropertyName(b'position')
|
||||
self.animation.setStartValue(0.0)
|
||||
self.animation.setEndValue(1.0)
|
||||
self.animation.setDuration(200)
|
||||
self.animation.setEasingCurve(QEasingCurve.InOutExpo)
|
||||
|
||||
self.animation.finished.connect(self.mPointer.update)
|
||||
|
||||
@pyqtProperty(float)
|
||||
def position(self):
|
||||
return self.mPosition
|
||||
|
||||
@position.setter
|
||||
def position(self, value):
|
||||
self.mPosition = value
|
||||
self.mPointer.update()
|
||||
|
||||
def draw(self, painter):
|
||||
r = self.mPointer.rect()
|
||||
margin = r.height()/10
|
||||
shadow = self.mPointer.palette().color(QPalette.Dark)
|
||||
light = self.mPointer.palette().color(QPalette.Light)
|
||||
button = self.mPointer.palette().color(QPalette.Button)
|
||||
painter.setPen(Qt.NoPen)
|
||||
|
||||
self.mGradient.setColorAt(0, shadow.darker(130))
|
||||
self.mGradient.setColorAt(1, light.darker(130))
|
||||
self.mGradient.setStart(0, r.height())
|
||||
self.mGradient.setFinalStop(0, 0)
|
||||
painter.setBrush(self.mGradient)
|
||||
painter.drawRoundedRect(r, r.height()/2, r.height()/2)
|
||||
|
||||
self.mGradient.setColorAt(0, shadow.darker(140))
|
||||
self.mGradient.setColorAt(1, light.darker(160))
|
||||
self.mGradient.setStart(0, 0)
|
||||
self.mGradient.setFinalStop(0, r.height())
|
||||
painter.setBrush(self.mGradient)
|
||||
painter.drawRoundedRect(r.adjusted(margin, margin, -margin, -margin), r.height()/2, r.height()/2)
|
||||
|
||||
self.mGradient.setColorAt(0, button.darker(130))
|
||||
self.mGradient.setColorAt(1, button)
|
||||
|
||||
painter.setBrush(self.mGradient)
|
||||
|
||||
x = r.height()/2.0 + self.mPosition*(r.width()-r.height())
|
||||
painter.drawEllipse(QPointF(x, r.height()/2), r.height()/2-margin, r.height()/2-margin)
|
||||
|
||||
@pyqtSlot(bool, name='animate')
|
||||
def animate(self, checked):
|
||||
self.animation.setDirection(QPropertyAnimation.Forward if checked else QPropertyAnimation.Backward)
|
||||
self.animation.start()
|
||||
|
||||
|
||||
class Switch(QAbstractButton):
|
||||
def __init__(self):
|
||||
QAbstractButton.__init__(self)
|
||||
self.dPtr = SwitchPrivate(self)
|
||||
self.setCheckable(True)
|
||||
self.clicked.connect(self.dPtr.animate)
|
||||
|
||||
def sizeHint(self):
|
||||
return QSize(42, 21)
|
||||
|
||||
def paintEvent(self, event):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.Antialiasing)
|
||||
self.dPtr.draw(painter)
|
||||
|
||||
def setChecked(self, a0: bool) -> None:
|
||||
super().setChecked(a0)
|
||||
self.dPtr.animate(a0)
|
||||
|
||||
def resizeEvent(self, event):
|
||||
self.update()
|
||||
|
|
Loading…
Reference in a new issue