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:
64
tools/download_icons.py
Normal file
64
tools/download_icons.py
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Download Material Design Icons PNG from GitHub.
|
||||
|
||||
Source: github.com/material-icons/material-icons-png (Apache 2.0)
|
||||
Style: round-4x (96x96 px) — enough for 4x HiDPI
|
||||
"""
|
||||
import os
|
||||
import urllib.request
|
||||
import time
|
||||
|
||||
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
BASE_URL = "https://raw.githubusercontent.com/material-icons/material-icons-png/master/png"
|
||||
|
||||
ICONS = [
|
||||
"add", "arrow_back", "arrow_upward", "backspace", "check", "close",
|
||||
"code", "computer", "content_copy", "dashboard", "delete", "edit",
|
||||
"file_upload", "folder", "folder_open", "info",
|
||||
"language", "lock", "play_arrow", "refresh", "save", "search",
|
||||
"settings", "storage", "trending_up", "visibility", "vpn_key",
|
||||
]
|
||||
|
||||
# Icons with different names on GitHub vs local filename
|
||||
ICON_RENAMES = {
|
||||
"get_app": "file_download", # Material "get_app" = download icon
|
||||
}
|
||||
|
||||
# GitHub color dir → local theme dir
|
||||
VARIANTS = {"white": "dark", "black": "light"}
|
||||
|
||||
|
||||
def download():
|
||||
done = 0
|
||||
errors = 0
|
||||
all_icons = [(name, name) for name in ICONS]
|
||||
all_icons += [(gh_name, local_name) for gh_name, local_name in ICON_RENAMES.items()]
|
||||
total = len(all_icons) * len(VARIANTS)
|
||||
|
||||
for gh_color, local_dir in VARIANTS.items():
|
||||
out_dir = os.path.join(PROJECT_DIR, "assets", "icons", local_dir)
|
||||
os.makedirs(out_dir, exist_ok=True)
|
||||
for gh_name, local_name in all_icons:
|
||||
done += 1
|
||||
dst = os.path.join(out_dir, f"{local_name}.png")
|
||||
if os.path.exists(dst):
|
||||
print(f" [{done}/{total}] SKIP {local_dir}/{local_name}.png")
|
||||
continue
|
||||
url = f"{BASE_URL}/{gh_color}/{gh_name}/round-4x.png"
|
||||
print(f" [{done}/{total}] GET {local_dir}/{local_name}.png ...", end=" ")
|
||||
try:
|
||||
urllib.request.urlretrieve(url, dst)
|
||||
size_kb = os.path.getsize(dst) / 1024
|
||||
print(f"OK ({size_kb:.1f} KB)")
|
||||
except Exception as e:
|
||||
print(f"FAIL: {e}")
|
||||
errors += 1
|
||||
time.sleep(0.1)
|
||||
|
||||
print(f"\nDone: {total - errors}/{total} icons downloaded")
|
||||
if errors:
|
||||
print(f" {errors} errors — re-run to retry")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
download()
|
||||
Reference in New Issue
Block a user