mirror of
https://github.com/mathuo/dockview
synced 2025-05-04 10:38:24 +00:00
feat: Improve onDidAdd/onDidRemove events for pane/splitview
This commit is contained in:
parent
6ba8015502
commit
67b4b2502f
105
packages/dockview/src/__tests__/paneview/paneview.spec.ts
Normal file
105
packages/dockview/src/__tests__/paneview/paneview.spec.ts
Normal file
@ -0,0 +1,105 @@
|
||||
import { CompositeDisposable } from '../../lifecycle';
|
||||
import { Paneview } from '../../paneview/paneview';
|
||||
import {
|
||||
IPaneBodyPart,
|
||||
IPaneHeaderPart,
|
||||
PaneviewPanel,
|
||||
} from '../../paneview/paneviewPanel';
|
||||
import { Orientation } from '../../splitview/core/splitview';
|
||||
|
||||
class TestPanel extends PaneviewPanel {
|
||||
protected getBodyComponent(): IPaneBodyPart {
|
||||
return {
|
||||
element: document.createElement('div'),
|
||||
update: () => {
|
||||
//
|
||||
},
|
||||
dispose: () => {
|
||||
//
|
||||
},
|
||||
init: () => {
|
||||
// /
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
protected getHeaderComponent(): IPaneHeaderPart {
|
||||
return {
|
||||
element: document.createElement('div'),
|
||||
update: () => {
|
||||
//
|
||||
},
|
||||
dispose: () => {
|
||||
//
|
||||
},
|
||||
init: () => {
|
||||
// /
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
describe('paneview', () => {
|
||||
let container: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
container = document.createElement('div');
|
||||
container.className = 'container';
|
||||
});
|
||||
|
||||
test('onDidAddView and onDidRemoveView events', () => {
|
||||
const paneview = new Paneview(container, {
|
||||
orientation: Orientation.HORIZONTAL,
|
||||
});
|
||||
|
||||
const added: PaneviewPanel[] = [];
|
||||
const removed: PaneviewPanel[] = [];
|
||||
|
||||
const disposable = new CompositeDisposable(
|
||||
paneview.onDidAddView((view) => added.push(view)),
|
||||
paneview.onDidRemoveView((view) => removed.push(view))
|
||||
);
|
||||
|
||||
const view1 = new TestPanel(
|
||||
'id',
|
||||
'component',
|
||||
'headerComponent',
|
||||
Orientation.VERTICAL,
|
||||
true,
|
||||
true
|
||||
);
|
||||
const view2 = new TestPanel(
|
||||
'id2',
|
||||
'component',
|
||||
'headerComponent',
|
||||
Orientation.VERTICAL,
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
expect(added.length).toBe(0);
|
||||
expect(removed.length).toBe(0);
|
||||
|
||||
paneview.addPane(view1);
|
||||
expect(added.length).toBe(1);
|
||||
expect(removed.length).toBe(0);
|
||||
expect(added[0]).toBe(view1);
|
||||
|
||||
paneview.addPane(view2);
|
||||
expect(added.length).toBe(2);
|
||||
expect(removed.length).toBe(0);
|
||||
expect(added[1]).toBe(view2);
|
||||
|
||||
paneview.removePane(0);
|
||||
expect(added.length).toBe(2);
|
||||
expect(removed.length).toBe(1);
|
||||
expect(removed[0]).toBe(view1);
|
||||
|
||||
paneview.removePane(0);
|
||||
expect(added.length).toBe(2);
|
||||
expect(removed.length).toBe(2);
|
||||
expect(removed[1]).toBe(view2);
|
||||
|
||||
disposable.dispose();
|
||||
});
|
||||
});
|
@ -12,7 +12,7 @@ import { Orientation } from '../../splitview/core/splitview';
|
||||
|
||||
class TestPanel extends PaneviewPanel {
|
||||
constructor(id: string, component: string) {
|
||||
super(id, component, 'header', Orientation.VERTICAL, false);
|
||||
super(id, component, 'header', Orientation.VERTICAL, false, true);
|
||||
}
|
||||
|
||||
getHeaderComponent() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { last } from '../../../array';
|
||||
import { Emitter } from '../../../events';
|
||||
import { CompositeDisposable } from '../../../lifecycle';
|
||||
import {
|
||||
IView,
|
||||
LayoutPriority,
|
||||
@ -522,4 +523,47 @@ describe('splitview', () => {
|
||||
]).toEqual([80, 100, 120]);
|
||||
expect(splitview.size).toBe(300);
|
||||
});
|
||||
|
||||
test('onDidAddView and onDidRemoveView events', () => {
|
||||
const splitview = new Splitview(container, {
|
||||
orientation: Orientation.HORIZONTAL,
|
||||
proportionalLayout: false,
|
||||
});
|
||||
|
||||
const added: IView[] = [];
|
||||
const removed: IView[] = [];
|
||||
|
||||
const disposable = new CompositeDisposable(
|
||||
splitview.onDidAddView((view) => added.push(view)),
|
||||
splitview.onDidRemoveView((view) => removed.push(view))
|
||||
);
|
||||
|
||||
const view1 = new Testview(0, 100);
|
||||
const view2 = new Testview(0, 100);
|
||||
|
||||
expect(added.length).toBe(0);
|
||||
expect(removed.length).toBe(0);
|
||||
|
||||
splitview.addView(view1);
|
||||
expect(added.length).toBe(1);
|
||||
expect(removed.length).toBe(0);
|
||||
expect(added[0]).toBe(view1);
|
||||
|
||||
splitview.addView(view2);
|
||||
expect(added.length).toBe(2);
|
||||
expect(removed.length).toBe(0);
|
||||
expect(added[1]).toBe(view2);
|
||||
|
||||
splitview.removeView(0);
|
||||
expect(added.length).toBe(2);
|
||||
expect(removed.length).toBe(1);
|
||||
expect(removed[0]).toBe(view1);
|
||||
|
||||
splitview.removeView(0);
|
||||
expect(added.length).toBe(2);
|
||||
expect(removed.length).toBe(2);
|
||||
expect(removed[1]).toBe(view2);
|
||||
|
||||
disposable.dispose();
|
||||
});
|
||||
});
|
||||
|
@ -27,7 +27,7 @@ import {
|
||||
SerializedSplitview,
|
||||
SplitviewComponentUpdateOptions,
|
||||
} from '../splitview/splitviewComponent';
|
||||
import { Orientation, Sizing } from '../splitview/core/splitview';
|
||||
import { IView, Orientation, Sizing } from '../splitview/core/splitview';
|
||||
import { ISplitviewPanel } from '../splitview/splitviewPanel';
|
||||
import { GroupviewPanel } from '../groupview/groupviewPanel';
|
||||
import { Emitter, Event } from '../events';
|
||||
@ -68,6 +68,14 @@ export class SplitviewApi implements CommonApi {
|
||||
return this.component.onDidLayoutChange;
|
||||
}
|
||||
|
||||
get onDidAddView(): Event<IView> {
|
||||
return this.component.onDidAddView;
|
||||
}
|
||||
|
||||
get onDidRemoveView(): Event<IView> {
|
||||
return this.component.onDidRemoveView;
|
||||
}
|
||||
|
||||
get orientation(): Orientation {
|
||||
return this.component.orientation;
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ export abstract class DraggablePaneviewPanel extends PaneviewPanel {
|
||||
isExpanded: boolean,
|
||||
disableDnd: boolean
|
||||
) {
|
||||
super(id, component, headerComponent, orientation, isExpanded);
|
||||
super(id, component, headerComponent, orientation, isExpanded, true);
|
||||
|
||||
if (!disableDnd) {
|
||||
this.initDragFeatures();
|
||||
|
@ -132,21 +132,21 @@ export class PaneviewComponent
|
||||
private readonly _onDidDrop = new Emitter<PaneviewDropEvent2>();
|
||||
readonly onDidDrop: Event<PaneviewDropEvent2> = this._onDidDrop.event;
|
||||
|
||||
get onDidAddView() {
|
||||
return this._paneview.onDidAddView;
|
||||
}
|
||||
private readonly _onDidAddView = new Emitter<PaneviewPanel>();
|
||||
readonly onDidAddView = this._onDidAddView.event;
|
||||
|
||||
get onDidRemoveView() {
|
||||
return this._paneview.onDidRemoveView;
|
||||
}
|
||||
private readonly _onDidRemoveView = new Emitter<PaneviewPanel>();
|
||||
readonly onDidRemoveView = this._onDidRemoveView.event;
|
||||
|
||||
set paneview(value: Paneview) {
|
||||
this._paneview = value;
|
||||
|
||||
this._disposable.value = new CompositeDisposable(
|
||||
this.paneview.onDidChange(() => {
|
||||
this._paneview.onDidChange(() => {
|
||||
this._onDidLayoutChange.fire(undefined);
|
||||
})
|
||||
}),
|
||||
this._paneview.onDidAddView((e) => this._onDidAddView.fire(e)),
|
||||
this._paneview.onDidRemoveView((e) => this._onDidRemoveView.fire(e))
|
||||
);
|
||||
}
|
||||
|
||||
@ -426,6 +426,11 @@ export class PaneviewComponent
|
||||
panel.orientation = this.paneview.orientation;
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
// the original onDidAddView events are missed since they are fired before we can subcribe to them
|
||||
this._onDidAddView.fire(panel);
|
||||
}, 0);
|
||||
|
||||
return { size: view.size, view: panel };
|
||||
}),
|
||||
},
|
||||
|
@ -58,6 +58,7 @@ export interface IPaneviewPanel
|
||||
readonly maximumBodySize: number;
|
||||
isExpanded(): boolean;
|
||||
setExpanded(isExpanded: boolean): void;
|
||||
headerVisible: boolean;
|
||||
}
|
||||
|
||||
export abstract class PaneviewPanel
|
||||
@ -85,6 +86,8 @@ export abstract class PaneviewPanel
|
||||
private animationTimer: any | undefined;
|
||||
private _orientation: Orientation;
|
||||
|
||||
private _headerVisible: boolean;
|
||||
|
||||
set orientation(value: Orientation) {
|
||||
this._orientation = value;
|
||||
}
|
||||
@ -138,16 +141,27 @@ export abstract class PaneviewPanel
|
||||
typeof value === 'number' ? value : Number.POSITIVE_INFINITY;
|
||||
}
|
||||
|
||||
get headerVisible(): boolean {
|
||||
return this._headerVisible;
|
||||
}
|
||||
|
||||
set headerVisible(value: boolean) {
|
||||
this._headerVisible = value;
|
||||
this.header!.style.display = value ? '' : 'none';
|
||||
}
|
||||
|
||||
constructor(
|
||||
id: string,
|
||||
component: string,
|
||||
private readonly headerComponent: string | undefined,
|
||||
orientation: Orientation,
|
||||
isExpanded: boolean
|
||||
isExpanded: boolean,
|
||||
isHeaderVisible: boolean
|
||||
) {
|
||||
super(id, component, new PaneviewPanelApiImpl(id));
|
||||
this.api.pane = this; // TODO cannot use 'this' before 'super'
|
||||
this._isExpanded = isExpanded;
|
||||
this._headerVisible = isHeaderVisible;
|
||||
|
||||
this._onDidChangeExpansionState.fire(this.isExpanded()); // initialize value
|
||||
|
||||
|
@ -111,7 +111,7 @@ export class Splitview {
|
||||
private readonly _onDidAddView = new Emitter<IView>();
|
||||
readonly onDidAddView = this._onDidAddView.event;
|
||||
private readonly _onDidRemoveView = new Emitter<IView>();
|
||||
readonly onDidRemoveView = this._onDidAddView.event;
|
||||
readonly onDidRemoveView = this._onDidRemoveView.event;
|
||||
|
||||
get size() {
|
||||
return this._size;
|
||||
|
@ -4,6 +4,7 @@ import {
|
||||
MutableDisposable,
|
||||
} from '../lifecycle';
|
||||
import {
|
||||
IView,
|
||||
LayoutPriority,
|
||||
Orientation,
|
||||
Sizing,
|
||||
@ -58,6 +59,8 @@ export interface ISplitviewComponent extends IDisposable {
|
||||
readonly width: number;
|
||||
readonly length: number;
|
||||
readonly orientation: Orientation;
|
||||
readonly onDidAddView: Event<IView>;
|
||||
readonly onDidRemoveView: Event<IView>;
|
||||
updateOptions(options: Partial<SplitviewComponentUpdateOptions>): void;
|
||||
addPanel(options: AddSplitviewComponentOptions): void;
|
||||
layout(width: number, height: number): void;
|
||||
@ -90,6 +93,15 @@ export class SplitviewComponent
|
||||
private panels = new Map<string, IDisposable>();
|
||||
private _options: SplitviewComponentOptions;
|
||||
|
||||
private readonly _onDidAddView = new Emitter<IView>();
|
||||
readonly onDidAddView = this._onDidAddView.event;
|
||||
|
||||
private readonly _onDidRemoveView = new Emitter<IView>();
|
||||
readonly onDidRemoveView = this._onDidRemoveView.event;
|
||||
|
||||
private readonly _onDidLayoutChange = new Emitter<void>();
|
||||
readonly onDidLayoutChange: Event<void> = this._onDidLayoutChange.event;
|
||||
|
||||
get options() {
|
||||
return this._options;
|
||||
}
|
||||
@ -108,13 +120,14 @@ export class SplitviewComponent
|
||||
this._disposable.value = new CompositeDisposable(
|
||||
this._splitview.onDidSashEnd(() => {
|
||||
this._onDidLayoutChange.fire(undefined);
|
||||
})
|
||||
}),
|
||||
this._splitview.onDidAddView((e) => this._onDidAddView.fire(e)),
|
||||
this._splitview.onDidRemoveView((e) =>
|
||||
this._onDidRemoveView.fire(e)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private readonly _onDidLayoutChange = new Emitter<void>();
|
||||
readonly onDidLayoutChange: Event<void> = this._onDidLayoutChange.event;
|
||||
|
||||
get minimumSize() {
|
||||
return this.splitview.minimumSize;
|
||||
}
|
||||
@ -370,6 +383,10 @@ export class SplitviewComponent
|
||||
panel.orientation = orientation;
|
||||
|
||||
this.doAddView(panel);
|
||||
setTimeout(() => {
|
||||
// the original onDidAddView events are missed since they are fired before we can subcribe to them
|
||||
this._onDidAddView.fire(panel);
|
||||
}, 0);
|
||||
|
||||
return { size: view.size, view: panel };
|
||||
}),
|
||||
|
Loading…
Reference in New Issue
Block a user