This commit is contained in:
mathuo 2024-03-11 21:35:58 +00:00
commit 5bd1f1e1c6
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
18 changed files with 285 additions and 133 deletions

View File

@ -5,7 +5,7 @@ describe('api', () => {
let api: PanelApiImpl; let api: PanelApiImpl;
beforeEach(() => { beforeEach(() => {
api = new PanelApiImpl('dummy_id'); api = new PanelApiImpl('dummy_id', 'fake-component');
}); });
test('updateParameters', () => { test('updateParameters', () => {

View File

@ -31,7 +31,8 @@ describe('groupPanelApi', () => {
const cut = new DockviewPanelApiImpl( const cut = new DockviewPanelApiImpl(
panel, panel,
group, group,
<DockviewComponent>accessor <DockviewComponent>accessor,
'fake-component'
); );
cut.setTitle('test_title'); cut.setTitle('test_title');
@ -59,7 +60,8 @@ describe('groupPanelApi', () => {
const cut = new DockviewPanelApiImpl( const cut = new DockviewPanelApiImpl(
<DockviewPanel>groupPanel, <DockviewPanel>groupPanel,
<DockviewGroupPanel>groupViewPanel, <DockviewGroupPanel>groupViewPanel,
<DockviewComponent>accessor <DockviewComponent>accessor,
'fake-component'
); );
cut.updateParameters({ keyA: 'valueA' }); cut.updateParameters({ keyA: 'valueA' });
@ -89,7 +91,8 @@ describe('groupPanelApi', () => {
const cut = new DockviewPanelApiImpl( const cut = new DockviewPanelApiImpl(
<DockviewPanel>groupPanel, <DockviewPanel>groupPanel,
<DockviewGroupPanel>groupViewPanel, <DockviewGroupPanel>groupViewPanel,
<DockviewComponent>accessor <DockviewComponent>accessor,
'fake-component'
); );
let events = 0; let events = 0;

View File

@ -8,7 +8,7 @@ import { PanelUpdateEvent } from '../../panel/types';
import { Orientation } from '../../splitview/splitview'; import { Orientation } from '../../splitview/splitview';
import { CompositeDisposable } from '../../lifecycle'; import { CompositeDisposable } from '../../lifecycle';
import { Emitter } from '../../events'; import { Emitter } from '../../events';
import { IDockviewPanel } from '../../dockview/dockviewPanel'; import { DockviewPanel, IDockviewPanel } from '../../dockview/dockviewPanel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel'; import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import { fireEvent } from '@testing-library/dom'; import { fireEvent } from '@testing-library/dom';
import { getPanelData } from '../../dnd/dataTransfer'; import { getPanelData } from '../../dnd/dataTransfer';
@ -4598,6 +4598,64 @@ describe('dockviewComponent', () => {
}); });
}); });
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 didLayoutChangeHandler = jest.fn();
const { dispose: disposeDidLayoutChangeHandler } =
dockview.onDidLayoutChange(didLayoutChangeHandler);
panel1.setTitle('new title');
jest.runAllTimers();
expect(didLayoutChangeHandler).toHaveBeenCalledTimes(1);
disposeDidLayoutChangeHandler();
});
test('that emits onDidPanelParametersChange and onDidLayoutChange when the panel updates parameters', () => {
const didLayoutChangeHandler = jest.fn();
const { dispose: disposeDidLayoutChangeHandler } =
dockview.onDidLayoutChange(didLayoutChangeHandler);
panel1.api.updateParameters({ keyA: 'valueA' });
jest.runAllTimers();
expect(didLayoutChangeHandler).toHaveBeenCalledTimes(1);
disposeDidLayoutChangeHandler();
});
});
test('that setVisible toggles visiblity', () => { test('that setVisible toggles visiblity', () => {
const container = document.createElement('div'); const container = document.createElement('div');

View File

@ -9,19 +9,40 @@ import {
} from '../../dockview/types'; } from '../../dockview/types';
import { PanelUpdateEvent, Parameters } from '../../panel/types'; import { PanelUpdateEvent, Parameters } from '../../panel/types';
import { import {
DockviewGroupLocation,
DockviewGroupPanelModel, DockviewGroupPanelModel,
GroupOptions, GroupOptions,
} from '../../dockview/dockviewGroupPanelModel'; } from '../../dockview/dockviewGroupPanelModel';
import { fireEvent } from '@testing-library/dom'; import { fireEvent } from '@testing-library/dom';
import { LocalSelectionTransfer, PanelTransfer } from '../../dnd/dataTransfer'; import { LocalSelectionTransfer, PanelTransfer } from '../../dnd/dataTransfer';
import { CompositeDisposable } from '../../lifecycle'; import { CompositeDisposable } from '../../lifecycle';
import { DockviewPanelApi } from '../../api/dockviewPanelApi'; import {
ActiveGroupEvent,
DockviewPanelApi,
GroupChangedEvent,
RendererChangedEvent,
} from '../../api/dockviewPanelApi';
import { IDockviewPanel } from '../../dockview/dockviewPanel'; import { IDockviewPanel } from '../../dockview/dockviewPanel';
import { IDockviewPanelModel } from '../../dockview/dockviewPanelModel'; import { IDockviewPanelModel } from '../../dockview/dockviewPanelModel';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel'; import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import { WatermarkRendererInitParameters } from '../../dockview/types'; import { WatermarkRendererInitParameters } from '../../dockview/types';
import { createOffsetDragOverEvent } from '../__test_utils__/utils'; 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,
WillFocusEvent,
} from '../../api/panelApi';
import { Position } from '../../dnd/droptarget';
import { Emitter, Event } from '../../events';
import { fromPartial } from '@total-typescript/shoehorn';
enum GroupChangeKind2 { enum GroupChangeKind2 {
ADD_PANEL, ADD_PANEL,
@ -240,12 +261,20 @@ describe('dockviewGroupPanelModel', () => {
let removePanelMock: jest.Mock; let removePanelMock: jest.Mock;
let removeGroupMock: jest.Mock; let removeGroupMock: jest.Mock;
let panelApi: DockviewPanelApi;
beforeEach(() => { beforeEach(() => {
removePanelMock = jest.fn(); removePanelMock = jest.fn();
removeGroupMock = jest.fn(); removeGroupMock = jest.fn();
options = {}; options = {};
panelApi = fromPartial<DockviewPanelApi>({
renderer: 'onlyWhenVisibile',
onDidTitleChange: new Emitter().event,
onDidParametersChange: new Emitter().event,
});
dockview = (<Partial<DockviewComponent>>{ dockview = (<Partial<DockviewComponent>>{
options: { parentElement: document.createElement('div') }, options: { parentElement: document.createElement('div') },
createWatermarkComponent: () => new Watermark(), createWatermarkComponent: () => new Watermark(),
@ -265,15 +294,9 @@ describe('dockviewGroupPanelModel', () => {
}); });
test('panel events are captured during de-serialization', () => { test('panel events are captured during de-serialization', () => {
const panel1 = new TestPanel('panel1', { const panel1 = new TestPanel('panel1', panelApi);
renderer: 'onlyWhenVisibile', const panel2 = new TestPanel('panel2', panelApi);
} as any); const panel3 = new TestPanel('panel3', panelApi);
const panel2 = new TestPanel('panel2', {
renderer: 'onlyWhenVisibile',
} as any);
const panel3 = new TestPanel('panel3', {
renderer: 'onlyWhenVisibile',
} as any);
const groupview2 = new DockviewGroupPanel(dockview, 'groupview-2', { const groupview2 = new DockviewGroupPanel(dockview, 'groupview-2', {
panels: [panel1, panel2, panel3], panels: [panel1, panel2, panel3],
@ -357,15 +380,9 @@ describe('dockviewGroupPanelModel', () => {
}) })
); );
const panel1 = new TestPanel('panel1', { const panel1 = new TestPanel('panel1', panelApi);
renderer: 'onlyWhenVisibile', const panel2 = new TestPanel('panel2', panelApi);
} as any); const panel3 = new TestPanel('panel3', panelApi);
const panel2 = new TestPanel('panel2', {
renderer: 'onlyWhenVisibile',
} as any);
const panel3 = new TestPanel('panel3', {
renderer: 'onlyWhenVisibile',
} as any);
expect(events.length).toBe(0); expect(events.length).toBe(0);
@ -443,15 +460,9 @@ describe('dockviewGroupPanelModel', () => {
}); });
test('moveToPrevious and moveToNext', () => { test('moveToPrevious and moveToNext', () => {
const panel1 = new TestPanel('panel1', { const panel1 = new TestPanel('panel1', panelApi);
renderer: 'onlyWhenVisibile', const panel2 = new TestPanel('panel2', panelApi);
} as any); const panel3 = new TestPanel('panel3', panelApi);
const panel2 = new TestPanel('panel2', {
renderer: 'onlyWhenVisibile',
} as any);
const panel3 = new TestPanel('panel3', {
renderer: 'onlyWhenVisibile',
} as any);
groupview.model.openPanel(panel1); groupview.model.openPanel(panel1);
groupview.model.openPanel(panel2); groupview.model.openPanel(panel2);
@ -495,15 +506,9 @@ describe('dockviewGroupPanelModel', () => {
}); });
test('closeAllPanels with panels', () => { test('closeAllPanels with panels', () => {
const panel1 = new TestPanel('panel1', { const panel1 = new TestPanel('panel1', panelApi);
renderer: 'onlyWhenVisibile', const panel2 = new TestPanel('panel2', panelApi);
} as any); const panel3 = new TestPanel('panel3', panelApi);
const panel2 = new TestPanel('panel2', {
renderer: 'onlyWhenVisibile',
} as any);
const panel3 = new TestPanel('panel3', {
renderer: 'onlyWhenVisibile',
} as any);
groupview.model.openPanel(panel1); groupview.model.openPanel(panel1);
groupview.model.openPanel(panel2); groupview.model.openPanel(panel2);
@ -608,25 +613,19 @@ describe('dockviewGroupPanelModel', () => {
.getElementsByClassName('content-container') .getElementsByClassName('content-container')
.item(0)!.childNodes; .item(0)!.childNodes;
const panel1 = new TestPanel('id_1', { const panel1 = new TestPanel('id_1', panelApi);
renderer: 'onlyWhenVisibile',
} as any);
cut.openPanel(panel1); cut.openPanel(panel1);
expect(contentContainer.length).toBe(1); expect(contentContainer.length).toBe(1);
expect(contentContainer.item(0)).toBe(panel1.view.content.element); expect(contentContainer.item(0)).toBe(panel1.view.content.element);
const panel2 = new TestPanel('id_2', { const panel2 = new TestPanel('id_2', panelApi);
renderer: 'onlyWhenVisibile',
} as any);
cut.openPanel(panel2); cut.openPanel(panel2);
expect(contentContainer.length).toBe(1); expect(contentContainer.length).toBe(1);
expect(contentContainer.item(0)).toBe(panel2.view.content.element); expect(contentContainer.item(0)).toBe(panel2.view.content.element);
const panel3 = new TestPanel('id_2', { const panel3 = new TestPanel('id_2', panelApi);
renderer: 'onlyWhenVisibile',
} as any);
cut.openPanel(panel3, { skipSetActive: true }); cut.openPanel(panel3, { skipSetActive: true });
expect(contentContainer.length).toBe(1); expect(contentContainer.length).toBe(1);
@ -834,11 +833,7 @@ describe('dockviewGroupPanelModel', () => {
new groupPanelMock() as DockviewGroupPanel new groupPanelMock() as DockviewGroupPanel
); );
cut.openPanel( cut.openPanel(new TestPanel('panel1', panelApi));
new TestPanel('panel1', {
renderer: 'onlyWhenVisibile',
} as any)
);
const element = container const element = container
.getElementsByClassName('content-container') .getElementsByClassName('content-container')
@ -908,16 +903,8 @@ describe('dockviewGroupPanelModel', () => {
new groupPanelMock() as DockviewGroupPanel new groupPanelMock() as DockviewGroupPanel
); );
cut.openPanel( cut.openPanel(new TestPanel('panel1', panelApi));
new TestPanel('panel1', { cut.openPanel(new TestPanel('panel2', panelApi));
renderer: 'onlyWhenVisibile',
} as any)
);
cut.openPanel(
new TestPanel('panel2', {
renderer: 'onlyWhenVisibile',
} as any)
);
const element = container const element = container
.getElementsByClassName('content-container') .getElementsByClassName('content-container')
@ -987,16 +974,8 @@ describe('dockviewGroupPanelModel', () => {
new groupPanelMock() as DockviewGroupPanel new groupPanelMock() as DockviewGroupPanel
); );
cut.openPanel( cut.openPanel(new TestPanel('panel1', panelApi));
new TestPanel('panel1', { cut.openPanel(new TestPanel('panel2', panelApi));
renderer: 'onlyWhenVisibile',
} as any)
);
cut.openPanel(
new TestPanel('panel2', {
renderer: 'onlyWhenVisibile',
} as any)
);
const element = container const element = container
.getElementsByClassName('content-container') .getElementsByClassName('content-container')
@ -1097,11 +1076,7 @@ describe('dockviewGroupPanelModel', () => {
container.getElementsByClassName('watermark-test-container').length container.getElementsByClassName('watermark-test-container').length
).toBe(1); ).toBe(1);
cut.openPanel( cut.openPanel(new TestPanel('panel1', panelApi));
new TestPanel('panel1', {
renderer: 'onlyWhenVisibile',
} as any)
);
expect( expect(
container.getElementsByClassName('watermark-test-container').length container.getElementsByClassName('watermark-test-container').length
@ -1111,11 +1086,7 @@ describe('dockviewGroupPanelModel', () => {
.length .length
).toBe(1); ).toBe(1);
cut.openPanel( cut.openPanel(new TestPanel('panel2', panelApi));
new TestPanel('panel2', {
renderer: 'onlyWhenVisibile',
} as any)
);
expect( expect(
container.getElementsByClassName('watermark-test-container').length container.getElementsByClassName('watermark-test-container').length
@ -1133,11 +1104,7 @@ describe('dockviewGroupPanelModel', () => {
container.getElementsByClassName('watermark-test-container').length container.getElementsByClassName('watermark-test-container').length
).toBe(1); ).toBe(1);
cut.openPanel( cut.openPanel(new TestPanel('panel1', panelApi));
new TestPanel('panel1', {
renderer: 'onlyWhenVisibile',
} as any)
);
expect( expect(
container.getElementsByClassName('watermark-test-container').length container.getElementsByClassName('watermark-test-container').length

View File

@ -34,9 +34,18 @@ describe('dockviewPanel', () => {
}); });
const model = <IDockviewPanelModel>new panelModelMock(); const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, { const cut = new DockviewPanel(
renderer: 'onlyWhenVisibile', 'fake-id',
}); 'fake-component',
undefined,
accessor,
api,
group,
model,
{
renderer: 'onlyWhenVisibile',
}
);
let latestTitle: string | undefined = undefined; let latestTitle: string | undefined = undefined;
@ -84,9 +93,18 @@ describe('dockviewPanel', () => {
}); });
const model = <IDockviewPanelModel>new panelModelMock(); const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, { const cut = new DockviewPanel(
renderer: 'onlyWhenVisibile', 'fake-id',
}); 'fake-component',
undefined,
accessor,
api,
group,
model,
{
renderer: 'onlyWhenVisibile',
}
);
cut.init({ title: 'myTitle', params: {} }); cut.init({ title: 'myTitle', params: {} });
expect(cut.title).toBe('myTitle'); expect(cut.title).toBe('myTitle');
@ -130,9 +148,18 @@ describe('dockviewPanel', () => {
}); });
const model = <IDockviewPanelModel>new panelModelMock(); const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, { const cut = new DockviewPanel(
renderer: 'onlyWhenVisibile', 'fake-id',
}); 'fake-component',
undefined,
accessor,
api,
group,
model,
{
renderer: 'onlyWhenVisibile',
}
);
cut.init({ params: {}, title: 'title' }); cut.init({ params: {}, title: 'title' });
@ -167,9 +194,18 @@ describe('dockviewPanel', () => {
}); });
const model = <IDockviewPanelModel>new panelModelMock(); const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, { const cut = new DockviewPanel(
renderer: 'onlyWhenVisibile', 'fake-id',
}); 'fake-component',
undefined,
accessor,
api,
group,
model,
{
renderer: 'onlyWhenVisibile',
}
);
expect(cut.params).toEqual(undefined); expect(cut.params).toEqual(undefined);
@ -205,9 +241,18 @@ describe('dockviewPanel', () => {
}); });
const model = <IDockviewPanelModel>new panelModelMock(); const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, { const cut = new DockviewPanel(
renderer: 'onlyWhenVisibile', 'fake-id',
}); 'fake-component',
undefined,
accessor,
api,
group,
model,
{
renderer: 'onlyWhenVisibile',
}
);
cut.api.setSize({ height: 123, width: 456 }); cut.api.setSize({ height: 123, width: 456 });
@ -241,9 +286,18 @@ describe('dockviewPanel', () => {
}); });
const model = <IDockviewPanelModel>new panelModelMock(); const model = <IDockviewPanelModel>new panelModelMock();
const cut = new DockviewPanel('fake-id', accessor, api, group, model, { const cut = new DockviewPanel(
renderer: 'onlyWhenVisibile', 'fake-id',
}); 'fake-component',
undefined,
accessor,
api,
group,
model,
{
renderer: 'onlyWhenVisibile',
}
);
cut.init({ params: { a: '1', b: '2' }, title: 'A title' }); cut.init({ params: { a: '1', b: '2' }, title: 'A title' });
expect(cut.params).toEqual({ a: '1', b: '2' }); expect(cut.params).toEqual({ a: '1', b: '2' });

View File

@ -42,7 +42,7 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl {
} }
constructor(id: string, private readonly accessor: DockviewComponent) { constructor(id: string, private readonly accessor: DockviewComponent) {
super(id); super(id, '__dockviewgroup__');
this.addDisposables(this._onDidLocationChange); this.addDisposables(this._onDidLocationChange);
} }

View File

@ -37,6 +37,7 @@ export interface DockviewPanelApi
readonly title: string | undefined; readonly title: string | undefined;
readonly onDidActiveGroupChange: Event<ActiveGroupEvent>; readonly onDidActiveGroupChange: Event<ActiveGroupEvent>;
readonly onDidGroupChange: Event<GroupChangedEvent>; readonly onDidGroupChange: Event<GroupChangedEvent>;
readonly onDidTitleChange: Event<TitleEvent>;
readonly onDidRendererChange: Event<RendererChangedEvent>; readonly onDidRendererChange: Event<RendererChangedEvent>;
readonly location: DockviewGroupLocation; readonly location: DockviewGroupLocation;
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>; readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>;
@ -62,6 +63,7 @@ export class DockviewPanelApiImpl
implements DockviewPanelApi implements DockviewPanelApi
{ {
private _group: DockviewGroupPanel; private _group: DockviewGroupPanel;
private _tabComponent: string | undefined;
readonly _onDidTitleChange = new Emitter<TitleEvent>(); readonly _onDidTitleChange = new Emitter<TitleEvent>();
readonly onDidTitleChange = this._onDidTitleChange.event; readonly onDidTitleChange = this._onDidTitleChange.event;
@ -118,12 +120,20 @@ export class DockviewPanelApiImpl
return this._group; return this._group;
} }
get tabComponent(): string | undefined {
return this._tabComponent;
}
constructor( constructor(
private panel: DockviewPanel, private panel: DockviewPanel,
group: DockviewGroupPanel, group: DockviewGroupPanel,
private readonly accessor: DockviewComponent private readonly accessor: DockviewComponent,
component: string,
tabComponent?: string
) { ) {
super(panel.id); super(panel.id, component);
this._tabComponent = tabComponent;
this.initialize(panel); this.initialize(panel);

View File

@ -44,8 +44,8 @@ export class GridviewPanelApiImpl
private readonly _onDidSizeChange = new Emitter<SizeEvent>(); private readonly _onDidSizeChange = new Emitter<SizeEvent>();
readonly onDidSizeChange: Event<SizeEvent> = this._onDidSizeChange.event; readonly onDidSizeChange: Event<SizeEvent> = this._onDidSizeChange.event;
constructor(id: string, panel?: IPanel) { constructor(id: string, component: string, panel?: IPanel) {
super(id); super(id, component);
this.addDisposables( this.addDisposables(
this._onDidConstraintsChangeInternal, this._onDidConstraintsChangeInternal,

View File

@ -24,6 +24,7 @@ export interface PanelApi {
readonly onDidFocusChange: Event<FocusEvent>; readonly onDidFocusChange: Event<FocusEvent>;
readonly onDidVisibilityChange: Event<VisibilityEvent>; readonly onDidVisibilityChange: Event<VisibilityEvent>;
readonly onDidActiveChange: Event<ActiveEvent>; readonly onDidActiveChange: Event<ActiveEvent>;
readonly onDidParametersChange: Event<Parameters>;
setActive(): void; setActive(): void;
setVisible(isVisible: boolean): void; setVisible(isVisible: boolean): void;
updateParameters(parameters: Parameters): void; updateParameters(parameters: Parameters): void;
@ -53,6 +54,8 @@ export interface PanelApi {
readonly height: number; readonly height: number;
readonly onWillFocus: Event<WillFocusEvent>; readonly onWillFocus: Event<WillFocusEvent>;
getParameters<T extends Parameters = Parameters>(): T;
} }
export class WillFocusEvent extends DockviewEvent { export class WillFocusEvent extends DockviewEvent {
@ -70,6 +73,7 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
private _isVisible = true; private _isVisible = true;
private _width = 0; private _width = 0;
private _height = 0; private _height = 0;
private _parameters: Parameters = {};
private readonly panelUpdatesDisposable = new MutableDisposable(); private readonly panelUpdatesDisposable = new MutableDisposable();
@ -97,9 +101,9 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
readonly _onActiveChange = new Emitter<void>(); readonly _onActiveChange = new Emitter<void>();
readonly onActiveChange: Event<void> = this._onActiveChange.event; readonly onActiveChange: Event<void> = this._onActiveChange.event;
readonly _onUpdateParameters = new Emitter<Parameters>(); readonly _onDidParametersChange = new Emitter<Parameters>();
readonly onUpdateParameters: Event<Parameters> = readonly onDidParametersChange: Event<Parameters> =
this._onUpdateParameters.event; this._onDidParametersChange.event;
get isFocused(): boolean { get isFocused(): boolean {
return this._isFocused; return this._isFocused;
@ -121,7 +125,7 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
return this._height; return this._height;
} }
constructor(readonly id: string) { constructor(readonly id: string, readonly component: string) {
super(); super();
this.addDisposables( this.addDisposables(
@ -145,16 +149,20 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
this._onDidActiveChange, this._onDidActiveChange,
this._onWillFocus, this._onWillFocus,
this._onActiveChange, this._onActiveChange,
this._onUpdateParameters,
this._onWillFocus, this._onWillFocus,
this._onWillVisibilityChange, this._onWillVisibilityChange,
this._onUpdateParameters this._onDidParametersChange
); );
} }
getParameters<T extends Parameters = Parameters>(): T {
return this._parameters as T;
}
public initialize(panel: IPanel): void { public initialize(panel: IPanel): void {
this.panelUpdatesDisposable.value = this._onUpdateParameters.event( this.panelUpdatesDisposable.value = this._onDidParametersChange.event(
(parameters) => { (parameters) => {
this._parameters = parameters;
panel.update({ panel.update({
params: parameters, params: parameters,
}); });
@ -171,6 +179,6 @@ export class PanelApiImpl extends CompositeDisposable implements PanelApi {
} }
updateParameters(parameters: Parameters): void { updateParameters(parameters: Parameters): void {
this._onUpdateParameters.fire(parameters); this._onDidParametersChange.fire(parameters);
} }
} }

View File

@ -35,8 +35,8 @@ export class PaneviewPanelApiImpl
this._pane = pane; this._pane = pane;
} }
constructor(id: string) { constructor(id: string, component: string) {
super(id); super(id, component);
this.addDisposables( this.addDisposables(
this._onDidExpansionChange, this._onDidExpansionChange,

View File

@ -45,8 +45,8 @@ export class SplitviewPanelApiImpl
this._onDidSizeChange.event; this._onDidSizeChange.event;
// //
constructor(id: string) { constructor(id: string, component: string) {
super(id); super(id, component);
this.addDisposables( this.addDisposables(
this._onDidConstraintsChangeInternal, this._onDidConstraintsChangeInternal,

View File

@ -49,6 +49,8 @@ export class DefaultDockviewDeserialzier implements IPanelDeserializer {
const panel = new DockviewPanel( const panel = new DockviewPanel(
panelId, panelId,
contentComponent,
tabComponent,
this.accessor, this.accessor,
new DockviewApi(this.accessor), new DockviewApi(this.accessor),
group, group,

View File

@ -65,6 +65,7 @@ import {
OverlayRenderContainer, OverlayRenderContainer,
} from '../overlayRenderContainer'; } from '../overlayRenderContainer';
import { PopoutWindow } from '../popoutWindow'; import { PopoutWindow } from '../popoutWindow';
import { TitleEvent } from '../api/dockviewPanelApi';
const DEFAULT_ROOT_OVERLAY_MODEL: DroptargetOverlayModel = { const DEFAULT_ROOT_OVERLAY_MODEL: DroptargetOverlayModel = {
activationSize: { type: 'pixels', value: 10 }, activationSize: { type: 'pixels', value: 10 },
@ -2175,6 +2176,12 @@ export class DockviewComponent
if (this._onDidActivePanelChange.value !== event.panel) { if (this._onDidActivePanelChange.value !== event.panel) {
this._onDidActivePanelChange.fire(event.panel); this._onDidActivePanelChange.fire(event.panel);
} }
}),
Event.any(
view.model.onDidPanelTitleChange,
view.model.onDidPanelParametersChange
)(() => {
this._bufferOnDidLayoutChange.fire();
}) })
); );
@ -2204,6 +2211,8 @@ export class DockviewComponent
const panel = new DockviewPanel( const panel = new DockviewPanel(
options.id, options.id,
contentComponent,
tabComponent,
this, this,
this._api, this._api,
group, group,

View File

@ -11,8 +11,13 @@ import {
IDockviewEvent, IDockviewEvent,
} from '../events'; } from '../events';
import { IViewSize } from '../gridview/gridview'; import { IViewSize } from '../gridview/gridview';
import { CompositeDisposable } from '../lifecycle'; import { CompositeDisposable, IDisposable } from '../lifecycle';
import { IPanel, PanelInitParameters, PanelUpdateEvent } from '../panel/types'; import {
IPanel,
PanelInitParameters,
PanelUpdateEvent,
Parameters,
} from '../panel/types';
import { import {
ContentContainer, ContentContainer,
IContentContainer, IContentContainer,
@ -28,6 +33,7 @@ import { DockviewGroupPanel } from './dockviewGroupPanel';
import { IDockviewPanel } from './dockviewPanel'; import { IDockviewPanel } from './dockviewPanel';
import { IHeaderActionsRenderer } from './options'; import { IHeaderActionsRenderer } from './options';
import { OverlayRenderContainer } from '../overlayRenderContainer'; import { OverlayRenderContainer } from '../overlayRenderContainer';
import { TitleEvent } from '../api/dockviewPanelApi';
interface GroupMoveEvent { interface GroupMoveEvent {
groupId: string; groupId: string;
@ -245,6 +251,7 @@ export class DockviewGroupPanelModel
private _height = 0; private _height = 0;
private _panels: IDockviewPanel[] = []; private _panels: IDockviewPanel[] = [];
private readonly _panelDisposables = new Map<string, IDisposable>();
private readonly _onMove = new Emitter<GroupMoveEvent>(); private readonly _onMove = new Emitter<GroupMoveEvent>();
readonly onMove: Event<GroupMoveEvent> = this._onMove.event; readonly onMove: Event<GroupMoveEvent> = this._onMove.event;
@ -271,6 +278,14 @@ export class DockviewGroupPanelModel
readonly onDidAddPanel: Event<DockviewGroupChangeEvent> = readonly onDidAddPanel: Event<DockviewGroupChangeEvent> =
this._onDidAddPanel.event; this._onDidAddPanel.event;
private readonly _onDidPanelTitleChange = new Emitter<TitleEvent>();
readonly onDidPanelTitleChange: Event<TitleEvent> =
this._onDidPanelTitleChange.event;
private readonly _onDidPanelParametersChange = new Emitter<Parameters>();
readonly onDidPanelParametersChange: Event<Parameters> =
this._onDidPanelParametersChange.event;
private readonly _onDidRemovePanel = private readonly _onDidRemovePanel =
new Emitter<DockviewGroupChangeEvent>(); new Emitter<DockviewGroupChangeEvent>();
readonly onDidRemovePanel: Event<DockviewGroupChangeEvent> = readonly onDidRemovePanel: Event<DockviewGroupChangeEvent> =
@ -826,6 +841,12 @@ export class DockviewGroupPanelModel
); );
} }
const disposable = this._panelDisposables.get(panel.id);
if (disposable) {
disposable.dispose();
this._panelDisposables.delete(panel.id);
}
this._onDidRemovePanel.fire({ panel }); this._onDidRemovePanel.fire({ panel });
} }
@ -856,6 +877,18 @@ export class DockviewGroupPanelModel
this.updateMru(panel); this.updateMru(panel);
this.panels.splice(index, 0, panel); this.panels.splice(index, 0, panel);
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 }); this._onDidAddPanel.fire({ panel });
} }

View File

@ -58,6 +58,8 @@ export class DockviewPanel
constructor( constructor(
public readonly id: string, public readonly id: string,
component: string,
tabComponent: string | undefined,
private readonly accessor: DockviewComponent, private readonly accessor: DockviewComponent,
private readonly containerApi: DockviewApi, private readonly containerApi: DockviewApi,
group: DockviewGroupPanel, group: DockviewGroupPanel,
@ -68,7 +70,13 @@ export class DockviewPanel
this._renderer = options.renderer; this._renderer = options.renderer;
this._group = group; this._group = group;
this.api = new DockviewPanelApiImpl(this, this._group, accessor); this.api = new DockviewPanelApiImpl(
this,
this._group,
accessor,
component,
tabComponent
);
this.addDisposables( this.addDisposables(
this.api.onActiveChange(() => { this.api.onActiveChange(() => {

View File

@ -140,7 +140,7 @@ export abstract class GridviewPanel<
}, },
api?: T api?: T
) { ) {
super(id, component, api ?? <T>new GridviewPanelApiImpl(id)); super(id, component, api ?? <T>new GridviewPanelApiImpl(id, component));
if (typeof options?.minimumWidth === 'number') { if (typeof options?.minimumWidth === 'number') {
this._minimumWidth = options.minimumWidth; this._minimumWidth = options.minimumWidth;

View File

@ -164,7 +164,7 @@ export abstract class PaneviewPanel
isExpanded: boolean, isExpanded: boolean,
isHeaderVisible: boolean isHeaderVisible: boolean
) { ) {
super(id, component, new PaneviewPanelApiImpl(id)); super(id, component, new PaneviewPanelApiImpl(id, component));
this.api.pane = this; // TODO cannot use 'this' before 'super' this.api.pane = this; // TODO cannot use 'this' before 'super'
this.api.initialize(this); this.api.initialize(this);

View File

@ -83,7 +83,7 @@ export abstract class SplitviewPanel
} }
constructor(id: string, componentName: string) { constructor(id: string, componentName: string) {
super(id, componentName, new SplitviewPanelApiImpl(id)); super(id, componentName, new SplitviewPanelApiImpl(id, componentName));
this.api.initialize(this); this.api.initialize(this);