From 22ba48e81ee29bd40ce4a5a80352b35c133b9b7f Mon Sep 17 00:00:00 2001
From: mathuo <6710312+mathuo@users.noreply.github.com>
Date: Fri, 19 Jan 2024 14:17:37 +0000
Subject: [PATCH] feat: locked mode
---
.../src/dockview/dockviewComponent.ts | 1 +
.../dockview-core/src/dockview/options.ts | 1 +
.../src/gridview/baseComponentGridview.ts | 11 +++++
.../dockview-core/src/gridview/branchNode.ts | 14 +++++-
.../dockview-core/src/gridview/gridview.ts | 44 ++++++++++++++++---
.../src/splitview/splitview.scss | 6 +++
.../dockview-core/src/splitview/splitview.ts | 11 +++++
packages/dockview/src/dockview/dockview.tsx | 10 +++++
8 files changed, 90 insertions(+), 8 deletions(-)
diff --git a/packages/dockview-core/src/dockview/dockviewComponent.ts b/packages/dockview-core/src/dockview/dockviewComponent.ts
index 82e5283a4..2ec7b7272 100644
--- a/packages/dockview-core/src/dockview/dockviewComponent.ts
+++ b/packages/dockview-core/src/dockview/dockviewComponent.ts
@@ -369,6 +369,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 34ab98989..ade5f7529 100644
--- a/packages/dockview-core/src/dockview/options.ts
+++ b/packages/dockview-core/src/dockview/options.ts
@@ -101,6 +101,7 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions {
defaultRenderer?: DockviewPanelRenderer;
debug?: boolean;
rootOverlayModel?: DroptargetOverlayModel;
+ locked?: boolean;
}
export interface PanelOptions
{
diff --git a/packages/dockview-core/src/gridview/baseComponentGridview.ts b/packages/dockview-core/src/gridview/baseComponentGridview.ts
index 2e4159a9b..0e152de00 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(options.parentElement, options.disableAutoResizing);
@@ -142,6 +151,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..d0e449e01 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 locked(): boolean {
+ return this.splitview.locked;
+ }
+
+ set locked(value: boolean) {
+ this.splitview.locked = 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.locked = 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 f34fe2672..e7f54637d 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.locked
);
let totalSize = 0;
@@ -273,6 +274,7 @@ export class Gridview implements IDisposable {
readonly element: HTMLElement;
private _root: BranchNode | undefined;
+ private _locked = false;
private _maximizedNode: LeafNode | undefined = undefined;
private readonly disposable: MutableDisposable = new MutableDisposable();
@@ -328,6 +330,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.locked = value;
+ branch.push(...node.children);
+ }
+ }
+ }
+
maximizedView(): IGridView | undefined {
return this._maximizedNode?.view;
}
@@ -427,7 +453,8 @@ export class Gridview implements IDisposable {
this.proportionalLayout,
this.styles,
this.root.size,
- this.root.orthogonalSize
+ this.root.orthogonalSize,
+ this._locked
);
}
@@ -487,8 +514,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 {
@@ -540,7 +567,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) {
@@ -655,7 +683,8 @@ export class Gridview implements IDisposable {
proportionalLayout,
styles,
0,
- 0
+ 0,
+ this._locked
);
}
@@ -739,7 +768,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..82c8a7ced 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-locked {
+ & > .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..4c5ef3707 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 locked(): boolean {
+ return this._disabled;
+ }
+
+ set locked(value: boolean) {
+ this._disabled = value;
+
+ toggleClass(this.element, 'dv-splitview-locked', 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 91aaa0562..f0012c1ca 100644
--- a/packages/dockview/src/dockview/dockview.tsx
+++ b/packages/dockview/src/dockview/dockview.tsx
@@ -81,6 +81,7 @@ export interface IDockviewReactProps {
debug?: boolean;
defaultRenderer?: DockviewPanelRenderer;
rootOverlayModel?: DroptargetOverlayModel;
+ locked?: boolean;
}
const DEFAULT_REACT_TAB = 'props.defaultTabComponent';
@@ -183,6 +184,7 @@ export const DockviewReact = React.forwardRef(
defaultRenderer: props.defaultRenderer,
debug: props.debug,
rootOverlayModel: props.rootOverlayModel,
+ locked: props.locked,
});
const { clientWidth, clientHeight } = domRef.current;
@@ -199,6 +201,14 @@ export const DockviewReact = React.forwardRef(
};
}, []);
+ React.useEffect(() => {
+ if (!dockviewRef.current) {
+ return;
+ }
+
+ dockviewRef.current.locked = !!props.locked;
+ }, [props.locked]);
+
React.useEffect(() => {
if (!dockviewRef.current) {
return () => {