diff --git a/seven_mods.py b/seven_mods.py index 3b2a516..394f421 100755 --- a/seven_mods.py +++ b/seven_mods.py @@ -75,15 +75,20 @@ class Config: else: raise AttributeError(f"Config has no attribute named '{name}'.") - def set_val(self, name: str, val: str): + def set_val(self, name: str, val): if name in ("warn_load", "warn_save", "warn_delete"): # boolean - if val.casefold() in ("on", "true", "yes", "y"): - self.settings[name] = True - elif val.casefold() in ("off", "false", "no", "n"): - self.settings[name] = False + if isinstance(val, bool): + self.settings[name] = val + elif isinstance(val, str): + if val.casefold() in ("on", "true", "yes", "y"): + self.settings[name] = True + elif val.casefold() in ("off", "false", "no", "n"): + self.settings[name] = False + else: + raise ValueError(f"Input cannot be interpreted as boolean: '{val}'") else: - raise ValueError(f"Input cannot be interpreted as boolean: '{val}'") + raise TypeError(f"Input must be a bool or string.") elif name in Config.defaults: # siletly remove newlines, replace with spaces # This is to prevent weird things. diff --git a/seven_mods_gui.py b/seven_mods_gui.py index 5e2053a..cb20871 100755 --- a/seven_mods_gui.py +++ b/seven_mods_gui.py @@ -49,30 +49,38 @@ class AppFrame(ttk.Frame): self.refresh_mod_list() def initialize_widgets(self): - self.columnconfigure(1, weight = 1) + self.columnconfigure(0, weight = 1) + self.rowconfigure(1, weight = 1) - self.configure_button = ttk.Button(self, + # Profile management + profile_frame = ttk.Frame(self) + profile_frame.grid(column = 0, row = 0, columnspan = 2, sticky = (N, S, E, W)) + profile_frame.columnconfigure(1, weight = 1) + + self.configure_button = ttk.Button(profile_frame, text = "Configure", command = self.prompt_configuration_window) self.configure_button.grid(column = 0, row = 0) self.profile_var = StringVar() - self.profile_box = ttk.Combobox(self, + self.profile_box = ttk.Combobox(profile_frame, textvariable = self.profile_var) self.refresh_profile_list() - self.profile_box.grid(column = 1, row = 0, sticky = (E, W)) - self.profile_load_btn = ttk.Button(self, + self.profile_box.grid(column = 1, row = 0, sticky = (E, W), padx = 5) + self.profile_load_btn = ttk.Button(profile_frame, text = "Load", command = self.command_load_button) self.profile_load_btn.grid(column = 2, row = 0) - self.profile_save_btn = ttk.Button(self, + self.profile_save_btn = ttk.Button(profile_frame, text = "Save", command = self.command_save_button) self.profile_save_btn.grid(column = 3, row = 0) - self.profile_delete_btn = ttk.Button(self, + self.profile_delete_btn = ttk.Button(profile_frame, text = "Delete", command = self.command_delete_button) self.profile_delete_btn.grid(column = 4, row = 0) + + # Mod list self.mod_list = ttk.Treeview(self, columns = ("name", "version", "author", "enabled"), height = 20, @@ -83,49 +91,88 @@ class AppFrame(ttk.Frame): self.mod_list.heading("enabled", text = "Enabled") self.mod_list.tag_configure("DISABLED", foreground = "red") self.mod_list.tag_configure("ENABLED", foreground = "green") - self.mod_list.tag_bind("DISABLED", '<>', lambda e: self.command_enable(self.mod_list.selection()[0])) - self.mod_list.tag_bind("ENABLED", '<>', lambda e: self.command_disable(self.mod_list.selection()[0])) - self.mod_list.grid(column = 0, row = 1, columnspan = 5, sticky = (N, E, S, W)) + self.mod_list.tag_bind("DISABLED", '', lambda e: self.command_enable(self.mod_list.selection()[0])) + self.mod_list.tag_bind("ENABLED", '', lambda e: self.command_disable(self.mod_list.selection()[0])) + self.mod_list.grid(column = 0, row = 1, sticky = (N, E, S, W)) + scroll = ttk.Scrollbar(self, orient = VERTICAL, command = self.mod_list.yview) + scroll.grid(column = 1, row = 1, sticky = (N, E, S, W)) + self.mod_list.configure(yscrollcommand=scroll.set) def prompt_configuration_window(self): SEVEN_DIR = "" MODS_DIR = "" + warn_load_var = BooleanVar(value = True) + warn_save_var = BooleanVar(value = True) + warn_delete_var = BooleanVar(value = True) if self.cfg == None: SEVEN_DIR = seven_mods.get_seven_days_install_path() MODS_DIR = seven_mods.MODS_DIR else: SEVEN_DIR = self.cfg.seven_dir MODS_DIR = self.cfg.mods_dir + warn_load_var.set(self.cfg.warn_load) + warn_save_var.set(self.cfg.warn_save) + warn_delete_var.set(self.cfg.warn_delete) t = Toplevel(self) + t.attributes("-topmost", 1) t.title("Configuration") - t.columnconfigure(1, weight = 1) - t.geometry("800x90") + t.columnconfigure(0, weight = 1) + t.rowconfigure(0, weight = 1) + t.rowconfigure(1, weight = 1) - ttk.Label(t, text = "Mod folder").grid(column = 0, row = 0) + paths_frame = ttk.Labelframe(t, text = "Paths") + paths_frame.grid(column = 0, row = 0, sticky = (N, S, E, W)) + paths_frame.columnconfigure(1, weight = 1) + + ttk.Label(paths_frame, text = "Mod folder").grid(column = 0, row = 0) mod_path_var = StringVar() mod_path_var.set(MODS_DIR) - mod_path_entry = ttk.Entry(t, textvariable = mod_path_var) + mod_path_entry = ttk.Entry(paths_frame, textvariable = mod_path_var) mod_path_entry.grid(column = 1, row = 0, sticky = (E, W)) - mod_path_button = ttk.Button(t, + mod_path_button = ttk.Button(paths_frame, text = "Browse...", command = lambda: mod_path_var.set(filedialog.askdirectory(initialdir = MODS_DIR))) mod_path_button.grid(column = 2, row = 0, sticky = (E, W)) - ttk.Label(t, text = "7D2D installation folder").grid(column = 0, row = 1) + ttk.Label(paths_frame, text = "7D2D installation folder").grid(column = 0, row = 1) seven_path_var = StringVar() seven_path_var.set(SEVEN_DIR) - seven_path_entry = ttk.Entry(t, textvariable = seven_path_var) + seven_path_entry = ttk.Entry(paths_frame, textvariable = seven_path_var) seven_path_entry.grid(column = 1, row = 1, sticky = (E, W)) - seven_path_button = ttk.Button(t, + seven_path_button = ttk.Button(paths_frame, text = "Browse...", command = lambda: seven_path_var.set(filedialog.askdirectory(initialdir = SEVEN_DIR))) seven_path_button.grid(column = 2, row = 1, sticky = (E, W)) - save_button = ttk.Button(t, text = "Save", command = lambda: self.save_config(mod_path_var.get(), seven_path_var.get())) - save_button.grid(column = 2, row = 2) + warnings_frame = ttk.Labelframe(t, text = "Warnings") + warnings_frame.grid(column = 0, row = 1, sticky = (N, S, E, W)) + warnings_frame.columnconfigure(1, weight = 1) - def save_config(self, mods_dir: str, seven_dir: str): - self.cfg = seven_mods.Config(mods_dir = mods_dir, seven_dir = seven_dir) + ttk.Checkbutton(warnings_frame, + text = "Warn on loading profile", + variable = warn_load_var).grid(column = 0, row = 0, sticky = (E, W)) + ttk.Checkbutton(warnings_frame, + text = "Warn on saving profile", + variable = warn_save_var).grid(column = 0, row = 1, sticky = (E, W)) + ttk.Checkbutton(warnings_frame, + text = "Warn on deleting profile", + variable = warn_delete_var).grid(column = 0, row = 2, sticky = (E, W)) + + save_button = ttk.Button(t, + text = "Apply", + command = lambda: self.save_config(mod_path_var.get(), + seven_path_var.get(), + warn_load_var.get(), + warn_save_var.get(), + warn_delete_var.get())) + save_button.grid(column = 0, row = 2) + + def save_config(self, mods_dir: str, seven_dir: str, warn_load: bool, warn_save: bool, warn_delete: bool): + self.cfg = seven_mods.Config(mods_dir = mods_dir, + seven_dir = seven_dir, + warn_load = warn_load, + warn_save = warn_save, + warn_delete = warn_delete) seven_mods.save_config(self.cfg) self.refresh_mod_list()