====== 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.