v1.9.1: PNG Material Design icons — 28 icons, dark/light theme, HiDPI, graceful Unicode fallback

- 56 PNG icons (28 unique × 2 color variants) from Material Design Icons (round style, 96×96px)
- core/icons.py: ctk_icon(), make_icon_button(), reconfigure_icon_button() with CTkImage cache
- Updated 15 GUI files: app.py, sidebar.py, server_dialog.py, all tabs
- build.py: auto-include assets/icons/ in PyInstaller bundle, patch rollover at 99→minor+1
- tools/download_icons.py: icon download script
- Automatic dark↔light theme switching via CTkImage dual-image support

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
chrome-storm-c442
2026-03-03 07:27:49 -05:00
parent 9b0e4c76a3
commit 1e729fcf3a
76 changed files with 397 additions and 148 deletions

View File

@@ -10,7 +10,7 @@ from tkinter import filedialog, messagebox
import customtkinter as ctk
from core.claude_setup import check_status, install_all, install_ssh_script, install_skill, generate_ssh_key
from core.i18n import t
from core.icons import icon_text
from core.icons import icon_text, make_icon_button
from core.logger import log
@@ -70,8 +70,8 @@ class SetupTab(ctk.CTkFrame):
btn_frame = ctk.CTkFrame(self._scroll, fg_color="transparent")
btn_frame.pack(fill="x", padx=20, pady=15)
self.install_all_btn = ctk.CTkButton(
btn_frame, text=icon_text("confirm", t("install_everything")),
self.install_all_btn = make_icon_button(
btn_frame, "confirm", t("install_everything"),
font=ctk.CTkFont(size=14, weight="bold"),
height=40, fg_color="#22c55e", hover_color="#16a34a",
command=self._install_all
@@ -82,16 +82,16 @@ class SetupTab(ctk.CTkFrame):
ind_frame = ctk.CTkFrame(btn_frame, fg_color="transparent")
ind_frame.pack(fill="x")
self.ssh_py_btn = ctk.CTkButton(ind_frame, text=icon_text("confirm", t("install_ssh_py")), width=110, fg_color="#6b7280",
self.ssh_py_btn = make_icon_button(ind_frame, "confirm", t("install_ssh_py"), width=110, fg_color="#6b7280",
command=self._install_script)
self.ssh_py_btn.pack(side="left", padx=(0, 5))
self.skill_btn = ctk.CTkButton(ind_frame, text=icon_text("confirm", t("install_skill")), width=110, fg_color="#6b7280",
self.skill_btn = make_icon_button(ind_frame, "confirm", t("install_skill"), width=110, fg_color="#6b7280",
command=self._install_skill)
self.skill_btn.pack(side="left", padx=5)
self.ssh_key_btn = ctk.CTkButton(ind_frame, text=icon_text("confirm", t("install_ssh_key")), width=110, fg_color="#6b7280",
self.ssh_key_btn = make_icon_button(ind_frame, "confirm", t("install_ssh_key"), width=110, fg_color="#6b7280",
command=self._gen_key)
self.ssh_key_btn.pack(side="left", padx=5)
self.refresh_btn = ctk.CTkButton(ind_frame, text=icon_text("refresh", t("refresh")), width=90, fg_color="#3b82f6",
self.refresh_btn = make_icon_button(ind_frame, "refresh", t("refresh"), width=90, fg_color="#3b82f6",
command=self._refresh_status)
self.refresh_btn.pack(side="right")
@@ -185,8 +185,8 @@ class SetupTab(ctk.CTkFrame):
font=ctk.CTkFont(family="Consolas", size=11)
)
self._path_label.pack(side="left", fill="x", expand=True, padx=(5, 10))
self.change_path_btn = ctk.CTkButton(
path_row, text=icon_text("folder", t("change_path")), width=120, fg_color="#6b7280",
self.change_path_btn = make_icon_button(
path_row, "folder", t("change_path"), width=120, fg_color="#6b7280",
command=self._change_config_path
)
self.change_path_btn.pack(side="right")
@@ -195,8 +195,8 @@ class SetupTab(ctk.CTkFrame):
backup_row = ctk.CTkFrame(config_frame, fg_color="transparent")
backup_row.pack(fill="x", padx=15, pady=(5, 10))
self.backup_btn = ctk.CTkButton(
backup_row, text=icon_text("save", t("backup_now")), width=120, fg_color="#3b82f6",
self.backup_btn = make_icon_button(
backup_row, "save", t("backup_now"), width=120, fg_color="#3b82f6",
command=self._backup_now
)
self.backup_btn.pack(side="left", padx=(0, 10))
@@ -210,8 +210,8 @@ class SetupTab(ctk.CTkFrame):
)
self._backup_menu.pack(side="left", padx=(0, 10))
self.restore_btn = ctk.CTkButton(
backup_row, text=icon_text("refresh", t("restore")), width=100, fg_color="#ef4444", hover_color="#dc2626",
self.restore_btn = make_icon_button(
backup_row, "refresh", t("restore"), width=100, fg_color="#ef4444", hover_color="#dc2626",
command=self._restore_backup
)
self.restore_btn.pack(side="left")
@@ -220,26 +220,26 @@ class SetupTab(ctk.CTkFrame):
ie_row = ctk.CTkFrame(config_frame, fg_color="transparent")
ie_row.pack(fill="x", padx=15, pady=(0, 10))
self.export_config_btn = ctk.CTkButton(
ie_row, text=icon_text("upload", t("export_config")), width=130, fg_color="#6b7280",
self.export_config_btn = make_icon_button(
ie_row, "upload", t("export_config"), width=130, fg_color="#6b7280",
command=self._export_config
)
self.export_config_btn.pack(side="left", padx=(0, 5))
self.import_config_btn = ctk.CTkButton(
ie_row, text=icon_text("download", t("import_config")), width=130, fg_color="#6b7280",
self.import_config_btn = make_icon_button(
ie_row, "download", t("import_config"), width=130, fg_color="#6b7280",
command=self._import_config
)
self.import_config_btn.pack(side="left", padx=5)
self.export_backup_btn = ctk.CTkButton(
ie_row, text=icon_text("upload", t("export_backup")), width=130, fg_color="#6b7280",
self.export_backup_btn = make_icon_button(
ie_row, "upload", t("export_backup"), width=130, fg_color="#6b7280",
command=self._export_backup
)
self.export_backup_btn.pack(side="left", padx=5)
self.import_backup_btn = ctk.CTkButton(
ie_row, text=icon_text("download", t("import_backup")), width=130, fg_color="#6b7280",
self.import_backup_btn = make_icon_button(
ie_row, "download", t("import_backup"), width=130, fg_color="#6b7280",
command=self._import_backup
)
self.import_backup_btn.pack(side="left", padx=5)