hexagram/py/hexagram/icon.py
2024-01-06 18:52:52 -05:00

64 lines
1.8 KiB
Python

import os
import enum
import cairo
from hexagram.svg import render_to_image
class Icon():
__slots__ = 'name', 'width', 'height', 'style', 'variants', \
'_path', '_surfaces',
__dirs__ = ('./icons',
'/usr/local/share/hexagram/icons'
'/usr/share/hexagram/icons')
@staticmethod
def _locate(name: str):
for dir in Icon.__dirs__:
path = "%s/%s.svg" % (dir, name)
if os.path.exists(path):
return path
raise FileNotFoundError(name + '.svg')
STYLE = 'rect,path,circle{stroke:%(s)s;}'
def __init__(self, name: str, width: float, height: float, variants: dict, style: str=STYLE):
self.name = name
self.width = width
self.height = height
self.style = style
self.variants = variants
self._path = Icon._locate(name)
self._surfaces: dict[enum.Enum, cairo.ImageSurface] = dict()
def __del__(self):
for key in self._surfaces:
self._surfaces[key].finish()
def _surface(self, status) -> cairo.ImageSurface:
surface = self._surfaces.get(status)
if surface is not None:
return surface
color = self.variants[status]
surface = render_to_image(self._path,
self.width,
self.height,
self.style % {'s': color})
self._surfaces[status] = surface
return surface
def drawable(self, status: enum.Enum):
return status in self.variants
def draw(self, cr: cairo.Context, x: float, y: float, status):
surface = self._surface(status)
cr.set_source_surface(surface, x, y)
cr.rectangle(x, y, self.width, self.height)
cr.fill()