diff --git a/assets/icon.ico b/assets/icon.ico deleted file mode 100644 index e3a8ef3..0000000 Binary files a/assets/icon.ico and /dev/null differ diff --git a/assets/icon.svg b/assets/icon.svg deleted file mode 100644 index 3a7106a..0000000 --- a/assets/icon.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/images/mtga-assistant-icon.ico b/images/mtga-assistant-icon.ico new file mode 100644 index 0000000..9f7e9b6 Binary files /dev/null and b/images/mtga-assistant-icon.ico differ diff --git a/images/mtga-assistant-icon.png b/images/mtga-assistant-icon.png new file mode 100644 index 0000000..b993cde Binary files /dev/null and b/images/mtga-assistant-icon.png differ diff --git a/packaging/make_icon.py b/packaging/make_icon.py index b16aa83..c86a506 100644 --- a/packaging/make_icon.py +++ b/packaging/make_icon.py @@ -1,39 +1,41 @@ -"""Render assets/icon.svg to assets/icon.ico (PNG-compressed entries at the usual Windows sizes). +"""Build the app icons from images/mtga-assistant-icon.png (the single source image). -Run with: uv run python packaging/make_icon.py +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, QPainter -from PySide6.QtSvg import QSvgRenderer +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 render_png(renderer: QSvgRenderer, size: int) -> bytes: - img = QImage(size, size, QImage.Format.Format_ARGB32) - img.fill(Qt.GlobalColor.transparent) - painter = QPainter(img) - painter.setRenderHint(QPainter.RenderHint.Antialiasing) - renderer.render(painter) - painter.end() +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) - img.save(buf, "PNG") - return bytes(data) + 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]) - renderer = QSvgRenderer(str(ROOT / "assets/icon.svg")) - pngs = [(size, render_png(renderer, size)) for size in SIZES] - # ICONDIR header, then one ICONDIRENTRY per image, then the PNG data. + 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(" None: out += struct.pack("