From f3c9ced47768102a25da8a61ff8d6fc5572ad7f7 Mon Sep 17 00:00:00 2001 From: Thomas Hooge Date: Sun, 14 Sep 2025 17:19:45 +0200 Subject: [PATCH] Verbessertes Zeichnen mit mehreren Drawing-Areas --- appdata.py | 4 +++ led.py | 75 +++++++++++++++++++++++++++++----------------- obp60v.conf-sample | 2 +- obp60v.py | 27 ++++++++++------- pages/tracker.py | 4 +++ 5 files changed, 72 insertions(+), 40 deletions(-) diff --git a/appdata.py b/appdata.py index 404c207..2ab9bd2 100644 --- a/appdata.py +++ b/appdata.py @@ -8,3 +8,7 @@ class AppData(): def __init__(self): self.shutdown = False # Globaler Ausschalter self.track = Tracker('NONE') + self.frontend = None + + def setFrontend(self, frontend): + self.frontend = frontend # Referenz zur GUI diff --git a/led.py b/led.py index 14943e6..a469ef7 100644 --- a/led.py +++ b/led.py @@ -39,9 +39,11 @@ class LED(): self._brightness = 0.0 self._color_off = (0.3725, 0.4275, 0.6078) # RGB(95, 109, 155) self._pos_x = 30 - self._pos_y = 16 - self._radius = 4 + self._pos_y = 14 + self._radius = 5 self._flashcounter = 0 + self._flashcolor = (0, 0, 0) + self._enabled = False # Box oberhalb des Displays self._da = Gtk.DrawingArea() @@ -50,11 +52,17 @@ class LED(): self._da.connect("draw", self.on_draw) def on_draw(self, widget, ctx): - #Debug + # Debug um Zeichenbereich zu sehen + #ctx.set_line_width(1.0) #ctx.set_source_rgb(1, 0, 0) - #ctx.rectangle(0, 0, 400, 32) + #ctx.rectangle(0.5, 0.5, 400, 32) #ctx.stroke() - ctx.set_source_rgb(*self._color_off) + print("LED draw") + ctx.set_line_width(2.0) + if self._brightness == 0: + ctx.set_source_rgb(*self._color_off) + else: + ctx.set_source_rgb(*self._color) ctx.arc(self._pos_x, self._pos_y, self._radius, 0, 2*math.pi) ctx.fill_preserve() ctx.set_source_rgb(0, 0, 0) # Schwarzer Rand @@ -63,39 +71,46 @@ class LED(): ctx.stroke() def on_timer(self): + print("Timer") self.switchOff() - return True + return False + + def on_blink(self): + print("Blink-Timer") + return False def on_flash(self): - if self._flashcounter > 0: - self._flashcounter -=1 + # TODO do not wait for drawing event but draw immediately + print("Flash-Timer", self._brightness) + self._da.queue_draw() + if self._brightness == 1: + self._brightness = 0 + else: + self._brightness = 1 + if self._flashcounter > 0: + if self._brightness == 0: + self._flashcounter -=1 + print("Flash timer ongoing") return True + print("Flash finished") + self._brightness = 0 return False def switchOn(self, duration=None): self._brightness = 1.0 - self._ctx.save() - self._ctx.set_source_rgb(*self._color) - self._ctx.arc(self._pos_x, self._pos_y, self._radius, 0, 2*math.pi) - self._ctx.fill_preserve() - self._ctx.set_source_rgb((0, 0, 0)) # Schwarzer Rand - self._ctx.stroke() - self._ctx.restore() - if self._duration: - GLib.timeout_add_seconds(duration, self.on_flash) - + self._da.queue_draw() + if duration: + GLib.timeout_add_seconds(duration, self.on_timer) def switchOff(self): self._brightness = 0.0 - self._ctx.save() - self._ctx.set_source_rgb(*self._color_off) - self._ctx.arc(self._pos_x, self._pos_y, self._radius, 0, 2*math.pi) - self._ctx.fill_preserve() - self._ctx.set_source_rgb((0, 0, 0)) # Schwarzer Rand - self._ctx.stroke() - self._ctx.restore() + self._da.queue_draw() + + def doBlink(self, duration=None): + pass def doFlash(self, count=1): + self._cr = self._da.get_window().cairo_create() # Context for immediate drawing if (self._brightness > 0) or (count < 0): # Wenn aktiv oder falscher Parameter, dann passiert nichts return @@ -104,7 +119,9 @@ class LED(): self._flashcounter = 10 else: self._flashcounter = count - GLib.timeout_add_seconds(0.2, self.on_flash) + self._brightness = 1 + self._da.queue_draw() + GLib.timeout_add_seconds(0.5, self.on_flash) def setColor(self, colorname, brightness=1.0): #TODO Helligkeit einstellen @@ -118,8 +135,10 @@ class LED(): return self._color def getColorAsHex(self): - # TODO - return None + return '#{:02x}{:02x}{:02x}'.format( + int(self._color[0] * 255), + int(self._color[1] * 255), + int(self._color[2] * 255)) def setBrightness(self, newbrightness): # 0% bis 100%, ausgehend von der aktuellen Basisfarbe diff --git a/obp60v.conf-sample b/obp60v.conf-sample index e43205a..ac4df85 100644 --- a/obp60v.conf-sample +++ b/obp60v.conf-sample @@ -48,7 +48,7 @@ passcode = 123456 trace = false [boat] -name = MY boat +name = My boat sailno = GER 4711 class = One off handicap = 100.0 diff --git a/obp60v.py b/obp60v.py index 2f48b1a..f5e57e6 100755 --- a/obp60v.py +++ b/obp60v.py @@ -300,6 +300,7 @@ class Frontend(Gtk.Window): def __init__(self, cfg, appdata, device, boatdata, profile): super().__init__() self.appdata = appdata + self.appdata.setFrontend(self) self.owndev = device self.boatdata = boatdata self._config = cfg['_config'] @@ -364,14 +365,19 @@ class Frontend(Gtk.Window): self.add(self.fixed) # OBP GUI + # Geräterahmen mit Buttons + self.da_device = Gtk.DrawingArea() + self.fixed.put(self.da_device, 0, 0) + self.da_device.set_size_request(530, 555) # für fixed benötigt + self.da_device.add_events(Gdk.EventMask.BUTTON_PRESS_MASK|Gdk.EventMask.BUTTON_RELEASE_MASK) + self.da_device.connect("draw", self.da_device_draw) + self.da_device.connect('button-press-event', self.da_button_press) + self.da_device.connect('button-release-event', self.da_button_release) + # Displayfläche self.da = Gtk.DrawingArea() - self.da.add_events(Gdk.EventMask.BUTTON_PRESS_MASK|Gdk.EventMask.BUTTON_RELEASE_MASK) - self.fixed.put(self.da, 0, 0) - self.da.set_size_request(530, 555) # für fixed benötigt + self.fixed.put(self.da, 64, 95) + self.da.set_size_request(400, 300) # für fixed benötigt self.da.connect("draw", self.da_draw) - self.da.connect('button-press-event', self.da_button_press) - self.da.connect('button-release-event', self.da_button_release) - # Flash LED self.flashled = LED(self.fixed) # Soft Flash-LED @@ -399,7 +405,7 @@ class Frontend(Gtk.Window): # Tastaturstatus an Seite durchreichen self.curpage.keylock = self.keylock # Neuzeichnen - self.queue_draw() + self.da.queue_draw() return True def on_draw(self, widget, ctx): @@ -407,7 +413,7 @@ class Frontend(Gtk.Window): ctx.set_source_rgba(0, 0, 0, 0) ctx.paint() - def da_draw(self, widget, ctx): + def da_device_draw(self, widget, ctx): viewport = Rsvg.Rectangle() viewport.x = 0 viewport.y = 0 @@ -418,16 +424,15 @@ class Frontend(Gtk.Window): viewport.width = 530 viewport.height = 555 self._svg.render_document(ctx, viewport) + + def da_draw(self, widget, ctx): ctx.set_source_rgb(1.0, 0, 0) if not self._fullscreen: - ctx.translate(64, 95) # Koordinatenursprung auf virtuellen Displaybereich setzen ctx.rectangle(0, 0, 400, 300) ctx.clip() else: ctx.scale(1.6, 1.6) - ctx.set_source_rgb(0, 0, 0) # Schwarz auf Weiß - # Heartbeat umschalten if self.curpage.header: self.curpage.draw_header(ctx) diff --git a/pages/tracker.py b/pages/tracker.py index 96b5953..6e2159d 100644 --- a/pages/tracker.py +++ b/pages/tracker.py @@ -40,6 +40,10 @@ class Tracker(Page): else: self._appdata.track.set_active(True) self.buttonlabel[2] = 'OFF' + elif buttonid == 5: + self._appdata.frontend.flashled.setColor('yellow') + #self._appdata.frontend.flashled.switchOn(4) + self._appdata.frontend.flashled.doFlash(2) def draw_normal(self, ctx): # Name