From b222de86f70a36b2af7673212e83024ada7f9ec1 Mon Sep 17 00:00:00 2001 From: mathuo <6710312+mathuo@users.noreply.github.com> Date: Wed, 3 Jan 2024 13:51:43 +0000 Subject: [PATCH] feat: enhance maximize group api methods --- .../src/__tests__/gridview/gridview.spec.ts | 14 +++++++- .../src/api/dockviewGroupPanelApi.ts | 36 +++++++++++++++++-- .../dockview-core/src/api/dockviewPanelApi.ts | 21 +++++++---- .../src/gridview/baseComponentGridview.ts | 5 +++ .../dockview-core/src/gridview/gridview.ts | 16 +++++++-- 5 files changed, 80 insertions(+), 12 deletions(-) diff --git a/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts b/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts index 2b95757dc..c0f0f1f65 100644 --- a/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts +++ b/packages/dockview-core/src/__tests__/gridview/gridview.spec.ts @@ -842,6 +842,11 @@ describe('gridview', () => { ); gridview.layout(1000, 1000); + let counter = 0; + const subscription = gridview.onDidMaxmizedNodeChange(() => { + counter++; + }); + const view1 = new MockGridview('1'); const view2 = new MockGridview('2'); const view3 = new MockGridview('3'); @@ -891,18 +896,25 @@ describe('gridview', () => { // base case assertions assertLayout(); expect(gridview.hasMaximizedView()).toBeFalsy(); + expect(counter).toBe(0); /** * maximize each view individually and then return to the standard view * checking on each iteration that the original layout dimensions * are restored */ - for (const view of views) { + for (let i = 0; i < views.length; i++) { + const view = views[i]; + gridview.maximizeView(view); + expect(counter).toBe(i * 2 + 1); expect(gridview.hasMaximizedView()).toBeTruthy(); gridview.exitMaximizedView(); + expect(counter).toBe(i * 2 + 2); assertLayout(); } + + subscription.dispose(); }); test('that maximizedView is exited when a views visibility is changed', () => { diff --git a/packages/dockview-core/src/api/dockviewGroupPanelApi.ts b/packages/dockview-core/src/api/dockviewGroupPanelApi.ts index c277d8680..8b075d620 100644 --- a/packages/dockview-core/src/api/dockviewGroupPanelApi.ts +++ b/packages/dockview-core/src/api/dockviewGroupPanelApi.ts @@ -9,12 +9,18 @@ export interface DockviewGroupPanelApi extends GridviewPanelApi { readonly onDidRenderPositionChange: Event; readonly location: DockviewGroupLocation; moveTo(options: { group: DockviewGroupPanel; position?: Position }): void; + maximize(): void; + isMaximized(): boolean; + exitMaximized(): void; } export interface DockviewGroupPanelFloatingChangeEvent { readonly location: DockviewGroupLocation; } +// TODO find a better way to initialize and avoid needing null checks +const NOT_INITIALIZED_MESSAGE = 'DockviewGroupPanelApiImpl not initialized'; + export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { private _group: DockviewGroupPanel | undefined; @@ -25,7 +31,7 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { get location(): DockviewGroupLocation { if (!this._group) { - throw new Error(`DockviewGroupPanelApiImpl not initialized`); + throw new Error(NOT_INITIALIZED_MESSAGE); } return this._group.model.location; } @@ -38,7 +44,7 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { moveTo(options: { group: DockviewGroupPanel; position?: Position }): void { if (!this._group) { - throw new Error(`DockviewGroupPanelApiImpl not initialized`); + throw new Error(NOT_INITIALIZED_MESSAGE); } this.accessor.moveGroupOrPanel( @@ -49,6 +55,32 @@ export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { ); } + maximize(): void { + if (!this._group) { + throw new Error(NOT_INITIALIZED_MESSAGE); + } + + this.accessor.maximizeGroup(this._group); + } + + isMaximized(): boolean { + if (!this._group) { + throw new Error(NOT_INITIALIZED_MESSAGE); + } + + return this.accessor.isMaximizedGroup(this._group); + } + + exitMaximized(): void { + if (!this._group) { + throw new Error(NOT_INITIALIZED_MESSAGE); + } + + if (this.isMaximized()) { + this.accessor.exitMaximizedGroup(); + } + } + initialize(group: DockviewGroupPanel): void { this._group = group; } diff --git a/packages/dockview-core/src/api/dockviewPanelApi.ts b/packages/dockview-core/src/api/dockviewPanelApi.ts index 38544b684..51ce82591 100644 --- a/packages/dockview-core/src/api/dockviewPanelApi.ts +++ b/packages/dockview-core/src/api/dockviewPanelApi.ts @@ -2,7 +2,7 @@ import { Emitter, Event } from '../events'; import { GridviewPanelApiImpl, GridviewPanelApi } from './gridviewPanelApi'; import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel'; import { MutableDisposable } from '../lifecycle'; -import { DockviewPanel, IDockviewPanel } from '../dockview/dockviewPanel'; +import { DockviewPanel } from '../dockview/dockviewPanel'; import { DockviewComponent } from '../dockview/dockviewComponent'; import { Position } from '../dnd/droptarget'; import { DockviewPanelRenderer } from '../dockview/components/greadyRenderContainer'; @@ -15,13 +15,10 @@ export interface RendererChangedEvent { renderer: DockviewPanelRenderer; } -/* - * omit visibility modifiers since the visibility of a single group doesn't make sense - * because it belongs to a groupview - */ export interface DockviewPanelApi extends Omit< GridviewPanelApi, + // omit properties that do not make sense here 'setVisible' | 'onDidConstraintsChange' | 'setConstraints' > { readonly group: DockviewGroupPanel; @@ -40,6 +37,8 @@ export interface DockviewPanelApi index?: number; }): void; maximize(): void; + isMaximized(): boolean; + exitMaximized(): void; } export class DockviewPanelApiImpl @@ -67,7 +66,7 @@ export class DockviewPanelApiImpl } get isGroupActive(): boolean { - return !!this.group?.isActive; + return this.group.isActive; } get renderer(): DockviewPanelRenderer { @@ -143,6 +142,14 @@ export class DockviewPanelApiImpl } maximize(): void { - this.accessor.maximizeGroup(this.panel.group); + this.group.api.maximize(); + } + + isMaximized(): boolean { + return this.group.api.isMaximized(); + } + + exitMaximized(): void { + this.group.api.exitMaximized(); } } diff --git a/packages/dockview-core/src/gridview/baseComponentGridview.ts b/packages/dockview-core/src/gridview/baseComponentGridview.ts index 7524b4120..2e4159a9b 100644 --- a/packages/dockview-core/src/gridview/baseComponentGridview.ts +++ b/packages/dockview-core/src/gridview/baseComponentGridview.ts @@ -65,6 +65,7 @@ export interface IBaseGrid { setVisible(panel: T, visible: boolean): void; isVisible(panel: T): boolean; maximizeGroup(panel: T): void; + isMaximizedGroup(panel: T): boolean; exitMaximizedGroup(): void; hasMaximizedGroup(): boolean; readonly onDidMaxmizedGroupChange: Event; @@ -182,6 +183,10 @@ export abstract class BaseGrid this.gridview.maximizeView(panel); } + isMaximizedGroup(panel: T): boolean { + return this.gridview.maximizedView() === panel; + } + exitMaximizedGroup(): void { this.gridview.exitMaximizedView(); } diff --git a/packages/dockview-core/src/gridview/gridview.ts b/packages/dockview-core/src/gridview/gridview.ts index 9b9dae231..1133b2502 100644 --- a/packages/dockview-core/src/gridview/gridview.ts +++ b/packages/dockview-core/src/gridview/gridview.ts @@ -273,7 +273,7 @@ export class Gridview implements IDisposable { readonly element: HTMLElement; private _root: BranchNode | undefined; - private _maximizedNode: Node | undefined = undefined; + private _maximizedNode: LeafNode | undefined = undefined; private readonly disposable: MutableDisposable = new MutableDisposable(); private readonly _onDidChange = new Emitter<{ @@ -307,6 +307,7 @@ export class Gridview implements IDisposable { get width(): number { return this.root.width; } + get height(): number { return this.root.height; } @@ -314,16 +315,23 @@ export class Gridview implements IDisposable { get minimumWidth(): number { return this.root.minimumWidth; } + get minimumHeight(): number { return this.root.minimumHeight; } + get maximumWidth(): number { return this.root.maximumHeight; } + get maximumHeight(): number { return this.root.maximumHeight; } + maximizedView(): IGridView | undefined { + return this._maximizedNode?.view; + } + hasMaximizedView(): boolean { return this._maximizedNode !== undefined; } @@ -332,6 +340,10 @@ export class Gridview implements IDisposable { const location = getGridLocation(view.element); const [_, node] = this.getNode(location); + if (!(node instanceof LeafNode)) { + return; + } + if (this._maximizedNode === node) { return; } @@ -353,7 +365,7 @@ export class Gridview implements IDisposable { } } - hideAllViewsBut(this.root, node as LeafNode); + hideAllViewsBut(this.root, node); this._maximizedNode = node; this._onDidMaxmizedNodeChange.fire(); }