Files
jail-launcher/assets/make_icon.py
T

100 lines
2.8 KiB
Python

"""Genera un icono provisional para jlauncher (PNG 1024x1024).
Dibuja un «squircle» con degradado y un triángulo de «play» (es un lanzador de juegos).
Se ejecuta sin pantalla con la plataforma offscreen de Qt:
QT_QPA_PLATFORM=offscreen .venv/bin/python assets/make_icon.py
Salida: assets/icon.png. El .icns lo construye build.sh con iconutil.
"""
from __future__ import annotations
import os
from pathlib import Path
os.environ.setdefault("QT_QPA_PLATFORM", "offscreen")
from PySide6.QtCore import QPointF, QRectF, Qt # noqa: E402
from PySide6.QtGui import ( # noqa: E402
QBrush,
QColor,
QGuiApplication,
QImage,
QLinearGradient,
QPainter,
QPainterPath,
)
SIZE = 1024
def render() -> QImage:
img = QImage(SIZE, SIZE, QImage.Format_ARGB32)
img.fill(Qt.transparent)
p = QPainter(img)
p.setRenderHint(QPainter.Antialiasing, True)
# «Squircle»: rectángulo con esquinas redondeadas estilo macOS (~22% del lado).
margin = SIZE * 0.06
rect = QRectF(margin, margin, SIZE - 2 * margin, SIZE - 2 * margin)
radius = rect.width() * 0.2237
body = QPainterPath()
body.addRoundedRect(rect, radius, radius)
grad = QLinearGradient(rect.topLeft(), rect.bottomRight())
grad.setColorAt(0.0, QColor("#4b3bd6"))
grad.setColorAt(1.0, QColor("#7b2ff7"))
p.fillPath(body, QBrush(grad))
# Barras verticales tenues: guiño a «jail».
p.save()
p.setClipPath(body)
p.setPen(Qt.NoPen)
p.setBrush(QColor(255, 255, 255, 26))
bars = 5
bar_w = rect.width() * 0.052
gap = (rect.width() - bars * bar_w) / (bars + 1)
x = rect.left() + gap
for _ in range(bars):
p.drawRoundedRect(QRectF(x, rect.top(), bar_w, rect.height()), bar_w / 2, bar_w / 2)
x += bar_w + gap
p.restore()
# Triángulo de «play» centrado, blanco con esquinas redondeadas.
cx, cy = rect.center().x(), rect.center().y()
r = rect.width() * 0.26
tri = QPainterPath()
tri.moveTo(QPointF(cx - r * 0.55, cy - r * 0.95))
tri.lineTo(QPointF(cx - r * 0.55, cy + r * 0.95))
tri.lineTo(QPointF(cx + r * 1.0, cy))
tri.closeSubpath()
pen_brush = QColor("#ffffff")
stroker_pen = p.pen()
stroker_pen.setColor(pen_brush)
stroker_pen.setWidthF(r * 0.28)
stroker_pen.setJoinStyle(Qt.RoundJoin)
stroker_pen.setCapStyle(Qt.RoundCap)
p.strokePath(tri, stroker_pen)
p.fillPath(tri, pen_brush)
p.end()
return img
def main() -> int:
QGuiApplication([])
out = Path(__file__).resolve().parent / "icon.png"
img = render()
if not img.save(str(out), "PNG"):
print(f"[icon] no se pudo guardar {out}")
return 1
print(f"[icon] generado {out} ({SIZE}x{SIZE})")
return 0
if __name__ == "__main__":
raise SystemExit(main())