====== Vega — Zeichnen ====== Vega zeichnet jedes Pixel selbst. Wer eine eigene Darstellung braucht — ein Diagramm, ein Raster, eine Anzeige mit fester Zeichenbreite —, bekommt dafür genau eine Schnittstelle: ''TCanvas''. Zwei Wege führen dorthin: * **[[lyx_-_programmiersprache:vega:controls:tpaintbox|TPaintBox]]** mit ''OnPaint'' — eine Fläche, die nur zeichnet. Kein eigener Typ nötig. * **Eigene Klasse** von [[lyx_-_programmiersprache:vega:controls:tcontrol|TControl]] mit ''override fn Paint(canvas: TCanvas)'' — wenn das Element außerdem Zustand hält und auf Eingaben reagiert (siehe [[lyx_-_programmiersprache:vega:praxis|Anwendungen aufbauen]]). → [[lyx_-_programmiersprache:vega:guides|Vega-Guides]] · [[lyx_-_programmiersprache:vega:guides:eigenschaften|Eigenschaften]] · [[lyx_-_programmiersprache:vega:themes|Themes]] ---- ===== Was TCanvas kann ===== ^ Gruppe ^ Methoden ^ | Flächen | ''Clear(c)'', ''FillRect(r, c)'', ''FillRectBlend(r, c)'', ''FillRoundRect(r, radius, c)'', ''FillEllipse(r, c)'' | | Umrisse | ''FrameRect(r, c)'', ''FrameRoundRect(r, radius, c)'', ''FrameEllipse(r, c)'' | | Linien | ''Line(x1, y1, x2, y2, c)'', ''HLine(x1, x2, y, c)'', ''VLine(x, y1, y2, c)'' | | Punkte | ''SetPixel(x, y, c)'', ''GetPixel(x, y)'', ''BlendPixel(x, y, c)'' | | Ausschnitt | ''PushClip(r)'' / ''PopClip()'', ''ClipIsEmpty()'' | | Ursprung | ''PushOrigin(dx, dy)'' / ''PopOrigin()'' | | Kopieren | ''Blit(src, x, y)'' | Koordinaten sind **relativ zum Control**; die Umrechnung in Fensterkoordinaten macht der Ursprungs-Stapel beim Zeichnen. ''TRect'' entsteht mit ''Rect(links, oben, rechts, unten)'', Maße liefern ''RectWidth'' und ''RectHeight''. Farben kommen aus ''RGB(r, g, b)''. ---- ===== Text ===== var f: TFont := DefaultFont(); var tw: int64 := f.TextWidth("Beschriftung"); f.DrawText(canvas, x, y, "Beschriftung", RGB(0, 0, 0)); * ''TextWidth'' misst, ''TextHeight'' liefert die Zeichenhöhe, ''LineHeight'' die Zeilenhöhe samt Durchschuss. * ''DrawTextIn(canvas, r, text, color, align)'' setzt Text in ein Rechteck statt an einen Punkt. * ''LoadTrueType(pfad, pixelgroesse)'' lädt eine echte Schrift; ohne sie zeichnet die eingebaute. * Eine Schrift ist ein **Zeiger**: mehrere Controls teilen sich dieselbe Instanz, statt jedes seinen eigenen Glyphenspeicher zu halten. ---- ===== Beispiel ===== Flächen, Linien, gemessener Text und ein Punkt, der dem Zeiger folgt: unit Main; import std.io; import Vega.Types; import Vega.Events; import Vega.Canvas; import Vega.Theme; import Vega.Control; import Vega.Font; import Vega.Strings; import Vega.Lists; import Vega.Style; import Vega.StdCtrls; import Vega.Extras; import Vega.Backend; import Vega.BackendAuto; import Vega.Forms; var g_app: TApplication; var g_box: TPaintBox; var g_x: int64; var g_y: int64; fn OnBeenden(sender: TControl): void { g_app.Terminate(); } // Zeichnen ueber den Handler einer TPaintBox: dieselbe Signatur wie ein // ueberschriebenes Paint, nur ohne eigene Klasse. fn OnZeichnen(sender: TControl, canvas: TCanvas): void { var r: TRect := sender.ClientRect(); canvas.FillRect(r, RGB(250, 250, 245)); canvas.FrameRect(r, RGB(120, 120, 120)); // Flaechen canvas.FillRect(Rect(16, 16, 116, 76), RGB(70, 130, 180)); canvas.FillRoundRect(Rect(132, 16, 232, 76), 10, RGB(200, 120, 60)); canvas.FillEllipse(Rect(248, 16, 348, 76), RGB(90, 160, 90)); // Linien canvas.Line(16, 96, 348, 96, RGB(60, 60, 60)); canvas.HLine(16, 348, 104, RGB(180, 180, 180)); canvas.VLine(16, 96, 150, RGB(180, 180, 180)); // Text: Breite messen, dann mittig setzen var f: TFont := DefaultFont(); var txt: pchar := "Vega zeichnet alles selbst"; var tw: int64 := f.TextWidth(txt); var tx: int64 := (RectWidth(r) - tw) / 2; f.DrawText(canvas, tx, 120, txt, RGB(0, 0, 0)); // Zeiger zuletzt, damit er ueber allem liegt canvas.FillEllipse(Rect(g_x - 4, g_y - 4, g_x + 4, g_y + 4), RGB(200, 0, 0)); } fn OnMaus(sender: TControl, x: int64, y: int64, button: int64): void { g_x := x; g_y := y; g_box.Invalidate(); } fn main(): int64 { g_app := new TApplication(NewPlatformBackend()); if (!g_app.Ready) { PrintLn("Kein Fenstersystem erreichbar."); return 1; } var f: TForm := new TForm(400, 240, "Zeichnen"); g_box := new TPaintBox(); g_box.SetBounds(8, 8, 368, 160); g_box.OnPaint := OnZeichnen; g_box.OnMouseMove := OnMaus; g_box.SetParent(f); var b: TButton := new TButton("Beenden"); b.SetBounds(256, 180, 120, 28); b.OnClick := OnBeenden; b.SetParent(f); if (!g_app.ShowForm(f)) { return 2; } g_app.Run(); g_app.Shutdown(); return 0; } Übersetzen: ''lyxc zeichnen.lyx -I . -I platform/linux -o zeichnen''. Nachgemessen mit ''lyxc 1.1.3I'', übersetzt fehlerfrei. ---- ===== Regeln fürs Zeichnen ===== * **''Paint'' rechnet nicht.** Es zeichnet, was schon feststeht. Werte, die aus Ereignissen kommen (Zeigerposition, Auswahl), gehören in Felder oder Modulvariablen — ''Paint'' liest sie nur. * **Nach jeder Zustandsänderung ''Invalidate()''.** Sonst bleibt das alte Bild stehen. * **Reihenfolge ist Tiefe.** Was zuletzt gezeichnet wird, liegt oben. * **''ClientRect()'' statt ''Width''/''Height''.** Es liefert die Fläche ohne Rahmen — sonst zeichnet man über den eigenen Rand. * **Für Bilder gibt es [[lyx_-_programmiersprache:vega:controls:timage|TImage]]** (''Vega.Images'') mit ''Picture'' und ''Stretch''; ''Blit'' ist der Weg, ein fertiges ''TCanvas'' zu übernehmen. * **Bilddaten liegen in [[lyx_-_programmiersprache:vega:controls:tbitmap|TBitmap]]** (''Vega.Picture''): laden, skalieren, Pixel setzen, mit ''DrawTo'' oder ''StretchDrawTo'' auf die Zeichenfläche bringen. * **Symbolsätze gehören in [[lyx_-_programmiersprache:vega:controls:timagelist|TImageList]]** — ''Draw'' und ''DrawDisabled'' zeichnen daraus, ohne dass man einen zweiten, blassen Satz pflegen muss. Letzte Aktualisierung: 2026-08-20 — Canvas- und Font-Methoden gegen ''Vega/Canvas.lyx'' und ''Vega/Font.lyx'' erhoben, Beispiel mit ''lyxc 1.1.3I'' übersetzt.