import os import tkinter as tk from tkinter import filedialog as fd from tkinter.messagebox import showinfo, askyesno, askokcancel from tkinter import ttk from tooltip import Hovertip from pathlib import Path from deploy import download_ffmpeg, download_git, deploy, get_ffmpeg_version, update import logging import sys def get_curr_screen_geometry(): """ Workaround to get the size of the current screen in a multi-screen setup. Returns: geometry (str): The standard Tk geometry string. [width]x[height]+[left]+[top] """ root = tk.Tk() root.update_idletasks() root.attributes('-fullscreen', True) root.state('iconic') geometry = root.winfo_geometry() root.destroy() return geometry def create_install_frame(container): def find_barotrauma_directory(): first_guess = Path("C:/Program Files (x86)/Steam/steamapps/common/Barotrauma") second_guess = Path("D:/Steam/steamapps/common/Barotrauma") if first_guess.is_dir(): return first_guess.as_posix() elif second_guess.is_dir(): return second_guess.as_posix() else: return False def select_barotrauma_directory(): return_dir = fd.askdirectory(initialdir="C:/") install_dir.set(return_dir) frame = ttk.LabelFrame(container, text='Barotrauma installation directory') find_button = ttk.Button(frame, text='Guess', command=lambda: install_dir.set(find_barotrauma_directory())) find_button.pack(side="left", padx=3, pady=3) install_dir = tk.StringVar() install_dir.set(find_barotrauma_directory()) directory_entry = ttk.Entry(frame, width=60, textvariable=install_dir) directory_entry.pack(side="left", padx=3, pady=3, expand=True, fill="x") browse_button = ttk.Button(frame, text='Browse', command=select_barotrauma_directory) browse_button.pack(side="left", padx=3, pady=3) return frame, install_dir def create_options_frame(container): frame = ttk.LabelFrame(container, text='Options') # Use ITA checkbox use_ita = tk.StringVar() use_ita.set("0") use_ita_check = ttk.Checkbutton( frame, variable=use_ita, text='Use ITA mod', command=lambda: print(use_ita.get())) # Buffs checkbox buffs = tk.StringVar() buffs.set("1") buffs_check = ttk.Checkbutton( frame, variable=buffs, text='Buffs', command=lambda: print(buffs.get())) # Override Workshop checkbox override_workshop = tk.StringVar() override_workshop.set("0") override_workshop_check = ttk.Checkbutton( frame, variable=override_workshop, text='Override Workshop', command=lambda: print(override_workshop.get())) Hovertip(use_ita_check, 'Check this box if you use Into The Abyss mod.' '\nITA and Sunken Tapes override the same style file.') Hovertip(buffs_check, 'Check this box to enable some songs causing strange effects' '\nThis is the intended default behaviour.') Hovertip(override_workshop_check, 'Keep this unchecked to prevent Steam Workshop' '\noverriding your custom installation.') for widget in frame.winfo_children(): widget.pack(side="top", padx=3, pady=3, fill="x") return frame, use_ita, buffs, override_workshop def create_resolution_frame(container): frame = ttk.LabelFrame(container, text='Resolution') def detect_screen_resolution(): w, h = get_curr_screen_geometry().split("+")[0].split("x") width.set(w) height.set(h) width = tk.StringVar() width.set("1920") width_label = ttk.Label(frame, text='Width:') width_frame = ttk.Entry(frame, width=12, textvariable=width) height = tk.StringVar() height.set("1080") height_label = ttk.Label(frame, text='Height:') height_frame = ttk.Entry(frame, width=12, textvariable=height) detect_button = ttk.Button(frame, text='Detect', command=detect_screen_resolution) for widget in frame.winfo_children(): widget.pack(side="left", padx=3, pady=3) return frame, width, height def create_deploy_frame(container, config): def deploy_action(): config_values = {"installdir": config["installdir"].get(), "use_ita": config["use_ita"].get() == "1", "buffs": config["buffs"].get() == "1", "override_workshop": config["override_workshop"].get() == "1", "resolution_x": int(config["resolution_x"].get()), "resolution_y": int(config["resolution_y"].get())} logging.info(f"deploying with config: {config_values}") deploy(config_values) if config_values["override_workshop"]: mod_name = "Sunken Tapes" note = "" else: mod_name = "Sunken Tapez" note = '\n\nThis is a custom version and is named with Z (Sunken Tapez) to differentiate it from ' \ + 'the Steam Workshop version that would overwrite it otherwise.' showinfo(title='Success!', message=f'{mod_name} was successfully installed to:' f'\n{config["installdir"].get()}' f'\n\nThis installer will now close.' f'{note}') container.destroy() def download_ffmpeg_action(): def finish(): does_ffmpeg_exists() showinfo(title='Success!', message=f'ffmpeg downloaded. You can now deploy Sunken Tapes:') if not Path("./utils/ffmpeg-" + get_ffmpeg_version() + "-full_build/bin/ffmpeg.exe").exists(): download_ffmpeg() finish() return else: answer = askyesno(title='ffmpeg already downloaded', message='ffmpeg is already in utils directory!' '\n\nDelete the existing one and download again?') if answer: download_ffmpeg(clean=True) finish() else: return def update_action(): if not Path("./utils/git").exists(): answer = askokcancel( title='Confirmation', message='Portable version of git will be downloaded.' '\nThis is needed to check for updates in the repository') if answer: download_git() else: return else: logging.info(f"git already in utils") update() def does_ffmpeg_exists(): if Path("./utils/ffmpeg-" + get_ffmpeg_version() + "-full_build/bin/ffmpeg.exe").exists(): deploy_button["state"] = "normal" else: deploy_button["state"] = "disable" frame = ttk.LabelFrame(container, text='Install') frame_1 = ttk.Frame(frame) download_tools_label = ttk.Label(frame_1, text='Download and unpack ffmpeg:') download_tools_label.pack(side="left", padx=3, pady=3) download_tools_button = ttk.Button(frame_1, text='Download', command=download_ffmpeg_action) download_tools_button.pack(side="right", padx=3, pady=3) frame_1.pack(side="top", fill="x") frame_2 = ttk.Frame(frame) update_label = ttk.Label(frame_2, text='Download update from git.kompot.si/jaka/barotrauma-sunken-tapes:') update_label.pack(side="left", padx=3, pady=3) update_button = ttk.Button(frame_2, text='Update', command=update_action) update_button.pack(side="right", padx=3, pady=3) frame_2.pack(side="top", fill="x") frame_3 = ttk.Frame(frame) deploy_label = ttk.Label(frame_3, text='Download songs and deploy mod to Barotrauma Mods directory:') deploy_label.pack(side="left", padx=3, pady=3) deploy_button = ttk.Button(frame_3, text='Deploy', command=deploy_action) deploy_button.pack(side="right", padx=3, pady=3) frame_3.pack(side="top", fill="x") does_ffmpeg_exists() return frame def create_main_window(): # root window root = tk.Tk() root.title('Sunken Tapes') middle_frame = ttk.Frame(root) install_frame, install_dir = create_install_frame(root) options_frame, use_ita, buffs, override_workshop = create_options_frame(middle_frame) resolution_frame, width, height = create_resolution_frame(middle_frame) config = {"installdir": install_dir, "use_ita": use_ita, "buffs": buffs, "override_workshop": override_workshop, "resolution_x": width, "resolution_y": height} deploy_frame = create_deploy_frame(root, config) install_frame.pack(side="top", fill="x", pady=3, padx=3) options_frame.pack(side="left", fill="y", pady=3, padx=3) resolution_frame.pack(side="left", fill="both", pady=3, padx=3, expand=True) middle_frame.pack(side="top", fill="x") deploy_frame.pack(side="top", fill="x", pady=3, padx=3) root.mainloop() if __name__ == "__main__": os.chdir(Path(__file__).parents[0]) logging.basicConfig(stream=sys.stdout, level=logging.INFO) create_main_window()