The icon now comes from images/mtga-assistant-icon.png: make_icon.py copies it into the package (window, taskbar and tray icon) and builds the Windows .ico used for the .exe. The old generated SVG icon is gone. The PyInstaller spec also keeps QtNetwork, needed for single-instance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
54 lines
1.9 KiB
Python
54 lines
1.9 KiB
Python
"""Build the app icons from images/mtga-assistant-icon.png (the single source image).
|
|
|
|
Writes:
|
|
* src/mtga_assistant/icon.png: loaded at runtime for the window, taskbar and tray icon.
|
|
* images/mtga-assistant-icon.ico: the Windows .exe icon (PNG-compressed entries at the usual sizes).
|
|
|
|
Run after changing the source image: uv run python packaging/make_icon.py
|
|
"""
|
|
|
|
import shutil
|
|
import struct
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
from PySide6.QtCore import QBuffer, QByteArray, QIODevice, Qt
|
|
from PySide6.QtGui import QGuiApplication, QImage
|
|
|
|
SIZES = [16, 24, 32, 48, 64, 128, 256]
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
SOURCE = ROOT / "images" / "mtga-assistant-icon.png"
|
|
|
|
|
|
def png_at(img: QImage, size: int) -> bytes:
|
|
scaled = img.scaled(size, size, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)
|
|
data = QByteArray()
|
|
buf = QBuffer(data)
|
|
buf.open(QIODevice.OpenModeFlag.WriteOnly)
|
|
scaled.save(buf, "PNG") # type: ignore[arg-type] # PySide accepts str; its stubs say bytes
|
|
return data.data()
|
|
|
|
|
|
def main() -> None:
|
|
QGuiApplication(sys.argv[:1])
|
|
img = QImage(str(SOURCE))
|
|
if img.isNull():
|
|
sys.exit(f"can't read {SOURCE}")
|
|
pngs = [(size, png_at(img, size)) for size in SIZES]
|
|
# ICONDIR header, one ICONDIRENTRY per image, then the PNG data.
|
|
out = struct.pack("<HHH", 0, 1, len(pngs))
|
|
offset = 6 + 16 * len(pngs)
|
|
for size, png in pngs:
|
|
dim = 0 if size >= 256 else size # 0 means 256
|
|
out += struct.pack("<BBBBHHII", dim, dim, 0, 0, 1, 32, len(png), offset)
|
|
offset += len(png)
|
|
out += b"".join(png for _, png in pngs)
|
|
ico = SOURCE.with_suffix(".ico")
|
|
ico.write_bytes(out)
|
|
shutil.copyfile(SOURCE, ROOT / "src" / "mtga_assistant" / "icon.png")
|
|
print(f"wrote {ico.relative_to(ROOT)} and src/mtga_assistant/icon.png from {SOURCE.relative_to(ROOT)}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|