0ea4b1a824
Also add a dialog to select optional downloads before verifying and refactor the move widget into a full-fledged dialog. To keep dialogs in a common format and allow them to share the same properties, three classes of dialogs have been implemented inheriting from each other. The classes are `BaseDialog` -> `ButtonDialog` -> `ActionDialog` * Basedialog: is the basis of all dialogs and is responsible for rejecting close requests from the window manager and the keyboard. It also restricts access to `exec()` and `exec_()` because they are harmful. It serves as the basis of Launch and Login dialogs * ButtonDialog: is offering buttons for accepting or rejecting the presented option. It implements its own buttons and exposes abstract methods to implement handling in them. It restricts access to `close()` because these dialogs should always product a result. It is the basis of Uninstall, Selective dialogs. * ActionDialog: in addition to the ButtonDialog, it offers an action buttom with to validate the form or to make the dialog unable to close. It serves as the basis of Install and Move dialogs. Accordingly all dialogs in Rare have been updated to use these classes.
334 lines
13 KiB
Python
334 lines
13 KiB
Python
from abc import abstractmethod
|
|
from enum import Enum, IntEnum
|
|
from logging import getLogger
|
|
from typing import List, Dict, Tuple, Any, Union
|
|
|
|
from PyQt5.QtCore import QCoreApplication, pyqtSignal
|
|
from PyQt5.QtGui import QIntValidator, QDoubleValidator, QShowEvent
|
|
from PyQt5.QtWidgets import QGroupBox, QCheckBox, QLineEdit, QComboBox
|
|
|
|
from rare.shared import LegendaryCoreSingleton
|
|
from rare.ui.components.tabs.settings.widgets.overlay import Ui_OverlaySettings
|
|
from rare.utils import config_helper as config
|
|
|
|
logger = getLogger("GameOverlays")
|
|
|
|
|
|
class OverlayLineEdit(QLineEdit):
|
|
def __init__(self, parent=None):
|
|
super(OverlayLineEdit, self).__init__(parent=parent)
|
|
self.valueChanged = self.textChanged
|
|
self.setValue = self.setText
|
|
|
|
def setDefault(self):
|
|
self.setText("")
|
|
|
|
def getValue(self):
|
|
return self.text()
|
|
|
|
|
|
class OverlayComboBox(QComboBox):
|
|
def __init__(self, parent=None):
|
|
super(OverlayComboBox, self).__init__(parent=parent)
|
|
self.valueChanged = self.currentIndexChanged
|
|
self.getValue = self.currentText
|
|
self.setValue = self.setCurrentText
|
|
|
|
def setDefault(self):
|
|
self.setCurrentIndex(0)
|
|
|
|
|
|
class CustomOption:
|
|
option: str
|
|
widget: Union[OverlayLineEdit, OverlayComboBox]
|
|
|
|
@classmethod
|
|
def string_input(cls, option: str, placeholder: str):
|
|
tmp = cls()
|
|
tmp.option = option
|
|
tmp.widget = OverlayLineEdit()
|
|
tmp.widget.setPlaceholderText(placeholder)
|
|
return tmp
|
|
|
|
@classmethod
|
|
def number_input(cls, option: str, placeholder: Any, is_float: bool = False):
|
|
tmp = cls()
|
|
tmp.option = option
|
|
tmp.widget = OverlayLineEdit()
|
|
tmp.widget.setPlaceholderText(str(placeholder))
|
|
validator = QDoubleValidator() if is_float else QIntValidator()
|
|
tmp.widget.setValidator(validator)
|
|
return tmp
|
|
|
|
@classmethod
|
|
def select_input(cls, option: str, values: List[str]):
|
|
"""options: default value in options[0]"""
|
|
tmp = cls()
|
|
tmp.option = option
|
|
tmp.widget = OverlayComboBox()
|
|
tmp.widget.addItems(values)
|
|
return tmp
|
|
|
|
|
|
class ActivationStates(IntEnum):
|
|
DEFAULT = -1
|
|
HIDDEN = 0
|
|
ENABLED = 1
|
|
|
|
|
|
class OverlaySettings(QGroupBox):
|
|
# str: option key
|
|
environ_changed = pyqtSignal(str)
|
|
|
|
def __init__(self, parent=None):
|
|
super(OverlaySettings, self).__init__(parent=parent)
|
|
self.ui = Ui_OverlaySettings()
|
|
self.ui.setupUi(self)
|
|
|
|
self.core = LegendaryCoreSingleton()
|
|
self.envvar_name: str = None
|
|
self.force_disabled: str = None
|
|
self.app_name: str = "default"
|
|
self.checkboxes: Dict[str, QCheckBox] = {}
|
|
self.values: Dict[str, Union[OverlayLineEdit, OverlayComboBox]] = {}
|
|
|
|
self.ui.options_group.setTitle(self.tr("Custom options"))
|
|
self.ui.show_overlay_combo.currentIndexChanged.connect(self.update_settings)
|
|
|
|
def setupWidget(
|
|
self,
|
|
checkbox_map: List[Tuple[str, str]],
|
|
custom_map: List[Tuple[CustomOption, str]],
|
|
envvar_name: str,
|
|
force_disabled: str,
|
|
):
|
|
self.envvar_name = envvar_name
|
|
self.force_disabled = force_disabled
|
|
|
|
for i, (variable, text) in enumerate(checkbox_map):
|
|
checkbox = QCheckBox(text)
|
|
self.ui.options_grid.addWidget(checkbox, i // 4, i % 4)
|
|
self.checkboxes[variable] = checkbox
|
|
checkbox.stateChanged.connect(self.update_settings)
|
|
|
|
for option, text in custom_map:
|
|
widget = option.widget
|
|
self.ui.options_form.addRow(text, widget)
|
|
self.values[option.option] = widget
|
|
widget.valueChanged.connect(self.update_settings)
|
|
|
|
@abstractmethod
|
|
def set_activation_state(self, state: ActivationStates):
|
|
raise NotImplementedError
|
|
|
|
def update_settings(self):
|
|
|
|
if self.ui.show_overlay_combo.currentIndex() == 0:
|
|
# System default
|
|
config.remove_envvar(self.app_name, self.envvar_name)
|
|
self.environ_changed.emit(self.envvar_name)
|
|
self.ui.options_group.setDisabled(True)
|
|
self.set_activation_state(ActivationStates.DEFAULT)
|
|
return
|
|
|
|
elif self.ui.show_overlay_combo.currentIndex() == 1:
|
|
# hidden
|
|
config.set_envvar(self.app_name, self.envvar_name, self.force_disabled)
|
|
self.environ_changed.emit(self.envvar_name)
|
|
self.ui.options_group.setDisabled(True)
|
|
self.set_activation_state(ActivationStates.HIDDEN)
|
|
return
|
|
elif self.ui.show_overlay_combo.currentIndex() == 2:
|
|
self.ui.options_group.setDisabled(False)
|
|
# custom options
|
|
var_names = []
|
|
for var_name, cb in self.checkboxes.items():
|
|
if cb.isChecked():
|
|
var_names.append(var_name)
|
|
|
|
for var_name, widget in self.values.items():
|
|
text = widget.getValue()
|
|
if text not in ["default", ""]:
|
|
var_names.append(f"{var_name}={text}")
|
|
|
|
if not var_names:
|
|
list(self.checkboxes.values())[0].setChecked(True)
|
|
var_names.append(list(self.checkboxes.keys())[0])
|
|
|
|
config.set_envvar(self.app_name, self.envvar_name, ",".join(var_names))
|
|
self.environ_changed.emit(self.envvar_name)
|
|
self.set_activation_state(ActivationStates.ENABLED)
|
|
|
|
def showEvent(self, a0: QShowEvent):
|
|
if a0.spontaneous():
|
|
return super().showEvent(a0)
|
|
|
|
for checkbox in self.checkboxes.values():
|
|
checkbox.setChecked(False)
|
|
for widget in self.values.values():
|
|
widget.setDefault()
|
|
|
|
options = config.get_envvar(self.app_name, self.envvar_name, fallback=None)
|
|
if options is None:
|
|
logger.debug(f"No Overlay settings found {self.envvar_name}")
|
|
self.ui.show_overlay_combo.setCurrentIndex(0)
|
|
self.ui.options_group.setDisabled(True)
|
|
|
|
elif options == self.force_disabled:
|
|
# not visible
|
|
self.ui.options_group.setDisabled(True)
|
|
self.ui.show_overlay_combo.setCurrentIndex(1)
|
|
|
|
else:
|
|
self.ui.show_overlay_combo.setCurrentIndex(2)
|
|
for option in options.split(","):
|
|
try:
|
|
if "=" in option:
|
|
key, value = option.split("=")
|
|
if key in self.checkboxes.keys():
|
|
self.checkboxes[key].setChecked(False)
|
|
else:
|
|
self.values[key].setValue(value)
|
|
else:
|
|
self.checkboxes[option].setChecked(True)
|
|
except Exception as e:
|
|
logger.warning(e)
|
|
|
|
self.ui.options_group.setDisabled(False)
|
|
|
|
return super().showEvent(a0)
|
|
|
|
|
|
class DxvkSettings(OverlaySettings):
|
|
def __init__(self, parent=None):
|
|
super(DxvkSettings, self).__init__(parent=parent)
|
|
self.setTitle(self.tr("DXVK Settings"))
|
|
self.setupWidget(
|
|
[
|
|
("fps", QCoreApplication.translate("DxvkSettings", "FPS")),
|
|
("frametime", QCoreApplication.translate("DxvkSettings", "Frametime")),
|
|
("memory", QCoreApplication.translate("DxvkSettings", "Memory usage")),
|
|
("gpuload", QCoreApplication.translate("DxvkSettings", "GPU usage")),
|
|
("devinfo", QCoreApplication.translate("DxvkSettings", "Show Device info")),
|
|
("version", QCoreApplication.translate("DxvkSettings", "DXVK Version")),
|
|
("api", QCoreApplication.translate("DxvkSettings", "D3D feature level")),
|
|
("compiler", QCoreApplication.translate("DxvkSettings", "Compiler activity")),
|
|
],
|
|
[
|
|
(
|
|
CustomOption.number_input("scale", 1, True),
|
|
QCoreApplication.translate("DxvkSettings", "Scale"),
|
|
)
|
|
],
|
|
"DXVK_HUD",
|
|
"0",
|
|
)
|
|
|
|
def set_activation_state(self, state: ActivationStates):
|
|
pass
|
|
|
|
|
|
mangohud_position = [
|
|
"default",
|
|
"top-left",
|
|
"top-right",
|
|
"middle-left",
|
|
"middle-right",
|
|
"bottom-left",
|
|
"bottom-right",
|
|
"top-center",
|
|
]
|
|
|
|
|
|
class MangoHudSettings(OverlaySettings):
|
|
def __init__(self, parent=None):
|
|
super(MangoHudSettings, self).__init__(parent=parent)
|
|
self.setTitle(self.tr("MangoHud Settings"))
|
|
self.setupWidget(
|
|
[
|
|
("fps", QCoreApplication.translate("MangoSettings", "FPS")),
|
|
("frame_timing", QCoreApplication.translate("MangoSettings", "Frame Time")),
|
|
("cpu_stats", QCoreApplication.translate("MangoSettings", "CPU Load")),
|
|
("gpu_stats", QCoreApplication.translate("MangoSettings", "GPU Load")),
|
|
("cpu_temp", QCoreApplication.translate("MangoSettings", "CPU Temp")),
|
|
("gpu_temp", QCoreApplication.translate("MangoSettings", "GPU Temp")),
|
|
("ram", QCoreApplication.translate("MangoSettings", "Memory usage")),
|
|
("vram", QCoreApplication.translate("MangoSettings", "VRAM usage")),
|
|
("time", QCoreApplication.translate("MangoSettings", "Local Time")),
|
|
("version", QCoreApplication.translate("MangoSettings", "MangoHud Version")),
|
|
("arch", QCoreApplication.translate("MangoSettings", "System architecture")),
|
|
("histogram", QCoreApplication.translate("MangoSettings", "FPS Graph")),
|
|
("gpu_name", QCoreApplication.translate("MangoSettings", "GPU Name")),
|
|
("cpu_power", QCoreApplication.translate("MangoSettings", "CPU Power consumption")),
|
|
("gpu_power", QCoreApplication.translate("MangoSettings", "GPU Power consumption")),
|
|
],
|
|
[
|
|
(
|
|
CustomOption.number_input("font_size", 24, is_float=False),
|
|
QCoreApplication.translate("MangoSettings", "Font size"),
|
|
),
|
|
(
|
|
CustomOption.select_input("position", mangohud_position),
|
|
QCoreApplication.translate("MangoSettings", "Position"),
|
|
),
|
|
],
|
|
"MANGOHUD_CONFIG",
|
|
"no_display",
|
|
)
|
|
|
|
def showEvent(self, a0: QShowEvent):
|
|
if a0.spontaneous():
|
|
return super().showEvent(a0)
|
|
|
|
# override
|
|
activated = bool(config.get_envvar(self.app_name, "MANGOHUD", None))
|
|
mango_config = config.get_envvar(self.app_name, "MANGOHUD_CONFIG", fallback="")
|
|
if not activated:
|
|
self.ui.options_group.setDisabled(True)
|
|
for i, checkbox in enumerate(list(self.checkboxes.values())):
|
|
checkbox.setChecked(i < 4)
|
|
self.ui.show_overlay_combo.setCurrentIndex(0)
|
|
return
|
|
self.ui.show_overlay_combo.setCurrentIndex(2)
|
|
self.ui.options_group.setDisabled(False)
|
|
for var_name, checkbox in list(self.checkboxes.items())[:4]:
|
|
checkbox.setChecked(f"{var_name}=0" not in mango_config)
|
|
|
|
return super().showEvent(a0)
|
|
|
|
def set_activation_state(self, state: IntEnum): # pylint: disable=E0202
|
|
if state == ActivationStates.DEFAULT:
|
|
config.remove_envvar(self.app_name, "MANGOHUD")
|
|
config.remove_envvar(self.app_name, "MANGOHUD_CONFIG")
|
|
self.ui.options_group.setDisabled(True)
|
|
|
|
elif state == ActivationStates.HIDDEN:
|
|
config.set_envvar(self.app_name, "MANGOHUD", "1")
|
|
config.set_envvar(self.app_name, "MANGOHUD_CONFIG", self.force_disabled)
|
|
|
|
elif state == ActivationStates.ENABLED:
|
|
|
|
mango_config = config.get_envvar(self.app_name, "MANGOHUD_CONFIG", fallback="")
|
|
|
|
split_config = mango_config.split(",")
|
|
for name in list(self.checkboxes.keys())[:4]:
|
|
if name in split_config:
|
|
split_config.remove(name)
|
|
mango_config = ",".join(split_config)
|
|
|
|
# first three are activated by default
|
|
for var_name, checkbox in list(self.checkboxes.items())[:4]:
|
|
if not checkbox.isChecked():
|
|
if mango_config:
|
|
mango_config += f",{var_name}=0"
|
|
else:
|
|
mango_config = f"{var_name}=0"
|
|
if mango_config:
|
|
config.set_envvar(self.app_name, "MANGOHUD", "1")
|
|
config.set_envvar(self.app_name, "MANGOHUD_CONFIG", mango_config)
|
|
else:
|
|
config.remove_envvar(self.app_name, "MANGOHUD")
|
|
config.remove_envvar(self.app_name, "MANGOHUD_CONFIG")
|
|
self.environ_changed.emit("MANGOHUD")
|
|
self.environ_changed.emit("MANGOHUD_CONFIG")
|