dockview-core
Advanced tools
Comparing version 0.0.0-experimental-1264055-20231228 to 0.0.0-experimental-1cc340f-20240127
@@ -456,2 +456,6 @@ import { DockviewDropEvent, IDockviewComponent, SerializedDockview } from '../dockview/dockviewComponent'; | ||
moveToPrevious(options?: MovementOptions): void; | ||
maximizeGroup(panel: IDockviewPanel): void; | ||
hasMaximizedGroup(): boolean; | ||
exitMaxmizedGroup(): void; | ||
get onDidMaxmizedGroupChange(): Event<void>; | ||
/** | ||
@@ -463,4 +467,6 @@ * Add a popout group in a new Window | ||
popoutUrl?: string; | ||
onOpened?: (id: string, window: Window) => void; | ||
onClosing?: (id: string, window: Window) => void; | ||
}): void; | ||
} | ||
//# sourceMappingURL=component.api.d.ts.map |
@@ -893,2 +893,18 @@ "use strict"; | ||
}; | ||
DockviewApi.prototype.maximizeGroup = function (panel) { | ||
this.component.maximizeGroup(panel.group); | ||
}; | ||
DockviewApi.prototype.hasMaximizedGroup = function () { | ||
return this.component.hasMaximizedGroup(); | ||
}; | ||
DockviewApi.prototype.exitMaxmizedGroup = function () { | ||
this.component.exitMaximizedGroup(); | ||
}; | ||
Object.defineProperty(DockviewApi.prototype, "onDidMaxmizedGroupChange", { | ||
get: function () { | ||
return this.component.onDidMaxmizedGroupChange; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
/** | ||
@@ -895,0 +911,0 @@ * Add a popout group in a new Window |
@@ -8,8 +8,11 @@ import { Position } from '../dnd/droptarget'; | ||
export interface DockviewGroupPanelApi extends GridviewPanelApi { | ||
readonly onDidRenderPositionChange: Event<DockviewGroupPanelFloatingChangeEvent>; | ||
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>; | ||
readonly location: DockviewGroupLocation; | ||
moveTo(options: { | ||
group: DockviewGroupPanel; | ||
group?: DockviewGroupPanel; | ||
position?: Position; | ||
}): void; | ||
maximize(): void; | ||
isMaximized(): boolean; | ||
exitMaximized(): void; | ||
} | ||
@@ -22,12 +25,15 @@ export interface DockviewGroupPanelFloatingChangeEvent { | ||
private _group; | ||
readonly _onDidRenderPositionChange: Emitter<DockviewGroupPanelFloatingChangeEvent>; | ||
readonly onDidRenderPositionChange: Event<DockviewGroupPanelFloatingChangeEvent>; | ||
readonly _onDidLocationChange: Emitter<DockviewGroupPanelFloatingChangeEvent>; | ||
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>; | ||
get location(): DockviewGroupLocation; | ||
constructor(id: string, accessor: DockviewComponent); | ||
moveTo(options: { | ||
group: DockviewGroupPanel; | ||
group?: DockviewGroupPanel; | ||
position?: Position; | ||
}): void; | ||
maximize(): void; | ||
isMaximized(): boolean; | ||
exitMaximized(): void; | ||
initialize(group: DockviewGroupPanel): void; | ||
} | ||
//# sourceMappingURL=dockviewGroupPanelApi.d.ts.map |
@@ -19,4 +19,7 @@ "use strict"; | ||
exports.DockviewGroupPanelApiImpl = void 0; | ||
var droptarget_1 = require("../dnd/droptarget"); | ||
var events_1 = require("../events"); | ||
var gridviewPanelApi_1 = require("./gridviewPanelApi"); | ||
// TODO find a better way to initialize and avoid needing null checks | ||
var NOT_INITIALIZED_MESSAGE = 'DockviewGroupPanelApiImpl not initialized'; | ||
var DockviewGroupPanelApiImpl = /** @class */ (function (_super) { | ||
@@ -27,5 +30,5 @@ __extends(DockviewGroupPanelApiImpl, _super); | ||
_this.accessor = accessor; | ||
_this._onDidRenderPositionChange = new events_1.Emitter(); | ||
_this.onDidRenderPositionChange = _this._onDidRenderPositionChange.event; | ||
_this.addDisposables(_this._onDidRenderPositionChange); | ||
_this._onDidLocationChange = new events_1.Emitter(); | ||
_this.onDidLocationChange = _this._onDidLocationChange.event; | ||
_this.addDisposables(_this._onDidLocationChange); | ||
return _this; | ||
@@ -36,3 +39,3 @@ } | ||
if (!this._group) { | ||
throw new Error("DockviewGroupPanelApiImpl not initialized"); | ||
throw new Error(NOT_INITIALIZED_MESSAGE); | ||
} | ||
@@ -45,8 +48,35 @@ return this._group.model.location; | ||
DockviewGroupPanelApiImpl.prototype.moveTo = function (options) { | ||
var _a; | ||
var _a, _b, _c; | ||
if (!this._group) { | ||
throw new Error("DockviewGroupPanelApiImpl not initialized"); | ||
throw new Error(NOT_INITIALIZED_MESSAGE); | ||
} | ||
this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center'); | ||
var group = (_a = options.group) !== null && _a !== void 0 ? _a : this.accessor.addGroup({ | ||
direction: (0, droptarget_1.positionToDirection)((_b = options.position) !== null && _b !== void 0 ? _b : 'right'), | ||
}); | ||
this.accessor.moveGroupOrPanel(group, this._group.id, undefined, options.group ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center' : 'center'); | ||
}; | ||
DockviewGroupPanelApiImpl.prototype.maximize = function () { | ||
if (!this._group) { | ||
throw new Error(NOT_INITIALIZED_MESSAGE); | ||
} | ||
if (this.location !== 'grid') { | ||
// only grid groups can be maximized | ||
return; | ||
} | ||
this.accessor.maximizeGroup(this._group); | ||
}; | ||
DockviewGroupPanelApiImpl.prototype.isMaximized = function () { | ||
if (!this._group) { | ||
throw new Error(NOT_INITIALIZED_MESSAGE); | ||
} | ||
return this.accessor.isMaximizedGroup(this._group); | ||
}; | ||
DockviewGroupPanelApiImpl.prototype.exitMaximized = function () { | ||
if (!this._group) { | ||
throw new Error(NOT_INITIALIZED_MESSAGE); | ||
} | ||
if (this.isMaximized()) { | ||
this.accessor.exitMaximizedGroup(); | ||
} | ||
}; | ||
DockviewGroupPanelApiImpl.prototype.initialize = function (group) { | ||
@@ -53,0 +83,0 @@ this._group = group; |
@@ -7,3 +7,3 @@ import { Emitter, Event } from '../events'; | ||
import { Position } from '../dnd/droptarget'; | ||
import { DockviewPanelRenderer } from '../dockview/components/greadyRenderContainer'; | ||
import { DockviewPanelRenderer } from '../overlayRenderContainer'; | ||
export interface TitleEvent { | ||
@@ -31,2 +31,5 @@ readonly title: string; | ||
}): void; | ||
maximize(): void; | ||
isMaximized(): boolean; | ||
exitMaximized(): void; | ||
} | ||
@@ -60,3 +63,6 @@ export declare class DockviewPanelApiImpl extends GridviewPanelApiImpl implements DockviewPanelApi { | ||
close(): void; | ||
maximize(): void; | ||
isMaximized(): boolean; | ||
exitMaximized(): void; | ||
} | ||
//# sourceMappingURL=dockviewPanelApi.d.ts.map |
@@ -51,4 +51,3 @@ "use strict"; | ||
get: function () { | ||
var _a; | ||
return !!((_a = this.group) === null || _a === void 0 ? void 0 : _a.isActive); | ||
return this.group.isActive; | ||
}, | ||
@@ -99,2 +98,11 @@ enumerable: false, | ||
}; | ||
DockviewPanelApiImpl.prototype.maximize = function () { | ||
this.group.api.maximize(); | ||
}; | ||
DockviewPanelApiImpl.prototype.isMaximized = function () { | ||
return this.group.api.isMaximized(); | ||
}; | ||
DockviewPanelApiImpl.prototype.exitMaximized = function () { | ||
this.group.api.exitMaximized(); | ||
}; | ||
return DockviewPanelApiImpl; | ||
@@ -101,0 +109,0 @@ }(gridviewPanelApi_1.GridviewPanelApiImpl)); |
@@ -13,2 +13,10 @@ import { Event } from '../events'; | ||
export type CanDisplayOverlay = boolean | ((dragEvent: DragEvent, state: Position) => boolean); | ||
export type MeasuredValue = { | ||
value: number; | ||
type: 'pixels' | 'percentage'; | ||
}; | ||
export type DroptargetOverlayModel = { | ||
size?: MeasuredValue; | ||
activationSize?: MeasuredValue; | ||
}; | ||
export declare class Droptarget extends CompositeDisposable { | ||
@@ -29,14 +37,6 @@ private readonly element; | ||
acceptedTargetZones: Position[]; | ||
overlayModel?: { | ||
size?: { | ||
value: number; | ||
type: 'pixels' | 'percentage'; | ||
}; | ||
activationSize?: { | ||
value: number; | ||
type: 'pixels' | 'percentage'; | ||
}; | ||
}; | ||
overlayModel?: DroptargetOverlayModel; | ||
}); | ||
setTargetZones(acceptedTargetZones: Position[]): void; | ||
setOverlayModel(model: DroptargetOverlayModel): void; | ||
dispose(): void; | ||
@@ -48,7 +48,6 @@ /** | ||
/** | ||
* Check is the event has already been used by another instance od DropTarget | ||
* Check is the event has already been used by another instance of DropTarget | ||
*/ | ||
private isAlreadyUsed; | ||
private toggleClasses; | ||
private setState; | ||
private calculateQuadrant; | ||
@@ -55,0 +54,0 @@ private removeDropTarget; |
@@ -24,5 +24,2 @@ "use strict"; | ||
var math_1 = require("../math"); | ||
function numberOrFallback(maybeNumber, fallback) { | ||
return typeof maybeNumber === 'number' ? maybeNumber : fallback; | ||
} | ||
function directionToPosition(direction) { | ||
@@ -62,2 +59,12 @@ switch (direction) { | ||
exports.positionToDirection = positionToDirection; | ||
var DEFAULT_ACTIVATION_SIZE = { | ||
value: 20, | ||
type: 'percentage', | ||
}; | ||
var DEFAULT_SIZE = { | ||
value: 50, | ||
type: 'percentage', | ||
}; | ||
var SMALL_WIDTH_BOUNDARY = 100; | ||
var SMALL_HEIGHT_BOUNDARY = 100; | ||
var Droptarget = /** @class */ (function (_super) { | ||
@@ -121,3 +128,3 @@ __extends(Droptarget, _super); | ||
_this.toggleClasses(quadrant, width, height); | ||
_this.setState(quadrant); | ||
_this._state = quadrant; | ||
}, | ||
@@ -155,2 +162,5 @@ onDragLeave: function () { | ||
}; | ||
Droptarget.prototype.setOverlayModel = function (model) { | ||
this.options.overlayModel = model; | ||
}; | ||
Droptarget.prototype.dispose = function () { | ||
@@ -167,3 +177,3 @@ this.removeDropTarget(); | ||
/** | ||
* Check is the event has already been used by another instance od DropTarget | ||
* Check is the event has already been used by another instance of DropTarget | ||
*/ | ||
@@ -175,8 +185,8 @@ Droptarget.prototype.isAlreadyUsed = function (event) { | ||
Droptarget.prototype.toggleClasses = function (quadrant, width, height) { | ||
var _a, _b, _c, _d; | ||
var _a, _b; | ||
if (!this.overlayElement) { | ||
return; | ||
} | ||
var isSmallX = width < 100; | ||
var isSmallY = height < 100; | ||
var isSmallX = width < SMALL_WIDTH_BOUNDARY; | ||
var isSmallY = height < SMALL_HEIGHT_BOUNDARY; | ||
var isLeft = quadrant === 'left'; | ||
@@ -190,16 +200,13 @@ var isRight = quadrant === 'right'; | ||
var bottomClass = !isSmallY && isBottom; | ||
var size = 0.5; | ||
if (((_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.size) === null || _b === void 0 ? void 0 : _b.type) === 'percentage') { | ||
size = (0, math_1.clamp)(this.options.overlayModel.size.value, 0, 100) / 100; | ||
var size = 1; | ||
var sizeOptions = (_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : DEFAULT_SIZE; | ||
if (sizeOptions.type === 'percentage') { | ||
size = (0, math_1.clamp)(sizeOptions.value, 0, 100) / 100; | ||
} | ||
if (((_d = (_c = this.options.overlayModel) === null || _c === void 0 ? void 0 : _c.size) === null || _d === void 0 ? void 0 : _d.type) === 'pixels') { | ||
else { | ||
if (rightClass || leftClass) { | ||
size = | ||
(0, math_1.clamp)(0, this.options.overlayModel.size.value, width) / | ||
width; | ||
size = (0, math_1.clamp)(0, sizeOptions.value, width) / width; | ||
} | ||
if (topClass || bottomClass) { | ||
size = | ||
(0, math_1.clamp)(0, this.options.overlayModel.size.value, height) / | ||
height; | ||
size = (0, math_1.clamp)(0, sizeOptions.value, height) / height; | ||
} | ||
@@ -226,35 +233,18 @@ } | ||
this.overlayElement.style.transform = transform; | ||
(0, dom_1.toggleClass)(this.overlayElement, 'small-right', isSmallX && isRight); | ||
(0, dom_1.toggleClass)(this.overlayElement, 'small-left', isSmallX && isLeft); | ||
(0, dom_1.toggleClass)(this.overlayElement, 'small-top', isSmallY && isTop); | ||
(0, dom_1.toggleClass)(this.overlayElement, 'small-bottom', isSmallY && isBottom); | ||
(0, dom_1.toggleClass)(this.overlayElement, 'dv-drop-target-small-vertical', isSmallY); | ||
(0, dom_1.toggleClass)(this.overlayElement, 'dv-drop-target-small-horizontal', isSmallX); | ||
(0, dom_1.toggleClass)(this.overlayElement, 'dv-drop-target-left', isLeft); | ||
(0, dom_1.toggleClass)(this.overlayElement, 'dv-drop-target-right', isRight); | ||
(0, dom_1.toggleClass)(this.overlayElement, 'dv-drop-target-top', isTop); | ||
(0, dom_1.toggleClass)(this.overlayElement, 'dv-drop-target-bottom', isBottom); | ||
(0, dom_1.toggleClass)(this.overlayElement, 'dv-drop-target-center', quadrant === 'center'); | ||
}; | ||
Droptarget.prototype.setState = function (quadrant) { | ||
switch (quadrant) { | ||
case 'top': | ||
this._state = 'top'; | ||
break; | ||
case 'left': | ||
this._state = 'left'; | ||
break; | ||
case 'bottom': | ||
this._state = 'bottom'; | ||
break; | ||
case 'right': | ||
this._state = 'right'; | ||
break; | ||
case 'center': | ||
this._state = 'center'; | ||
break; | ||
} | ||
}; | ||
Droptarget.prototype.calculateQuadrant = function (overlayType, x, y, width, height) { | ||
var _a, _b, _c, _d, _e, _f; | ||
var isPercentage = ((_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.activationSize) === undefined || | ||
((_c = (_b = this.options.overlayModel) === null || _b === void 0 ? void 0 : _b.activationSize) === null || _c === void 0 ? void 0 : _c.type) === 'percentage'; | ||
var value = numberOrFallback((_f = (_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.overlayModel) === null || _e === void 0 ? void 0 : _e.activationSize) === null || _f === void 0 ? void 0 : _f.value, 20); | ||
var _a, _b; | ||
var activationSizeOptions = (_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.activationSize) !== null && _b !== void 0 ? _b : DEFAULT_ACTIVATION_SIZE; | ||
var isPercentage = activationSizeOptions.type === 'percentage'; | ||
if (isPercentage) { | ||
return calculateQuadrantAsPercentage(overlayType, x, y, width, height, value); | ||
return calculateQuadrantAsPercentage(overlayType, x, y, width, height, activationSizeOptions.value); | ||
} | ||
return calculateQuadrantAsPixels(overlayType, x, y, width, height, value); | ||
return calculateQuadrantAsPixels(overlayType, x, y, width, height, activationSizeOptions.value); | ||
}; | ||
@@ -261,0 +251,0 @@ Droptarget.prototype.removeDropTarget = function () { |
@@ -17,3 +17,5 @@ import { CompositeDisposable, IDisposable } from '../../../lifecycle'; | ||
hide(): void; | ||
renderPanel(panel: IDockviewPanel): void; | ||
renderPanel(panel: IDockviewPanel, options: { | ||
asActive: boolean; | ||
}): void; | ||
} | ||
@@ -35,3 +37,5 @@ export declare class ContentContainer extends CompositeDisposable implements IContentContainer { | ||
hide(): void; | ||
renderPanel(panel: IDockviewPanel): void; | ||
renderPanel(panel: IDockviewPanel, options?: { | ||
asActive: boolean; | ||
}): void; | ||
openPanel(panel: IDockviewPanel): void; | ||
@@ -38,0 +42,0 @@ layout(_width: number, _height: number): void; |
@@ -40,7 +40,2 @@ "use strict"; | ||
_this.addDisposables(_this._onDidFocus, _this._onDidBlur); | ||
// for hosted containers | ||
// 1) register a drop target on the host | ||
// 2) register window dragStart events to disable pointer events | ||
// 3) register dragEnd events | ||
// 4) register mouseMove events (if no buttons are present we take this as a dragEnd event) | ||
_this.dropTarget = new droptarget_1.Droptarget(_this.element, { | ||
@@ -93,11 +88,21 @@ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'], | ||
}; | ||
ContentContainer.prototype.renderPanel = function (panel) { | ||
ContentContainer.prototype.renderPanel = function (panel, options) { | ||
var _this = this; | ||
var isActive = panel === this.group.activePanel; | ||
if (options === void 0) { options = { asActive: true }; } | ||
var doRender = options.asActive || | ||
(this.panel && this.group.isPanelActive(this.panel)); | ||
if (this.panel && | ||
this.panel.view.content.element.parentElement === this._element) { | ||
/** | ||
* If the currently attached panel is mounted directly to the content then remove it | ||
*/ | ||
this._element.removeChild(this.panel.view.content.element); | ||
} | ||
this.panel = panel; | ||
var container; | ||
switch (panel.api.renderer) { | ||
case 'onlyWhenVisibile': | ||
this.accessor.greadyRenderContainer.remove(panel); | ||
if (isActive) { | ||
if (this.panel) { | ||
this.accessor.overlayRenderContainer.detatch(panel); | ||
if (this.panel) { | ||
if (doRender) { | ||
this._element.appendChild(this.panel.view.content.element); | ||
@@ -112,7 +117,9 @@ } | ||
} | ||
container = | ||
this.accessor.greadyRenderContainer.setReferenceContentContainer(panel, this); | ||
container = this.accessor.overlayRenderContainer.attach({ | ||
panel: panel, | ||
referenceContainer: this, | ||
}); | ||
break; | ||
} | ||
if (isActive) { | ||
if (doRender) { | ||
var _onDidFocus = panel.view.content.onDidFocus; | ||
@@ -133,38 +140,6 @@ var _onDidBlur = panel.view.content.onDidBlur; | ||
ContentContainer.prototype.openPanel = function (panel) { | ||
var _this = this; | ||
if (this.panel === panel) { | ||
return; | ||
} | ||
var renderer = panel.api.renderer; | ||
if (this.panel && | ||
this.panel.view.content.element.parentElement === this._element) { | ||
/** | ||
* If the currently attached panel is mounted directly to the content then remove it | ||
*/ | ||
this._element.removeChild(this.panel.view.content.element); | ||
} | ||
this.panel = panel; | ||
var container; | ||
switch (renderer) { | ||
case 'always': | ||
container = | ||
this.accessor.greadyRenderContainer.setReferenceContentContainer(panel, this); | ||
break; | ||
case 'onlyWhenVisibile': | ||
this._element.appendChild(this.panel.view.content.element); | ||
container = this._element; | ||
break; | ||
} | ||
var _onDidFocus = this.panel.view.content.onDidFocus; | ||
var _onDidBlur = this.panel.view.content.onDidBlur; | ||
var disposable = new lifecycle_1.CompositeDisposable(); | ||
var focusTracker = (0, dom_1.trackFocus)(container); | ||
disposable.addDisposables(focusTracker, focusTracker.onDidFocus(function () { return _this._onDidFocus.fire(); }), focusTracker.onDidBlur(function () { return _this._onDidBlur.fire(); })); | ||
if (_onDidFocus) { | ||
disposable.addDisposables(_onDidFocus(function () { return _this._onDidFocus.fire(); })); | ||
} | ||
if (_onDidBlur) { | ||
disposable.addDisposables(_onDidBlur(function () { return _this._onDidBlur.fire(); })); | ||
} | ||
this.disposable.value = disposable; | ||
this.renderPanel(panel); | ||
}; | ||
@@ -171,0 +146,0 @@ ContentContainer.prototype.layout = function (_width, _height) { |
@@ -15,3 +15,3 @@ import { SerializedGridObject } from '../gridview/gridview'; | ||
import { Box } from '../types'; | ||
import { GreadyRenderContainer, DockviewPanelRenderer } from './components/greadyRenderContainer'; | ||
import { DockviewPanelRenderer, OverlayRenderContainer } from '../overlayRenderContainer'; | ||
export interface PanelReference { | ||
@@ -45,3 +45,3 @@ update: (event: { | ||
} | ||
export type DockviewComponentUpdateOptions = Pick<DockviewComponentOptions, 'orientation' | 'components' | 'frameworkComponents' | 'tabComponents' | 'frameworkTabComponents' | 'showDndOverlay' | 'watermarkFrameworkComponent' | 'defaultTabComponent' | 'createLeftHeaderActionsElement' | 'createRightHeaderActionsElement' | 'createPrefixHeaderActionsElement' | 'disableFloatingGroups' | 'floatingGroupBounds'>; | ||
export type DockviewComponentUpdateOptions = Pick<DockviewComponentOptions, 'orientation' | 'components' | 'frameworkComponents' | 'tabComponents' | 'frameworkTabComponents' | 'showDndOverlay' | 'watermarkFrameworkComponent' | 'defaultTabComponent' | 'createLeftHeaderActionsElement' | 'createRightHeaderActionsElement' | 'createPrefixHeaderActionsElement' | 'disableFloatingGroups' | 'floatingGroupBounds' | 'rootOverlayModel'>; | ||
export interface DockviewDropEvent extends GroupviewDropEvent { | ||
@@ -87,2 +87,4 @@ api: DockviewApi; | ||
popoutUrl?: string; | ||
onOpened?: (id: string, window: Window) => void; | ||
onClosing?: (id: string, window: Window) => void; | ||
}): void; | ||
@@ -96,3 +98,3 @@ } | ||
private watermark; | ||
readonly greadyRenderContainer: GreadyRenderContainer; | ||
readonly overlayRenderContainer: OverlayRenderContainer; | ||
private readonly _onWillDragPanel; | ||
@@ -114,2 +116,3 @@ readonly onWillDragPanel: Event<TabDragEvent>; | ||
private readonly _popoutGroups; | ||
private readonly _rootDropTarget; | ||
get orientation(): Orientation; | ||
@@ -126,2 +129,4 @@ get totalPanels(): number; | ||
popoutUrl?: string; | ||
onOpened?: (id: string, window: Window) => void; | ||
onClosing?: (id: string, window: Window) => void; | ||
}): void; | ||
@@ -128,0 +133,0 @@ addFloatingGroup(item: DockviewPanel | DockviewGroupPanel, coord?: { |
@@ -22,2 +22,4 @@ "use strict"; | ||
var dockviewGroupPanelApi_1 = require("../api/dockviewGroupPanelApi"); | ||
var MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH = 100; | ||
var MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT = 100; | ||
var DockviewGroupPanel = /** @class */ (function (_super) { | ||
@@ -27,4 +29,4 @@ __extends(DockviewGroupPanel, _super); | ||
var _this = _super.call(this, id, 'groupview_default', { | ||
minimumHeight: 100, | ||
minimumWidth: 100, | ||
minimumHeight: MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT, | ||
minimumWidth: MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH, | ||
}, new dockviewGroupPanelApi_1.DockviewGroupPanelApiImpl(id, accessor)) || this; | ||
@@ -31,0 +33,0 @@ _this.api.initialize(_this); // cannot use 'this' after after 'super' call |
@@ -213,3 +213,5 @@ "use strict"; | ||
this.contentContainer.dropTarget.setTargetZones(['center']); | ||
this.contentContainer.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']); | ||
this.contentContainer.dropTarget.setTargetZones(value | ||
? ['center'] | ||
: ['top', 'bottom', 'left', 'right', 'center']); | ||
(0, dom_1.toggleClass)(this.container, 'dv-groupview-floating', true); | ||
@@ -222,3 +224,3 @@ break; | ||
} | ||
this.groupPanel.api._onDidRenderPositionChange.fire({ | ||
this.groupPanel.api._onDidLocationChange.fire({ | ||
location: this.location, | ||
@@ -277,3 +279,3 @@ }); | ||
DockviewGroupPanelModel.prototype.rerender = function (panel) { | ||
this.contentContainer.renderPanel(panel); | ||
this.contentContainer.renderPanel(panel, { asActive: false }); | ||
}; | ||
@@ -622,3 +624,2 @@ DockviewGroupPanelModel.prototype.indexOf = function (panel) { | ||
} | ||
// this.dropTarget.dispose(); | ||
this.tabsContainer.dispose(); | ||
@@ -625,0 +626,0 @@ this.contentContainer.dispose(); |
@@ -9,3 +9,3 @@ import { DockviewApi } from '../api/component.api'; | ||
import { DockviewComponent } from './dockviewComponent'; | ||
import { DockviewPanelRenderer } from './components/greadyRenderContainer'; | ||
import { DockviewPanelRenderer } from '../overlayRenderContainer'; | ||
export interface IDockviewPanel extends IDisposable, IPanel { | ||
@@ -12,0 +12,0 @@ readonly view: IDockviewPanelModel; |
@@ -6,11 +6,14 @@ import { CompositeDisposable } from '../lifecycle'; | ||
export declare class DockviewPopoutGroupPanel extends CompositeDisposable { | ||
readonly id: string; | ||
readonly group: DockviewGroupPanel; | ||
private readonly options; | ||
readonly window: PopoutWindow; | ||
constructor(group: DockviewGroupPanel, options: { | ||
constructor(id: string, group: DockviewGroupPanel, options: { | ||
className: string; | ||
popoutUrl: string; | ||
box: Box; | ||
onOpened?: (id: string, window: Window) => void; | ||
onClosing?: (id: string, window: Window) => void; | ||
}); | ||
} | ||
//# sourceMappingURL=dockviewPopoutGroupPanel.d.ts.map |
@@ -23,8 +23,9 @@ "use strict"; | ||
__extends(DockviewPopoutGroupPanel, _super); | ||
function DockviewPopoutGroupPanel(group, options) { | ||
function DockviewPopoutGroupPanel(id, group, options) { | ||
var _a; | ||
var _this = _super.call(this) || this; | ||
_this.id = id; | ||
_this.group = group; | ||
_this.options = options; | ||
_this.window = new popoutWindow_1.PopoutWindow('test', (_a = options.className) !== null && _a !== void 0 ? _a : '', { | ||
_this.window = new popoutWindow_1.PopoutWindow(id, (_a = options.className) !== null && _a !== void 0 ? _a : '', { | ||
url: _this.options.popoutUrl, | ||
@@ -35,2 +36,4 @@ left: _this.options.box.left, | ||
height: _this.options.box.height, | ||
onOpened: _this.options.onOpened, | ||
onClosing: _this.options.onClosing, | ||
}); | ||
@@ -37,0 +40,0 @@ group.model.location = 'popout'; |
@@ -10,7 +10,7 @@ import { DockviewApi } from '../api/component.api'; | ||
import { IDisposable } from '../lifecycle'; | ||
import { Position } from '../dnd/droptarget'; | ||
import { DroptargetOverlayModel, Position } from '../dnd/droptarget'; | ||
import { IDockviewPanel } from './dockviewPanel'; | ||
import { ComponentConstructor, FrameworkFactory } from '../panel/componentFactory'; | ||
import { DockviewGroupPanelApi } from '../api/dockviewGroupPanelApi'; | ||
import { DockviewPanelRenderer } from './components/greadyRenderContainer'; | ||
import { DockviewPanelRenderer } from '../overlayRenderContainer'; | ||
export interface IHeaderActionsRenderer extends IDisposable { | ||
@@ -80,2 +80,3 @@ readonly element: HTMLElement; | ||
debug?: boolean; | ||
rootOverlayModel?: DroptargetOverlayModel; | ||
} | ||
@@ -82,0 +83,0 @@ export interface PanelOptions<P extends object = Parameters> { |
@@ -8,3 +8,3 @@ import { IDockviewComponent } from './dockviewComponent'; | ||
import { DockviewGroupPanel, IDockviewGroupPanel } from './dockviewGroupPanel'; | ||
import { DockviewPanelRenderer } from './components/greadyRenderContainer'; | ||
import { DockviewPanelRenderer } from '../overlayRenderContainer'; | ||
export declare enum DockviewDropTargets { | ||
@@ -11,0 +11,0 @@ Tab = 0, |
@@ -24,2 +24,7 @@ import { Event as DockviewEvent } from './events'; | ||
}; | ||
/** | ||
* Check whether an element is in the DOM (including the Shadow DOM) | ||
* @see https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/ | ||
*/ | ||
export declare function isInDocument(element: Element): boolean; | ||
//# sourceMappingURL=dom.d.ts.map |
@@ -29,3 +29,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
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.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"); | ||
@@ -257,2 +257,23 @@ var lifecycle_1 = require("./lifecycle"); | ||
exports.getDomNodePagePosition = getDomNodePagePosition; | ||
/** | ||
* Check whether an element is in the DOM (including the Shadow DOM) | ||
* @see https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/ | ||
*/ | ||
function isInDocument(element) { | ||
var currentElement = element; | ||
while (currentElement === null || currentElement === void 0 ? void 0 : currentElement.parentNode) { | ||
if (currentElement.parentNode === document) { | ||
return true; | ||
} | ||
else if (currentElement.parentNode instanceof DocumentFragment) { | ||
// handle shadow DOMs | ||
currentElement = currentElement.parentNode.host; | ||
} | ||
else { | ||
currentElement = currentElement.parentNode; | ||
} | ||
} | ||
return false; | ||
} | ||
exports.isInDocument = isInDocument; | ||
//# sourceMappingURL=dom.js.map |
@@ -45,2 +45,7 @@ import { Emitter, Event, TickDelayedEvent } from '../events'; | ||
isVisible(panel: T): boolean; | ||
maximizeGroup(panel: T): void; | ||
isMaximizedGroup(panel: T): boolean; | ||
exitMaximizedGroup(): void; | ||
hasMaximizedGroup(): boolean; | ||
readonly onDidMaxmizedGroupChange: Event<void>; | ||
} | ||
@@ -77,2 +82,7 @@ export declare abstract class BaseGrid<T extends IGridPanelView> extends Resizable implements IBaseGrid<T> { | ||
isVisible(panel: T): boolean; | ||
maximizeGroup(panel: T): void; | ||
isMaximizedGroup(panel: T): boolean; | ||
exitMaximizedGroup(): void; | ||
hasMaximizedGroup(): boolean; | ||
get onDidMaxmizedGroupChange(): Event<void>; | ||
protected doAddGroup(group: T, location?: number[], size?: number): void; | ||
@@ -79,0 +89,0 @@ protected doRemoveGroup(group: T, options?: { |
@@ -156,2 +156,21 @@ "use strict"; | ||
}; | ||
BaseGrid.prototype.maximizeGroup = function (panel) { | ||
this.gridview.maximizeView(panel); | ||
}; | ||
BaseGrid.prototype.isMaximizedGroup = function (panel) { | ||
return this.gridview.maximizedView() === panel; | ||
}; | ||
BaseGrid.prototype.exitMaximizedGroup = function () { | ||
this.gridview.exitMaximizedView(); | ||
}; | ||
BaseGrid.prototype.hasMaximizedGroup = function () { | ||
return this.gridview.hasMaximizedView(); | ||
}; | ||
Object.defineProperty(BaseGrid.prototype, "onDidMaxmizedGroupChange", { | ||
get: function () { | ||
return this.gridview.onDidMaxmizedNodeChange; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
BaseGrid.prototype.doAddGroup = function (group, location, size) { | ||
@@ -158,0 +177,0 @@ if (location === void 0) { location = [0]; } |
@@ -21,2 +21,4 @@ import { IView, Orientation, Sizing, LayoutPriority, ISplitviewStyles } from '../splitview/splitview'; | ||
}>; | ||
private readonly _onDidVisibilityChange; | ||
readonly onDidVisibilityChange: Event<boolean>; | ||
get width(): number; | ||
@@ -23,0 +25,0 @@ get height(): number; |
@@ -74,2 +74,4 @@ "use strict"; | ||
_this.onDidChange = _this._onDidChange.event; | ||
_this._onDidVisibilityChange = new events_1.Emitter(); | ||
_this.onDidVisibilityChange = _this._onDidVisibilityChange.event; | ||
_this._orthogonalSize = orthogonalSize; | ||
@@ -109,3 +111,3 @@ _this._size = size; | ||
} | ||
_this.addDisposables(_this._onDidChange, _this.splitview.onDidSashEnd(function () { | ||
_this.addDisposables(_this._onDidChange, _this._onDidVisibilityChange, _this.splitview.onDidSashEnd(function () { | ||
_this._onDidChange.fire({}); | ||
@@ -136,5 +138,10 @@ })); | ||
get: function () { | ||
var _this = this; | ||
return this.children.length === 0 | ||
? 0 | ||
: Math.max.apply(Math, __spreadArray([], __read(this.children.map(function (c) { return c.minimumOrthogonalSize; })), false)); | ||
: Math.max.apply(Math, __spreadArray([], __read(this.children.map(function (c, index) { | ||
return _this.splitview.isViewVisible(index) | ||
? c.minimumOrthogonalSize | ||
: 0; | ||
})), false)); | ||
}, | ||
@@ -146,3 +153,8 @@ enumerable: false, | ||
get: function () { | ||
return Math.min.apply(Math, __spreadArray([], __read(this.children.map(function (c) { return c.maximumOrthogonalSize; })), false)); | ||
var _this = this; | ||
return Math.min.apply(Math, __spreadArray([], __read(this.children.map(function (c, index) { | ||
return _this.splitview.isViewVisible(index) | ||
? c.maximumOrthogonalSize | ||
: Number.POSITIVE_INFINITY; | ||
})), false)); | ||
}, | ||
@@ -266,3 +278,11 @@ enumerable: false, | ||
} | ||
var wereAllChildrenHidden = this.splitview.contentSize === 0; | ||
this.splitview.setViewVisible(index, visible); | ||
var areAllChildrenHidden = this.splitview.contentSize === 0; | ||
// If all children are hidden then the parent should hide the entire splitview | ||
// If the entire splitview is hidden then the parent should show the splitview when a child is shown | ||
if ((visible && wereAllChildrenHidden) || | ||
(!visible && areAllChildrenHidden)) { | ||
this._onDidVisibilityChange.fire(visible); | ||
} | ||
}; | ||
@@ -332,9 +352,16 @@ BranchNode.prototype.moveChild = function (from, to) { | ||
this._childrenDisposable.dispose(); | ||
this._childrenDisposable = events_1.Event.any.apply(events_1.Event, __spreadArray([], __read(this.children.map(function (c) { return c.onDidChange; })), false))(function (e) { | ||
/** | ||
* indicate a change has occured to allows any re-rendering but don't bubble | ||
* event because that was specific to this branch | ||
*/ | ||
_this._onDidChange.fire({ size: e.orthogonalSize }); | ||
}); | ||
this._childrenDisposable = new (lifecycle_1.CompositeDisposable.bind.apply(lifecycle_1.CompositeDisposable, __spreadArray([void 0, events_1.Event.any.apply(events_1.Event, __spreadArray([], __read(this.children.map(function (c) { return c.onDidChange; })), false))(function (e) { | ||
/** | ||
* indicate a change has occured to allows any re-rendering but don't bubble | ||
* event because that was specific to this branch | ||
*/ | ||
_this._onDidChange.fire({ size: e.orthogonalSize }); | ||
})], __read(this.children.map(function (c, i) { | ||
if (c instanceof BranchNode) { | ||
return c.onDidVisibilityChange(function (visible) { | ||
_this.setChildVisible(i, visible); | ||
}); | ||
} | ||
return lifecycle_1.Disposable.NONE; | ||
})), false)))(); | ||
}; | ||
@@ -341,0 +368,0 @@ BranchNode.prototype.dispose = function () { |
@@ -88,5 +88,6 @@ import { ISplitviewStyles, LayoutPriority, Orientation, Sizing } from '../splitview/splitview'; | ||
readonly styles: ISplitviewStyles | undefined; | ||
readonly element: HTMLElement; | ||
private _root; | ||
readonly element: HTMLElement; | ||
private disposable; | ||
private _maximizedNode; | ||
private readonly disposable; | ||
private readonly _onDidChange; | ||
@@ -97,2 +98,4 @@ readonly onDidChange: Event<{ | ||
}>; | ||
private readonly _onDidMaxmizedNodeChange; | ||
readonly onDidMaxmizedNodeChange: Event<void>; | ||
get length(): number; | ||
@@ -107,6 +110,10 @@ get orientation(): Orientation; | ||
get maximumHeight(): number; | ||
maximizedView(): IGridView | undefined; | ||
hasMaximizedView(): boolean; | ||
maximizeView(view: IGridView): void; | ||
exitMaximizedView(): void; | ||
serialize(): SerializedGridview<any>; | ||
dispose(): void; | ||
clear(): void; | ||
deserialize(json: any, deserializer: IViewDeserializer): void; | ||
deserialize<T>(json: SerializedGridview<T>, deserializer: IViewDeserializer): void; | ||
private _deserialize; | ||
@@ -113,0 +120,0 @@ private _deserializeNode; |
@@ -168,5 +168,8 @@ "use strict"; | ||
this.styles = styles; | ||
this._maximizedNode = undefined; | ||
this.disposable = new lifecycle_1.MutableDisposable(); | ||
this._onDidChange = new events_1.Emitter(); | ||
this.onDidChange = this._onDidChange.event; | ||
this._onDidMaxmizedNodeChange = new events_1.Emitter(); | ||
this.onDidMaxmizedNodeChange = this._onDidMaxmizedNodeChange.event; | ||
this.element = document.createElement('div'); | ||
@@ -240,3 +243,65 @@ this.element.className = 'grid-view'; | ||
}); | ||
Gridview.prototype.maximizedView = function () { | ||
var _a; | ||
return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.view; | ||
}; | ||
Gridview.prototype.hasMaximizedView = function () { | ||
return this._maximizedNode !== undefined; | ||
}; | ||
Gridview.prototype.maximizeView = function (view) { | ||
var location = getGridLocation(view.element); | ||
var _a = __read(this.getNode(location), 2), _ = _a[0], node = _a[1]; | ||
if (!(node instanceof leafNode_1.LeafNode)) { | ||
return; | ||
} | ||
if (this._maximizedNode === node) { | ||
return; | ||
} | ||
if (this.hasMaximizedView()) { | ||
this.exitMaximizedView(); | ||
} | ||
function hideAllViewsBut(parent, exclude) { | ||
for (var i = 0; i < parent.children.length; i++) { | ||
var child = parent.children[i]; | ||
if (child instanceof leafNode_1.LeafNode) { | ||
if (child !== exclude) { | ||
parent.setChildVisible(i, false); | ||
} | ||
} | ||
else { | ||
hideAllViewsBut(child, exclude); | ||
} | ||
} | ||
} | ||
hideAllViewsBut(this.root, node); | ||
this._maximizedNode = node; | ||
this._onDidMaxmizedNodeChange.fire(); | ||
}; | ||
Gridview.prototype.exitMaximizedView = function () { | ||
if (!this._maximizedNode) { | ||
return; | ||
} | ||
function showViewsInReverseOrder(parent) { | ||
for (var index = parent.children.length - 1; index >= 0; index--) { | ||
var child = parent.children[index]; | ||
if (child instanceof leafNode_1.LeafNode) { | ||
parent.setChildVisible(index, true); | ||
} | ||
else { | ||
showViewsInReverseOrder(child); | ||
} | ||
} | ||
} | ||
showViewsInReverseOrder(this.root); | ||
this._maximizedNode = undefined; | ||
this._onDidMaxmizedNodeChange.fire(); | ||
}; | ||
Gridview.prototype.serialize = function () { | ||
if (this.hasMaximizedView()) { | ||
/** | ||
* do not persist maximized view state but we must first exit any maximized views | ||
* before serialization to ensure the correct dimensions are persisted | ||
*/ | ||
this.exitMaximizedView(); | ||
} | ||
var root = serializeBranchNode(this.getView(), this.orientation); | ||
@@ -253,3 +318,5 @@ return { | ||
this._onDidChange.dispose(); | ||
this._onDidMaxmizedNodeChange.dispose(); | ||
this.root.dispose(); | ||
this._maximizedNode = undefined; | ||
this.element.remove(); | ||
@@ -298,2 +365,3 @@ }; | ||
oldRoot.dispose(); | ||
this._maximizedNode = undefined; | ||
this.element.removeChild(oldRoot.element); | ||
@@ -398,2 +466,5 @@ } | ||
Gridview.prototype.setViewVisible = function (location, visible) { | ||
if (this.hasMaximizedView()) { | ||
this.exitMaximizedView(); | ||
} | ||
var _a = __read((0, array_1.tail)(location), 2), rest = _a[0], index = _a[1]; | ||
@@ -407,2 +478,5 @@ var _b = __read(this.getNode(rest), 2), parent = _b[1]; | ||
Gridview.prototype.moveView = function (parentLocation, from, to) { | ||
if (this.hasMaximizedView()) { | ||
this.exitMaximizedView(); | ||
} | ||
var _a = __read(this.getNode(parentLocation), 2), parent = _a[1]; | ||
@@ -415,2 +489,5 @@ if (!(parent instanceof branchNode_1.BranchNode)) { | ||
Gridview.prototype.addView = function (view, size, location) { | ||
if (this.hasMaximizedView()) { | ||
this.exitMaximizedView(); | ||
} | ||
var _a = __read((0, array_1.tail)(location), 2), rest = _a[0], index = _a[1]; | ||
@@ -448,2 +525,5 @@ var _b = __read(this.getNode(rest), 2), pathToParent = _b[0], parent = _b[1]; | ||
Gridview.prototype.removeView = function (location, sizing) { | ||
if (this.hasMaximizedView()) { | ||
this.exitMaximizedView(); | ||
} | ||
var _a = __read((0, array_1.tail)(location), 2), rest = _a[0], index = _a[1]; | ||
@@ -450,0 +530,0 @@ var _b = __read(this.getNode(rest), 2), pathToParent = _b[0], parent = _b[1]; |
@@ -12,4 +12,4 @@ "use strict"; | ||
function LeafNode(view, orientation, orthogonalSize, size) { | ||
if (size === void 0) { size = 0; } | ||
var _this = this; | ||
if (size === void 0) { size = 0; } | ||
this.view = view; | ||
@@ -157,3 +157,2 @@ this.orientation = orientation; | ||
this.view.setVisible(visible); | ||
this._onDidChange.fire({}); | ||
} | ||
@@ -160,0 +159,0 @@ }; |
@@ -35,4 +35,4 @@ export * from './dnd/dataTransfer'; | ||
export * from './dockview/types'; | ||
export { DockviewPanelRenderer } from './dockview/components/greadyRenderContainer'; | ||
export { Position, positionToDirection, directionToPosition, } from './dnd/droptarget'; | ||
export { DockviewPanelRenderer } from './overlayRenderContainer'; | ||
export { Position, positionToDirection, directionToPosition, MeasuredValue, DroptargetOverlayModel, } from './dnd/droptarget'; | ||
export { FocusEvent, PanelDimensionChangeEvent, VisibilityEvent, ActiveEvent, PanelApi, } from './api/panelApi'; | ||
@@ -39,0 +39,0 @@ export { SizeEvent, GridviewPanelApi, GridConstraintChangeEvent, } from './api/gridviewPanelApi'; |
@@ -10,2 +10,3 @@ export interface IDisposable { | ||
const NONE: IDisposable; | ||
function from(func: () => void): IDisposable; | ||
} | ||
@@ -12,0 +13,0 @@ export declare class CompositeDisposable { |
@@ -11,2 +11,10 @@ "use strict"; | ||
}; | ||
function from(func) { | ||
return { | ||
dispose: function () { | ||
func(); | ||
}, | ||
}; | ||
} | ||
Disposable.from = from; | ||
})(Disposable || (exports.Disposable = Disposable = {})); | ||
@@ -13,0 +21,0 @@ var CompositeDisposable = /** @class */ (function () { |
@@ -5,2 +5,4 @@ import { CompositeDisposable } from './lifecycle'; | ||
url: string; | ||
onOpened?: (id: string, window: Window) => void; | ||
onClosing?: (id: string, window: Window) => void; | ||
} & Box; | ||
@@ -7,0 +9,0 @@ export declare class PopoutWindow extends CompositeDisposable { |
@@ -67,2 +67,5 @@ "use strict"; | ||
if (this._window) { | ||
if (this.options.onClosing) { | ||
this.options.onClosing(this.id, this._window.value); | ||
} | ||
this._window.disposable.dispose(); | ||
@@ -97,5 +100,3 @@ this._window.value.close(); | ||
this._window = { value: externalWindow, disposable: disposable }; | ||
var grievingParent = content.parentElement; | ||
var cleanUp = function () { | ||
grievingParent === null || grievingParent === void 0 ? void 0 : grievingParent.appendChild(content); | ||
_this._onDidClose.fire(); | ||
@@ -130,2 +131,5 @@ _this._window = null; | ||
}); | ||
if (this.options.onOpened) { | ||
this.options.onOpened(this.id, externalWindow); | ||
} | ||
}; | ||
@@ -132,0 +136,0 @@ return PopoutWindow; |
@@ -47,4 +47,19 @@ "use strict"; | ||
} | ||
if (!document.body.contains(_this._element)) { | ||
if (!_this._element.offsetParent) { | ||
/** | ||
* offsetParent === null is equivalent to display: none being set on the element or one | ||
* of it's parents. In the display: none case the size will become (0, 0) which we do | ||
* not want to propagate. | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent | ||
* | ||
* You could use checkVisibility() but at the time of writing it's not supported across | ||
* all Browsers | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility | ||
*/ | ||
return; | ||
} | ||
if (!(0, dom_1.isInDocument)(_this._element)) { | ||
/** | ||
* since the event is dispatched through requestAnimationFrame there is a small chance | ||
@@ -51,0 +66,0 @@ * the component is no longer attached to the DOM, if that is the case the dimensions |
@@ -23,4 +23,4 @@ import { Event } from '../events'; | ||
export declare enum LayoutPriority { | ||
Low = "low", | ||
High = "high", | ||
Low = "low",// view is offered space last | ||
High = "high",// view is offered space first | ||
Normal = "normal" | ||
@@ -78,3 +78,3 @@ } | ||
private _orthogonalSize; | ||
private contentSize; | ||
private _contentSize; | ||
private _proportions; | ||
@@ -90,2 +90,3 @@ private proportionalLayout; | ||
readonly onDidRemoveView: Event<IView>; | ||
get contentSize(): number; | ||
get size(): number; | ||
@@ -96,3 +97,3 @@ set size(value: number); | ||
get length(): number; | ||
get proportions(): number[] | undefined; | ||
get proportions(): (number | undefined)[] | undefined; | ||
get orientation(): Orientation; | ||
@@ -99,0 +100,0 @@ set orientation(value: Orientation); |
@@ -87,3 +87,3 @@ "use strict"; | ||
this._orthogonalSize = 0; | ||
this.contentSize = 0; | ||
this._contentSize = 0; | ||
this._proportions = undefined; | ||
@@ -231,6 +231,13 @@ this._startSnappingEnabled = true; | ||
// Initialize content size and proportions for first layout | ||
this.contentSize = this.viewItems.reduce(function (r, i) { return r + i.size; }, 0); | ||
this._contentSize = this.viewItems.reduce(function (r, i) { return r + i.size; }, 0); | ||
this.saveProportions(); | ||
} | ||
} | ||
Object.defineProperty(Splitview.prototype, "contentSize", { | ||
get: function () { | ||
return this._contentSize; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
Object.defineProperty(Splitview.prototype, "size", { | ||
@@ -675,3 +682,3 @@ get: function () { | ||
var _this = this; | ||
var previousSize = Math.max(this.size, this.contentSize); | ||
var previousSize = Math.max(this.size, this._contentSize); | ||
this.size = size; | ||
@@ -686,6 +693,20 @@ this.orthogonalSize = orthogonalSize; | ||
else { | ||
var total = 0; | ||
for (var i = 0; i < this.viewItems.length; i++) { | ||
var item = this.viewItems[i]; | ||
item.size = (0, math_1.clamp)(Math.round(this.proportions[i] * size), item.minimumSize, item.maximumSize); | ||
var proportion = this.proportions[i]; | ||
if (typeof proportion === 'number') { | ||
total += proportion; | ||
} | ||
else { | ||
size -= item.size; | ||
} | ||
} | ||
for (var i = 0; i < this.viewItems.length; i++) { | ||
var item = this.viewItems[i]; | ||
var proportion = this.proportions[i]; | ||
if (typeof proportion === 'number' && total > 0) { | ||
item.size = (0, math_1.clamp)(Math.round((proportion * size) / total), item.minimumSize, item.maximumSize); | ||
} | ||
} | ||
} | ||
@@ -749,4 +770,6 @@ this.distributeEmptySpace(); | ||
var _this = this; | ||
if (this.proportionalLayout && this.contentSize > 0) { | ||
this._proportions = this.viewItems.map(function (i) { return i.size / _this.contentSize; }); | ||
if (this.proportionalLayout && this._contentSize > 0) { | ||
this._proportions = this.viewItems.map(function (i) { | ||
return i.visible ? i.size / _this._contentSize : undefined; | ||
}); | ||
} | ||
@@ -756,3 +779,3 @@ }; | ||
var _this = this; | ||
this.contentSize = this.viewItems.reduce(function (r, i) { return r + i.size; }, 0); | ||
this._contentSize = this.viewItems.reduce(function (r, i) { return r + i.size; }, 0); | ||
var sum = 0; | ||
@@ -872,3 +895,3 @@ var x = []; | ||
collapsesDown[index] && | ||
(position < this.contentSize || this.endSnappingEnabled)) { | ||
(position < this._contentSize || this.endSnappingEnabled)) { | ||
this.updateSash(sash, SashState.MAXIMUM); | ||
@@ -875,0 +898,0 @@ } |
@@ -456,2 +456,6 @@ import { DockviewDropEvent, IDockviewComponent, SerializedDockview } from '../dockview/dockviewComponent'; | ||
moveToPrevious(options?: MovementOptions): void; | ||
maximizeGroup(panel: IDockviewPanel): void; | ||
hasMaximizedGroup(): boolean; | ||
exitMaxmizedGroup(): void; | ||
get onDidMaxmizedGroupChange(): Event<void>; | ||
/** | ||
@@ -463,4 +467,6 @@ * Add a popout group in a new Window | ||
popoutUrl?: string; | ||
onOpened?: (id: string, window: Window) => void; | ||
onClosing?: (id: string, window: Window) => void; | ||
}): void; | ||
} | ||
//# sourceMappingURL=component.api.d.ts.map |
@@ -638,2 +638,14 @@ import { Emitter } from '../events'; | ||
} | ||
maximizeGroup(panel) { | ||
this.component.maximizeGroup(panel.group); | ||
} | ||
hasMaximizedGroup() { | ||
return this.component.hasMaximizedGroup(); | ||
} | ||
exitMaxmizedGroup() { | ||
this.component.exitMaximizedGroup(); | ||
} | ||
get onDidMaxmizedGroupChange() { | ||
return this.component.onDidMaxmizedGroupChange; | ||
} | ||
/** | ||
@@ -640,0 +652,0 @@ * Add a popout group in a new Window |
@@ -8,8 +8,11 @@ import { Position } from '../dnd/droptarget'; | ||
export interface DockviewGroupPanelApi extends GridviewPanelApi { | ||
readonly onDidRenderPositionChange: Event<DockviewGroupPanelFloatingChangeEvent>; | ||
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>; | ||
readonly location: DockviewGroupLocation; | ||
moveTo(options: { | ||
group: DockviewGroupPanel; | ||
group?: DockviewGroupPanel; | ||
position?: Position; | ||
}): void; | ||
maximize(): void; | ||
isMaximized(): boolean; | ||
exitMaximized(): void; | ||
} | ||
@@ -22,12 +25,15 @@ export interface DockviewGroupPanelFloatingChangeEvent { | ||
private _group; | ||
readonly _onDidRenderPositionChange: Emitter<DockviewGroupPanelFloatingChangeEvent>; | ||
readonly onDidRenderPositionChange: Event<DockviewGroupPanelFloatingChangeEvent>; | ||
readonly _onDidLocationChange: Emitter<DockviewGroupPanelFloatingChangeEvent>; | ||
readonly onDidLocationChange: Event<DockviewGroupPanelFloatingChangeEvent>; | ||
get location(): DockviewGroupLocation; | ||
constructor(id: string, accessor: DockviewComponent); | ||
moveTo(options: { | ||
group: DockviewGroupPanel; | ||
group?: DockviewGroupPanel; | ||
position?: Position; | ||
}): void; | ||
maximize(): void; | ||
isMaximized(): boolean; | ||
exitMaximized(): void; | ||
initialize(group: DockviewGroupPanel): void; | ||
} | ||
//# sourceMappingURL=dockviewGroupPanelApi.d.ts.map |
@@ -0,7 +1,10 @@ | ||
import { positionToDirection } from '../dnd/droptarget'; | ||
import { Emitter } from '../events'; | ||
import { GridviewPanelApiImpl } from './gridviewPanelApi'; | ||
// TODO find a better way to initialize and avoid needing null checks | ||
const NOT_INITIALIZED_MESSAGE = 'DockviewGroupPanelApiImpl not initialized'; | ||
export class DockviewGroupPanelApiImpl extends GridviewPanelApiImpl { | ||
get location() { | ||
if (!this._group) { | ||
throw new Error(`DockviewGroupPanelApiImpl not initialized`); | ||
throw new Error(NOT_INITIALIZED_MESSAGE); | ||
} | ||
@@ -13,13 +16,40 @@ return this._group.model.location; | ||
this.accessor = accessor; | ||
this._onDidRenderPositionChange = new Emitter(); | ||
this.onDidRenderPositionChange = this._onDidRenderPositionChange.event; | ||
this.addDisposables(this._onDidRenderPositionChange); | ||
this._onDidLocationChange = new Emitter(); | ||
this.onDidLocationChange = this._onDidLocationChange.event; | ||
this.addDisposables(this._onDidLocationChange); | ||
} | ||
moveTo(options) { | ||
var _a; | ||
var _a, _b, _c; | ||
if (!this._group) { | ||
throw new Error(`DockviewGroupPanelApiImpl not initialized`); | ||
throw new Error(NOT_INITIALIZED_MESSAGE); | ||
} | ||
this.accessor.moveGroupOrPanel(options.group, this._group.id, undefined, (_a = options.position) !== null && _a !== void 0 ? _a : 'center'); | ||
const group = (_a = options.group) !== null && _a !== void 0 ? _a : this.accessor.addGroup({ | ||
direction: positionToDirection((_b = options.position) !== null && _b !== void 0 ? _b : 'right'), | ||
}); | ||
this.accessor.moveGroupOrPanel(group, this._group.id, undefined, options.group ? (_c = options.position) !== null && _c !== void 0 ? _c : 'center' : 'center'); | ||
} | ||
maximize() { | ||
if (!this._group) { | ||
throw new Error(NOT_INITIALIZED_MESSAGE); | ||
} | ||
if (this.location !== 'grid') { | ||
// only grid groups can be maximized | ||
return; | ||
} | ||
this.accessor.maximizeGroup(this._group); | ||
} | ||
isMaximized() { | ||
if (!this._group) { | ||
throw new Error(NOT_INITIALIZED_MESSAGE); | ||
} | ||
return this.accessor.isMaximizedGroup(this._group); | ||
} | ||
exitMaximized() { | ||
if (!this._group) { | ||
throw new Error(NOT_INITIALIZED_MESSAGE); | ||
} | ||
if (this.isMaximized()) { | ||
this.accessor.exitMaximizedGroup(); | ||
} | ||
} | ||
initialize(group) { | ||
@@ -26,0 +56,0 @@ this._group = group; |
@@ -7,3 +7,3 @@ import { Emitter, Event } from '../events'; | ||
import { Position } from '../dnd/droptarget'; | ||
import { DockviewPanelRenderer } from '../dockview/components/greadyRenderContainer'; | ||
import { DockviewPanelRenderer } from '../overlayRenderContainer'; | ||
export interface TitleEvent { | ||
@@ -31,2 +31,5 @@ readonly title: string; | ||
}): void; | ||
maximize(): void; | ||
isMaximized(): boolean; | ||
exitMaximized(): void; | ||
} | ||
@@ -60,3 +63,6 @@ export declare class DockviewPanelApiImpl extends GridviewPanelApiImpl implements DockviewPanelApi { | ||
close(): void; | ||
maximize(): void; | ||
isMaximized(): boolean; | ||
exitMaximized(): void; | ||
} | ||
//# sourceMappingURL=dockviewPanelApi.d.ts.map |
@@ -9,4 +9,3 @@ import { Emitter } from '../events'; | ||
get isGroupActive() { | ||
var _a; | ||
return !!((_a = this.group) === null || _a === void 0 ? void 0 : _a.isActive); | ||
return this.group.isActive; | ||
} | ||
@@ -62,3 +61,12 @@ get renderer() { | ||
} | ||
maximize() { | ||
this.group.api.maximize(); | ||
} | ||
isMaximized() { | ||
return this.group.api.isMaximized(); | ||
} | ||
exitMaximized() { | ||
this.group.api.exitMaximized(); | ||
} | ||
} | ||
//# sourceMappingURL=dockviewPanelApi.js.map |
@@ -13,2 +13,10 @@ import { Event } from '../events'; | ||
export type CanDisplayOverlay = boolean | ((dragEvent: DragEvent, state: Position) => boolean); | ||
export type MeasuredValue = { | ||
value: number; | ||
type: 'pixels' | 'percentage'; | ||
}; | ||
export type DroptargetOverlayModel = { | ||
size?: MeasuredValue; | ||
activationSize?: MeasuredValue; | ||
}; | ||
export declare class Droptarget extends CompositeDisposable { | ||
@@ -29,14 +37,6 @@ private readonly element; | ||
acceptedTargetZones: Position[]; | ||
overlayModel?: { | ||
size?: { | ||
value: number; | ||
type: 'pixels' | 'percentage'; | ||
}; | ||
activationSize?: { | ||
value: number; | ||
type: 'pixels' | 'percentage'; | ||
}; | ||
}; | ||
overlayModel?: DroptargetOverlayModel; | ||
}); | ||
setTargetZones(acceptedTargetZones: Position[]): void; | ||
setOverlayModel(model: DroptargetOverlayModel): void; | ||
dispose(): void; | ||
@@ -48,7 +48,6 @@ /** | ||
/** | ||
* Check is the event has already been used by another instance od DropTarget | ||
* Check is the event has already been used by another instance of DropTarget | ||
*/ | ||
private isAlreadyUsed; | ||
private toggleClasses; | ||
private setState; | ||
private calculateQuadrant; | ||
@@ -55,0 +54,0 @@ private removeDropTarget; |
@@ -6,5 +6,2 @@ import { toggleClass } from '../dom'; | ||
import { clamp } from '../math'; | ||
function numberOrFallback(maybeNumber, fallback) { | ||
return typeof maybeNumber === 'number' ? maybeNumber : fallback; | ||
} | ||
export function directionToPosition(direction) { | ||
@@ -42,2 +39,12 @@ switch (direction) { | ||
} | ||
const DEFAULT_ACTIVATION_SIZE = { | ||
value: 20, | ||
type: 'percentage', | ||
}; | ||
const DEFAULT_SIZE = { | ||
value: 50, | ||
type: 'percentage', | ||
}; | ||
const SMALL_WIDTH_BOUNDARY = 100; | ||
const SMALL_HEIGHT_BOUNDARY = 100; | ||
export class Droptarget extends CompositeDisposable { | ||
@@ -103,3 +110,3 @@ get state() { | ||
this.toggleClasses(quadrant, width, height); | ||
this.setState(quadrant); | ||
this._state = quadrant; | ||
}, | ||
@@ -129,2 +136,5 @@ onDragLeave: () => { | ||
} | ||
setOverlayModel(model) { | ||
this.options.overlayModel = model; | ||
} | ||
dispose() { | ||
@@ -141,3 +151,3 @@ this.removeDropTarget(); | ||
/** | ||
* Check is the event has already been used by another instance od DropTarget | ||
* Check is the event has already been used by another instance of DropTarget | ||
*/ | ||
@@ -149,8 +159,8 @@ isAlreadyUsed(event) { | ||
toggleClasses(quadrant, width, height) { | ||
var _a, _b, _c, _d; | ||
var _a, _b; | ||
if (!this.overlayElement) { | ||
return; | ||
} | ||
const isSmallX = width < 100; | ||
const isSmallY = height < 100; | ||
const isSmallX = width < SMALL_WIDTH_BOUNDARY; | ||
const isSmallY = height < SMALL_HEIGHT_BOUNDARY; | ||
const isLeft = quadrant === 'left'; | ||
@@ -164,16 +174,13 @@ const isRight = quadrant === 'right'; | ||
const bottomClass = !isSmallY && isBottom; | ||
let size = 0.5; | ||
if (((_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.size) === null || _b === void 0 ? void 0 : _b.type) === 'percentage') { | ||
size = clamp(this.options.overlayModel.size.value, 0, 100) / 100; | ||
let size = 1; | ||
const sizeOptions = (_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.size) !== null && _b !== void 0 ? _b : DEFAULT_SIZE; | ||
if (sizeOptions.type === 'percentage') { | ||
size = clamp(sizeOptions.value, 0, 100) / 100; | ||
} | ||
if (((_d = (_c = this.options.overlayModel) === null || _c === void 0 ? void 0 : _c.size) === null || _d === void 0 ? void 0 : _d.type) === 'pixels') { | ||
else { | ||
if (rightClass || leftClass) { | ||
size = | ||
clamp(0, this.options.overlayModel.size.value, width) / | ||
width; | ||
size = clamp(0, sizeOptions.value, width) / width; | ||
} | ||
if (topClass || bottomClass) { | ||
size = | ||
clamp(0, this.options.overlayModel.size.value, height) / | ||
height; | ||
size = clamp(0, sizeOptions.value, height) / height; | ||
} | ||
@@ -200,35 +207,18 @@ } | ||
this.overlayElement.style.transform = transform; | ||
toggleClass(this.overlayElement, 'small-right', isSmallX && isRight); | ||
toggleClass(this.overlayElement, 'small-left', isSmallX && isLeft); | ||
toggleClass(this.overlayElement, 'small-top', isSmallY && isTop); | ||
toggleClass(this.overlayElement, 'small-bottom', isSmallY && isBottom); | ||
toggleClass(this.overlayElement, 'dv-drop-target-small-vertical', isSmallY); | ||
toggleClass(this.overlayElement, 'dv-drop-target-small-horizontal', isSmallX); | ||
toggleClass(this.overlayElement, 'dv-drop-target-left', isLeft); | ||
toggleClass(this.overlayElement, 'dv-drop-target-right', isRight); | ||
toggleClass(this.overlayElement, 'dv-drop-target-top', isTop); | ||
toggleClass(this.overlayElement, 'dv-drop-target-bottom', isBottom); | ||
toggleClass(this.overlayElement, 'dv-drop-target-center', quadrant === 'center'); | ||
} | ||
setState(quadrant) { | ||
switch (quadrant) { | ||
case 'top': | ||
this._state = 'top'; | ||
break; | ||
case 'left': | ||
this._state = 'left'; | ||
break; | ||
case 'bottom': | ||
this._state = 'bottom'; | ||
break; | ||
case 'right': | ||
this._state = 'right'; | ||
break; | ||
case 'center': | ||
this._state = 'center'; | ||
break; | ||
} | ||
} | ||
calculateQuadrant(overlayType, x, y, width, height) { | ||
var _a, _b, _c, _d, _e, _f; | ||
const isPercentage = ((_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.activationSize) === undefined || | ||
((_c = (_b = this.options.overlayModel) === null || _b === void 0 ? void 0 : _b.activationSize) === null || _c === void 0 ? void 0 : _c.type) === 'percentage'; | ||
const value = numberOrFallback((_f = (_e = (_d = this.options) === null || _d === void 0 ? void 0 : _d.overlayModel) === null || _e === void 0 ? void 0 : _e.activationSize) === null || _f === void 0 ? void 0 : _f.value, 20); | ||
var _a, _b; | ||
const activationSizeOptions = (_b = (_a = this.options.overlayModel) === null || _a === void 0 ? void 0 : _a.activationSize) !== null && _b !== void 0 ? _b : DEFAULT_ACTIVATION_SIZE; | ||
const isPercentage = activationSizeOptions.type === 'percentage'; | ||
if (isPercentage) { | ||
return calculateQuadrantAsPercentage(overlayType, x, y, width, height, value); | ||
return calculateQuadrantAsPercentage(overlayType, x, y, width, height, activationSizeOptions.value); | ||
} | ||
return calculateQuadrantAsPixels(overlayType, x, y, width, height, value); | ||
return calculateQuadrantAsPixels(overlayType, x, y, width, height, activationSizeOptions.value); | ||
} | ||
@@ -235,0 +225,0 @@ removeDropTarget() { |
@@ -17,3 +17,5 @@ import { CompositeDisposable, IDisposable } from '../../../lifecycle'; | ||
hide(): void; | ||
renderPanel(panel: IDockviewPanel): void; | ||
renderPanel(panel: IDockviewPanel, options: { | ||
asActive: boolean; | ||
}): void; | ||
} | ||
@@ -35,3 +37,5 @@ export declare class ContentContainer extends CompositeDisposable implements IContentContainer { | ||
hide(): void; | ||
renderPanel(panel: IDockviewPanel): void; | ||
renderPanel(panel: IDockviewPanel, options?: { | ||
asActive: boolean; | ||
}): void; | ||
openPanel(panel: IDockviewPanel): void; | ||
@@ -38,0 +42,0 @@ layout(_width: number, _height: number): void; |
@@ -24,7 +24,2 @@ import { CompositeDisposable, MutableDisposable, } from '../../../lifecycle'; | ||
this.addDisposables(this._onDidFocus, this._onDidBlur); | ||
// for hosted containers | ||
// 1) register a drop target on the host | ||
// 2) register window dragStart events to disable pointer events | ||
// 3) register dragEnd events | ||
// 4) register mouseMove events (if no buttons are present we take this as a dragEnd event) | ||
this.dropTarget = new Droptarget(this.element, { | ||
@@ -69,10 +64,19 @@ acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'], | ||
} | ||
renderPanel(panel) { | ||
const isActive = panel === this.group.activePanel; | ||
renderPanel(panel, options = { asActive: true }) { | ||
const doRender = options.asActive || | ||
(this.panel && this.group.isPanelActive(this.panel)); | ||
if (this.panel && | ||
this.panel.view.content.element.parentElement === this._element) { | ||
/** | ||
* If the currently attached panel is mounted directly to the content then remove it | ||
*/ | ||
this._element.removeChild(this.panel.view.content.element); | ||
} | ||
this.panel = panel; | ||
let container; | ||
switch (panel.api.renderer) { | ||
case 'onlyWhenVisibile': | ||
this.accessor.greadyRenderContainer.remove(panel); | ||
if (isActive) { | ||
if (this.panel) { | ||
this.accessor.overlayRenderContainer.detatch(panel); | ||
if (this.panel) { | ||
if (doRender) { | ||
this._element.appendChild(this.panel.view.content.element); | ||
@@ -87,7 +91,9 @@ } | ||
} | ||
container = | ||
this.accessor.greadyRenderContainer.setReferenceContentContainer(panel, this); | ||
container = this.accessor.overlayRenderContainer.attach({ | ||
panel, | ||
referenceContainer: this, | ||
}); | ||
break; | ||
} | ||
if (isActive) { | ||
if (doRender) { | ||
const _onDidFocus = panel.view.content.onDidFocus; | ||
@@ -111,34 +117,3 @@ const _onDidBlur = panel.view.content.onDidBlur; | ||
} | ||
const renderer = panel.api.renderer; | ||
if (this.panel && | ||
this.panel.view.content.element.parentElement === this._element) { | ||
/** | ||
* If the currently attached panel is mounted directly to the content then remove it | ||
*/ | ||
this._element.removeChild(this.panel.view.content.element); | ||
} | ||
this.panel = panel; | ||
let container; | ||
switch (renderer) { | ||
case 'always': | ||
container = | ||
this.accessor.greadyRenderContainer.setReferenceContentContainer(panel, this); | ||
break; | ||
case 'onlyWhenVisibile': | ||
this._element.appendChild(this.panel.view.content.element); | ||
container = this._element; | ||
break; | ||
} | ||
const _onDidFocus = this.panel.view.content.onDidFocus; | ||
const _onDidBlur = this.panel.view.content.onDidBlur; | ||
const disposable = new CompositeDisposable(); | ||
const focusTracker = trackFocus(container); | ||
disposable.addDisposables(focusTracker, focusTracker.onDidFocus(() => this._onDidFocus.fire()), focusTracker.onDidBlur(() => this._onDidBlur.fire())); | ||
if (_onDidFocus) { | ||
disposable.addDisposables(_onDidFocus(() => this._onDidFocus.fire())); | ||
} | ||
if (_onDidBlur) { | ||
disposable.addDisposables(_onDidBlur(() => this._onDidBlur.fire())); | ||
} | ||
this.disposable.value = disposable; | ||
this.renderPanel(panel); | ||
} | ||
@@ -145,0 +120,0 @@ layout(_width, _height) { |
@@ -15,3 +15,3 @@ import { SerializedGridObject } from '../gridview/gridview'; | ||
import { Box } from '../types'; | ||
import { GreadyRenderContainer, DockviewPanelRenderer } from './components/greadyRenderContainer'; | ||
import { DockviewPanelRenderer, OverlayRenderContainer } from '../overlayRenderContainer'; | ||
export interface PanelReference { | ||
@@ -45,3 +45,3 @@ update: (event: { | ||
} | ||
export type DockviewComponentUpdateOptions = Pick<DockviewComponentOptions, 'orientation' | 'components' | 'frameworkComponents' | 'tabComponents' | 'frameworkTabComponents' | 'showDndOverlay' | 'watermarkFrameworkComponent' | 'defaultTabComponent' | 'createLeftHeaderActionsElement' | 'createRightHeaderActionsElement' | 'createPrefixHeaderActionsElement' | 'disableFloatingGroups' | 'floatingGroupBounds'>; | ||
export type DockviewComponentUpdateOptions = Pick<DockviewComponentOptions, 'orientation' | 'components' | 'frameworkComponents' | 'tabComponents' | 'frameworkTabComponents' | 'showDndOverlay' | 'watermarkFrameworkComponent' | 'defaultTabComponent' | 'createLeftHeaderActionsElement' | 'createRightHeaderActionsElement' | 'createPrefixHeaderActionsElement' | 'disableFloatingGroups' | 'floatingGroupBounds' | 'rootOverlayModel'>; | ||
export interface DockviewDropEvent extends GroupviewDropEvent { | ||
@@ -87,2 +87,4 @@ api: DockviewApi; | ||
popoutUrl?: string; | ||
onOpened?: (id: string, window: Window) => void; | ||
onClosing?: (id: string, window: Window) => void; | ||
}): void; | ||
@@ -96,3 +98,3 @@ } | ||
private watermark; | ||
readonly greadyRenderContainer: GreadyRenderContainer; | ||
readonly overlayRenderContainer: OverlayRenderContainer; | ||
private readonly _onWillDragPanel; | ||
@@ -114,2 +116,3 @@ readonly onWillDragPanel: Event<TabDragEvent>; | ||
private readonly _popoutGroups; | ||
private readonly _rootDropTarget; | ||
get orientation(): Orientation; | ||
@@ -126,2 +129,4 @@ get totalPanels(): number; | ||
popoutUrl?: string; | ||
onOpened?: (id: string, window: Window) => void; | ||
onClosing?: (id: string, window: Window) => void; | ||
}): void; | ||
@@ -128,0 +133,0 @@ addFloatingGroup(item: DockviewPanel | DockviewGroupPanel, coord?: { |
import { getRelativeLocation, getGridLocation, } from '../gridview/gridview'; | ||
import { directionToPosition, Droptarget } from '../dnd/droptarget'; | ||
import { directionToPosition, Droptarget, } from '../dnd/droptarget'; | ||
import { tail, sequenceEquals, remove } from '../array'; | ||
import { DockviewPanel } from './dockviewPanel'; | ||
import { CompositeDisposable } from '../lifecycle'; | ||
import { CompositeDisposable, Disposable } from '../lifecycle'; | ||
import { Event, Emitter } from '../events'; | ||
@@ -22,4 +22,9 @@ import { Watermark } from './components/watermark/watermark'; | ||
import { DockviewFloatingGroupPanel } from './dockviewFloatingGroupPanel'; | ||
import { GreadyRenderContainer, } from './components/greadyRenderContainer'; | ||
import { DockviewPopoutGroupPanel } from './dockviewPopoutGroupPanel'; | ||
import { DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE, DEFAULT_FLOATING_GROUP_POSITION, } from '../constants'; | ||
import { OverlayRenderContainer, } from '../overlayRenderContainer'; | ||
const DEFAULT_ROOT_OVERLAY_MODEL = { | ||
activationSize: { type: 'pixels', value: 10 }, | ||
size: { type: 'pixels', value: 20 }, | ||
}; | ||
function getTheme(element) { | ||
@@ -44,3 +49,2 @@ function toClassList(element) { | ||
} | ||
const DEFAULT_FLOATING_GROUP_OVERFLOW_SIZE = 100; | ||
function typeValidate3(data, path) { | ||
@@ -131,3 +135,3 @@ if (typeof data.id !== 'string') { | ||
constructor(options) { | ||
var _a; | ||
var _a, _b; | ||
super({ | ||
@@ -160,11 +164,20 @@ proportionalLayout: true, | ||
const gready = document.createElement('div'); | ||
gready.className = 'dv-gready-render-container'; | ||
gready.className = 'dv-overlay-render-container'; | ||
this.gridview.element.appendChild(gready); | ||
this.greadyRenderContainer = new GreadyRenderContainer(gready); | ||
this.overlayRenderContainer = new OverlayRenderContainer(gready); | ||
toggleClass(this.gridview.element, 'dv-dockview', true); | ||
toggleClass(this.element, 'dv-debug', !!options.debug); | ||
this.addDisposables(this.greadyRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, Event.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => { | ||
this.addDisposables(this.overlayRenderContainer, this._onWillDragPanel, this._onWillDragGroup, this._onDidActivePanelChange, this._onDidAddPanel, this._onDidRemovePanel, this._onDidLayoutFromJSON, this._onDidDrop, Event.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => { | ||
this.updateWatermark(); | ||
}), Event.any(this.onDidAddPanel, this.onDidRemovePanel, this.onDidActivePanelChange)(() => { | ||
this._bufferOnDidLayoutChange.fire(); | ||
}), Disposable.from(() => { | ||
// iterate over a copy of the array since .dispose() mutates the original array | ||
for (const group of [...this._floatingGroups]) { | ||
group.dispose(); | ||
} | ||
// iterate over a copy of the array since .dispose() mutates the original array | ||
for (const group of [...this._popoutGroups]) { | ||
group.dispose(); | ||
} | ||
})); | ||
@@ -188,3 +201,3 @@ this._options = options; | ||
} | ||
const dropTarget = new Droptarget(this.element, { | ||
this._rootDropTarget = new Droptarget(this.element, { | ||
canDisplayOverlay: (event, position) => { | ||
@@ -222,8 +235,5 @@ const data = getPanelData(); | ||
acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'], | ||
overlayModel: { | ||
activationSize: { type: 'pixels', value: 10 }, | ||
size: { type: 'pixels', value: 20 }, | ||
}, | ||
overlayModel: (_b = this.options.rootOverlayModel) !== null && _b !== void 0 ? _b : DEFAULT_ROOT_OVERLAY_MODEL, | ||
}); | ||
this.addDisposables(dropTarget.onDrop((event) => { | ||
this.addDisposables(this._rootDropTarget.onDrop((event) => { | ||
var _a; | ||
@@ -237,3 +247,3 @@ const data = getPanelData(); | ||
} | ||
}), dropTarget); | ||
}), this._rootDropTarget); | ||
this._api = new DockviewApi(this); | ||
@@ -269,11 +279,14 @@ this.updateWatermark(); | ||
const theme = getTheme(this.gridview.element); | ||
const popoutWindow = new DockviewPopoutGroupPanel(group, { | ||
const popoutWindow = new DockviewPopoutGroupPanel(`${this.id}-${group.id}`, // globally unique within dockview | ||
group, { | ||
className: theme !== null && theme !== void 0 ? theme : '', | ||
popoutUrl: (_a = options === null || options === void 0 ? void 0 : options.popoutUrl) !== null && _a !== void 0 ? _a : '/popout.html', | ||
box: { | ||
left: box.left, | ||
top: box.top, | ||
left: window.screenX + box.left, | ||
top: window.screenY + box.top, | ||
width: box.width, | ||
height: box.height, | ||
}, | ||
onOpened: options === null || options === void 0 ? void 0 : options.onOpened, | ||
onClosing: options === null || options === void 0 ? void 0 : options.onClosing | ||
}); | ||
@@ -283,2 +296,3 @@ popoutWindow.addDisposables({ | ||
remove(this._popoutGroups, popoutWindow); | ||
this.updateWatermark(); | ||
}, | ||
@@ -289,2 +303,3 @@ }, popoutWindow.window.onDidClose(() => { | ||
this._popoutGroups.push(popoutWindow); | ||
this.updateWatermark(); | ||
} | ||
@@ -311,4 +326,8 @@ addFloatingGroup(item, coord, options) { | ||
group.model.location = 'floating'; | ||
const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100; | ||
const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100; | ||
const overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' | ||
? Math.max(coord.x, 0) | ||
: DEFAULT_FLOATING_GROUP_POSITION.left; | ||
const overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' | ||
? Math.max(coord.y, 0) | ||
: DEFAULT_FLOATING_GROUP_POSITION.top; | ||
const overlay = new Overlay({ | ||
@@ -400,11 +419,13 @@ container: this.gridview.element, | ||
var _a, _b; | ||
const hasOrientationChanged = typeof options.orientation === 'string' && | ||
const changed_orientation = typeof options.orientation === 'string' && | ||
this.gridview.orientation !== options.orientation; | ||
const hasFloatingGroupOptionsChanged = options.floatingGroupBounds !== undefined && | ||
const changed_floatingGroupBounds = options.floatingGroupBounds !== undefined && | ||
options.floatingGroupBounds !== this.options.floatingGroupBounds; | ||
const changed_rootOverlayOptions = options.rootOverlayModel !== undefined && | ||
options.rootOverlayModel !== this.options.rootOverlayModel; | ||
this._options = Object.assign(Object.assign({}, this.options), options); | ||
if (hasOrientationChanged) { | ||
if (changed_orientation) { | ||
this.gridview.orientation = options.orientation; | ||
} | ||
if (hasFloatingGroupOptionsChanged) { | ||
if (changed_floatingGroupBounds) { | ||
for (const group of this._floatingGroups) { | ||
@@ -431,2 +452,5 @@ switch (this.options.floatingGroupBounds) { | ||
} | ||
if (changed_rootOverlayOptions) { | ||
this._rootDropTarget.setOverlayModel(options.rootOverlayModel); | ||
} | ||
this.layout(this.gridview.width, this.gridview.height, true); | ||
@@ -776,3 +800,3 @@ } | ||
if (!options.skipDispose) { | ||
this.greadyRenderContainer.remove(panel); | ||
this.overlayRenderContainer.detatch(panel); | ||
panel.dispose(); | ||
@@ -984,3 +1008,3 @@ } | ||
break; | ||
case 'floating': | ||
case 'floating': { | ||
const selectedFloatingGroup = this._floatingGroups.find((x) => x.group === sourceGroup); | ||
@@ -992,3 +1016,4 @@ if (!selectedFloatingGroup) { | ||
break; | ||
case 'popout': | ||
} | ||
case 'popout': { | ||
const selectedPopoutGroup = this._popoutGroups.find((x) => x.group === sourceGroup); | ||
@@ -999,2 +1024,3 @@ if (!selectedPopoutGroup) { | ||
selectedPopoutGroup.dispose(); | ||
} | ||
} | ||
@@ -1001,0 +1027,0 @@ const referenceLocation = getGridLocation(referenceGroup.element); |
import { DockviewGroupPanelModel, } from './dockviewGroupPanelModel'; | ||
import { GridviewPanel } from '../gridview/gridviewPanel'; | ||
import { DockviewGroupPanelApiImpl, } from '../api/dockviewGroupPanelApi'; | ||
const MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH = 100; | ||
const MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT = 100; | ||
export class DockviewGroupPanel extends GridviewPanel { | ||
@@ -28,4 +30,4 @@ get panels() { | ||
super(id, 'groupview_default', { | ||
minimumHeight: 100, | ||
minimumWidth: 100, | ||
minimumHeight: MINIMUM_DOCKVIEW_GROUP_PANEL_HEIGHT, | ||
minimumWidth: MINIMUM_DOCKVIEW_GROUP_PANEL_WIDTH, | ||
}, new DockviewGroupPanelApiImpl(id, accessor)); | ||
@@ -32,0 +34,0 @@ this.api.initialize(this); // cannot use 'this' after after 'super' call |
@@ -65,3 +65,5 @@ import { DockviewApi } from '../api/component.api'; | ||
this.contentContainer.dropTarget.setTargetZones(['center']); | ||
this.contentContainer.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']); | ||
this.contentContainer.dropTarget.setTargetZones(value | ||
? ['center'] | ||
: ['top', 'bottom', 'left', 'right', 'center']); | ||
toggleClass(this.container, 'dv-groupview-floating', true); | ||
@@ -74,3 +76,3 @@ break; | ||
} | ||
this.groupPanel.api._onDidRenderPositionChange.fire({ | ||
this.groupPanel.api._onDidLocationChange.fire({ | ||
location: this.location, | ||
@@ -176,3 +178,3 @@ }); | ||
rerender(panel) { | ||
this.contentContainer.renderPanel(panel); | ||
this.contentContainer.renderPanel(panel, { asActive: false }); | ||
} | ||
@@ -491,3 +493,2 @@ indexOf(panel) { | ||
} | ||
// this.dropTarget.dispose(); | ||
this.tabsContainer.dispose(); | ||
@@ -494,0 +495,0 @@ this.contentContainer.dispose(); |
@@ -9,3 +9,3 @@ import { DockviewApi } from '../api/component.api'; | ||
import { DockviewComponent } from './dockviewComponent'; | ||
import { DockviewPanelRenderer } from './components/greadyRenderContainer'; | ||
import { DockviewPanelRenderer } from '../overlayRenderContainer'; | ||
export interface IDockviewPanel extends IDisposable, IPanel { | ||
@@ -12,0 +12,0 @@ readonly view: IDockviewPanelModel; |
@@ -6,11 +6,14 @@ import { CompositeDisposable } from '../lifecycle'; | ||
export declare class DockviewPopoutGroupPanel extends CompositeDisposable { | ||
readonly id: string; | ||
readonly group: DockviewGroupPanel; | ||
private readonly options; | ||
readonly window: PopoutWindow; | ||
constructor(group: DockviewGroupPanel, options: { | ||
constructor(id: string, group: DockviewGroupPanel, options: { | ||
className: string; | ||
popoutUrl: string; | ||
box: Box; | ||
onOpened?: (id: string, window: Window) => void; | ||
onClosing?: (id: string, window: Window) => void; | ||
}); | ||
} | ||
//# sourceMappingURL=dockviewPopoutGroupPanel.d.ts.map |
import { CompositeDisposable } from '../lifecycle'; | ||
import { PopoutWindow } from '../popoutWindow'; | ||
export class DockviewPopoutGroupPanel extends CompositeDisposable { | ||
constructor(group, options) { | ||
constructor(id, group, options) { | ||
var _a; | ||
super(); | ||
this.id = id; | ||
this.group = group; | ||
this.options = options; | ||
this.window = new PopoutWindow('test', (_a = options.className) !== null && _a !== void 0 ? _a : '', { | ||
this.window = new PopoutWindow(id, (_a = options.className) !== null && _a !== void 0 ? _a : '', { | ||
url: this.options.popoutUrl, | ||
@@ -15,2 +16,4 @@ left: this.options.box.left, | ||
height: this.options.box.height, | ||
onOpened: this.options.onOpened, | ||
onClosing: this.options.onClosing, | ||
}); | ||
@@ -17,0 +20,0 @@ group.model.location = 'popout'; |
@@ -10,7 +10,7 @@ import { DockviewApi } from '../api/component.api'; | ||
import { IDisposable } from '../lifecycle'; | ||
import { Position } from '../dnd/droptarget'; | ||
import { DroptargetOverlayModel, Position } from '../dnd/droptarget'; | ||
import { IDockviewPanel } from './dockviewPanel'; | ||
import { ComponentConstructor, FrameworkFactory } from '../panel/componentFactory'; | ||
import { DockviewGroupPanelApi } from '../api/dockviewGroupPanelApi'; | ||
import { DockviewPanelRenderer } from './components/greadyRenderContainer'; | ||
import { DockviewPanelRenderer } from '../overlayRenderContainer'; | ||
export interface IHeaderActionsRenderer extends IDisposable { | ||
@@ -80,2 +80,3 @@ readonly element: HTMLElement; | ||
debug?: boolean; | ||
rootOverlayModel?: DroptargetOverlayModel; | ||
} | ||
@@ -82,0 +83,0 @@ export interface PanelOptions<P extends object = Parameters> { |
@@ -8,3 +8,3 @@ import { IDockviewComponent } from './dockviewComponent'; | ||
import { DockviewGroupPanel, IDockviewGroupPanel } from './dockviewGroupPanel'; | ||
import { DockviewPanelRenderer } from './components/greadyRenderContainer'; | ||
import { DockviewPanelRenderer } from '../overlayRenderContainer'; | ||
export declare enum DockviewDropTargets { | ||
@@ -11,0 +11,0 @@ Tab = 0, |
@@ -24,2 +24,7 @@ import { Event as DockviewEvent } from './events'; | ||
}; | ||
/** | ||
* Check whether an element is in the DOM (including the Shadow DOM) | ||
* @see https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/ | ||
*/ | ||
export declare function isInDocument(element: Element): boolean; | ||
//# sourceMappingURL=dom.d.ts.map |
@@ -162,2 +162,22 @@ import { Emitter, addDisposableListener, addDisposableWindowListener, } from './events'; | ||
} | ||
/** | ||
* Check whether an element is in the DOM (including the Shadow DOM) | ||
* @see https://terodox.tech/how-to-tell-if-an-element-is-in-the-dom-including-the-shadow-dom/ | ||
*/ | ||
export function isInDocument(element) { | ||
let currentElement = element; | ||
while (currentElement === null || currentElement === void 0 ? void 0 : currentElement.parentNode) { | ||
if (currentElement.parentNode === document) { | ||
return true; | ||
} | ||
else if (currentElement.parentNode instanceof DocumentFragment) { | ||
// handle shadow DOMs | ||
currentElement = currentElement.parentNode.host; | ||
} | ||
else { | ||
currentElement = currentElement.parentNode; | ||
} | ||
} | ||
return false; | ||
} | ||
//# sourceMappingURL=dom.js.map |
@@ -45,2 +45,7 @@ import { Emitter, Event, TickDelayedEvent } from '../events'; | ||
isVisible(panel: T): boolean; | ||
maximizeGroup(panel: T): void; | ||
isMaximizedGroup(panel: T): boolean; | ||
exitMaximizedGroup(): void; | ||
hasMaximizedGroup(): boolean; | ||
readonly onDidMaxmizedGroupChange: Event<void>; | ||
} | ||
@@ -77,2 +82,7 @@ export declare abstract class BaseGrid<T extends IGridPanelView> extends Resizable implements IBaseGrid<T> { | ||
isVisible(panel: T): boolean; | ||
maximizeGroup(panel: T): void; | ||
isMaximizedGroup(panel: T): boolean; | ||
exitMaximizedGroup(): void; | ||
hasMaximizedGroup(): boolean; | ||
get onDidMaxmizedGroupChange(): Event<void>; | ||
protected doAddGroup(group: T, location?: number[], size?: number): void; | ||
@@ -79,0 +89,0 @@ protected doRemoveGroup(group: T, options?: { |
@@ -84,2 +84,17 @@ import { Emitter, Event, TickDelayedEvent } from '../events'; | ||
} | ||
maximizeGroup(panel) { | ||
this.gridview.maximizeView(panel); | ||
} | ||
isMaximizedGroup(panel) { | ||
return this.gridview.maximizedView() === panel; | ||
} | ||
exitMaximizedGroup() { | ||
this.gridview.exitMaximizedView(); | ||
} | ||
hasMaximizedGroup() { | ||
return this.gridview.hasMaximizedView(); | ||
} | ||
get onDidMaxmizedGroupChange() { | ||
return this.gridview.onDidMaxmizedNodeChange; | ||
} | ||
doAddGroup(group, location = [0], size) { | ||
@@ -86,0 +101,0 @@ this.gridview.addView(group, size !== null && size !== void 0 ? size : Sizing.Distribute, location); |
@@ -21,2 +21,4 @@ import { IView, Orientation, Sizing, LayoutPriority, ISplitviewStyles } from '../splitview/splitview'; | ||
}>; | ||
private readonly _onDidVisibilityChange; | ||
readonly onDidVisibilityChange: Event<boolean>; | ||
get width(): number; | ||
@@ -23,0 +25,0 @@ get height(): number; |
@@ -23,6 +23,10 @@ /*--------------------------------------------------------------------------------------------- | ||
? 0 | ||
: Math.max(...this.children.map((c) => c.minimumOrthogonalSize)); | ||
: Math.max(...this.children.map((c, index) => this.splitview.isViewVisible(index) | ||
? c.minimumOrthogonalSize | ||
: 0)); | ||
} | ||
get maximumSize() { | ||
return Math.min(...this.children.map((c) => c.maximumOrthogonalSize)); | ||
return Math.min(...this.children.map((c, index) => this.splitview.isViewVisible(index) | ||
? c.maximumOrthogonalSize | ||
: Number.POSITIVE_INFINITY)); | ||
} | ||
@@ -85,2 +89,4 @@ get minimumOrthogonalSize() { | ||
this.onDidChange = this._onDidChange.event; | ||
this._onDidVisibilityChange = new Emitter(); | ||
this.onDidVisibilityChange = this._onDidVisibilityChange.event; | ||
this._orthogonalSize = orthogonalSize; | ||
@@ -120,3 +126,3 @@ this._size = size; | ||
} | ||
this.addDisposables(this._onDidChange, this.splitview.onDidSashEnd(() => { | ||
this.addDisposables(this._onDidChange, this._onDidVisibilityChange, this.splitview.onDidSashEnd(() => { | ||
this._onDidChange.fire({}); | ||
@@ -144,3 +150,11 @@ })); | ||
} | ||
const wereAllChildrenHidden = this.splitview.contentSize === 0; | ||
this.splitview.setViewVisible(index, visible); | ||
const areAllChildrenHidden = this.splitview.contentSize === 0; | ||
// If all children are hidden then the parent should hide the entire splitview | ||
// If the entire splitview is hidden then the parent should show the splitview when a child is shown | ||
if ((visible && wereAllChildrenHidden) || | ||
(!visible && areAllChildrenHidden)) { | ||
this._onDidVisibilityChange.fire(visible); | ||
} | ||
} | ||
@@ -209,3 +223,3 @@ moveChild(from, to) { | ||
this._childrenDisposable.dispose(); | ||
this._childrenDisposable = Event.any(...this.children.map((c) => c.onDidChange))((e) => { | ||
this._childrenDisposable = new CompositeDisposable(Event.any(...this.children.map((c) => c.onDidChange))((e) => { | ||
/** | ||
@@ -216,3 +230,10 @@ * indicate a change has occured to allows any re-rendering but don't bubble | ||
this._onDidChange.fire({ size: e.orthogonalSize }); | ||
}); | ||
}), ...this.children.map((c, i) => { | ||
if (c instanceof BranchNode) { | ||
return c.onDidVisibilityChange((visible) => { | ||
this.setChildVisible(i, visible); | ||
}); | ||
} | ||
return Disposable.NONE; | ||
})); | ||
} | ||
@@ -219,0 +240,0 @@ dispose() { |
@@ -88,5 +88,6 @@ import { ISplitviewStyles, LayoutPriority, Orientation, Sizing } from '../splitview/splitview'; | ||
readonly styles: ISplitviewStyles | undefined; | ||
readonly element: HTMLElement; | ||
private _root; | ||
readonly element: HTMLElement; | ||
private disposable; | ||
private _maximizedNode; | ||
private readonly disposable; | ||
private readonly _onDidChange; | ||
@@ -97,2 +98,4 @@ readonly onDidChange: Event<{ | ||
}>; | ||
private readonly _onDidMaxmizedNodeChange; | ||
readonly onDidMaxmizedNodeChange: Event<void>; | ||
get length(): number; | ||
@@ -107,6 +110,10 @@ get orientation(): Orientation; | ||
get maximumHeight(): number; | ||
maximizedView(): IGridView | undefined; | ||
hasMaximizedView(): boolean; | ||
maximizeView(view: IGridView): void; | ||
exitMaximizedView(): void; | ||
serialize(): SerializedGridview<any>; | ||
dispose(): void; | ||
clear(): void; | ||
deserialize(json: any, deserializer: IViewDeserializer): void; | ||
deserialize<T>(json: SerializedGridview<T>, deserializer: IViewDeserializer): void; | ||
private _deserialize; | ||
@@ -113,0 +120,0 @@ private _deserializeNode; |
@@ -158,3 +158,65 @@ /*--------------------------------------------------------------------------------------------- | ||
} | ||
maximizedView() { | ||
var _a; | ||
return (_a = this._maximizedNode) === null || _a === void 0 ? void 0 : _a.view; | ||
} | ||
hasMaximizedView() { | ||
return this._maximizedNode !== undefined; | ||
} | ||
maximizeView(view) { | ||
const location = getGridLocation(view.element); | ||
const [_, node] = this.getNode(location); | ||
if (!(node instanceof LeafNode)) { | ||
return; | ||
} | ||
if (this._maximizedNode === node) { | ||
return; | ||
} | ||
if (this.hasMaximizedView()) { | ||
this.exitMaximizedView(); | ||
} | ||
function hideAllViewsBut(parent, exclude) { | ||
for (let i = 0; i < parent.children.length; i++) { | ||
const child = parent.children[i]; | ||
if (child instanceof LeafNode) { | ||
if (child !== exclude) { | ||
parent.setChildVisible(i, false); | ||
} | ||
} | ||
else { | ||
hideAllViewsBut(child, exclude); | ||
} | ||
} | ||
} | ||
hideAllViewsBut(this.root, node); | ||
this._maximizedNode = node; | ||
this._onDidMaxmizedNodeChange.fire(); | ||
} | ||
exitMaximizedView() { | ||
if (!this._maximizedNode) { | ||
return; | ||
} | ||
function showViewsInReverseOrder(parent) { | ||
for (let index = parent.children.length - 1; index >= 0; index--) { | ||
const child = parent.children[index]; | ||
if (child instanceof LeafNode) { | ||
parent.setChildVisible(index, true); | ||
} | ||
else { | ||
showViewsInReverseOrder(child); | ||
} | ||
} | ||
} | ||
showViewsInReverseOrder(this.root); | ||
this._maximizedNode = undefined; | ||
this._onDidMaxmizedNodeChange.fire(); | ||
} | ||
serialize() { | ||
if (this.hasMaximizedView()) { | ||
/** | ||
* do not persist maximized view state but we must first exit any maximized views | ||
* before serialization to ensure the correct dimensions are persisted | ||
*/ | ||
this.exitMaximizedView(); | ||
} | ||
const root = serializeBranchNode(this.getView(), this.orientation); | ||
@@ -171,3 +233,5 @@ return { | ||
this._onDidChange.dispose(); | ||
this._onDidMaxmizedNodeChange.dispose(); | ||
this.root.dispose(); | ||
this._maximizedNode = undefined; | ||
this.element.remove(); | ||
@@ -213,2 +277,3 @@ } | ||
oldRoot.dispose(); | ||
this._maximizedNode = undefined; | ||
this.element.removeChild(oldRoot.element); | ||
@@ -302,5 +367,8 @@ } | ||
this.styles = styles; | ||
this._maximizedNode = undefined; | ||
this.disposable = new MutableDisposable(); | ||
this._onDidChange = new Emitter(); | ||
this.onDidChange = this._onDidChange.event; | ||
this._onDidMaxmizedNodeChange = new Emitter(); | ||
this.onDidMaxmizedNodeChange = this._onDidMaxmizedNodeChange.event; | ||
this.element = document.createElement('div'); | ||
@@ -319,2 +387,5 @@ this.element.className = 'grid-view'; | ||
setViewVisible(location, visible) { | ||
if (this.hasMaximizedView()) { | ||
this.exitMaximizedView(); | ||
} | ||
const [rest, index] = tail(location); | ||
@@ -328,2 +399,5 @@ const [, parent] = this.getNode(rest); | ||
moveView(parentLocation, from, to) { | ||
if (this.hasMaximizedView()) { | ||
this.exitMaximizedView(); | ||
} | ||
const [, parent] = this.getNode(parentLocation); | ||
@@ -336,2 +410,5 @@ if (!(parent instanceof BranchNode)) { | ||
addView(view, size, location) { | ||
if (this.hasMaximizedView()) { | ||
this.exitMaximizedView(); | ||
} | ||
const [rest, index] = tail(location); | ||
@@ -369,2 +446,5 @@ const [pathToParent, parent] = this.getNode(rest); | ||
removeView(location, sizing) { | ||
if (this.hasMaximizedView()) { | ||
this.exitMaximizedView(); | ||
} | ||
const [rest, index] = tail(location); | ||
@@ -371,0 +451,0 @@ const [pathToParent, parent] = this.getNode(rest); |
@@ -91,3 +91,2 @@ /*--------------------------------------------------------------------------------------------- | ||
this.view.setVisible(visible); | ||
this._onDidChange.fire({}); | ||
} | ||
@@ -94,0 +93,0 @@ } |
@@ -35,4 +35,4 @@ export * from './dnd/dataTransfer'; | ||
export * from './dockview/types'; | ||
export { DockviewPanelRenderer } from './dockview/components/greadyRenderContainer'; | ||
export { Position, positionToDirection, directionToPosition, } from './dnd/droptarget'; | ||
export { DockviewPanelRenderer } from './overlayRenderContainer'; | ||
export { Position, positionToDirection, directionToPosition, MeasuredValue, DroptargetOverlayModel, } from './dnd/droptarget'; | ||
export { FocusEvent, PanelDimensionChangeEvent, VisibilityEvent, ActiveEvent, PanelApi, } from './api/panelApi'; | ||
@@ -39,0 +39,0 @@ export { SizeEvent, GridviewPanelApi, GridConstraintChangeEvent, } from './api/gridviewPanelApi'; |
@@ -10,2 +10,3 @@ export interface IDisposable { | ||
const NONE: IDisposable; | ||
function from(func: () => void): IDisposable; | ||
} | ||
@@ -12,0 +13,0 @@ export declare class CompositeDisposable { |
@@ -8,2 +8,10 @@ export var Disposable; | ||
}; | ||
function from(func) { | ||
return { | ||
dispose: () => { | ||
func(); | ||
}, | ||
}; | ||
} | ||
Disposable.from = from; | ||
})(Disposable || (Disposable = {})); | ||
@@ -10,0 +18,0 @@ export class CompositeDisposable { |
@@ -5,2 +5,4 @@ import { CompositeDisposable } from './lifecycle'; | ||
url: string; | ||
onOpened?: (id: string, window: Window) => void; | ||
onClosing?: (id: string, window: Window) => void; | ||
} & Box; | ||
@@ -7,0 +9,0 @@ export declare class PopoutWindow extends CompositeDisposable { |
@@ -31,2 +31,5 @@ import { addStyles } from './dom'; | ||
if (this._window) { | ||
if (this.options.onClosing) { | ||
this.options.onClosing(this.id, this._window.value); | ||
} | ||
this._window.disposable.dispose(); | ||
@@ -57,5 +60,3 @@ this._window.value.close(); | ||
this._window = { value: externalWindow, disposable }; | ||
const grievingParent = content.parentElement; | ||
const cleanUp = () => { | ||
grievingParent === null || grievingParent === void 0 ? void 0 : grievingParent.appendChild(content); | ||
this._onDidClose.fire(); | ||
@@ -90,4 +91,7 @@ this._window = null; | ||
}); | ||
if (this.options.onOpened) { | ||
this.options.onOpened(this.id, externalWindow); | ||
} | ||
} | ||
} | ||
//# sourceMappingURL=popoutWindow.js.map |
@@ -1,2 +0,2 @@ | ||
import { watchElementResize } from './dom'; | ||
import { isInDocument, watchElementResize } from './dom'; | ||
import { CompositeDisposable } from './lifecycle'; | ||
@@ -36,4 +36,19 @@ export class Resizable extends CompositeDisposable { | ||
} | ||
if (!document.body.contains(this._element)) { | ||
if (!this._element.offsetParent) { | ||
/** | ||
* offsetParent === null is equivalent to display: none being set on the element or one | ||
* of it's parents. In the display: none case the size will become (0, 0) which we do | ||
* not want to propagate. | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent | ||
* | ||
* You could use checkVisibility() but at the time of writing it's not supported across | ||
* all Browsers | ||
* | ||
* @see https://developer.mozilla.org/en-US/docs/Web/API/Element/checkVisibility | ||
*/ | ||
return; | ||
} | ||
if (!isInDocument(this._element)) { | ||
/** | ||
* since the event is dispatched through requestAnimationFrame there is a small chance | ||
@@ -40,0 +55,0 @@ * the component is no longer attached to the DOM, if that is the case the dimensions |
@@ -23,4 +23,4 @@ import { Event } from '../events'; | ||
export declare enum LayoutPriority { | ||
Low = "low", | ||
High = "high", | ||
Low = "low",// view is offered space last | ||
High = "high",// view is offered space first | ||
Normal = "normal" | ||
@@ -78,3 +78,3 @@ } | ||
private _orthogonalSize; | ||
private contentSize; | ||
private _contentSize; | ||
private _proportions; | ||
@@ -90,2 +90,3 @@ private proportionalLayout; | ||
readonly onDidRemoveView: Event<IView>; | ||
get contentSize(): number; | ||
get size(): number; | ||
@@ -96,3 +97,3 @@ set size(value: number); | ||
get length(): number; | ||
get proportions(): number[] | undefined; | ||
get proportions(): (number | undefined)[] | undefined; | ||
get orientation(): Orientation; | ||
@@ -99,0 +100,0 @@ set orientation(value: Orientation); |
@@ -41,2 +41,5 @@ /*--------------------------------------------------------------------------------------------- | ||
export class Splitview { | ||
get contentSize() { | ||
return this._contentSize; | ||
} | ||
get size() { | ||
@@ -107,3 +110,3 @@ return this._size; | ||
this._orthogonalSize = 0; | ||
this.contentSize = 0; | ||
this._contentSize = 0; | ||
this._proportions = undefined; | ||
@@ -227,3 +230,3 @@ this._startSnappingEnabled = true; | ||
// Initialize content size and proportions for first layout | ||
this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); | ||
this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); | ||
this.saveProportions(); | ||
@@ -502,3 +505,3 @@ } | ||
layout(size, orthogonalSize) { | ||
const previousSize = Math.max(this.size, this.contentSize); | ||
const previousSize = Math.max(this.size, this._contentSize); | ||
this.size = size; | ||
@@ -513,6 +516,20 @@ this.orthogonalSize = orthogonalSize; | ||
else { | ||
let total = 0; | ||
for (let i = 0; i < this.viewItems.length; i++) { | ||
const item = this.viewItems[i]; | ||
item.size = clamp(Math.round(this.proportions[i] * size), item.minimumSize, item.maximumSize); | ||
const proportion = this.proportions[i]; | ||
if (typeof proportion === 'number') { | ||
total += proportion; | ||
} | ||
else { | ||
size -= item.size; | ||
} | ||
} | ||
for (let i = 0; i < this.viewItems.length; i++) { | ||
const item = this.viewItems[i]; | ||
const proportion = this.proportions[i]; | ||
if (typeof proportion === 'number' && total > 0) { | ||
item.size = clamp(Math.round((proportion * size) / total), item.minimumSize, item.maximumSize); | ||
} | ||
} | ||
} | ||
@@ -553,8 +570,8 @@ this.distributeEmptySpace(); | ||
saveProportions() { | ||
if (this.proportionalLayout && this.contentSize > 0) { | ||
this._proportions = this.viewItems.map((i) => i.size / this.contentSize); | ||
if (this.proportionalLayout && this._contentSize > 0) { | ||
this._proportions = this.viewItems.map((i) => i.visible ? i.size / this._contentSize : undefined); | ||
} | ||
} | ||
layoutViews() { | ||
this.contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); | ||
this._contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); | ||
let sum = 0; | ||
@@ -653,3 +670,3 @@ const x = []; | ||
collapsesDown[index] && | ||
(position < this.contentSize || this.endSnappingEnabled)) { | ||
(position < this._contentSize || this.endSnappingEnabled)) { | ||
this.updateSash(sash, SashState.MAXIMUM); | ||
@@ -656,0 +673,0 @@ } |
{ | ||
"name": "dockview-core", | ||
"version": "0.0.0-experimental-1264055-20231228", | ||
"version": "0.0.0-experimental-1cc340f-20240127", | ||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -11,2 +11,3 @@ <div align="center"> | ||
[![npm version](https://badge.fury.io/js/dockview.svg)](https://www.npmjs.com/package/dockview) | ||
[![npm](https://img.shields.io/npm/dm/dockview)](https://www.npmjs.com/package/dockview) | ||
[![CI Build](https://github.com/mathuo/dockview/workflows/CI/badge.svg)](https://github.com/mathuo/dockview/actions?query=workflow%3ACI) | ||
@@ -19,2 +20,4 @@ [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=mathuo_dockview&metric=coverage)](https://sonarcloud.io/summary/overall?id=mathuo_dockview) | ||
![](packages/docs/static/img/splashscreen.gif) | ||
Please see the website: https://dockview.dev | ||
@@ -24,16 +27,20 @@ | ||
- Simple splitviews, nested splitviews (i.e. gridviews) supporting full layout managment with | ||
dockable and tabular views | ||
- Extensive API support at the component level and view level | ||
- Themable and customizable | ||
- Serialization / deserialization support | ||
- Tabular docking and Drag and Drop support | ||
- Floating groups, customized header bars and tab | ||
- Documentation and examples | ||
- Serialization / deserialization with full layout management | ||
- Support for split-views, grid-views and 'dockable' views | ||
- Themeable and customizable | ||
- Tab and Group docking / Drag n' Drop | ||
- Popout Windows | ||
- Floating Groups | ||
- Extensive API | ||
- Supports Shadow DOMs | ||
- High test coverage | ||
- Documentation website with live examples | ||
- Transparent builds and Code Analysis | ||
- Security at mind - verifed publishing and builds through GitHub Actions | ||
Want to inspect the latest deployment? Go to https://unpkg.com/browse/dockview-core@latest/ | ||
Want to verify our builds? Go [here](https://www.npmjs.com/package/dockview#Provenance). | ||
## Quick start | ||
You can install dockview-core from [npm](https://www.npmjs.com/package/dockview-core). | ||
Dockview has a peer dependency on `react >= 16.8.0` and `react-dom >= 16.8.0`. You can install dockview from [npm](https://www.npmjs.com/package/dockview-core). | ||
@@ -40,0 +47,0 @@ ``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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 not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
7672688
537
82646
59