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 typing import Iterable, List
from hexagram.box import Align
from hexagram.pattern import HexagonPattern from hexagram.pattern import HexagonPattern
from hexagram.gauge import Gauge from hexagram.gauge import Gauge, TextGauge
from hexagram.dial import Dial from hexagram.dial import Dial
from hexagram.speedo import Speedo from hexagram.speedo import Speedo
from hexagram.tacho import Tacho from hexagram.tacho import Tacho
@ -78,77 +79,29 @@ class ShiftIndicator(Gauge):
for l in range(0, len(self.LIGHT_LEVELS)): for l in range(0, len(self.LIGHT_LEVELS)):
self.draw_level(cr, level, l >= level) self.draw_level(cr, level, l >= level)
class Odometer(Gauge): class Odometer(TextGauge):
__slots__ = 'x', 'y', def __init__(self, x: float, y: float, align: Align):
super().__init__(x, y, 0, 999999999, align)
def __init__(self, x: float, y: float): def format_text(self):
super().__init__(0, 999999999) return "%d mi" % self.value
self.x = x class AmbientTemp(TextGauge):
self.y = y def __init__(self, x: float, y: float, align: Align):
super().__init__(x, y, -100, 100, align)
def draw_bg(self, cr: cairo.Context): def format_text(self):
pass return "%.1f°C" % self.value
def draw_fg(self, cr: cairo.Context): class Clock(TextGauge):
cr.set_source_rgb(1, 1, 1) def __init__(self, x: float, y: float, align: Align):
cr.select_font_face("Muli", super().__init__(x, y, 0, 9999, align)
cairo.FontSlant.NORMAL,
cairo.FontWeight.BOLD)
cr.set_font_size(24) def format_text(self):
return "%d:%02d" % (
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" % (
(self.value - (self.value % 60)) / 60, (self.value - (self.value % 60)) / 60,
self.value % 60 self.value % 60
)) )
class Cluster(): class Cluster():
__slots__ = 'gauges', 'speedo', 'fuel', 'tacho', 'thermo', 'odo', \ __slots__ = 'gauges', 'speedo', 'fuel', 'tacho', 'thermo', 'odo', \
@ -181,9 +134,9 @@ class Cluster():
self.HEIGHT / 2, self.HEIGHT / 2,
self.HEIGHT / 2) self.HEIGHT / 2)
self.odo = Odometer(0.8 * self.HEIGHT, self.HEIGHT - 16) self.odo = Odometer(0.8 * self.HEIGHT, self.HEIGHT - 16, Align.LEFT)
self.ambient = AmbientTemp(self.WIDTH - self.HEIGHT, self.HEIGHT - 16) self.clock = Clock(self.WIDTH / 2, self.HEIGHT - 16, Align.MIDDLE)
self.clock = Clock(self.WIDTH / 2 - 32, self.HEIGHT - 16) self.ambient = AmbientTemp(self.WIDTH - 0.8 * self.HEIGHT, self.HEIGHT - 16, Align.RIGHT)
self.gauges.append(self.speedo) self.gauges.append(self.speedo)
self.gauges.append(self.fuel) self.gauges.append(self.fuel)

View file

@ -1,5 +1,7 @@
import cairo import cairo
from hexagram.box import Align
class Gauge(): class Gauge():
__slots__ = 'min_value', 'max_value', 'value', __slots__ = 'min_value', 'max_value', 'value',
@ -17,3 +19,46 @@ class Gauge():
def draw_fg(self, cr: cairo.Context): def draw_fg(self, cr: cairo.Context):
raise NotImplementedError 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)