diff --git a/py/hexagram/cluster.py b/py/hexagram/cluster.py index 969b028..ad4318e 100644 --- a/py/hexagram/cluster.py +++ b/py/hexagram/cluster.py @@ -123,6 +123,9 @@ class Cluster(): SHIFT_INDICATOR_X = 392 SHIFT_INDICATOR_Y = 24 + SECTION_HEIGHT_TOP = 64 + SECTION_HEIGHT_BOTTOM = 52 + def __init__(self, rpm_min: float, rpm_redline: float, rpm_max: float): self.gauges: List[Gauge] = list() @@ -154,8 +157,9 @@ class Cluster(): rpm_redline, rpm_max) - self.status = StatusIconBox(478, 280, - StatusIconBox.ICON_WIDTH * 6, + self.status = StatusIconBox(self.WIDTH/ 2 - StatusIconBox.ICON_WIDTH * 3.5, + self.HEIGHT - self.SECTION_HEIGHT_BOTTOM - 16 - StatusIconBox.ICON_HEIGHT * 3, + StatusIconBox.ICON_WIDTH * 7, StatusIconBox.ICON_HEIGHT * 3) self.gauges.append(self.speedo) @@ -180,22 +184,24 @@ class Cluster(): # Top dark area cr.set_source_rgba(0, 0, 0, 0.5) - cr.rectangle(0, 0, self.WIDTH, 64) + cr.rectangle(0, 0, self.WIDTH, self.SECTION_HEIGHT_TOP) cr.fill() cr.set_source_rgba(1, 1, 1, 0.25) - cr.move_to(0, 64) - cr.line_to(self.WIDTH, 64) + cr.move_to(0, self.SECTION_HEIGHT_TOP) + cr.line_to(self.WIDTH, self.SECTION_HEIGHT_TOP) cr.stroke() # Bottom dark area cr.set_source_rgba(0, 0, 0, 0.5) - cr.rectangle(0, self.HEIGHT - 52, self.WIDTH, 52) + cr.rectangle(0, self.HEIGHT - self.SECTION_HEIGHT_BOTTOM, + self.WIDTH, + self.SECTION_HEIGHT_BOTTOM) cr.fill() cr.set_source_rgba(1, 1, 1, 0.25) - cr.move_to(0, self.HEIGHT - 52) - cr.line_to(self.WIDTH, self.HEIGHT - 52) + cr.move_to(0, self.HEIGHT - self.SECTION_HEIGHT_BOTTOM) + cr.line_to(self.WIDTH, self.HEIGHT - self.SECTION_HEIGHT_BOTTOM) cr.stroke() for gauge in self.gauges: diff --git a/py/hexagram/icons.py b/py/hexagram/icons.py index d4d7920..bc6ea1f 100644 --- a/py/hexagram/icons.py +++ b/py/hexagram/icons.py @@ -24,17 +24,19 @@ class ISO7000Icon(): raise FileNotFoundError(name + '.svg') - def __init__(self, status: VehicleStatus, name: str, width: float, height: float, color: str): + def __init__(self, status: VehicleStatus, name: str, width: float, height: float, color: str, style: Optional[str]): self.status = status self.name = name self.width = width self.height = height self.color = color - style = 'rect,path,circle{stroke:%(s)s;fill:%(s)s}' % {'s': color} - path = ISO7000Icon._locate(name) + if style is None: + style = 'rect,path,circle{stroke:%(s)s;}' - self.surface = render_to_image(path, width, height, style) + path = ISO7000Icon._locate(name) + + self.surface = render_to_image(path, width, height, style % {'s': color}) def __del__(self): if self.surface is not None: @@ -49,39 +51,41 @@ class ISO7000(): __slots__ = 'icons', __icons__ = ( - (VehicleStatus.BATTERY_FAULT, 'beams-fog', '#f00'), - (VehicleStatus.BEAMS_FOG, 'beams-fog', '#0f0'), - (VehicleStatus.BEAMS_HIGH, 'beams-high', '#00f'), - (VehicleStatus.BEAMS_LOW, 'beams-low', '#0f0'), + (VehicleStatus.BATTERY_FAULT, 'battery', '#f00', '#rect5, #rect6 {fill: %(s)s} #rect4, path {stroke: %(s)s}'), + (VehicleStatus.BEAMS_FOG, 'beams-fog', '#0f0', '#g9 path {fill: %(s)s} #g5 path {stroke: %(s)s}'), + (VehicleStatus.BEAMS_HIGH, 'beams-high', '#00f', 'path {fill: %(s)s; stroke: %(s)s}'), + (VehicleStatus.BEAMS_LOW, 'beams-low', '#0f0', 'path {fill: %(s)s; stroke: %(s)s}'), (VehicleStatus.BEAMS_PARKING, 'beams-parking', '#ff0'), - (VehicleStatus.BELT, 'belt', '#f00'), + (VehicleStatus.BELT, 'belt', '#f00', 'path {fill: %(s)s}'), (VehicleStatus.COLD, 'cold', '#eef'), - (VehicleStatus.COLLISION, 'coolant', '#f00'), - (VehicleStatus.COOLANT_LOW, 'coolant', '#fa0'), - (VehicleStatus.COOLANT_OVERHEAT, 'coolant', '#f00'), - (VehicleStatus.CRUISE, 'cruise', '#0f0'), - (VehicleStatus.FUEL_LOW, 'fuel', '#fa0'), + (VehicleStatus.COLLISION, 'collision', '#f00', 'path {stroke: %(s)s}'), + (VehicleStatus.COOLANT_LOW, 'coolant', '#fa0', 'path, circle, rect {fill: %(s)s} #g9 path {stroke: %(s)s}'), + (VehicleStatus.COOLANT_OVERHEAT, 'coolant', '#f00', 'path, circle, rect {fill: %(s)s} #g9 path {stroke: %(s)s}'), + (VehicleStatus.CRUISE, 'cruise', '#0f0', 'path, circle {fill: %(s)s; stroke: %(s)s}'), + (VehicleStatus.FUEL_LOW, 'fuel', '#fa0', '#g9 * {stroke: %(s)s} #path9 {fill: %(s)s}'), (VehicleStatus.LANEKEEP_OFF, 'lane-departure', '#fa0'), - (VehicleStatus.OIL_LOW, 'oil', '#fa0'), - (VehicleStatus.OIL_OVERHEAT, 'oil', '#f00'), - (VehicleStatus.PARKING_BRAKE_ON, 'parking', '#fa0'), - (VehicleStatus.PARKING_BRAKE_FAULT, 'parking', '#f00'), - (VehicleStatus.STABILITY_OFF, 'stability', '#fa0'), - (VehicleStatus.TPMS_WARNING, 'tpms', '#fa0'), + (VehicleStatus.OIL_LOW, 'oil', '#fa0', 'path {fill: %(s)s; stroke: %(s)s}'), + (VehicleStatus.OIL_OVERHEAT, 'oil', '#f00', 'path {fill: %(s)s; stroke: %(s)s}'), + (VehicleStatus.PARKING_BRAKE_ON, 'parking', '#fa0', '#path6, #path5 {stroke: %(s)s} circle {stroke: %(s)s} #path7 {fill: %(s)s}'), + (VehicleStatus.PARKING_BRAKE_FAULT, 'parking', '#f00', '#path6, #path5 {stroke: %(s)s} circle {stroke: %(s)s} #path7 {fill: %(s)s}'), + (VehicleStatus.STABILITY_OFF, 'stability', '#fa0', '#path9, #path8, #path7, #path6, #path5 {fill: %(s)s} #path10 {stroke: %(s)s}'), + (VehicleStatus.TPMS_WARNING, 'tpms', '#fa0', 'path, circle {fill: %(s)s}'), (VehicleStatus.WIPER_WASHER_LOW, 'wiper-washer', '#fa0'), ) def __init__(self, width: float, height: float): - self.icons = dict() + self.icons = dict() for item in self.__icons__: - status, name, color = item + status, name, color = item[0:3] + style = 'rect,path,circle{stroke:%(s)s;}' if len(item) < 4 else item[3] self.icons[status.value] = ISO7000Icon(status, name, width, height, - color) + color, + style) class StatusIconBox(Gauge): __slots__ = 'x', 'y', 'width', 'height', 'iso7000', 'value',