From 0e4733cc1e16016deb9d6b2ed7374e1e855f9b0a Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Sun, 25 Feb 2024 02:30:35 +0100 Subject: [PATCH] wip: extra files & picture scroller --- client.py | 20 ++++-- client_details.py | 60 +++++++++++++----- example_software_root/FreeDink/meta.yaml | 3 +- .../FreeDink/pictures/freedink_ingamel.jpg | Bin 0 -> 33869 bytes software.py | 10 ++- 5 files changed, 71 insertions(+), 22 deletions(-) create mode 100644 example_software_root/FreeDink/pictures/freedink_ingamel.jpg diff --git a/client.py b/client.py index 7b2fe5a..3bbc3e0 100644 --- a/client.py +++ b/client.py @@ -9,7 +9,7 @@ customtkinter.set_default_color_theme("blue") app = customtkinter.CTk() -app.geometry("1000x750") +app.geometry("1030x750") last_geometry = app.winfo_geometry() app.title("Test") app.update() @@ -26,10 +26,16 @@ def create_navbar(): def switch_to_main(): '''Switch back to main view from details''' + global details_elements + global last_geometry + + last_geometry = (0,0) + # destroy details elements # for el in details_elements: - el.destory() + el.destroy() + details_elements = [] load_main() def switch_to_game_details(software): @@ -48,21 +54,27 @@ def load_main(): create_main_window_tile(software) # set update listener & update positions # - app.bind("", update_button_positions) update_button_positions() + app.bind("", update_button_positions) def destroy_main(): '''Destroy all elements in the main view''' + global buttons + app.unbind("") for b in buttons: b.destroy() + + buttons = [] def load_details(app, software): '''Load the details page for a software''' + global details_elements + app.title("Lan Vault: {}".format(software.title)) - details_elements = client_details.create_details_page(app, software) + details_elements = client_details.create_details_page(app, software, switch_to_main) def create_main_window_tile(software): '''Create the main window tile''' diff --git a/client_details.py b/client_details.py index 2fd2ec1..ebdb0c7 100644 --- a/client_details.py +++ b/client_details.py @@ -6,7 +6,7 @@ def show_large_picture(app, path): '''Show a full-window version of the clicked picture''' pass -def create_details_page(app, software): +def create_details_page(app, software, backswitch_function): '''Create the details page for a software and return its elements for later destruction''' elements = [] @@ -19,10 +19,19 @@ def create_details_page(app, software): img = PIL.ImageTk.PhotoImage(img) + # navbar # + navbar = customtkinter.CTkFrame(app) + navbar.grid(column=0, row=0) + back_button = customtkinter.CTkButton(navbar, text="Back", + command=backswitch_function) + back_button.pack(anchor="nw", side="left") + elements.append(navbar) + elements.append(back_button) + # thumbnail image # thumbnail_image = customtkinter.CTkButton(app, text="", image=img, width=500, height=700, command=lambda: show_large_picture(app, path)) - thumbnail_image.grid(column=0, row=0, padx=10, pady=10) + thumbnail_image.grid(column=0, row=1, padx=10, pady=10) elements.append(thumbnail_image) # fonts # @@ -31,7 +40,8 @@ def create_details_page(app, software): # info box # info_frame = customtkinter.CTkFrame(app) - info_frame.grid(column=1, row=0, sticky="ns", padx=10, pady=10) + info_frame.grid(column=1, row=1, sticky="ns", padx=10, pady=10) + elements.append(info_frame) # title # title = customtkinter.CTkLabel(info_frame, text=software.title, font=title_font) @@ -46,18 +56,32 @@ def create_details_page(app, software): elements.append(genre) # description # - description = customtkinter.CTkTextbox(info_frame, width=400, height=200) + description = customtkinter.CTkTextbox(info_frame) description.insert("0.0", software.description) description.pack(anchor="w", side="top", fill="both", padx=20, pady=15) elements.append(description) + # registry modification # + reg_mod_yes_no = "yes" if software.reg_files else "no" + reg_mod_text = "Requires Registry Modification: {}".format(reg_mod_yes_no) + reg_mod_info = customtkinter.CTkLabel(info_frame, text=reg_mod_text, padx=20) + reg_mod_info.pack(anchor="w", side="top") + elements.append(reg_mod_info) + # dependencies # if software.dependencies: - dependencies_text = ",".join(software.dependencies) + dependencies_text = "Dependencies: " + ",".join(software.dependencies) dependencies = customtkinter.CTkLabel(info_frame, text=dependencies_text) dependencies.pack(anchor="w", side="top", padx=20) elements.append(dependencies) + # extra_files # + if software.extra_files: + extra_text = "Targets extra directories: " + ",".join(set(software.extra_files.values())) + extra_text_label = customtkinter.CTkLabel(info_frame, text=extra_text) + extra_text_label.pack(anchor="w", side="top", padx=20) + elements.append(extra_text_label) + # buttons # install_button = customtkinter.CTkButton(info_frame, text="Install", command=lambda: software.install()) @@ -75,15 +99,21 @@ def create_details_page(app, software): elements.append(remove_button) # add other pictures # - i = 0 - for path in software.pictures[1:]: - img = PIL.Image.open(path) - img = img.resize((200, 300)) - img = PIL.ImageTk.PhotoImage(img) - extra_pic_button = customtkinter.CTkButton(app, text="", image=img, width=200, height=300, - command=lambda: show_large_picture(app, path)) - extra_pic_button.grid(padx=10, pady=10, row=0, column=i) - elements.append(extra_pic_button) - i += 1 + if software.pictures: + + picture_frame = customtkinter.CTkScrollableFrame(info_frame, height=200, width=300, orientation="horizontal") + picture_frame.pack(anchor="w", side="top", padx=10) + + i = 0 + for path in software.pictures[1:]: + img = PIL.Image.open(path) + img = img.resize((180, 180)) + img = PIL.ImageTk.PhotoImage(img) + extra_pic_button = customtkinter.CTkButton(picture_frame, text="", image=img, command=lambda: show_large_picture(app, path)) + extra_pic_button.grid(padx=10, pady=10, row=0, column=i) + elements.append(extra_pic_button) + i += 1 + + elements.append(picture_frame) return elements diff --git a/example_software_root/FreeDink/meta.yaml b/example_software_root/FreeDink/meta.yaml index 1821ffc..92cfbfb 100644 --- a/example_software_root/FreeDink/meta.yaml +++ b/example_software_root/FreeDink/meta.yaml @@ -11,6 +11,5 @@ dependencies: - DirectX 9.0c link_only: false extra_files: - dummy_file_1.txt: "%APP_DATA%/game_vault/" - dummy_dir_1: "%APP_DATA%/game_vault/" + dummy_file_1.txt: "%APPDATA%/game_vault/" run_exe: "GNUFreeDink/dink.exe" \ No newline at end of file diff --git a/example_software_root/FreeDink/pictures/freedink_ingamel.jpg b/example_software_root/FreeDink/pictures/freedink_ingamel.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0f161b182548b84d3631b94c91480a8ff9a795f3 GIT binary patch literal 33869 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 literal 0 HcmV?d00001 diff --git a/software.py b/software.py index 5eaef81..36b178a 100644 --- a/software.py +++ b/software.py @@ -2,6 +2,8 @@ import yaml import os import localaction import zipfile +import shutil +import pathlib class Software: @@ -84,7 +86,13 @@ class Software: print("Running installer:", installer_path) localaction.run_exe(installer_path) - # TODO download & install gamefiles # + # install gamefiles # + if self.extra_files: + for src, dest in self.extra_files.items(): + tmp = self.backend.get(os.path.join(self.directory, "extra_files", src), self.cache_dir) + dest_dir = os.path.expandvars(dest) + os.makedirs(dest_dir, exist_ok=True) + shutil.copy(tmp, dest_dir) def run(self): '''Run the configured exe for this software'''