====== Document-Sidebar-Affinity ====== Document-Sidebar-Affinity bindet Sidebar-Views an Dokumenttypen. Wenn der Benutzer zwischen Dokument-Tabs wechselt, zeigt der Host automatisch die zugehörigen Sidebar-Panels an und blendet nicht zugehörige aus. Ziel ist es, den Kontext der Seitenleiste stets zum aktiven Dokument passend zu halten, ohne dass das Plugin dieses Verhalten selbst implementieren muss. Im Unterschied dazu mussten Plugins bisher ''ShowPanel'' und ''HidePanel'' in ihren ''DoActivated''/''DoDeactivated''-Methoden manuell aufrufen. Der Vorteil besteht darin, dass die gesamte Sidebar-Steuerung deklarativ über das Manifest erfolgt und der Host die Konsistenz über alle Plugins hinweg garantiert. Zurück zur [[start|Contributions-Übersicht]] oder zur [[..:start|Hauptübersicht]]. ===== Manifest-Deklaration ===== Das neue Feld ''documentAffinity'' wird auf View-Ebene in der Manifest-Datei (''plugin.json'') deklariert: "contributes": { "views": { "sidebar": [ { "id": "wis.orgTree", "title": "%nls.orgTree.title%", "icon": "codicon-list-tree", "containerId": "wis.navigation", "documentAffinity": ["wis.proofPlan", "wis.proofExec"] }, { "id": "wis.filter", "title": "%nls.filter.title%", "containerId": "wis.navigation", "documentAffinity": ["wis.proofPlan", "wis.proofExec", "wis.proofForecast"] } ], "secondary": [ { "id": "wis.taskDetail", "title": "%nls.taskDetail.title%", "documentAffinity": ["wis.proofExec"], "autoShow": true }, { "id": "wis.ruleDetail", "title": "%nls.ruleDetail.title%", "documentAffinity": ["wis.proofPlan"] } ] } } ===== Felder ===== | **Feld** | **Typ** | **Pflicht** | **Default** | **Beschreibung** | | ''documentAffinity'' | ''string[]'' | nein | ''[]'' | Liste von Dokumenttypen, bei denen diese View sichtbar sein soll. Leeres Array bedeutet globale View (immer sichtbar). | | ''autoShow'' | ''boolean'' | nein | ''false'' | Wenn ''true'', wird die Sidebar automatisch aufgeklappt, sobald diese View durch Affinity aktiviert wird. Nur relevant für die sekundäre Seitenleiste. | ===== Verhaltensregeln ===== ==== Affine Views ==== Eine View mit ''documentAffinity'' ist an die aufgelisteten Dokumenttypen gebunden. Der Host zeigt sie nur, wenn der aktive Dokument-Tab einen dieser Typen hat. documentAffinity: ["wis.proofExec", "wis.proofPlan"] → Sichtbar wenn aktives Dokument = wis.proofExec ODER wis.proofPlan → Unsichtbar bei allen anderen Dokumenttypen ==== Globale Views ==== Views ohne ''documentAffinity'' (oder mit leerem Array) sind globale Views. Sie bleiben immer sichtbar, unabhängig vom aktiven Dokument. ==== Benutzer-Override ==== Der Host respektiert die Entscheidungen des Benutzers: | **Zustand** | **Verhalten** | | ''Auto'' | Manager steuert Show/Hide nach Affinity (Standard) | | ''UserHidden'' | Benutzer hat manuell geschlossen — Manager ignoriert diese View | | ''UserPinned'' | Benutzer hat angepinnt — View bleibt immer sichtbar | Ein Layout-Reset setzt alle Overrides zurück auf ''Auto''. ==== Tab-Wechsel-Optimierung ==== Wechselt der Benutzer zwischen zwei Tabs desselben Dokumenttyps (z.B. zwei offene ''wis.proofExec''-Instanzen), findet kein Sidebar-Wechsel statt. Der Manager erkennt, dass der Dokumenttyp identisch ist, und überspringt die Neuauswertung. ===== Zusammenspiel mit bestehenden Contributions ===== Document-Sidebar-Affinity ergänzt die bestehenden Sidebar-Contributions und arbeitet mit ihnen zusammen: | **Contribution** | **Zusammenspiel** | | ''containerId'' (Accordion) | Affinity gilt für den gesamten Container. Wenn eine View im Container affin ist, wird der gesamte Accordion-Container angezeigt. | | ''view/title'' (Titelleisten-Buttons) | Unverändert — die Buttons erscheinen nach Affinity-Aktivierung wie gewohnt. | | ''viewsWelcome'' | Unverändert — Welcome-Inhalt wird angezeigt, wenn die View sichtbar aber leer ist. | | ''when''-Ausdrücke | Affinity ergänzt When-Clauses. ''documentAffinity'' steuert die Sichtbarkeit der View, ''when'' steuert die Sichtbarkeit einzelner Menüeinträge. | ===== ActivityBar-Integration ===== Wenn eine affine View zur primären Seitenleiste gehört, aktiviert der Manager automatisch das entsprechende ActivityBar-Icon. Der Benutzer sieht sofort, welche Seitenleiste zum aktiven Dokument gehört. Für die sekundäre Seitenleiste gibt es keine ActivityBar — dort steuert ''autoShow'' die automatische Sichtbarkeit. ===== Kein Plugin-Code nötig ===== Die gesamte Sidebar-Steuerung läuft über die Manifest-Deklaration. Das Plugin muss weder ''ShowPanel''/''HidePanel'' aufrufen noch ''DoActivated''/''DoDeactivated'' überschreiben, um Sidebar-Panels zu steuern. Der Host erledigt alles auf Basis der ''documentAffinity''-Arrays. // Vorher (manuell im Plugin): procedure TWISExecFrame.DoActivated; begin inherited; FHost.SideBar.ShowPanel('wis.orgTree'); FHost.SideBar.ShowPanel('wis.filter'); end; // Nachher (deklarativ im Manifest): // Kein Code nötig — documentAffinity im Manifest reicht. ===== Technische Implementierung (Host-intern) ===== Die Implementierung besteht aus drei Teilen: - **Manifest-Parser** (''WvdS.Document.Host.Manifest.pas'') — liest ''documentAffinity'' und ''autoShow'' aus der JSON-View-Deklaration. - **Contribution-Router** (''WvdS.Document.Host.GUI.ContributionRouter.pas'') — übergibt Affinities an den Manager während der View-Routing-Phase. - **SidebarManager** (''WvdS.Document.Host.GUI.SidebarManager.pas'') — evaluiert Affinities bei jedem Tab-Wechsel und steuert ActivityBar und Sidebar-Sichtbarkeit. Der Manager wird vom Host-internen ''HandleActiveDocChanged'' aufgerufen, wenn der Benutzer einen Dokument-Tab aktiviert. Plugins interagieren nie direkt mit dem Manager. Weiter zu [[toolbar|Toolbar]] oder zurück zur [[start|Contributions-Übersicht]].