Skip to content

Commit d488e8c

Browse files
authored
Merge pull request #461 from mathuo/460-locked-mode-prevent-all-mouse-resizing
feat: locked mode
2 parents c70327e + 1d7ab22 commit d488e8c

File tree

8 files changed

+91
-8
lines changed

8 files changed

+91
-8
lines changed

packages/dockview-core/src/dockview/dockviewComponent.ts

+1
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,7 @@ export class DockviewComponent
380380
styles: options.styles,
381381
parentElement: options.parentElement,
382382
disableAutoResizing: options.disableAutoResizing,
383+
locked: options.locked,
383384
});
384385

385386
const gready = document.createElement('div');

packages/dockview-core/src/dockview/options.ts

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions {
102102
defaultRenderer?: DockviewPanelRenderer;
103103
debug?: boolean;
104104
rootOverlayModel?: DroptargetOverlayModel;
105+
locked?: boolean;
105106
disableDnd?: boolean;
106107
}
107108

packages/dockview-core/src/gridview/baseComponentGridview.ts

+11
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export interface BaseGridOptions {
3434
readonly styles?: ISplitviewStyles;
3535
readonly parentElement: HTMLElement;
3636
readonly disableAutoResizing?: boolean;
37+
readonly locked?: boolean;
3738
}
3839

3940
export interface IGridPanelView extends IGridView, IPanel {
@@ -133,6 +134,14 @@ export abstract class BaseGrid<T extends IGridPanelView>
133134
return this._activeGroup;
134135
}
135136

137+
get locked(): boolean {
138+
return this.gridview.locked;
139+
}
140+
141+
set locked(value: boolean) {
142+
this.gridview.locked = value;
143+
}
144+
136145
constructor(options: BaseGridOptions) {
137146
super(document.createElement('div'), options.disableAutoResizing);
138147

@@ -144,6 +153,8 @@ export abstract class BaseGrid<T extends IGridPanelView>
144153
options.orientation
145154
);
146155

156+
this.gridview.locked = !!options.locked;
157+
147158
this.element.appendChild(this.gridview.element);
148159

149160
this.layout(0, 0, true); // set some elements height/widths

packages/dockview-core/src/gridview/branchNode.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,27 @@ export class BranchNode extends CompositeDisposable implements IView {
131131
return LayoutPriority.Normal;
132132
}
133133

134+
get disabled(): boolean {
135+
return this.splitview.disabled;
136+
}
137+
138+
set disabled(value: boolean) {
139+
this.splitview.disabled = value;
140+
}
141+
134142
constructor(
135143
readonly orientation: Orientation,
136144
readonly proportionalLayout: boolean,
137145
readonly styles: ISplitviewStyles | undefined,
138146
size: number,
139147
orthogonalSize: number,
148+
disabled: boolean,
140149
childDescriptors?: INodeDescriptor[]
141150
) {
142151
super();
143152
this._orthogonalSize = orthogonalSize;
144153
this._size = size;
154+
145155
this.element = document.createElement('div');
146156
this.element.className = 'branch-node';
147157

@@ -177,6 +187,8 @@ export class BranchNode extends CompositeDisposable implements IView {
177187
});
178188
}
179189

190+
this.disabled = disabled;
191+
180192
this.addDisposables(
181193
this._onDidChange,
182194
this._onDidVisibilityChange,
@@ -202,7 +214,7 @@ export class BranchNode extends CompositeDisposable implements IView {
202214
return this.splitview.isViewVisible(index);
203215
}
204216

205-
setChildVisible(index: number, visible: boolean): void {
217+
setChildVisible(index: number, visible: boolean): void {
206218
if (index < 0 || index >= this.children.length) {
207219
throw new Error('Invalid index');
208220
}

packages/dockview-core/src/gridview/gridview.ts

+37-7
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ function flipNode<T extends Node>(
4141
node.proportionalLayout,
4242
node.styles,
4343
size,
44-
orthogonalSize
44+
orthogonalSize,
45+
node.disabled
4546
);
4647

4748
let totalSize = 0;
@@ -273,6 +274,7 @@ export class Gridview implements IDisposable {
273274
readonly element: HTMLElement;
274275

275276
private _root: BranchNode | undefined;
277+
private _locked = false;
276278
private _maximizedNode:
277279
| { leaf: LeafNode; hiddenOnMaximize: LeafNode[] }
278280
| undefined = undefined;
@@ -330,6 +332,30 @@ export class Gridview implements IDisposable {
330332
return this.root.maximumHeight;
331333
}
332334

335+
get locked(): boolean {
336+
return this._locked;
337+
}
338+
339+
set locked(value: boolean) {
340+
this._locked = value;
341+
342+
const branch: Node[] = [this.root];
343+
344+
/**
345+
* simple depth-first-search to cover all nodes
346+
*
347+
* @see https://en.wikipedia.org/wiki/Depth-first_search
348+
*/
349+
while (branch.length > 0) {
350+
const node = branch.pop();
351+
352+
if (node instanceof BranchNode) {
353+
node.disabled = value;
354+
branch.push(...node.children);
355+
}
356+
}
357+
}
358+
333359
maximizedView(): IGridView | undefined {
334360
return this._maximizedNode?.leaf.view;
335361
}
@@ -439,7 +465,8 @@ export class Gridview implements IDisposable {
439465
this.proportionalLayout,
440466
this.styles,
441467
this.root.size,
442-
this.root.orthogonalSize
468+
this.root.orthogonalSize,
469+
this._locked
443470
);
444471
}
445472

@@ -499,8 +526,8 @@ export class Gridview implements IDisposable {
499526
this.proportionalLayout,
500527
this.styles,
501528
node.size, // <- orthogonal size - flips at each depth
502-
orthogonalSize, // <- size - flips at each depth
503-
529+
orthogonalSize, // <- size - flips at each depth,
530+
this._locked,
504531
children
505532
);
506533
} else {
@@ -552,7 +579,8 @@ export class Gridview implements IDisposable {
552579
this.proportionalLayout,
553580
this.styles,
554581
this.root.orthogonalSize,
555-
this.root.size
582+
this.root.size,
583+
this._locked
556584
);
557585

558586
if (oldRoot.children.length === 0) {
@@ -667,7 +695,8 @@ export class Gridview implements IDisposable {
667695
proportionalLayout,
668696
styles,
669697
0,
670-
0
698+
0,
699+
this._locked
671700
);
672701
}
673702

@@ -751,7 +780,8 @@ export class Gridview implements IDisposable {
751780
this.proportionalLayout,
752781
this.styles,
753782
parent.size,
754-
parent.orthogonalSize
783+
parent.orthogonalSize,
784+
this._locked
755785
);
756786
grandParent.addChild(newParent, parent.size, parentIndex);
757787

packages/dockview-core/src/splitview/splitview.scss

+6
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
height: 100%;
2626
width: 100%;
2727

28+
&.dv-splitview-disabled {
29+
& > .sash-container > .sash {
30+
pointer-events: none;
31+
}
32+
}
33+
2834
&.animation {
2935
.view,
3036
.sash {

packages/dockview-core/src/splitview/splitview.ts

+11
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ export class Splitview {
109109
private proportionalLayout: boolean;
110110
private _startSnappingEnabled = true;
111111
private _endSnappingEnabled = true;
112+
private _disabled = false;
112113

113114
private readonly _onDidSashEnd = new Emitter<void>();
114115
readonly onDidSashEnd = this._onDidSashEnd.event;
@@ -200,6 +201,16 @@ export class Splitview {
200201
this.updateSashEnablement();
201202
}
202203

204+
get disabled(): boolean {
205+
return this._disabled;
206+
}
207+
208+
set disabled(value: boolean) {
209+
this._disabled = value;
210+
211+
toggleClass(this.element, 'dv-splitview-disabled', value);
212+
}
213+
203214
constructor(
204215
private readonly container: HTMLElement,
205216
options: SplitViewOptions

packages/dockview/src/dockview/dockview.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export interface IDockviewReactProps {
8383
debug?: boolean;
8484
defaultRenderer?: DockviewPanelRenderer;
8585
rootOverlayModel?: DroptargetOverlayModel;
86+
locked?: boolean;
8687
disableDnd?: boolean;
8788
}
8889

@@ -186,6 +187,7 @@ export const DockviewReact = React.forwardRef(
186187
defaultRenderer: props.defaultRenderer,
187188
debug: props.debug,
188189
rootOverlayModel: props.rootOverlayModel,
190+
locked: props.locked,
189191
disableDnd: props.disableDnd,
190192
});
191193

@@ -207,6 +209,15 @@ export const DockviewReact = React.forwardRef(
207209
if (!dockviewRef.current) {
208210
return;
209211
}
212+
213+
dockviewRef.current.locked = !!props.locked;
214+
}, [props.locked]);
215+
216+
React.useEffect(() => {
217+
if (!dockviewRef.current) {
218+
return;
219+
}
220+
210221
dockviewRef.current.updateOptions({
211222
disableDnd: props.disableDnd,
212223
});

0 commit comments

Comments
 (0)