From 86a76c5b350c50ad4a356fd24257bffd60c619f1 Mon Sep 17 00:00:00 2001 From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com> Date: Sun, 30 Mar 2025 14:23:09 +1000 Subject: [PATCH 1/6] Move WinSize.txt to parent directory This will make it so it can be git ignored. --- .gitignore | 3 ++- GUI.py | 8 ++++---- scripts/template.sst | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 scripts/template.sst diff --git a/.gitignore b/.gitignore index 511b903..5040a31 100644 --- a/.gitignore +++ b/.gitignore @@ -162,4 +162,5 @@ cython_debug/ back.bmp Snark.code-workspace *.mdl -scripts/ +# scripts/ +WinSize.txt \ No newline at end of file diff --git a/GUI.py b/GUI.py index 8e37ef3..c9037bc 100644 --- a/GUI.py +++ b/GUI.py @@ -287,8 +287,8 @@ def __init__(self): self.selTheme = self.options["theme"] winSizeFile = False - if sys.platform == "linux" and os.path.exists("save/WinSize.txt"): - wsFile = open("save/WinSize.txt", "r") + if sys.platform == "linux" and os.path.exists("WinSize.txt"): + wsFile = open("WinSize.txt", "r") ws = wsFile.readlines() wsFile.close() winSizeFile = True @@ -477,8 +477,8 @@ def __init__(self): else: self.geometry("501x443") - if not os.path.exists("save/WinSize.txt"): - wsf = open("save/WinSize.txt", "w") + if not os.path.exists("WinSize.txt"): + wsf = open("WinSize.txt", "w") wsf.write(f"{self.goodWidth}\n{self.goodHeight}") wsf.close() diff --git a/scripts/template.sst b/scripts/template.sst new file mode 100644 index 0000000..9cf6370 --- /dev/null +++ b/scripts/template.sst @@ -0,0 +1,34 @@ +- +version 1 +format jsonc +- +{ + "name": "Template Script", + // You can specify a global output folder for every task + "globalOutput": "path/to/output/folder", + "tasks": [ + { + // This specifies the name of the task, this will show up in the console when the task has been started. + // Task names cannot have slashes in their name, otherwise it will confuse the interpreter. + "name": "Decompile MDL", + // Valid values for tasks are compile, decompile and view. + "task": "decompile", + "file": "absolute/path/to/mdl/file", + // You can use this key to specify an output folder for this specific task. + "output": "path/to/output/folder" + }, + { + "name": "Compile MDL", + "task": "compile", + "file": "absolute/path/to/qc/file", + // Please note that with compile tasks, the output will not be put in a subfolder of the output folder. + "output": "path/to/output/folder" + }, + { + "name": "View Compiled Model", + "task": "view", + // For the file key in view tasks, you can specify the file you want to open, or specify a compile task to open a MDL file of your choice! + "file": "Compile MDL" + } + ] +} \ No newline at end of file From d3c96b642eed9890fbcb63be7a75bd4a1d84a3b1 Mon Sep 17 00:00:00 2001 From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com> Date: Sun, 30 Mar 2025 15:08:18 +1000 Subject: [PATCH 2/6] Script GUI update --- GUI.py | 2 +- menus.py | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/GUI.py b/GUI.py index c9037bc..7915f5b 100644 --- a/GUI.py +++ b/GUI.py @@ -29,7 +29,7 @@ def __init__(self): self.devMode = False # Flag specifically for Snark, scripts are currently not implemented yet and is a copy of the scripting system from SMD Tools v1.1 # This will allow me to disable the functionality for it until I come up with a proper implementation - self.allowScripts = False + self.allowScripts = True # Another flag for Snark, it disables booting to the "games" menu and makes the menu show a "This menu will be completed soon" message # instead of showing the (very much) incomplete menu self.allowGames = True diff --git a/menus.py b/menus.py index fcb9024..7b7761c 100644 --- a/menus.py +++ b/menus.py @@ -1650,6 +1650,9 @@ def __init__(self, template, master, startHidden:bool=False): self.master = master thme = template.thme self.thme, self.safeWidth = thme, template.safeWidth + if self.safeWidth > 609: + n = 3 + self.widthFix, self.conFix = self.widthFix-n, self.conFix-n # Setting up options js = open("save/options.json", 'r') self.options = json.loads(js.read()) @@ -1669,7 +1672,7 @@ def __init__(self, template, master, startHidden:bool=False): count += 1 self.scr_list.insert(count, self.scripts[count]) self.runBtn = Button(master, text="Run script", cursor="hand2") - self.console = Console(master, 'Run a script and an output of the script\'s progress will appear here!', 0, 2, self.conFix, 12) + self.console = Console(master, 'Run a script and an output of the script\'s progress will appear here!', 0, 2, self.conFix, 11) if not startHidden: self.show() From 69ed83c9c5ba98f514bbfeadfaccb8e00842022a Mon Sep 17 00:00:00 2001 From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com> Date: Sun, 30 Mar 2025 19:04:01 +1000 Subject: [PATCH 3/6] HLAM Wayland Fix + improvements - Added XDG_SESSION_TYPE=x11 to the command for starting up HLAM so the program will work properly under Wayland. - Fixed the -k option being displayed improperly on other Linux systems. - Fixed the "Prioritise Default Paths" option not displaying. - Improved the script GUI. - Moved the Model Viewer path tooltip to the "Set Model Viewer Executable" button. - Fixed the -k option not displaying when the default compiler is set to "Svengine" - Fixed the default compiler option not properly displaying what you selected --- GUI.py | 2 +- menus.py | 27 ++++++++++++++++++--------- version.txt | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/GUI.py b/GUI.py index 7915f5b..c9037bc 100644 --- a/GUI.py +++ b/GUI.py @@ -29,7 +29,7 @@ def __init__(self): self.devMode = False # Flag specifically for Snark, scripts are currently not implemented yet and is a copy of the scripting system from SMD Tools v1.1 # This will allow me to disable the functionality for it until I come up with a proper implementation - self.allowScripts = True + self.allowScripts = False # Another flag for Snark, it disables booting to the "games" menu and makes the menu show a "This menu will be completed soon" message # instead of showing the (very much) incomplete menu self.allowGames = True diff --git a/menus.py b/menus.py index 7b7761c..b85161d 100644 --- a/menus.py +++ b/menus.py @@ -430,7 +430,7 @@ def openHLAM(self): # If "Half-Life Asset Manager" is selected if self.options["gsMV"]["selectedMV"] == 1: if sys.platform == "linux": - a = subprocess.getoutput(f"hlam \"{self.name.get()}\"") + a = subprocess.getoutput(f"XDG_SESSION_TYPE=x11 hlam \"{self.name.get()}\"") else: a = subprocess.getoutput(f"\"C:/Program Files (x86)/Half-Life Asset Manager/hlam.exe\" \"{self.name.get()}\"") # If "Other" option is selected @@ -672,7 +672,6 @@ def __init__(self, template, master, startHidden:bool=False): self.hitboxB = BooleanVar(self.advOpt, value=False) self.hitboxChk = Checkbutton(self.advOpt, text="-h", variable=self.hitboxB) self.keepBonesB = BooleanVar(self.advOpt, value=False) - self.keepBonesChk = Checkbutton(self.advOpt, text="-k", variable=self.keepBonesB) if self.advOptFix: self.ignoreB = BooleanVar(self.advOpt, value=False) self.ignoreChk = Checkbutton(self.advOpt, text="-i", variable=self.ignoreB) @@ -686,6 +685,7 @@ def __init__(self, template, master, startHidden:bool=False): self.groupSB.entry.config(width=4) self.pf2B = BooleanVar(self.advOpt, value=False) self.pf2Chk = Checkbutton(self.advOpt, text="-p", variable=self.pf2B) + self.keepBonesChk = Checkbutton(self.advOpt, text="-k", variable=self.keepBonesB) else: self.ignoreB = BooleanVar(self.advOpt, value=False) self.ignoreChk = Checkbutton(self.advOpt, text="-i", variable=self.ignoreB) @@ -699,6 +699,7 @@ def __init__(self, template, master, startHidden:bool=False): self.groupSB.entry.config(width=4) self.pf2B = BooleanVar(self.advOpt2, value=False) self.pf2Chk = Checkbutton(self.advOpt2, text="-p", variable=self.pf2B) + self.keepBonesChk = Checkbutton(self.advOpt2, text="-k", variable=self.keepBonesB) # Tooltips self.logChkTT = ToolTip(self.logChk, "Writes the log in the terminal below as a text file inside the logs folder.", background=thme["tt"], foreground=thme["txt"]) self.dashTChkTT = ToolTip(self.dashTChk, "Specify a texture to replace while compiling, you can globally replace all textures by specifying one bitmap or replace a single texture by following this format: \'tex1.bmp,tex2.bmp\'.", background=thme["tt"], foreground=thme["txt"]) @@ -713,6 +714,9 @@ def __init__(self, template, master, startHidden:bool=False): self.pf2ChkTT = ToolTip(self.pf2Chk, "Forces power of 2 textures when enabled", background=thme["tt"], foreground=thme["txt"]) self.mdlTT = ToolTip(self.mdlBrowse, "REQUIRED, specifies the QC file used to compile your model, you cannot leave this blank.", background=thme["tt"], foreground=thme["txt"]) self.outputTT = ToolTip(self.outBrowse, "OPTIONAL, if an output folder is not specified, then it will place the compiled model in a subfolder of where the QC file is located.", background=thme["tt"], foreground=thme["txt"]) + + # Checking if the default compiler has the engine type Svengine. + self.compilerStuff() self.decomp = Button(master, text='Compile', command=self.startCompile, cursor="hand2") self.console = Console(master, 'Currently no warnings or errors!', 0, 5, self.conFix, 12) @@ -779,7 +783,7 @@ def groupSBhandler(self): else: self.groupSB.lock() - def compilerStuff(self, event): + def compilerStuff(self, event=None): self.compJS = self.fullCJS["compilers"][self.compSel.get()] if self.compJS["type"].lower() == "svengine": self.svengine = True @@ -801,7 +805,7 @@ def openHLAM(self): # If "Half-Life Asset Manager" is selected if self.options["gsMV"]["selectedMV"] == 1: if sys.platform == "linux": - a = subprocess.getoutput(f"hlam \"{self.mdlPath}\"") + a = subprocess.getoutput(f"XDG_SESSION_TYPE=x11 hlam \"{self.mdlPath}\"") else: a = subprocess.getoutput(f"\"C:/Program Files (x86)/Half-Life Asset Manager/hlam.exe\" \"{self.mdlPath}\"") # If "Other" option is selected @@ -879,6 +883,7 @@ def updateOpt(self, key, value): # Doing specific things for specific options if key == "defComp": self.compSel.current(self.options[key]) + self.compilerStuff() elif key == "defGame": self.gameSel.current(self.options[key]) # Doing this since the gsMV option needs two square bracket data things in order to update stuff properly, @@ -1377,7 +1382,7 @@ def __init__(self, template, master, thmecallback, updFunc, startHidden:bool=Fal cOptions.pop(len(cOptions)-1) self.compSel = ttk.Combobox(master, values=cOptions) self.compSel.bind("<>", self.setCmp) - self.compSel.current(self.options["defGame"]) + self.compSel.current(self.options["defComp"]) gList = open("save/games.txt", "r") self.gOptions = gList.read().split('\n') self.gOptions.pop(len(self.gOptions)-1) @@ -1387,16 +1392,16 @@ def __init__(self, template, master, thmecallback, updFunc, startHidden:bool=Fal self.gameSel.bind("<>", self.setGame) self.gameSel.current(self.options["defGame"]) # Checking if anything is exceeding the width of the "safe zone" - self.show() + """self.show() self.checkWidth() - self.hide() + self.hide()""" # Tooltips self.themeTT = ToolTip(self.themeCBox, "Changes the program's theme, the built-in themes are: Freeman, Shephard, Calhoun and Cross.", background=thme["tt"], foreground=thme["txt"]) self.startFolderTT = ToolTip(self.startFent, "Sets the directory that the built-in file explorer will start in, the default is the documents folder.", background=thme["tt"], foreground=thme["txt"]) self.startFolderTT2 = ToolTip(self.setSF, "Sets the directory that the built-in file explorer will start in, the default is the documents folder.", background=thme["tt"], foreground=thme["txt"]) self.forceDefTT = ToolTip(self.forceDefault, "By default, Snark prioritises the custom path you set over the default paths for compilers, enabling this will prioritise the default paths instead, meaning that Snark won't use the custom path if it finds the compiler in its default path.", background=thme["tt"], foreground=thme["txt"]) self.hlmvTT = ToolTip(self.hlmvCBox, "Sets the model viewer you want to use when clicking the \"Open model in HLMV\" button, if this is set to None, the button will not show up!", background=thme["tt"], foreground=thme["txt"]) - self.mvPathTT = ToolTip(self.mvPathEnt.entry, "Sets the path to the model viewer you want to use if you select \"Other\"", background=thme["tt"], foreground=thme["txt"]) + self.setMVPtt = ToolTip(self.setMVP, "Sets the path to the model viewer you want to use if you select \"Other\"", background=thme["tt"], foreground=thme["txt"]) if not startHidden: self.show() @@ -1458,6 +1463,7 @@ def genPg(self): self.startFent.grid(column=2, row=2, sticky="w") self.setSF.grid(column=3, row=2, sticky="w") self.fdLabel.grid(column=1, row=3, sticky="w") + self.forceDefault.grid(column=2, row=3, sticky="w") self.defCLabel.grid(column=1, row=4, sticky="w") self.compSel.grid(column=2, row=4, sticky="w") self.defGLabel.grid(column=1, row=5, sticky="w") @@ -1624,6 +1630,7 @@ def show(self): self.startFent.grid(column=2, row=2, sticky="w") self.setSF.grid(column=3, row=2, sticky="w") self.fdLabel.grid(column=1, row=3, sticky="w") + self.forceDefault.grid(column=2, row=3, sticky="w") self.defCLabel.grid(column=1, row=4, sticky="w") self.compSel.grid(column=2, row=4, sticky="w") self.defGLabel.grid(column=1, row=5, sticky="w") @@ -1640,10 +1647,12 @@ def __init__(self, template, master, startHidden:bool=False): self.curFont = font.nametofont('TkDefaultFont').actual() self.widthFix = 74 self.conFix = 46 + self.conHeight = 11 self.logOutput = False if self.curFont["family"].lower() == "nimbus sans l" or sys.platform == "win32": self.widthFix = 81 self.conFix = 59 + self.conHeight = 13 else: pass self.hidden = startHidden @@ -1672,7 +1681,7 @@ def __init__(self, template, master, startHidden:bool=False): count += 1 self.scr_list.insert(count, self.scripts[count]) self.runBtn = Button(master, text="Run script", cursor="hand2") - self.console = Console(master, 'Run a script and an output of the script\'s progress will appear here!', 0, 2, self.conFix, 11) + self.console = Console(master, 'Run a script and an output of the script\'s progress will appear here!', 0, 2, self.conFix, self.conHeight) if not startHidden: self.show() diff --git a/version.txt b/version.txt index 12bda4c..e2c9a17 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v0.1.3-(OS)-alpha +v0.1.4-(OS)-alpha From 29004c2474986b4e6e104d7d462b77ba7ea50b57 Mon Sep 17 00:00:00 2001 From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com> Date: Sun, 30 Mar 2025 19:25:42 +1000 Subject: [PATCH 4/6] Remove tksvg --- GUI.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/GUI.py b/GUI.py index c9037bc..0a3b34a 100644 --- a/GUI.py +++ b/GUI.py @@ -2,10 +2,6 @@ from tkinter import * from tkinter.filedialog import askopenfilename, askdirectory from tkinter import font -try: - import tksvg -except: - pass import os from os.path import * import importlib.machinery @@ -294,10 +290,7 @@ def __init__(self): winSizeFile = True # Loading in window icon - try: - ico = tksvg.SvgImage(file="icon-linux.svg") - except: - ico = PhotoImage(file="icon-linux.png") + ico = PhotoImage(file="icon-linux.png") self.iconphoto(True, ico) thCol = {} From 813b6214697d1512280d1ec8d4446a82f1c40d9d Mon Sep 17 00:00:00 2001 From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com> Date: Sun, 30 Mar 2025 19:34:01 +1000 Subject: [PATCH 5/6] Update Github Actions --- .github/workflows/pyinstaller-linux.yml | 33 ------------------------- .github/workflows/pyinstaller.yml | 6 ++--- 2 files changed, 3 insertions(+), 36 deletions(-) delete mode 100644 .github/workflows/pyinstaller-linux.yml diff --git a/.github/workflows/pyinstaller-linux.yml b/.github/workflows/pyinstaller-linux.yml deleted file mode 100644 index d0cf26e..0000000 --- a/.github/workflows/pyinstaller-linux.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: PyInstaller Action Linux -on: [push] -jobs: - pyinstaller-build: - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest] - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set date environment variable - run: echo "DATE=$(date +%d-%m-%Y)" >> $GITHUB_ENV - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.12.7' - - name: Install dependencies - run: | - sudo apt install cmake build-essential tcl-dev tk-dev python3-tk - python -m pip install --upgrade pip - pip install pyinstaller - pip install jsoncparser - pip install scikit-build - pip install tksvg - - name: Run PyInstaller - run: | - pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "icon-linux.svg:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py" - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: Snark-${{ matrix.os }}-${{ env.DATE }} - path: dist/Snark diff --git a/.github/workflows/pyinstaller.yml b/.github/workflows/pyinstaller.yml index 3b07522..612dd68 100644 --- a/.github/workflows/pyinstaller.yml +++ b/.github/workflows/pyinstaller.yml @@ -5,7 +5,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [windows-latest] + os: [windows-latest, ubuntu-latest] steps: - name: Checkout code uses: actions/checkout@v4 @@ -14,7 +14,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.12.7' + python-version: '3.12.9' - name: Install dependencies run: | python -m pip install --upgrade pip @@ -22,7 +22,7 @@ jobs: pip install jsoncparser - name: Run PyInstaller run: | - pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py" + pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "icon-linux.svg:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py" - name: Upload artifact uses: actions/upload-artifact@v4 with: From 006239abae9caa74f95ed67707edc119279c32ef Mon Sep 17 00:00:00 2001 From: PostScriptReal <149461738+PostScriptReal@users.noreply.github.com> Date: Sun, 30 Mar 2025 19:46:25 +1000 Subject: [PATCH 6/6] Update Github Actions Linux versions will now be built using python 3.13.2, Windows versions will be using the latest release of 3.12 so Windows 8.1 will still be supported. --- .github/workflows/pyinstaller-linux.yml | 30 +++++++++++++++++++++++++ .github/workflows/pyinstaller.yml | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/pyinstaller-linux.yml diff --git a/.github/workflows/pyinstaller-linux.yml b/.github/workflows/pyinstaller-linux.yml new file mode 100644 index 0000000..1b74f54 --- /dev/null +++ b/.github/workflows/pyinstaller-linux.yml @@ -0,0 +1,30 @@ +name: PyInstaller Action (3.13.2) +on: [push] +jobs: + pyinstaller-build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest] + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set date environment variable + run: echo "DATE=$(date +%d-%m-%Y)" >> $GITHUB_ENV + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.13.2' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pyinstaller + pip install jsoncparser + - name: Run PyInstaller + run: | + pyinstaller --noconfirm --onedir --console --name "Snark" --add-data "version.txt:." --add-data "activities.txt:." --add-data "logo128.png:." --add-data "icon-win32.ico:." --add-data "icon-linux.png:." --add-data "icon-linux.svg:." --add-data "LICENSE:." --add-data "README.md:." --add-data "save:save/" --add-data "themes:themes/" --add-data "third_party:third_party/" --add-data "images:images/" --add-data "logs:logs/" "GUI.py" + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: Snark-${{ matrix.os }}-${{ env.DATE }} + path: dist/Snark diff --git a/.github/workflows/pyinstaller.yml b/.github/workflows/pyinstaller.yml index 612dd68..e8ce4ac 100644 --- a/.github/workflows/pyinstaller.yml +++ b/.github/workflows/pyinstaller.yml @@ -5,7 +5,7 @@ jobs: runs-on: ${{ matrix.os }} strategy: matrix: - os: [windows-latest, ubuntu-latest] + os: [windows-latest] steps: - name: Checkout code uses: actions/checkout@v4