Code-Generierung
Lopaka erzeugt aus deinem visuellen Design in Echtzeit plattformspezifischen Quellcode. Diese Seite erklärt, wie dieser Code entsteht, wie du ihn in dein Projekt bringst und wie es in die andere Richtung geht – bestehenden Code in Lopaka importieren, um daraus Ebenen zu rekonstruieren.
Generierung
So entsteht die Ausgabe
Der Code-Bereich zeigt den Screen, der in seinen Code-Tabs ausgewählt ist. Jedes Mal, wenn sich dieser Screen ändert, erzeugt Lopaka seinen Codeblock neu. Die Ausgabe hängt von vier Dingen ab:
- Plattform – jede Plattform hat ihre eigene Code-Vorlage und Syntax.
- Ebenen – nur sichtbare Ebenen ohne Overlay erscheinen in der Ausgabe, in ihrer Stapelreihenfolge.
- Screen-Titel – wird zum Namen der Wrapper-Funktion (siehe unten).
- Code-Einstellungen – Schalter, die festlegen, welche Abschnitte enthalten sind.
Screen-Titel und Wrapper-Funktion
Der Screen-Titel (bearbeitbar per Doppelklick auf den Titel über dem Screen) wird zum Namen der generierten Wrapper-Funktion. Lopaka wandelt ihn automatisch in einen gültigen C++-Bezeichner um:
| Screen-Titel | Generierte Funktion |
|---|---|
Main Screen | void drawMain_Screen(void) |
gauge display | void drawgauge_display(void) |
123 Alert | void draw_123_Alert(void) |
Status/Bar | void drawStatus_Bar(void) |
Regeln: Leerzeichen und Sonderzeichen werden zu Unterstrichen; Namen, die mit einer Ziffer beginnen, erhalten einen führenden Unterstrich; reservierte C++-Wörter erhalten einen angehängten Unterstrich.
Wenn du Wrapper-Funktion in den Code-Einstellungen ausschaltest, werden die reinen Zeichenaufrufe ohne umschließende Funktion ausgegeben. Das ist praktisch, wenn du den Code direkt in einen bestehenden Callback einfügst.
Ebenennamen und Variablennamen
Ebenennamen erscheinen an zwei Stellen in der Ausgabe:
- Kommentare – wenn Kommentare, Ebenentitel aktiviert ist, steht vor jedem Zeichenaufruf
// layer name. - Variablennamen – wenn Variablen deklarieren aktiviert ist, heißen Eigenschaftsvariablen
{layerName}_{property}(z. B.label_x,label_color).
Benenne deine Ebenen eindeutig, bevor du Variablen aktivierst – die Namen landen direkt in den Code-Bezeichnern.
Ausgeblendete Ebenen
Ebenen, die du im Ebenen-Bereich mit dem Augensymbol ausblendest, werden komplett von der Code-Generierung ausgeschlossen. So kannst du unfertige Formen oder Referenzebenen im Projekt behalten, ohne dass sie in der Ausgabe landen.
Code-Einstellungen
Der Bereich Code-Einstellungen (unten rechts im Editor) legt fest, welche Abschnitte ausgegeben werden. Nicht alle Einstellungen sind auf jeder Plattform verfügbar.
| Einstellung | Wirkung |
|---|---|
| Wrapper-Funktion | Umschließt alle Zeichenaufrufe mit void draw{ScreenTitle}(void) { ... } |
| Kommentare, Ebenentitel | Gibt vor jedem Zeichenaufruf einen Kommentar // layer name aus |
| Schriftarten einbinden | Fügt Schriftart-Deklarationen oder #include-Direktiven für die im Design verwendeten Schriftarten hinzu |
| Bilder deklarieren | Fügt Bild-Array-Deklarationen für Bitmap- und Icon-Ebenen hinzu |
| Bilddateien einbinden | Hält die Bildpixel aus dem generierten Quellcode heraus und referenziert stattdessen die heruntergeladenen Asset-Dateien |
| Variablen deklarieren | Zieht markierte Ebeneneigenschaften in typisierte Variablendeklarationen heraus (siehe unten) |
| Display leeren/füllen | Fügt am Anfang der Funktion einen Aufruf zum Leeren des Displays hinzu |
| Animations-Hilfsfunktionen | Fügt Wiedergabe-Hilfsfunktionen und externe Frame-Daten für Animationsebenen hinzu |
| Als PROGMEM deklarieren | Kennzeichnet Bild- und Schriftart-Arrays mit der Arduino-Speicherklasse PROGMEM |
Die Einstellungen werden pro Plattform in deinem Browser gespeichert, sodass Projekte auf verschiedenen Plattformen ihre eigene Konfiguration behalten.
Die animationsspezifische Ausgabe, einschließlich Wiedergabe-Hilfsfunktionen und herunterladbarer Frame-Daten, beschreibt Animationen.
Polygon-Hilfsfunktionen
Polygon-Ebenen werden über generierte Hilfsfunktionen ausgegeben. Der Name der Hilfsfunktion wird aus dem Ebenennamen abgeleitet und in einen gültigen Code-Bezeichner umgewandelt; der Hauptzeichenablauf ruft dann diese Hilfsfunktion auf.
Text-Vordergrund und -Hintergrund
Einige Farbplattformen erlauben für Textebenen eine Hintergrundfarbe, die in den generierten Code zum Zeichnen des Texts übernommen wird.
Variablen
Mit Variablen ersetzt du fest eingetragene Ebeneneigenschaften durch benannte Bezeichner, die du zur Laufzeit ändern kannst, ohne die Zeichenlogik anzufassen.
So markierst du eine Eigenschaft als Variable:
- Wähle eine Ebene aus.
- Klicke im Inspektor auf den Variablenschalter (das Sechseck-Icon) neben einer unterstützten Eigenschaft wie
x,y,textodercolor. - Aktiviere Variablen deklarieren in den Code-Einstellungen.
Der Wert der Eigenschaft wird als typisierte Deklaration an den Anfang des generierten Codes gezogen:
// Declared at the top when "Declare variables" is on
int label_x = 10;
int label_y = 20;
const char* label_text = "Hello";
// Draw call references the variables
display.setCursor(label_x, label_y);
display.print(label_text);Variablennamen werden aus dem Ebenennamen und dem Eigenschaftsnamen abgeleitet. Wenn du die Ebene umbenennst, ändern sich alle ihre Variablennamen – erledige das, bevor du den Code teilst oder committest.
Nicht jede Eigenschaft unterstützt Variablen. Position, Größe, Farbe und Textinhalt tun es auf den meisten Plattformen. Eigenschaften wie die Schriftgröße sind fest und lassen sich nicht als Variablen markieren.
Export
Aus dem Code-Bereich kopieren
Wähle den Code-Tab des Screens und klicke auf Kopieren, um die gesamte Ausgabe zu kopieren – einschließlich deines eigenen Codes vor und nach dem generierten Abschnitt. Nur der generierte Abschnitt ist schreibgeschützt; die Abschnitte drumherum kannst du bearbeiten. Siehe Bearbeitbare Code-Vorlage. Du kannst den Text auch manuell mit Ctrl A und Ctrl C markieren und kopieren.
Als Datei herunterladen
Du kannst den Inhalt des geöffneten Code-Tabs als .txt-Datei herunterladen, einschließlich deines eigenen Codes vor und nach dem generierten Abschnitt.
So geht's: Öffne in der oberen Leiste das Menü Teilen und wähle Speichern unter → Textdatei.
Schriftarten und Bilder herunterladen
Wenn dein Design eigene Schriftarten oder Bildebenen verwendet, kann Lopaka diese Assets separat exportieren, damit du sie zusammen mit dem generierten Code in dein Projekt aufnehmen kannst.
In den Code-Einstellungen listet der Abschnitt Schriftarten alle Schriftartdateien auf, auf die das Design verweist. Der Abschnitt Bilder enthält einen Eintrag pro eindeutigem Bild im Design. Klicke auf das Download-Icon neben einem Eintrag, um das Asset zu speichern.
- Schriftartdateien werden in dem Format heruntergeladen, das die aktive Plattform verlangt (
.hfür GFX-basierte Plattformen und U8g2). - Unter U8g2 beschränkt Nur verwendete Glyphen rendern jede heruntergeladene Schriftart auf die Zeichen, die von Text- und Textbereich-Ebenen mit dieser Schriftart verwendet werden. Lass die Option deaktiviert, um alle BDF-Glyphen zu exportieren. Schriftarten, die von zur Laufzeit variablem Text verwendet werden, werden immer vollständig exportiert.
- Bilddateien werden in dem Format heruntergeladen, das die aktive Plattform kompiliert, und nach dem Symbol benannt, das der generierte Code verwendet. Bilder mit identischen Pixeln erscheinen nur einmal und werden aus diesem einen Asset gezeichnet.
| Plattform | Bild-Asset-Datei |
|---|---|
| Adafruit GFX (Farbe und Mono), Arduino GFX, TFT_eSPI, GxEPD2, Inkplate | C-Header mit XBM-Bytes oder RGB565-Pixeln – image_<Name>_bits.h oder image_<Name>_pixels.h |
| U8g2 (Arduino und ESP-IDF) | C-Header – image_<Name>_bits.h |
| Flipper Zero | Eigenständiger C-Header mit uint8_t-Arrays und ohne Arduino-Header – image_<Name>_bits.h |
| LVGL (v9) | C-Quelldatei mit dem Deskriptor image_<Name>_dsc und seiner Pixelmap – <Name>.c |
| CircuitPython | Bitmap, geladen über displayio.OnDiskBitmap – image_<Name>_bits.bmp |
| MicroPython | Portable Bitmap – image_<Name>_bits.pbm |
| ESPHome | PNG, auf das das generierte YAML als images/<Name>.png verweist |
Mit aktiviertem Bilddateien einbinden (und eingeschaltetem Bilder deklarieren) verweist der generierte Quellcode auf diese Dateien, statt die Pixel selbst zu enthalten: In C- und C++-Ausgaben werden die Inline-Arrays durch #include "<symbol>.h" ersetzt, und MicroPython lädt die .pbm-Datei beim Start. Die Asset-Bytes entsprechen genau dem Inhalt der Inline-Arrays, daher zeichnen beide Arbeitsweisen dasselbe Ergebnis. Ist Bilder deklarieren ausgeschaltet, referenziert der Quellcode nur die Bildsymbole und enthält keine Pixeldaten; die Downloads bleiben verfügbar.
Achtung
Lade Schriftart- und Bild-Assets immer herunter und lege sie vor dem Flashen neben deine .ino- oder YAML-Datei. Bei U8g2 legst du die heruntergeladenen .h-Dateien neben den generierten Screen-Code. Bei ESPHome legst du die PNG-Dateien in den Ordner images/, auf den das YAML verweist.
Import
Lopaka kann vorhandenen Plattform-Quellcode parsen und daraus Ebenen rekonstruieren. Das ist praktisch, um dort weiterzumachen, wo ein früherer Export aufgehört hat, oder um einen bestehenden Sketch in den visuellen Editor zu holen.
Achtung
Der Code-Import ist eine experimentelle Funktion. Nicht jede Syntax wird unterstützt. Der Parser rekonstruiert so viel wie möglich aus einer Best-Effort-Analyse des Codes – prüfe das Ergebnis und achte auf Warnungen, die nach dem Import angezeigt werden.
So importierst du
Wähle den Code-Tab des Ziel-Screens und klicke dann auf die Schaltfläche Code importieren links neben Kopieren, um eine Quelldatei auszuwählen. Die Schaltfläche ist auf Plattformen verfügbar, die den Code-Import unterstützen.
Importierte Ebenen werden an den Screen dieses Tabs angehängt. Vorhandene Ebenen werden nicht entfernt. Wenn du neu anfangen willst, entferne zuerst die Ebenen dieses Screens.
Was rekonstruiert wird
Der Parser entfernt Kommentare, extrahiert #define-Makros und Variablendeklarationen, sucht dann nach Aufrufen von Zeichenfunktionen und ordnet sie Ebenentypen zu.
| Geparstes Konstrukt | Rekonstruiert als |
|---|---|
drawLine / line | Linienebene |
drawRect / fillRect | Rechteckebene |
drawCircle / fillCircle | Kreisebene |
drawPixel | Punktebene |
print / drawString | Textebene |
drawBitmap / drawXBitmap | Bild- / Malebene |
| Bild-Array-Deklarationen | Bitmap-Daten, mit Ebenen verknüpft |
| Schriftart-Verweise | Den Textebenen zugewiesene Schriftart |
Variablenwerte, auf die Funktionsargumente verweisen, werden auf ihre deklarierten Werte zurückgeführt: drawRect(x, y, 40, 20, WHITE) mit x = 10 und y = 5 erzeugt ein Rechteck bei (10, 5) mit der Größe 40 × 20.
Bekannte Einschränkungen
- Ebenennamen werden nicht wiederhergestellt. Importierte Ebenen erhalten generische Namen. Benenne sie manuell um, wenn du Variablen verwenden willst.
- Nur Standard-Bibliotheksaufrufe werden geparst. Eigene Hilfsfunktionen,
#ifdef-Zweige und Präprozessor-Makros außer#definewerden ignoriert. - Der Variablenstatus wird nicht wiederhergestellt. Auch wenn eine Eigenschaft ursprünglich eine Variable war, wird sie als fester Wert importiert. Schalte den Variablenschalter bei Bedarf pro Ebene manuell wieder ein.
- Mehrdeutige Farben. Bei monochromen Plattformen unterscheidet der Parser die Farben
0/1. Bei RGB-Plattformen erwartet er Hex-Konstanten (0xRRGGBB,0xRRRR) oder benannte Konstanten wieWHITEoderBLACK. Nicht standardmäßige Farbdefinitionen werden möglicherweise nicht erkannt. - Keine Erkennung der Einstellungen. Der Parser erkennt nicht, welche Code-Einstellungen beim Generieren des Codes aktiv waren. Prüfe die Einstellungen nach dem Import.
Warnungen
Nach dem Import werden alle Konstrukte, die der Parser nicht auflösen konnte, in einer Warnmeldung im Editor angezeigt. Häufige Warnungen:
- Bitmap-Array nicht gefunden – der Code verweist per Namen auf ein Bild, aber der importierte Code enthielt keine passende Array-Deklaration. Die Bildebene wird als Platzhalter angelegt.
- Schriftart nicht erkannt – der Schriftartname im Code passt zu keiner verfügbaren Schriftart. Die Textebene wird angelegt, verwendet aber die Standardschriftart der Plattform.
- Variable nicht aufgelöst – eine Variable in einem Zeichenaufruf hatte keine passende Deklaration. Das Argument wird als Null importiert.
Kläre die Warnungen, bevor du das importierte Design als verbindliche Grundlage behandelst.