rewrote the ModSettings to be simpler

This commit is contained in:
Faraphel 2022-08-21 20:35:49 +02:00
parent 5f5dc6bfbc
commit f2d27deb68
6 changed files with 52 additions and 68 deletions

View file

@ -59,7 +59,7 @@
"en": "Should the mod balancing (fake item box, blooper) be enabled ?", "en": "Should the mod balancing (fake item box, blooper) be enabled ?",
"fr": "Est-ce que l'équilibrage du mod (fausse boite d'objet, bloops) devrait être activé ?" "fr": "Est-ce que l'équilibrage du mod (fausse boite d'objet, bloops) devrait être activé ?"
}, },
"type": "check", "type": "boolean",
"default": true "default": true
} }
}, },

View file

@ -6,10 +6,9 @@ import json
from PIL import Image from PIL import Image
from source import threaded from source import threaded
from source.mkw import Tag from source.mkw import Tag, ModSettings
from source.mkw.Track.Cup import Cup from source.mkw.Track.Cup import Cup
from source.mkw.collection import MKWColor, Slot from source.mkw.collection import MKWColor, Slot
from source.mkw.ModSettings import AbstractModSettings
from source.mkw.Track import CustomTrack, DefaultTrack, Arena from source.mkw.Track import CustomTrack, DefaultTrack, Arena
from source.progress import Progress from source.progress import Progress
from source.safe_eval.safe_eval import safe_eval from source.safe_eval.safe_eval import safe_eval
@ -121,11 +120,11 @@ class ModConfig:
self._tracks = [CustomTrack.from_dict(self, track) for track in self._tracks if isinstance(track, dict)] self._tracks = [CustomTrack.from_dict(self, track) for track in self._tracks if isinstance(track, dict)]
self._arenas = [Arena.from_dict(self, arena) for arena in self._arenas if isinstance(arena, dict)] self._arenas = [Arena.from_dict(self, arena) for arena in self._arenas if isinstance(arena, dict)]
self.global_settings = {name: AbstractModSettings.get(data) for name, data in merge_dict( self.global_settings = {name: ModSettings.get(data) for name, data in merge_dict(
default_global_settings, self.global_settings, dict_keys=default_global_settings.keys() default_global_settings, self.global_settings, dict_keys=default_global_settings.keys()
# Avoid modder to add their own settings to globals one # Avoid modder to add their own settings to globals one
).items()} ).items()}
self.specific_settings = {name: AbstractModSettings.get(data) for name, data in self.specific_settings.items()} self.specific_settings = {name: ModSettings.get(data) for name, data in self.specific_settings.items()}
def __hash__(self) -> int: def __hash__(self) -> int:
return hash(self.name) return hash(self.name)

View file

@ -1,34 +1,25 @@
import tkinter import tkinter
from tkinter import ttk from tkinter import ttk
from dataclasses import dataclass, field
from source.mkw.ModSettings import AbstractModSettings from source.mkw.ModSettings import AbstractModSettings
from source.translation import translate as _ from source.translation import translate as _
@dataclass(init=False)
class Choices(AbstractModSettings): class Choices(AbstractModSettings):
""" """
This setting type allow you to input a string text. This setting type allow you to input a string text.
You can optionally add a "preview" to allow the user to use a window to select the value. You can optionally add a "preview" to allow the user to use a window to select the value.
""" """
type = "check" type = "boolean"
def __init__(self, enabled: bool = False,
default: bool | None = None, text: dict[str, str] = None, description: dict[str, str] = None):
self._value = default if default is not None else False
self.default = default
self.description = description if description is not None else {}
self.enabled = enabled
self.text = text if text is not None else {}
def tkinter_show(self, master, checkbox) -> None: def tkinter_show(self, master, checkbox) -> None:
super().tkinter_show(master, checkbox) super().tkinter_show(master, checkbox)
variable = self.tkinter_variable(tkinter.BooleanVar)
value_variable = tkinter.BooleanVar(master, value=self._value) radiobutton_on = ttk.Radiobutton(master, text=_("DISABLED"), variable=variable, value=False)
value_variable.trace_add("write", lambda *_: setattr(self, "_value", value_variable.get()))
radiobutton_on = ttk.Radiobutton(master, text=_("DISABLED"), variable=value_variable, value=False)
radiobutton_on.grid(row=1, column=1, sticky="E") radiobutton_on.grid(row=1, column=1, sticky="E")
radiobutton_off = ttk.Radiobutton(master, text=_("ENABLED"), variable=value_variable, value=True) radiobutton_off = ttk.Radiobutton(master, text=_("ENABLED"), variable=variable, value=True)
radiobutton_off.grid(row=1, column=2, sticky="E") radiobutton_off.grid(row=1, column=2, sticky="E")

View file

@ -1,9 +1,11 @@
import tkinter import tkinter
from dataclasses import field, dataclass
from tkinter import ttk from tkinter import ttk
from source.mkw.ModSettings import AbstractModSettings from source.mkw.ModSettings import AbstractModSettings
@dataclass(init=False)
class Choices(AbstractModSettings): class Choices(AbstractModSettings):
""" """
This setting type allow you to input a string text. This setting type allow you to input a string text.
@ -12,25 +14,14 @@ class Choices(AbstractModSettings):
type = "choices" type = "choices"
def __init__(self, choices: list[str], enabled: bool = False, def __init__(self, choices: list[str] = None, **kwargs):
default: str | None = None, text: dict[str, str] = None, description: dict[str, str] = None): super().__init__(**kwargs)
self._value = default if default is not None else choices[0] self.choices = choices if choices is not None else []
self.default = default
self.enabled = enabled
self.text = text if text is not None else {}
self.description = description if description is not None else {}
self.choices = choices
def tkinter_show(self, master, checkbox) -> None: def tkinter_show(self, master, checkbox) -> None:
super().tkinter_show(master, checkbox) super().tkinter_show(master, checkbox)
variable = self.tkinter_variable(tkinter.StringVar)
master.grid_rowconfigure(1, weight=1)
master.grid_columnconfigure(1, weight=1) master.grid_columnconfigure(1, weight=1)
value_variable = tkinter.StringVar(master, value=self._value) combobox = ttk.Combobox(master, values=self.choices, textvariable=variable)
value_variable.trace_add("write", lambda *_: setattr(self, "_value", value_variable.get()))
combobox = ttk.Combobox(master, values=self.choices, textvariable=value_variable)
combobox.grid(row=1, column=1, sticky="EW") combobox.grid(row=1, column=1, sticky="EW")

View file

@ -13,34 +13,23 @@ class String(AbstractModSettings):
type = "string" type = "string"
def __init__(self, preview: str = None, enabled: bool = False, def __init__(self, preview: str | None = None, **kwargs):
default: str | None = None, text: dict[str, str] = None, description: dict[str, str] = None): super().__init__(**kwargs)
self._value: str = default if default is not None else "" self.preview = preview
self.default = default
self.enabled = enabled
self.text = text if text is not None else {}
self.description = description if description is not None else {}
self.preview: str | None = preview
def tkinter_show(self, master, checkbox) -> None: def tkinter_show(self, master, checkbox) -> None:
super().tkinter_show(master, checkbox) super().tkinter_show(master, checkbox)
variable = self.tkinter_variable(tkinter.StringVar)
master.grid_rowconfigure(1, weight=1)
master.grid_columnconfigure(1, weight=1) master.grid_columnconfigure(1, weight=1)
value_variable = tkinter.StringVar(master, value=self._value) entry = ttk.Entry(master, textvariable=variable)
value_variable.trace_add("write", lambda *_: setattr(self, "_value", value_variable.get()))
entry = ttk.Entry(master, textvariable=value_variable)
entry.grid(row=1, column=1, sticky="EW") entry.grid(row=1, column=1, sticky="EW")
if self.preview is not None: if self.preview is not None:
button = ttk.Button( button = ttk.Button(
master, text="...", width=3, master, text="...", width=3,
command=lambda: AbstractPreviewWindow.get(self.preview)( command=lambda: AbstractPreviewWindow.get(self.preview)(
master.master.master.master.mod_config, value_variable master.master.master.master.mod_config, variable
) )
) )
button.grid(row=1, column=2, sticky="EW") button.grid(row=1, column=2, sticky="EW")

View file

@ -1,6 +1,7 @@
import tkinter import tkinter
from tkinter import ttk from tkinter import ttk
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Type
from source.translation import translate as _ from source.translation import translate as _
@ -16,10 +17,16 @@ class AbstractModSettings(ABC):
""" """
type: str # type name of the settings type: str # type name of the settings
text: dict[str] # text to display in the settings window depending on the language
enabled: bool # is the settings enabled def __init__(self, text: dict[str, str] = None, description: dict[str, str] = None, enabled: bool = False,
default: str | None # default value of the settings (used is disabled) default: str | None = None, value: any = None):
_value: any # value for the settings
self.text = text if text is not None else {} # text to display in the window settings.
self.description = description if description is not None else {} # desc to display in the window settings.
self.enabled = enabled # is the settings enabled
self.default: str | None = default # default value of the settings (used is disabled)
self._value: any = value if value is not None else default # value for the settings
@property @property
def value(self) -> "any | None": def value(self) -> "any | None":
@ -45,19 +52,26 @@ class AbstractModSettings(ABC):
""" """
enabled_variable.set(self.enabled) enabled_variable.set(self.enabled)
enabled_variable.trace_add("write", lambda *_: setattr(self, "enabled", enabled_variable.get())) enabled_variable.trace_add("write", lambda *_: setattr(self, "enabled", enabled_variable.get()))
# si le paramètre est modifié, coche automatiquement la case
... ...
@classmethod def tkinter_variable(self, vartype: Type[tkinter.Variable]) -> tkinter.Variable:
def get(cls, settings_data: dict) -> "AbstractModSettings": variable = vartype(value=self._value)
""" variable.trace_add("write", lambda *_: setattr(self, "_value", variable.get()))
Load all the settings in mod_settings_dict return variable
:param settings_data: dictionary containing all the settings defined for the mod
"""
for subclass in filter(lambda subclass: subclass.type == settings_data["type"], cls.__subclasses__()): def get(settings_data: dict) -> "AbstractModSettings":
settings_data.pop("type") """
return subclass(**settings_data) Load all the settings in mod_settings_dict
else: raise InvalidSettingsType(settings_data["type"]) :param settings_data: dictionary containing all the settings defined for the mod
"""
for subclass in filter(lambda subclass: subclass.type == settings_data["type"],
AbstractModSettings.__subclasses__()):
settings_data.pop("type")
return subclass(**settings_data)
else: raise InvalidSettingsType(settings_data["type"])
# these import load the different ModSettings, and so get_mod_settings will be able to fetch them with __subclasses__ # these import load the different ModSettings, and so get_mod_settings will be able to fetch them with __subclasses__
from source.mkw.ModSettings import Choices, String, Check from source.mkw.ModSettings import Choices, String, Boolean