init new Version
This commit is contained in:
parent
e6b5a50b90
commit
c9c52b0917
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/images/
|
80
Rare.py
80
Rare.py
|
@ -425,46 +425,48 @@ def startMainProcess(loggedIn=False):
|
|||
# Since some games have the background and logo split into two files,
|
||||
# we have to do some extra logic to combine those
|
||||
if not os.path.isfile('images/' + game["app_name"] + '/FinalArt.png'):
|
||||
print('Scaling cover for ' + game["app_name"])
|
||||
# First off, check if the extra logo file is even there
|
||||
if os.path.isfile('images/' + game["app_name"] + '/DieselGameBoxLogo.png'):
|
||||
# Load in the two images that need to be combined
|
||||
bg = Image.open('images/' + game["app_name"] + '/DieselGameBoxTall.png')
|
||||
# To make sure the background is actually horizontal (3/4) (looking at you Celeste), resize the image
|
||||
bg = bg.resize((int(bg.size[1] * 3 / 4), bg.size[1]))
|
||||
# Since the logo is transparent, we have to convert it to RGBA
|
||||
logo = Image.open('images/' + game["app_name"] + '/DieselGameBoxLogo.png').convert('RGBA')
|
||||
# Resize the logo to be ~ 3/4 as wide as the background (EGL does something like this)
|
||||
wpercent = ((bg.size[0] * (3 / 4)) / float(logo.size[0]))
|
||||
hsize = int((float(logo.size[1]) * float(wpercent)))
|
||||
logo = logo.resize((int(bg.size[0] * (3 / 4)), hsize), Image.ANTIALIAS)
|
||||
# Calculate where the image has to be placed
|
||||
pasteX = int((bg.size[0] - logo.size[0]) / 2)
|
||||
pasteY = int((bg.size[1] - logo.size[1]) / 2)
|
||||
# And finally copy the background and paste in the image
|
||||
finalArt = bg.copy()
|
||||
finalArt.paste(logo, (pasteX, pasteY), logo)
|
||||
# Write out the file
|
||||
finalArt.save('images/' + game["app_name"] + '/FinalArt.png')
|
||||
|
||||
# And we have to do part of that again
|
||||
# since the cover for an uninstalled game has the logo half-transparent
|
||||
logoCopy = logo.copy()
|
||||
logoCopy.putalpha(int(256 * 3 / 4))
|
||||
logo.paste(logoCopy, logo)
|
||||
uninstalledArt = bg.copy()
|
||||
uninstalledArt.paste(logo, (pasteX, pasteY), logo)
|
||||
uninstalledArt = uninstalledArt.convert('L')
|
||||
uninstalledArt.save('images/' + game["app_name"] + '/UninstalledArt.png')
|
||||
# And if the logo and background aren't split
|
||||
else:
|
||||
# We just open up the background and save that as the final image
|
||||
finalArt = Image.open('images/' + game["app_name"] + '/DieselGameBoxTall.png')
|
||||
finalArt.save('images/' + game["app_name"] + '/FinalArt.png')
|
||||
# And same with the grayscale one
|
||||
uninstalledArt = finalArt.convert('L')
|
||||
uninstalledArt.save('images/' + game["app_name"] + '/UninstalledArt.png')
|
||||
try:
|
||||
print('Scaling cover for ' + game["app_name"])
|
||||
# First off, check if the extra logo file is even there
|
||||
if os.path.isfile('images/' + game["app_name"] + '/DieselGameBoxLogo.png'):
|
||||
# Load in the two images that need to be combined
|
||||
bg = Image.open('images/' + game["app_name"] + '/DieselGameBoxTall.png')
|
||||
# To make sure the background is actually horizontal (3/4) (looking at you Celeste), resize the image
|
||||
bg = bg.resize((int(bg.size[1] * 3 / 4), bg.size[1]))
|
||||
# Since the logo is transparent, we have to convert it to RGBA
|
||||
logo = Image.open('images/' + game["app_name"] + '/DieselGameBoxLogo.png').convert('RGBA')
|
||||
# Resize the logo to be ~ 3/4 as wide as the background (EGL does something like this)
|
||||
wpercent = ((bg.size[0] * (3 / 4)) / float(logo.size[0]))
|
||||
hsize = int((float(logo.size[1]) * float(wpercent)))
|
||||
logo = logo.resize((int(bg.size[0] * (3 / 4)), hsize), Image.ANTIALIAS)
|
||||
# Calculate where the image has to be placed
|
||||
pasteX = int((bg.size[0] - logo.size[0]) / 2)
|
||||
pasteY = int((bg.size[1] - logo.size[1]) / 2)
|
||||
# And finally copy the background and paste in the image
|
||||
finalArt = bg.copy()
|
||||
finalArt.paste(logo, (pasteX, pasteY), logo)
|
||||
# Write out the file
|
||||
finalArt.save('images/' + game["app_name"] + '/FinalArt.png')
|
||||
|
||||
# And we have to do part of that again
|
||||
# since the cover for an uninstalled game has the logo half-transparent
|
||||
logoCopy = logo.copy()
|
||||
logoCopy.putalpha(int(256 * 3 / 4))
|
||||
logo.paste(logoCopy, logo)
|
||||
uninstalledArt = bg.copy()
|
||||
uninstalledArt.paste(logo, (pasteX, pasteY), logo)
|
||||
uninstalledArt = uninstalledArt.convert('L')
|
||||
uninstalledArt.save('images/' + game["app_name"] + '/UninstalledArt.png')
|
||||
# And if the logo and background aren't split
|
||||
else:
|
||||
# We just open up the background and save that as the final image
|
||||
finalArt = Image.open('images/' + game["app_name"] + '/DieselGameBoxTall.png')
|
||||
finalArt.save('images/' + game["app_name"] + '/FinalArt.png')
|
||||
# And same with the grayscale one
|
||||
uninstalledArt = finalArt.convert('L')
|
||||
uninstalledArt.save('images/' + game["app_name"] + '/UninstalledArt.png')
|
||||
except:
|
||||
pass
|
||||
#If the user had to login first, the QApplication will already be running, so we don't have to start it again
|
||||
if not loggedIn:
|
||||
# Start GUI stuff
|
||||
|
|
92
Rare/FlowLayout.py
Normal file
92
Rare/FlowLayout.py
Normal file
|
@ -0,0 +1,92 @@
|
|||
from PyQt5 import Qt
|
||||
from PyQt5.QtCore import QRect, QPoint, QSize
|
||||
from PyQt5.QtWidgets import QSizePolicy, QLayout
|
||||
|
||||
|
||||
class FlowLayout(QLayout):
|
||||
def __init__(self, parent=None, margin=0, spacing=-1):
|
||||
super(FlowLayout, self).__init__(parent)
|
||||
|
||||
if parent is not None:
|
||||
self.setContentsMargins(margin, margin, margin, margin)
|
||||
|
||||
self.setSpacing(spacing)
|
||||
|
||||
self.itemList = []
|
||||
|
||||
def __del__(self):
|
||||
item = self.takeAt(0)
|
||||
while item:
|
||||
item = self.takeAt(0)
|
||||
|
||||
def addItem(self, item):
|
||||
self.itemList.append(item)
|
||||
|
||||
def count(self):
|
||||
return len(self.itemList)
|
||||
|
||||
def itemAt(self, index):
|
||||
if index >= 0 and index < len(self.itemList):
|
||||
return self.itemList[index]
|
||||
|
||||
return None
|
||||
|
||||
def takeAt(self, index):
|
||||
if index >= 0 and index < len(self.itemList):
|
||||
return self.itemList.pop(index)
|
||||
|
||||
return None
|
||||
|
||||
def expandingDirections(self):
|
||||
return Qt.Orientations(Qt.Orientation(0))
|
||||
|
||||
def hasHeightForWidth(self):
|
||||
return True
|
||||
|
||||
def heightForWidth(self, width):
|
||||
height = self.doLayout(QRect(0, 0, width, 0), True)
|
||||
return height
|
||||
|
||||
def setGeometry(self, rect):
|
||||
super(FlowLayout, self).setGeometry(rect)
|
||||
self.doLayout(rect, False)
|
||||
|
||||
def sizeHint(self):
|
||||
return self.minimumSize()
|
||||
|
||||
def minimumSize(self):
|
||||
size = QSize()
|
||||
|
||||
for item in self.itemList:
|
||||
size = size.expandedTo(item.minimumSize())
|
||||
|
||||
margin, _, _, _ = self.getContentsMargins()
|
||||
|
||||
size += QSize(2 * margin, 2 * margin)
|
||||
return size
|
||||
|
||||
def doLayout(self, rect, testOnly):
|
||||
x = rect.x()
|
||||
y = rect.y()
|
||||
lineHeight = 0
|
||||
|
||||
for item in self.itemList:
|
||||
wid = item.widget()
|
||||
spaceX = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton,
|
||||
Qt.Horizontal)
|
||||
spaceY = self.spacing() + wid.style().layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton,
|
||||
Qt.Vertical)
|
||||
nextX = x + item.sizeHint().width() + spaceX
|
||||
if nextX - spaceX > rect.right() and lineHeight > 0:
|
||||
x = rect.x()
|
||||
y = y + lineHeight + spaceY
|
||||
nextX = x + item.sizeHint().width() + spaceX
|
||||
lineHeight = 0
|
||||
|
||||
if not testOnly:
|
||||
item.setGeometry(QRect(QPoint(x, y), item.sizeHint()))
|
||||
|
||||
x = nextX
|
||||
lineHeight = max(lineHeight, item.sizeHint().height())
|
||||
|
||||
return y + lineHeight - rect.y()
|
44
Rare/GameWidget.py
Normal file
44
Rare/GameWidget.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
import qtawesome as qta
|
||||
from PyQt5.QtGui import QPixmap
|
||||
from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QVBoxLayout, QPushButton
|
||||
|
||||
|
||||
class GameWidget(QWidget):
|
||||
def __init__(self, game):
|
||||
super(GameWidget, self).__init__()
|
||||
# self.setStyleSheet("border:1px solid rgb(0, 0, 0)")
|
||||
|
||||
self.title = game.title
|
||||
self.version = game.version
|
||||
|
||||
self.layout = QHBoxLayout()
|
||||
|
||||
|
||||
self.pixmap = QPixmap(f"../images/{game.app_name}/FinalArt.png")
|
||||
self.pixmap = self.pixmap.scaled(240, 320)
|
||||
self.image = QLabel()
|
||||
self.image.setPixmap(self.pixmap)
|
||||
self.layout.addWidget(self.image)
|
||||
|
||||
##Layout on the right
|
||||
self.childLayout = QVBoxLayout()
|
||||
|
||||
self.childLayout.addWidget(QLabel(f"<h1>{self.title}</h1>"))
|
||||
play_icon = qta.icon('fa5s.play')
|
||||
|
||||
self.launch_button = QPushButton(play_icon, "Launch")
|
||||
self.launch_button.clicked.connect(self.launch)
|
||||
self.wine_rating = QLabel("Wine Rating: Comming Soon")
|
||||
self.version_label = QLabel("Version: " + str(self.version))
|
||||
|
||||
self.childLayout.addWidget(self.launch_button)
|
||||
self.childLayout.addWidget(self.wine_rating)
|
||||
self.childLayout.addWidget(self.version_label)
|
||||
|
||||
self.childLayout.addStretch(1)
|
||||
# self.layout.addWidget(QLabel(game.title))
|
||||
self.layout.addLayout(self.childLayout)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
def launch(self):
|
||||
print(f"launch {self.title}")
|
79
Rare/Main.py
Normal file
79
Rare/Main.py
Normal file
|
@ -0,0 +1,79 @@
|
|||
import json
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from PyQt5.QtGui import QPixmap
|
||||
from PyQt5.QtWidgets import QStackedLayout, QScrollArea
|
||||
|
||||
import Rare
|
||||
from Rare import FlowLayout
|
||||
from Rare.ShowGame import GameWidget
|
||||
|
||||
|
||||
class BodyGames(QScrollArea):
|
||||
def __init__(self, allGames, installedGames):
|
||||
super().__init__()
|
||||
self.allGames = allGames
|
||||
self.installedGames = installedGames
|
||||
self.initUI()
|
||||
|
||||
def initUI(self):
|
||||
self.layout = FlowLayout.FlowLayout()
|
||||
self.setLayout(self.layout)
|
||||
for game in self.allGames:
|
||||
self.layout.addWidget(GameWidget(game=game, installed=game['app_name'] in self.installedGames))
|
||||
|
||||
def addImage(self, pathToImage, layout, x, y):
|
||||
self.label = Rare.ExtendedQLabel()
|
||||
self.label.setPixmap(QPixmap(pathToImage).scaled(240, 320))
|
||||
self.label.clicked.connect(lambda: self.clickedGame(pathToImage.split('/', 2)[1]))
|
||||
self.label.rightClicked.connect(lambda: self.gameSettings(pathToImage.split('/', 2)[1]))
|
||||
layout.addWidget(self.label, x, y)
|
||||
|
||||
def clickedGame(self, game):
|
||||
self.game = game
|
||||
if self.game in self.installedGames:
|
||||
self.launchGame(self.game)
|
||||
else:
|
||||
self.installGame(self.game)
|
||||
|
||||
# def launchGame(self, game):
|
||||
# self.window = LaunchWindow(game)
|
||||
# self.window.show()
|
||||
# self.window.outputWindow.appendPlainText('> legendary launch ' + game + '\n')
|
||||
# self.window.reader.start('legendary', ['launch', game])
|
||||
|
||||
def installGame(self, game):
|
||||
self.window = Rare.InstallWindow(game)
|
||||
self.window.show()
|
||||
|
||||
def gameSettings(self, game):
|
||||
self.window = Rare.GameSettingsWindow(game)
|
||||
self.window.show()
|
||||
|
||||
|
||||
class Body(QStackedLayout):
|
||||
def __init__(self):
|
||||
super(Body, self).__init__()
|
||||
|
||||
all, installed = self.get_games()
|
||||
self.addWidget(BodyGames(all, installed))
|
||||
|
||||
def get_games(self):
|
||||
all_games = []
|
||||
for filename in os.listdir(os.path.expanduser("~") + '/.config/legendary/metadata/'):
|
||||
with open(os.path.expanduser("~") + '/.config/legendary/metadata/' + filename, 'r') as f:
|
||||
game = json.load(f)
|
||||
all_games.append(game)
|
||||
try:
|
||||
os.mkdir('images/' + game["app_name"])
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# print('Parsing installed games')
|
||||
installedGames = []
|
||||
for line in subprocess.Popen('legendary list-installed --csv | tail -n +2', shell=True,
|
||||
stdout=subprocess.PIPE, universal_newlines=True).stdout:
|
||||
installedGames.append(line.split(',', 1)[0])
|
||||
|
||||
return all_games, installedGames
|
46
Rare/MainRare.py
Normal file
46
Rare/MainRare.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
import sys
|
||||
|
||||
from PyQt5.QtWidgets import QTabWidget, QMainWindow, QWidget, QApplication
|
||||
|
||||
from Rare.TabWidgets import Settings, GameListInstalled, BrowserTab, GameListUninstalled, UpdateList
|
||||
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setWindowTitle("Rare")
|
||||
self.setGeometry(0, 0, 800, 600)
|
||||
self.setCentralWidget(TabWidget(self))
|
||||
self.show()
|
||||
|
||||
|
||||
class TabWidget(QTabWidget):
|
||||
|
||||
def __init__(self, parent):
|
||||
super(QWidget, self).__init__(parent)
|
||||
|
||||
self.game_list = GameListInstalled(self)
|
||||
self.addTab(self.game_list, "Games")
|
||||
|
||||
self.uninstalled_games = GameListUninstalled(self)
|
||||
self.addTab(self.uninstalled_games, "Install Games")
|
||||
|
||||
self.update_tab = UpdateList(self)
|
||||
self.addTab(self.update_tab, "Updates")
|
||||
|
||||
self.browser = BrowserTab(self)
|
||||
self.addTab(self.browser, "Store")
|
||||
|
||||
self.settings = Settings(self)
|
||||
self.addTab(self.settings, "Settings")
|
||||
|
||||
|
||||
def main():
|
||||
app = QApplication(sys.argv)
|
||||
ex = MainWindow()
|
||||
sys.exit(app.exec_())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
56
Rare/TabWidgets.py
Normal file
56
Rare/TabWidgets.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
from PyQt5.QtCore import QUrl, Qt
|
||||
from PyQt5.QtWebEngineWidgets import QWebEngineView
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QScrollArea
|
||||
|
||||
from Rare.utils.legendary import get_installed
|
||||
from Rare.GameWidget import GameWidget
|
||||
|
||||
|
||||
class BrowserTab(QWebEngineView):
|
||||
def __init__(self, parent):
|
||||
super(BrowserTab, self).__init__(parent=parent)
|
||||
self.load(QUrl("https://www.epicgames.com/store/"))
|
||||
self.show()
|
||||
|
||||
|
||||
class Settings(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(Settings, self).__init__(parent=parent)
|
||||
self.layout = QVBoxLayout()
|
||||
label = QLabel()
|
||||
print(label.fontInfo().pixelSize())
|
||||
self.layout.addWidget(QLabel("<h1>Settings</h1>"))
|
||||
self.layout.addWidget(QLabel("Coming soon"))
|
||||
self.layout.addStretch(1)
|
||||
self.setLayout(self.layout)
|
||||
|
||||
|
||||
class GameListInstalled(QScrollArea):
|
||||
def __init__(self, parent):
|
||||
super(GameListInstalled, self).__init__(parent=parent)
|
||||
self.widget = QWidget()
|
||||
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
|
||||
|
||||
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
self.layout = QVBoxLayout()
|
||||
for i in get_installed():
|
||||
widget = GameWidget(i)
|
||||
#widget.setFixedSize(240, 340)
|
||||
self.layout.addWidget(widget)
|
||||
|
||||
self.widget.setLayout(self.layout)
|
||||
self.setWidget(self.widget)
|
||||
|
||||
|
||||
class GameListUninstalled(QScrollArea):
|
||||
def __init__(self, parent):
|
||||
super(GameListUninstalled, self).__init__(parent=parent)
|
||||
self.setWidget(QLabel("Hier kommen die nicht installierten Spiele"))
|
||||
|
||||
|
||||
class UpdateList(QWidget):
|
||||
def __init__(self, parent):
|
||||
super(UpdateList, self).__init__(parent=parent)
|
||||
self.layout = QVBoxLayout()
|
||||
self.layout.addWidget(QLabel("Updates"))
|
||||
self.setLayout(self.layout)
|
1
Rare/__init__.py
Normal file
1
Rare/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
__version__="0.0.1"
|
0
Rare/utils/__init__.py
Normal file
0
Rare/utils/__init__.py
Normal file
40
Rare/utils/legendary.py
Normal file
40
Rare/utils/legendary.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
import subprocess
|
||||
|
||||
from legendary.cli import LegendaryCLI
|
||||
from legendary.core import LegendaryCore
|
||||
|
||||
core = LegendaryCore()
|
||||
cli = LegendaryCLI
|
||||
|
||||
|
||||
def get_installed():
|
||||
return core.get_installed_list()
|
||||
# games = sorted(get_installed, key=lambda x: x.title)
|
||||
|
||||
|
||||
def get_installed_names():
|
||||
names = []
|
||||
for i in core.get_installed_list():
|
||||
names.append(i.app_name)
|
||||
return names
|
||||
|
||||
|
||||
# return (games, dlcs)
|
||||
def get_games_and_dlcs():
|
||||
if not core.login():
|
||||
print("Login Failed")
|
||||
exit(1)
|
||||
print('Getting game list... (this may take a while)')
|
||||
return core.get_game_and_dlc_list()
|
||||
|
||||
|
||||
def get_games():
|
||||
if not core.login():
|
||||
print("Login Failed")
|
||||
exit(1)
|
||||
print('Getting game list... (this may take a while)')
|
||||
return core.get_game_list()
|
||||
|
||||
|
||||
def start(game_name: str, args):
|
||||
subprocess.run(["legendary", "launch", game_name])
|
Loading…
Reference in a new issue