Merge pull request #461 from mathuo/460-locked-mode-prevent-all-mouse-resizing

feat: locked mode
This commit is contained in:
mathuo 2024-01-30 19:58:31 +00:00 committed by GitHub
commit d488e8c3d9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 91 additions and 8 deletions

View File

@ -380,6 +380,7 @@ export class DockviewComponent
styles: options.styles, styles: options.styles,
parentElement: options.parentElement, parentElement: options.parentElement,
disableAutoResizing: options.disableAutoResizing, disableAutoResizing: options.disableAutoResizing,
locked: options.locked,
}); });
const gready = document.createElement('div'); const gready = document.createElement('div');

View File

@ -102,6 +102,7 @@ export interface DockviewComponentOptions extends DockviewRenderFunctions {
defaultRenderer?: DockviewPanelRenderer; defaultRenderer?: DockviewPanelRenderer;
debug?: boolean; debug?: boolean;
rootOverlayModel?: DroptargetOverlayModel; rootOverlayModel?: DroptargetOverlayModel;
locked?: boolean;
disableDnd?: boolean; disableDnd?: boolean;
} }

View File

@ -34,6 +34,7 @@ export interface BaseGridOptions {
readonly styles?: ISplitviewStyles; readonly styles?: ISplitviewStyles;
readonly parentElement: HTMLElement; readonly parentElement: HTMLElement;
readonly disableAutoResizing?: boolean; readonly disableAutoResizing?: boolean;
readonly locked?: boolean;
} }
export interface IGridPanelView extends IGridView, IPanel { export interface IGridPanelView extends IGridView, IPanel {
@ -133,6 +134,14 @@ export abstract class BaseGrid<T extends IGridPanelView>
return this._activeGroup; return this._activeGroup;
} }
get locked(): boolean {
return this.gridview.locked;
}
set locked(value: boolean) {
this.gridview.locked = value;
}
constructor(options: BaseGridOptions) { constructor(options: BaseGridOptions) {
super(document.createElement('div'), options.disableAutoResizing); super(document.createElement('div'), options.disableAutoResizing);
@ -144,6 +153,8 @@ export abstract class BaseGrid<T extends IGridPanelView>
options.orientation options.orientation
); );
this.gridview.locked = !!options.locked;
this.element.appendChild(this.gridview.element); this.element.appendChild(this.gridview.element);
this.layout(0, 0, true); // set some elements height/widths this.layout(0, 0, true); // set some elements height/widths

View File

@ -131,17 +131,27 @@ export class BranchNode extends CompositeDisposable implements IView {
return LayoutPriority.Normal; return LayoutPriority.Normal;
} }
get disabled(): boolean {
return this.splitview.disabled;
}
set disabled(value: boolean) {
this.splitview.disabled = value;
}
constructor( constructor(
readonly orientation: Orientation, readonly orientation: Orientation,
readonly proportionalLayout: boolean, readonly proportionalLayout: boolean,
readonly styles: ISplitviewStyles | undefined, readonly styles: ISplitviewStyles | undefined,
size: number, size: number,
orthogonalSize: number, orthogonalSize: number,
disabled: boolean,
childDescriptors?: INodeDescriptor[] childDescriptors?: INodeDescriptor[]
) { ) {
super(); super();
this._orthogonalSize = orthogonalSize; this._orthogonalSize = orthogonalSize;
this._size = size; this._size = size;
this.element = document.createElement('div'); this.element = document.createElement('div');
this.element.className = 'branch-node'; this.element.className = 'branch-node';
@ -177,6 +187,8 @@ export class BranchNode extends CompositeDisposable implements IView {
}); });
} }
this.disabled = disabled;
this.addDisposables( this.addDisposables(
this._onDidChange, this._onDidChange,
this._onDidVisibilityChange, this._onDidVisibilityChange,
@ -202,7 +214,7 @@ export class BranchNode extends CompositeDisposable implements IView {
return this.splitview.isViewVisible(index); return this.splitview.isViewVisible(index);
} }
setChildVisible(index: number, visible: boolean): void { setChildVisible(index: number, visible: boolean): void {
if (index < 0 || index >= this.children.length) { if (index < 0 || index >= this.children.length) {
throw new Error('Invalid index'); throw new Error('Invalid index');
} }

View File

@ -41,7 +41,8 @@ function flipNode<T extends Node>(
node.proportionalLayout, node.proportionalLayout,
node.styles, node.styles,
size, size,
orthogonalSize orthogonalSize,
node.disabled
); );
let totalSize = 0; let totalSize = 0;
@ -273,6 +274,7 @@ export class Gridview implements IDisposable {
readonly element: HTMLElement; readonly element: HTMLElement;
private _root: BranchNode | undefined; private _root: BranchNode | undefined;
private _locked = false;
private _maximizedNode: private _maximizedNode:
| { leaf: LeafNode; hiddenOnMaximize: LeafNode[] } | { leaf: LeafNode; hiddenOnMaximize: LeafNode[] }
| undefined = undefined; | undefined = undefined;
@ -330,6 +332,30 @@ export class Gridview implements IDisposable {
return this.root.maximumHeight; 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 { maximizedView(): IGridView | undefined {
return this._maximizedNode?.leaf.view; return this._maximizedNode?.leaf.view;
} }
@ -439,7 +465,8 @@ export class Gridview implements IDisposable {
this.proportionalLayout, this.proportionalLayout,
this.styles, this.styles,
this.root.size, this.root.size,
this.root.orthogonalSize this.root.orthogonalSize,
this._locked
); );
} }
@ -499,8 +526,8 @@ export class Gridview implements IDisposable {
this.proportionalLayout, this.proportionalLayout,
this.styles, this.styles,
node.size, // <- orthogonal size - flips at each depth node.size, // <- orthogonal size - flips at each depth
orthogonalSize, // <- size - flips at each depth orthogonalSize, // <- size - flips at each depth,
this._locked,
children children
); );
} else { } else {
@ -552,7 +579,8 @@ export class Gridview implements IDisposable {
this.proportionalLayout, this.proportionalLayout,
this.styles, this.styles,
this.root.orthogonalSize, this.root.orthogonalSize,
this.root.size this.root.size,
this._locked
); );
if (oldRoot.children.length === 0) { if (oldRoot.children.length === 0) {
@ -667,7 +695,8 @@ export class Gridview implements IDisposable {
proportionalLayout, proportionalLayout,
styles, styles,
0, 0,
0 0,
this._locked
); );
} }
@ -751,7 +780,8 @@ export class Gridview implements IDisposable {
this.proportionalLayout, this.proportionalLayout,
this.styles, this.styles,
parent.size, parent.size,
parent.orthogonalSize parent.orthogonalSize,
this._locked
); );
grandParent.addChild(newParent, parent.size, parentIndex); grandParent.addChild(newParent, parent.size, parentIndex);

View File

@ -25,6 +25,12 @@
height: 100%; height: 100%;
width: 100%; width: 100%;
&.dv-splitview-disabled {
& > .sash-container > .sash {
pointer-events: none;
}
}
&.animation { &.animation {
.view, .view,
.sash { .sash {

View File

@ -109,6 +109,7 @@ export class Splitview {
private proportionalLayout: boolean; private proportionalLayout: boolean;
private _startSnappingEnabled = true; private _startSnappingEnabled = true;
private _endSnappingEnabled = true; private _endSnappingEnabled = true;
private _disabled = false;
private readonly _onDidSashEnd = new Emitter<void>(); private readonly _onDidSashEnd = new Emitter<void>();
readonly onDidSashEnd = this._onDidSashEnd.event; readonly onDidSashEnd = this._onDidSashEnd.event;
@ -200,6 +201,16 @@ export class Splitview {
this.updateSashEnablement(); this.updateSashEnablement();
} }
get disabled(): boolean {
return this._disabled;
}
set disabled(value: boolean) {
this._disabled = value;
toggleClass(this.element, 'dv-splitview-disabled', value);
}
constructor( constructor(
private readonly container: HTMLElement, private readonly container: HTMLElement,
options: SplitViewOptions options: SplitViewOptions

View File

@ -83,6 +83,7 @@ export interface IDockviewReactProps {
debug?: boolean; debug?: boolean;
defaultRenderer?: DockviewPanelRenderer; defaultRenderer?: DockviewPanelRenderer;
rootOverlayModel?: DroptargetOverlayModel; rootOverlayModel?: DroptargetOverlayModel;
locked?: boolean;
disableDnd?: boolean; disableDnd?: boolean;
} }
@ -186,6 +187,7 @@ export const DockviewReact = React.forwardRef(
defaultRenderer: props.defaultRenderer, defaultRenderer: props.defaultRenderer,
debug: props.debug, debug: props.debug,
rootOverlayModel: props.rootOverlayModel, rootOverlayModel: props.rootOverlayModel,
locked: props.locked,
disableDnd: props.disableDnd, disableDnd: props.disableDnd,
}); });
@ -207,6 +209,15 @@ export const DockviewReact = React.forwardRef(
if (!dockviewRef.current) { if (!dockviewRef.current) {
return; return;
} }
dockviewRef.current.locked = !!props.locked;
}, [props.locked]);
React.useEffect(() => {
if (!dockviewRef.current) {
return;
}
dockviewRef.current.updateOptions({ dockviewRef.current.updateOptions({
disableDnd: props.disableDnd, disableDnd: props.disableDnd,
}); });