1
0
Fork 0
mirror of synced 2024-05-20 04:22:58 +12:00
Rare/rare/components/tabs/settings/widgets/overlays.py
loathingKernel af6d7c5055 Various WIP
* Use `vars()` instead of directly accessing `__dict__`
* Remove `auto_update` from RareGame's metadata
* Correct check for updating the Steam App ID (We want to keep any changes from the user)
* Collect both Wine and Proton prefixes when removing overlay registry keys.
* Add few convenience functions in config_helper and paths.
2024-02-12 21:52:07 +02:00

191 lines
6.9 KiB
Python

from enum import Enum
from logging import getLogger
from typing import List, Dict, Tuple, Any, Callable
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QIntValidator, QDoubleValidator
from PyQt5.QtWidgets import QGroupBox, QCheckBox, QWidget, QLineEdit, QLabel, QComboBox
from rare.shared import LegendaryCoreSingleton
from rare.ui.components.tabs.settings.widgets.overlay import Ui_OverlaySettings
from rare.utils import config_helper
logger = getLogger("GameOverlays")
class TextInputField(QLineEdit):
def __init__(self):
super(TextInputField, self).__init__()
self.value_changed = self.textChanged
self.set_value = self.setText
self.set_default = lambda: self.setText("")
def get_value(self):
return self.text()
class ComboBox(QComboBox):
def __init__(self):
super(ComboBox, self).__init__()
self.value_changed = self.currentIndexChanged
self.get_value = self.currentText
self.set_value = self.setCurrentText
self.set_default = lambda: self.setCurrentIndex(0)
class CustomOption:
input_field: QWidget
var_name: str
@classmethod
def string_input(cls, var_name: str, placeholder: str):
tmp = cls()
tmp.input_field = TextInputField()
tmp.var_name = var_name
tmp.input_field.setPlaceholderText(placeholder)
return tmp
@classmethod
def number_input(cls, var_name: str, placeholder: Any, is_float: bool = False):
tmp = cls()
tmp.input_field = TextInputField()
tmp.var_name = var_name
tmp.input_field.setPlaceholderText(str(placeholder))
if is_float:
validator = QDoubleValidator()
else:
validator = QIntValidator()
tmp.input_field.setValidator(validator)
return tmp
@classmethod
def select_input(cls, var_name: str, options: List[str]):
"""options: default value in options[0]"""
tmp = cls()
tmp.input_field = ComboBox()
tmp.var_name = var_name
tmp.input_field.addItems(options)
return tmp
class ActivationStates(Enum):
DEFAULT = 0
HIDDEN = 1
ACTIVATED = 2
class OverlaySettings(QGroupBox, Ui_OverlaySettings):
# str: option key
environ_changed = pyqtSignal(str)
name: str = "default"
settings_updatable = True
def __init__(self, checkboxes_map: List[Tuple[str, str]], value_map: List[Tuple[CustomOption, str]],
config_env_var_name: str, no_display_value: str,
set_activation_state: Callable[[Enum], None] = lambda x: None, parent=None):
super(OverlaySettings, self).__init__(parent=parent)
self.setupUi(self)
self.core = LegendaryCoreSingleton()
self.config_env_var_name = config_env_var_name
self.no_display_value = no_display_value
self.set_activation_state = set_activation_state
self.checkboxes: Dict[str, QCheckBox] = {}
for i, (var_name, translated_text) in enumerate(checkboxes_map):
cb = QCheckBox(translated_text)
self.options_grid.addWidget(cb, i // 4, i % 4)
self.checkboxes[var_name] = cb
cb.stateChanged.connect(self.update_settings)
self.values: Dict[str, QWidget] = {}
num_rows = len(checkboxes_map) // 4
for custom_option, translated_text in value_map:
input_field = custom_option.input_field
self.options_form.addRow(QLabel(translated_text), input_field)
self.values[custom_option.var_name] = input_field
input_field.value_changed.connect(self.update_settings)
num_rows += 1
self.show_overlay_combo.currentIndexChanged.connect(self.update_settings)
def update_settings(self):
if not self.settings_updatable:
return
if self.show_overlay_combo.currentIndex() == 0:
# System default
config_helper.remove_option(f"{self.name}.env", self.config_env_var_name)
self.environ_changed.emit(self.config_env_var_name)
self.gb_options.setDisabled(True)
self.set_activation_state(ActivationStates.DEFAULT)
return
elif self.show_overlay_combo.currentIndex() == 1:
# hidden
config_helper.add_option(f"{self.name}.env", self.config_env_var_name, self.no_display_value)
self.environ_changed.emit(self.config_env_var_name)
self.gb_options.setDisabled(True)
self.set_activation_state(ActivationStates.HIDDEN)
return
elif self.show_overlay_combo.currentIndex() == 2:
self.gb_options.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, input_field in self.values.items():
text = input_field.get_value()
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_helper.add_option(f"{self.name}.env", self.config_env_var_name, ",".join(var_names))
self.environ_changed.emit(self.config_env_var_name)
self.set_activation_state(ActivationStates.ACTIVATED)
def load_settings(self, name: str):
self.settings_updatable = False
# load game specific
self.name = name
for checkbox in self.checkboxes.values():
checkbox.setChecked(False)
for input_field in self.values.values():
input_field.set_default()
options = self.core.lgd.config.get(f"{self.name}.env", self.config_env_var_name, fallback=None)
if options is None:
logger.debug(f"No Overlay settings found {self.config_env_var_name}")
self.show_overlay_combo.setCurrentIndex(0)
self.gb_options.setDisabled(True)
elif options == self.no_display_value:
# not visible
self.gb_options.setDisabled(True)
self.show_overlay_combo.setCurrentIndex(1)
else:
self.show_overlay_combo.setCurrentIndex(2)
for option in options.split(","):
try:
if "=" in option:
var_name, value = option.split("=")
if var_name in self.checkboxes.keys():
self.checkboxes[var_name].setChecked(False)
else:
self.values[var_name].set_value(value)
else:
self.checkboxes[option].setChecked(True)
except Exception as e:
logger.warning(e)
self.gb_options.setDisabled(False)
self.settings_updatable = True