63 lines
2.2 KiB
Python
63 lines
2.2 KiB
Python
import enum
|
|
import math
|
|
import cairo
|
|
|
|
from hexagram.dial import Dial
|
|
|
|
class ThermoGauge(Dial):
|
|
MIN_ANGLE = 144.0 * (math.pi / 180.0)
|
|
MAX_ANGLE = 216.0 * (math.pi / 180.0)
|
|
|
|
MIN_VALUE = 85
|
|
MAX_VALUE = 110
|
|
WARN_VALUE = 106
|
|
|
|
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)
|
|
|
|
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
|
|
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,
|
|
self.y + radius * self.radius * math.sin(angle) + y_offset)
|
|
|
|
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.select_font_face(self.FONT_FACE,
|
|
cairo.FontSlant.NORMAL,
|
|
cairo.FontWeight.BOLD)
|
|
|
|
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)
|
|
|
|
cr.set_source_rgb(1, 0, 0)
|
|
self.draw_value(cr, 0.75, self.MAX_VALUE - self.MIN_VALUE, "H", -5, 5)
|
|
|
|
cr.set_line_width(6.0)
|
|
|
|
for level in range(0, self.MAX_VALUE - self.MIN_VALUE, math.ceil((self.MAX_VALUE - self.MIN_VALUE) / 9)):
|
|
if level + self.MIN_VALUE >= self.WARN_VALUE:
|
|
cr.set_source_rgb(0.8, 0, 0)
|
|
else:
|
|
cr.set_source_rgb(1, 1, 1)
|
|
|
|
self.draw_mark(cr, 0.83, 0.87, self.max_value - level)
|