diff --git a/source/CT_Config.py b/source/CT_Config.py index 7a01579..54e335a 100644 --- a/source/CT_Config.py +++ b/source/CT_Config.py @@ -66,10 +66,9 @@ class CT_Config: cup.tracks[index] = track yield cup - def create_ctfile(self, directory: str = "./file/", highlight_version: str = None) -> None: + def create_ctfile(self, directory: str = "./file/") -> None: """ create a ctfile configuration in a directory - :param highlight_version: highlight a specific version in light blue :param directory: create CTFILE.txt and RCTFILE.txt in this directory """ with open(directory + "CTFILE.txt", "w", encoding="utf-8") as ctfile, \ diff --git a/source/Common.py b/source/Common.py index 1d0f570..fb74315 100644 --- a/source/Common.py +++ b/source/Common.py @@ -4,6 +4,7 @@ from source.Game import Game from source.Gui.Main import Main from source.Gui.TrackSelection import TrackSelection + class Common: def __init__(self): """ @@ -11,6 +12,8 @@ class Common: having to access an object with some obscure way """ + self.json_frame_filter = None + self.option = Option().load_from_file("./option.json") self.ct_config = CT_Config() self.game = Game(common=self) diff --git a/source/Game.py b/source/Game.py index 0086488..0321f2a 100644 --- a/source/Game.py +++ b/source/Game.py @@ -432,9 +432,7 @@ class Game: self.common.gui_main.progress(show=True, indeter=False, statut=self.common.gui_main.translate("Converting files"), max=max_step, step=0) self.common.gui_main.progress(statut=self.common.gui_main.translate("Configurating LE-CODE"), add=1) - self.common.ct_config.create_ctfile( - highlight_version=self.common.gui_main.stringvar_mark_track_from_version.get(), - ) + self.common.ct_config.create_ctfile() self.generate_cticons() self.generate_all_image() diff --git a/source/Gui/Main.py b/source/Gui/Main.py index 6cc8063..ea96936 100644 --- a/source/Gui/Main.py +++ b/source/Gui/Main.py @@ -203,26 +203,12 @@ class Main: menu=self.menu_conv_process ) - self.menu_conv_process.add_radiobutton( - label=self.translate("1 ", "process"), - variable=self.intvar_process_track, value=1, - command=lambda: self.common.option.edit("process_track", 1) - ) - self.menu_conv_process.add_radiobutton( - label=self.translate("2 ", "process"), - variable=self.intvar_process_track, value=2, - command=lambda: self.common.option.edit("process_track", 2) - ) - self.menu_conv_process.add_radiobutton( - label=self.translate("4 ", "process"), - variable=self.intvar_process_track, value=4, - command=lambda: self.common.option.edit("process_track", 4) - ) - self.menu_conv_process.add_radiobutton( - label=self.translate("8 ", "process"), - variable=self.intvar_process_track, value=8, - command=lambda: self.common.option.edit("process_track", 8) - ) + for process_number in range(1, 8+1): + self.menu_conv_process.add_radiobutton( + label=self.translate(f"{process_number} ", "process"), + variable=self.intvar_process_track, value=process_number, + command=lambda p=process_number: self.common.option.edit("process_track", p) + ) ## GAME PARAMETER self.menu_advanced.add_separator() diff --git a/source/Gui/TrackSelection.py b/source/Gui/TrackSelection.py index 01908b8..db3ba36 100644 --- a/source/Gui/TrackSelection.py +++ b/source/Gui/TrackSelection.py @@ -1,5 +1,7 @@ +import json from tkinter import * from tkinter import ttk +from tkinter import filedialog class Orderbox(Listbox): @@ -46,7 +48,6 @@ class TrackSelection: self.text_xnor = "xnor" self.condition_link_end = "end" - track_filter_row_start = 10 self.condition_links = { self.text_and: lambda a, b: lambda track: a(track) and b(track), self.text_nand: lambda a, b: lambda track: not (a(track) and b(track)), @@ -57,94 +58,10 @@ class TrackSelection: self.condition_link_end: -1 } - def del_frame_track_filter(frames_filter: list, index: int = 0): - for elem in frames_filter[index:]: # remove all track filter after this one - elem["frame"].destroy() - del frames_filter[index:] - - def add_frame_track_filter(root: Frame, frames_filter: list, index: int = 0): - frame = Frame(root) - frame.grid(row=index + track_filter_row_start, column=1, sticky="NEWS") - Label(frame, text="If track's").grid(row=1, column=1) - track_property = ttk.Combobox(frame, values=list(self.common.ct_config.get_all_track_possibilities().keys())) - track_property.current(0) - track_property.grid(row=1, column=2) - - frame_equal = Frame(frame) - entry_equal = Entry(frame_equal, width=20) - entry_equal.grid(row=1, column=1) - entry_equal.insert(END, "value") - - frame_in = Frame(frame) - entry_in = Entry(frame_in, width=30) - entry_in.grid(row=1, column=1) - entry_in.insert(END, "value1, value2, ...") - - frame_between = Frame(frame) - entry_start = Entry(frame_between, width=10) - entry_start.grid(row=1, column=1) - entry_start.insert(END, "value1") - Label(frame_between, text="and").grid(row=1, column=2) - entry_end = Entry(frame_between, width=10) - entry_end.insert(END, "value2") - entry_end.grid(row=1, column=3) - - frame_contains = Frame(frame) - entry_contains = Entry(frame_contains, width=20) - entry_contains.grid(row=1, column=1) - entry_contains.insert(END, "value") - - condition_frames = { - self.text_is_equal_to: frame_equal, - self.text_is_in: frame_in, - self.text_is_between: frame_between, - self.text_contains: frame_contains, - } - - def change_condition_type(event: Event = None): - condition = combobox_condition_type.get() - for frame in condition_frames.values(): frame.grid_forget() - condition_frames[condition].grid(row=1, column=10) - - combobox_condition_type = ttk.Combobox(frame, values=list(condition_frames.keys()), width=10) - combobox_condition_type.current(0) - combobox_condition_type.bind("<>", change_condition_type) - change_condition_type() - combobox_condition_type.grid(row=1, column=3) - - def change_condition_link(event: Event = None): - link = next_condition_link.get() - - if link == self.condition_link_end: - del_frame_track_filter(frames_filter, index=index + 1) - - else: - if frames_filter[-1]["frame"] == frame: # if this is the last filter available - add_frame_track_filter(root=root, frames_filter=frames_filter, index=index + 1) - - next_condition_link = ttk.Combobox(frame, values=list(self.condition_links.keys()), width=10) - next_condition_link.bind("<>", change_condition_link) - next_condition_link.set(self.condition_link_end) - next_condition_link.grid(row=1, column=100) - - frames_filter.append({ - "frame": frame, - "track_property": track_property, - "condition_type": combobox_condition_type, - - "value_equal": entry_equal, - "value_in": entry_in, - "value_between_start": entry_start, - "value_between_end": entry_end, - "value_contains": entry_contains, - - "next_condition_link": next_condition_link - }) - def get_change_enable_track_filter_func(root: [Frame, LabelFrame], frames_filter: list, variable_enable: BooleanVar): def change_enable_track_filter(event: Event = None): - if variable_enable.get(): add_frame_track_filter(root=root, frames_filter=frames_filter) - else: del_frame_track_filter(frames_filter=frames_filter) + if variable_enable.get(): self.add_frame_track_filter(root=root, frames_filter=frames_filter) + else: self.del_frame_track_filter(frames_filter=frames_filter) return change_enable_track_filter @@ -175,6 +92,11 @@ class TrackSelection: ) ) self.checkbutton_track_filter.grid(row=1, column=1) + Label( + self.track_filter, + text="Warning : only unordered tracks are affected by this option.", + fg="gray" + ).grid(row=2, column=1) self.track_highlight = LabelFrame(self.root, text="Highlight Track") self.track_highlight.grid(row=3, column=1, sticky="NEWS") @@ -210,14 +132,137 @@ class TrackSelection: ) self.checkbutton_track_random_new.grid(row=1, column=1) - Button( - self.root, - text="Save configuration", - relief=RIDGE, - command=self.save_configuration - ).grid(row=100, column=1, sticky="E") + self.all_frames_filters = { + "track_filter": { + "frame": self.track_filter, + "variable_checkbox": self.variable_enable_track_filter, + "list": self.frames_track_filter + }, + "track_highlight": { + "frame": self.track_highlight, + "variable_checkbox": self.variable_enable_track_highlight, + "list": self.frames_track_highlight + }, + "track_random_new": { + "frame": self.track_random_new, + "variable_checkbox": self.variable_enable_track_random_new, + "list": self.frames_track_random_new + } + } - def save_configuration(self): + if self.common.json_frame_filter: self.load_from_json(self.common.json_frame_filter) + + self.frame_action_button = Frame(self.root) + self.frame_action_button.grid(row=100, column=1, sticky="E") + + Button( + self.frame_action_button, + text="Apply change", + relief=RIDGE, + command=self.apply_configuration + ).grid(row=1, column=1, sticky="W") + + Button( + self.frame_action_button, + text="Save to file", + relief=RIDGE, + command=self.promp_save_to_file + ).grid(row=1, column=2, sticky="E") + + Button( + self.frame_action_button, + text="Load from file", + relief=RIDGE, + command=self.promp_load_from_file + ).grid(row=1, column=3, sticky="E") + + def del_frame_track_filter(self, frames_filter: list, index: int = 0): + for elem in frames_filter[index:]: # remove all track filter after this one + elem["frame"].destroy() + del frames_filter[index:] + + def add_frame_track_filter(self, root: [Frame, LabelFrame], frames_filter: list): + index = len(frames_filter) - 1 + + frame = Frame(root) + frame.grid(row=len(frames_filter) + 10, column=1, sticky="NEWS") + Label(frame, text="If track's").grid(row=1, column=1) + track_property = ttk.Combobox(frame, values=list(self.common.ct_config.get_all_track_possibilities().keys())) + track_property.current(0) + track_property.grid(row=1, column=2) + + frame_equal = Frame(frame) + entry_equal = Entry(frame_equal, width=20) + entry_equal.grid(row=1, column=1) + entry_equal.insert(END, "value") + + frame_in = Frame(frame) + entry_in = Entry(frame_in, width=30) + entry_in.grid(row=1, column=1) + entry_in.insert(END, "value1, value2, ...") + + frame_between = Frame(frame) + entry_start = Entry(frame_between, width=10) + entry_start.grid(row=1, column=1) + entry_start.insert(END, "value1") + Label(frame_between, text="and").grid(row=1, column=2) + entry_end = Entry(frame_between, width=10) + entry_end.insert(END, "value2") + entry_end.grid(row=1, column=3) + + frame_contains = Frame(frame) + entry_contains = Entry(frame_contains, width=20) + entry_contains.grid(row=1, column=1) + entry_contains.insert(END, "value") + + condition_frames = { + self.text_is_equal_to: frame_equal, + self.text_is_in: frame_in, + self.text_is_between: frame_between, + self.text_contains: frame_contains, + } + + def change_condition_type(event: Event = None): + condition = combobox_condition_type.get() + for frame in condition_frames.values(): frame.grid_forget() + condition_frames[condition].grid(row=1, column=10) + + combobox_condition_type = ttk.Combobox(frame, values=list(condition_frames.keys()), width=10) + combobox_condition_type.current(0) + combobox_condition_type.bind("<>", change_condition_type) + change_condition_type() + combobox_condition_type.grid(row=1, column=3) + + def change_condition_link(event: Event = None): + link = next_condition_link.get() + + if link == self.condition_link_end: + self.del_frame_track_filter(frames_filter, index=index + 1) + + else: + if frames_filter[-1]["frame"] == frame: # if this is the last filter available + self.add_frame_track_filter(root=root, frames_filter=frames_filter) + + next_condition_link = ttk.Combobox(frame, values=list(self.condition_links.keys()), width=10) + next_condition_link.bind("<>", change_condition_link) + next_condition_link.set(self.condition_link_end) + next_condition_link.grid(row=1, column=100) + + frames_filter.append({ + "frame": frame, + "track_property": track_property, + "condition_type": combobox_condition_type, + + "value_equal": entry_equal, + "value_in": entry_in, + "value_between_start": entry_start, + "value_between_end": entry_end, + "value_contains": entry_contains, + + "next_condition_link": next_condition_link + }) + + def apply_configuration(self): self.common.gui_main.is_track_configuration_edited = True self.common.ct_config.sort_track_attr = self.combobox_track_sort.get() self.common.ct_config.filter_track_selection = self.get_filter( @@ -233,6 +278,9 @@ class TrackSelection: self.frames_track_random_new ) + self.common.json_frame_filter = self.save_to_json() + self.root.destroy() + def get_filter(self, condition_enabled: BooleanVar, frames_filter: list): s = lambda x: str(x).strip() @@ -282,3 +330,72 @@ class TrackSelection: next_condition_link_func = self.condition_links[next_condition_link] return filter_condition + + def save_to_json(self) -> dict: + """ + save the menu values in a dictionnary + :return: dictionnary + """ + + json_frame_filter = {} + + for frame_name, tk_frames_data in self.all_frames_filters.items(): + json_frame_filter[frame_name] = [] + + for tk_data in tk_frames_data["list"]: + json_frame_filter[frame_name].append({}) + + for varname, tkvar in tk_data.items(): + if "get" in dir(tkvar): + json_frame_filter[frame_name][-1][varname] = tkvar.get() + + return json_frame_filter + + def save_to_file(self, path: str): + with open(path, "w", encoding="utf8") as f: + json.dump(self.save_to_json(), f, ensure_ascii=False) + + def promp_save_to_file(self): + filename = filedialog.asksaveasfilename( + title="Save track configuration", + defaultextension=".mkwf.tc", + filetypes=[("track configuration (*.mkwf.tc)", "*.mkwf.tc")] + ) + if filename: self.save_to_file(filename) + + def load_from_json(self, json_frame_filter: dict) -> None: + """ + :param json_frame_filter: json to load in the menu + """ + + for json_filter_name, json_frames in json_frame_filter.items(): + + tk_frame_filter = self.all_frames_filters[json_filter_name] + self.del_frame_track_filter(tk_frame_filter["list"]) + tk_frame_filter["variable_checkbox"].set(len(json_frames) > 0) + + for i, json_frame in enumerate(json_frames): + self.add_frame_track_filter( + self.all_frames_filters[json_filter_name]["frame"], + self.all_frames_filters[json_filter_name]["list"] + ) + + for json_param_name, json_param_value in json_frame.items(): + obj = self.all_frames_filters[json_filter_name]["list"][i][json_param_name] + if type(obj) in [Entry]: + obj.delete(0, END) + obj.insert(0, json_param_value) + else: + obj.set(json_param_value) + + def load_from_file(self, path: str) -> None: + with open(path, encoding="utf8") as f: + self.load_from_json(json.load(f)) + + def promp_load_from_file(self): + filename = filedialog.askopenfilename( + title="Load track configuration", + defaultextension=".mkwf.tc", + filetypes=[("track configuration (*.mkwf.tc)", "*.mkwf.tc")] + ) + if filename: self.load_from_file(filename) \ No newline at end of file