====== Vega — Menüs, Werkzeugleiste, Befehle, Hinweise ====== Derselbe Befehl steht in einer Anwendung meist an drei Stellen: im Menü, auf der Werkzeugleiste und hinter einem Tastenkürzel. Vega hat dafür ''TAction'' — den Befehl als eigenes Ding. Beschriftung, Kürzel, Hinweistext und der gesperrte Zustand stehen **einmal** dort und gelten überall, wo er verknüpft ist. → [[lyx_-_programmiersprache:vega:guides|Vega-Guides]] · [[lyx_-_programmiersprache:vega:guides:komponenten|Komponenten]] · [[lyx_-_programmiersprache:vega:guides:events|Ereignisse]] ---- ===== Menü ===== var mm: TMainMenu := new TMainMenu(); var mDatei: TMenuItem := mm.Add("Datei"); mDatei.Add("Neu").OnClick := OnNeu; mDatei.AddSeparator(); mDatei.Add("Beenden").OnClick := OnBeenden; mDatei.Item(2).SetShortcut(113, MOD_CTRL); // Strg+Q f.SetMenu(mm); ''Add'' liefert den neuen Eintrag zurück — daher die kurze Schreibweise. Untermenüs entstehen, indem man an einem Eintrag wieder ''Add'' ruft. Auf bestehende Einträge kommt man über ''Item(index)''; ''Checked'' und ''Enabled'' setzen den Zustand. Die Menüleiste **nimmt am Layout nicht teil**: sie liegt auf ''0/0'' und wird zuletzt gezeichnet. Zwei Folgen — Platz darunter selbst freihalten (''f.MenuHeight()'') und im ''OnResize'' die Breite nachziehen (''f.Menu.Width := f.Width''). Ein Kontextmenü ist ein ''TPopupMenu'', zugewiesen über ''PopupMenuPtr''. ---- ===== Werkzeugleiste ===== var tb: TToolBar := new TToolBar(); tb.SetBounds(0, f.MenuHeight(), 520, 34); tb.ButtonWidth := 120; tb.SetParent(f); var t1: TButton := new TButton(""); t1.Width := 0; // 0 = die Leiste bestimmt die Breite t1.SetParent(tb); tb.ArrangeButtons(); ''TToolBar'' ordnet ihre Kinder selbst an: ''ButtonWidth'', ''ButtonHeight'', ''Spacing'', ''Flat'', ''ShowCaptions'', ''Wrapable''. Ein Knopf mit ''Width := 0'' übernimmt die Vorgabebreite der Leiste; ein Knopf mit eigener Breite behält sie. ''ArrangeButtons()'' nach dem Befüllen. ---- ===== Befehle (TAction) ===== g_al := new TActionList(); g_app.AddActionList(g_al); var aSp: TAction := g_al.Add("Speichern"); aSp.SetHint("Schreibt die Datei"); aSp.SetShortcut(83, MOD_CTRL); // Strg+S aSp.OnExecute := TueSpeichern; // fn(action: TAction): void aSp.OnUpdate := PruefeSpeichern; // setzt action.Enabled Verknüpft wird in beide Richtungen: * ''aSp.LinkMenuItem(mDatei.Add(""))'' — der Eintrag bekommt Beschriftung, Kürzel und Zustand vom Befehl; deshalb der leere Text. * ''aSp.LinkControl(knopf as TControl)'' — dasselbe für einen Knopf. ''OnUpdate'' läuft, bevor die Oberfläche gezeigt wird. Dort steht **eine** Bedingung, und Menüeintrag wie Knopf werden gemeinsam gesperrt — statt an jeder Stelle dieselbe Prüfung zu wiederholen. Ein ''TAction'' trägt außerdem ''Checked'', ''Visible'', ''ImageIndex'' und ''Tag''. ---- ===== Hinweise (Hints) ===== Jedes Control hat ''Hint'' und ''ShowHint''. Gesetzt wird der Text mit ''SetHint("…")''; ''ShowHint := false'' schaltet ihn für einen Bereich ab — auch für dessen Kinder. Die Anzeige selbst übernimmt der ''THintController'' der Anwendung; ein Klick räumt den Hinweis sofort weg. Ein ''TAction'' gibt seinen ''Hint'' an alles weiter, was mit ihm verknüpft ist. ---- ===== Beispiel ===== Ein Befehl, drei Bedienwege — Menü, Leiste, Tastenkürzel — plus Kontextmenü und Hinweistext: 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.Layout; import Vega.Menus; import Vega.Actions; import Vega.Backend; import Vega.BackendAuto; import Vega.Forms; var g_app: TApplication; var g_form: TForm; var g_al: TActionList; var g_status: TLabel; var g_geaendert: bool; // Ein Befehl fuehrt aus … fn TueSpeichern(action: TAction): void { g_geaendert := false; g_status.SetCaption("gespeichert"); } // … und sagt selbst, wann er verfuegbar ist. OnUpdate laeuft vor dem // Anzeigen — Menueeintrag UND Knopf werden gemeinsam gesperrt. fn PruefeSpeichern(action: TAction): void { action.Enabled := g_geaendert; } fn TueAendern(action: TAction): void { g_geaendert := true; g_status.SetCaption("geaendert"); } fn TueBeenden(action: TAction): void { g_app.Terminate(); } // Ein Menueeintrag ohne Befehl bekommt einen gewoehnlichen TNotifyEvent. fn OnKontext(sender: TControl): void { g_status.SetCaption("aus dem Kontextmenue"); } fn main(): int64 { g_app := new TApplication(NewPlatformBackend()); if (!g_app.Ready) { PrintLn("Kein Fenstersystem erreichbar."); return 1; } g_form := new TForm(520, 240, "Menue, Leiste, Befehle"); g_geaendert := false; g_al := new TActionList(); g_app.AddActionList(g_al); var aSp: TAction := g_al.Add("Speichern"); aSp.SetHint("Schreibt die Datei"); aSp.SetShortcut(83, MOD_CTRL); // Strg+S aSp.OnExecute := TueSpeichern; aSp.OnUpdate := PruefeSpeichern; var aAe: TAction := g_al.Add("Aendern"); aAe.SetHint("Markiert das Dokument als geaendert"); aAe.OnExecute := TueAendern; var aEn: TAction := g_al.Add("Beenden"); aEn.SetShortcut(81, MOD_CTRL); // Strg+Q aEn.OnExecute := TueBeenden; // Menue: der Eintrag bekommt Beschriftung, Kuerzel und Zustand vom Befehl var mm: TMainMenu := new TMainMenu(); var mDatei: TMenuItem := mm.Add("Datei"); aSp.LinkMenuItem(mDatei.Add("")); aAe.LinkMenuItem(mDatei.Add("")); mDatei.AddSeparator(); aEn.LinkMenuItem(mDatei.Add("")); g_form.SetMenu(mm); // Werkzeugleiste: Width auf 0 heisst "die Leiste bestimmt die Breite" var tb: TToolBar := new TToolBar(); tb.SetBounds(0, g_form.MenuHeight(), 520, 34); tb.ButtonWidth := 120; tb.SetParent(g_form); var t1: TButton := new TButton(""); t1.Width := 0; t1.SetParent(tb); aSp.LinkControl(t1 as TControl); var t2: TButton := new TButton(""); t2.Width := 0; t2.SetParent(tb); aAe.LinkControl(t2 as TControl); tb.ArrangeButtons(); g_status := new TLabel("bereit"); g_status.SetBounds(16, 100, 480, 18); g_status.SetHint("Zeigt, was zuletzt geschah"); g_status.SetParent(g_form); // Kontextmenue am Fenster var pm: TPopupMenu := new TPopupMenu(); pm.Add("Was war zuletzt?").OnClick := OnKontext; g_form.PopupMenuPtr := pm as int64; if (!g_app.ShowForm(g_form)) { return 2; } g_app.Run(); g_app.Shutdown(); return 0; } Übersetzen: ''lyxc befehle.lyx -I . -I platform/linux -o befehle''. Nachgemessen mit ''lyxc 1.1.3I'', übersetzt fehlerfrei. ---- ===== Fallstricke ===== * **''AddActionList'' vergessen.** Ohne sie läuft kein ''OnUpdate'' und kein Kürzel. * **Beschriftung doppelt gepflegt.** Wer den Menüeintrag mit Text anlegt **und** einen Befehl verknüpft, hat zwei Wahrheiten. Mit Befehl: ''Add("")''. * **''ArrangeButtons()'' vergessen.** Die Leiste bleibt leer aussehend, obwohl die Knöpfe da sind. * **Platz unter der Menüleiste.** Sie nimmt am Layout nicht teil; ohne eigenen Streifen liegt die erste Zeile darunter. Letzte Aktualisierung: 2026-08-19 — API gegen ''Vega/Menus.lyx'', ''Vega/Layout.lyx'', ''Vega/Actions.lyx'' und ''Vega/Hints.lyx'' erhoben; Beispiel mit ''lyxc 1.1.3I'' übersetzt.