From 61498c91a639bf3f975a5e29ca4d799c89301c81 Mon Sep 17 00:00:00 2001 From: XANTRONIX Development Date: Tue, 2 Jan 2024 14:46:36 -0500 Subject: [PATCH] Implement proper text gauge alignment --- py/hexagram/cluster.py | 89 ++++++++++-------------------------------- py/hexagram/gauge.py | 45 +++++++++++++++++++++ 2 files changed, 66 insertions(+), 68 deletions(-) diff --git a/py/hexagram/cluster.py b/py/hexagram/cluster.py index 13a033d..b2bc895 100644 --- a/py/hexagram/cluster.py +++ b/py/hexagram/cluster.py @@ -3,8 +3,9 @@ import cairo from typing import Iterable, List +from hexagram.box import Align from hexagram.pattern import HexagonPattern -from hexagram.gauge import Gauge +from hexagram.gauge import Gauge, TextGauge from hexagram.dial import Dial from hexagram.speedo import Speedo from hexagram.tacho import Tacho @@ -78,77 +79,29 @@ class ShiftIndicator(Gauge): for l in range(0, len(self.LIGHT_LEVELS)): self.draw_level(cr, level, l >= level) -class Odometer(Gauge): - __slots__ = 'x', 'y', +class Odometer(TextGauge): + def __init__(self, x: float, y: float, align: Align): + super().__init__(x, y, 0, 999999999, align) - def __init__(self, x: float, y: float): - super().__init__(0, 999999999) + def format_text(self): + return "%d mi" % self.value - self.x = x - self.y = y +class AmbientTemp(TextGauge): + def __init__(self, x: float, y: float, align: Align): + super().__init__(x, y, -100, 100, align) - def draw_bg(self, cr: cairo.Context): - pass + def format_text(self): + return "%.1f°C" % self.value - def draw_fg(self, cr: cairo.Context): - cr.set_source_rgb(1, 1, 1) - cr.select_font_face("Muli", - cairo.FontSlant.NORMAL, - cairo.FontWeight.BOLD) +class Clock(TextGauge): + def __init__(self, x: float, y: float, align: Align): + super().__init__(x, y, 0, 9999, align) - cr.set_font_size(24) - - cr.move_to(self.x, self.y) - cr.show_text("%d mi" % self.value) - -class AmbientTemp(Gauge): - __slots__ = 'x', 'y', - - def __init__(self, x: float, y: float): - super().__init__(-100, 100) - - self.x = x - self.y = y - - def draw_bg(self, cr: cairo.Context): - pass - - def draw_fg(self, cr: cairo.Context): - cr.set_source_rgb(1, 1, 1) - cr.select_font_face("Muli", - cairo.FontSlant.NORMAL, - cairo.FontWeight.BOLD) - - cr.set_font_size(24) - - cr.move_to(self.x, self.y) - cr.show_text("%.1f°C" % self.value) - -class Clock(Gauge): - __slots__ = 'x', 'y', - - def __init__(self, x: float, y: float): - super().__init__(0, 9999) - - self.x = x - self.y = y - - def draw_bg(self, cr: cairo.Context): - pass - - def draw_fg(self, cr: cairo.Context): - cr.set_source_rgb(1, 1, 1) - cr.select_font_face("Muli", - cairo.FontSlant.NORMAL, - cairo.FontWeight.BOLD) - - cr.set_font_size(24) - - cr.move_to(self.x, self.y) - cr.show_text("%d:%02d" % ( + def format_text(self): + return "%d:%02d" % ( (self.value - (self.value % 60)) / 60, self.value % 60 - )) + ) class Cluster(): __slots__ = 'gauges', 'speedo', 'fuel', 'tacho', 'thermo', 'odo', \ @@ -181,9 +134,9 @@ class Cluster(): self.HEIGHT / 2, self.HEIGHT / 2) - self.odo = Odometer(0.8 * self.HEIGHT, self.HEIGHT - 16) - self.ambient = AmbientTemp(self.WIDTH - self.HEIGHT, self.HEIGHT - 16) - self.clock = Clock(self.WIDTH / 2 - 32, self.HEIGHT - 16) + self.odo = Odometer(0.8 * self.HEIGHT, self.HEIGHT - 16, Align.LEFT) + self.clock = Clock(self.WIDTH / 2, self.HEIGHT - 16, Align.MIDDLE) + self.ambient = AmbientTemp(self.WIDTH - 0.8 * self.HEIGHT, self.HEIGHT - 16, Align.RIGHT) self.gauges.append(self.speedo) self.gauges.append(self.fuel) diff --git a/py/hexagram/gauge.py b/py/hexagram/gauge.py index 04fe172..150e3b1 100644 --- a/py/hexagram/gauge.py +++ b/py/hexagram/gauge.py @@ -1,5 +1,7 @@ import cairo +from hexagram.box import Align + class Gauge(): __slots__ = 'min_value', 'max_value', 'value', @@ -17,3 +19,46 @@ class Gauge(): def draw_fg(self, cr: cairo.Context): raise NotImplementedError +class TextGauge(Gauge): + __slots__ = 'x', 'y', 'align', + + FONT_FACE = "Muli" + FONT_SLANT = cairo.FontSlant.NORMAL + FONT_WEIGHT = cairo.FontWeight.BOLD + FONT_SIZE = 24 + + def __init__(self, x: float, y: float, min_value: float, max_value: float, align: Align=Align.LEFT): + super().__init__(min_value, max_value) + + self.x = x + self.y = y + self.align = align + + def format_text(self) -> str: + raise NotImplementedError + + def draw_bg(self, cr: cairo.Context): + pass + + def draw_fg(self, cr: cairo.Context): + cr.set_source_rgb(1, 1, 1) + + cr.select_font_face(self.FONT_FACE, + self.FONT_SLANT, + self.FONT_WEIGHT) + + text = self.format_text() + + cr.set_font_size(self.FONT_SIZE) + + extents = cr.text_extents(text) + width = extents[2] - extents[0] + + if self.align is Align.LEFT: + cr.move_to(self.x, self.y) + elif self.align is Align.MIDDLE: + cr.move_to(self.x - width / 2, self.y) + elif self.align is Align.RIGHT: + cr.move_to(self.x - width, self.y) + + cr.show_text(text)