diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts index 926abd40c..895e954e0 100644 --- a/packages/dockview-core/src/dockview/dockviewComponent.ts +++ b/packages/dockview-core/src/dockview/dockviewComponent.ts @@ -380,6 +380,7 @@ export class DockviewComponent styles: options.styles, parentElement: options.parentElement, disableAutoResizing: options.disableAutoResizing, + locked: options.locked, }); const gready = document.createElement('div'); diff --git a/packages/dockview-core/src/dockview/options.ts b/packages/dockview-core/src/dockview/options.ts index 7311b2704..d410fcfe9 100644 --- a/packages/dockview-core/src/dockview/options.ts +++ b/packages/dockview-core/src/dockview/options.ts @@ -102,6 +102,7 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions { defaultRenderer?: DockviewPanelRenderer; debug?: boolean; rootOverlayModel?: DroptargetOverlayModel; + locked?: boolean; disableDnd?: boolean; } diff --git a/packages/dockview-core/src/gridview/baseComponentGridview.ts b/packages/dockview-core/src/gridview/baseComponentGridview.ts index 12e877d2f..fa1974d15 100644 --- a/packages/dockview-core/src/gridview/baseComponentGridview.ts +++ b/packages/dockview-core/src/gridview/baseComponentGridview.ts @@ -34,6 +34,7 @@ export interface BaseGridOptions { readonly styles?: ISplitviewStyles; readonly parentElement: HTMLElement; readonly disableAutoResizing?: boolean; + readonly locked?: boolean; } export interface IGridPanelView extends IGridView, IPanel { @@ -133,6 +134,14 @@ export abstract class BaseGrid return this._activeGroup; } + get locked(): boolean { + return this.gridview.locked; + } + + set locked(value: boolean) { + this.gridview.locked = value; + } + constructor(options: BaseGridOptions) { super(document.createElement('div'), options.disableAutoResizing); @@ -144,6 +153,8 @@ export abstract class BaseGrid options.orientation ); + this.gridview.locked = !!options.locked; + this.element.appendChild(this.gridview.element); this.layout(0, 0, true); // set some elements height/widths diff --git a/packages/dockview-core/src/gridview/branchNode.ts b/packages/dockview-core/src/gridview/branchNode.ts index 8ba96ef05..511f9398e 100644 --- a/packages/dockview-core/src/gridview/branchNode.ts +++ b/packages/dockview-core/src/gridview/branchNode.ts @@ -131,17 +131,27 @@ export class BranchNode extends CompositeDisposable implements IView { return LayoutPriority.Normal; } + get disabled(): boolean { + return this.splitview.disabled; + } + + set disabled(value: boolean) { + this.splitview.disabled = value; + } + constructor( readonly orientation: Orientation, readonly proportionalLayout: boolean, readonly styles: ISplitviewStyles | undefined, size: number, orthogonalSize: number, + disabled: boolean, childDescriptors?: INodeDescriptor[] ) { super(); this._orthogonalSize = orthogonalSize; this._size = size; + this.element = document.createElement('div'); this.element.className = 'branch-node'; @@ -177,6 +187,8 @@ export class BranchNode extends CompositeDisposable implements IView { }); } + this.disabled = disabled; + this.addDisposables( this._onDidChange, this._onDidVisibilityChange, @@ -202,7 +214,7 @@ export class BranchNode extends CompositeDisposable implements IView { return this.splitview.isViewVisible(index); } - setChildVisible(index: number, visible: boolean): void { + setChildVisible(index: number, visible: boolean): void { if (index < 0 || index >= this.children.length) { throw new Error('Invalid index'); } diff --git a/packages/dockview-core/src/gridview/gridview.ts b/packages/dockview-core/src/gridview/gridview.ts index 48138d1e8..f73b75bd8 100644 --- a/packages/dockview-core/src/gridview/gridview.ts +++ b/packages/dockview-core/src/gridview/gridview.ts @@ -41,7 +41,8 @@ function flipNode( node.proportionalLayout, node.styles, size, - orthogonalSize + orthogonalSize, + node.disabled ); let totalSize = 0; @@ -273,6 +274,7 @@ export class Gridview implements IDisposable { readonly element: HTMLElement; private _root: BranchNode | undefined; + private _locked = false; private _maximizedNode: | { leaf: LeafNode; hiddenOnMaximize: LeafNode[] } | undefined = undefined; @@ -330,6 +332,30 @@ export class Gridview implements IDisposable { return this.root.maximumHeight; } + get locked(): boolean { + return this._locked; + } + + set locked(value: boolean) { + this._locked = value; + + const branch: Node[] = [this.root]; + + /** + * simple depth-first-search to cover all nodes + * + * @see https://en.wikipedia.org/wiki/Depth-first_search + */ + while (branch.length > 0) { + const node = branch.pop(); + + if (node instanceof BranchNode) { + node.disabled = value; + branch.push(...node.children); + } + } + } + maximizedView(): IGridView | undefined { return this._maximizedNode?.leaf.view; } @@ -439,7 +465,8 @@ export class Gridview implements IDisposable { this.proportionalLayout, this.styles, this.root.size, - this.root.orthogonalSize + this.root.orthogonalSize, + this._locked ); } @@ -499,8 +526,8 @@ export class Gridview implements IDisposable { this.proportionalLayout, this.styles, node.size, // <- orthogonal size - flips at each depth - orthogonalSize, // <- size - flips at each depth - + orthogonalSize, // <- size - flips at each depth, + this._locked, children ); } else { @@ -552,7 +579,8 @@ export class Gridview implements IDisposable { this.proportionalLayout, this.styles, this.root.orthogonalSize, - this.root.size + this.root.size, + this._locked ); if (oldRoot.children.length === 0) { @@ -667,7 +695,8 @@ export class Gridview implements IDisposable { proportionalLayout, styles, 0, - 0 + 0, + this._locked ); } @@ -751,7 +780,8 @@ export class Gridview implements IDisposable { this.proportionalLayout, this.styles, parent.size, - parent.orthogonalSize + parent.orthogonalSize, + this._locked ); grandParent.addChild(newParent, parent.size, parentIndex); diff --git a/packages/dockview-core/src/splitview/splitview.scss b/packages/dockview-core/src/splitview/splitview.scss index b12b0969a..a9f9644e6 100644 --- a/packages/dockview-core/src/splitview/splitview.scss +++ b/packages/dockview-core/src/splitview/splitview.scss @@ -25,6 +25,12 @@ height: 100%; width: 100%; + &.dv-splitview-disabled { + & > .sash-container > .sash { + pointer-events: none; + } + } + &.animation { .view, .sash { diff --git a/packages/dockview-core/src/splitview/splitview.ts b/packages/dockview-core/src/splitview/splitview.ts index c8b3fdf66..465958fe6 100644 --- a/packages/dockview-core/src/splitview/splitview.ts +++ b/packages/dockview-core/src/splitview/splitview.ts @@ -109,6 +109,7 @@ export class Splitview { private proportionalLayout: boolean; private _startSnappingEnabled = true; private _endSnappingEnabled = true; + private _disabled = false; private readonly _onDidSashEnd = new Emitter(); readonly onDidSashEnd = this._onDidSashEnd.event; @@ -200,6 +201,16 @@ export class Splitview { this.updateSashEnablement(); } + get disabled(): boolean { + return this._disabled; + } + + set disabled(value: boolean) { + this._disabled = value; + + toggleClass(this.element, 'dv-splitview-disabled', value); + } + constructor( private readonly container: HTMLElement, options: SplitViewOptions diff --git a/packages/dockview/src/dockview/dockview.tsx b/packages/dockview/src/dockview/dockview.tsx index 2289e107f..62f5b3194 100644 --- a/packages/dockview/src/dockview/dockview.tsx +++ b/packages/dockview/src/dockview/dockview.tsx @@ -83,6 +83,7 @@ export interface IDockviewReactProps { debug?: boolean; defaultRenderer?: DockviewPanelRenderer; rootOverlayModel?: DroptargetOverlayModel; + locked?: boolean; disableDnd?: boolean; } @@ -186,6 +187,7 @@ export const DockviewReact = React.forwardRef( defaultRenderer: props.defaultRenderer, debug: props.debug, rootOverlayModel: props.rootOverlayModel, + locked: props.locked, disableDnd: props.disableDnd, }); @@ -207,6 +209,15 @@ export const DockviewReact = React.forwardRef( if (!dockviewRef.current) { return; } + + dockviewRef.current.locked = !!props.locked; + }, [props.locked]); + + React.useEffect(() => { + if (!dockviewRef.current) { + return; + } + dockviewRef.current.updateOptions({ disableDnd: props.disableDnd, });