Simplify code around drawing bottom gauges

This commit is contained in:
XANTRONIX Development 2024-01-02 13:36:16 -05:00
parent 1c40300ca7
commit fce90134c7
7 changed files with 68 additions and 51 deletions

View file

@ -82,9 +82,10 @@ class Odometer(Gauge):
__slots__ = 'x', 'y',
def __init__(self, x: float, y: float):
self.value = 0
self.x = x
self.y = y
super().__init__(0, 999999999)
self.x = x
self.y = y
def draw_bg(self, cr: cairo.Context):
pass
@ -104,9 +105,10 @@ class AmbientTemp(Gauge):
__slots__ = 'x', 'y',
def __init__(self, x: float, y: float):
self.value = 0
self.x = x
self.y = y
super().__init__(-100, 100)
self.x = x
self.y = y
def draw_bg(self, cr: cairo.Context):
pass
@ -126,9 +128,10 @@ class Clock(Gauge):
__slots__ = 'x', 'y',
def __init__(self, x: float, y: float):
self.value = 0
self.x = x
self.y = y
super().__init__(0, 9999)
self.x = x
self.y = y
def draw_bg(self, cr: cairo.Context):
pass

View file

@ -4,7 +4,7 @@ import cairo
from hexagram.gauge import Gauge
class Dial(Gauge):
__slots = 'x', 'y', 'radius', 'min_angle', 'max_angle', 'max_value',
__slots = 'x', 'y', 'radius', 'min_angle', 'max_angle',
ANGLE_OFFSET = math.pi / 2
@ -14,15 +14,14 @@ class Dial(Gauge):
(1, 0.4, 0.0, 0.4, 0.0)
)
def __init__(self, x: float, y: float, radius: float, min_angle: float, max_angle: float, max_value: float):
super().__init__()
def __init__(self, x: float, y: float, radius: float, min_angle: float, max_angle: float, min_value: float, max_value: float):
super().__init__(min_value, max_value)
self.x = x
self.y = y
self.radius = radius
self.min_angle = min_angle
self.max_angle = max_angle
self.max_value = max_value
def _gradient(self):
gradient = cairo.LinearGradient(self.x - self.radius,
@ -46,8 +45,11 @@ class Dial(Gauge):
cr.stroke()
def draw_mark(self, cr: cairo.Context, min_radius: float, max_radius: float, value: float):
adj = value - self.min_value
adj_max = self.max_value - self.min_value
angle = self.min_angle + \
((self.max_angle - self.min_angle) * (value / self.max_value)) - self.ANGLE_OFFSET
((self.max_angle - self.min_angle) * (adj / adj_max)) - self.ANGLE_OFFSET
cr.move_to(self.x + (min_radius * self.radius) * math.cos(angle),
self.y + (min_radius * self.radius) * math.sin(angle))
@ -58,8 +60,11 @@ class Dial(Gauge):
cr.stroke()
def draw_needle(self, cr: cairo.Context, min_radius: float, max_radius: float, value: float):
adj = value - self.min_value
adj_max = self.max_value - self.min_value
angle = self.min_angle + \
((self.max_angle - self.min_angle) * (value / self.max_value)) \
((self.max_angle - self.min_angle) * (adj / adj_max)) \
- self.ANGLE_OFFSET
cr.set_source_rgba(1, 0.4, 1, 0.75)
@ -101,8 +106,26 @@ class Dial(Gauge):
self.draw_needle(cr, 0.5, 0.89, self.value)
class BottomDial(Dial):
def draw_mark(self, cr: cairo.Context, min_radius: float, max_radius: float, value: float):
adj = value - self.min_value
adj_max = self.max_value - self.min_value
angle = self.min_angle + \
((self.max_angle - self.min_angle) * (adj / adj_max)) - self.ANGLE_OFFSET
cr.move_to(self.x + (min_radius * self.radius) * math.cos(angle),
self.y + (min_radius * self.radius) * math.sin(angle))
cr.line_to(self.x + (max_radius * self.radius) * math.cos(angle),
self.y + (max_radius * self.radius) * math.sin(angle))
cr.stroke()
def draw_fg(self, cr: cairo.Context):
min_radius = 0.8
max_radius = 0.9
self.draw_needle(cr, min_radius, max_radius, self.MAX_VALUE - self.value)
adj = self.value - self.min_value
adj_max = self.max_value - self.min_value
self.draw_needle(cr, min_radius, max_radius, adj_max - adj)

View file

@ -8,12 +8,17 @@ class FuelGauge(BottomDial):
MIN_ANGLE = 144.0 * (math.pi / 180.0)
MAX_ANGLE = 216.0 * (math.pi / 180.0)
MIN_VALUE = 0
MAX_VALUE = 15
FONT_FACE = "Muli"
def __init__(self, x: float, y: float, radius: float):
super().__init__(x, y, radius, self.MIN_ANGLE, self.MAX_ANGLE, self.MAX_VALUE)
super().__init__(x, y, radius,
self.MIN_ANGLE,
self.MAX_ANGLE,
self.MIN_VALUE,
self.MAX_VALUE)
self.value = 0
@ -27,18 +32,6 @@ class FuelGauge(BottomDial):
cr.show_text(text)
cr.stroke()
def draw_mark(self, cr: cairo.Context, min_radius: float, max_radius: float, value: float):
angle = self.min_angle + \
((self.max_angle - self.min_angle) * (value / self.max_value)) - self.ANGLE_OFFSET
cr.move_to(self.x + (min_radius * self.radius) * math.cos(angle),
self.y + (min_radius * self.radius) * math.sin(angle))
cr.line_to(self.x + (max_radius * self.radius) * math.cos(angle),
self.y + (max_radius * self.radius) * math.sin(angle))
cr.stroke()
def draw_bg(self, cr: cairo.Context):
cr.set_line_width(24)
cr.set_source_rgb(0.2, 0.2, 0.2)

View file

@ -1,10 +1,12 @@
import cairo
class Gauge():
__slots__ = 'value',
__slots__ = 'min_value', 'max_value', 'value',
def __init__(self):
self.value = None
def __init__(self, min_value: float, max_value: float):
self.min_value: float = min_value
self.max_value: float = max_value
self.value: float = min_value
def set_value(self, value):
self.value = value

View file

@ -17,7 +17,7 @@ class Speedo(Dial):
FONT_FACE = "Muli"
def __init__(self, x: float, y: float, radius: float, max_value: float, units: SpeedUnits=SpeedUnits.KPH):
super().__init__(x, y, radius, self.MIN_ANGLE, self.MAX_ANGLE, max_value)
super().__init__(x, y, radius, self.MIN_ANGLE, self.MAX_ANGLE, 0, max_value)
self.value = 0
self.units = units

View file

@ -37,7 +37,7 @@ class Tacho(Dial):
FONT_FACE = "Muli"
def __init__(self, x: float, y: float, radius: float, max_value: float):
super().__init__(x, y, radius, self.MIN_ANGLE, self.MAX_ANGLE, max_value)
super().__init__(x, y, radius, self.MIN_ANGLE, self.MAX_ANGLE, 0, max_value)
self.value = 0
self.gear: Gear = Gear.N

View file

@ -15,12 +15,20 @@ class ThermoGauge(BottomDial):
FONT_FACE = "Muli"
def __init__(self, x: float, y: float, radius: float):
super().__init__(x, y, radius, self.MIN_ANGLE, self.MAX_ANGLE, self.MAX_VALUE - self.MIN_VALUE)
super().__init__(x, y, radius,
self.MIN_ANGLE,
self.MAX_ANGLE,
self.MIN_VALUE,
self.MAX_VALUE)
self.value = self.MIN_VALUE
def draw_needle(self, cr: cairo.Context, min_radius: float, max_radius: float, value: float):
super().draw_needle(cr, min_radius, max_radius, self.max_value - value)
def draw_value(self, cr: cairo.Context, radius: float, value: float, text: str, x_offset: float, y_offset: float):
scale = (self.max_value - value) / self.max_value
adj = value - self.min_value
adj_max = self.max_value - self.min_value
scale = adj / adj_max
angle = self.min_angle + ((self.max_angle - self.min_angle) * scale) - self.ANGLE_OFFSET
cr.move_to(self.x + radius * self.radius * math.cos(angle) + x_offset,
@ -29,18 +37,6 @@ class ThermoGauge(BottomDial):
cr.show_text(text)
cr.stroke()
def draw_mark(self, cr: cairo.Context, min_radius: float, max_radius: float, value: float):
angle = self.min_angle + \
((self.max_angle - self.min_angle) * (value / self.max_value)) - self.ANGLE_OFFSET
cr.move_to(self.x + (min_radius * self.radius) * math.cos(angle),
self.y + (min_radius * self.radius) * math.sin(angle))
cr.line_to(self.x + (max_radius * self.radius) * math.cos(angle),
self.y + (max_radius * self.radius) * math.sin(angle))
cr.stroke()
def draw_bg(self, cr: cairo.Context):
cr.set_line_width(24)
cr.set_source_rgb(0.2, 0.2, 0.2)
@ -58,10 +54,10 @@ class ThermoGauge(BottomDial):
cr.set_font_size(self.radius * 0.1)
cr.set_source_rgb(1, 1, 1)
self.draw_value(cr, 0.78, 0, "C", 0, 5)
self.draw_value(cr, 0.78, self.min_value, "C", 0, 5)
cr.set_source_rgb(1, 0, 0)
self.draw_value(cr, 0.75, self.MAX_VALUE - self.MIN_VALUE, "H", -25, 15)
self.draw_value(cr, 0.75, self.max_value, "H", -25, 15)
cr.set_line_width(6.0)