optimised some of the gui object

This commit is contained in:
Faraphel 2022-08-21 22:23:10 +02:00
parent f2d27deb68
commit 777acb7cbf
8 changed files with 72 additions and 53 deletions

View file

@ -43,6 +43,7 @@ class Window(tkinter.Tk):
super().__init__() super().__init__()
self.root = self self.root = self
self.mod_config: ModConfig | None = None
self.options: Options = options self.options: Options = options
self.title(_("INSTALLER_TITLE")) self.title(_("INSTALLER_TITLE"))
@ -114,13 +115,6 @@ class Window(tkinter.Tk):
if progress.max_step is not None: self.progress_bar.set_max_step(progress.max_step) if progress.max_step is not None: self.progress_bar.set_max_step(progress.max_step)
if progress.determinate is not None: self.progress_bar.set_determinate(progress.determinate) if progress.determinate is not None: self.progress_bar.set_determinate(progress.determinate)
def get_mod_config(self) -> ModConfig:
"""
Get the mod configuration
:return: Get the mod configuration
"""
return self.select_pack.mod_config
def get_source_path(self) -> Path: def get_source_path(self) -> Path:
""" """
Get the path of the source game Get the path of the source game
@ -179,7 +173,8 @@ class Menu(tkinter.Menu):
self.root = master.root self.root = master.root
master.add_cascade(label=_("ADVANCED_CONFIGURATION"), menu=self) master.add_cascade(label=_("ADVANCED_CONFIGURATION"), menu=self)
self.add_command(label=_("OPEN_MYSTUFF_SETTINGS"), command= mystuff.Window) self.add_command(label=_("OPEN_MYSTUFF_SETTINGS"),
command=lambda: mystuff.Window(self.root.mod_config, self.root.options))
self.threads_used = self.ThreadsUsed(self) self.threads_used = self.ThreadsUsed(self)
@ -413,22 +408,21 @@ class ButtonInstall(ttk.Button):
return return
game = Game(source_path) game = Game(source_path)
mod_config = self.root.get_mod_config()
output_type = self.root.get_output_type() output_type = self.root.get_output_type()
self.root.progress_function( self.root.progress_function(
game.install_mod( game.install_mod(
dest=destination_path, dest=destination_path,
mod_config=mod_config, mod_config=self.root.mod_config,
output_type=output_type, output_type=output_type,
options=self.root.options options=self.root.options
) )
) )
message: str = translate_external( message: str = translate_external(
mod_config, self.root.mod_config,
self.root.options.language.get(), self.root.options.language.get(),
mod_config.messages.get("installation_completed", {}).get("text", {}) self.root.mod_config.messages.get("installation_completed", {}).get("text", {})
) )
messagebox.showinfo( messagebox.showinfo(
@ -522,7 +516,6 @@ class SelectPack(ttk.Frame):
self.button_settings = ttk.Button(self, text="...", width=2, command=self.open_mod_configuration) self.button_settings = ttk.Button(self, text="...", width=2, command=self.open_mod_configuration)
self.button_settings.grid(row=1, column=2, sticky="NEWS") self.button_settings.grid(row=1, column=2, sticky="NEWS")
self.mod_config: ModConfig | None = None
self.packs: list[Path] = [] self.packs: list[Path] = []
self.refresh_packs() self.refresh_packs()
@ -531,7 +524,7 @@ class SelectPack(ttk.Frame):
self.combobox.bind("<<ComboboxSelected>>", lambda _: self.select()) self.combobox.bind("<<ComboboxSelected>>", lambda _: self.select())
def open_mod_configuration(self) -> None: def open_mod_configuration(self) -> None:
mod_settings.Window(self.mod_config) mod_settings.Window(self.root.mod_config, self.root.options)
def refresh_packs(self) -> None: def refresh_packs(self) -> None:
""" """
@ -564,7 +557,7 @@ class SelectPack(ttk.Frame):
:param pack: the pack :param pack: the pack
:return: :return:
""" """
self.mod_config = ModConfig.from_file(pack / "mod_config.json") self.root.mod_config = ModConfig.from_file(pack / "mod_config.json")
@classmethod @classmethod
def is_valid_pack(cls, path: Path) -> bool: def is_valid_pack(cls, path: Path) -> bool:

View file

@ -7,12 +7,13 @@ from source.translation import translate as _, translate_external
if TYPE_CHECKING: if TYPE_CHECKING:
from source.mkw.ModConfig import ModConfig from source.mkw.ModConfig import ModConfig
from source.mkw.ModSettings import AbstractModSettings from source.mkw.ModSettings import AbstractModSettings
from source.option import Options
class Window(tkinter.Toplevel): class Window(tkinter.Toplevel):
def __init__(self, mod_config: "ModConfig"): def __init__(self, mod_config: "ModConfig", options: "Options"):
super().__init__() super().__init__()
self.root = self.master.root self.root = self
self.resizable(False, False) self.resizable(False, False)
self.grab_set() self.grab_set()
@ -20,6 +21,7 @@ class Window(tkinter.Toplevel):
self.columnconfigure(1, weight=1) self.columnconfigure(1, weight=1)
self.mod_config = mod_config self.mod_config = mod_config
self.options = options
self.panel_window = NotebookSettings(self) self.panel_window = NotebookSettings(self)
self.panel_window.grid(row=1, column=1, sticky="NEWS") self.panel_window.grid(row=1, column=1, sticky="NEWS")
@ -38,7 +40,7 @@ class Window(tkinter.Toplevel):
# add at the end a message from the mod creator where he can put some additional note about the settings. # add at the end a message from the mod creator where he can put some additional note about the settings.
if text := translate_external( if text := translate_external(
self.mod_config, self.mod_config,
self.root.options.language.get(), self.options.language.get(),
self.mod_config.messages.get("settings_description", {}).get("text", {}) self.mod_config.messages.get("settings_description", {}).get("text", {})
): ):
self.label_description = ttk.Label(self, text="\n" + text, foreground="gray") self.label_description = ttk.Label(self, text="\n" + text, foreground="gray")
@ -68,8 +70,8 @@ class FrameSettings(ttk.Frame):
index: int = 0 index: int = 0
for index, (settings_name, settings_data) in enumerate(settings.items()): for index, (settings_name, settings_data) in enumerate(settings.items()):
text = translate_external(self.master.master.mod_config, language, settings_data.text) text = translate_external(self.root.mod_config, language, settings_data.text)
description = translate_external(self.master.master.mod_config, language, settings_data.description) description = translate_external(self.root.mod_config, language, settings_data.description)
enabled_variable = tkinter.BooleanVar(value=False) enabled_variable = tkinter.BooleanVar(value=False)
checkbox = ttk.Checkbutton(self, text=text, variable=enabled_variable) checkbox = ttk.Checkbutton(self, text=text, variable=enabled_variable)
@ -79,6 +81,7 @@ class FrameSettings(ttk.Frame):
frame.columnconfigure(1, weight=1) frame.columnconfigure(1, weight=1)
action_frame = ttk.Frame(frame) action_frame = ttk.Frame(frame)
action_frame.root = self.root
action_frame.grid(row=1, column=1, sticky="NEWS") action_frame.grid(row=1, column=1, sticky="NEWS")
settings_data.tkinter_show(action_frame, enabled_variable) settings_data.tkinter_show(action_frame, enabled_variable)
@ -87,6 +90,3 @@ class FrameSettings(ttk.Frame):
foreground="gray", justify=tkinter.CENTER) foreground="gray", justify=tkinter.CENTER)
description_label.grid(row=2, column=1) description_label.grid(row=2, column=1)
# if any of the label child are clicked, automatically enable the option
for child in frame.winfo_children():
child.bind("<Button-1>", (lambda variable: (lambda event: variable.set(True)))(enabled_variable))

View file

@ -3,18 +3,27 @@ from pathlib import Path
from tkinter import ttk from tkinter import ttk
from tkinter import filedialog from tkinter import filedialog
from tkinter import messagebox from tkinter import messagebox
from typing import TYPE_CHECKING
from source.translation import translate as _ from source.translation import translate as _
if TYPE_CHECKING:
from source.mkw.ModConfig import ModConfig
from source.option import Options
class Window(tkinter.Toplevel): class Window(tkinter.Toplevel):
""" """
A window that let the user select MyStuff pack for a MKWF patch A window that let the user select MyStuff pack for a MKWF patch
""" """
def __init__(self): def __init__(self, mod_config: "ModConfig", options: "Options"):
super().__init__() super().__init__()
self.root = self.master.root
self.root = self
self.mod_config = mod_config
self.options = options
self.title(_("CONFIGURE_MYSTUFF_PATCH")) self.title(_("CONFIGURE_MYSTUFF_PATCH"))
self.resizable(False, False) self.resizable(False, False)
self.grab_set() # the others window will be disabled, keeping only this one activated self.grab_set() # the others window will be disabled, keeping only this one activated
@ -105,8 +114,7 @@ class Window(tkinter.Toplevel):
state = tkinter.DISABLED if is_disabled else tkinter.NORMAL state = tkinter.DISABLED if is_disabled else tkinter.NORMAL
self.button_delete_profile.configure(state=state) self.button_delete_profile.configure(state=state)
for children in self.frame_mystuff_paths_action.children.values(): for children in self.frame_mystuff_paths_action.children.values(): children.configure(state=state)
children.configure(state=state)
if is_disabled: return if is_disabled: return

View file

@ -20,7 +20,7 @@ class AbstractPreviewWindow(tkinter.Toplevel, ABC):
name: str name: str
@abstractmethod @abstractmethod
def __init__(self, mod_config: "ModConfig", template_variable: tkinter.StringVar = None): def __init__(self, mod_config: "ModConfig", template_variable: tkinter.Variable = None):
super().__init__() super().__init__()
... ...

View file

@ -1,12 +1,7 @@
import tkinter
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.
@ -16,6 +11,9 @@ class Choices(AbstractModSettings):
type = "boolean" type = "boolean"
def tkinter_show(self, master, checkbox) -> None: def tkinter_show(self, master, checkbox) -> None:
import tkinter
from tkinter import ttk
super().tkinter_show(master, checkbox) super().tkinter_show(master, checkbox)
variable = self.tkinter_variable(tkinter.BooleanVar) variable = self.tkinter_variable(tkinter.BooleanVar)
@ -23,3 +21,5 @@ class Choices(AbstractModSettings):
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=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")
self.tkinter_bind(master, checkbox)

View file

@ -1,11 +1,6 @@
import tkinter
from dataclasses import field, dataclass
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.
@ -14,14 +9,21 @@ class Choices(AbstractModSettings):
type = "choices" type = "choices"
def __init__(self, choices: list[str] = None, **kwargs): def __init__(self, choices: list[str], **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.choices = choices if choices is not None else [] self.choices = choices
if self.default is None: self.default = self.choices[0]
def tkinter_show(self, master, checkbox) -> None: def tkinter_show(self, master, checkbox) -> None:
import tkinter
from tkinter import ttk
super().tkinter_show(master, checkbox) super().tkinter_show(master, checkbox)
variable = self.tkinter_variable(tkinter.StringVar) variable = self.tkinter_variable(tkinter.StringVar)
master.grid_columnconfigure(1, weight=1) master.grid_columnconfigure(1, weight=1)
combobox = ttk.Combobox(master, values=self.choices, textvariable=variable) combobox = ttk.Combobox(master, values=self.choices, textvariable=variable)
combobox.set(self.default)
combobox.grid(row=1, column=1, sticky="EW") combobox.grid(row=1, column=1, sticky="EW")
self.tkinter_bind(master, checkbox)

View file

@ -1,6 +1,3 @@
import tkinter
from tkinter import ttk
from source.mkw.ModSettings import AbstractModSettings from source.mkw.ModSettings import AbstractModSettings
from source.gui.preview import AbstractPreviewWindow from source.gui.preview import AbstractPreviewWindow
@ -18,6 +15,9 @@ class String(AbstractModSettings):
self.preview = preview self.preview = preview
def tkinter_show(self, master, checkbox) -> None: def tkinter_show(self, master, checkbox) -> None:
import tkinter
from tkinter import ttk
super().tkinter_show(master, checkbox) super().tkinter_show(master, checkbox)
variable = self.tkinter_variable(tkinter.StringVar) variable = self.tkinter_variable(tkinter.StringVar)
master.grid_columnconfigure(1, weight=1) master.grid_columnconfigure(1, weight=1)
@ -28,8 +28,8 @@ class String(AbstractModSettings):
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.root.mod_config, variable)
master.master.master.master.mod_config, variable
)
) )
button.grid(row=1, column=2, sticky="EW") button.grid(row=1, column=2, sticky="EW")
self.tkinter_bind(master, checkbox)

View file

@ -1,10 +1,11 @@
import tkinter
from tkinter import ttk
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Type from typing import Type, TYPE_CHECKING
from source.translation import translate as _ from source.translation import translate as _
if TYPE_CHECKING:
import tkinter
class InvalidSettingsType(Exception): class InvalidSettingsType(Exception):
def __init__(self, settings_type: str): def __init__(self, settings_type: str):
@ -44,7 +45,7 @@ class AbstractModSettings(ABC):
return self.value == self.default return self.value == self.default
@abstractmethod @abstractmethod
def tkinter_show(self, master: ttk.LabelFrame, enabled_variable: tkinter.BooleanVar) -> None: def tkinter_show(self, master, enabled_variable: "tkinter.BooleanVar") -> None:
""" """
Show the option inside a tkinter widget Show the option inside a tkinter widget
:master: master widget :master: master widget
@ -52,14 +53,29 @@ 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
... ...
def tkinter_variable(self, vartype: Type[tkinter.Variable]) -> tkinter.Variable: def tkinter_variable(self, vartype: Type["tkinter.Variable"]) -> "tkinter.Variable":
"""
Create a tkinter variable that is linked to the ModSettings value
:param vartype: the type of variable (boolean, int string)
:return: the tkinter variable
"""
variable = vartype(value=self._value) variable = vartype(value=self._value)
variable.trace_add("write", lambda *_: setattr(self, "_value", variable.get())) variable.trace_add("write", lambda *_: setattr(self, "_value", variable.get()))
return variable return variable
@staticmethod
def tkinter_bind(master, enabled_variable: "tkinter.BooleanVar") -> None:
"""
Bind all widget of the master so that clicking on the frame enable automatically the option
:param master: the frame containing the elements
:param enabled_variable: the variable associated with the enable state
:return:
"""
for child in master.winfo_children():
child.bind("<Button-1>", lambda e: enabled_variable.set(True))
def get(settings_data: dict) -> "AbstractModSettings": def get(settings_data: dict) -> "AbstractModSettings":
""" """