diff --git a/py/hexagram/status.py b/py/hexagram/status.py index a4cbb1a..db4e4ab 100644 --- a/py/hexagram/status.py +++ b/py/hexagram/status.py @@ -99,7 +99,7 @@ class StatusIcon(): cr.fill() class StatusIconBox(Gauge): - __slots__ = 'x', 'y', 'width', 'height', 'icons', 'value', + __slots__ = 'x', 'y', 'width', 'height', 'value', 'surface', 'icons', '_redraw' __icons__ = ( (VehicleStatus.BATTERY_FAULT, 'battery', '#f00', '#rect5, #rect6 {fill: %(s)s} #rect4, path {stroke: %(s)s}'), @@ -128,11 +128,14 @@ class StatusIconBox(Gauge): ICON_HEIGHT = 48 def __init__(self, x: float, y: float, width: float, height: float): - self.x = x - self.y = y - self.width = width - self.height = height - self.value = VehicleStatus.OK.value + self.x = x + self.y = y + self.width = width + self.height = height + self.value = VehicleStatus.OK.value + self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,int(width), int(height)) + self._redraw = False + self.icons: dict[int, StatusIcon] = dict() for item in self.__icons__: @@ -144,19 +147,19 @@ class StatusIconBox(Gauge): self.ICON_HEIGHT, color, style) - def reset(self): - self.value = VehicleStatus.OK.value - - def set_status(self, status: VehicleStatus): - self.value |= status.value - - def clear_status(self, status: VehicleStatus): - self.value &= ~status.value + def __del__(self): + self.surface.finish() def draw_bg(self, cr: cairo.Context): pass - def draw_fg(self, cr: cairo.Context): + def _update_surface(self): + cr = cairo.Context(self.surface) + cr.set_source_rgba(0, 0, 0, 0) + cr.set_operator(cairo.OPERATOR_SOURCE) + cr.rectangle(0, 0, self.width, self.height) + cr.fill() + x, y = 0, self.height - self.ICON_HEIGHT for status_value in self.icons: @@ -164,10 +167,31 @@ class StatusIconBox(Gauge): if self.value & status_value: if icon is not None: - icon.draw(cr, self.x + x, self.y + y) + icon.draw(cr, x, y) x += self.ICON_WIDTH if x >= self.width: x = 0 y -= self.ICON_HEIGHT + + def draw_fg(self, cr: cairo.Context): + if self._redraw: + self._update_surface() + self._redraw = False + + cr.set_source_surface(self.surface, self.x, self.y) + cr.rectangle(self.x, self.y, self.width, self.height) + cr.fill() + + def reset(self): + self.value = VehicleStatus.OK.value + self._redraw = True + + def set_status(self, status: VehicleStatus): + self.value |= status.value + self._redraw = True + + def clear_status(self, status: VehicleStatus): + self.value &= ~status.value + self._redraw = True