====== Tutorial: Menü- und Toolbar-Integration ====== Dieses Tutorial zeigt, wie ein Add-in seine Commands in die Menüleiste, die Toolbar, die ActionBar und die QuickBar der Shell integriert. Der Schwerpunkt liegt auf dem Merge-Verfahren: Wie werden Beiträge mehrerer Add-ins zusammengeführt, und wie steuern ''group'', ''order'' und ''when'' das Ergebnis. Zurück zur [[..:start|Übersicht]]. ===== Ausgangssituation ===== Drei Add-ins sollen ihre Funktionalität in die Shell einbringen: * **Assets** — Anlageverwaltung (Öffnen, Speichern, Drucken) * **Reports** — Berichtswesen (Monatsbericht, Jahresbericht) * **Export** — Datenexport (CSV, PDF) Jedes Add-in hat ein eigenes Top-Level-Menü, und alle drei tragen Buttons zur Haupt-Toolbar und zur ActionBar bei. ===== Schritt 1: Top-Level-Menüs anlegen ===== Jedes Add-in deklariert ein Submenü und platziert es in der Menüleiste: **Assets:** "submenus": [ { "id": "assets", "label": "Assets" } ], "menus": { "menuBar": [ { "submenu": "assets", "group": "modules", "order": 100 } ], "assets": [ { "command": "assets.open", "group": "file", "order": 1 }, { "command": "assets.save", "group": "file", "order": 2 }, { "command": "assets.print", "group": "output", "order": 1 } ] } **Reports:** "submenus": [ { "id": "reports", "label": "Berichte" } ], "menus": { "menuBar": [ { "submenu": "reports", "group": "modules", "order": 200 } ], "reports": [ { "command": "reports.monthly", "group": "standard", "order": 1 }, { "command": "reports.yearly", "group": "standard", "order": 2 }, { "command": "reports.custom", "group": "custom", "order": 1 } ] } **Export:** "submenus": [ { "id": "export", "label": "Export" } ], "menus": { "menuBar": [ { "submenu": "export", "group": "tools", "order": 100 } ], "export": [ { "command": "export.csv", "group": "formats", "order": 1 }, { "command": "export.pdf", "group": "formats", "order": 2 } ] } ==== Ergebnis in der Menüleiste ==== [ Datei ] [ Assets ] [ Berichte ] [ Export ] [ Hilfe ] (modules/100) (modules/200) (tools/100) Assets und Berichte stehen nebeneinander, weil beide die Gruppe ''modules'' verwenden. Innerhalb der Gruppe bestimmt ''order'' die Reihenfolge (100 < 200). Export steht in der Gruppe ''tools'', die alphabetisch nach ''modules'' kommt. ==== Ergebnis im Assets-Menü ==== Assets ├── Anlage öffnen (file / 1) ├── Anlage speichern (file / 2) ├── ───────────────── (Trennstrich) └── Drucken (output / 1) Die Gruppen ''file'' und ''output'' werden durch einen Trennstrich getrennt. ===== Schritt 2: In bestehende Menüs einfügen ===== Ein Add-in kann auch in ein Menü eines anderen Add-ins einfügen. Das Export-Add-in möchte etwa einen Eintrag im Assets-Menü platzieren: "menus": { "assets": [ { "command": "export.asset-csv", "group": "output", "order": 2, "when": "activeDocument == assets.editor" } ] } Dieser Eintrag landet in der Gruppe ''output'' des Assets-Menüs, direkt nach dem Drucken-Eintrag (''order'' 2 > 1). Er ist nur sichtbar, wenn ein Asset-Editor aktiv ist. Assets ├── Anlage öffnen (file / 1) ├── Anlage speichern (file / 2) ├── ───────────────── ├── Drucken (output / 1) └── Als CSV exportieren (output / 2) ← Vom Export-Add-in Dieses Cross-Plugin-Merging funktioniert, weil der Host alle Manifest-Beiträge sammelt und nach Location-Schlüssel zusammenführt. Dem Assets-Menü ist es egal, von welchem Add-in der Eintrag kommt — die Sortierung nach Gruppe und Order gilt einheitlich. ===== Schritt 3: Toolbar-Integration ===== Die drei Add-ins tragen Buttons zu verschiedenen Toolbar-Bereichen bei: **Haupt-Toolbar (immer sichtbar):** // Assets { "toolbarId": "main", "command": "assets.open", "icon": "media/asset.svg", "group": "modules", "order": 1 } // Reports { "toolbarId": "main", "command": "reports.monthly", "icon": "media/report.svg", "group": "modules", "order": 2 } **ActionBar (kontextabhängig):** // Assets — nur sichtbar bei aktivem Asset-Editor { "toolbarId": "actionbar", "command": "assets.save", "icon": "media/save.svg", "when": "activeDocument == assets.editor && isDirty" } { "toolbarId": "actionbar", "command": "assets.print", "icon": "media/print.svg", "when": "activeDocument == assets.editor" } // Export — nur sichtbar bei aktivem Asset-Editor { "toolbarId": "actionbar", "command": "export.asset-csv", "icon": "media/csv.svg", "when": "activeDocument == assets.editor" } **QuickBar (benutzerdefinierbar):** // Assets — Schnellzugriff { "toolbarId": "quickbar", "command": "assets.open", "icon": "media/asset.svg" } ==== Ergebnis ==== Haupt-Toolbar: [ Asset öffnen ] [ Monatsbericht ] (modules/1) (modules/2) ActionBar (wenn Asset-Editor aktiv und dirty): [ Speichern ] [ Drucken ] [ CSV Export ] Die ActionBar-Buttons erscheinen und verschwinden automatisch, wenn der Benutzer zwischen Tabs wechselt. Das liegt an den ''when''-Ausdrücken, die der Host bei jedem Kontextwechsel neu auswertet. ===== Schritt 4: CommandPalette ===== Standardmäßig erscheinen alle Commands in der CommandPalette. Commands, die nur über andere Wege erreichbar sein sollen, werden ausgeblendet: "menus": { "commandPalette": [ { "command": "assets.internal.cleanup", "when": "false" } ] } Der Ausdruck ''when'': ''"false"'' ist immer falsch — der Command erscheint nie in der Palette. Er bleibt aber über ''ExecuteCommand'' und Menüs erreichbar. ===== Schritt 5: Kontextmenüs ===== Kontextmenüs für TreeView-Elemente verwenden den Ort ''view/item/context'': "menus": { "view/item/context": [ { "command": "assets.nav.open", "when": "view == assets.navigator && viewItem == asset", "group": "navigation", "order": 1 }, { "command": "export.asset-csv", "when": "view == assets.navigator && viewItem == asset", "group": "export", "order": 1 }, { "command": "assets.nav.delete", "when": "view == assets.navigator && viewItem == asset", "group": "modification", "order": 1 } ] } Das Kontextmenü für einen Asset-Baumknoten: ├── Anlage öffnen (navigation / 1) ← Vom Assets-Add-in ├── ───────────────── ├── Als CSV exportieren (export / 1) ← Vom Export-Add-in ├── ───────────────── └── Löschen (modification / 1) ← Vom Assets-Add-in Auch hier werden Beiträge verschiedener Add-ins nach Gruppe und Order zusammengeführt. Das Export-Add-in fügt seinen Eintrag in das Kontextmenü des Assets-Navigators ein, ohne dass das Assets-Add-in davon wissen muss. ===== Zusammenfassung der Merge-Regeln ===== - Jeder Beitrag hat einen **Ort** (Location): ''menuBar'', ''commandPalette'', ''view/title'', ''view/item/context'' oder eine Submenu-Id. - Innerhalb eines Orts sortiert der Host nach **Gruppe** (alphabetisch), dann nach **Order** (numerisch). - Zwischen verschiedenen Gruppen fügt der Host einen **Trennstrich** ein. - **When-Ausdrücke** steuern die Sichtbarkeit dynamisch. Ändert sich ein Kontextwert, aktualisiert der Host sofort alle betroffenen Einträge. - **Cross-Plugin-Merging** funktioniert automatisch: Ein Add-in kann in das Menü oder Kontextmenü eines anderen Add-ins einfügen, indem es denselben Location-Schlüssel verwendet. - Die **Installationsreihenfolge** spielt keine Rolle. Das Ergebnis ist deterministisch, weil es nur von Gruppe und Order abhängt. Zurück zur [[..:start|Übersicht]].