diff --git a/packages/dockview/src/__tests__/groupview/groupview.spec.ts b/packages/dockview/src/__tests__/groupview/groupview.spec.ts index d6fc1c10b..84eccea64 100644 --- a/packages/dockview/src/__tests__/groupview/groupview.spec.ts +++ b/packages/dockview/src/__tests__/groupview/groupview.spec.ts @@ -444,4 +444,19 @@ describe('groupview', () => { groupview.model.closeAllPanels(); expect(removeGroupMock).toBeCalledWith(groupview); }); + + test('that group is set on panel during onDidAddPanel event', () => { + const cut = new DockviewComponent(document.createElement('div'), { + components: { + component: TestContentPart, + }, + }); + + const disposable = cut.onDidAddPanel((panel) => { + expect(panel.group).toBeTruthy(); + }); + + const panel = cut.addPanel({ id: 'id', component: 'component' }); + disposable.dispose(); + }); }); diff --git a/packages/dockview/src/dockview/dockviewComponent.ts b/packages/dockview/src/dockview/dockviewComponent.ts index bbeb2a163..c09a4d823 100644 --- a/packages/dockview/src/dockview/dockviewComponent.ts +++ b/packages/dockview/src/dockview/dockviewComponent.ts @@ -113,6 +113,10 @@ export interface IDockviewComponent extends IBaseGrid { focus(): void; toJSON(): SerializedDockview; fromJSON(data: SerializedDockview): void; + // + readonly onDidRemovePanel: Event; + readonly onDidAddPanel: Event; + readonly onDidActivePanelChange: Event; } export class DockviewComponent @@ -133,6 +137,19 @@ export class DockviewComponent private readonly _onDidDrop = new Emitter(); readonly onDidDrop: Event = this._onDidDrop.event; + private readonly _onDidRemovePanel = new Emitter(); + readonly onDidRemovePanel: Event = + this._onDidRemovePanel.event; + + private readonly _onDidAddPanel = new Emitter(); + readonly onDidAddPanel: Event = this._onDidAddPanel.event; + + private readonly _onDidActivePanelChange = new Emitter< + IGroupPanel | undefined + >(); + readonly onDidActivePanelChange: Event = + this._onDidActivePanelChange.event; + // everything else private _deserializer: IPanelDeserializer | undefined; private _api: DockviewApi; @@ -632,6 +649,9 @@ export class DockviewComponent kind: GroupChangeKind.PANEL_ACTIVE, panel: this._activeGroup?.model.activePanel, }); + this._onDidActivePanelChange.fire( + this._activeGroup?.model.activePanel + ); } } @@ -677,24 +697,25 @@ export class DockviewComponent kind: GroupChangeKind.ADD_PANEL, panel: event.panel, }); - break; - case GroupChangeKind2.GROUP_ACTIVE: - this._onGridEvent.fire({ - kind: GroupChangeKind.GROUP_ACTIVE, - panel: event.panel, - }); + if (event.panel) { + this._onDidAddPanel.fire(event.panel); + } break; case GroupChangeKind2.REMOVE_PANEL: this._onGridEvent.fire({ kind: GroupChangeKind.REMOVE_PANEL, panel: event.panel, }); + if (event.panel) { + this._onDidRemovePanel.fire(event.panel); + } break; case GroupChangeKind2.PANEL_ACTIVE: this._onGridEvent.fire({ kind: GroupChangeKind.PANEL_ACTIVE, panel: event.panel, }); + this._onDidActivePanelChange.fire(event.panel); break; } }) @@ -778,4 +799,12 @@ export class DockviewComponent group.value.model.containsPanel(panel) )?.value; } + + public dispose(): void { + super.dispose(); + + this._onDidActivePanelChange.dispose(); + this._onDidAddPanel.dispose(); + this._onDidRemovePanel.dispose(); + } } diff --git a/packages/dockview/src/dockview/dockviewGroupPanel.ts b/packages/dockview/src/dockview/dockviewGroupPanel.ts index c0ddcd33d..e4136e586 100644 --- a/packages/dockview/src/dockview/dockviewGroupPanel.ts +++ b/packages/dockview/src/dockview/dockviewGroupPanel.ts @@ -1,4 +1,3 @@ -import { GroupChangeKind2 } from '../groupview/groupview'; import { DockviewApi } from '../api/component.api'; import { DockviewPanelApiImpl } from '../api/groupPanelApi'; import { @@ -147,20 +146,6 @@ export class DockviewGroupPanel this._group = group; this.api.group = group; - this.mutableDisposable.value = this._group.model.onDidGroupChange( - (ev) => { - if (ev.kind === GroupChangeKind2.GROUP_ACTIVE) { - const isVisible = !!this._group?.model.isPanelActive(this); - this.api._onDidActiveChange.fire({ - isActive: isGroupActive && isVisible, - }); - this.api._onDidVisibilityChange.fire({ - isVisible, - }); - } - } - ); - const isPanelVisible = this._group.model.isPanelActive(this); this.api._onDidActiveChange.fire({ diff --git a/packages/dockview/src/gridview/baseComponentGridview.ts b/packages/dockview/src/gridview/baseComponentGridview.ts index 6135d455f..14077f0a5 100644 --- a/packages/dockview/src/gridview/baseComponentGridview.ts +++ b/packages/dockview/src/gridview/baseComponentGridview.ts @@ -74,6 +74,9 @@ export interface IBaseGrid { readonly groups: T[]; readonly onGridEvent: Event; readonly onDidLayoutChange: Event; + readonly onDidRemoveGroup: Event; + readonly onDidAddGroup: Event; + readonly onDidActiveGroupChange: Event; getPanel(id: string): T | undefined; toJSON(): object; fromJSON(data: any): void; @@ -99,6 +102,16 @@ export abstract class BaseGrid private _onDidLayoutChange = new Emitter(); readonly onDidLayoutChange = this._onDidLayoutChange.event; + private readonly _onDidRemoveGroup = new Emitter(); + readonly onDidRemoveGroup: Event = this._onDidRemoveGroup.event; + + private readonly _onDidAddGroup = new Emitter(); + readonly onDidAddGroup: Event = this._onDidAddGroup.event; + + private readonly _onDidActiveGroupChange = new Emitter(); + readonly onDidActiveGroupChange: Event = + this._onDidActiveGroupChange.event; + get id() { return this._id; } @@ -208,6 +221,7 @@ export abstract class BaseGrid this.gridview.addView(group, size ?? Sizing.Distribute, location); this._onGridEvent.fire({ kind: GroupChangeKind.ADD_GROUP }); + this._onDidAddGroup.fire(group); this.doSetGroupActive(group); } @@ -230,6 +244,7 @@ export abstract class BaseGrid } this._onGridEvent.fire({ kind: GroupChangeKind.REMOVE_GROUP }); + this._onDidRemoveGroup.fire(group); if (!options?.skipActive && this._activeGroup === group) { const groups = Array.from(this._groups.values()); @@ -269,6 +284,7 @@ export abstract class BaseGrid this._onGridEvent.fire({ kind: GroupChangeKind.GROUP_ACTIVE, }); + this._onDidActiveGroupChange.fire(group); } public removeGroup(group: T) { @@ -337,6 +353,11 @@ export abstract class BaseGrid super.dispose(); this._onGridEvent.dispose(); + this._onDidActiveGroupChange.dispose(); + this._onDidAddGroup.dispose(); + this._onDidRemoveGroup.dispose(); + this._onDidLayoutChange.dispose(); + this.gridview.dispose(); } } diff --git a/packages/dockview/src/groupview/groupview.ts b/packages/dockview/src/groupview/groupview.ts index 14779da1a..8f8d16ec7 100644 --- a/packages/dockview/src/groupview/groupview.ts +++ b/packages/dockview/src/groupview/groupview.ts @@ -19,7 +19,6 @@ export enum GroupChangeKind2 { ADD_PANEL = 'ADD_PANEL', REMOVE_PANEL = 'REMOVE_PANEL', PANEL_ACTIVE = 'PANEL_ACTIVE', - GROUP_ACTIVE = 'GROUP_ACTIVE', } export interface DndService { @@ -365,6 +364,10 @@ export class Groupview extends CompositeDisposable implements IGroupview { ) { options.index = this.panels.length; } + + // ensure the group is updated before we fire any events + panel.updateParentGroup(this.parent, true); + if (this._activePanel === panel) { this.accessor.doSetGroupActive(this.parent); return;