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.setTabBar(TabBar(disabled_tab))
|
||||||
self.settings = SettingsTab(core)
|
self.settings = SettingsTab(core)
|
||||||
self.game_list = GameTab(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
|
updates = self.game_list.default_widget.game_list.updates
|
||||||
self.addTab(self.game_list, self.tr("Games"))
|
self.addTab(self.game_list, self.tr("Games"))
|
||||||
self.downloadTab = DownloadTab(core, updates)
|
self.downloadTab = DownloadTab(core, updates)
|
||||||
|
|
|
@ -10,6 +10,7 @@ from legendary.models.game import Game
|
||||||
from notifypy import Notify
|
from notifypy import Notify
|
||||||
|
|
||||||
from Rare.Components.Dialogs.InstallDialog import InstallInfoDialog
|
from Rare.Components.Dialogs.InstallDialog import InstallInfoDialog
|
||||||
|
from Rare.utils.Models import InstallOptions
|
||||||
|
|
||||||
logger = getLogger("Download")
|
logger = getLogger("Download")
|
||||||
|
|
||||||
|
@ -37,6 +38,7 @@ class DownloadThread(QThread):
|
||||||
else:
|
else:
|
||||||
self.status.emit("dl_finished")
|
self.status.emit("dl_finished")
|
||||||
end_t = time.time()
|
end_t = time.time()
|
||||||
|
|
||||||
game = self.core.get_game(self.igame.app_name)
|
game = self.core.get_game(self.igame.app_name)
|
||||||
postinstall = self.core.install_game(self.igame)
|
postinstall = self.core.install_game(self.igame)
|
||||||
if postinstall:
|
if postinstall:
|
||||||
|
@ -129,13 +131,34 @@ class DownloadTab(QWidget):
|
||||||
|
|
||||||
self.setLayout(self.layout)
|
self.setLayout(self.layout)
|
||||||
|
|
||||||
def install_game(self, options: {}):
|
def install_game(self, options: InstallOptions):
|
||||||
game = self.core.get_game(options["app_name"])
|
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(
|
dlm, analysis, igame = self.core.prepare_download(
|
||||||
game=game,
|
game=game,
|
||||||
base_path=options["options"]["path"],
|
base_path=options.path,
|
||||||
max_workers=options["options"]["max_workers"])
|
max_workers=options.max_workers)
|
||||||
if not analysis.dl_size:
|
if not analysis.dl_size:
|
||||||
QMessageBox.information(self, "Warning", self.tr("Download size is 0. Game already exists"))
|
QMessageBox.information(self, "Warning", self.tr("Download size is 0. Game already exists"))
|
||||||
return
|
return
|
||||||
|
@ -146,7 +169,7 @@ class DownloadTab(QWidget):
|
||||||
self.installing_game_widget.setText("")
|
self.installing_game_widget.setText("")
|
||||||
self.installing_game.setText("Installing Game: " + game.app_title)
|
self.installing_game.setText("Installing Game: " + game.app_title)
|
||||||
res = self.core.check_installation_conditions(analysis=analysis, install=igame, game=game,
|
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:
|
if res.warnings:
|
||||||
for w in sorted(res.warnings):
|
for w in sorted(res.warnings):
|
||||||
|
@ -179,6 +202,11 @@ class DownloadTab(QWidget):
|
||||||
|
|
||||||
def update_game(self, app_name: str):
|
def update_game(self, app_name: str):
|
||||||
print("Update ", app_name)
|
print("Update ", app_name)
|
||||||
|
self.install_game(InstallOptions(app_name))
|
||||||
|
|
||||||
|
|
||||||
|
def repair(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class UpdateWidget(QWidget):
|
class UpdateWidget(QWidget):
|
||||||
|
|
|
@ -12,7 +12,7 @@ from Rare.utils.QtExtensions import FlowLayout
|
||||||
class GameList(QScrollArea):
|
class GameList(QScrollArea):
|
||||||
install_game = pyqtSignal(dict)
|
install_game = pyqtSignal(dict)
|
||||||
show_game_info = pyqtSignal(str)
|
show_game_info = pyqtSignal(str)
|
||||||
|
update_game = pyqtSignal()
|
||||||
def __init__(self, core: LegendaryCore):
|
def __init__(self, core: LegendaryCore):
|
||||||
super(GameList, self).__init__()
|
super(GameList, self).__init__()
|
||||||
self.core = core
|
self.core = core
|
||||||
|
@ -45,6 +45,7 @@ class GameList(QScrollArea):
|
||||||
widget = GameWidget(game, self.core)
|
widget = GameWidget(game, self.core)
|
||||||
if widget.update_available:
|
if widget.update_available:
|
||||||
self.updates.append(widget.game.app_name)
|
self.updates.append(widget.game.app_name)
|
||||||
|
widget.update_game.connect(self.update_game.emit)
|
||||||
self.layout.addWidget(widget)
|
self.layout.addWidget(widget)
|
||||||
widget.update_list.connect(self.update_list)
|
widget.update_list.connect(self.update_list)
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ logger = getLogger("GameWidgetInstalled")
|
||||||
class GameWidgetInstalled(QWidget):
|
class GameWidgetInstalled(QWidget):
|
||||||
update_list = pyqtSignal()
|
update_list = pyqtSignal()
|
||||||
show_info = pyqtSignal(str)
|
show_info = pyqtSignal(str)
|
||||||
|
update_game = pyqtSignal()
|
||||||
|
|
||||||
def __init__(self, core: LegendaryCore, game: InstalledGame):
|
def __init__(self, core: LegendaryCore, game: InstalledGame):
|
||||||
super(GameWidgetInstalled, self).__init__()
|
super(GameWidgetInstalled, self).__init__()
|
||||||
|
@ -79,7 +80,9 @@ class GameWidgetInstalled(QWidget):
|
||||||
self.setFixedWidth(self.sizeHint().width())
|
self.setFixedWidth(self.sizeHint().width())
|
||||||
|
|
||||||
def enterEvent(self, a0: QEvent) -> None:
|
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")
|
self.info_label.setText("Start Game")
|
||||||
|
|
||||||
def leaveEvent(self, a0: QEvent) -> None:
|
def leaveEvent(self, a0: QEvent) -> None:
|
||||||
|
@ -89,7 +92,7 @@ class GameWidgetInstalled(QWidget):
|
||||||
self.launch()
|
self.launch()
|
||||||
|
|
||||||
def launch(self, offline=False):
|
def launch(self, offline=False):
|
||||||
if not self.running:
|
if not self.running and not self.update_available:
|
||||||
logger.info("Launching " + self.game.title)
|
logger.info("Launching " + self.game.title)
|
||||||
self.proc = LegendaryApi.launch_game(self.core, self.game.app_name, offline)
|
self.proc = LegendaryApi.launch_game(self.core, self.game.app_name, offline)
|
||||||
if not self.proc:
|
if not self.proc:
|
||||||
|
@ -98,6 +101,8 @@ class GameWidgetInstalled(QWidget):
|
||||||
self.proc.finished.connect(self.finished)
|
self.proc.finished.connect(self.finished)
|
||||||
self.info_label.setText(self.tr("Game running"))
|
self.info_label.setText(self.tr("Game running"))
|
||||||
self.running = True
|
self.running = True
|
||||||
|
if self.update_available:
|
||||||
|
self.update_game.emit()
|
||||||
|
|
||||||
def finished(self):
|
def finished(self):
|
||||||
self.info_label.setText("")
|
self.info_label.setText("")
|
||||||
|
@ -121,4 +126,3 @@ class Menu(QMenu):
|
||||||
super(Menu, self).__init__()
|
super(Menu, self).__init__()
|
||||||
self.addAction(self.tr("Game info"), lambda: self.action.emit("info"))
|
self.addAction(self.tr("Game info"), lambda: self.action.emit("info"))
|
||||||
self.addAction(self.tr("Uninstall"), lambda: self.action.emit("uninstall"))
|
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 legendary.core import LegendaryCore
|
||||||
|
|
||||||
from Rare.Components.Dialogs.InstallDialog import InstallDialog
|
from Rare.Components.Dialogs.InstallDialog import InstallDialog
|
||||||
|
from Rare.utils.Models import InstallOptions
|
||||||
|
|
||||||
logger = getLogger("Game")
|
logger = getLogger("Game")
|
||||||
|
|
||||||
|
|
||||||
class UninstalledGameWidget(QWidget):
|
class UninstalledGameWidget(QWidget):
|
||||||
install_game = pyqtSignal(dict)
|
install_game = pyqtSignal(InstallOptions)
|
||||||
|
|
||||||
def __init__(self, core: LegendaryCore, game):
|
def __init__(self, core: LegendaryCore, game):
|
||||||
super(UninstalledGameWidget, self).__init__()
|
super(UninstalledGameWidget, self).__init__()
|
||||||
self.title = game.app_title
|
self.title = game.app_title
|
||||||
|
@ -57,11 +59,9 @@ class UninstalledGameWidget(QWidget):
|
||||||
infos = InstallDialog().get_information()
|
infos = InstallDialog().get_information()
|
||||||
if infos != 0:
|
if infos != 0:
|
||||||
path, max_workers = infos
|
path, max_workers = infos
|
||||||
self.install_game.emit({
|
self.install_game.emit(InstallOptions(
|
||||||
"app_name": self.game.app_name,
|
app_name=self.game.app_name,
|
||||||
"options": {
|
path=path,
|
||||||
"path": path,
|
max_workers=max_workers,
|
||||||
"max_workers": max_workers
|
repair=False))
|
||||||
}
|
|
||||||
})
|
|
||||||
# wait for update of legendary to get progress
|
# 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.GameInfo.GameInfo import InfoTabs
|
||||||
from Rare.Components.Tabs.Games.GameList import GameList
|
from Rare.Components.Tabs.Games.GameList import GameList
|
||||||
|
from Rare.utils.QtExtensions import Switch
|
||||||
|
|
||||||
|
|
||||||
class GameTab(QWidget):
|
class GameTab(QWidget):
|
||||||
|
@ -43,7 +44,7 @@ class Games(QWidget):
|
||||||
self.layout.addWidget(self.head_bar)
|
self.layout.addWidget(self.head_bar)
|
||||||
self.layout.addWidget(self.game_list)
|
self.layout.addWidget(self.game_list)
|
||||||
# self.layout.addStretch(1)
|
# 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()))
|
lambda: self.game_list.update_list(not self.head_bar.view.isChecked()))
|
||||||
self.setLayout(self.layout)
|
self.setLayout(self.layout)
|
||||||
|
|
||||||
|
@ -64,10 +65,16 @@ class GameListHeadBar(QWidget):
|
||||||
|
|
||||||
self.layout.addStretch()
|
self.layout.addStretch()
|
||||||
self.list_view = QLabel(self.tr("List view"))
|
self.list_view = QLabel(self.tr("List view"))
|
||||||
self.layout.addWidget(self.list_view)
|
|
||||||
self.view = QCheckBox(self.tr("Icon view"))
|
self.icon_view = QLabel(self.tr("Icon view"))
|
||||||
self.view.setChecked(not QSettings().value("icon_view", True, bool))
|
|
||||||
|
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.view)
|
||||||
|
self.layout.addWidget(self.list_view)
|
||||||
|
|
||||||
self.refresh_list = QPushButton()
|
self.refresh_list = QPushButton()
|
||||||
self.refresh_list.setIcon(self.style().standardIcon(getattr(QStyle, "SP_BrowserReload"))) # Reload icon
|
self.refresh_list.setIcon(self.style().standardIcon(getattr(QStyle, "SP_BrowserReload"))) # Reload icon
|
||||||
self.layout.addWidget(self.refresh_list)
|
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
|
import os
|
||||||
|
|
||||||
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal
|
from PyQt5.QtCore import Qt, QRect, QSize, QPoint, pyqtSignal, QPropertyAnimation, pyqtSlot, QPointF, QEasingCurve, \
|
||||||
from PyQt5.QtGui import QMovie
|
QObject, pyqtProperty
|
||||||
|
from PyQt5.QtGui import QMovie, QPainter, QPalette, QLinearGradient, QGradient
|
||||||
from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLabel, QFileDialog, QHBoxLayout, QWidget, QLineEdit, \
|
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
|
from Rare import style_path
|
||||||
|
|
||||||
|
@ -191,3 +192,89 @@ class WaitingSpinner(QLabel):
|
||||||
self.movie = QMovie(style_path+"Icons/loader.gif")
|
self.movie = QMovie(style_path+"Icons/loader.gif")
|
||||||
self.setMovie(self.movie)
|
self.setMovie(self.movie)
|
||||||
self.movie.start()
|
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