mirror of
https://github.com/Faraphel/Atlas-Install.git
synced 2025-07-02 02:38:30 +02:00
implemented user options and made translation capable of changing language
This commit is contained in:
parent
7f85d7eeae
commit
31a28c3cf1
8 changed files with 130 additions and 10 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
/.idea/
|
||||
/option.json
|
||||
|
|
11
main.pyw
11
main.pyw
|
@ -1,8 +1,15 @@
|
|||
from source.gui import install
|
||||
import sys
|
||||
|
||||
from source.gui import install
|
||||
from source.option import Option
|
||||
from source.translation import load_language
|
||||
|
||||
|
||||
# this allows every variable to be accessible from other files, useful for the plugins
|
||||
self = sys.modules[__name__]
|
||||
|
||||
self.window = install.Window()
|
||||
options = Option.from_file("./option.json")
|
||||
translater = load_language(options["language"])
|
||||
|
||||
self.window = install.Window(options)
|
||||
self.window.run()
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import os
|
||||
import sys
|
||||
from threading import Thread
|
||||
from typing import Callable
|
||||
|
||||
|
@ -28,3 +30,10 @@ def threaded(func: Callable) -> Callable:
|
|||
Thread(target=func, args=args, kwargs=kwargs, daemon=True).start()
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def restart_program():
|
||||
"""
|
||||
Restart the program
|
||||
"""
|
||||
os.execl(sys.executable, sys.executable, *sys.argv)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import traceback
|
||||
from tkinter import messagebox
|
||||
from typing import Callable
|
||||
|
||||
from source.translation import translate as _
|
||||
|
||||
|
||||
|
@ -12,6 +11,6 @@ def better_gui_error(func: Callable) -> Callable:
|
|||
|
||||
def wrapper(*args, **kwargs):
|
||||
try: return func(*args, **kwargs)
|
||||
except: messagebox.showerror(_("ERROR"), traceback.format_exc())
|
||||
except: messagebox.showerror(_("Error"), traceback.format_exc())
|
||||
|
||||
return wrapper
|
|
@ -12,6 +12,7 @@ from typing import Generator
|
|||
from source.gui import better_gui_error
|
||||
from source.mkw.Game import Game
|
||||
from source.mkw.ModConfig import ModConfig
|
||||
from source.option import Option
|
||||
from source.translation import translate as _
|
||||
from source import event
|
||||
from source import *
|
||||
|
@ -35,9 +36,11 @@ class InstallerState(enum.Enum):
|
|||
|
||||
# Main window for the installer
|
||||
class Window(tkinter.Tk):
|
||||
def __init__(self):
|
||||
def __init__(self, options: Option):
|
||||
super().__init__()
|
||||
|
||||
self.options: Option = options
|
||||
|
||||
self.title(_("INSTALLER_TITLE"))
|
||||
self.resizable(False, False)
|
||||
self.iconbitmap("./assets/icon.ico")
|
||||
|
@ -141,8 +144,15 @@ class Menu(tkinter.Menu):
|
|||
|
||||
master.add_cascade(label=_("LANGUAGE_SELECTION"), menu=self)
|
||||
|
||||
def callback(file: Path):
|
||||
def func(): self.master.master.options["language"] = file.stem
|
||||
return func
|
||||
|
||||
for file in Path("./assets/language/").iterdir():
|
||||
self.add_command(label=json.loads(file.read_text(encoding="utf8"))["name"])
|
||||
self.add_command(
|
||||
label=json.loads(file.read_text(encoding="utf8"))["name"],
|
||||
command=callback(file)
|
||||
)
|
||||
|
||||
# Track configuration menu
|
||||
class TrackConfiguration(tkinter.Menu):
|
||||
|
|
|
@ -37,6 +37,8 @@ class Track:
|
|||
|
||||
# others not mandatory attributes
|
||||
for key, value in kwargs.items():
|
||||
# if the attribute start with __, this is a magic attribute, and it should not be modified
|
||||
if key.startswith("__"): continue
|
||||
setattr(self, key, value)
|
||||
|
||||
@classmethod
|
||||
|
|
77
source/option.py
Normal file
77
source/option.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from source import restart_program
|
||||
|
||||
|
||||
class Option:
|
||||
__slots__ = ("_path", "_options")
|
||||
|
||||
reboot_on_change: list[any] = ["language"]
|
||||
default_options: dict[str, any] = {
|
||||
"language": "en"
|
||||
}
|
||||
|
||||
def __init__(self, language=None):
|
||||
self._path: Path | None = None
|
||||
self._options: dict[str, any] = self.default_options.copy()
|
||||
if language is not None: self._options["language"] = language
|
||||
|
||||
def __getitem__(self, key: str) -> any:
|
||||
"""
|
||||
get an options value from its key
|
||||
:param key: the option name
|
||||
:return: the value of the option
|
||||
"""
|
||||
return self._options[key]
|
||||
|
||||
def __setitem__(self, key: str, value: any) -> None:
|
||||
"""
|
||||
change the value of an options for a key, if the options have been loaded from a file, save it inside
|
||||
if the option is in the reboot_on_change list, reboot the program
|
||||
:param key: the name of the option to edit
|
||||
:param value: the value of the option
|
||||
:return:
|
||||
"""
|
||||
self._options[key] = value
|
||||
if self._path: self.save()
|
||||
if key in self.reboot_on_change: restart_program()
|
||||
|
||||
def save(self, option_file: Path | str = None) -> None:
|
||||
"""
|
||||
save the options to the file
|
||||
:return: None
|
||||
"""
|
||||
if option_file is None: option_file = self._path
|
||||
if isinstance(option_file, str): option_file = Path(option_file)
|
||||
|
||||
with option_file.open("w") as file:
|
||||
json.dump(self._options, file, indent=4, ensure_ascii=False)
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, option_dict: dict) -> "Option":
|
||||
"""
|
||||
Create a Option from a dict if the parameters are in the default_options
|
||||
:param option_dict: dict containing the configuration
|
||||
:return: Option
|
||||
"""
|
||||
kwargs = {}
|
||||
for key in cls.default_options.keys():
|
||||
if "key" in option_dict: kwargs[key] = option_dict[key]
|
||||
|
||||
return cls(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def from_file(cls, option_file: str | Path) -> "Option":
|
||||
"""
|
||||
Loads the option from a file. If the option file does not exist, only load default configuration
|
||||
:param option_file: the option file
|
||||
:return: Option
|
||||
"""
|
||||
if isinstance(option_file, str): option_file = Path(option_file)
|
||||
|
||||
if not option_file.exists(): obj = cls()
|
||||
else: obj = cls.from_dict(json.loads(option_file.read_text(encoding="utf8")))
|
||||
|
||||
obj._path = option_file
|
||||
return obj
|
|
@ -1,8 +1,19 @@
|
|||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
language_data = json.loads(Path("./assets/language/en.json").read_text(encoding="utf8"))
|
||||
self = sys.modules[__name__]
|
||||
self._language_data = {}
|
||||
|
||||
|
||||
def load_language(language: str):
|
||||
"""
|
||||
Load a language file.
|
||||
:param language: language code to load
|
||||
:return:
|
||||
"""
|
||||
self._language_data = json.loads(Path(f"./assets/language/{language}.json").read_text(encoding="utf8"))
|
||||
|
||||
|
||||
def translate(*text) -> str:
|
||||
|
@ -11,4 +22,8 @@ def translate(*text) -> str:
|
|||
:param text: list of text to translate
|
||||
:return: translated text
|
||||
"""
|
||||
return "".join([language_data["translation"].get(word, word) for word in text])
|
||||
return "".join([self._language_data["translation"].get(word, word) for word in text])
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue