Add Footer, Remove Mods, and Add Main Mod
All checks were successful
Build and Upload Release (Windows EXE) / Build Windows EXE (release) Successful in 3m30s

This commit is contained in:
2025-09-16 15:10:13 -04:00
parent ca4fd2c9d5
commit 6b520a1bcc
6 changed files with 126 additions and 43 deletions

View File

@@ -3,6 +3,7 @@ import os
import shutil
import sys
import threading
import webbrowser
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, List, Tuple
@@ -209,9 +210,23 @@ class SeaLoaderApp(tk.Tk):
bottom.pack(fill=tk.X, padx=12, pady=(0, 12))
self.enable_btn = ttk.Button(bottom, text="Enable Matching Mods", command=self._on_enable)
self.enable_btn.pack(side=tk.LEFT)
self.disable_all_btn = ttk.Button(bottom, text="Disable All Mods", command=self._on_disable_all)
self.disable_all_btn.pack(side=tk.LEFT, padx=(8, 0))
self.help_btn = ttk.Button(bottom, text="Help", command=self._on_help)
self.help_btn.pack(side=tk.RIGHT)
# Footer attribution
footer = ttk.Frame(self, style="TFrame")
footer.pack(fill=tk.X, padx=12, pady=(0, 10))
self._footer_icon = self._load_png_icon("hrsys.png", max_px=18)
if self._footer_icon is not None:
icon_lbl = ttk.Label(footer, image=self._footer_icon, style="TLabel")
icon_lbl.pack(side=tk.LEFT)
icon_lbl.bind("<Button-1>", lambda e: self._open_link("https://hudsonriggs.systems"))
link_lbl = ttk.Label(footer, text="Created by HudsonRiggs.Systems", style="TLabel", foreground=MUTED)
link_lbl.pack(side=tk.LEFT, padx=(6, 0))
link_lbl.bind("<Button-1>", lambda e: self._open_link("https://hudsonriggs.systems"))
def _create_tree(self, parent, columns: List[str], ratios: List[float]):
tree = ttk.Treeview(parent, columns=columns, show="headings", height=12)
for col in columns:
@@ -219,12 +234,10 @@ class SeaLoaderApp(tk.Tk):
tree.column(col, width=50, anchor=tk.W, stretch=True)
vsb = ttk.Scrollbar(parent, orient="vertical", command=tree.yview)
hsb = ttk.Scrollbar(parent, orient="horizontal", command=tree.xview)
tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set)
tree.configure(yscrollcommand=vsb.set)
tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
vsb.pack(side=tk.LEFT, fill=tk.Y)
hsb.pack(side=tk.BOTTOM, fill=tk.X)
self._bind_auto_columns(parent, tree, ratios)
return tree
@@ -372,6 +385,59 @@ class SeaLoaderApp(tk.Tk):
pass
return Path(__file__).resolve().parent / name
def _open_link(self, url: str) -> None:
try:
webbrowser.open(url)
except Exception:
pass
def _load_png_icon(self, filename: str, max_px: int = 18):
try:
png_path = self._resource_path(filename)
if not png_path.exists():
return None
img = tk.PhotoImage(file=str(png_path))
# Downscale if needed using integer subsample
sx = max(img.width() // max_px, 1)
sy = max(img.height() // max_px, 1)
scale = max(sx, sy)
if scale > 1:
img = img.subsample(scale, scale)
return img
except Exception:
return None
def _on_disable_all(self) -> None:
confirm = messagebox.askyesno("SeaLoader", "Disable all mods in usersettings.ini?")
if not confirm:
return
try:
self._disable_all_mods()
except Exception as exc:
messagebox.showerror("SeaLoader", f"Failed to disable all mods: {exc}")
return
self._load_installed_mods()
messagebox.showinfo("SeaLoader", "All mods disabled.")
def _disable_all_mods(self) -> None:
parser = configparser.ConfigParser()
parser.optionxform = str
parser.read(self.ini_path, encoding="utf-8")
section = "LoadOrder"
if section not in parser:
raise ValueError("[LoadOrder] section not found in usersettings.ini")
shutil.copyfile(self.ini_path, self.ini_path + ".bak")
for key, value in list(parser[section].items()):
if not key.lower().startswith("mod"):
continue
parts = value.split(",")
if not parts:
continue
left_token = parts[0].strip()
parser[section][key] = f"{left_token},False"
with open(self.ini_path, "w", encoding="utf-8") as f:
parser.write(f)
def main() -> None:
ini_path = DEFAULT_INI_PATH