bug: fix constraints

This commit is contained in:
mathuo 2024-10-27 21:23:29 +00:00
parent 4bf3fc4820
commit 2dc4f81b20
No known key found for this signature in database
GPG Key ID: C6EEDEFD6CA07281
8 changed files with 218 additions and 40 deletions

View File

@ -11,12 +11,13 @@ export class DockviewPanelModelMock implements IDockviewPanelModel {
constructor( constructor(
readonly contentComponent: string, readonly contentComponent: string,
readonly content: IContentRenderer, readonly content: IContentRenderer,
readonly tabComponent?: string, readonly tabComponent: string,
readonly tab?: ITabRenderer readonly tab: ITabRenderer
) { ) {
// //
} }
init(params: GroupPanelPartInitParameters): void { init(params: GroupPanelPartInitParameters): void {
// //
} }

View File

@ -0,0 +1,141 @@
import { DockviewComponent } from '../../dockview/dockviewComponent';
import { DockviewGroupPanel } from '../../dockview/dockviewGroupPanel';
import { fromPartial } from '@total-typescript/shoehorn';
import { GroupOptions } from '../../dockview/dockviewGroupPanelModel';
import { DockviewPanel } from '../../dockview/dockviewPanel';
import { DockviewPanelModelMock } from '../__mocks__/mockDockviewPanelModel';
import { IContentRenderer, ITabRenderer } from '../../dockview/types';
import { OverlayRenderContainer } from '../../overlay/overlayRenderContainer';
describe('dockviewGroupPanel', () => {
test('default minimum/maximium width/height', () => {
const accessor = fromPartial<DockviewComponent>({
onDidActivePanelChange: jest.fn(),
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
options: {},
});
const options = fromPartial<GroupOptions>({});
const cut = new DockviewGroupPanel(accessor, 'test_id', options);
expect(cut.minimumWidth).toBe(100);
expect(cut.minimumHeight).toBe(100);
expect(cut.maximumHeight).toBe(Number.MAX_SAFE_INTEGER);
expect(cut.maximumWidth).toBe(Number.MAX_SAFE_INTEGER);
});
test('group constraints', () => {
const accessor = fromPartial<DockviewComponent>({
onDidActivePanelChange: jest.fn(),
onDidAddPanel: jest.fn(),
onDidRemovePanel: jest.fn(),
doSetGroupActive: jest.fn(),
overlayRenderContainer: fromPartial<OverlayRenderContainer>({
attach: jest.fn(),
detatch: jest.fn(),
}),
options: {},
});
const options = fromPartial<GroupOptions>({});
const cut = new DockviewGroupPanel(accessor, 'test_id', options);
cut.api.setConstraints({
minimumHeight: 10,
maximumHeight: 100,
minimumWidth: 20,
maximumWidth: 200,
});
// initial constraints
expect(cut.minimumWidth).toBe(20);
expect(cut.minimumHeight).toBe(10);
expect(cut.maximumHeight).toBe(100);
expect(cut.maximumWidth).toBe(200);
const panelModel = new DockviewPanelModelMock(
'content_component',
fromPartial<IContentRenderer>({
element: document.createElement('div'),
}),
'tab_component',
fromPartial<ITabRenderer>({
element: document.createElement('div'),
})
);
const panel = new DockviewPanel(
'panel_id',
'component_id',
undefined,
accessor,
accessor.api,
cut,
panelModel,
{
renderer: 'onlyWhenVisible',
minimumWidth: 21,
minimumHeight: 11,
maximumHeight: 101,
maximumWidth: 201,
}
);
cut.model.openPanel(panel);
// active panel constraints
expect(cut.minimumWidth).toBe(21);
expect(cut.minimumHeight).toBe(11);
expect(cut.maximumHeight).toBe(101);
expect(cut.maximumWidth).toBe(201);
const panel2 = new DockviewPanel(
'panel_id',
'component_id',
undefined,
accessor,
accessor.api,
cut,
panelModel,
{
renderer: 'onlyWhenVisible',
minimumWidth: 22,
minimumHeight: 12,
maximumHeight: 102,
maximumWidth: 202,
}
);
cut.model.openPanel(panel2);
// active panel constraints
expect(cut.minimumWidth).toBe(22);
expect(cut.minimumHeight).toBe(12);
expect(cut.maximumHeight).toBe(102);
expect(cut.maximumWidth).toBe(202);
const panel3 = new DockviewPanel(
'panel_id',
'component_id',
undefined,
accessor,
accessor.api,
cut,
panelModel,
{
renderer: 'onlyWhenVisible',
}
);
cut.model.openPanel(panel3);
// active panel without specified constraints so falls back to group constraints
expect(cut.minimumWidth).toBe(20);
expect(cut.minimumHeight).toBe(10);
expect(cut.maximumHeight).toBe(100);
expect(cut.maximumWidth).toBe(200);
});
});

View File

@ -154,6 +154,10 @@ export class ContentContainer
referenceContainer: this, referenceContainer: this,
}); });
break; break;
default:
throw new Error(
`dockview: invalid renderer type '${panel.api.renderer}'`
);
} }
if (doRender) { if (doRender) {

View File

@ -347,9 +347,6 @@ export class TabsContainer
return; return;
} }
const tab = new Tab(panel, this.accessor, this.group); const tab = new Tab(panel, this.accessor, this.group);
if (!panel.view?.tab) {
throw new Error('invalid header component');
}
tab.setContent(panel.view.tab); tab.setContent(panel.view.tab);
const disposable = new CompositeDisposable( const disposable = new CompositeDisposable(

View File

@ -34,32 +34,36 @@ export class DockviewGroupPanel
{ {
private readonly _model: DockviewGroupPanelModel; private readonly _model: DockviewGroupPanelModel;
get minimumWidth(): number { override get minimumWidth(): number {
const activePanelMinimumWidth = this.activePanel?.minimumWidth; const activePanelMinimumWidth = this.activePanel?.minimumWidth;
return typeof activePanelMinimumWidth === 'number' if (typeof activePanelMinimumWidth === 'number') {
? activePanelMinimumWidth return activePanelMinimumWidth;
: MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH; }
return super.__minimumWidth();
} }
get minimumHeight(): number { override get minimumHeight(): number {
const activePanelMinimumHeight = this.activePanel?.minimumHeight; const activePanelMinimumHeight = this.activePanel?.minimumHeight;
return typeof activePanelMinimumHeight === 'number' if (typeof activePanelMinimumHeight === 'number') {
? activePanelMinimumHeight return activePanelMinimumHeight;
: MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT; }
return super.__minimumHeight();
} }
get maximumWidth(): number { override get maximumWidth(): number {
const activePanelMaximumWidth = this.activePanel?.maximumWidth; const activePanelMaximumWidth = this.activePanel?.maximumWidth;
return typeof activePanelMaximumWidth === 'number' if (typeof activePanelMaximumWidth === 'number') {
? activePanelMaximumWidth return activePanelMaximumWidth;
: Number.MAX_SAFE_INTEGER; }
return super.__maximumWidth();
} }
get maximumHeight(): number { override get maximumHeight(): number {
const activePanelMaximumHeight = this.activePanel?.maximumHeight; const activePanelMaximumHeight = this.activePanel?.maximumHeight;
return typeof activePanelMaximumHeight === 'number' if (typeof activePanelMaximumHeight === 'number') {
? activePanelMaximumHeight return activePanelMaximumHeight;
: Number.MAX_SAFE_INTEGER; }
return super.__maximumHeight();
} }
get panels(): IDockviewPanel[] { get panels(): IDockviewPanel[] {

View File

@ -264,6 +264,7 @@ export class DockviewGroupPanelModel
private _location: DockviewGroupLocation = { type: 'grid' }; private _location: DockviewGroupLocation = { type: 'grid' };
private mostRecentlyUsed: IDockviewPanel[] = []; private mostRecentlyUsed: IDockviewPanel[] = [];
private _overwriteRenderContainer: OverlayRenderContainer | null = null;
private readonly _onDidChange = new Emitter<IViewSize | undefined>(); private readonly _onDidChange = new Emitter<IViewSize | undefined>();
readonly onDidChange: Event<IViewSize | undefined> = readonly onDidChange: Event<IViewSize | undefined> =
@ -513,8 +514,6 @@ export class DockviewGroupPanelModel
this.contentContainer.element.focus(); this.contentContainer.element.focus();
} }
private _overwriteRenderContainer: OverlayRenderContainer | null = null;
set renderContainer(value: OverlayRenderContainer | null) { set renderContainer(value: OverlayRenderContainer | null) {
this.panels.forEach((panel) => { this.panels.forEach((panel) => {
this.renderContainer.detatch(panel); this.renderContainer.detatch(panel);

View File

@ -13,7 +13,7 @@ export interface IDockviewPanelModel extends IDisposable {
readonly contentComponent: string; readonly contentComponent: string;
readonly tabComponent?: string; readonly tabComponent?: string;
readonly content: IContentRenderer; readonly content: IContentRenderer;
readonly tab?: ITabRenderer; readonly tab: ITabRenderer;
update(event: PanelUpdateEvent): void; update(event: PanelUpdateEvent): void;
layout(width: number, height: number): void; layout(width: number, height: number): void;
init(params: GroupPanelPartInitParameters): void; init(params: GroupPanelPartInitParameters): void;

View File

@ -74,6 +74,38 @@ export abstract class GridviewPanel<
} }
get minimumWidth(): number { get minimumWidth(): number {
/**
* defer to protected function to allow subclasses to override easily.
* see https://github.com/microsoft/TypeScript/issues/338
*/
return this.__minimumWidth();
}
get minimumHeight(): number {
/**
* defer to protected function to allow subclasses to override easily.
* see https://github.com/microsoft/TypeScript/issues/338
*/
return this.__minimumHeight();
}
get maximumHeight(): number {
/**
* defer to protected function to allow subclasses to override easily.
* see https://github.com/microsoft/TypeScript/issues/338
*/
return this.__maximumHeight();
}
get maximumWidth(): number {
/**
* defer to protected function to allow subclasses to override easily.
* see https://github.com/microsoft/TypeScript/issues/338
*/
return this.__maximumWidth();
}
protected __minimumWidth(): number {
const width = const width =
typeof this._minimumWidth === 'function' typeof this._minimumWidth === 'function'
? this._minimumWidth() ? this._minimumWidth()
@ -87,7 +119,21 @@ export abstract class GridviewPanel<
return width; return width;
} }
get minimumHeight(): number { protected __maximumWidth(): number {
const width =
typeof this._maximumWidth === 'function'
? this._maximumWidth()
: this._maximumWidth;
if (width !== this._evaluatedMaximumWidth) {
this._evaluatedMaximumWidth = width;
this.updateConstraints();
}
return width;
}
protected __minimumHeight(): number {
const height = const height =
typeof this._minimumHeight === 'function' typeof this._minimumHeight === 'function'
? this._minimumHeight() ? this._minimumHeight()
@ -101,7 +147,7 @@ export abstract class GridviewPanel<
return height; return height;
} }
get maximumHeight(): number { protected __maximumHeight(): number {
const height = const height =
typeof this._maximumHeight === 'function' typeof this._maximumHeight === 'function'
? this._maximumHeight() ? this._maximumHeight()
@ -115,20 +161,6 @@ export abstract class GridviewPanel<
return height; return height;
} }
get maximumWidth(): number {
const width =
typeof this._maximumWidth === 'function'
? this._maximumWidth()
: this._maximumWidth;
if (width !== this._evaluatedMaximumWidth) {
this._evaluatedMaximumWidth = width;
this.updateConstraints();
}
return width;
}
get isActive(): boolean { get isActive(): boolean {
return this.api.isActive; return this.api.isActive;
} }