Implement proper text gauge alignment

This commit is contained in:
XANTRONIX Development 2024-01-02 14:46:36 -05:00
parent 1eb4724040
commit 61498c91a6
2 changed files with 66 additions and 68 deletions

View file

@ -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)

View file

@ -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)