1
0
Fork 0
mirror of synced 2024-06-02 10:44:40 +12:00

Update the RareStyle to handle radiobutton, disabled widgets, etc.

* Add RareStyle qrc with the icons needed for comboboxes and spinboxes
* Add images as svg
* Refactor `styles` to `resources` since it contains more things now.
* Add stylesheet folders, each folder must contain a `stylesheet.qss` file.
* Don't use QResources, instead add an identifier in the qss url() which can
  replaced later with the full path.
* Update RareStyle with SVG images for better quality.
This commit is contained in:
Stelios Tsampas 2021-05-31 22:43:50 +03:00
parent f49cc413dd
commit e8dadb6b00
31 changed files with 372 additions and 37 deletions

View file

@ -46,7 +46,7 @@ else:
src_files += [
'LICENSE',
'README.md',
'rare/styles/Logo.ico',
'rare/resources/images/Rare.ico',
]
# Dependencies are automatically detected, but it might need fine tuning.
@ -65,7 +65,7 @@ setup(name='Rare',
executables=[
Executable('rare/__main__.py',
targetName=name,
icon='rare/styles/Logo.ico',
icon='rare/resources/images/Rare.ico',
base=base,
shortcutName=shortcutName,
shortcutDir=shortcutDir,

View file

@ -1,5 +1,5 @@
import os
__version__ = "1.4.1"
style_path = os.path.join(os.path.dirname(__file__), "styles/")
lang_path = os.path.join(os.path.dirname(__file__), "languages/")
resources_path = os.path.join(os.path.dirname(__file__), "resources/")
languages_path = os.path.join(os.path.dirname(__file__), "languages/")

View file

@ -3,13 +3,14 @@ import logging
import os
import sys
import time
import importlib
from PyQt5.QtCore import QSettings, QTranslator
from PyQt5.QtCore import QSettings, QTranslator, QFile, QIODevice, QTextStream
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QStyleFactory
from custom_legendary.core import LegendaryCore
from rare import lang_path, style_path
from rare import languages_path, resources_path
from rare.components.dialogs.launch_dialog import LaunchDialog
from rare.components.main_window import MainWindow
from rare.components.tray_icon import TrayIcon
@ -67,8 +68,8 @@ class App(QApplication):
# Translator
self.translator = QTranslator()
lang = settings.value("language", get_lang(), type=str)
if os.path.exists(lang_path + lang + ".qm"):
self.translator.load(lang_path + lang + ".qm")
if os.path.exists(languages_path + lang + ".qm"):
self.translator.load(languages_path + lang + ".qm")
logger.info("Your language is supported: " + lang)
elif not lang == "en":
logger.info("Your language is not supported")
@ -81,13 +82,20 @@ class App(QApplication):
settings.setValue("style_sheet", "RareStyle")
if color := settings.value("color_scheme", False):
settings.setValue("style_sheet", "")
custom_palette = load_color_scheme(os.path.join(style_path, "colors", color + ".scheme"))
custom_palette = load_color_scheme(os.path.join(resources_path, "colors", color + ".scheme"))
if custom_palette is not None:
self.setPalette(custom_palette)
elif style := settings.value("style_sheet", False):
settings.setValue("color_scheme", "")
self.setStyleSheet(open(os.path.join(style_path, "qss", style + ".qss")).read())
self.setWindowIcon(QIcon(os.path.join(style_path, "Logo.png")))
stylesheet = open(os.path.join(resources_path, "stylesheets", style, "stylesheet.qss")).read()
self.setStyleSheet(stylesheet.replace("@path@", os.path.join(resources_path, "stylesheets", style, '')))
# lk: for qresources stylesheets, not an ideal solution for modability,
# lk: too many extra steps and I don't like binary files in git, even as strings.
# importlib.import_module("rare.resources.stylesheets." + style)
# resource = QFile(f":/{style}/stylesheet.qss")
# resource.open(QIODevice.ReadOnly)
# self.setStyleSheet(QTextStream(resource).readAll())
self.setWindowIcon(QIcon(os.path.join(resources_path, "images", "Rare.png")))
# launch app
self.launch_dialog = LaunchDialog(self.core, args.offline)

View file

@ -27,25 +27,28 @@ class ImportLogin(QWidget, Ui_ImportLogin):
self.core = core
self.text_egl_found = self.tr("Found EGL Program Data. Click 'Next' to import them.")
self.text_egl_notfound = self.tr("Could not find EGL Program Data. ")
if os.name == "nt":
if not self.core.egl.appdata_path and os.path.exists(self.egl_data_path):
self.core.egl.appdata_path = self.appdata_path
if not self.core.egl.appdata_path:
self.status_label.setText(self.tr("Could not find EGL Program Data."))
self.status_label.setText(self.text_egl_notfound)
else:
self.status_label.setText(self.tr("Found EGL Program Data. Click 'Next' to import them."))
self.status_label.setText(self.text_egl_found)
self.found = True
else:
self.info_label.setText(
self.tr(
"Please select the Wine prefix where Epic Games Launcher is installed. ") + self.info_label.text()
self.info_label.setText(self.tr(
"Please select the Wine prefix"
" where Epic Games Launcher is installed. ") + self.info_label.text()
)
prefixes = self.get_wine_prefixes()
if len(prefixes):
self.prefix_combo.addItems(prefixes)
self.status_label.setText(self.tr("Select the Wine prefix you want to import."))
else:
self.status_label.setText(self.tr("Could not any EGL Program Data."))
self.status_label.setText(self.text_egl_notfound)
self.prefix_tool.clicked.connect(self.prefix_path)
self.prefix_combo.editTextChanged.connect(self.changed.emit)
@ -86,6 +89,7 @@ class ImportLogin(QWidget, Ui_ImportLogin):
self.success.emit()
else:
self.status_label.setText(self.tr("Login failed."))
logger.warning("Failed to import existing session")
logger.warning("Failed to import existing session.")
except Exception as e:
logger.warning(e)
self.status_label.setText(self.tr("Login failed. ") + str(e))
logger.warning("Failed to import existing session: " + str(e))

View file

@ -1,13 +1,15 @@
import os
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QSystemTrayIcon, QMenu, QAction
from rare import style_path
from rare import resources_path
class TrayIcon(QSystemTrayIcon):
def __init__(self, parent):
super(TrayIcon, self).__init__(parent)
self.setIcon(QIcon(style_path + "Logo.png"))
self.setIcon(QIcon(os.path.join(resources_path, "images", "Rare.png")))
self.setVisible(True)
self.setToolTip("Rare")

View file

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -0,0 +1 @@
<svg height="736" viewBox="0 0 736 736" width="736" xmlns="http://www.w3.org/2000/svg"><path d="m368 120c-137 0-248 111-248 248s111 248 248 248 248-111 248-248-111-248-248-248z" fill="#43474d"/></svg>

After

Width:  |  Height:  |  Size: 200 B

View file

@ -0,0 +1 @@
<svg height="736" viewBox="0 0 736 736" width="736" xmlns="http://www.w3.org/2000/svg"><path d="m368 120c-137 0-248 111-248 248s111 248 248 248 248-111 248-248-111-248-248-248z" fill="#483d8b"/></svg>

After

Width:  |  Height:  |  Size: 200 B

View file

@ -0,0 +1 @@
<svg height="640" viewBox="0 0 320 640" width="320" xmlns="http://www.w3.org/2000/svg"><path d="m41 236.475h238c21.4 0 32.1 25.9 17 41l-119 119c-9.4 9.4-24.6 9.4-33.9 0l-119.1-119c-15.1-15.1-4.4-41 17-41z" fill="#eee"/></svg>

After

Width:  |  Height:  |  Size: 225 B

View file

@ -0,0 +1 @@
<svg height="320" viewBox="0 0 320 320" width="320" xmlns="http://www.w3.org/2000/svg"><path d="m41 76.475h238c21.4 0 32.1 25.9 17 41l-119 119c-9.4 9.4-24.6 9.4-33.9 0l-119.1-119c-15.1-15.1-4.4-41 17-41z" fill="#eee"/></svg>

After

Width:  |  Height:  |  Size: 224 B

View file

@ -0,0 +1 @@
<svg height="320" viewBox="0 0 320 320" width="320" xmlns="http://www.w3.org/2000/svg"><path d="m279.01546 243.525h-237.999997c-21.4 0-32.1000001-25.9-17-41l118.999997-119c9.4-9.4 24.6-9.4 33.9 0l119 119c15.2 15.1 4.5 41-16.9 41z" fill="#eee"/></svg>

After

Width:  |  Height:  |  Size: 250 B

View file

@ -0,0 +1 @@
<svg height="688" viewBox="0 0 688 688" width="688" xmlns="http://www.w3.org/2000/svg"><path d="m520 120h-352c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-352c0-26.5-21.5-48-48-48z" fill="#43474d"/></svg>

After

Width:  |  Height:  |  Size: 232 B

View file

@ -0,0 +1 @@
<svg height="688" viewBox="0 0 688 688" width="688" xmlns="http://www.w3.org/2000/svg"><path d="m520 120h-352c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-352c0-26.5-21.5-48-48-48z" fill="#483d8b"/></svg>

After

Width:  |  Height:  |  Size: 232 B

View file

@ -0,0 +1,314 @@
/*
$active_base = #202225;
$active_text = #eeeeee;
$widget_base = #333344;
$primary_border = #42474E;
$secondary_border = darkslategrey;
*/
* { background-color: #202225; }
* { color: #eeeeee; }
* { border-color: darkslateblue; }
*::disabled,
*::drop-down:disabled {
color: #43474d;
border-color: #43474d;
background-color: #202225;
}
QLabel {
border-width: 0px;
background-color: transparent;
padding: 0px;
}
QMenu,
QListView,
QListWidget,
QFrame[frameShape="6"],
QLineEdit,
QTextEdit,
QTimeEdit,
QDateEdit,
QDateTimeEdit,
QComboBox,
QComboBox:editable,
QComboBox QAbstractItemView,
QSpinBox,
QDoubleSpinBox,
QProgressBar,
QScrollBar {
border-width: 1px;
border-style: solid;
border-radius: 2px;
padding: 2px;
}
QListView,
QListWidget,
QLineEdit,
QTextEdit,
QTimeEdit,
QDateEdit,
QDateTimeEdit,
QComboBox:editable,
QComboBox QAbstractItemView,
QSpinBox,
QDoubleSpinBox,
QProgressBar,
QScrollBar {
border-color: darkslategray;
background-color: #333344;
selection-background-color: darkslategray;
}
QComboBox {
background-color: #3c3f41;
}
*::item:selected,
QComboBox QAbstractItemView {
selection-background-color: darkslategray;
}
*::drop-down,
*::drop-down:editable,
*::up-button,
*::down-button {
subcontrol-origin: border;
border-width: 1px;
border-style: solid;
border-radius: 2px;
border-top-left-radius: 0px;
border-bottom-left-radius: 0px;
}
*::drop-down {
subcontrol-position: top right;
border-color: darkslateblue;
border-left-color: #5246a0; /* darkslateblue lighter */
}
*::drop-down:editable,
*::up-button ,
*::down-button {
border-color: darkslategray;
background-color: #3c3f41;
}
*::drop-down,
*::drop-down:editable {
width: 14px;
image: url(@path@drop-down.svg);
}
*::up-button ,
*::down-button {
width: 14px; /* 16 + 2*1px border-width = 15px padding + 3px parent border */
}
*::up-button {
subcontrol-position: top right; /* position at the top right corner */
border-bottom-width: 1;
image: url(@path@sort-up.svg);
}
*::down-button {
subcontrol-position: bottom right; /* position at bottom right corner */
border-top-width: 1;
image: url(@path@sort-down.svg);
}
QProgressBar {
text-align: center;
}
QProgressBar::chunk {
width: 9.5%;
margin: 0.5%;
background-color: darkslategray;
}
QScrollBar {
border-radius: 6px;
padding: 1px;
}
QScrollBar::add-line:vertical,
QScrollBar::sub-line:vertical,
QScrollBar::add-line:horizontal,
QScrollBar::sub-line:horizontal {
border: none;
height: 0px;
background: transparent;
}
QScrollBar::add-line:vertical {
subcontrol-position: top;
subcontrol-origin: margin;
}
QScrollBar::sub-line:vertical {
subcontrol-position: bottom;
subcontrol-origin: margin;
}
QScrollBar::add-line:horizontal {
subcontrol-position: right;
subcontrol-origin: margin;
}
QScrollBar::sub-line:horizontal {
subcontrol-position: left;
subcontrol-origin: margin;
}
QScrollBar::handle {
border-width: 1px;
border-style: solid;
border-color: lightgray;
background-color: gray;
border-radius: 4px;
min-height: 20px;
min-width: 20px;
}
QPushButton,
QToolButton {
background-color: #3c3f41;
}
QPushButton::hover,
QToolButton::hover {
background-color: #222233;
}
QPushButton,
QToolButton {
border-width: 1px;
border-style: solid;
border-radius: 2px;
padding: 2px;
padding-left: 6px;
padding-right: 6px
}
QPushButton::menu-indicator {
subcontrol-position: right center;
subcontrol-origin: padding;
left: -2px;
border-style: none;
}
QPushButton#menu {
padding: 0px;
margin: 0px;
border-style: none;
}
QPushButton#menu_button {
background-color: transparent;
border: none;
}
QPushButton:hover#menu_button {
background-color: #334;
}
QGroupBox,
QCheckBox,
QRadioButton {
background-color: none;
}
QGroupBox::indicator,
QCheckBox::indicator,
QRadioButton::indicator {
border-color: darkslategray;
border-width: 1px;
border-style: solid;
}
QCheckBox::indicator,
QRadioButton::indicator {
width: 11px;
height: 11px;
}
QGroupBox::indicator:disabled,
QCheckBox::indicator:disabled,
QRadioButton::indicator:disabled {
border-color: #43474d;
}
QRadioButton::indicator {
border-radius: 5%;
}
QGroupBox::indicator,
QCheckBox::indicator {
border-radius: 2px;
}
QGroupBox::indicator:checked,
QCheckBox::indicator:checked {
border-radius: 2px;
image: url(@path@square.svg);
}
QRadioButton::indicator:checked {
border-radius: 5%;
image: url(@path@circle.svg);
}
QGroupBox::indicator:checked:disabled,
QCheckBox::indicator:checked:disabled {
image: url(@path@square-disabled.svg);
}
QRadioButton::indicator:checked:disabled {
image: url(@path@circle-disabled.svg);
}
QGroupBox,
QGroupBox#group,
QGroupBox#settings_widget {
border-width: 1px;
border-style: solid;
border-radius: 4px;
font-size: 11px;
font-weight: bold;
margin-top: 3ex;
padding: 1px;
}
QGroupBox#game_widget_icon {
border: none;
padding: 0px;
margin: 0px;
}
QSizeGrip {
image: none;
width: 4px;
height: 4px;
}
#list_widget {
border-top-width: 2px;
}
#search_bar {
padding: 3px;
border-radius: 5px;
background-color: #334;
}
QPushButton:hover#installed_menu_button {
background-color: green;
}
QTabBar#main_tab_bar {
border-bottom: none;
background-color: #2b2b2c;
}
QTabBar::tab#main_tab_bar {
border-bottom: none;
}
QTabBar::tab#main_tab_bar {
border-bottom: none;
padding: 5px
}
QTabBar::tab:selected#main_tab_bar {
background-color: gray;
}
QTabBar::tab:hover#main_tab_bar {
border-bottom: 2px solid black;
}
QTabBar::tab#settings_bar {
border-radius: 0;
}
QTabBar::tab:hover#settings_bar {
border-left: 2px solid white;
}
QTabBar::tab::selected#settings_bar {
background-color: darkslategray;
}
QTabBar::tab:disabled#settings_bar {
color: transparent;
background-color: transparent;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

View file

@ -14,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_ImportLogin(object):
def setupUi(self, ImportLogin):
ImportLogin.setObjectName("ImportLogin")
ImportLogin.resize(246, 117)
ImportLogin.resize(503, 173)
ImportLogin.setWindowTitle("ImportLogin")
self.import_layout = QtWidgets.QGridLayout(ImportLogin)
self.import_layout.setObjectName("import_layout")
@ -67,7 +67,7 @@ class Ui_ImportLogin(object):
_translate = QtCore.QCoreApplication.translate
self.info_label.setText(_translate("ImportLogin", "You will get logged out from EGL in the process."))
self.title_label.setText(_translate("ImportLogin", "Import existing session from EGL"))
self.prefix_label.setText(_translate("ImportLogin", "Select prefix"))
self.prefix_label.setText(_translate("ImportLogin", "Select path"))
self.prefix_tool.setText(_translate("ImportLogin", "Browse"))

View file

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>246</width>
<height>117</height>
<width>503</width>
<height>173</height>
</rect>
</property>
<property name="windowTitle">
@ -58,7 +58,7 @@
<item row="1" column="0">
<widget class="QLabel" name="prefix_label">
<property name="text">
<string>Select prefix</string>
<string>Select path</string>
</property>
</widget>
</item>

View file

@ -6,7 +6,7 @@ from PyQt5.QtWidgets import QLayout, QStyle, QSizePolicy, QLabel, QFileDialog, Q
QStyleOptionTab, QStylePainter, QTabBar
from qtawesome import icon
from rare import style_path
from rare import resources_path
from rare.ui.utils.pathedit import Ui_PathEdit
@ -213,7 +213,7 @@ class WaitingSpinner(QLabel):
margin-left: auto;
margin-right: auto;
""")
self.movie = QMovie(os.path.join(style_path, "loader.gif"))
self.movie = QMovie(os.path.join(resources_path, "images", "loader.gif"))
self.setMovie(self.movie)
self.movie.start()

View file

@ -13,7 +13,7 @@ from PyQt5.QtGui import QPalette, QColor
if os.name == "nt":
from win32com.client import Dispatch
from rare import lang_path, style_path
from rare import languages_path, resources_path
# Mac not supported
from custom_legendary.core import LegendaryCore
@ -180,23 +180,23 @@ def load_color_scheme(path: str):
def get_color_schemes():
colors = []
for file in os.listdir(os.path.join(style_path, "colors")):
if file.endswith(".scheme") and os.path.isfile(os.path.join(style_path, "colors", file)):
for file in os.listdir(os.path.join(resources_path, "colors")):
if file.endswith(".scheme") and os.path.isfile(os.path.join(resources_path, "colors", file)):
colors.append(file.replace(".scheme", ""))
return colors
def get_style_sheets():
styles = []
for file in os.listdir(os.path.join(style_path, "qss")):
if file.endswith(".qss") and os.path.isfile(os.path.join(style_path, "qss", file)):
styles.append(file.replace(".qss", ""))
for folder in os.listdir(os.path.join(resources_path, "stylesheets")):
if os.path.isfile(os.path.join(resources_path, "stylesheets", folder, "stylesheet.qss")):
styles.append(folder)
return styles
def get_possible_langs():
langs = ["en"]
for i in os.listdir(lang_path):
for i in os.listdir(languages_path):
if i.endswith(".qm"):
langs.append(i.split(".")[0])
return langs
@ -232,7 +232,7 @@ def create_rare_desktop_link(type_of_link):
desktop_file.write("[Desktop Entry]\n"
f"Name=Rare\n"
f"Type=Application\n"
f"Icon={os.path.join(style_path, 'Logo.png')}\n"
f"Icon={os.path.join(resources_path, 'images', 'Rare.png')}\n"
f"Exec={os.path.abspath(sys.argv[0])}\n"
"Terminal=false\n"
"StartupWMClass=rare\n"
@ -262,7 +262,7 @@ def create_rare_desktop_link(type_of_link):
shortcut.WorkingDirectory = os.getcwd()
# Icon
shortcut.IconLocation = os.path.join(style_path, "Logo.ico")
shortcut.IconLocation = os.path.join(resources_path, "images", "Rare.ico")
shortcut.save()