Files
WGSecure/app/ui/icons.py
T
2026-06-01 22:31:22 +02:00

107 lines
3.1 KiB
Python

"""Icônes WGSecure — bouclier VPN dessiné via QPainter."""
from PyQt6.QtGui import (
QIcon, QPixmap, QPainter, QColor, QBrush, QPen,
QFont, QPainterPath, QLinearGradient,
)
from PyQt6.QtCore import Qt, QRect, QPointF
def _shield(
size: int,
body_top: str,
body_bot: str,
dot_color: str,
dot: bool = True,
) -> QPixmap:
"""Dessine un bouclier avec dégradé vertical et un indicateur coloré."""
pix = QPixmap(size, size)
pix.fill(Qt.GlobalColor.transparent)
p = QPainter(pix)
p.setRenderHint(QPainter.RenderHint.Antialiasing)
s = size
m = s * 0.06 # marge
# --- Forme bouclier ---
path = QPainterPath()
path.moveTo(s / 2, m)
path.lineTo(s - m, s * 0.25)
path.cubicTo(
s - m, s * 0.65,
s * 0.72, s * 0.85,
s / 2, s - m,
)
path.cubicTo(
s * 0.28, s * 0.85,
m, s * 0.65,
m, s * 0.25,
)
path.closeSubpath()
# Dégradé vertical corps du bouclier
grad = QLinearGradient(QPointF(s / 2, m), QPointF(s / 2, s - m))
grad.setColorAt(0.0, QColor(body_top))
grad.setColorAt(1.0, QColor(body_bot))
p.setBrush(QBrush(grad))
p.setPen(Qt.PenStyle.NoPen)
p.drawPath(path)
# Liseré blanc semi-transparent
pen = QPen(QColor(255, 255, 255, 60))
pen.setWidthF(s * 0.04)
p.setPen(pen)
p.setBrush(Qt.BrushStyle.NoBrush)
p.drawPath(path)
# --- "W" centré ---
p.setPen(QPen(QColor(255, 255, 255, 230)))
font = QFont("Arial", max(7, int(s * 0.38)), QFont.Weight.Bold)
p.setFont(font)
rect = QRect(int(s * 0.08), int(s * 0.22), int(s * 0.84), int(s * 0.55))
p.drawText(rect, Qt.AlignmentFlag.AlignCenter, "W")
# --- Point de statut (coin bas-droit) ---
if dot:
dr = s * 0.22
dx = s - m - dr * 0.5
dy = s * 0.68
# Halo blanc
p.setPen(Qt.PenStyle.NoPen)
p.setBrush(QBrush(QColor(255, 255, 255, 200)))
p.drawEllipse(QPointF(dx, dy), dr * 0.72, dr * 0.72)
# Dot coloré
p.setBrush(QBrush(QColor(dot_color)))
p.drawEllipse(QPointF(dx, dy), dr * 0.55, dr * 0.55)
p.end()
return pix
def icon_connected(size: int = 32) -> QIcon:
return QIcon(_shield(size, "#1a7a4a", "#0d5c35", "#2ecc71", dot=True))
def icon_disconnected(size: int = 32) -> QIcon:
return QIcon(_shield(size, "#2c3e50", "#1a252f", "#e74c3c", dot=True))
def icon_connecting(size: int = 32) -> QIcon:
return QIcon(_shield(size, "#7d5a00", "#4a3500", "#f39c12", dot=True))
def icon_app(size: int = 32) -> QIcon:
"""Icône principale multi-tailles — bouclier bleu sans point de statut.
Plusieurs résolutions pour la barre des tâches, l'alt-tab et le systray."""
ico = QIcon()
for s in (16, 24, 32, 48, 64, 128, 256):
ico.addPixmap(_shield(s, "#2980b9", "#1a5276", "#ffffff", dot=False))
return ico
def icon_admin(size: int = 32) -> QIcon:
return QIcon(_shield(size, "#6c3483", "#4a235a", "#9b59b6", dot=True))
def pixmap_app(size: int = 64) -> QPixmap:
return _shield(size, "#2980b9", "#1a5276", "#ffffff", dot=False)