dockview-core
Advanced tools
Comparing version 1.14.2 to 1.15.0
@@ -1,2 +0,2 @@ | ||
import { IDockviewComponent, SerializedDockview } from '../dockview/dockviewComponent'; | ||
import { FloatingGroupOptions, IDockviewComponent, MovePanelEvent, SerializedDockview } from '../dockview/dockviewComponent'; | ||
import { AddGroupOptions, AddPanelOptions, DockviewDndOverlayEvent, MovementOptions } from '../dockview/options'; | ||
@@ -357,2 +357,3 @@ import { Parameters } from '../panel/types'; | ||
get onDidRemovePanel(): Event<IDockviewPanel>; | ||
get onDidMovePanel(): Event<MovePanelEvent>; | ||
/** | ||
@@ -454,6 +455,3 @@ * Invoked after a layout is deserialzied using the `fromJSON` method. | ||
*/ | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, coord?: { | ||
x: number; | ||
y: number; | ||
}): void; | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, options?: FloatingGroupOptions): void; | ||
/** | ||
@@ -498,2 +496,3 @@ * Create a component from a serialized object. | ||
}): Promise<void>; | ||
setGap(gap: number | undefined): void; | ||
} |
@@ -712,2 +712,9 @@ "use strict"; | ||
}); | ||
Object.defineProperty(DockviewApi.prototype, "onDidMovePanel", { | ||
get: function () { | ||
return this.component.onDidMovePanel; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(DockviewApi.prototype, "onDidLayoutFromJSON", { | ||
@@ -899,4 +906,4 @@ /** | ||
*/ | ||
DockviewApi.prototype.addFloatingGroup = function (item, coord) { | ||
return this.component.addFloatingGroup(item, coord); | ||
DockviewApi.prototype.addFloatingGroup = function (item, options) { | ||
return this.component.addFloatingGroup(item, options); | ||
}; | ||
@@ -955,4 +962,7 @@ /** | ||
}; | ||
DockviewApi.prototype.setGap = function (gap) { | ||
this.component.updateOptions({ gap: gap }); | ||
}; | ||
return DockviewApi; | ||
}()); | ||
exports.DockviewApi = DockviewApi; |
@@ -5,2 +5,4 @@ export declare const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100; | ||
top: number; | ||
width: number; | ||
height: number; | ||
}; |
@@ -5,2 +5,2 @@ "use strict"; | ||
exports.DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100; | ||
exports.DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100 }; | ||
exports.DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100, width: 300, height: 300 }; |
import { Event } from '../events'; | ||
import { CompositeDisposable } from '../lifecycle'; | ||
import { Box } from '../types'; | ||
import { AnchoredBox } from '../types'; | ||
export declare class Overlay extends CompositeDisposable { | ||
@@ -13,5 +13,7 @@ private readonly options; | ||
private static MINIMUM_WIDTH; | ||
private verticalAlignment; | ||
private horiziontalAlignment; | ||
set minimumInViewportWidth(value: number | undefined); | ||
set minimumInViewportHeight(value: number | undefined); | ||
constructor(options: Box & { | ||
constructor(options: AnchoredBox & { | ||
container: HTMLElement; | ||
@@ -22,4 +24,4 @@ content: HTMLElement; | ||
}); | ||
setBounds(bounds?: Partial<Box>): void; | ||
toJSON(): Box; | ||
setBounds(bounds?: Partial<AnchoredBox>): void; | ||
toJSON(): AnchoredBox; | ||
setupDrag(dragTarget: HTMLElement, options?: { | ||
@@ -26,0 +28,0 @@ inDragMode: boolean; |
@@ -17,2 +17,13 @@ "use strict"; | ||
})(); | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
@@ -94,8 +105,3 @@ var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
// if input bad resize within acceptable boundaries | ||
_this.setBounds({ | ||
height: _this.options.height, | ||
width: _this.options.width, | ||
top: _this.options.top, | ||
left: _this.options.left, | ||
}); | ||
_this.setBounds(__assign(__assign(__assign(__assign({ height: _this.options.height, width: _this.options.width }, ('top' in _this.options && { top: _this.options.top })), ('bottom' in _this.options && { bottom: _this.options.bottom })), ('left' in _this.options && { left: _this.options.left })), ('right' in _this.options && { right: _this.options.right }))); | ||
return _this; | ||
@@ -125,8 +131,22 @@ } | ||
} | ||
if (typeof bounds.top === 'number') { | ||
if ('top' in bounds && typeof bounds.top === 'number') { | ||
this._element.style.top = "".concat(bounds.top, "px"); | ||
this._element.style.bottom = 'auto'; | ||
this.verticalAlignment = 'top'; | ||
} | ||
if (typeof bounds.left === 'number') { | ||
if ('bottom' in bounds && typeof bounds.bottom === 'number') { | ||
this._element.style.bottom = "".concat(bounds.bottom, "px"); | ||
this._element.style.top = 'auto'; | ||
this.verticalAlignment = 'bottom'; | ||
} | ||
if ('left' in bounds && typeof bounds.left === 'number') { | ||
this._element.style.left = "".concat(bounds.left, "px"); | ||
this._element.style.right = 'auto'; | ||
this.horiziontalAlignment = 'left'; | ||
} | ||
if ('right' in bounds && typeof bounds.right === 'number') { | ||
this._element.style.right = "".concat(bounds.right, "px"); | ||
this._element.style.left = 'auto'; | ||
this.horiziontalAlignment = 'right'; | ||
} | ||
var containerRect = this.options.container.getBoundingClientRect(); | ||
@@ -138,9 +158,23 @@ var overlayRect = this._element.getBoundingClientRect(); | ||
// a minimum height of minimumViewportHeight must be inside the viewport | ||
var yOffset = typeof this.options.minimumInViewportHeight === 'number' | ||
? Math.max(0, this.getMinimumHeight(overlayRect.height)) | ||
: 0; | ||
var left = (0, math_1.clamp)(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset)); | ||
var top = (0, math_1.clamp)(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
this._element.style.left = "".concat(left, "px"); | ||
this._element.style.top = "".concat(top, "px"); | ||
var yOffset = Math.max(0, this.getMinimumHeight(overlayRect.height)); | ||
if (this.verticalAlignment === 'top') { | ||
var top_1 = (0, math_1.clamp)(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
this._element.style.top = "".concat(top_1, "px"); | ||
this._element.style.bottom = 'auto'; | ||
} | ||
if (this.verticalAlignment === 'bottom') { | ||
var bottom = (0, math_1.clamp)(containerRect.bottom - overlayRect.bottom, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
this._element.style.bottom = "".concat(bottom, "px"); | ||
this._element.style.top = 'auto'; | ||
} | ||
if (this.horiziontalAlignment === 'left') { | ||
var left = (0, math_1.clamp)(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset)); | ||
this._element.style.left = "".concat(left, "px"); | ||
this._element.style.right = 'auto'; | ||
} | ||
if (this.horiziontalAlignment === 'right') { | ||
var right = (0, math_1.clamp)(containerRect.right - overlayRect.right, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset)); | ||
this._element.style.right = "".concat(right, "px"); | ||
this._element.style.left = 'auto'; | ||
} | ||
this._onDidChange.fire(); | ||
@@ -151,8 +185,24 @@ }; | ||
var element = this._element.getBoundingClientRect(); | ||
return { | ||
top: element.top - container.top, | ||
left: element.left - container.left, | ||
width: element.width, | ||
height: element.height, | ||
}; | ||
var result = {}; | ||
if (this.verticalAlignment === 'top') { | ||
result.top = parseFloat(this._element.style.top); | ||
} | ||
else if (this.verticalAlignment === 'bottom') { | ||
result.bottom = parseFloat(this._element.style.bottom); | ||
} | ||
else { | ||
result.top = element.top - container.top; | ||
} | ||
if (this.horiziontalAlignment === 'left') { | ||
result.left = parseFloat(this._element.style.left); | ||
} | ||
else if (this.horiziontalAlignment === 'right') { | ||
result.right = parseFloat(this._element.style.right); | ||
} | ||
else { | ||
result.left = element.left - container.left; | ||
} | ||
result.width = element.width; | ||
result.height = element.height; | ||
return result; | ||
}; | ||
@@ -210,8 +260,26 @@ Overlay.prototype.setupDrag = function (dragTarget, options) { | ||
var xOffset = Math.max(0, _this.getMinimumWidth(overlayRect.width)); | ||
var yOffset = Math.max(0, _this.options.minimumInViewportHeight | ||
? _this.getMinimumHeight(overlayRect.height) | ||
: 0); | ||
var yOffset = Math.max(0, _this.getMinimumHeight(overlayRect.height)); | ||
var top = (0, math_1.clamp)(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
var bottom = (0, math_1.clamp)(offset.y - | ||
y + | ||
containerRect.height - | ||
overlayRect.height, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
var left = (0, math_1.clamp)(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset)); | ||
var top = (0, math_1.clamp)(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
_this.setBounds({ top: top, left: left }); | ||
var right = (0, math_1.clamp)(offset.x - x + containerRect.width - overlayRect.width, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset)); | ||
var bounds = {}; | ||
// Anchor to top or to bottom depending on which one is closer | ||
if (top <= bottom) { | ||
bounds.top = top; | ||
} | ||
else { | ||
bounds.bottom = bottom; | ||
} | ||
// Anchor to left or to right depending on which one is closer | ||
if (left <= right) { | ||
bounds.left = left; | ||
} | ||
else { | ||
bounds.right = right; | ||
} | ||
_this.setBounds(bounds); | ||
}), (0, events_1.addDisposableWindowListener)(window, 'mouseup', function () { | ||
@@ -293,4 +361,6 @@ (0, dom_1.toggleClass)(_this._element, 'dv-resize-container-dragging', false); | ||
var top = undefined; | ||
var bottom = undefined; | ||
var height = undefined; | ||
var left = undefined; | ||
var right = undefined; | ||
var width = undefined; | ||
@@ -309,2 +379,3 @@ var moveTop = function () { | ||
top; | ||
bottom = containerRect.height - top - height; | ||
}; | ||
@@ -321,2 +392,3 @@ var moveBottom = function () { | ||
: Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE); | ||
bottom = containerRect.height - top - height; | ||
}; | ||
@@ -335,2 +407,3 @@ var moveLeft = function () { | ||
left; | ||
right = containerRect.width - left - width; | ||
}; | ||
@@ -347,2 +420,3 @@ var moveRight = function () { | ||
: Overlay.MINIMUM_WIDTH, Number.MAX_VALUE); | ||
right = containerRect.width - left - width; | ||
}; | ||
@@ -379,3 +453,20 @@ switch (direction) { | ||
} | ||
_this.setBounds({ height: height, width: width, top: top, left: left }); | ||
var bounds = {}; | ||
// Anchor to top or to bottom depending on which one is closer | ||
if (top <= bottom) { | ||
bounds.top = top; | ||
} | ||
else { | ||
bounds.bottom = bottom; | ||
} | ||
// Anchor to left or to right depending on which one is closer | ||
if (left <= right) { | ||
bounds.left = left; | ||
} | ||
else { | ||
bounds.right = right; | ||
} | ||
bounds.height = height; | ||
bounds.width = width; | ||
_this.setBounds(bounds); | ||
}), { | ||
@@ -414,3 +505,3 @@ dispose: function () { | ||
} | ||
return height; | ||
return 0; | ||
}; | ||
@@ -417,0 +508,0 @@ Overlay.prototype.dispose = function () { |
@@ -133,3 +133,4 @@ "use strict"; | ||
y: top_1 - rootTop + 20, | ||
}, { inDragMode: true }); | ||
inDragMode: true, | ||
}); | ||
} | ||
@@ -291,3 +292,4 @@ }), (0, events_1.addDisposableListener)(_this.tabContainer, 'mousedown', function (event) { | ||
y: top_2 - rootTop, | ||
}, { inDragMode: true }); | ||
inDragMode: true, | ||
}); | ||
return; | ||
@@ -294,0 +296,0 @@ } |
@@ -14,3 +14,3 @@ import { SerializedGridObject } from '../gridview/gridview'; | ||
import { GroupDragEvent, TabDragEvent } from './components/titlebar/tabsContainer'; | ||
import { Box } from '../types'; | ||
import { AnchoredBox, Box } from '../types'; | ||
import { DockviewPanelRenderer, OverlayRenderContainer } from '../overlayRenderContainer'; | ||
@@ -27,3 +27,3 @@ export interface PanelReference { | ||
data: GroupPanelViewState; | ||
position: Box; | ||
position: AnchoredBox; | ||
} | ||
@@ -47,2 +47,6 @@ export interface SerializedPopoutGroup { | ||
} | ||
export interface MovePanelEvent { | ||
panel: IDockviewPanel; | ||
from: DockviewGroupPanel; | ||
} | ||
type MoveGroupOptions = { | ||
@@ -68,2 +72,12 @@ from: { | ||
}; | ||
export interface FloatingGroupOptions { | ||
x?: number; | ||
y?: number; | ||
height?: number; | ||
width?: number; | ||
position?: AnchoredBox; | ||
skipRemoveGroup?: boolean; | ||
inDragMode?: boolean; | ||
skipActiveGroup?: boolean; | ||
} | ||
export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> { | ||
@@ -87,2 +101,3 @@ readonly activePanel: IDockviewPanel | undefined; | ||
readonly onUnhandledDragOverEvent: Event<DockviewDndOverlayEvent>; | ||
readonly onDidMovePanel: Event<MovePanelEvent>; | ||
readonly options: DockviewComponentOptions; | ||
@@ -106,6 +121,3 @@ updateOptions(options: DockviewOptions): void; | ||
fromJSON(data: SerializedDockview): void; | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, coord?: { | ||
x: number; | ||
y: number; | ||
}): void; | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, options?: FloatingGroupOptions): void; | ||
addPopoutGroup(item: IDockviewPanel | DockviewGroupPanel, options?: { | ||
@@ -152,6 +164,6 @@ position?: Box; | ||
private readonly _onDidMovePanel; | ||
readonly onDidMovePanel: Event<MovePanelEvent>; | ||
private readonly _floatingGroups; | ||
private readonly _popoutGroups; | ||
private readonly _rootDropTarget; | ||
private _ignoreEvents; | ||
private readonly _onDidRemoveGroup; | ||
@@ -185,12 +197,3 @@ readonly onDidRemoveGroup: Event<DockviewGroupPanel>; | ||
}): Promise<void>; | ||
addFloatingGroup(item: DockviewPanel | DockviewGroupPanel, coord?: { | ||
x?: number; | ||
y?: number; | ||
height?: number; | ||
width?: number; | ||
}, options?: { | ||
skipRemoveGroup?: boolean; | ||
inDragMode: boolean; | ||
skipActiveGroup?: boolean; | ||
}): void; | ||
addFloatingGroup(item: DockviewPanel | DockviewGroupPanel, options?: FloatingGroupOptions): void; | ||
private orthogonalize; | ||
@@ -197,0 +200,0 @@ updateOptions(options: Partial<DockviewComponentOptions>): void; |
import { Overlay } from '../dnd/overlay'; | ||
import { CompositeDisposable } from '../lifecycle'; | ||
import { AnchoredBox } from '../types'; | ||
import { DockviewGroupPanel, IDockviewGroupPanel } from './dockviewGroupPanel'; | ||
export interface IDockviewFloatingGroupPanel { | ||
readonly group: IDockviewGroupPanel; | ||
position(bounds: Partial<{ | ||
top: number; | ||
left: number; | ||
height: number; | ||
width: number; | ||
}>): void; | ||
position(bounds: Partial<AnchoredBox>): void; | ||
} | ||
@@ -17,8 +13,3 @@ export declare class DockviewFloatingGroupPanel extends CompositeDisposable implements IDockviewFloatingGroupPanel { | ||
constructor(group: DockviewGroupPanel, overlay: Overlay); | ||
position(bounds: Partial<{ | ||
top: number; | ||
left: number; | ||
height: number; | ||
width: number; | ||
}>): void; | ||
position(bounds: Partial<AnchoredBox>): void; | ||
} |
@@ -14,2 +14,3 @@ import { DockviewApi } from '../api/component.api'; | ||
import { IGroupHeaderProps } from './framework'; | ||
import { AnchoredBox } from '../types'; | ||
export interface IHeaderActionsRenderer extends IDisposable { | ||
@@ -29,2 +30,6 @@ readonly element: HTMLElement; | ||
export interface DockviewOptions { | ||
/** | ||
* Disable the auto-resizing which is controlled through a `ResizeObserver`. | ||
* Call `.layout(width, height)` to manually resize the container. | ||
*/ | ||
disableAutoResizing?: boolean; | ||
@@ -44,2 +49,6 @@ hideBorders?: boolean; | ||
disableDnd?: boolean; | ||
/** | ||
* Pixel gap between groups | ||
*/ | ||
gap?: number; | ||
} | ||
@@ -106,8 +115,3 @@ export interface DockviewDndOverlayEvent { | ||
type AddPanelFloatingGroupUnion = { | ||
floating: { | ||
height?: number; | ||
width?: number; | ||
x?: number; | ||
y?: number; | ||
} | true; | ||
floating: Partial<AnchoredBox> | true; | ||
position: never; | ||
@@ -114,0 +118,0 @@ }; |
@@ -43,2 +43,3 @@ "use strict"; | ||
disableDnd: undefined, | ||
gap: undefined, | ||
}; | ||
@@ -45,0 +46,0 @@ return Object.keys(properties); |
@@ -29,1 +29,2 @@ import { Event as DockviewEvent } from './events'; | ||
export declare function isInDocument(element: Element): boolean; | ||
export declare function addTestId(element: HTMLElement, id: string): void; |
@@ -29,3 +29,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.isInDocument = exports.getDomNodePagePosition = exports.addStyles = exports.quasiDefaultPrevented = exports.quasiPreventDefault = exports.trackFocus = exports.getElementsByTagName = exports.isAncestor = exports.toggleClass = exports.addClasses = exports.removeClasses = exports.watchElementResize = void 0; | ||
exports.addTestId = exports.isInDocument = exports.getDomNodePagePosition = exports.addStyles = exports.quasiDefaultPrevented = exports.quasiPreventDefault = exports.trackFocus = exports.getElementsByTagName = exports.isAncestor = exports.toggleClass = exports.addClasses = exports.removeClasses = exports.watchElementResize = void 0; | ||
var events_1 = require("./events"); | ||
@@ -278,1 +278,5 @@ var lifecycle_1 = require("./lifecycle"); | ||
exports.isInDocument = isInDocument; | ||
function addTestId(element, id) { | ||
element.setAttribute('data-testid', id); | ||
} | ||
exports.addTestId = addTestId; |
@@ -18,2 +18,3 @@ import { Event, AsapEvent } from '../events'; | ||
readonly locked?: boolean; | ||
readonly margin?: number; | ||
} | ||
@@ -63,2 +64,4 @@ export interface IGridPanelView extends IGridView, IPanel { | ||
readonly onDidLayoutChange: Event<void>; | ||
private readonly _onDidViewVisibilityChangeMicroTaskQueue; | ||
readonly onDidViewVisibilityChangeMicroTaskQueue: Event<void>; | ||
get id(): string; | ||
@@ -65,0 +68,0 @@ get size(): number; |
@@ -67,10 +67,16 @@ "use strict"; | ||
_this.onDidLayoutChange = _this._bufferOnDidLayoutChange.onEvent; | ||
_this._onDidViewVisibilityChangeMicroTaskQueue = new events_1.AsapEvent(); | ||
_this.onDidViewVisibilityChangeMicroTaskQueue = _this._onDidViewVisibilityChangeMicroTaskQueue.onEvent; | ||
_this.element.style.height = '100%'; | ||
_this.element.style.width = '100%'; | ||
options.parentElement.appendChild(_this.element); | ||
_this.gridview = new gridview_1.Gridview(!!options.proportionalLayout, options.styles, options.orientation); | ||
_this.gridview = new gridview_1.Gridview(!!options.proportionalLayout, options.styles, options.orientation, options.locked, options.margin); | ||
_this.gridview.locked = !!options.locked; | ||
_this.element.appendChild(_this.gridview.element); | ||
_this.layout(0, 0, true); // set some elements height/widths | ||
_this.addDisposables(lifecycle_1.Disposable.from(function () { | ||
_this.addDisposables(_this.gridview.onDidViewVisibilityChange(function () { | ||
return _this._onDidViewVisibilityChangeMicroTaskQueue.fire(); | ||
}), _this.onDidViewVisibilityChangeMicroTaskQueue(function () { | ||
_this.layout(_this.width, _this.height, true); | ||
}), lifecycle_1.Disposable.from(function () { | ||
var _a; | ||
@@ -77,0 +83,0 @@ (_a = _this.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(_this.element); |
@@ -22,3 +22,5 @@ import { IView, Orientation, Sizing, LayoutPriority, ISplitviewStyles } from '../splitview/splitview'; | ||
private readonly _onDidVisibilityChange; | ||
readonly onDidVisibilityChange: Event<boolean>; | ||
readonly onDidVisibilityChange: Event<{ | ||
visible: boolean; | ||
}>; | ||
get width(): number; | ||
@@ -39,4 +41,6 @@ get height(): number; | ||
set disabled(value: boolean); | ||
constructor(orientation: Orientation, proportionalLayout: boolean, styles: ISplitviewStyles | undefined, size: number, orthogonalSize: number, disabled: boolean, childDescriptors?: INodeDescriptor[]); | ||
setVisible(visible: boolean): void; | ||
get margin(): number; | ||
set margin(value: number); | ||
constructor(orientation: Orientation, proportionalLayout: boolean, styles: ISplitviewStyles | undefined, size: number, orthogonalSize: number, disabled: boolean, margin: number | undefined, childDescriptors?: INodeDescriptor[]); | ||
setVisible(_visible: boolean): void; | ||
isChildVisible(index: number): boolean; | ||
@@ -43,0 +47,0 @@ setChildVisible(index: number, visible: boolean): void; |
@@ -46,13 +46,2 @@ "use strict"; | ||
}; | ||
var __values = (this && this.__values) || function(o) { | ||
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; | ||
if (m) return m.call(o); | ||
if (o && typeof o.length === "number") return { | ||
next: function () { | ||
if (o && i >= o.length) o = void 0; | ||
return { value: o && o[i++], done: !o }; | ||
} | ||
}; | ||
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -66,3 +55,3 @@ exports.BranchNode = void 0; | ||
__extends(BranchNode, _super); | ||
function BranchNode(orientation, proportionalLayout, styles, size, orthogonalSize, disabled, childDescriptors) { | ||
function BranchNode(orientation, proportionalLayout, styles, size, orthogonalSize, disabled, margin, childDescriptors) { | ||
var _this = _super.call(this) || this; | ||
@@ -87,2 +76,3 @@ _this.orientation = orientation; | ||
styles: styles, | ||
margin: margin, | ||
}); | ||
@@ -111,2 +101,3 @@ _this.splitview.layout(_this.size, _this.orthogonalSize); | ||
styles: styles, | ||
margin: margin, | ||
}); | ||
@@ -260,17 +251,19 @@ } | ||
}); | ||
BranchNode.prototype.setVisible = function (visible) { | ||
var e_1, _a; | ||
try { | ||
for (var _b = __values(this.children), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var child = _c.value; | ||
child.setVisible(visible); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
Object.defineProperty(BranchNode.prototype, "margin", { | ||
get: function () { | ||
return this.splitview.margin; | ||
}, | ||
set: function (value) { | ||
this.splitview.margin = value; | ||
this.children.forEach(function (child) { | ||
if (child instanceof BranchNode) { | ||
child.margin = value; | ||
} | ||
}); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
BranchNode.prototype.setVisible = function (_visible) { | ||
// noop | ||
}; | ||
@@ -292,2 +285,3 @@ BranchNode.prototype.isChildVisible = function (index) { | ||
this.splitview.setViewVisible(index, visible); | ||
// } | ||
var areAllChildrenHidden = this.splitview.contentSize === 0; | ||
@@ -298,3 +292,3 @@ // If all children are hidden then the parent should hide the entire splitview | ||
(!visible && areAllChildrenHidden)) { | ||
this._onDidVisibilityChange.fire(visible); | ||
this._onDidVisibilityChange.fire({ visible: visible }); | ||
} | ||
@@ -373,3 +367,4 @@ }; | ||
if (c instanceof BranchNode) { | ||
return c.onDidVisibilityChange(function (visible) { | ||
return c.onDidVisibilityChange(function (_a) { | ||
var visible = _a.visible; | ||
_this.setChildVisible(i, visible); | ||
@@ -376,0 +371,0 @@ }); |
@@ -29,2 +29,3 @@ import { ISplitviewStyles, LayoutPriority, Orientation, Sizing } from '../splitview/splitview'; | ||
readonly maximumHeight: number; | ||
readonly isVisible: boolean; | ||
priority?: LayoutPriority; | ||
@@ -92,2 +93,3 @@ layout(width: number, height: number): void; | ||
private _locked; | ||
private _margin; | ||
private _maximizedNode; | ||
@@ -100,2 +102,4 @@ private readonly disposable; | ||
}>; | ||
private readonly _onDidViewVisibilityChange; | ||
readonly onDidViewVisibilityChange: Event<void>; | ||
private readonly _onDidMaximizedNodeChange; | ||
@@ -114,2 +118,4 @@ readonly onDidMaximizedNodeChange: Event<void>; | ||
set locked(value: boolean); | ||
get margin(): number; | ||
set margin(value: number); | ||
maximizedView(): IGridView | undefined; | ||
@@ -138,3 +144,3 @@ hasMaximizedView(): boolean; | ||
private progmaticSelect; | ||
constructor(proportionalLayout: boolean, styles: ISplitviewStyles | undefined, orientation: Orientation); | ||
constructor(proportionalLayout: boolean, styles: ISplitviewStyles | undefined, orientation: Orientation, locked?: boolean, margin?: number); | ||
isViewVisible(location: number[]): boolean; | ||
@@ -141,0 +147,0 @@ setViewVisible(location: number[], visible: boolean): void; |
@@ -50,3 +50,3 @@ "use strict"; | ||
if (node instanceof branchNode_1.BranchNode) { | ||
var result = new branchNode_1.BranchNode((0, exports.orthogonal)(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled); | ||
var result = new branchNode_1.BranchNode((0, exports.orthogonal)(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled, node.margin); | ||
var totalSize = 0; | ||
@@ -166,6 +166,7 @@ for (var i = node.children.length - 1; i >= 0; i--) { | ||
var Gridview = /** @class */ (function () { | ||
function Gridview(proportionalLayout, styles, orientation) { | ||
function Gridview(proportionalLayout, styles, orientation, locked, margin) { | ||
this.proportionalLayout = proportionalLayout; | ||
this.styles = styles; | ||
this._locked = false; | ||
this._margin = 0; | ||
this._maximizedNode = undefined; | ||
@@ -175,2 +176,4 @@ this.disposable = new lifecycle_1.MutableDisposable(); | ||
this.onDidChange = this._onDidChange.event; | ||
this._onDidViewVisibilityChange = new events_1.Emitter(); | ||
this.onDidViewVisibilityChange = this._onDidViewVisibilityChange.event; | ||
this._onDidMaximizedNodeChange = new events_1.Emitter(); | ||
@@ -180,3 +183,5 @@ this.onDidMaximizedNodeChange = this._onDidMaximizedNodeChange.event; | ||
this.element.className = 'grid-view'; | ||
this.root = new branchNode_1.BranchNode(orientation, proportionalLayout, styles, 0, 0, this._locked); | ||
this._locked = locked !== null && locked !== void 0 ? locked : false; | ||
this._margin = margin !== null && margin !== void 0 ? margin : 0; | ||
this.root = new branchNode_1.BranchNode(orientation, proportionalLayout, styles, 0, 0, this.locked, this.margin); | ||
} | ||
@@ -270,2 +275,13 @@ Object.defineProperty(Gridview.prototype, "length", { | ||
}); | ||
Object.defineProperty(Gridview.prototype, "margin", { | ||
get: function () { | ||
return this._margin; | ||
}, | ||
set: function (value) { | ||
this._margin = value; | ||
this.root.margin = value; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Gridview.prototype.maximizedView = function () { | ||
@@ -356,2 +372,3 @@ var _a; | ||
this._onDidMaximizedNodeChange.dispose(); | ||
this._onDidViewVisibilityChange.dispose(); | ||
this.root.dispose(); | ||
@@ -363,3 +380,3 @@ this._maximizedNode = undefined; | ||
var orientation = this.root.orientation; | ||
this.root = new branchNode_1.BranchNode(orientation, this.proportionalLayout, this.styles, this.root.size, this.root.orthogonalSize, this._locked); | ||
this.root = new branchNode_1.BranchNode(orientation, this.proportionalLayout, this.styles, this.root.size, this.root.orthogonalSize, this.locked, this.margin); | ||
}; | ||
@@ -376,2 +393,3 @@ Gridview.prototype.deserialize = function (json, deserializer) { | ||
var _this = this; | ||
var _a; | ||
var result; | ||
@@ -388,6 +406,10 @@ if (node.type === 'branch') { | ||
orthogonalSize, // <- size - flips at each depth, | ||
this._locked, children); | ||
this.locked, this.margin, children); | ||
} | ||
else { | ||
result = new leafNode_1.LeafNode(deserializer.fromJSON(node), orientation, orthogonalSize, node.size); | ||
var view = deserializer.fromJSON(node); | ||
if (typeof node.visible === 'boolean') { | ||
(_a = view.setVisible) === null || _a === void 0 ? void 0 : _a.call(view, node.visible); | ||
} | ||
result = new leafNode_1.LeafNode(view, orientation, orthogonalSize, node.size); | ||
} | ||
@@ -428,3 +450,3 @@ return result; | ||
oldRoot.element.remove(); | ||
this._root = new branchNode_1.BranchNode((0, exports.orthogonal)(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size, this._locked); | ||
this._root = new branchNode_1.BranchNode((0, exports.orthogonal)(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size, this.locked, this.margin); | ||
if (oldRoot.children.length === 0) { | ||
@@ -514,2 +536,3 @@ // no data so no need to add anything back in | ||
} | ||
this._onDidViewVisibilityChange.fire(); | ||
parent.setChildVisible(index, visible); | ||
@@ -547,3 +570,3 @@ }; | ||
child.dispose(); | ||
var newParent = new branchNode_1.BranchNode(parent.orientation, this.proportionalLayout, this.styles, parent.size, parent.orthogonalSize, this._locked); | ||
var newParent = new branchNode_1.BranchNode(parent.orientation, this.proportionalLayout, this.styles, parent.size, parent.orthogonalSize, this.locked, this.margin); | ||
grandParent.addChild(newParent, parent.size, parentIndex); | ||
@@ -550,0 +573,0 @@ var newSibling = new leafNode_1.LeafNode(parent.view, grandParent.orientation, parent.size); |
@@ -47,2 +47,3 @@ import { PanelInitParameters } from '../panel/types'; | ||
get isActive(): boolean; | ||
get isVisible(): boolean; | ||
constructor(id: string, component: string, options?: { | ||
@@ -49,0 +50,0 @@ minimumWidth?: number; |
@@ -170,2 +170,9 @@ "use strict"; | ||
}); | ||
Object.defineProperty(GridviewPanel.prototype, "isVisible", { | ||
get: function () { | ||
return this.api.isVisible; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
GridviewPanel.prototype.setVisible = function (isVisible) { | ||
@@ -172,0 +179,0 @@ this.api._onDidVisibilityChange.fire({ isVisible: isVisible }); |
@@ -6,3 +6,7 @@ "use strict"; | ||
if (min > max) { | ||
throw new Error("".concat(min, " > ").concat(max, " is an invalid condition")); | ||
/** | ||
* caveat: an error should be thrown here if this was a proper `clamp` function but we need to handle | ||
* cases where `min` > `max` and in those cases return `min`. | ||
*/ | ||
return min; | ||
} | ||
@@ -9,0 +13,0 @@ return Math.min(max, Math.max(value, min)); |
@@ -21,2 +21,3 @@ import { Event } from '../events'; | ||
readonly styles?: ISplitviewStyles; | ||
readonly margin?: number; | ||
} | ||
@@ -84,2 +85,3 @@ export declare enum LayoutPriority { | ||
private _disabled; | ||
private _margin; | ||
private readonly _onDidSashEnd; | ||
@@ -108,2 +110,4 @@ readonly onDidSashEnd: Event<void>; | ||
set disabled(value: boolean); | ||
get margin(): number; | ||
set margin(value: number); | ||
constructor(container: HTMLElement, options: SplitViewOptions); | ||
@@ -126,2 +130,11 @@ style(styles?: ISplitviewStyles): void; | ||
private saveProportions; | ||
/** | ||
* Margin explain: | ||
* | ||
* For `n` views in a splitview there will be `n-1` margins `m`. | ||
* | ||
* To fit the margins each view must reduce in size by `(m * (n - 1)) / n`. | ||
* | ||
* For each view `i` the offet must be adjusted by `m * i/(n - 1)`. | ||
*/ | ||
private layoutViews; | ||
@@ -128,0 +141,0 @@ private findFirstSnapIndex; |
@@ -82,2 +82,3 @@ "use strict"; | ||
var _this = this; | ||
var _a; | ||
this.container = container; | ||
@@ -93,2 +94,3 @@ this.viewItems = []; | ||
this._disabled = false; | ||
this._margin = 0; | ||
this._onDidSashEnd = new events_1.Emitter(); | ||
@@ -206,2 +208,3 @@ this.onDidSashEnd = this._onDidSashEnd.event; | ||
this.element = this.createContainer(); | ||
this.margin = (_a = options.margin) !== null && _a !== void 0 ? _a : 0; | ||
this.proportionalLayout = | ||
@@ -351,2 +354,12 @@ options.proportionalLayout === undefined | ||
}); | ||
Object.defineProperty(Splitview.prototype, "margin", { | ||
get: function () { | ||
return this._margin; | ||
}, | ||
set: function (value) { | ||
this._margin = value; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Splitview.prototype.style = function (styles) { | ||
@@ -375,5 +388,3 @@ if ((styles === null || styles === void 0 ? void 0 : styles.separatorBorder) === 'transparent') { | ||
} | ||
(0, dom_1.toggleClass)(this.container, 'visible', visible); | ||
var viewItem = this.viewItems[index]; | ||
(0, dom_1.toggleClass)(this.container, 'visible', visible); | ||
viewItem.setVisible(visible, viewItem.size); | ||
@@ -789,12 +800,26 @@ this.distributeEmptySpace(index); | ||
}; | ||
/** | ||
* Margin explain: | ||
* | ||
* For `n` views in a splitview there will be `n-1` margins `m`. | ||
* | ||
* To fit the margins each view must reduce in size by `(m * (n - 1)) / n`. | ||
* | ||
* For each view `i` the offet must be adjusted by `m * i/(n - 1)`. | ||
*/ | ||
Splitview.prototype.layoutViews = function () { | ||
var _this = this; | ||
this._contentSize = this.viewItems.reduce(function (r, i) { return r + i.size; }, 0); | ||
var sum = 0; | ||
var x = []; | ||
this.updateSashEnablement(); | ||
if (this.viewItems.length === 0) { | ||
return; | ||
} | ||
var sashCount = this.viewItems.length - 1; | ||
var marginReducedSize = (this.margin * sashCount) / this.viewItems.length; | ||
var totalLeftOffset = 0; | ||
var viewLeftOffsets = []; | ||
for (var i = 0; i < this.viewItems.length - 1; i++) { | ||
sum += this.viewItems[i].size; | ||
x.push(sum); | ||
var offset = Math.min(Math.max(0, sum - 2), this.size - 4); | ||
totalLeftOffset += this.viewItems[i].size; | ||
viewLeftOffsets.push(totalLeftOffset); | ||
var offset = Math.min(Math.max(0, totalLeftOffset - 2), this.size - this.margin); | ||
if (this._orientation === Orientation.HORIZONTAL) { | ||
@@ -810,5 +835,10 @@ this.sashes[i].container.style.left = "".concat(offset, "px"); | ||
this.viewItems.forEach(function (view, i) { | ||
var size = view.size - marginReducedSize; | ||
var offset = i === 0 | ||
? 0 | ||
: viewLeftOffsets[i - 1] + | ||
(i / sashCount) * marginReducedSize; | ||
if (_this._orientation === Orientation.HORIZONTAL) { | ||
view.container.style.width = "".concat(view.size, "px"); | ||
view.container.style.left = i == 0 ? '0px' : "".concat(x[i - 1], "px"); | ||
view.container.style.width = "".concat(size, "px"); | ||
view.container.style.left = "".concat(offset, "px"); | ||
view.container.style.top = ''; | ||
@@ -818,8 +848,8 @@ view.container.style.height = ''; | ||
if (_this._orientation === Orientation.VERTICAL) { | ||
view.container.style.height = "".concat(view.size, "px"); | ||
view.container.style.top = i == 0 ? '0px' : "".concat(x[i - 1], "px"); | ||
view.container.style.height = "".concat(size, "px"); | ||
view.container.style.top = "".concat(offset, "px"); | ||
view.container.style.width = ''; | ||
view.container.style.left = ''; | ||
} | ||
view.view.layout(view.size, _this._orthogonalSize); | ||
view.view.layout(view.size - marginReducedSize, _this._orthogonalSize); | ||
}); | ||
@@ -826,0 +856,0 @@ }; |
@@ -9,1 +9,24 @@ export type FunctionOrValue<T> = (() => T) | T; | ||
} | ||
type TopLeft = { | ||
top: number; | ||
left: number; | ||
}; | ||
type TopRight = { | ||
top: number; | ||
right: number; | ||
}; | ||
type BottomLeft = { | ||
bottom: number; | ||
left: number; | ||
}; | ||
type BottomRight = { | ||
bottom: number; | ||
right: number; | ||
}; | ||
type AnchorPosition = TopLeft | TopRight | BottomLeft | BottomRight; | ||
type Size = { | ||
width: number; | ||
height: number; | ||
}; | ||
export type AnchoredBox = Size & AnchorPosition; | ||
export {}; |
@@ -1,2 +0,2 @@ | ||
import { IDockviewComponent, SerializedDockview } from '../dockview/dockviewComponent'; | ||
import { FloatingGroupOptions, IDockviewComponent, MovePanelEvent, SerializedDockview } from '../dockview/dockviewComponent'; | ||
import { AddGroupOptions, AddPanelOptions, DockviewDndOverlayEvent, MovementOptions } from '../dockview/options'; | ||
@@ -357,2 +357,3 @@ import { Parameters } from '../panel/types'; | ||
get onDidRemovePanel(): Event<IDockviewPanel>; | ||
get onDidMovePanel(): Event<MovePanelEvent>; | ||
/** | ||
@@ -454,6 +455,3 @@ * Invoked after a layout is deserialzied using the `fromJSON` method. | ||
*/ | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, coord?: { | ||
x: number; | ||
y: number; | ||
}): void; | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, options?: FloatingGroupOptions): void; | ||
/** | ||
@@ -498,2 +496,3 @@ * Create a component from a serialized object. | ||
}): Promise<void>; | ||
setGap(gap: number | undefined): void; | ||
} |
@@ -491,2 +491,5 @@ import { Emitter } from '../events'; | ||
} | ||
get onDidMovePanel() { | ||
return this.component.onDidMovePanel; | ||
} | ||
/** | ||
@@ -632,4 +635,4 @@ * Invoked after a layout is deserialzied using the `fromJSON` method. | ||
*/ | ||
addFloatingGroup(item, coord) { | ||
return this.component.addFloatingGroup(item, coord); | ||
addFloatingGroup(item, options) { | ||
return this.component.addFloatingGroup(item, options); | ||
} | ||
@@ -684,2 +687,5 @@ /** | ||
} | ||
setGap(gap) { | ||
this.component.updateOptions({ gap }); | ||
} | ||
} |
@@ -5,2 +5,4 @@ export declare const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100; | ||
top: number; | ||
width: number; | ||
height: number; | ||
}; |
export const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100; | ||
export const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100 }; | ||
export const DEFAULT_FLOATING_GROUP_POSITION = { left: 100, top: 100, width: 300, height: 300 }; |
import { Event } from '../events'; | ||
import { CompositeDisposable } from '../lifecycle'; | ||
import { Box } from '../types'; | ||
import { AnchoredBox } from '../types'; | ||
export declare class Overlay extends CompositeDisposable { | ||
@@ -13,5 +13,7 @@ private readonly options; | ||
private static MINIMUM_WIDTH; | ||
private verticalAlignment; | ||
private horiziontalAlignment; | ||
set minimumInViewportWidth(value: number | undefined); | ||
set minimumInViewportHeight(value: number | undefined); | ||
constructor(options: Box & { | ||
constructor(options: AnchoredBox & { | ||
container: HTMLElement; | ||
@@ -22,4 +24,4 @@ content: HTMLElement; | ||
}); | ||
setBounds(bounds?: Partial<Box>): void; | ||
toJSON(): Box; | ||
setBounds(bounds?: Partial<AnchoredBox>): void; | ||
toJSON(): AnchoredBox; | ||
setupDrag(dragTarget: HTMLElement, options?: { | ||
@@ -26,0 +28,0 @@ inDragMode: boolean; |
@@ -44,8 +44,3 @@ import { getElementsByTagName, quasiDefaultPrevented, toggleClass, } from '../dom'; | ||
// if input bad resize within acceptable boundaries | ||
this.setBounds({ | ||
height: this.options.height, | ||
width: this.options.width, | ||
top: this.options.top, | ||
left: this.options.left, | ||
}); | ||
this.setBounds(Object.assign(Object.assign(Object.assign(Object.assign({ height: this.options.height, width: this.options.width }, ('top' in this.options && { top: this.options.top })), ('bottom' in this.options && { bottom: this.options.bottom })), ('left' in this.options && { left: this.options.left })), ('right' in this.options && { right: this.options.right }))); | ||
} | ||
@@ -59,8 +54,22 @@ setBounds(bounds = {}) { | ||
} | ||
if (typeof bounds.top === 'number') { | ||
if ('top' in bounds && typeof bounds.top === 'number') { | ||
this._element.style.top = `${bounds.top}px`; | ||
this._element.style.bottom = 'auto'; | ||
this.verticalAlignment = 'top'; | ||
} | ||
if (typeof bounds.left === 'number') { | ||
if ('bottom' in bounds && typeof bounds.bottom === 'number') { | ||
this._element.style.bottom = `${bounds.bottom}px`; | ||
this._element.style.top = 'auto'; | ||
this.verticalAlignment = 'bottom'; | ||
} | ||
if ('left' in bounds && typeof bounds.left === 'number') { | ||
this._element.style.left = `${bounds.left}px`; | ||
this._element.style.right = 'auto'; | ||
this.horiziontalAlignment = 'left'; | ||
} | ||
if ('right' in bounds && typeof bounds.right === 'number') { | ||
this._element.style.right = `${bounds.right}px`; | ||
this._element.style.left = 'auto'; | ||
this.horiziontalAlignment = 'right'; | ||
} | ||
const containerRect = this.options.container.getBoundingClientRect(); | ||
@@ -72,9 +81,23 @@ const overlayRect = this._element.getBoundingClientRect(); | ||
// a minimum height of minimumViewportHeight must be inside the viewport | ||
const yOffset = typeof this.options.minimumInViewportHeight === 'number' | ||
? Math.max(0, this.getMinimumHeight(overlayRect.height)) | ||
: 0; | ||
const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset)); | ||
const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
this._element.style.left = `${left}px`; | ||
this._element.style.top = `${top}px`; | ||
const yOffset = Math.max(0, this.getMinimumHeight(overlayRect.height)); | ||
if (this.verticalAlignment === 'top') { | ||
const top = clamp(overlayRect.top - containerRect.top, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
this._element.style.top = `${top}px`; | ||
this._element.style.bottom = 'auto'; | ||
} | ||
if (this.verticalAlignment === 'bottom') { | ||
const bottom = clamp(containerRect.bottom - overlayRect.bottom, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
this._element.style.bottom = `${bottom}px`; | ||
this._element.style.top = 'auto'; | ||
} | ||
if (this.horiziontalAlignment === 'left') { | ||
const left = clamp(overlayRect.left - containerRect.left, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset)); | ||
this._element.style.left = `${left}px`; | ||
this._element.style.right = 'auto'; | ||
} | ||
if (this.horiziontalAlignment === 'right') { | ||
const right = clamp(containerRect.right - overlayRect.right, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset)); | ||
this._element.style.right = `${right}px`; | ||
this._element.style.left = 'auto'; | ||
} | ||
this._onDidChange.fire(); | ||
@@ -85,8 +108,24 @@ } | ||
const element = this._element.getBoundingClientRect(); | ||
return { | ||
top: element.top - container.top, | ||
left: element.left - container.left, | ||
width: element.width, | ||
height: element.height, | ||
}; | ||
const result = {}; | ||
if (this.verticalAlignment === 'top') { | ||
result.top = parseFloat(this._element.style.top); | ||
} | ||
else if (this.verticalAlignment === 'bottom') { | ||
result.bottom = parseFloat(this._element.style.bottom); | ||
} | ||
else { | ||
result.top = element.top - container.top; | ||
} | ||
if (this.horiziontalAlignment === 'left') { | ||
result.left = parseFloat(this._element.style.left); | ||
} | ||
else if (this.horiziontalAlignment === 'right') { | ||
result.right = parseFloat(this._element.style.right); | ||
} | ||
else { | ||
result.left = element.left - container.left; | ||
} | ||
result.width = element.width; | ||
result.height = element.height; | ||
return result; | ||
} | ||
@@ -123,8 +162,26 @@ setupDrag(dragTarget, options = { inDragMode: false }) { | ||
const xOffset = Math.max(0, this.getMinimumWidth(overlayRect.width)); | ||
const yOffset = Math.max(0, this.options.minimumInViewportHeight | ||
? this.getMinimumHeight(overlayRect.height) | ||
: 0); | ||
const yOffset = Math.max(0, this.getMinimumHeight(overlayRect.height)); | ||
const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
const bottom = clamp(offset.y - | ||
y + | ||
containerRect.height - | ||
overlayRect.height, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
const left = clamp(x - offset.x, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset)); | ||
const top = clamp(y - offset.y, -yOffset, Math.max(0, containerRect.height - overlayRect.height + yOffset)); | ||
this.setBounds({ top, left }); | ||
const right = clamp(offset.x - x + containerRect.width - overlayRect.width, -xOffset, Math.max(0, containerRect.width - overlayRect.width + xOffset)); | ||
const bounds = {}; | ||
// Anchor to top or to bottom depending on which one is closer | ||
if (top <= bottom) { | ||
bounds.top = top; | ||
} | ||
else { | ||
bounds.bottom = bottom; | ||
} | ||
// Anchor to left or to right depending on which one is closer | ||
if (left <= right) { | ||
bounds.left = left; | ||
} | ||
else { | ||
bounds.right = right; | ||
} | ||
this.setBounds(bounds); | ||
}), addDisposableWindowListener(window, 'mouseup', () => { | ||
@@ -197,4 +254,6 @@ toggleClass(this._element, 'dv-resize-container-dragging', false); | ||
let top = undefined; | ||
let bottom = undefined; | ||
let height = undefined; | ||
let left = undefined; | ||
let right = undefined; | ||
let width = undefined; | ||
@@ -213,2 +272,3 @@ const moveTop = () => { | ||
top; | ||
bottom = containerRect.height - top - height; | ||
}; | ||
@@ -225,2 +285,3 @@ const moveBottom = () => { | ||
: Overlay.MINIMUM_HEIGHT, Number.MAX_VALUE); | ||
bottom = containerRect.height - top - height; | ||
}; | ||
@@ -239,2 +300,3 @@ const moveLeft = () => { | ||
left; | ||
right = containerRect.width - left - width; | ||
}; | ||
@@ -251,2 +313,3 @@ const moveRight = () => { | ||
: Overlay.MINIMUM_WIDTH, Number.MAX_VALUE); | ||
right = containerRect.width - left - width; | ||
}; | ||
@@ -283,3 +346,20 @@ switch (direction) { | ||
} | ||
this.setBounds({ height, width, top, left }); | ||
const bounds = {}; | ||
// Anchor to top or to bottom depending on which one is closer | ||
if (top <= bottom) { | ||
bounds.top = top; | ||
} | ||
else { | ||
bounds.bottom = bottom; | ||
} | ||
// Anchor to left or to right depending on which one is closer | ||
if (left <= right) { | ||
bounds.left = left; | ||
} | ||
else { | ||
bounds.right = right; | ||
} | ||
bounds.height = height; | ||
bounds.width = width; | ||
this.setBounds(bounds); | ||
}), { | ||
@@ -307,3 +387,3 @@ dispose: () => { | ||
} | ||
return height; | ||
return 0; | ||
} | ||
@@ -310,0 +390,0 @@ dispose() { |
@@ -148,3 +148,4 @@ import { CompositeDisposable, } from '../../../lifecycle'; | ||
y: top - rootTop + 20, | ||
}, { inDragMode: true }); | ||
inDragMode: true, | ||
}); | ||
} | ||
@@ -218,3 +219,4 @@ }), addDisposableListener(this.tabContainer, 'mousedown', (event) => { | ||
y: top - rootTop, | ||
}, { inDragMode: true }); | ||
inDragMode: true, | ||
}); | ||
return; | ||
@@ -221,0 +223,0 @@ } |
@@ -14,3 +14,3 @@ import { SerializedGridObject } from '../gridview/gridview'; | ||
import { GroupDragEvent, TabDragEvent } from './components/titlebar/tabsContainer'; | ||
import { Box } from '../types'; | ||
import { AnchoredBox, Box } from '../types'; | ||
import { DockviewPanelRenderer, OverlayRenderContainer } from '../overlayRenderContainer'; | ||
@@ -27,3 +27,3 @@ export interface PanelReference { | ||
data: GroupPanelViewState; | ||
position: Box; | ||
position: AnchoredBox; | ||
} | ||
@@ -47,2 +47,6 @@ export interface SerializedPopoutGroup { | ||
} | ||
export interface MovePanelEvent { | ||
panel: IDockviewPanel; | ||
from: DockviewGroupPanel; | ||
} | ||
type MoveGroupOptions = { | ||
@@ -68,2 +72,12 @@ from: { | ||
}; | ||
export interface FloatingGroupOptions { | ||
x?: number; | ||
y?: number; | ||
height?: number; | ||
width?: number; | ||
position?: AnchoredBox; | ||
skipRemoveGroup?: boolean; | ||
inDragMode?: boolean; | ||
skipActiveGroup?: boolean; | ||
} | ||
export interface IDockviewComponent extends IBaseGrid<DockviewGroupPanel> { | ||
@@ -87,2 +101,3 @@ readonly activePanel: IDockviewPanel | undefined; | ||
readonly onUnhandledDragOverEvent: Event<DockviewDndOverlayEvent>; | ||
readonly onDidMovePanel: Event<MovePanelEvent>; | ||
readonly options: DockviewComponentOptions; | ||
@@ -106,6 +121,3 @@ updateOptions(options: DockviewOptions): void; | ||
fromJSON(data: SerializedDockview): void; | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, coord?: { | ||
x: number; | ||
y: number; | ||
}): void; | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, options?: FloatingGroupOptions): void; | ||
addPopoutGroup(item: IDockviewPanel | DockviewGroupPanel, options?: { | ||
@@ -152,6 +164,6 @@ position?: Box; | ||
private readonly _onDidMovePanel; | ||
readonly onDidMovePanel: Event<MovePanelEvent>; | ||
private readonly _floatingGroups; | ||
private readonly _popoutGroups; | ||
private readonly _rootDropTarget; | ||
private _ignoreEvents; | ||
private readonly _onDidRemoveGroup; | ||
@@ -185,12 +197,3 @@ readonly onDidRemoveGroup: Event<DockviewGroupPanel>; | ||
}): Promise<void>; | ||
addFloatingGroup(item: DockviewPanel | DockviewGroupPanel, coord?: { | ||
x?: number; | ||
y?: number; | ||
height?: number; | ||
width?: number; | ||
}, options?: { | ||
skipRemoveGroup?: boolean; | ||
inDragMode: boolean; | ||
skipActiveGroup?: boolean; | ||
}): void; | ||
addFloatingGroup(item: DockviewPanel | DockviewGroupPanel, options?: FloatingGroupOptions): void; | ||
private orthogonalize; | ||
@@ -197,0 +200,0 @@ updateOptions(options: Partial<DockviewComponentOptions>): void; |
import { Overlay } from '../dnd/overlay'; | ||
import { CompositeDisposable } from '../lifecycle'; | ||
import { AnchoredBox } from '../types'; | ||
import { DockviewGroupPanel, IDockviewGroupPanel } from './dockviewGroupPanel'; | ||
export interface IDockviewFloatingGroupPanel { | ||
readonly group: IDockviewGroupPanel; | ||
position(bounds: Partial<{ | ||
top: number; | ||
left: number; | ||
height: number; | ||
width: number; | ||
}>): void; | ||
position(bounds: Partial<AnchoredBox>): void; | ||
} | ||
@@ -17,8 +13,3 @@ export declare class DockviewFloatingGroupPanel extends CompositeDisposable implements IDockviewFloatingGroupPanel { | ||
constructor(group: DockviewGroupPanel, overlay: Overlay); | ||
position(bounds: Partial<{ | ||
top: number; | ||
left: number; | ||
height: number; | ||
width: number; | ||
}>): void; | ||
position(bounds: Partial<AnchoredBox>): void; | ||
} |
@@ -14,2 +14,3 @@ import { DockviewApi } from '../api/component.api'; | ||
import { IGroupHeaderProps } from './framework'; | ||
import { AnchoredBox } from '../types'; | ||
export interface IHeaderActionsRenderer extends IDisposable { | ||
@@ -29,2 +30,6 @@ readonly element: HTMLElement; | ||
export interface DockviewOptions { | ||
/** | ||
* Disable the auto-resizing which is controlled through a `ResizeObserver`. | ||
* Call `.layout(width, height)` to manually resize the container. | ||
*/ | ||
disableAutoResizing?: boolean; | ||
@@ -44,2 +49,6 @@ hideBorders?: boolean; | ||
disableDnd?: boolean; | ||
/** | ||
* Pixel gap between groups | ||
*/ | ||
gap?: number; | ||
} | ||
@@ -106,8 +115,3 @@ export interface DockviewDndOverlayEvent { | ||
type AddPanelFloatingGroupUnion = { | ||
floating: { | ||
height?: number; | ||
width?: number; | ||
x?: number; | ||
y?: number; | ||
} | true; | ||
floating: Partial<AnchoredBox> | true; | ||
position: never; | ||
@@ -114,0 +118,0 @@ }; |
@@ -34,2 +34,3 @@ export class DockviewUnhandledDragOverEvent { | ||
disableDnd: undefined, | ||
gap: undefined, | ||
}; | ||
@@ -36,0 +37,0 @@ return Object.keys(properties); |
@@ -29,1 +29,2 @@ import { Event as DockviewEvent } from './events'; | ||
export declare function isInDocument(element: Element): boolean; | ||
export declare function addTestId(element: HTMLElement, id: string): void; |
@@ -182,1 +182,4 @@ import { Emitter, addDisposableListener, addDisposableWindowListener, } from './events'; | ||
} | ||
export function addTestId(element, id) { | ||
element.setAttribute('data-testid', id); | ||
} |
@@ -18,2 +18,3 @@ import { Event, AsapEvent } from '../events'; | ||
readonly locked?: boolean; | ||
readonly margin?: number; | ||
} | ||
@@ -63,2 +64,4 @@ export interface IGridPanelView extends IGridView, IPanel { | ||
readonly onDidLayoutChange: Event<void>; | ||
private readonly _onDidViewVisibilityChangeMicroTaskQueue; | ||
readonly onDidViewVisibilityChangeMicroTaskQueue: Event<void>; | ||
get id(): string; | ||
@@ -65,0 +68,0 @@ get size(): number; |
@@ -72,10 +72,14 @@ import { Emitter, Event, AsapEvent } from '../events'; | ||
this.onDidLayoutChange = this._bufferOnDidLayoutChange.onEvent; | ||
this._onDidViewVisibilityChangeMicroTaskQueue = new AsapEvent(); | ||
this.onDidViewVisibilityChangeMicroTaskQueue = this._onDidViewVisibilityChangeMicroTaskQueue.onEvent; | ||
this.element.style.height = '100%'; | ||
this.element.style.width = '100%'; | ||
options.parentElement.appendChild(this.element); | ||
this.gridview = new Gridview(!!options.proportionalLayout, options.styles, options.orientation); | ||
this.gridview = new Gridview(!!options.proportionalLayout, options.styles, options.orientation, options.locked, options.margin); | ||
this.gridview.locked = !!options.locked; | ||
this.element.appendChild(this.gridview.element); | ||
this.layout(0, 0, true); // set some elements height/widths | ||
this.addDisposables(Disposable.from(() => { | ||
this.addDisposables(this.gridview.onDidViewVisibilityChange(() => this._onDidViewVisibilityChangeMicroTaskQueue.fire()), this.onDidViewVisibilityChangeMicroTaskQueue(() => { | ||
this.layout(this.width, this.height, true); | ||
}), Disposable.from(() => { | ||
var _a; | ||
@@ -82,0 +86,0 @@ (_a = this.element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(this.element); |
@@ -22,3 +22,5 @@ import { IView, Orientation, Sizing, LayoutPriority, ISplitviewStyles } from '../splitview/splitview'; | ||
private readonly _onDidVisibilityChange; | ||
readonly onDidVisibilityChange: Event<boolean>; | ||
readonly onDidVisibilityChange: Event<{ | ||
visible: boolean; | ||
}>; | ||
get width(): number; | ||
@@ -39,4 +41,6 @@ get height(): number; | ||
set disabled(value: boolean); | ||
constructor(orientation: Orientation, proportionalLayout: boolean, styles: ISplitviewStyles | undefined, size: number, orthogonalSize: number, disabled: boolean, childDescriptors?: INodeDescriptor[]); | ||
setVisible(visible: boolean): void; | ||
get margin(): number; | ||
set margin(value: number); | ||
constructor(orientation: Orientation, proportionalLayout: boolean, styles: ISplitviewStyles | undefined, size: number, orthogonalSize: number, disabled: boolean, margin: number | undefined, childDescriptors?: INodeDescriptor[]); | ||
setVisible(_visible: boolean): void; | ||
isChildVisible(index: number): boolean; | ||
@@ -43,0 +47,0 @@ setChildVisible(index: number, visible: boolean): void; |
@@ -85,3 +85,14 @@ /*--------------------------------------------------------------------------------------------- | ||
} | ||
constructor(orientation, proportionalLayout, styles, size, orthogonalSize, disabled, childDescriptors) { | ||
get margin() { | ||
return this.splitview.margin; | ||
} | ||
set margin(value) { | ||
this.splitview.margin = value; | ||
this.children.forEach((child) => { | ||
if (child instanceof BranchNode) { | ||
child.margin = value; | ||
} | ||
}); | ||
} | ||
constructor(orientation, proportionalLayout, styles, size, orthogonalSize, disabled, margin, childDescriptors) { | ||
super(); | ||
@@ -106,2 +117,3 @@ this.orientation = orientation; | ||
styles, | ||
margin, | ||
}); | ||
@@ -130,2 +142,3 @@ this.splitview.layout(this.size, this.orthogonalSize); | ||
styles, | ||
margin, | ||
}); | ||
@@ -139,6 +152,4 @@ } | ||
} | ||
setVisible(visible) { | ||
for (const child of this.children) { | ||
child.setVisible(visible); | ||
} | ||
setVisible(_visible) { | ||
// noop | ||
} | ||
@@ -160,2 +171,3 @@ isChildVisible(index) { | ||
this.splitview.setViewVisible(index, visible); | ||
// } | ||
const areAllChildrenHidden = this.splitview.contentSize === 0; | ||
@@ -166,3 +178,3 @@ // If all children are hidden then the parent should hide the entire splitview | ||
(!visible && areAllChildrenHidden)) { | ||
this._onDidVisibilityChange.fire(visible); | ||
this._onDidVisibilityChange.fire({ visible }); | ||
} | ||
@@ -240,3 +252,3 @@ } | ||
if (c instanceof BranchNode) { | ||
return c.onDidVisibilityChange((visible) => { | ||
return c.onDidVisibilityChange(({ visible }) => { | ||
this.setChildVisible(i, visible); | ||
@@ -243,0 +255,0 @@ }); |
@@ -29,2 +29,3 @@ import { ISplitviewStyles, LayoutPriority, Orientation, Sizing } from '../splitview/splitview'; | ||
readonly maximumHeight: number; | ||
readonly isVisible: boolean; | ||
priority?: LayoutPriority; | ||
@@ -92,2 +93,3 @@ layout(width: number, height: number): void; | ||
private _locked; | ||
private _margin; | ||
private _maximizedNode; | ||
@@ -100,2 +102,4 @@ private readonly disposable; | ||
}>; | ||
private readonly _onDidViewVisibilityChange; | ||
readonly onDidViewVisibilityChange: Event<void>; | ||
private readonly _onDidMaximizedNodeChange; | ||
@@ -114,2 +118,4 @@ readonly onDidMaximizedNodeChange: Event<void>; | ||
set locked(value: boolean); | ||
get margin(): number; | ||
set margin(value: number); | ||
maximizedView(): IGridView | undefined; | ||
@@ -138,3 +144,3 @@ hasMaximizedView(): boolean; | ||
private progmaticSelect; | ||
constructor(proportionalLayout: boolean, styles: ISplitviewStyles | undefined, orientation: Orientation); | ||
constructor(proportionalLayout: boolean, styles: ISplitviewStyles | undefined, orientation: Orientation, locked?: boolean, margin?: number); | ||
isViewVisible(location: number[]): boolean; | ||
@@ -141,0 +147,0 @@ setViewVisible(location: number[], visible: boolean): void; |
@@ -22,3 +22,3 @@ /*--------------------------------------------------------------------------------------------- | ||
if (node instanceof BranchNode) { | ||
const result = new BranchNode(orthogonal(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled); | ||
const result = new BranchNode(orthogonal(node.orientation), node.proportionalLayout, node.styles, size, orthogonalSize, node.disabled, node.margin); | ||
let totalSize = 0; | ||
@@ -178,2 +178,9 @@ for (let i = node.children.length - 1; i >= 0; i--) { | ||
} | ||
get margin() { | ||
return this._margin; | ||
} | ||
set margin(value) { | ||
this._margin = value; | ||
this.root.margin = value; | ||
} | ||
maximizedView() { | ||
@@ -264,2 +271,3 @@ var _a; | ||
this._onDidMaximizedNodeChange.dispose(); | ||
this._onDidViewVisibilityChange.dispose(); | ||
this.root.dispose(); | ||
@@ -271,3 +279,3 @@ this._maximizedNode = undefined; | ||
const orientation = this.root.orientation; | ||
this.root = new BranchNode(orientation, this.proportionalLayout, this.styles, this.root.size, this.root.orthogonalSize, this._locked); | ||
this.root = new BranchNode(orientation, this.proportionalLayout, this.styles, this.root.size, this.root.orthogonalSize, this.locked, this.margin); | ||
} | ||
@@ -283,2 +291,3 @@ deserialize(json, deserializer) { | ||
_deserializeNode(node, orientation, deserializer, orthogonalSize) { | ||
var _a; | ||
let result; | ||
@@ -295,6 +304,10 @@ if (node.type === 'branch') { | ||
orthogonalSize, // <- size - flips at each depth, | ||
this._locked, children); | ||
this.locked, this.margin, children); | ||
} | ||
else { | ||
result = new LeafNode(deserializer.fromJSON(node), orientation, orthogonalSize, node.size); | ||
const view = deserializer.fromJSON(node); | ||
if (typeof node.visible === 'boolean') { | ||
(_a = view.setVisible) === null || _a === void 0 ? void 0 : _a.call(view, node.visible); | ||
} | ||
result = new LeafNode(view, orientation, orthogonalSize, node.size); | ||
} | ||
@@ -329,3 +342,3 @@ return result; | ||
oldRoot.element.remove(); | ||
this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size, this._locked); | ||
this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size, this.locked, this.margin); | ||
if (oldRoot.children.length === 0) { | ||
@@ -397,6 +410,7 @@ // no data so no need to add anything back in | ||
} | ||
constructor(proportionalLayout, styles, orientation) { | ||
constructor(proportionalLayout, styles, orientation, locked, margin) { | ||
this.proportionalLayout = proportionalLayout; | ||
this.styles = styles; | ||
this._locked = false; | ||
this._margin = 0; | ||
this._maximizedNode = undefined; | ||
@@ -406,2 +420,4 @@ this.disposable = new MutableDisposable(); | ||
this.onDidChange = this._onDidChange.event; | ||
this._onDidViewVisibilityChange = new Emitter(); | ||
this.onDidViewVisibilityChange = this._onDidViewVisibilityChange.event; | ||
this._onDidMaximizedNodeChange = new Emitter(); | ||
@@ -411,3 +427,5 @@ this.onDidMaximizedNodeChange = this._onDidMaximizedNodeChange.event; | ||
this.element.className = 'grid-view'; | ||
this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0, this._locked); | ||
this._locked = locked !== null && locked !== void 0 ? locked : false; | ||
this._margin = margin !== null && margin !== void 0 ? margin : 0; | ||
this.root = new BranchNode(orientation, proportionalLayout, styles, 0, 0, this.locked, this.margin); | ||
} | ||
@@ -431,2 +449,3 @@ isViewVisible(location) { | ||
} | ||
this._onDidViewVisibilityChange.fire(); | ||
parent.setChildVisible(index, visible); | ||
@@ -464,3 +483,3 @@ } | ||
child.dispose(); | ||
const newParent = new BranchNode(parent.orientation, this.proportionalLayout, this.styles, parent.size, parent.orthogonalSize, this._locked); | ||
const newParent = new BranchNode(parent.orientation, this.proportionalLayout, this.styles, parent.size, parent.orthogonalSize, this.locked, this.margin); | ||
grandParent.addChild(newParent, parent.size, parentIndex); | ||
@@ -467,0 +486,0 @@ const newSibling = new LeafNode(parent.view, grandParent.orientation, parent.size); |
@@ -47,2 +47,3 @@ import { PanelInitParameters } from '../panel/types'; | ||
get isActive(): boolean; | ||
get isVisible(): boolean; | ||
constructor(id: string, component: string, options?: { | ||
@@ -49,0 +50,0 @@ minimumWidth?: number; |
@@ -54,2 +54,5 @@ import { BasePanelView, } from './basePanelView'; | ||
} | ||
get isVisible() { | ||
return this.api.isVisible; | ||
} | ||
constructor(id, component, options, api) { | ||
@@ -56,0 +59,0 @@ super(id, component, api !== null && api !== void 0 ? api : new GridviewPanelApiImpl(id, component)); |
export const clamp = (value, min, max) => { | ||
if (min > max) { | ||
throw new Error(`${min} > ${max} is an invalid condition`); | ||
/** | ||
* caveat: an error should be thrown here if this was a proper `clamp` function but we need to handle | ||
* cases where `min` > `max` and in those cases return `min`. | ||
*/ | ||
return min; | ||
} | ||
@@ -5,0 +9,0 @@ return Math.min(max, Math.max(value, min)); |
@@ -21,2 +21,3 @@ import { Event } from '../events'; | ||
readonly styles?: ISplitviewStyles; | ||
readonly margin?: number; | ||
} | ||
@@ -84,2 +85,3 @@ export declare enum LayoutPriority { | ||
private _disabled; | ||
private _margin; | ||
private readonly _onDidSashEnd; | ||
@@ -108,2 +110,4 @@ readonly onDidSashEnd: Event<void>; | ||
set disabled(value: boolean); | ||
get margin(): number; | ||
set margin(value: number); | ||
constructor(container: HTMLElement, options: SplitViewOptions); | ||
@@ -126,2 +130,11 @@ style(styles?: ISplitviewStyles): void; | ||
private saveProportions; | ||
/** | ||
* Margin explain: | ||
* | ||
* For `n` views in a splitview there will be `n-1` margins `m`. | ||
* | ||
* To fit the margins each view must reduce in size by `(m * (n - 1)) / n`. | ||
* | ||
* For each view `i` the offet must be adjusted by `m * i/(n - 1)`. | ||
*/ | ||
private layoutViews; | ||
@@ -128,0 +141,0 @@ private findFirstSnapIndex; |
@@ -110,3 +110,10 @@ /*--------------------------------------------------------------------------------------------- | ||
} | ||
get margin() { | ||
return this._margin; | ||
} | ||
set margin(value) { | ||
this._margin = value; | ||
} | ||
constructor(container, options) { | ||
var _a; | ||
this.container = container; | ||
@@ -122,2 +129,3 @@ this.viewItems = []; | ||
this._disabled = false; | ||
this._margin = 0; | ||
this._onDidSashEnd = new Emitter(); | ||
@@ -211,2 +219,3 @@ this.onDidSashEnd = this._onDidSashEnd.event; | ||
this.element = this.createContainer(); | ||
this.margin = (_a = options.margin) !== null && _a !== void 0 ? _a : 0; | ||
this.proportionalLayout = | ||
@@ -266,5 +275,3 @@ options.proportionalLayout === undefined | ||
} | ||
toggleClass(this.container, 'visible', visible); | ||
const viewItem = this.viewItems[index]; | ||
toggleClass(this.container, 'visible', visible); | ||
viewItem.setVisible(visible, viewItem.size); | ||
@@ -581,11 +588,25 @@ this.distributeEmptySpace(index); | ||
} | ||
/** | ||
* Margin explain: | ||
* | ||
* For `n` views in a splitview there will be `n-1` margins `m`. | ||
* | ||
* To fit the margins each view must reduce in size by `(m * (n - 1)) / n`. | ||
* | ||
* For each view `i` the offet must be adjusted by `m * i/(n - 1)`. | ||
*/ | ||
layoutViews() { | ||
this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); | ||
let sum = 0; | ||
const x = []; | ||
this.updateSashEnablement(); | ||
if (this.viewItems.length === 0) { | ||
return; | ||
} | ||
const sashCount = this.viewItems.length - 1; | ||
const marginReducedSize = (this.margin * sashCount) / this.viewItems.length; | ||
let totalLeftOffset = 0; | ||
const viewLeftOffsets = []; | ||
for (let i = 0; i < this.viewItems.length - 1; i++) { | ||
sum += this.viewItems[i].size; | ||
x.push(sum); | ||
const offset = Math.min(Math.max(0, sum - 2), this.size - 4); | ||
totalLeftOffset += this.viewItems[i].size; | ||
viewLeftOffsets.push(totalLeftOffset); | ||
const offset = Math.min(Math.max(0, totalLeftOffset - 2), this.size - this.margin); | ||
if (this._orientation === Orientation.HORIZONTAL) { | ||
@@ -601,5 +622,10 @@ this.sashes[i].container.style.left = `${offset}px`; | ||
this.viewItems.forEach((view, i) => { | ||
const size = view.size - marginReducedSize; | ||
const offset = i === 0 | ||
? 0 | ||
: viewLeftOffsets[i - 1] + | ||
(i / sashCount) * marginReducedSize; | ||
if (this._orientation === Orientation.HORIZONTAL) { | ||
view.container.style.width = `${view.size}px`; | ||
view.container.style.left = i == 0 ? '0px' : `${x[i - 1]}px`; | ||
view.container.style.width = `${size}px`; | ||
view.container.style.left = `${offset}px`; | ||
view.container.style.top = ''; | ||
@@ -609,8 +635,8 @@ view.container.style.height = ''; | ||
if (this._orientation === Orientation.VERTICAL) { | ||
view.container.style.height = `${view.size}px`; | ||
view.container.style.top = i == 0 ? '0px' : `${x[i - 1]}px`; | ||
view.container.style.height = `${size}px`; | ||
view.container.style.top = `${offset}px`; | ||
view.container.style.width = ''; | ||
view.container.style.left = ''; | ||
} | ||
view.view.layout(view.size, this._orthogonalSize); | ||
view.view.layout(view.size - marginReducedSize, this._orthogonalSize); | ||
}); | ||
@@ -617,0 +643,0 @@ } |
@@ -9,1 +9,24 @@ export type FunctionOrValue<T> = (() => T) | T; | ||
} | ||
type TopLeft = { | ||
top: number; | ||
left: number; | ||
}; | ||
type TopRight = { | ||
top: number; | ||
right: number; | ||
}; | ||
type BottomLeft = { | ||
bottom: number; | ||
left: number; | ||
}; | ||
type BottomRight = { | ||
bottom: number; | ||
right: number; | ||
}; | ||
type AnchorPosition = TopLeft | TopRight | BottomLeft | BottomRight; | ||
type Size = { | ||
width: number; | ||
height: number; | ||
}; | ||
export type AnchoredBox = Size & AnchorPosition; | ||
export {}; |
{ | ||
"name": "dockview-core", | ||
"version": "1.14.2", | ||
"version": "1.15.0", | ||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
12187132
92310