From 465141c097aac81d42fd87c1c7d9db22a20c0c87 Mon Sep 17 00:00:00 2001 From: Sherbakov Mikhail Date: Tue, 27 Feb 2024 19:57:31 +0300 Subject: [PATCH 1/2] fix(panels): improve the reactivity of panel parameters and titles --- .../dockview/dockviewComponent.spec.ts | 76 +++++++++- .../dockview/dockviewGroupPanelModel.spec.ts | 141 +++++++----------- .../dockview-core/src/api/dockviewPanelApi.ts | 1 + packages/dockview-core/src/api/panelApi.ts | 2 +- .../src/dockview/dockviewComponent.ts | 19 ++- .../src/dockview/dockviewGroupPanelModel.ts | 35 ++++- 6 files changed, 182 insertions(+), 92 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index c3f537aa7..69f6c1bb7 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -8,7 +8,7 @@ import { PanelUpdateEvent } from '../../panel/types'; import { Orientation } from '../../splitview/splitview'; import { CompositeDisposable } from '../../lifecycle'; import { Emitter } from '../../events'; -import { IDockviewPanel } from '../../dockview/dockviewPanel'; +import { DockviewPanel, IDockviewPanel } from '../../dockview/dockviewPanel'; import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel'; import { fireEvent } from '@testing-library/dom'; import { getPanelData } from '../../dnd/dataTransfer'; @@ -4596,4 +4596,78 @@ describe('dockviewComponent', () => { expect(panel2.group.api.isActive).toBeFalsy(); }); }); + + describe('that emits onDidLayoutChange', () => { + let dockview: DockviewComponent; + let panel1: DockviewPanel; + + beforeEach(() => { + jest.useFakeTimers(); + + dockview = new DockviewComponent({ + parentElement: container, + components: { + default: PanelContentPartTest, + }, + tabComponents: { + test_tab_id: PanelTabPartTest, + }, + orientation: Orientation.HORIZONTAL, + }); + + panel1 = dockview.addPanel({ + id: 'panel_1', + component: 'default', + }); + }); + + afterEach(() => { + jest.runAllTimers(); + jest.useRealTimers(); + }); + + test('that emits onDidPanelTitleChange and onDidLayoutChange when the panel set a title', () => { + const container = document.createElement('div'); + + const didPanelTitleChangeHandler = jest.fn(); + const { dispose: disposeDidPanelTitleChangeHandler } = + dockview.onDidPanelTitleChange(didPanelTitleChangeHandler); + + const didLayoutChangeHandler = jest.fn(); + const { dispose: disposeDidLayoutChangeHandler } = + dockview.onDidLayoutChange(didLayoutChangeHandler); + + panel1.setTitle('new title'); + + jest.runAllTimers(); + + expect(didPanelTitleChangeHandler).toHaveBeenCalledTimes(1); + expect(didLayoutChangeHandler).toHaveBeenCalledTimes(1); + + disposeDidPanelTitleChangeHandler(); + disposeDidLayoutChangeHandler(); + }); + + test('that emits onDidPanelParametersChange and onDidLayoutChange when the panel updates parameters', () => { + const didPanelParametersChangeHandler = jest.fn(); + const { dispose: disposeDidPanelParametersChangeHandler } = + dockview.onDidPanelParametersChange( + didPanelParametersChangeHandler + ); + + const didLayoutChangeHandler = jest.fn(); + const { dispose: disposeDidLayoutChangeHandler } = + dockview.onDidLayoutChange(didLayoutChangeHandler); + + panel1.api.updateParameters({ keyA: 'valueA' }); + + jest.runAllTimers(); + + expect(didPanelParametersChangeHandler).toHaveBeenCalledTimes(1); + expect(didLayoutChangeHandler).toHaveBeenCalledTimes(1); + + disposeDidPanelParametersChangeHandler(); + disposeDidLayoutChangeHandler(); + }); + }); }); diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts index b1963dbe5..31f710d03 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts @@ -9,19 +9,40 @@ import { } from '../../dockview/types'; import { PanelUpdateEvent, Parameters } from '../../panel/types'; import { + DockviewGroupLocation, DockviewGroupPanelModel, GroupOptions, } from '../../dockview/dockviewGroupPanelModel'; import { fireEvent } from '@testing-library/dom'; import { LocalSelectionTransfer, PanelTransfer } from '../../dnd/dataTransfer'; import { CompositeDisposable } from '../../lifecycle'; -import { DockviewPanelApi } from '../../api/dockviewPanelApi'; +import { + ActiveGroupEvent, + DockviewPanelApi, + GroupChangedEvent, + RendererChangedEvent, +} from '../../api/dockviewPanelApi'; import { IDockviewPanel } from '../../dockview/dockviewPanel'; import { IDockviewPanelModel } from '../../dockview/dockviewPanelModel'; import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel'; import { WatermarkRendererInitParameters } from '../../dockview/types'; import { createOffsetDragOverEvent } from '../__test_utils__/utils'; -import { OverlayRenderContainer } from '../../overlayRenderContainer'; +import { + DockviewPanelRenderer, + OverlayRenderContainer, +} from '../../overlayRenderContainer'; +import { DockviewGroupPanelFloatingChangeEvent } from '../../api/dockviewGroupPanelApi'; +import { SizeEvent } from '../../api/gridviewPanelApi'; +import { + PanelDimensionChangeEvent, + FocusEvent, + VisibilityEvent, + ActiveEvent, + HiddenEvent, + WillFocusEvent, +} from '../../api/panelApi'; +import { Position } from '../../dnd/droptarget'; +import { Emitter, Event } from '../../events'; enum GroupChangeKind2 { ADD_PANEL, @@ -240,12 +261,20 @@ describe('dockviewGroupPanelModel', () => { let removePanelMock: jest.Mock; let removeGroupMock: jest.Mock; + let panelApi: DockviewPanelApi; + beforeEach(() => { removePanelMock = jest.fn(); removeGroupMock = jest.fn(); options = {}; + panelApi = { + renderer: 'onlyWhenVisibile', + onDidTitleChange: new Emitter().event, + onUpdateParameters: new Emitter().event, + } as DockviewPanelApi; + dockview = (>{ options: { parentElement: document.createElement('div') }, createWatermarkComponent: () => new Watermark(), @@ -265,15 +294,9 @@ describe('dockviewGroupPanelModel', () => { }); test('panel events are captured during de-serialization', () => { - const panel1 = new TestPanel('panel1', { - renderer: 'onlyWhenVisibile', - } as any); - const panel2 = new TestPanel('panel2', { - renderer: 'onlyWhenVisibile', - } as any); - const panel3 = new TestPanel('panel3', { - renderer: 'onlyWhenVisibile', - } as any); + const panel1 = new TestPanel('panel1', panelApi); + const panel2 = new TestPanel('panel2', panelApi); + const panel3 = new TestPanel('panel3', panelApi); const groupview2 = new DockviewGroupPanel(dockview, 'groupview-2', { panels: [panel1, panel2, panel3], @@ -357,15 +380,9 @@ describe('dockviewGroupPanelModel', () => { }) ); - const panel1 = new TestPanel('panel1', { - renderer: 'onlyWhenVisibile', - } as any); - const panel2 = new TestPanel('panel2', { - renderer: 'onlyWhenVisibile', - } as any); - const panel3 = new TestPanel('panel3', { - renderer: 'onlyWhenVisibile', - } as any); + const panel1 = new TestPanel('panel1', panelApi); + const panel2 = new TestPanel('panel2', panelApi); + const panel3 = new TestPanel('panel3', panelApi); expect(events.length).toBe(0); @@ -443,15 +460,9 @@ describe('dockviewGroupPanelModel', () => { }); test('moveToPrevious and moveToNext', () => { - const panel1 = new TestPanel('panel1', { - renderer: 'onlyWhenVisibile', - } as any); - const panel2 = new TestPanel('panel2', { - renderer: 'onlyWhenVisibile', - } as any); - const panel3 = new TestPanel('panel3', { - renderer: 'onlyWhenVisibile', - } as any); + const panel1 = new TestPanel('panel1', panelApi); + const panel2 = new TestPanel('panel2', panelApi); + const panel3 = new TestPanel('panel3', panelApi); groupview.model.openPanel(panel1); groupview.model.openPanel(panel2); @@ -495,15 +506,9 @@ describe('dockviewGroupPanelModel', () => { }); test('closeAllPanels with panels', () => { - const panel1 = new TestPanel('panel1', { - renderer: 'onlyWhenVisibile', - } as any); - const panel2 = new TestPanel('panel2', { - renderer: 'onlyWhenVisibile', - } as any); - const panel3 = new TestPanel('panel3', { - renderer: 'onlyWhenVisibile', - } as any); + const panel1 = new TestPanel('panel1', panelApi); + const panel2 = new TestPanel('panel2', panelApi); + const panel3 = new TestPanel('panel3', panelApi); groupview.model.openPanel(panel1); groupview.model.openPanel(panel2); @@ -608,25 +613,19 @@ describe('dockviewGroupPanelModel', () => { .getElementsByClassName('content-container') .item(0)!.childNodes; - const panel1 = new TestPanel('id_1', { - renderer: 'onlyWhenVisibile', - } as any); + const panel1 = new TestPanel('id_1', panelApi); cut.openPanel(panel1); expect(contentContainer.length).toBe(1); expect(contentContainer.item(0)).toBe(panel1.view.content.element); - const panel2 = new TestPanel('id_2', { - renderer: 'onlyWhenVisibile', - } as any); + const panel2 = new TestPanel('id_2', panelApi); cut.openPanel(panel2); expect(contentContainer.length).toBe(1); expect(contentContainer.item(0)).toBe(panel2.view.content.element); - const panel3 = new TestPanel('id_2', { - renderer: 'onlyWhenVisibile', - } as any); + const panel3 = new TestPanel('id_2', panelApi); cut.openPanel(panel3, { skipSetActive: true }); expect(contentContainer.length).toBe(1); @@ -834,11 +833,7 @@ describe('dockviewGroupPanelModel', () => { new groupPanelMock() as DockviewGroupPanel ); - cut.openPanel( - new TestPanel('panel1', { - renderer: 'onlyWhenVisibile', - } as any) - ); + cut.openPanel(new TestPanel('panel1', panelApi)); const element = container .getElementsByClassName('content-container') @@ -908,16 +903,8 @@ describe('dockviewGroupPanelModel', () => { new groupPanelMock() as DockviewGroupPanel ); - cut.openPanel( - new TestPanel('panel1', { - renderer: 'onlyWhenVisibile', - } as any) - ); - cut.openPanel( - new TestPanel('panel2', { - renderer: 'onlyWhenVisibile', - } as any) - ); + cut.openPanel(new TestPanel('panel1', panelApi)); + cut.openPanel(new TestPanel('panel2', panelApi)); const element = container .getElementsByClassName('content-container') @@ -987,16 +974,8 @@ describe('dockviewGroupPanelModel', () => { new groupPanelMock() as DockviewGroupPanel ); - cut.openPanel( - new TestPanel('panel1', { - renderer: 'onlyWhenVisibile', - } as any) - ); - cut.openPanel( - new TestPanel('panel2', { - renderer: 'onlyWhenVisibile', - } as any) - ); + cut.openPanel(new TestPanel('panel1', panelApi)); + cut.openPanel(new TestPanel('panel2', panelApi)); const element = container .getElementsByClassName('content-container') @@ -1097,11 +1076,7 @@ describe('dockviewGroupPanelModel', () => { container.getElementsByClassName('watermark-test-container').length ).toBe(1); - cut.openPanel( - new TestPanel('panel1', { - renderer: 'onlyWhenVisibile', - } as any) - ); + cut.openPanel(new TestPanel('panel1', panelApi)); expect( container.getElementsByClassName('watermark-test-container').length @@ -1111,11 +1086,7 @@ describe('dockviewGroupPanelModel', () => { .length ).toBe(1); - cut.openPanel( - new TestPanel('panel2', { - renderer: 'onlyWhenVisibile', - } as any) - ); + cut.openPanel(new TestPanel('panel2', panelApi)); expect( container.getElementsByClassName('watermark-test-container').length @@ -1133,11 +1104,7 @@ describe('dockviewGroupPanelModel', () => { container.getElementsByClassName('watermark-test-container').length ).toBe(1); - cut.openPanel( - new TestPanel('panel1', { - renderer: 'onlyWhenVisibile', - } as any) - ); + cut.openPanel(new TestPanel('panel1', panelApi)); expect( container.getElementsByClassName('watermark-test-container').length diff --git a/packages/dockview-core/src/api/dockviewPanelApi.ts b/packages/dockview-core/src/api/dockviewPanelApi.ts index 3bace3792..2acd907dc 100644 --- a/packages/dockview-core/src/api/dockviewPanelApi.ts +++ b/packages/dockview-core/src/api/dockviewPanelApi.ts @@ -37,6 +37,7 @@ export interface DockviewPanelApi readonly title: string | undefined; readonly onDidActiveGroupChange: Event; readonly onDidGroupChange: Event; + readonly onDidTitleChange: Event; readonly onDidRendererChange: Event; readonly location: DockviewGroupLocation; readonly onDidLocationChange: Event; diff --git a/packages/dockview-core/src/api/panelApi.ts b/packages/dockview-core/src/api/panelApi.ts index d604f0122..8d26ebe70 100644 --- a/packages/dockview-core/src/api/panelApi.ts +++ b/packages/dockview-core/src/api/panelApi.ts @@ -29,6 +29,7 @@ export interface PanelApi { readonly onDidVisibilityChange: Event; readonly onDidActiveChange: Event; readonly onDidHiddenChange: Event; + readonly onUpdateParameters: Event; setActive(): void; updateParameters(parameters: Parameters): void; /** @@ -161,7 +162,6 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi { this._onDidActiveChange, this._onWillFocus, this._onActiveChange, - this._onUpdateParameters, this._onWillFocus, this._onDidHiddenChange, this._onUpdateParameters diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 9b33959ab..f89263dfb 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -65,6 +65,7 @@ import { OverlayRenderContainer, } from '../overlayRenderContainer'; import { PopoutWindow } from '../popoutWindow'; +import { TitleEvent } from '../api/dockviewPanelApi'; const DEFAULT_ROOT_OVERLAY_MODEL: DroptargetOverlayModel = { activationSize: { type: 'pixels', value: 10 }, @@ -360,6 +361,14 @@ export class DockviewComponent private readonly _onDidAddPanel = new Emitter(); readonly onDidAddPanel: Event = this._onDidAddPanel.event; + private readonly _onDidPanelTitleChange = new Emitter(); + readonly onDidPanelTitleChange: Event = + this._onDidPanelTitleChange.event; + + private readonly _onDidPanelParametersChange = new Emitter(); + readonly onDidPanelParametersChange: Event = + this._onDidPanelParametersChange.event; + private readonly _onDidLayoutFromJSON = new Emitter(); readonly onDidLayoutFromJSON: Event = this._onDidLayoutFromJSON.event; @@ -486,7 +495,9 @@ export class DockviewComponent Event.any( this.onDidAddPanel, this.onDidRemovePanel, - this.onDidActivePanelChange + this.onDidActivePanelChange, + this.onDidPanelTitleChange, + this.onDidPanelParametersChange )(() => { this._bufferOnDidLayoutChange.fire(); }), @@ -2175,6 +2186,12 @@ export class DockviewComponent if (this._onDidActivePanelChange.value !== event.panel) { this._onDidActivePanelChange.fire(event.panel); } + }), + view.model.onDidPanelTitleChange((event) => { + this._onDidPanelTitleChange.fire(event); + }), + view.model.onDidPanelParametersChange((event) => { + this._onDidPanelParametersChange.fire(event); }) ); diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts index d690d0f4c..7adbdf1df 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts @@ -11,8 +11,13 @@ import { IDockviewEvent, } from '../events'; import { IViewSize } from '../gridview/gridview'; -import { CompositeDisposable } from '../lifecycle'; -import { IPanel, PanelInitParameters, PanelUpdateEvent } from '../panel/types'; +import { CompositeDisposable, IDisposable } from '../lifecycle'; +import { + IPanel, + PanelInitParameters, + PanelUpdateEvent, + Parameters, +} from '../panel/types'; import { ContentContainer, IContentContainer, @@ -28,6 +33,7 @@ import { DockviewGroupPanel } from './dockviewGroupPanel'; import { IDockviewPanel } from './dockviewPanel'; import { IHeaderActionsRenderer } from './options'; import { OverlayRenderContainer } from '../overlayRenderContainer'; +import { TitleEvent } from '../api/dockviewPanelApi'; interface GroupMoveEvent { groupId: string; @@ -233,6 +239,8 @@ export class DockviewGroupPanelModel private _leftHeaderActions: IHeaderActionsRenderer | undefined; private _prefixHeaderActions: IHeaderActionsRenderer | undefined; + private _panelDisposables = new Map(); + private _location: DockviewGroupLocation = { type: 'grid' }; private mostRecentlyUsed: IDockviewPanel[] = []; @@ -271,6 +279,14 @@ export class DockviewGroupPanelModel readonly onDidAddPanel: Event = this._onDidAddPanel.event; + private readonly _onDidPanelTitleChange = new Emitter(); + readonly onDidPanelTitleChange: Event = + this._onDidPanelTitleChange.event; + + private readonly _onDidPanelParametersChange = new Emitter(); + readonly onDidPanelParametersChange: Event = + this._onDidPanelParametersChange.event; + private readonly _onDidRemovePanel = new Emitter(); readonly onDidRemovePanel: Event = @@ -826,6 +842,12 @@ export class DockviewGroupPanelModel ); } + const panelDisposables = this._panelDisposables.get(panel.id); + + this._panelDisposables.delete(panel.id); + + panelDisposables?.forEach(({ dispose }) => dispose()); + this._onDidRemovePanel.fire({ panel }); } @@ -856,6 +878,15 @@ export class DockviewGroupPanelModel this.updateMru(panel); this.panels.splice(index, 0, panel); + this._panelDisposables.set(panel.id, [ + panel.api.onDidTitleChange((event) => + this._onDidPanelTitleChange.fire(event) + ), + panel.api.onUpdateParameters((event) => + this._onDidPanelParametersChange.fire(event) + ), + ]); + this._onDidAddPanel.fire({ panel }); } From c55c3e4a2fa79ec85551610a9f9274378957c7a3 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Mon, 11 Mar 2024 20:20:19 +0000 Subject: [PATCH 2/2] feat: title and parameter events --- .../dockview/dockviewComponent.spec.ts | 16 ---------- .../dockview/dockviewGroupPanelModel.spec.ts | 8 ++--- packages/dockview-core/src/api/panelApi.ts | 23 ++++++++----- .../src/dockview/dockviewComponent.ts | 22 ++++--------- .../src/dockview/dockviewGroupPanelModel.ts | 32 ++++++++++--------- 5 files changed, 42 insertions(+), 59 deletions(-) diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts index a52b16088..1ec04ab90 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewComponent.spec.ts @@ -4628,12 +4628,6 @@ describe('dockviewComponent', () => { }); test('that emits onDidPanelTitleChange and onDidLayoutChange when the panel set a title', () => { - const container = document.createElement('div'); - - const didPanelTitleChangeHandler = jest.fn(); - const { dispose: disposeDidPanelTitleChangeHandler } = - dockview.onDidPanelTitleChange(didPanelTitleChangeHandler); - const didLayoutChangeHandler = jest.fn(); const { dispose: disposeDidLayoutChangeHandler } = dockview.onDidLayoutChange(didLayoutChangeHandler); @@ -4642,20 +4636,12 @@ describe('dockviewComponent', () => { jest.runAllTimers(); - expect(didPanelTitleChangeHandler).toHaveBeenCalledTimes(1); expect(didLayoutChangeHandler).toHaveBeenCalledTimes(1); - disposeDidPanelTitleChangeHandler(); disposeDidLayoutChangeHandler(); }); test('that emits onDidPanelParametersChange and onDidLayoutChange when the panel updates parameters', () => { - const didPanelParametersChangeHandler = jest.fn(); - const { dispose: disposeDidPanelParametersChangeHandler } = - dockview.onDidPanelParametersChange( - didPanelParametersChangeHandler - ); - const didLayoutChangeHandler = jest.fn(); const { dispose: disposeDidLayoutChangeHandler } = dockview.onDidLayoutChange(didLayoutChangeHandler); @@ -4664,10 +4650,8 @@ describe('dockviewComponent', () => { jest.runAllTimers(); - expect(didPanelParametersChangeHandler).toHaveBeenCalledTimes(1); expect(didLayoutChangeHandler).toHaveBeenCalledTimes(1); - disposeDidPanelParametersChangeHandler(); disposeDidLayoutChangeHandler(); }); }); diff --git a/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts b/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts index 31f710d03..939380ec6 100644 --- a/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts +++ b/packages/dockview-core/src/__tests__/dockview/dockviewGroupPanelModel.spec.ts @@ -38,11 +38,11 @@ import { FocusEvent, VisibilityEvent, ActiveEvent, - HiddenEvent, WillFocusEvent, } from '../../api/panelApi'; import { Position } from '../../dnd/droptarget'; import { Emitter, Event } from '../../events'; +import { fromPartial } from '@total-typescript/shoehorn'; enum GroupChangeKind2 { ADD_PANEL, @@ -269,11 +269,11 @@ describe('dockviewGroupPanelModel', () => { options = {}; - panelApi = { + panelApi = fromPartial({ renderer: 'onlyWhenVisibile', onDidTitleChange: new Emitter().event, - onUpdateParameters: new Emitter().event, - } as DockviewPanelApi; + onDidParametersChange: new Emitter().event, + }); dockview = (>{ options: { parentElement: document.createElement('div') }, diff --git a/packages/dockview-core/src/api/panelApi.ts b/packages/dockview-core/src/api/panelApi.ts index 989931e00..ad332613a 100644 --- a/packages/dockview-core/src/api/panelApi.ts +++ b/packages/dockview-core/src/api/panelApi.ts @@ -24,8 +24,7 @@ export interface PanelApi { readonly onDidFocusChange: Event; readonly onDidVisibilityChange: Event; readonly onDidActiveChange: Event; - readonly onDidHiddenChange: Event; - readonly onUpdateParameters: Event; + readonly onDidParametersChange: Event; setActive(): void; setVisible(isVisible: boolean): void; updateParameters(parameters: Parameters): void; @@ -55,6 +54,8 @@ export interface PanelApi { readonly height: number; readonly onWillFocus: Event; + + getParameters(): T; } export class WillFocusEvent extends DockviewEvent { @@ -72,6 +73,7 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi { private _isVisible = true; private _width = 0; private _height = 0; + private _parameters: Parameters = {}; private readonly panelUpdatesDisposable = new MutableDisposable(); @@ -99,9 +101,9 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi { readonly _onActiveChange = new Emitter(); readonly onActiveChange: Event = this._onActiveChange.event; - readonly _onUpdateParameters = new Emitter(); - readonly onUpdateParameters: Event = - this._onUpdateParameters.event; + readonly _onDidParametersChange = new Emitter(); + readonly onDidParametersChange: Event = + this._onDidParametersChange.event; get isFocused(): boolean { return this._isFocused; @@ -149,13 +151,18 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi { this._onActiveChange, this._onWillFocus, this._onWillVisibilityChange, - this._onUpdateParameters + this._onDidParametersChange ); } + getParameters(): T { + return this._parameters as T; + } + public initialize(panel: IPanel): void { - this.panelUpdatesDisposable.value = this._onUpdateParameters.event( + this.panelUpdatesDisposable.value = this._onDidParametersChange.event( (parameters) => { + this._parameters = parameters; panel.update({ params: parameters, }); @@ -172,6 +179,6 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi { } updateParameters(parameters: Parameters): void { - this._onUpdateParameters.fire(parameters); + this._onDidParametersChange.fire(parameters); } } diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index a0318a1cd..220a5ad1c 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -361,14 +361,6 @@ export class DockviewComponent private readonly _onDidAddPanel = new Emitter(); readonly onDidAddPanel: Event = this._onDidAddPanel.event; - private readonly _onDidPanelTitleChange = new Emitter(); - readonly onDidPanelTitleChange: Event = - this._onDidPanelTitleChange.event; - - private readonly _onDidPanelParametersChange = new Emitter(); - readonly onDidPanelParametersChange: Event = - this._onDidPanelParametersChange.event; - private readonly _onDidLayoutFromJSON = new Emitter(); readonly onDidLayoutFromJSON: Event = this._onDidLayoutFromJSON.event; @@ -495,9 +487,7 @@ export class DockviewComponent Event.any( this.onDidAddPanel, this.onDidRemovePanel, - this.onDidActivePanelChange, - this.onDidPanelTitleChange, - this.onDidPanelParametersChange + this.onDidActivePanelChange )(() => { this._bufferOnDidLayoutChange.fire(); }), @@ -2187,11 +2177,11 @@ export class DockviewComponent this._onDidActivePanelChange.fire(event.panel); } }), - view.model.onDidPanelTitleChange((event) => { - this._onDidPanelTitleChange.fire(event); - }), - view.model.onDidPanelParametersChange((event) => { - this._onDidPanelParametersChange.fire(event); + Event.any( + view.model.onDidPanelTitleChange, + view.model.onDidPanelParametersChange + )(() => { + this._bufferOnDidLayoutChange.fire(); }) ); diff --git a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts index 7adbdf1df..e1989dd68 100644 --- a/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts +++ b/packages/dockview-core/src/dockview/dockviewGroupPanelModel.ts @@ -239,8 +239,6 @@ export class DockviewGroupPanelModel private _leftHeaderActions: IHeaderActionsRenderer | undefined; private _prefixHeaderActions: IHeaderActionsRenderer | undefined; - private _panelDisposables = new Map(); - private _location: DockviewGroupLocation = { type: 'grid' }; private mostRecentlyUsed: IDockviewPanel[] = []; @@ -253,6 +251,7 @@ export class DockviewGroupPanelModel private _height = 0; private _panels: IDockviewPanel[] = []; + private readonly _panelDisposables = new Map(); private readonly _onMove = new Emitter(); readonly onMove: Event = this._onMove.event; @@ -842,11 +841,11 @@ export class DockviewGroupPanelModel ); } - const panelDisposables = this._panelDisposables.get(panel.id); - - this._panelDisposables.delete(panel.id); - - panelDisposables?.forEach(({ dispose }) => dispose()); + const disposable = this._panelDisposables.get(panel.id); + if (disposable) { + disposable.dispose(); + this._panelDisposables.delete(panel.id); + } this._onDidRemovePanel.fire({ panel }); } @@ -878,14 +877,17 @@ export class DockviewGroupPanelModel this.updateMru(panel); this.panels.splice(index, 0, panel); - this._panelDisposables.set(panel.id, [ - panel.api.onDidTitleChange((event) => - this._onDidPanelTitleChange.fire(event) - ), - panel.api.onUpdateParameters((event) => - this._onDidPanelParametersChange.fire(event) - ), - ]); + this._panelDisposables.set( + panel.id, + new CompositeDisposable( + panel.api.onDidTitleChange((event) => + this._onDidPanelTitleChange.fire(event) + ), + panel.api.onDidParametersChange((event) => + this._onDidPanelParametersChange.fire(event) + ) + ) + ); this._onDidAddPanel.fire({ panel }); }