dockview-core
Advanced tools
Comparing version 1.7.6 to 1.8.0
@@ -17,6 +17,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DockviewApi = exports.GridviewApi = exports.PaneviewApi = exports.SplitviewApi = exports.directionToPosition = exports.positionToDirection = exports.DockviewCompositeDisposable = exports.DockviewMutableDisposable = exports.DockviewEvent = exports.DockviewEmitter = exports.watchElementResize = void 0; | ||
exports.DockviewApi = exports.GridviewApi = exports.PaneviewApi = exports.SplitviewApi = exports.directionToPosition = exports.positionToDirection = exports.DockviewCompositeDisposable = exports.DockviewMutableDisposable = exports.DockviewEvent = exports.DockviewEmitter = void 0; | ||
__exportStar(require("./dnd/dataTransfer"), exports); | ||
var dom_1 = require("./dom"); | ||
Object.defineProperty(exports, "watchElementResize", { enumerable: true, get: function () { return dom_1.watchElementResize; } }); | ||
/** | ||
@@ -23,0 +21,0 @@ * Events, Emitters and Disposables are very common concepts that most codebases will contain. |
@@ -134,3 +134,4 @@ import { DockviewDropEvent, IDockviewComponent, SerializedDockview } from '../dockview/dockviewComponent'; | ||
addPanel(options: AddPanelOptions): IDockviewPanel; | ||
addGroup(options?: AddGroupOptions): IDockviewGroupPanel; | ||
removePanel(panel: IDockviewPanel): void; | ||
addGroup(options?: AddGroupOptions): DockviewGroupPanel; | ||
moveToNext(options?: MovementOptions): void; | ||
@@ -141,2 +142,6 @@ moveToPrevious(options?: MovementOptions): void; | ||
getGroup(id: string): DockviewGroupPanel | undefined; | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, coord?: { | ||
x: number; | ||
y: number; | ||
}): void; | ||
fromJSON(data: SerializedDockview): void; | ||
@@ -143,0 +148,0 @@ toJSON(): SerializedDockview; |
@@ -543,2 +543,5 @@ "use strict"; | ||
}; | ||
DockviewApi.prototype.removePanel = function (panel) { | ||
this.component.removePanel(panel); | ||
}; | ||
DockviewApi.prototype.addGroup = function (options) { | ||
@@ -562,2 +565,5 @@ return this.component.addGroup(options); | ||
}; | ||
DockviewApi.prototype.addFloatingGroup = function (item, coord) { | ||
return this.component.addFloatingGroup(item, coord); | ||
}; | ||
DockviewApi.prototype.fromJSON = function (data) { | ||
@@ -564,0 +570,0 @@ this.component.fromJSON(data); |
@@ -5,2 +5,4 @@ import { Emitter, Event } from '../events'; | ||
import { IDockviewPanel } from '../dockview/dockviewPanel'; | ||
import { DockviewComponent } from '../dockview/dockviewComponent'; | ||
import { Position } from '../dnd/droptarget'; | ||
export interface TitleEvent { | ||
@@ -17,5 +19,11 @@ readonly title: string; | ||
setTitle(title: string): void; | ||
moveTo(options: { | ||
group: DockviewGroupPanel; | ||
position?: Position; | ||
index?: number; | ||
}): void; | ||
} | ||
export declare class DockviewPanelApiImpl extends GridviewPanelApiImpl implements DockviewPanelApi { | ||
private panel; | ||
private readonly accessor; | ||
private _group; | ||
@@ -33,3 +41,8 @@ readonly _onDidTitleChange: Emitter<TitleEvent>; | ||
get group(): DockviewGroupPanel; | ||
constructor(panel: IDockviewPanel, group: DockviewGroupPanel); | ||
constructor(panel: IDockviewPanel, group: DockviewGroupPanel, accessor: DockviewComponent); | ||
moveTo(options: { | ||
group: DockviewGroupPanel; | ||
position?: Position; | ||
index?: number; | ||
}): void; | ||
setTitle(title: string): void; | ||
@@ -36,0 +49,0 @@ close(): void; |
@@ -24,5 +24,6 @@ "use strict"; | ||
__extends(DockviewPanelApiImpl, _super); | ||
function DockviewPanelApiImpl(panel, group) { | ||
function DockviewPanelApiImpl(panel, group, accessor) { | ||
var _this = _super.call(this, panel.id) || this; | ||
_this.panel = panel; | ||
_this.accessor = accessor; | ||
_this._onDidTitleChange = new events_1.Emitter(); | ||
@@ -76,2 +77,6 @@ _this.onDidTitleChange = _this._onDidTitleChange.event; | ||
}); | ||
DockviewPanelApiImpl.prototype.moveTo = function (options) { | ||
var _a; | ||
this.accessor.moveGroupOrPanel(options.group, this._group.id, this.panel.id, (_a = options.position) !== null && _a !== void 0 ? _a : 'center', options.index); | ||
}; | ||
DockviewPanelApiImpl.prototype.setTitle = function (title) { | ||
@@ -78,0 +83,0 @@ this.panel.setTitle(title); |
@@ -13,2 +13,3 @@ export declare function tail<T>(arr: T[]): [T[], T]; | ||
export declare function firstIndex<T>(array: T[] | ReadonlyArray<T>, fn: (item: T) => boolean): number; | ||
export declare function remove<T>(array: T[], value: T): boolean; | ||
//# sourceMappingURL=array.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.firstIndex = exports.pushToEnd = exports.pushToStart = exports.sequenceEquals = exports.last = exports.tail = void 0; | ||
exports.remove = exports.firstIndex = exports.pushToEnd = exports.pushToStart = exports.sequenceEquals = exports.last = exports.tail = void 0; | ||
function tail(arr) { | ||
@@ -59,2 +59,11 @@ if (arr.length === 0) { | ||
exports.firstIndex = firstIndex; | ||
function remove(array, value) { | ||
var index = array.findIndex(function (t) { return t === value; }); | ||
if (index > -1) { | ||
array.splice(index, 1); | ||
return true; | ||
} | ||
return false; | ||
} | ||
exports.remove = remove; | ||
//# sourceMappingURL=array.js.map |
@@ -10,4 +10,5 @@ import { CompositeDisposable, IDisposable } from '../lifecycle'; | ||
abstract getData(dataTransfer?: DataTransfer | null): IDisposable; | ||
protected isCancelled(_event: DragEvent): boolean; | ||
private configure; | ||
} | ||
//# sourceMappingURL=abstractDragHandler.d.ts.map |
@@ -71,2 +71,5 @@ "use strict"; | ||
} | ||
DragHandler.prototype.isCancelled = function (_event) { | ||
return false; | ||
}; | ||
DragHandler.prototype.configure = function () { | ||
@@ -76,2 +79,6 @@ var _this = this; | ||
var e_1, _a; | ||
if (_this.isCancelled(event)) { | ||
event.preventDefault(); | ||
return; | ||
} | ||
var iframes = __spreadArray(__spreadArray([], __read((0, dom_1.getElementsByTagName)('iframe')), false), __read((0, dom_1.getElementsByTagName)('webview')), false); | ||
@@ -78,0 +85,0 @@ _this.pointerEventsDisposable.value = { |
@@ -18,4 +18,6 @@ import { Event } from '../events'; | ||
private _state; | ||
private _acceptedTargetZonesSet; | ||
private readonly _onDrop; | ||
readonly onDrop: Event<DroptargetEvent>; | ||
private static USED_EVENT_ID; | ||
get state(): Position | undefined; | ||
@@ -36,3 +38,12 @@ constructor(element: HTMLElement, options: { | ||
}); | ||
setTargetZones(acceptedTargetZones: Position[]): void; | ||
dispose(): void; | ||
/** | ||
* Add a property to the event object for other potential listeners to check | ||
*/ | ||
private markAsUsed; | ||
/** | ||
* Check is the event has already been used by another instance od DropTarget | ||
*/ | ||
private isAlreadyUsed; | ||
private toggleClasses; | ||
@@ -39,0 +50,0 @@ private setState; |
@@ -70,6 +70,10 @@ "use strict"; | ||
// use a set to take advantage of #<set>.has | ||
var acceptedTargetZonesSet = new Set(_this.options.acceptedTargetZones); | ||
_this._acceptedTargetZonesSet = new Set(_this.options.acceptedTargetZones); | ||
_this.addDisposables(_this._onDrop, new dnd_1.DragAndDropObserver(_this.element, { | ||
onDragEnter: function () { return undefined; }, | ||
onDragOver: function (e) { | ||
if (_this._acceptedTargetZonesSet.size === 0) { | ||
_this.removeDropTarget(); | ||
return; | ||
} | ||
var width = _this.element.clientWidth; | ||
@@ -83,4 +87,9 @@ var height = _this.element.clientHeight; | ||
var y = e.clientY - rect.top; | ||
var quadrant = _this.calculateQuadrant(acceptedTargetZonesSet, x, y, width, height); | ||
if (quadrant === null) { | ||
var quadrant = _this.calculateQuadrant(_this._acceptedTargetZonesSet, x, y, width, height); | ||
/** | ||
* If the event has already been used by another DropTarget instance | ||
* then don't show a second drop target, only one target should be | ||
* active at any one time | ||
*/ | ||
if (_this.isAlreadyUsed(e) || quadrant === null) { | ||
// no drop target should be displayed | ||
@@ -92,2 +101,3 @@ _this.removeDropTarget(); | ||
if (!_this.options.canDisplayOverlay) { | ||
_this.removeDropTarget(); | ||
return; | ||
@@ -97,4 +107,6 @@ } | ||
else if (!_this.options.canDisplayOverlay(e, quadrant)) { | ||
_this.removeDropTarget(); | ||
return; | ||
} | ||
_this.markAsUsed(e); | ||
if (!_this.targetElement) { | ||
@@ -110,8 +122,2 @@ _this.targetElement = document.createElement('div'); | ||
} | ||
if (_this.options.acceptedTargetZones.length === 0) { | ||
return; | ||
} | ||
if (!_this.targetElement || !_this.overlayElement) { | ||
return; | ||
} | ||
_this.toggleClasses(quadrant, width, height); | ||
@@ -147,2 +153,5 @@ _this.setState(quadrant); | ||
}); | ||
Droptarget.prototype.setTargetZones = function (acceptedTargetZones) { | ||
this._acceptedTargetZonesSet = new Set(acceptedTargetZones); | ||
}; | ||
Droptarget.prototype.dispose = function () { | ||
@@ -152,2 +161,15 @@ this.removeDropTarget(); | ||
}; | ||
/** | ||
* Add a property to the event object for other potential listeners to check | ||
*/ | ||
Droptarget.prototype.markAsUsed = function (event) { | ||
event[Droptarget.USED_EVENT_ID] = true; | ||
}; | ||
/** | ||
* Check is the event has already been used by another instance od DropTarget | ||
*/ | ||
Droptarget.prototype.isAlreadyUsed = function (event) { | ||
var value = event[Droptarget.USED_EVENT_ID]; | ||
return typeof value === 'boolean' && value; | ||
}; | ||
Droptarget.prototype.toggleClasses = function (quadrant, width, height) { | ||
@@ -246,2 +268,3 @@ var _a, _b, _c, _d; | ||
}; | ||
Droptarget.USED_EVENT_ID = '__dockview_droptarget_event_is_used__'; | ||
return Droptarget; | ||
@@ -248,0 +271,0 @@ }(lifecycle_1.CompositeDisposable)); |
@@ -9,4 +9,5 @@ import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel'; | ||
constructor(element: HTMLElement, accessorId: string, group: DockviewGroupPanel); | ||
isCancelled(_event: DragEvent): boolean; | ||
getData(dataTransfer: DataTransfer | null): IDisposable; | ||
} | ||
//# sourceMappingURL=groupDragHandler.d.ts.map |
@@ -19,2 +19,4 @@ "use strict"; | ||
exports.GroupDragHandler = void 0; | ||
var dom_1 = require("../dom"); | ||
var events_1 = require("../events"); | ||
var abstractDragHandler_1 = require("./abstractDragHandler"); | ||
@@ -30,4 +32,20 @@ var dataTransfer_1 = require("./dataTransfer"); | ||
_this.panelTransfer = dataTransfer_1.LocalSelectionTransfer.getInstance(); | ||
_this.addDisposables((0, events_1.addDisposableListener)(element, 'mousedown', function (e) { | ||
if (e.shiftKey) { | ||
/** | ||
* You cannot call e.preventDefault() because that will prevent drag events from firing | ||
* but we also need to stop any group overlay drag events from occuring | ||
* Use a custom event marker that can be checked by the overlay drag events | ||
*/ | ||
(0, dom_1.quasiPreventDefault)(e); | ||
} | ||
}, true)); | ||
return _this; | ||
} | ||
GroupDragHandler.prototype.isCancelled = function (_event) { | ||
if (this.group.api.isFloating && !_event.shiftKey) { | ||
return true; | ||
} | ||
return false; | ||
}; | ||
GroupDragHandler.prototype.getData = function (dataTransfer) { | ||
@@ -34,0 +52,0 @@ var _this = this; |
import { Event } from '../../../events'; | ||
import { CompositeDisposable, IDisposable } from '../../../lifecycle'; | ||
import { IDockviewComponent } from '../../dockviewComponent'; | ||
import { DockviewComponent } from '../../dockviewComponent'; | ||
import { ITabRenderer } from '../../types'; | ||
@@ -27,3 +27,3 @@ import { DockviewGroupPanel } from '../../dockviewGroupPanel'; | ||
get element(): HTMLElement; | ||
constructor(panelId: string, accessor: IDockviewComponent, group: DockviewGroupPanel); | ||
constructor(panelId: string, accessor: DockviewComponent, group: DockviewGroupPanel); | ||
setActive(isActive: boolean): void; | ||
@@ -30,0 +30,0 @@ setContent(part: ITabRenderer): void; |
@@ -64,9 +64,2 @@ "use strict"; | ||
} | ||
/** | ||
* TODO: alternative to stopPropagation | ||
* | ||
* I need to stop the event propagation here since otherwise it'll be intercepted by event handlers | ||
* on the tabs-container. I cannot use event.preventDefault() since I need the on DragStart event to occur | ||
*/ | ||
event.stopPropagation(); | ||
_this._onChanged.fire(event); | ||
@@ -73,0 +66,0 @@ })); |
@@ -23,3 +23,4 @@ import { IDisposable, CompositeDisposable } from '../../../lifecycle'; | ||
openPanel: (panel: IDockviewPanel, index?: number) => void; | ||
setActionElement(element: HTMLElement | undefined): void; | ||
setRightActionsElement(element: HTMLElement | undefined): void; | ||
setLeftActionsElement(element: HTMLElement | undefined): void; | ||
hidden: boolean; | ||
@@ -34,7 +35,9 @@ show(): void; | ||
private readonly tabContainer; | ||
private readonly actionContainer; | ||
private readonly rightActionsContainer; | ||
private readonly leftActionsContainer; | ||
private readonly voidContainer; | ||
private tabs; | ||
private selectedIndex; | ||
private actions; | ||
private rightActions; | ||
private leftActions; | ||
private _hidden; | ||
@@ -49,3 +52,4 @@ private readonly _onDrop; | ||
hide(): void; | ||
setActionElement(element: HTMLElement | undefined): void; | ||
setRightActionsElement(element: HTMLElement | undefined): void; | ||
setLeftActionsElement(element: HTMLElement | undefined): void; | ||
get element(): HTMLElement; | ||
@@ -52,0 +56,0 @@ isActive(tab: ITab): boolean; |
@@ -84,4 +84,6 @@ "use strict"; | ||
})); | ||
_this.actionContainer = document.createElement('div'); | ||
_this.actionContainer.className = 'action-container'; | ||
_this.rightActionsContainer = document.createElement('div'); | ||
_this.rightActionsContainer.className = 'right-actions-container'; | ||
_this.leftActionsContainer = document.createElement('div'); | ||
_this.leftActionsContainer.className = 'left-actions-container'; | ||
_this.tabContainer = document.createElement('div'); | ||
@@ -91,4 +93,5 @@ _this.tabContainer.className = 'tabs-container'; | ||
_this._element.appendChild(_this.tabContainer); | ||
_this._element.appendChild(_this.leftActionsContainer); | ||
_this._element.appendChild(_this.voidContainer.element); | ||
_this._element.appendChild(_this.actionContainer); | ||
_this._element.appendChild(_this.rightActionsContainer); | ||
_this.addDisposables(_this.voidContainer, _this.voidContainer.onDrop(function (event) { | ||
@@ -99,2 +102,15 @@ _this._onDrop.fire({ | ||
}); | ||
}), (0, events_1.addDisposableListener)(_this.voidContainer.element, 'mousedown', function (event) { | ||
var isFloatingGroupsEnabled = !_this.accessor.options.disableFloatingGroups; | ||
if (isFloatingGroupsEnabled && | ||
event.shiftKey && | ||
!_this.group.api.isFloating) { | ||
event.preventDefault(); | ||
var _a = _this.element.getBoundingClientRect(), top_1 = _a.top, left = _a.left; | ||
var _b = _this.accessor.element.getBoundingClientRect(), rootTop = _b.top, rootLeft = _b.left; | ||
_this.accessor.addFloatingGroup(_this.group, { | ||
x: left - rootLeft + 20, | ||
y: top_1 - rootTop + 20, | ||
}, { inDragMode: true }); | ||
} | ||
}), (0, events_1.addDisposableListener)(_this.tabContainer, 'mousedown', function (event) { | ||
@@ -144,15 +160,28 @@ if (event.defaultPrevented) { | ||
}; | ||
TabsContainer.prototype.setActionElement = function (element) { | ||
if (this.actions === element) { | ||
TabsContainer.prototype.setRightActionsElement = function (element) { | ||
if (this.rightActions === element) { | ||
return; | ||
} | ||
if (this.actions) { | ||
this.actions.remove(); | ||
this.actions = undefined; | ||
if (this.rightActions) { | ||
this.rightActions.remove(); | ||
this.rightActions = undefined; | ||
} | ||
if (element) { | ||
this.actionContainer.appendChild(element); | ||
this.actions = element; | ||
this.rightActionsContainer.appendChild(element); | ||
this.rightActions = element; | ||
} | ||
}; | ||
TabsContainer.prototype.setLeftActionsElement = function (element) { | ||
if (this.leftActions === element) { | ||
return; | ||
} | ||
if (this.leftActions) { | ||
this.leftActions.remove(); | ||
this.leftActions = undefined; | ||
} | ||
if (element) { | ||
this.leftActionsContainer.appendChild(element); | ||
this.leftActions = element; | ||
} | ||
}; | ||
Object.defineProperty(TabsContainer.prototype, "element", { | ||
@@ -216,2 +245,17 @@ get: function () { | ||
var _a; | ||
var isFloatingGroupsEnabled = !_this.accessor.options.disableFloatingGroups; | ||
var isFloatingWithOnePanel = _this.group.api.isFloating && _this.size === 1; | ||
if (isFloatingGroupsEnabled && | ||
!isFloatingWithOnePanel && | ||
event.shiftKey) { | ||
event.preventDefault(); | ||
var panel_1 = _this.accessor.getGroupPanel(tabToAdd.panelId); | ||
var _b = tabToAdd.element.getBoundingClientRect(), top_2 = _b.top, left = _b.left; | ||
var _c = _this.accessor.element.getBoundingClientRect(), rootTop = _c.top, rootLeft = _c.left; | ||
_this.accessor.addFloatingGroup(panel_1, { | ||
x: left - rootLeft, | ||
y: top_2 - rootTop, | ||
}, { inDragMode: true }); | ||
return; | ||
} | ||
var alreadyFocused = panel.id === ((_a = _this.group.model.activePanel) === null || _a === void 0 ? void 0 : _a.id) && | ||
@@ -218,0 +262,0 @@ _this.group.model.isContentFocused; |
import { GroupviewPanelState } from './types'; | ||
import { DockviewGroupPanel } from './dockviewGroupPanel'; | ||
import { IDockviewPanel } from './dockviewPanel'; | ||
import { IDockviewComponent } from './dockviewComponent'; | ||
import { DockviewComponent } from './dockviewComponent'; | ||
export interface IPanelDeserializer { | ||
@@ -10,5 +10,5 @@ fromJSON(panelData: GroupviewPanelState, group: DockviewGroupPanel): IDockviewPanel; | ||
private readonly layout; | ||
constructor(layout: IDockviewComponent); | ||
constructor(layout: DockviewComponent); | ||
fromJSON(panelData: GroupviewPanelState, group: DockviewGroupPanel): IDockviewPanel; | ||
} | ||
//# sourceMappingURL=deserializer.d.ts.map |
import { SerializedGridObject } from '../gridview/gridview'; | ||
import { Position } from '../dnd/droptarget'; | ||
import { IDockviewPanel } from './dockviewPanel'; | ||
import { DockviewPanel, IDockviewPanel } from './dockviewPanel'; | ||
import { Event } from '../events'; | ||
@@ -11,3 +11,4 @@ import { IWatermarkRenderer, GroupviewPanelState } from './types'; | ||
import { GroupOptions, GroupPanelViewState, GroupviewDropEvent } from './dockviewGroupPanelModel'; | ||
import { DockviewGroupPanel, IDockviewGroupPanel } from './dockviewGroupPanel'; | ||
import { DockviewGroupPanel } from './dockviewGroupPanel'; | ||
import { DockviewFloatingGroupPanel, IDockviewFloatingGroupPanel } from './dockviewFloatingGroupPanel'; | ||
export interface PanelReference { | ||
@@ -21,2 +22,11 @@ update: (event: { | ||
} | ||
export interface SerializedFloatingGroup { | ||
data: GroupPanelViewState; | ||
position: { | ||
height: number; | ||
width: number; | ||
left: number; | ||
top: number; | ||
}; | ||
} | ||
export interface SerializedDockview { | ||
@@ -29,8 +39,7 @@ grid: { | ||
}; | ||
panels: { | ||
[key: string]: GroupviewPanelState; | ||
}; | ||
panels: Record<string, GroupviewPanelState>; | ||
activeGroup?: string; | ||
floatingGroups?: SerializedFloatingGroup[]; | ||
} | ||
export type DockviewComponentUpdateOptions = Pick<DockviewComponentOptions, 'orientation' | 'components' | 'frameworkComponents' | 'tabComponents' | 'frameworkTabComponents' | 'showDndOverlay' | 'watermarkFrameworkComponent' | 'defaultTabComponent' | 'createGroupControlElement'>; | ||
export type DockviewComponentUpdateOptions = Pick<DockviewComponentOptions, 'orientation' | 'components' | 'frameworkComponents' | 'tabComponents' | 'frameworkTabComponents' | 'showDndOverlay' | 'watermarkFrameworkComponent' | 'defaultTabComponent' | 'createLeftHeaderActionsElement' | 'createRightHeaderActionsElement' | 'disableFloatingGroups'>; | ||
export interface DockviewDropEvent extends GroupviewDropEvent { | ||
@@ -44,2 +53,3 @@ api: DockviewApi; | ||
readonly panels: IDockviewPanel[]; | ||
readonly floatingGroups: IDockviewFloatingGroupPanel[]; | ||
readonly onDidDrop: Event<DockviewDropEvent>; | ||
@@ -56,3 +66,3 @@ readonly orientation: Orientation; | ||
createWatermarkComponent(): IWatermarkRenderer; | ||
addGroup(options?: AddGroupOptions): IDockviewGroupPanel; | ||
addGroup(options?: AddGroupOptions): DockviewGroupPanel; | ||
closeAllGroups(): void; | ||
@@ -69,2 +79,6 @@ moveToNext(options?: MovementOptions): void; | ||
readonly onDidActivePanelChange: Event<IDockviewPanel | undefined>; | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, coord?: { | ||
x: number; | ||
y: number; | ||
}): void; | ||
} | ||
@@ -87,2 +101,3 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> implements IDockviewComponent { | ||
readonly onDidActivePanelChange: Event<IDockviewPanel | undefined>; | ||
readonly floatingGroups: DockviewFloatingGroupPanel[]; | ||
get orientation(): Orientation; | ||
@@ -94,4 +109,14 @@ get totalPanels(): number; | ||
constructor(options: DockviewComponentOptions); | ||
addFloatingGroup(item: DockviewPanel | DockviewGroupPanel, coord?: { | ||
x?: number; | ||
y?: number; | ||
height?: number; | ||
width?: number; | ||
}, options?: { | ||
skipRemoveGroup?: boolean; | ||
inDragMode: boolean; | ||
}): void; | ||
private orthogonalize; | ||
updateOptions(options: DockviewComponentUpdateOptions): void; | ||
layout(width: number, height: number, forceResize?: boolean | undefined): void; | ||
focus(): void; | ||
@@ -111,3 +136,3 @@ getGroupPanel(id: string): IDockviewPanel | undefined; | ||
closeAllGroups(): void; | ||
addPanel(options: AddPanelOptions): IDockviewPanel; | ||
addPanel(options: AddPanelOptions): DockviewPanel; | ||
removePanel(panel: IDockviewPanel, options?: { | ||
@@ -120,3 +145,10 @@ removeEmptyGroup: boolean; | ||
addGroup(options?: AddGroupOptions): DockviewGroupPanel; | ||
removeGroup(group: DockviewGroupPanel, skipActive?: boolean): void; | ||
removeGroup(group: DockviewGroupPanel, options?: { | ||
skipActive?: boolean; | ||
skipDispose?: boolean; | ||
} | undefined): void; | ||
protected doRemoveGroup(group: DockviewGroupPanel, options?: { | ||
skipActive?: boolean; | ||
skipDispose?: boolean; | ||
} | undefined): DockviewGroupPanel; | ||
moveGroupOrPanel(destinationGroup: DockviewGroupPanel, sourceGroupId: string, sourceItemId: string | undefined, destinationTarget: Position, destinationIndex?: number): void; | ||
@@ -123,0 +155,0 @@ private moveGroup; |
@@ -84,2 +84,5 @@ "use strict"; | ||
var dataTransfer_1 = require("../dnd/dataTransfer"); | ||
var overlay_1 = require("../dnd/overlay"); | ||
var dom_1 = require("../dom"); | ||
var dockviewFloatingGroupPanel_1 = require("./dockviewFloatingGroupPanel"); | ||
var DockviewComponent = /** @class */ (function (_super) { | ||
@@ -107,3 +110,4 @@ __extends(DockviewComponent, _super); | ||
_this.onDidActivePanelChange = _this._onDidActivePanelChange.event; | ||
_this.element.classList.add('dv-dockview'); | ||
_this.floatingGroups = []; | ||
(0, dom_1.toggleClass)(_this.gridview.element, 'dv-dockview', true); | ||
_this.addDisposables(_this._onDidDrop, events_1.Event.any(_this.onDidAddGroup, _this.onDidRemoveGroup)(function () { | ||
@@ -138,2 +142,7 @@ _this.updateWatermark(); | ||
} | ||
if (position === 'center') { | ||
// center drop target is only allowed if there are no panels in the grid | ||
// floating panels are allowed | ||
return _this.gridview.length === 0; | ||
} | ||
return true; | ||
@@ -151,3 +160,3 @@ } | ||
}, | ||
acceptedTargetZones: ['top', 'bottom', 'left', 'right'], | ||
acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'], | ||
overlayModel: { | ||
@@ -210,2 +219,72 @@ activationSize: { type: 'pixels', value: 10 }, | ||
}); | ||
DockviewComponent.prototype.addFloatingGroup = function (item, coord, options) { | ||
var _this = this; | ||
var _a, _b; | ||
var group; | ||
if (item instanceof dockviewPanel_1.DockviewPanel) { | ||
group = this.createGroup(); | ||
this.removePanel(item, { | ||
removeEmptyGroup: true, | ||
skipDispose: true, | ||
}); | ||
group.model.openPanel(item); | ||
} | ||
else { | ||
group = item; | ||
var skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' && | ||
options.skipRemoveGroup; | ||
if (!skip) { | ||
this.doRemoveGroup(item, { skipDispose: true }); | ||
} | ||
} | ||
group.model.isFloating = true; | ||
var overlayLeft = typeof (coord === null || coord === void 0 ? void 0 : coord.x) === 'number' ? Math.max(coord.x, 0) : 100; | ||
var overlayTop = typeof (coord === null || coord === void 0 ? void 0 : coord.y) === 'number' ? Math.max(coord.y, 0) : 100; | ||
var overlay = new overlay_1.Overlay({ | ||
container: this.gridview.element, | ||
content: group.element, | ||
height: (_a = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _a !== void 0 ? _a : 300, | ||
width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300, | ||
left: overlayLeft, | ||
top: overlayTop, | ||
minimumInViewportWidth: 100, | ||
minimumInViewportHeight: 100, | ||
}); | ||
var el = group.element.querySelector('.void-container'); | ||
if (!el) { | ||
throw new Error('failed to find drag handle'); | ||
} | ||
overlay.setupDrag(el, { | ||
inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean' | ||
? options.inDragMode | ||
: false, | ||
}); | ||
var floatingGroupPanel = new dockviewFloatingGroupPanel_1.DockviewFloatingGroupPanel(group, overlay); | ||
var disposable = (0, dom_1.watchElementResize)(group.element, function (entry) { | ||
var _a = entry.contentRect, width = _a.width, height = _a.height; | ||
group.layout(width, height); // let the group know it's size is changing so it can fire events to the panel | ||
}); | ||
floatingGroupPanel.addDisposables(overlay.onDidChange(function () { | ||
// this is either a resize or a move | ||
// to inform the panels .layout(...) the group with it's current size | ||
// don't care about resize since the above watcher handles that | ||
group.layout(group.height, group.width); | ||
}), overlay.onDidChangeEnd(function () { | ||
_this._bufferOnDidLayoutChange.fire(); | ||
}), group.onDidChange(function (event) { | ||
overlay.setBounds({ | ||
height: event === null || event === void 0 ? void 0 : event.height, | ||
width: event === null || event === void 0 ? void 0 : event.width, | ||
}); | ||
}), { | ||
dispose: function () { | ||
disposable.dispose(); | ||
group.model.isFloating = false; | ||
(0, array_1.remove)(_this.floatingGroups, floatingGroupPanel); | ||
_this.updateWatermark(); | ||
}, | ||
}); | ||
this.floatingGroups.push(floatingGroupPanel); | ||
this.updateWatermark(); | ||
}; | ||
DockviewComponent.prototype.orthogonalize = function (position) { | ||
@@ -235,2 +314,3 @@ switch (position) { | ||
case 'left': | ||
case 'center': | ||
return this.createGroupAtLocation([0]); // insert into first position | ||
@@ -253,2 +333,22 @@ case 'bottom': | ||
}; | ||
DockviewComponent.prototype.layout = function (width, height, forceResize) { | ||
var e_1, _a; | ||
_super.prototype.layout.call(this, width, height, forceResize); | ||
if (this.floatingGroups) { | ||
try { | ||
for (var _b = __values(this.floatingGroups), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
var floating = _c.value; | ||
// ensure floting groups stay within visible boundaries | ||
floating.overlay.setBounds(); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
} | ||
}; | ||
DockviewComponent.prototype.focus = function () { | ||
@@ -318,3 +418,9 @@ var _a; | ||
}, {}); | ||
return { | ||
var floats = this.floatingGroups.map(function (floatingGroup) { | ||
return { | ||
data: floatingGroup.group.toJSON(), | ||
position: floatingGroup.overlay.toJSON(), | ||
}; | ||
}); | ||
var result = { | ||
grid: data, | ||
@@ -324,5 +430,11 @@ panels: panels, | ||
}; | ||
if (floats.length > 0) { | ||
result.floatingGroups = floats; | ||
} | ||
return result; | ||
}; | ||
DockviewComponent.prototype.fromJSON = function (data) { | ||
var e_2, _a, e_3, _b; | ||
var _this = this; | ||
var _c; | ||
this.clear(); | ||
@@ -333,39 +445,79 @@ var grid = data.grid, panels = data.panels, activeGroup = data.activeGroup; | ||
} | ||
this.gridview.deserialize(grid, { | ||
fromJSON: function (node) { | ||
var e_1, _a; | ||
var _b = node.data, id = _b.id, locked = _b.locked, hideHeader = _b.hideHeader, views = _b.views, activeView = _b.activeView; | ||
var group = _this.createGroup({ | ||
id: id, | ||
locked: !!locked, | ||
hideHeader: !!hideHeader, | ||
}); | ||
_this._onDidAddGroup.fire(group); | ||
try { | ||
for (var views_1 = __values(views), views_1_1 = views_1.next(); !views_1_1.done; views_1_1 = views_1.next()) { | ||
var child = views_1_1.value; | ||
var panel = _this._deserializer.fromJSON(panels[child], group); | ||
var isActive = typeof activeView === 'string' && | ||
activeView === panel.id; | ||
group.model.openPanel(panel, { | ||
skipSetPanelActive: !isActive, | ||
skipSetGroupActive: true, | ||
}); | ||
} | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (views_1_1 && !views_1_1.done && (_a = views_1.return)) _a.call(views_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
if (!group.activePanel && group.panels.length > 0) { | ||
group.model.openPanel(group.panels[group.panels.length - 1], { | ||
// take note of the existing dimensions | ||
var width = this.width; | ||
var height = this.height; | ||
var createGroupFromSerializedState = function (data) { | ||
var e_4, _a; | ||
var id = data.id, locked = data.locked, hideHeader = data.hideHeader, views = data.views, activeView = data.activeView; | ||
var group = _this.createGroup({ | ||
id: id, | ||
locked: !!locked, | ||
hideHeader: !!hideHeader, | ||
}); | ||
_this._onDidAddGroup.fire(group); | ||
try { | ||
for (var views_1 = __values(views), views_1_1 = views_1.next(); !views_1_1.done; views_1_1 = views_1.next()) { | ||
var child = views_1_1.value; | ||
var panel = _this._deserializer.fromJSON(panels[child], group); | ||
var isActive = typeof activeView === 'string' && activeView === panel.id; | ||
group.model.openPanel(panel, { | ||
skipSetPanelActive: !isActive, | ||
skipSetGroupActive: true, | ||
}); | ||
} | ||
return group; | ||
} | ||
catch (e_4_1) { e_4 = { error: e_4_1 }; } | ||
finally { | ||
try { | ||
if (views_1_1 && !views_1_1.done && (_a = views_1.return)) _a.call(views_1); | ||
} | ||
finally { if (e_4) throw e_4.error; } | ||
} | ||
if (!group.activePanel && group.panels.length > 0) { | ||
group.model.openPanel(group.panels[group.panels.length - 1], { | ||
skipSetGroupActive: true, | ||
}); | ||
} | ||
return group; | ||
}; | ||
this.gridview.deserialize(grid, { | ||
fromJSON: function (node) { | ||
return createGroupFromSerializedState(node.data); | ||
}, | ||
}); | ||
this.layout(width, height, true); | ||
var serializedFloatingGroups = (_c = data.floatingGroups) !== null && _c !== void 0 ? _c : []; | ||
try { | ||
for (var serializedFloatingGroups_1 = __values(serializedFloatingGroups), serializedFloatingGroups_1_1 = serializedFloatingGroups_1.next(); !serializedFloatingGroups_1_1.done; serializedFloatingGroups_1_1 = serializedFloatingGroups_1.next()) { | ||
var serializedFloatingGroup = serializedFloatingGroups_1_1.value; | ||
var data_1 = serializedFloatingGroup.data, position = serializedFloatingGroup.position; | ||
var group = createGroupFromSerializedState(data_1); | ||
this.addFloatingGroup(group, { | ||
x: position.left, | ||
y: position.top, | ||
height: position.height, | ||
width: position.width, | ||
}, { skipRemoveGroup: true, inDragMode: false }); | ||
} | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
finally { | ||
try { | ||
if (serializedFloatingGroups_1_1 && !serializedFloatingGroups_1_1.done && (_a = serializedFloatingGroups_1.return)) _a.call(serializedFloatingGroups_1); | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
} | ||
try { | ||
for (var _d = __values(this.floatingGroups), _e = _d.next(); !_e.done; _e = _d.next()) { | ||
var floatingGroup = _e.value; | ||
floatingGroup.overlay.setBounds(); | ||
} | ||
} | ||
catch (e_3_1) { e_3 = { error: e_3_1 }; } | ||
finally { | ||
try { | ||
if (_e && !_e.done && (_b = _d.return)) _b.call(_d); | ||
} | ||
finally { if (e_3) throw e_3.error; } | ||
} | ||
if (typeof activeGroup === 'string') { | ||
@@ -377,7 +529,6 @@ var panel = this.getPanel(activeGroup); | ||
} | ||
this.gridview.layout(this.width, this.height); | ||
this._onDidLayoutFromJSON.fire(); | ||
}; | ||
DockviewComponent.prototype.clear = function () { | ||
var e_2, _a; | ||
var e_5, _a; | ||
var groups = Array.from(this._groups.values()).map(function (_) { return _.value; }); | ||
@@ -390,6 +541,6 @@ var hasActiveGroup = !!this.activeGroup; | ||
// remove the group will automatically remove the panels | ||
this.removeGroup(group, true); | ||
this.removeGroup(group, { skipActive: true }); | ||
} | ||
} | ||
catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
catch (e_5_1) { e_5 = { error: e_5_1 }; } | ||
finally { | ||
@@ -399,3 +550,3 @@ try { | ||
} | ||
finally { if (e_2) throw e_2.error; } | ||
finally { if (e_5) throw e_5.error; } | ||
} | ||
@@ -411,3 +562,3 @@ if (hasActiveGroup) { | ||
DockviewComponent.prototype.closeAllGroups = function () { | ||
var e_3, _a; | ||
var e_6, _a; | ||
try { | ||
@@ -420,3 +571,3 @@ for (var _b = __values(this._groups.entries()), _c = _b.next(); !_c.done; _c = _b.next()) { | ||
} | ||
catch (e_3_1) { e_3 = { error: e_3_1 }; } | ||
catch (e_6_1) { e_6 = { error: e_6_1 }; } | ||
finally { | ||
@@ -426,3 +577,3 @@ try { | ||
} | ||
finally { if (e_3) throw e_3.error; } | ||
finally { if (e_6) throw e_6.error; } | ||
} | ||
@@ -436,2 +587,5 @@ }; | ||
var referenceGroup; | ||
if (options.position && options.floating) { | ||
throw new Error('you can only provide one of: position, floating as arguments to .addPanel(...)'); | ||
} | ||
if (options.position) { | ||
@@ -469,3 +623,16 @@ if ((0, options_1.isPanelOptionsWithPanel)(options.position)) { | ||
var target = (0, baseComponentGridview_1.toTarget)(((_b = options.position) === null || _b === void 0 ? void 0 : _b.direction) || 'within'); | ||
if (target === 'center') { | ||
if (options.floating) { | ||
var group = this.createGroup(); | ||
panel = this.createPanel(options, group); | ||
group.model.openPanel(panel); | ||
var o = typeof options.floating === 'object' && | ||
options.floating !== null | ||
? options.floating | ||
: {}; | ||
this.addFloatingGroup(group, o, { | ||
inDragMode: false, | ||
skipRemoveGroup: true, | ||
}); | ||
} | ||
else if (referenceGroup.api.isFloating || target === 'center') { | ||
panel = this.createPanel(options, referenceGroup); | ||
@@ -482,2 +649,15 @@ referenceGroup.model.openPanel(panel); | ||
} | ||
else if (options.floating) { | ||
var group = this.createGroup(); | ||
panel = this.createPanel(options, group); | ||
group.model.openPanel(panel); | ||
var o = typeof options.floating === 'object' && | ||
options.floating !== null | ||
? options.floating | ||
: {}; | ||
this.addFloatingGroup(group, o, { | ||
inDragMode: false, | ||
skipRemoveGroup: true, | ||
}); | ||
} | ||
else { | ||
@@ -500,3 +680,5 @@ var group = this.createGroupAtLocation(); | ||
group.model.removePanel(panel); | ||
panel.dispose(); | ||
if (!options.skipDispose) { | ||
panel.dispose(); | ||
} | ||
if (group.size === 0 && options.removeEmptyGroup) { | ||
@@ -516,3 +698,3 @@ this.removeGroup(group); | ||
var _a, _b; | ||
if (this.groups.length === 0) { | ||
if (this.groups.filter(function (x) { return !x.api.isFloating; }).length === 0) { | ||
if (!this.watermark) { | ||
@@ -526,3 +708,3 @@ this.watermark = this.createWatermarkComponent(); | ||
watermarkContainer.appendChild(this.watermark.element); | ||
this.element.appendChild(watermarkContainer); | ||
this.gridview.element.appendChild(watermarkContainer); | ||
} | ||
@@ -577,5 +759,5 @@ } | ||
}; | ||
DockviewComponent.prototype.removeGroup = function (group, skipActive) { | ||
var e_4, _a; | ||
if (skipActive === void 0) { skipActive = false; } | ||
DockviewComponent.prototype.removeGroup = function (group, options) { | ||
var e_7, _a; | ||
var _b; | ||
var panels = __spreadArray([], __read(group.panels), false); // reassign since group panels will mutate | ||
@@ -587,7 +769,7 @@ try { | ||
removeEmptyGroup: false, | ||
skipDispose: false, | ||
skipDispose: (_b = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _b !== void 0 ? _b : false, | ||
}); | ||
} | ||
} | ||
catch (e_4_1) { e_4 = { error: e_4_1 }; } | ||
catch (e_7_1) { e_7 = { error: e_7_1 }; } | ||
finally { | ||
@@ -597,6 +779,18 @@ try { | ||
} | ||
finally { if (e_4) throw e_4.error; } | ||
finally { if (e_7) throw e_7.error; } | ||
} | ||
_super.prototype.doRemoveGroup.call(this, group, { skipActive: skipActive }); | ||
this.doRemoveGroup(group, options); | ||
}; | ||
DockviewComponent.prototype.doRemoveGroup = function (group, options) { | ||
var floatingGroup = this.floatingGroups.find(function (_) { return _.group === group; }); | ||
if (floatingGroup) { | ||
if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) { | ||
floatingGroup.group.dispose(); | ||
this._groups.delete(group.id); | ||
} | ||
floatingGroup.dispose(); | ||
return floatingGroup.group; | ||
} | ||
return _super.prototype.doRemoveGroup.call(this, group, options); | ||
}; | ||
DockviewComponent.prototype.moveGroupOrPanel = function (destinationGroup, sourceGroupId, sourceItemId, destinationTarget, destinationIndex) { | ||
@@ -631,21 +825,22 @@ var _a; | ||
var _b = __read((0, array_1.tail)(targetLocation), 2), targetParentLocation = _b[0], to = _b[1]; | ||
var sourceLocation = (0, gridview_1.getGridLocation)(sourceGroup.element); | ||
var _c = __read((0, array_1.tail)(sourceLocation), 2), sourceParentLocation = _c[0], from = _c[1]; | ||
if ((0, array_1.sequenceEquals)(sourceParentLocation, targetParentLocation)) { | ||
// special case when 'swapping' two views within same grid location | ||
// if a group has one tab - we are essentially moving the 'group' | ||
// which is equivalent to swapping two views in this case | ||
this.gridview.moveView(sourceParentLocation, from, to); | ||
var isFloating = this.floatingGroups.find(function (x) { return x.group === sourceGroup; }); | ||
if (!isFloating) { | ||
var sourceLocation = (0, gridview_1.getGridLocation)(sourceGroup.element); | ||
var _c = __read((0, array_1.tail)(sourceLocation), 2), sourceParentLocation = _c[0], from = _c[1]; | ||
if ((0, array_1.sequenceEquals)(sourceParentLocation, targetParentLocation)) { | ||
// special case when 'swapping' two views within same grid location | ||
// if a group has one tab - we are essentially moving the 'group' | ||
// which is equivalent to swapping two views in this case | ||
this.gridview.moveView(sourceParentLocation, from, to); | ||
} | ||
} | ||
else { | ||
// source group will become empty so delete the group | ||
var targetGroup = this.doRemoveGroup(sourceGroup, { | ||
skipActive: true, | ||
skipDispose: true, | ||
}); | ||
// after deleting the group we need to re-evaulate the ref location | ||
var updatedReferenceLocation = (0, gridview_1.getGridLocation)(destinationGroup.element); | ||
var location_3 = (0, gridview_1.getRelativeLocation)(this.gridview.orientation, updatedReferenceLocation, destinationTarget); | ||
this.doAddGroup(targetGroup, location_3); | ||
} | ||
// source group will become empty so delete the group | ||
var targetGroup = this.doRemoveGroup(sourceGroup, { | ||
skipActive: true, | ||
skipDispose: true, | ||
}); | ||
// after deleting the group we need to re-evaulate the ref location | ||
var updatedReferenceLocation = (0, gridview_1.getGridLocation)(destinationGroup.element); | ||
var location_3 = (0, gridview_1.getRelativeLocation)(this.gridview.orientation, updatedReferenceLocation, destinationTarget); | ||
this.doAddGroup(targetGroup, location_3); | ||
} | ||
@@ -665,3 +860,3 @@ else { | ||
DockviewComponent.prototype.moveGroup = function (sourceGroup, referenceGroup, target) { | ||
var e_5, _a; | ||
var e_8, _a; | ||
if (sourceGroup) { | ||
@@ -684,3 +879,3 @@ if (!target || target === 'center') { | ||
} | ||
catch (e_5_1) { e_5 = { error: e_5_1 }; } | ||
catch (e_8_1) { e_8 = { error: e_8_1 }; } | ||
finally { | ||
@@ -690,7 +885,13 @@ try { | ||
} | ||
finally { if (e_5) throw e_5.error; } | ||
finally { if (e_8) throw e_8.error; } | ||
} | ||
} | ||
else { | ||
this.gridview.removeView((0, gridview_1.getGridLocation)(sourceGroup.element)); | ||
var floatingGroup = this.floatingGroups.find(function (x) { return x.group === sourceGroup; }); | ||
if (floatingGroup) { | ||
floatingGroup.dispose(); | ||
} | ||
else { | ||
this.gridview.removeView((0, gridview_1.getGridLocation)(sourceGroup.element)); | ||
} | ||
var referenceLocation = (0, gridview_1.getGridLocation)(referenceGroup.element); | ||
@@ -697,0 +898,0 @@ var dropLocation = (0, gridview_1.getRelativeLocation)(this.gridview.orientation, referenceLocation, target); |
import { IFrameworkPart } from '../panel/types'; | ||
import { DockviewComponent } from '../dockview/dockviewComponent'; | ||
import { GridviewPanelApi } from '../api/gridviewPanelApi'; | ||
import { GroupOptions, IDockviewGroupPanelModel, IHeader } from './dockviewGroupPanelModel'; | ||
import { DockviewGroupPanelModel, GroupOptions, IDockviewGroupPanelModel, IHeader } from './dockviewGroupPanelModel'; | ||
import { GridviewPanel, IGridviewPanel } from '../gridview/gridviewPanel'; | ||
import { IDockviewPanel } from '../dockview/dockviewPanel'; | ||
export interface IDockviewGroupPanel extends IGridviewPanel { | ||
import { DockviewGroupPanelApi, DockviewGroupPanelApiImpl } from '../api/dockviewGroupPanelApi'; | ||
export interface IDockviewGroupPanel extends IGridviewPanel<DockviewGroupPanelApi> { | ||
model: IDockviewGroupPanelModel; | ||
@@ -15,4 +15,3 @@ locked: boolean; | ||
export type IDockviewGroupPanelPublic = IDockviewGroupPanel; | ||
export type DockviewGroupPanelApi = GridviewPanelApi; | ||
export declare class DockviewGroupPanel extends GridviewPanel implements IDockviewGroupPanel { | ||
export declare class DockviewGroupPanel extends GridviewPanel<DockviewGroupPanelApiImpl> implements IDockviewGroupPanel { | ||
private readonly _model; | ||
@@ -22,3 +21,3 @@ get panels(): IDockviewPanel[]; | ||
get size(): number; | ||
get model(): IDockviewGroupPanelModel; | ||
get model(): DockviewGroupPanelModel; | ||
get locked(): boolean; | ||
@@ -25,0 +24,0 @@ set locked(value: boolean); |
@@ -21,2 +21,3 @@ "use strict"; | ||
var gridviewPanel_1 = require("../gridview/gridviewPanel"); | ||
var dockviewGroupPanelApi_1 = require("../api/dockviewGroupPanelApi"); | ||
var DockviewGroupPanel = /** @class */ (function (_super) { | ||
@@ -28,3 +29,4 @@ __extends(DockviewGroupPanel, _super); | ||
minimumWidth: 100, | ||
}) || this; | ||
}, new dockviewGroupPanelApi_1.DockviewGroupPanelApiImpl(id, accessor)) || this; | ||
_this.api.initialize(_this); // cannot use 'this' after after 'super' call | ||
_this._model = new dockviewGroupPanelModel_1.DockviewGroupPanelModel(_this.element, accessor, id, options, _this); | ||
@@ -93,3 +95,2 @@ return _this; | ||
DockviewGroupPanel.prototype.toJSON = function () { | ||
// TODO fix typing | ||
return this.model.toJSON(); | ||
@@ -96,0 +97,0 @@ }; |
@@ -106,3 +106,5 @@ import { PanelTransfer } from '../dnd/dataTransfer'; | ||
private _locked; | ||
private _control; | ||
private _isFloating; | ||
private _rightHeaderActions; | ||
private _leftHeaderActions; | ||
private mostRecentlyUsed; | ||
@@ -135,2 +137,4 @@ private readonly _onDidChange; | ||
get isContentFocused(): boolean; | ||
get isFloating(): boolean; | ||
set isFloating(value: boolean); | ||
constructor(container: HTMLElement, accessor: DockviewComponent, id: string, options: GroupOptions, groupPanel: DockviewGroupPanel); | ||
@@ -137,0 +141,0 @@ initialize(): void; |
@@ -75,2 +75,3 @@ "use strict"; | ||
_this._locked = false; | ||
_this._isFloating = false; | ||
_this.mostRecentlyUsed = []; | ||
@@ -92,3 +93,3 @@ _this._onDidChange = new events_1.Emitter(); | ||
_this.onDidActivePanelChange = _this._onDidActivePanelChange.event; | ||
_this.container.classList.add('groupview'); | ||
(0, dom_1.toggleClass)(_this.container, 'groupview', true); | ||
_this.tabsContainer = new tabsContainer_1.TabsContainer(_this.accessor, _this.groupPanel); | ||
@@ -103,2 +104,5 @@ _this.contentContainer = new content_1.ContentContainer(); | ||
var data = (0, dataTransfer_1.getPanelData)(); | ||
if (!data && event.shiftKey && !_this.isFloating) { | ||
return false; | ||
} | ||
if (data && data.viewId === _this.accessor.id) { | ||
@@ -212,2 +216,17 @@ if (data.groupId === _this.id) { | ||
}); | ||
Object.defineProperty(DockviewGroupPanelModel.prototype, "isFloating", { | ||
get: function () { | ||
return this._isFloating; | ||
}, | ||
set: function (value) { | ||
this._isFloating = value; | ||
this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']); | ||
(0, dom_1.toggleClass)(this.container, 'dv-groupview-floating', value); | ||
this.groupPanel.api._onDidFloatingStateChange.fire({ | ||
isFloating: this.isFloating, | ||
}); | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
DockviewGroupPanelModel.prototype.initialize = function () { | ||
@@ -228,11 +247,22 @@ var _this = this; | ||
this.updateContainer(); | ||
if (this.accessor.options.createGroupControlElement) { | ||
this._control = this.accessor.options.createGroupControlElement(this.groupPanel); | ||
this.addDisposables(this._control); | ||
this._control.init({ | ||
if (this.accessor.options.createRightHeaderActionsElement) { | ||
this._rightHeaderActions = | ||
this.accessor.options.createRightHeaderActionsElement(this.groupPanel); | ||
this.addDisposables(this._rightHeaderActions); | ||
this._rightHeaderActions.init({ | ||
containerApi: new component_api_1.DockviewApi(this.accessor), | ||
api: this.groupPanel.api, | ||
}); | ||
this.tabsContainer.setActionElement(this._control.element); | ||
this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element); | ||
} | ||
if (this.accessor.options.createLeftHeaderActionsElement) { | ||
this._leftHeaderActions = | ||
this.accessor.options.createLeftHeaderActionsElement(this.groupPanel); | ||
this.addDisposables(this._leftHeaderActions); | ||
this._leftHeaderActions.init({ | ||
containerApi: new component_api_1.DockviewApi(this.accessor), | ||
api: this.groupPanel.api, | ||
}); | ||
this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element); | ||
} | ||
}; | ||
@@ -381,3 +411,3 @@ DockviewGroupPanelModel.prototype.indexOf = function (panel) { | ||
DockviewGroupPanelModel.prototype.updateActions = function (element) { | ||
this.tabsContainer.setActionElement(element); | ||
this.tabsContainer.setRightActionsElement(element); | ||
}; | ||
@@ -562,8 +592,9 @@ DockviewGroupPanelModel.prototype.setActive = function (isGroupActive, skipFocus, force) { | ||
var e_2, _a; | ||
var _b, _c; | ||
var _b, _c, _d; | ||
_super.prototype.dispose.call(this); | ||
(_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b); | ||
(_b = this.watermark) === null || _b === void 0 ? void 0 : _b.element.remove(); | ||
(_d = (_c = this.watermark) === null || _c === void 0 ? void 0 : _c.dispose) === null || _d === void 0 ? void 0 : _d.call(_c); | ||
try { | ||
for (var _d = __values(this.panels), _e = _d.next(); !_e.done; _e = _d.next()) { | ||
var panel = _e.value; | ||
for (var _e = __values(this.panels), _f = _e.next(); !_f.done; _f = _e.next()) { | ||
var panel = _f.value; | ||
panel.dispose(); | ||
@@ -575,3 +606,3 @@ } | ||
try { | ||
if (_e && !_e.done && (_a = _d.return)) _a.call(_d); | ||
if (_f && !_f.done && (_a = _e.return)) _a.call(_e); | ||
} | ||
@@ -578,0 +609,0 @@ finally { if (e_2) throw e_2.error; } |
@@ -8,3 +8,3 @@ import { DockviewApi } from '../api/component.api'; | ||
import { IDockviewPanelModel } from './dockviewPanelModel'; | ||
import { IDockviewComponent } from './dockviewComponent'; | ||
import { DockviewComponent } from './dockviewComponent'; | ||
export interface IDockviewPanel extends IDisposable, IPanel { | ||
@@ -33,3 +33,3 @@ readonly view: IDockviewPanelModel; | ||
get group(): DockviewGroupPanel; | ||
constructor(id: string, accessor: IDockviewComponent, containerApi: DockviewApi, group: DockviewGroupPanel, view: IDockviewPanelModel); | ||
constructor(id: string, accessor: DockviewComponent, containerApi: DockviewApi, group: DockviewGroupPanel, view: IDockviewPanelModel); | ||
init(params: IGroupPanelInitParameters): void; | ||
@@ -36,0 +36,0 @@ focus(): void; |
@@ -51,3 +51,3 @@ "use strict"; | ||
_this._group = group; | ||
_this.api = new dockviewPanelApi_1.DockviewPanelApiImpl(_this, _this._group); | ||
_this.api = new dockviewPanelApi_1.DockviewPanelApiImpl(_this, _this._group, accessor); | ||
_this.addDisposables(_this.api.onActiveChange(function () { | ||
@@ -54,0 +54,0 @@ accessor.setActivePanel(_this); |
@@ -5,3 +5,3 @@ import { DockviewApi } from '../api/component.api'; | ||
import { IContentRenderer, ITabRenderer, WatermarkConstructor, IWatermarkRenderer, DockviewDropTargets } from './types'; | ||
import { DockviewGroupPanel, DockviewGroupPanelApi } from './dockviewGroupPanel'; | ||
import { DockviewGroupPanel } from './dockviewGroupPanel'; | ||
import { ISplitviewStyles, Orientation } from '../splitview/splitview'; | ||
@@ -13,3 +13,4 @@ import { PanelTransfer } from '../dnd/dataTransfer'; | ||
import { FrameworkFactory } from '../panel/componentFactory'; | ||
export interface IGroupControlRenderer extends IDisposable { | ||
import { DockviewGroupPanelApi } from '../api/dockviewGroupPanelApi'; | ||
export interface IHeaderActionsRenderer extends IDisposable { | ||
readonly element: HTMLElement; | ||
@@ -68,5 +69,7 @@ init(params: { | ||
showDndOverlay?: (event: DockviewDndOverlayEvent) => boolean; | ||
createGroupControlElement?: (group: DockviewGroupPanel) => IGroupControlRenderer; | ||
createRightHeaderActionsElement?: (group: DockviewGroupPanel) => IHeaderActionsRenderer; | ||
createLeftHeaderActionsElement?: (group: DockviewGroupPanel) => IHeaderActionsRenderer; | ||
singleTabMode?: 'fullwidth' | 'default'; | ||
parentElement?: HTMLElement; | ||
disableFloatingGroups?: boolean; | ||
} | ||
@@ -96,7 +99,20 @@ export interface PanelOptions { | ||
export declare function isPanelOptionsWithGroup(data: AddPanelPositionOptions): data is RelativeGroup; | ||
export interface AddPanelOptions extends Omit<PanelOptions, 'component' | 'tabComponent'> { | ||
type AddPanelFloatingGroupUnion = { | ||
floating: { | ||
height?: number; | ||
width?: number; | ||
x?: number; | ||
y?: number; | ||
} | true; | ||
position: never; | ||
}; | ||
type AddPanelPositionUnion = { | ||
floating: false | never; | ||
position: AddPanelPositionOptions; | ||
}; | ||
type AddPanelOptionsUnion = AddPanelFloatingGroupUnion | AddPanelPositionUnion; | ||
export type AddPanelOptions = Omit<PanelOptions, 'component' | 'tabComponent'> & { | ||
component: string; | ||
tabComponent?: string; | ||
position?: AddPanelPositionOptions; | ||
} | ||
} & Partial<AddPanelOptionsUnion>; | ||
type AddGroupOptionsWithPanel = { | ||
@@ -103,0 +119,0 @@ referencePanel: string | IDockviewPanel; |
@@ -1,2 +0,2 @@ | ||
import { Event } from './events'; | ||
import { Event as DockviewEvent } from './events'; | ||
import { IDisposable } from './lifecycle'; | ||
@@ -10,7 +10,9 @@ export declare function watchElementResize(element: HTMLElement, cb: (entry: ResizeObserverEntry) => void): IDisposable; | ||
export interface IFocusTracker extends IDisposable { | ||
readonly onDidFocus: Event<void>; | ||
readonly onDidBlur: Event<void>; | ||
readonly onDidFocus: DockviewEvent<void>; | ||
readonly onDidBlur: DockviewEvent<void>; | ||
refreshState?(): void; | ||
} | ||
export declare function trackFocus(element: HTMLElement | Window): IFocusTracker; | ||
export declare function quasiPreventDefault(event: Event): void; | ||
export declare function quasiDefaultPrevented(event: Event): boolean; | ||
//# sourceMappingURL=dom.d.ts.map |
@@ -29,3 +29,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.trackFocus = exports.getElementsByTagName = exports.isAncestor = exports.toggleClass = exports.addClasses = exports.removeClasses = exports.watchElementResize = void 0; | ||
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"); | ||
@@ -187,2 +187,14 @@ var lifecycle_1 = require("./lifecycle"); | ||
}(lifecycle_1.CompositeDisposable)); | ||
// quasi: apparently, but not really; seemingly | ||
var QUASI_PREVENT_DEFAULT_KEY = 'dv-quasiPreventDefault'; | ||
// mark an event directly for other listeners to check | ||
function quasiPreventDefault(event) { | ||
event[QUASI_PREVENT_DEFAULT_KEY] = true; | ||
} | ||
exports.quasiPreventDefault = quasiPreventDefault; | ||
// check if this event has been marked | ||
function quasiDefaultPrevented(event) { | ||
return event[QUASI_PREVENT_DEFAULT_KEY]; | ||
} | ||
exports.quasiDefaultPrevented = quasiDefaultPrevented; | ||
//# sourceMappingURL=dom.js.map |
@@ -98,3 +98,3 @@ "use strict"; | ||
}), | ||
size: _this.size, | ||
size: _this.orthogonalSize, | ||
}; | ||
@@ -293,3 +293,3 @@ _this.children = childDescriptors.map(function (c) { return c.node; }); | ||
this._orthogonalSize = size; | ||
this.splitview.layout(this.size, this.orthogonalSize); | ||
this.splitview.layout(orthogonalSize, size); | ||
}; | ||
@@ -296,0 +296,0 @@ BranchNode.prototype.addChild = function (node, size, index, skipLayout) { |
@@ -264,7 +264,6 @@ "use strict"; | ||
Gridview.prototype._deserialize = function (root, orientation, deserializer, orthogonalSize) { | ||
this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize, true); | ||
this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize); | ||
}; | ||
Gridview.prototype._deserializeNode = function (node, orientation, deserializer, orthogonalSize, isRoot) { | ||
Gridview.prototype._deserializeNode = function (node, orientation, deserializer, orthogonalSize) { | ||
var _this = this; | ||
if (isRoot === void 0) { isRoot = false; } | ||
var result; | ||
@@ -279,5 +278,5 @@ if (node.type === 'branch') { | ||
}); | ||
// HORIZONTAL => height=orthogonalsize width=size | ||
// VERTICAL => height=size width=orthogonalsize | ||
result = new branchNode_1.BranchNode(orientation, this.proportionalLayout, this.styles, isRoot ? orthogonalSize : node.size, isRoot ? node.size : orthogonalSize, children); | ||
result = new branchNode_1.BranchNode(orientation, this.proportionalLayout, this.styles, node.size, // <- orthogonal size - flips at each depth | ||
orthogonalSize, // <- size - flips at each depth | ||
children); | ||
} | ||
@@ -321,3 +320,6 @@ else { | ||
this._root = new branchNode_1.BranchNode((0, exports.orthogonal)(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size); | ||
if (oldRoot.children.length === 1) { | ||
if (oldRoot.children.length === 0) { | ||
// no data so no need to add anything back in | ||
} | ||
else if (oldRoot.children.length === 1) { | ||
// can remove one level of redundant branching if there is only a single child | ||
@@ -324,0 +326,0 @@ var childReference = oldRoot.children[0]; |
@@ -152,2 +152,5 @@ "use strict"; | ||
var queue = []; | ||
// take note of the existing dimensions | ||
var width = this.width; | ||
var height = this.height; | ||
this.gridview.deserialize(grid, { | ||
@@ -180,3 +183,3 @@ fromJSON: function (node) { | ||
}); | ||
this.layout(this.width, this.height, true); | ||
this.layout(width, height, true); | ||
queue.forEach(function (f) { return f(); }); | ||
@@ -183,0 +186,0 @@ if (typeof activePanel === 'string') { |
@@ -18,3 +18,3 @@ import { PanelInitParameters } from '../panel/types'; | ||
} | ||
export interface IGridviewPanel extends BasePanelViewExported<GridviewPanelApi> { | ||
export interface IGridviewPanel<T extends GridviewPanelApi = GridviewPanelApi> extends BasePanelViewExported<T> { | ||
readonly minimumWidth: number; | ||
@@ -27,3 +27,3 @@ readonly maximumWidth: number; | ||
} | ||
export declare abstract class GridviewPanel extends BasePanelView<GridviewPanelApiImpl> implements IGridPanelComponentView, IGridviewPanel { | ||
export declare abstract class GridviewPanel<T extends GridviewPanelApiImpl = GridviewPanelApiImpl> extends BasePanelView<T> implements IGridPanelComponentView, IGridviewPanel { | ||
private _evaluatedMinimumWidth; | ||
@@ -53,3 +53,3 @@ private _evaluatedMaximumWidth; | ||
maximumHeight?: number; | ||
}); | ||
}, api?: T); | ||
setVisible(isVisible: boolean): void; | ||
@@ -56,0 +56,0 @@ setActive(isActive: boolean): void; |
@@ -35,4 +35,4 @@ "use strict"; | ||
__extends(GridviewPanel, _super); | ||
function GridviewPanel(id, component, options) { | ||
var _this = _super.call(this, id, component, new gridviewPanelApi_1.GridviewPanelApiImpl(id)) || this; | ||
function GridviewPanel(id, component, options, api) { | ||
var _this = _super.call(this, id, component, api !== null && api !== void 0 ? api : new gridviewPanelApi_1.GridviewPanelApiImpl(id)) || this; | ||
_this._evaluatedMinimumWidth = 0; | ||
@@ -39,0 +39,0 @@ _this._evaluatedMaximumWidth = Number.MAX_SAFE_INTEGER; |
export * from './dnd/dataTransfer'; | ||
export { watchElementResize } from './dom'; | ||
/** | ||
@@ -41,3 +40,4 @@ * Events, Emitters and Disposables are very common concepts that most codebases will contain. | ||
export { ExpansionEvent, PaneviewPanelApi } from './api/paneviewPanelApi'; | ||
export { DockviewGroupPanelApi, DockviewGroupPanelFloatingChangeEvent, } from './api/dockviewGroupPanelApi'; | ||
export { CommonApi, SplitviewApi, PaneviewApi, GridviewApi, DockviewApi, } from './api/component.api'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -17,6 +17,4 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.DockviewApi = exports.GridviewApi = exports.PaneviewApi = exports.SplitviewApi = exports.directionToPosition = exports.positionToDirection = exports.DockviewCompositeDisposable = exports.DockviewMutableDisposable = exports.DockviewEvent = exports.DockviewEmitter = exports.watchElementResize = void 0; | ||
exports.DockviewApi = exports.GridviewApi = exports.PaneviewApi = exports.SplitviewApi = exports.directionToPosition = exports.positionToDirection = exports.DockviewCompositeDisposable = exports.DockviewMutableDisposable = exports.DockviewEvent = exports.DockviewEmitter = void 0; | ||
__exportStar(require("./dnd/dataTransfer"), exports); | ||
var dom_1 = require("./dom"); | ||
Object.defineProperty(exports, "watchElementResize", { enumerable: true, get: function () { return dom_1.watchElementResize; } }); | ||
/** | ||
@@ -23,0 +21,0 @@ * Events, Emitters and Disposables are very common concepts that most codebases will contain. |
@@ -282,2 +282,5 @@ "use strict"; | ||
var queue = []; | ||
// take note of the existing dimensions | ||
var width = this.width; | ||
var height = this.height; | ||
this.paneview = new paneview_1.Paneview(this.element, { | ||
@@ -338,3 +341,3 @@ orientation: splitview_1.Orientation.VERTICAL, | ||
}); | ||
this.layout(this.width, this.height); | ||
this.layout(width, height); | ||
queue.forEach(function (f) { return f(); }); | ||
@@ -341,0 +344,0 @@ this._onDidLayoutfromJSON.fire(); |
@@ -286,2 +286,5 @@ "use strict"; | ||
var queue = []; | ||
// take note of the existing dimensions | ||
var width = this.width; | ||
var height = this.height; | ||
this.splitview = new splitview_1.Splitview(this.element, { | ||
@@ -323,3 +326,3 @@ orientation: orientation, | ||
}); | ||
this.layout(this.width, this.height); | ||
this.layout(width, height); | ||
queue.forEach(function (f) { return f(); }); | ||
@@ -326,0 +329,0 @@ if (typeof activeView === 'string') { |
@@ -134,3 +134,4 @@ import { DockviewDropEvent, IDockviewComponent, SerializedDockview } from '../dockview/dockviewComponent'; | ||
addPanel(options: AddPanelOptions): IDockviewPanel; | ||
addGroup(options?: AddGroupOptions): IDockviewGroupPanel; | ||
removePanel(panel: IDockviewPanel): void; | ||
addGroup(options?: AddGroupOptions): DockviewGroupPanel; | ||
moveToNext(options?: MovementOptions): void; | ||
@@ -141,2 +142,6 @@ moveToPrevious(options?: MovementOptions): void; | ||
getGroup(id: string): DockviewGroupPanel | undefined; | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, coord?: { | ||
x: number; | ||
y: number; | ||
}): void; | ||
fromJSON(data: SerializedDockview): void; | ||
@@ -143,0 +148,0 @@ toJSON(): SerializedDockview; |
@@ -296,2 +296,5 @@ import { Emitter } from '../events'; | ||
} | ||
removePanel(panel) { | ||
this.component.removePanel(panel); | ||
} | ||
addGroup(options) { | ||
@@ -315,2 +318,5 @@ return this.component.addGroup(options); | ||
} | ||
addFloatingGroup(item, coord) { | ||
return this.component.addFloatingGroup(item, coord); | ||
} | ||
fromJSON(data) { | ||
@@ -317,0 +323,0 @@ this.component.fromJSON(data); |
@@ -5,2 +5,4 @@ import { Emitter, Event } from '../events'; | ||
import { IDockviewPanel } from '../dockview/dockviewPanel'; | ||
import { DockviewComponent } from '../dockview/dockviewComponent'; | ||
import { Position } from '../dnd/droptarget'; | ||
export interface TitleEvent { | ||
@@ -17,5 +19,11 @@ readonly title: string; | ||
setTitle(title: string): void; | ||
moveTo(options: { | ||
group: DockviewGroupPanel; | ||
position?: Position; | ||
index?: number; | ||
}): void; | ||
} | ||
export declare class DockviewPanelApiImpl extends GridviewPanelApiImpl implements DockviewPanelApi { | ||
private panel; | ||
private readonly accessor; | ||
private _group; | ||
@@ -33,3 +41,8 @@ readonly _onDidTitleChange: Emitter<TitleEvent>; | ||
get group(): DockviewGroupPanel; | ||
constructor(panel: IDockviewPanel, group: DockviewGroupPanel); | ||
constructor(panel: IDockviewPanel, group: DockviewGroupPanel, accessor: DockviewComponent); | ||
moveTo(options: { | ||
group: DockviewGroupPanel; | ||
position?: Position; | ||
index?: number; | ||
}): void; | ||
setTitle(title: string): void; | ||
@@ -36,0 +49,0 @@ close(): void; |
@@ -28,5 +28,6 @@ import { Emitter } from '../events'; | ||
} | ||
constructor(panel, group) { | ||
constructor(panel, group, accessor) { | ||
super(panel.id); | ||
this.panel = panel; | ||
this.accessor = accessor; | ||
this._onDidTitleChange = new Emitter(); | ||
@@ -43,2 +44,6 @@ this.onDidTitleChange = this._onDidTitleChange.event; | ||
} | ||
moveTo(options) { | ||
var _a; | ||
this.accessor.moveGroupOrPanel(options.group, this._group.id, this.panel.id, (_a = options.position) !== null && _a !== void 0 ? _a : 'center', options.index); | ||
} | ||
setTitle(title) { | ||
@@ -45,0 +50,0 @@ this.panel.setTitle(title); |
@@ -13,2 +13,3 @@ export declare function tail<T>(arr: T[]): [T[], T]; | ||
export declare function firstIndex<T>(array: T[] | ReadonlyArray<T>, fn: (item: T) => boolean): number; | ||
export declare function remove<T>(array: T[], value: T): boolean; | ||
//# sourceMappingURL=array.d.ts.map |
@@ -50,2 +50,10 @@ export function tail(arr) { | ||
} | ||
export function remove(array, value) { | ||
const index = array.findIndex((t) => t === value); | ||
if (index > -1) { | ||
array.splice(index, 1); | ||
return true; | ||
} | ||
return false; | ||
} | ||
//# sourceMappingURL=array.js.map |
@@ -10,4 +10,5 @@ import { CompositeDisposable, IDisposable } from '../lifecycle'; | ||
abstract getData(dataTransfer?: DataTransfer | null): IDisposable; | ||
protected isCancelled(_event: DragEvent): boolean; | ||
private configure; | ||
} | ||
//# sourceMappingURL=abstractDragHandler.d.ts.map |
@@ -15,4 +15,11 @@ import { getElementsByTagName } from '../dom'; | ||
} | ||
isCancelled(_event) { | ||
return false; | ||
} | ||
configure() { | ||
this.addDisposables(this._onDragStart, addDisposableListener(this.el, 'dragstart', (event) => { | ||
if (this.isCancelled(event)) { | ||
event.preventDefault(); | ||
return; | ||
} | ||
const iframes = [ | ||
@@ -19,0 +26,0 @@ ...getElementsByTagName('iframe'), |
@@ -18,4 +18,6 @@ import { Event } from '../events'; | ||
private _state; | ||
private _acceptedTargetZonesSet; | ||
private readonly _onDrop; | ||
readonly onDrop: Event<DroptargetEvent>; | ||
private static USED_EVENT_ID; | ||
get state(): Position | undefined; | ||
@@ -36,3 +38,12 @@ constructor(element: HTMLElement, options: { | ||
}); | ||
setTargetZones(acceptedTargetZones: Position[]): void; | ||
dispose(): void; | ||
/** | ||
* Add a property to the event object for other potential listeners to check | ||
*/ | ||
private markAsUsed; | ||
/** | ||
* Check is the event has already been used by another instance od DropTarget | ||
*/ | ||
private isAlreadyUsed; | ||
private toggleClasses; | ||
@@ -39,0 +50,0 @@ private setState; |
@@ -52,6 +52,10 @@ import { toggleClass } from '../dom'; | ||
// use a set to take advantage of #<set>.has | ||
const acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones); | ||
this._acceptedTargetZonesSet = new Set(this.options.acceptedTargetZones); | ||
this.addDisposables(this._onDrop, new DragAndDropObserver(this.element, { | ||
onDragEnter: () => undefined, | ||
onDragOver: (e) => { | ||
if (this._acceptedTargetZonesSet.size === 0) { | ||
this.removeDropTarget(); | ||
return; | ||
} | ||
const width = this.element.clientWidth; | ||
@@ -65,4 +69,9 @@ const height = this.element.clientHeight; | ||
const y = e.clientY - rect.top; | ||
const quadrant = this.calculateQuadrant(acceptedTargetZonesSet, x, y, width, height); | ||
if (quadrant === null) { | ||
const quadrant = this.calculateQuadrant(this._acceptedTargetZonesSet, x, y, width, height); | ||
/** | ||
* If the event has already been used by another DropTarget instance | ||
* then don't show a second drop target, only one target should be | ||
* active at any one time | ||
*/ | ||
if (this.isAlreadyUsed(e) || quadrant === null) { | ||
// no drop target should be displayed | ||
@@ -74,2 +83,3 @@ this.removeDropTarget(); | ||
if (!this.options.canDisplayOverlay) { | ||
this.removeDropTarget(); | ||
return; | ||
@@ -79,4 +89,6 @@ } | ||
else if (!this.options.canDisplayOverlay(e, quadrant)) { | ||
this.removeDropTarget(); | ||
return; | ||
} | ||
this.markAsUsed(e); | ||
if (!this.targetElement) { | ||
@@ -92,8 +104,2 @@ this.targetElement = document.createElement('div'); | ||
} | ||
if (this.options.acceptedTargetZones.length === 0) { | ||
return; | ||
} | ||
if (!this.targetElement || !this.overlayElement) { | ||
return; | ||
} | ||
this.toggleClasses(quadrant, width, height); | ||
@@ -121,2 +127,5 @@ this.setState(quadrant); | ||
} | ||
setTargetZones(acceptedTargetZones) { | ||
this._acceptedTargetZonesSet = new Set(acceptedTargetZones); | ||
} | ||
dispose() { | ||
@@ -126,2 +135,15 @@ this.removeDropTarget(); | ||
} | ||
/** | ||
* Add a property to the event object for other potential listeners to check | ||
*/ | ||
markAsUsed(event) { | ||
event[Droptarget.USED_EVENT_ID] = true; | ||
} | ||
/** | ||
* Check is the event has already been used by another instance od DropTarget | ||
*/ | ||
isAlreadyUsed(event) { | ||
const value = event[Droptarget.USED_EVENT_ID]; | ||
return typeof value === 'boolean' && value; | ||
} | ||
toggleClasses(quadrant, width, height) { | ||
@@ -221,2 +243,3 @@ var _a, _b, _c, _d; | ||
} | ||
Droptarget.USED_EVENT_ID = '__dockview_droptarget_event_is_used__'; | ||
export function calculateQuadrantAsPercentage(overlayType, x, y, width, height, threshold) { | ||
@@ -223,0 +246,0 @@ const xp = (100 * x) / width; |
@@ -9,4 +9,5 @@ import { DockviewGroupPanel } from '../dockview/dockviewGroupPanel'; | ||
constructor(element: HTMLElement, accessorId: string, group: DockviewGroupPanel); | ||
isCancelled(_event: DragEvent): boolean; | ||
getData(dataTransfer: DataTransfer | null): IDisposable; | ||
} | ||
//# sourceMappingURL=groupDragHandler.d.ts.map |
@@ -0,1 +1,3 @@ | ||
import { quasiPreventDefault } from '../dom'; | ||
import { addDisposableListener } from '../events'; | ||
import { DragHandler } from './abstractDragHandler'; | ||
@@ -10,3 +12,19 @@ import { LocalSelectionTransfer, PanelTransfer } from './dataTransfer'; | ||
this.panelTransfer = LocalSelectionTransfer.getInstance(); | ||
this.addDisposables(addDisposableListener(element, 'mousedown', (e) => { | ||
if (e.shiftKey) { | ||
/** | ||
* You cannot call e.preventDefault() because that will prevent drag events from firing | ||
* but we also need to stop any group overlay drag events from occuring | ||
* Use a custom event marker that can be checked by the overlay drag events | ||
*/ | ||
quasiPreventDefault(e); | ||
} | ||
}, true)); | ||
} | ||
isCancelled(_event) { | ||
if (this.group.api.isFloating && !_event.shiftKey) { | ||
return true; | ||
} | ||
return false; | ||
} | ||
getData(dataTransfer) { | ||
@@ -13,0 +31,0 @@ this.panelTransfer.setData([new PanelTransfer(this.accessorId, this.group.id, null)], PanelTransfer.prototype); |
import { Event } from '../../../events'; | ||
import { CompositeDisposable, IDisposable } from '../../../lifecycle'; | ||
import { IDockviewComponent } from '../../dockviewComponent'; | ||
import { DockviewComponent } from '../../dockviewComponent'; | ||
import { ITabRenderer } from '../../types'; | ||
@@ -27,3 +27,3 @@ import { DockviewGroupPanel } from '../../dockviewGroupPanel'; | ||
get element(): HTMLElement; | ||
constructor(panelId: string, accessor: IDockviewComponent, group: DockviewGroupPanel); | ||
constructor(panelId: string, accessor: DockviewComponent, group: DockviewGroupPanel); | ||
setActive(isActive: boolean): void; | ||
@@ -30,0 +30,0 @@ setContent(part: ITabRenderer): void; |
@@ -44,9 +44,2 @@ import { addDisposableListener, Emitter } from '../../../events'; | ||
} | ||
/** | ||
* TODO: alternative to stopPropagation | ||
* | ||
* I need to stop the event propagation here since otherwise it'll be intercepted by event handlers | ||
* on the tabs-container. I cannot use event.preventDefault() since I need the on DragStart event to occur | ||
*/ | ||
event.stopPropagation(); | ||
this._onChanged.fire(event); | ||
@@ -53,0 +46,0 @@ })); |
@@ -23,3 +23,4 @@ import { IDisposable, CompositeDisposable } from '../../../lifecycle'; | ||
openPanel: (panel: IDockviewPanel, index?: number) => void; | ||
setActionElement(element: HTMLElement | undefined): void; | ||
setRightActionsElement(element: HTMLElement | undefined): void; | ||
setLeftActionsElement(element: HTMLElement | undefined): void; | ||
hidden: boolean; | ||
@@ -34,7 +35,9 @@ show(): void; | ||
private readonly tabContainer; | ||
private readonly actionContainer; | ||
private readonly rightActionsContainer; | ||
private readonly leftActionsContainer; | ||
private readonly voidContainer; | ||
private tabs; | ||
private selectedIndex; | ||
private actions; | ||
private rightActions; | ||
private leftActions; | ||
private _hidden; | ||
@@ -49,3 +52,4 @@ private readonly _onDrop; | ||
hide(): void; | ||
setActionElement(element: HTMLElement | undefined): void; | ||
setRightActionsElement(element: HTMLElement | undefined): void; | ||
setLeftActionsElement(element: HTMLElement | undefined): void; | ||
get element(): HTMLElement; | ||
@@ -52,0 +56,0 @@ isActive(tab: ITab): boolean; |
@@ -28,15 +28,28 @@ import { CompositeDisposable, } from '../../../lifecycle'; | ||
} | ||
setActionElement(element) { | ||
if (this.actions === element) { | ||
setRightActionsElement(element) { | ||
if (this.rightActions === element) { | ||
return; | ||
} | ||
if (this.actions) { | ||
this.actions.remove(); | ||
this.actions = undefined; | ||
if (this.rightActions) { | ||
this.rightActions.remove(); | ||
this.rightActions = undefined; | ||
} | ||
if (element) { | ||
this.actionContainer.appendChild(element); | ||
this.actions = element; | ||
this.rightActionsContainer.appendChild(element); | ||
this.rightActions = element; | ||
} | ||
} | ||
setLeftActionsElement(element) { | ||
if (this.leftActions === element) { | ||
return; | ||
} | ||
if (this.leftActions) { | ||
this.leftActions.remove(); | ||
this.leftActions = undefined; | ||
} | ||
if (element) { | ||
this.leftActionsContainer.appendChild(element); | ||
this.leftActions = element; | ||
} | ||
} | ||
get element() { | ||
@@ -74,4 +87,6 @@ return this._element; | ||
})); | ||
this.actionContainer = document.createElement('div'); | ||
this.actionContainer.className = 'action-container'; | ||
this.rightActionsContainer = document.createElement('div'); | ||
this.rightActionsContainer.className = 'right-actions-container'; | ||
this.leftActionsContainer = document.createElement('div'); | ||
this.leftActionsContainer.className = 'left-actions-container'; | ||
this.tabContainer = document.createElement('div'); | ||
@@ -81,4 +96,5 @@ this.tabContainer.className = 'tabs-container'; | ||
this._element.appendChild(this.tabContainer); | ||
this._element.appendChild(this.leftActionsContainer); | ||
this._element.appendChild(this.voidContainer.element); | ||
this._element.appendChild(this.actionContainer); | ||
this._element.appendChild(this.rightActionsContainer); | ||
this.addDisposables(this.voidContainer, this.voidContainer.onDrop((event) => { | ||
@@ -89,2 +105,15 @@ this._onDrop.fire({ | ||
}); | ||
}), addDisposableListener(this.voidContainer.element, 'mousedown', (event) => { | ||
const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups; | ||
if (isFloatingGroupsEnabled && | ||
event.shiftKey && | ||
!this.group.api.isFloating) { | ||
event.preventDefault(); | ||
const { top, left } = this.element.getBoundingClientRect(); | ||
const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect(); | ||
this.accessor.addFloatingGroup(this.group, { | ||
x: left - rootLeft + 20, | ||
y: top - rootTop + 20, | ||
}, { inDragMode: true }); | ||
} | ||
}), addDisposableListener(this.tabContainer, 'mousedown', (event) => { | ||
@@ -143,2 +172,17 @@ if (event.defaultPrevented) { | ||
var _a; | ||
const isFloatingGroupsEnabled = !this.accessor.options.disableFloatingGroups; | ||
const isFloatingWithOnePanel = this.group.api.isFloating && this.size === 1; | ||
if (isFloatingGroupsEnabled && | ||
!isFloatingWithOnePanel && | ||
event.shiftKey) { | ||
event.preventDefault(); | ||
const panel = this.accessor.getGroupPanel(tabToAdd.panelId); | ||
const { top, left } = tabToAdd.element.getBoundingClientRect(); | ||
const { top: rootTop, left: rootLeft } = this.accessor.element.getBoundingClientRect(); | ||
this.accessor.addFloatingGroup(panel, { | ||
x: left - rootLeft, | ||
y: top - rootTop, | ||
}, { inDragMode: true }); | ||
return; | ||
} | ||
const alreadyFocused = panel.id === ((_a = this.group.model.activePanel) === null || _a === void 0 ? void 0 : _a.id) && | ||
@@ -145,0 +189,0 @@ this.group.model.isContentFocused; |
import { GroupviewPanelState } from './types'; | ||
import { DockviewGroupPanel } from './dockviewGroupPanel'; | ||
import { IDockviewPanel } from './dockviewPanel'; | ||
import { IDockviewComponent } from './dockviewComponent'; | ||
import { DockviewComponent } from './dockviewComponent'; | ||
export interface IPanelDeserializer { | ||
@@ -10,5 +10,5 @@ fromJSON(panelData: GroupviewPanelState, group: DockviewGroupPanel): IDockviewPanel; | ||
private readonly layout; | ||
constructor(layout: IDockviewComponent); | ||
constructor(layout: DockviewComponent); | ||
fromJSON(panelData: GroupviewPanelState, group: DockviewGroupPanel): IDockviewPanel; | ||
} | ||
//# sourceMappingURL=deserializer.d.ts.map |
import { SerializedGridObject } from '../gridview/gridview'; | ||
import { Position } from '../dnd/droptarget'; | ||
import { IDockviewPanel } from './dockviewPanel'; | ||
import { DockviewPanel, IDockviewPanel } from './dockviewPanel'; | ||
import { Event } from '../events'; | ||
@@ -11,3 +11,4 @@ import { IWatermarkRenderer, GroupviewPanelState } from './types'; | ||
import { GroupOptions, GroupPanelViewState, GroupviewDropEvent } from './dockviewGroupPanelModel'; | ||
import { DockviewGroupPanel, IDockviewGroupPanel } from './dockviewGroupPanel'; | ||
import { DockviewGroupPanel } from './dockviewGroupPanel'; | ||
import { DockviewFloatingGroupPanel, IDockviewFloatingGroupPanel } from './dockviewFloatingGroupPanel'; | ||
export interface PanelReference { | ||
@@ -21,2 +22,11 @@ update: (event: { | ||
} | ||
export interface SerializedFloatingGroup { | ||
data: GroupPanelViewState; | ||
position: { | ||
height: number; | ||
width: number; | ||
left: number; | ||
top: number; | ||
}; | ||
} | ||
export interface SerializedDockview { | ||
@@ -29,8 +39,7 @@ grid: { | ||
}; | ||
panels: { | ||
[key: string]: GroupviewPanelState; | ||
}; | ||
panels: Record<string, GroupviewPanelState>; | ||
activeGroup?: string; | ||
floatingGroups?: SerializedFloatingGroup[]; | ||
} | ||
export type DockviewComponentUpdateOptions = Pick<DockviewComponentOptions, 'orientation' | 'components' | 'frameworkComponents' | 'tabComponents' | 'frameworkTabComponents' | 'showDndOverlay' | 'watermarkFrameworkComponent' | 'defaultTabComponent' | 'createGroupControlElement'>; | ||
export type DockviewComponentUpdateOptions = Pick<DockviewComponentOptions, 'orientation' | 'components' | 'frameworkComponents' | 'tabComponents' | 'frameworkTabComponents' | 'showDndOverlay' | 'watermarkFrameworkComponent' | 'defaultTabComponent' | 'createLeftHeaderActionsElement' | 'createRightHeaderActionsElement' | 'disableFloatingGroups'>; | ||
export interface DockviewDropEvent extends GroupviewDropEvent { | ||
@@ -44,2 +53,3 @@ api: DockviewApi; | ||
readonly panels: IDockviewPanel[]; | ||
readonly floatingGroups: IDockviewFloatingGroupPanel[]; | ||
readonly onDidDrop: Event<DockviewDropEvent>; | ||
@@ -56,3 +66,3 @@ readonly orientation: Orientation; | ||
createWatermarkComponent(): IWatermarkRenderer; | ||
addGroup(options?: AddGroupOptions): IDockviewGroupPanel; | ||
addGroup(options?: AddGroupOptions): DockviewGroupPanel; | ||
closeAllGroups(): void; | ||
@@ -69,2 +79,6 @@ moveToNext(options?: MovementOptions): void; | ||
readonly onDidActivePanelChange: Event<IDockviewPanel | undefined>; | ||
addFloatingGroup(item: IDockviewPanel | DockviewGroupPanel, coord?: { | ||
x: number; | ||
y: number; | ||
}): void; | ||
} | ||
@@ -87,2 +101,3 @@ export declare class DockviewComponent extends BaseGrid<DockviewGroupPanel> implements IDockviewComponent { | ||
readonly onDidActivePanelChange: Event<IDockviewPanel | undefined>; | ||
readonly floatingGroups: DockviewFloatingGroupPanel[]; | ||
get orientation(): Orientation; | ||
@@ -94,4 +109,14 @@ get totalPanels(): number; | ||
constructor(options: DockviewComponentOptions); | ||
addFloatingGroup(item: DockviewPanel | DockviewGroupPanel, coord?: { | ||
x?: number; | ||
y?: number; | ||
height?: number; | ||
width?: number; | ||
}, options?: { | ||
skipRemoveGroup?: boolean; | ||
inDragMode: boolean; | ||
}): void; | ||
private orthogonalize; | ||
updateOptions(options: DockviewComponentUpdateOptions): void; | ||
layout(width: number, height: number, forceResize?: boolean | undefined): void; | ||
focus(): void; | ||
@@ -111,3 +136,3 @@ getGroupPanel(id: string): IDockviewPanel | undefined; | ||
closeAllGroups(): void; | ||
addPanel(options: AddPanelOptions): IDockviewPanel; | ||
addPanel(options: AddPanelOptions): DockviewPanel; | ||
removePanel(panel: IDockviewPanel, options?: { | ||
@@ -120,3 +145,10 @@ removeEmptyGroup: boolean; | ||
addGroup(options?: AddGroupOptions): DockviewGroupPanel; | ||
removeGroup(group: DockviewGroupPanel, skipActive?: boolean): void; | ||
removeGroup(group: DockviewGroupPanel, options?: { | ||
skipActive?: boolean; | ||
skipDispose?: boolean; | ||
} | undefined): void; | ||
protected doRemoveGroup(group: DockviewGroupPanel, options?: { | ||
skipActive?: boolean; | ||
skipDispose?: boolean; | ||
} | undefined): DockviewGroupPanel; | ||
moveGroupOrPanel(destinationGroup: DockviewGroupPanel, sourceGroupId: string, sourceItemId: string | undefined, destinationTarget: Position, destinationIndex?: number): void; | ||
@@ -123,0 +155,0 @@ private moveGroup; |
import { getRelativeLocation, getGridLocation, } from '../gridview/gridview'; | ||
import { directionToPosition, Droptarget } from '../dnd/droptarget'; | ||
import { tail, sequenceEquals } from '../array'; | ||
import { tail, sequenceEquals, remove } from '../array'; | ||
import { DockviewPanel } from './dockviewPanel'; | ||
@@ -19,2 +19,5 @@ import { CompositeDisposable } from '../lifecycle'; | ||
import { getPanelData } from '../dnd/dataTransfer'; | ||
import { Overlay } from '../dnd/overlay'; | ||
import { toggleClass, watchElementResize } from '../dom'; | ||
import { DockviewFloatingGroupPanel, } from './dockviewFloatingGroupPanel'; | ||
export class DockviewComponent extends BaseGrid { | ||
@@ -60,3 +63,4 @@ get orientation() { | ||
this.onDidActivePanelChange = this._onDidActivePanelChange.event; | ||
this.element.classList.add('dv-dockview'); | ||
this.floatingGroups = []; | ||
toggleClass(this.gridview.element, 'dv-dockview', true); | ||
this.addDisposables(this._onDidDrop, Event.any(this.onDidAddGroup, this.onDidRemoveGroup)(() => { | ||
@@ -91,2 +95,7 @@ this.updateWatermark(); | ||
} | ||
if (position === 'center') { | ||
// center drop target is only allowed if there are no panels in the grid | ||
// floating panels are allowed | ||
return this.gridview.length === 0; | ||
} | ||
return true; | ||
@@ -104,3 +113,3 @@ } | ||
}, | ||
acceptedTargetZones: ['top', 'bottom', 'left', 'right'], | ||
acceptedTargetZones: ['top', 'bottom', 'left', 'right', 'center'], | ||
overlayModel: { | ||
@@ -123,2 +132,71 @@ activationSize: { type: 'pixels', value: 10 }, | ||
} | ||
addFloatingGroup(item, coord, options) { | ||
var _a, _b; | ||
let group; | ||
if (item instanceof DockviewPanel) { | ||
group = this.createGroup(); | ||
this.removePanel(item, { | ||
removeEmptyGroup: true, | ||
skipDispose: true, | ||
}); | ||
group.model.openPanel(item); | ||
} | ||
else { | ||
group = item; | ||
const skip = typeof (options === null || options === void 0 ? void 0 : options.skipRemoveGroup) === 'boolean' && | ||
options.skipRemoveGroup; | ||
if (!skip) { | ||
this.doRemoveGroup(item, { skipDispose: true }); | ||
} | ||
} | ||
group.model.isFloating = true; | ||
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 overlay = new Overlay({ | ||
container: this.gridview.element, | ||
content: group.element, | ||
height: (_a = coord === null || coord === void 0 ? void 0 : coord.height) !== null && _a !== void 0 ? _a : 300, | ||
width: (_b = coord === null || coord === void 0 ? void 0 : coord.width) !== null && _b !== void 0 ? _b : 300, | ||
left: overlayLeft, | ||
top: overlayTop, | ||
minimumInViewportWidth: 100, | ||
minimumInViewportHeight: 100, | ||
}); | ||
const el = group.element.querySelector('.void-container'); | ||
if (!el) { | ||
throw new Error('failed to find drag handle'); | ||
} | ||
overlay.setupDrag(el, { | ||
inDragMode: typeof (options === null || options === void 0 ? void 0 : options.inDragMode) === 'boolean' | ||
? options.inDragMode | ||
: false, | ||
}); | ||
const floatingGroupPanel = new DockviewFloatingGroupPanel(group, overlay); | ||
const disposable = watchElementResize(group.element, (entry) => { | ||
const { width, height } = entry.contentRect; | ||
group.layout(width, height); // let the group know it's size is changing so it can fire events to the panel | ||
}); | ||
floatingGroupPanel.addDisposables(overlay.onDidChange(() => { | ||
// this is either a resize or a move | ||
// to inform the panels .layout(...) the group with it's current size | ||
// don't care about resize since the above watcher handles that | ||
group.layout(group.height, group.width); | ||
}), overlay.onDidChangeEnd(() => { | ||
this._bufferOnDidLayoutChange.fire(); | ||
}), group.onDidChange((event) => { | ||
overlay.setBounds({ | ||
height: event === null || event === void 0 ? void 0 : event.height, | ||
width: event === null || event === void 0 ? void 0 : event.width, | ||
}); | ||
}), { | ||
dispose: () => { | ||
disposable.dispose(); | ||
group.model.isFloating = false; | ||
remove(this.floatingGroups, floatingGroupPanel); | ||
this.updateWatermark(); | ||
}, | ||
}); | ||
this.floatingGroups.push(floatingGroupPanel); | ||
this.updateWatermark(); | ||
} | ||
orthogonalize(position) { | ||
@@ -148,2 +226,3 @@ switch (position) { | ||
case 'left': | ||
case 'center': | ||
return this.createGroupAtLocation([0]); // insert into first position | ||
@@ -166,2 +245,11 @@ case 'bottom': | ||
} | ||
layout(width, height, forceResize) { | ||
super.layout(width, height, forceResize); | ||
if (this.floatingGroups) { | ||
for (const floating of this.floatingGroups) { | ||
// ensure floting groups stay within visible boundaries | ||
floating.overlay.setBounds(); | ||
} | ||
} | ||
} | ||
focus() { | ||
@@ -229,3 +317,9 @@ var _a; | ||
}, {}); | ||
return { | ||
const floats = this.floatingGroups.map((floatingGroup) => { | ||
return { | ||
data: floatingGroup.group.toJSON(), | ||
position: floatingGroup.overlay.toJSON(), | ||
}; | ||
}); | ||
const result = { | ||
grid: data, | ||
@@ -235,4 +329,9 @@ panels, | ||
}; | ||
if (floats.length > 0) { | ||
result.floatingGroups = floats; | ||
} | ||
return result; | ||
} | ||
fromJSON(data) { | ||
var _a; | ||
this.clear(); | ||
@@ -243,28 +342,48 @@ const { grid, panels, activeGroup } = data; | ||
} | ||
// take note of the existing dimensions | ||
const width = this.width; | ||
const height = this.height; | ||
const createGroupFromSerializedState = (data) => { | ||
const { id, locked, hideHeader, views, activeView } = data; | ||
const group = this.createGroup({ | ||
id, | ||
locked: !!locked, | ||
hideHeader: !!hideHeader, | ||
}); | ||
this._onDidAddGroup.fire(group); | ||
for (const child of views) { | ||
const panel = this._deserializer.fromJSON(panels[child], group); | ||
const isActive = typeof activeView === 'string' && activeView === panel.id; | ||
group.model.openPanel(panel, { | ||
skipSetPanelActive: !isActive, | ||
skipSetGroupActive: true, | ||
}); | ||
} | ||
if (!group.activePanel && group.panels.length > 0) { | ||
group.model.openPanel(group.panels[group.panels.length - 1], { | ||
skipSetGroupActive: true, | ||
}); | ||
} | ||
return group; | ||
}; | ||
this.gridview.deserialize(grid, { | ||
fromJSON: (node) => { | ||
const { id, locked, hideHeader, views, activeView } = node.data; | ||
const group = this.createGroup({ | ||
id, | ||
locked: !!locked, | ||
hideHeader: !!hideHeader, | ||
}); | ||
this._onDidAddGroup.fire(group); | ||
for (const child of views) { | ||
const panel = this._deserializer.fromJSON(panels[child], group); | ||
const isActive = typeof activeView === 'string' && | ||
activeView === panel.id; | ||
group.model.openPanel(panel, { | ||
skipSetPanelActive: !isActive, | ||
skipSetGroupActive: true, | ||
}); | ||
} | ||
if (!group.activePanel && group.panels.length > 0) { | ||
group.model.openPanel(group.panels[group.panels.length - 1], { | ||
skipSetGroupActive: true, | ||
}); | ||
} | ||
return group; | ||
return createGroupFromSerializedState(node.data); | ||
}, | ||
}); | ||
this.layout(width, height, true); | ||
const serializedFloatingGroups = (_a = data.floatingGroups) !== null && _a !== void 0 ? _a : []; | ||
for (const serializedFloatingGroup of serializedFloatingGroups) { | ||
const { data, position } = serializedFloatingGroup; | ||
const group = createGroupFromSerializedState(data); | ||
this.addFloatingGroup(group, { | ||
x: position.left, | ||
y: position.top, | ||
height: position.height, | ||
width: position.width, | ||
}, { skipRemoveGroup: true, inDragMode: false }); | ||
} | ||
for (const floatingGroup of this.floatingGroups) { | ||
floatingGroup.overlay.setBounds(); | ||
} | ||
if (typeof activeGroup === 'string') { | ||
@@ -276,3 +395,2 @@ const panel = this.getPanel(activeGroup); | ||
} | ||
this.gridview.layout(this.width, this.height); | ||
this._onDidLayoutFromJSON.fire(); | ||
@@ -286,3 +404,3 @@ } | ||
// remove the group will automatically remove the panels | ||
this.removeGroup(group, true); | ||
this.removeGroup(group, { skipActive: true }); | ||
} | ||
@@ -309,2 +427,5 @@ if (hasActiveGroup) { | ||
let referenceGroup; | ||
if (options.position && options.floating) { | ||
throw new Error('you can only provide one of: position, floating as arguments to .addPanel(...)'); | ||
} | ||
if (options.position) { | ||
@@ -342,3 +463,16 @@ if (isPanelOptionsWithPanel(options.position)) { | ||
const target = toTarget(((_b = options.position) === null || _b === void 0 ? void 0 : _b.direction) || 'within'); | ||
if (target === 'center') { | ||
if (options.floating) { | ||
const group = this.createGroup(); | ||
panel = this.createPanel(options, group); | ||
group.model.openPanel(panel); | ||
const o = typeof options.floating === 'object' && | ||
options.floating !== null | ||
? options.floating | ||
: {}; | ||
this.addFloatingGroup(group, o, { | ||
inDragMode: false, | ||
skipRemoveGroup: true, | ||
}); | ||
} | ||
else if (referenceGroup.api.isFloating || target === 'center') { | ||
panel = this.createPanel(options, referenceGroup); | ||
@@ -355,2 +489,15 @@ referenceGroup.model.openPanel(panel); | ||
} | ||
else if (options.floating) { | ||
const group = this.createGroup(); | ||
panel = this.createPanel(options, group); | ||
group.model.openPanel(panel); | ||
const o = typeof options.floating === 'object' && | ||
options.floating !== null | ||
? options.floating | ||
: {}; | ||
this.addFloatingGroup(group, o, { | ||
inDragMode: false, | ||
skipRemoveGroup: true, | ||
}); | ||
} | ||
else { | ||
@@ -372,3 +519,5 @@ const group = this.createGroupAtLocation(); | ||
group.model.removePanel(panel); | ||
panel.dispose(); | ||
if (!options.skipDispose) { | ||
panel.dispose(); | ||
} | ||
if (group.size === 0 && options.removeEmptyGroup) { | ||
@@ -388,3 +537,3 @@ this.removeGroup(group); | ||
var _a, _b; | ||
if (this.groups.length === 0) { | ||
if (this.groups.filter((x) => !x.api.isFloating).length === 0) { | ||
if (!this.watermark) { | ||
@@ -398,3 +547,3 @@ this.watermark = this.createWatermarkComponent(); | ||
watermarkContainer.appendChild(this.watermark.element); | ||
this.element.appendChild(watermarkContainer); | ||
this.gridview.element.appendChild(watermarkContainer); | ||
} | ||
@@ -449,3 +598,4 @@ } | ||
} | ||
removeGroup(group, skipActive = false) { | ||
removeGroup(group, options) { | ||
var _a; | ||
const panels = [...group.panels]; // reassign since group panels will mutate | ||
@@ -455,7 +605,19 @@ for (const panel of panels) { | ||
removeEmptyGroup: false, | ||
skipDispose: false, | ||
skipDispose: (_a = options === null || options === void 0 ? void 0 : options.skipDispose) !== null && _a !== void 0 ? _a : false, | ||
}); | ||
} | ||
super.doRemoveGroup(group, { skipActive }); | ||
this.doRemoveGroup(group, options); | ||
} | ||
doRemoveGroup(group, options) { | ||
const floatingGroup = this.floatingGroups.find((_) => _.group === group); | ||
if (floatingGroup) { | ||
if (!(options === null || options === void 0 ? void 0 : options.skipDispose)) { | ||
floatingGroup.group.dispose(); | ||
this._groups.delete(group.id); | ||
} | ||
floatingGroup.dispose(); | ||
return floatingGroup.group; | ||
} | ||
return super.doRemoveGroup(group, options); | ||
} | ||
moveGroupOrPanel(destinationGroup, sourceGroupId, sourceItemId, destinationTarget, destinationIndex) { | ||
@@ -490,21 +652,22 @@ var _a; | ||
const [targetParentLocation, to] = tail(targetLocation); | ||
const sourceLocation = getGridLocation(sourceGroup.element); | ||
const [sourceParentLocation, from] = tail(sourceLocation); | ||
if (sequenceEquals(sourceParentLocation, targetParentLocation)) { | ||
// special case when 'swapping' two views within same grid location | ||
// if a group has one tab - we are essentially moving the 'group' | ||
// which is equivalent to swapping two views in this case | ||
this.gridview.moveView(sourceParentLocation, from, to); | ||
const isFloating = this.floatingGroups.find((x) => x.group === sourceGroup); | ||
if (!isFloating) { | ||
const sourceLocation = getGridLocation(sourceGroup.element); | ||
const [sourceParentLocation, from] = tail(sourceLocation); | ||
if (sequenceEquals(sourceParentLocation, targetParentLocation)) { | ||
// special case when 'swapping' two views within same grid location | ||
// if a group has one tab - we are essentially moving the 'group' | ||
// which is equivalent to swapping two views in this case | ||
this.gridview.moveView(sourceParentLocation, from, to); | ||
} | ||
} | ||
else { | ||
// source group will become empty so delete the group | ||
const targetGroup = this.doRemoveGroup(sourceGroup, { | ||
skipActive: true, | ||
skipDispose: true, | ||
}); | ||
// after deleting the group we need to re-evaulate the ref location | ||
const updatedReferenceLocation = getGridLocation(destinationGroup.element); | ||
const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget); | ||
this.doAddGroup(targetGroup, location); | ||
} | ||
// source group will become empty so delete the group | ||
const targetGroup = this.doRemoveGroup(sourceGroup, { | ||
skipActive: true, | ||
skipDispose: true, | ||
}); | ||
// after deleting the group we need to re-evaulate the ref location | ||
const updatedReferenceLocation = getGridLocation(destinationGroup.element); | ||
const location = getRelativeLocation(this.gridview.orientation, updatedReferenceLocation, destinationTarget); | ||
this.doAddGroup(targetGroup, location); | ||
} | ||
@@ -538,3 +701,9 @@ else { | ||
else { | ||
this.gridview.removeView(getGridLocation(sourceGroup.element)); | ||
const floatingGroup = this.floatingGroups.find((x) => x.group === sourceGroup); | ||
if (floatingGroup) { | ||
floatingGroup.dispose(); | ||
} | ||
else { | ||
this.gridview.removeView(getGridLocation(sourceGroup.element)); | ||
} | ||
const referenceLocation = getGridLocation(referenceGroup.element); | ||
@@ -541,0 +710,0 @@ const dropLocation = getRelativeLocation(this.gridview.orientation, referenceLocation, target); |
import { IFrameworkPart } from '../panel/types'; | ||
import { DockviewComponent } from '../dockview/dockviewComponent'; | ||
import { GridviewPanelApi } from '../api/gridviewPanelApi'; | ||
import { GroupOptions, IDockviewGroupPanelModel, IHeader } from './dockviewGroupPanelModel'; | ||
import { DockviewGroupPanelModel, GroupOptions, IDockviewGroupPanelModel, IHeader } from './dockviewGroupPanelModel'; | ||
import { GridviewPanel, IGridviewPanel } from '../gridview/gridviewPanel'; | ||
import { IDockviewPanel } from '../dockview/dockviewPanel'; | ||
export interface IDockviewGroupPanel extends IGridviewPanel { | ||
import { DockviewGroupPanelApi, DockviewGroupPanelApiImpl } from '../api/dockviewGroupPanelApi'; | ||
export interface IDockviewGroupPanel extends IGridviewPanel<DockviewGroupPanelApi> { | ||
model: IDockviewGroupPanelModel; | ||
@@ -15,4 +15,3 @@ locked: boolean; | ||
export type IDockviewGroupPanelPublic = IDockviewGroupPanel; | ||
export type DockviewGroupPanelApi = GridviewPanelApi; | ||
export declare class DockviewGroupPanel extends GridviewPanel implements IDockviewGroupPanel { | ||
export declare class DockviewGroupPanel extends GridviewPanel<DockviewGroupPanelApiImpl> implements IDockviewGroupPanel { | ||
private readonly _model; | ||
@@ -22,3 +21,3 @@ get panels(): IDockviewPanel[]; | ||
get size(): number; | ||
get model(): IDockviewGroupPanelModel; | ||
get model(): DockviewGroupPanelModel; | ||
get locked(): boolean; | ||
@@ -25,0 +24,0 @@ set locked(value: boolean); |
import { DockviewGroupPanelModel, } from './dockviewGroupPanelModel'; | ||
import { GridviewPanel } from '../gridview/gridviewPanel'; | ||
import { DockviewGroupPanelApiImpl, } from '../api/dockviewGroupPanelApi'; | ||
export class DockviewGroupPanel extends GridviewPanel { | ||
@@ -29,3 +30,4 @@ get panels() { | ||
minimumWidth: 100, | ||
}); | ||
}, new DockviewGroupPanelApiImpl(id, accessor)); | ||
this.api.initialize(this); // cannot use 'this' after after 'super' call | ||
this._model = new DockviewGroupPanelModel(this.element, accessor, id, options, this); | ||
@@ -48,3 +50,2 @@ } | ||
toJSON() { | ||
// TODO fix typing | ||
return this.model.toJSON(); | ||
@@ -51,0 +52,0 @@ } |
@@ -106,3 +106,5 @@ import { PanelTransfer } from '../dnd/dataTransfer'; | ||
private _locked; | ||
private _control; | ||
private _isFloating; | ||
private _rightHeaderActions; | ||
private _leftHeaderActions; | ||
private mostRecentlyUsed; | ||
@@ -135,2 +137,4 @@ private readonly _onDidChange; | ||
get isContentFocused(): boolean; | ||
get isFloating(): boolean; | ||
set isFloating(value: boolean); | ||
constructor(container: HTMLElement, accessor: DockviewComponent, id: string, options: GroupOptions, groupPanel: DockviewGroupPanel); | ||
@@ -137,0 +141,0 @@ initialize(): void; |
@@ -48,2 +48,13 @@ import { DockviewApi } from '../api/component.api'; | ||
} | ||
get isFloating() { | ||
return this._isFloating; | ||
} | ||
set isFloating(value) { | ||
this._isFloating = value; | ||
this.dropTarget.setTargetZones(value ? ['center'] : ['top', 'bottom', 'left', 'right', 'center']); | ||
toggleClass(this.container, 'dv-groupview-floating', value); | ||
this.groupPanel.api._onDidFloatingStateChange.fire({ | ||
isFloating: this.isFloating, | ||
}); | ||
} | ||
constructor(container, accessor, id, options, groupPanel) { | ||
@@ -58,2 +69,3 @@ super(); | ||
this._locked = false; | ||
this._isFloating = false; | ||
this.mostRecentlyUsed = []; | ||
@@ -75,3 +87,3 @@ this._onDidChange = new Emitter(); | ||
this.onDidActivePanelChange = this._onDidActivePanelChange.event; | ||
this.container.classList.add('groupview'); | ||
toggleClass(this.container, 'groupview', true); | ||
this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel); | ||
@@ -86,2 +98,5 @@ this.contentContainer = new ContentContainer(); | ||
const data = getPanelData(); | ||
if (!data && event.shiftKey && !this.isFloating) { | ||
return false; | ||
} | ||
if (data && data.viewId === this.accessor.id) { | ||
@@ -131,11 +146,22 @@ if (data.groupId === this.id) { | ||
this.updateContainer(); | ||
if (this.accessor.options.createGroupControlElement) { | ||
this._control = this.accessor.options.createGroupControlElement(this.groupPanel); | ||
this.addDisposables(this._control); | ||
this._control.init({ | ||
if (this.accessor.options.createRightHeaderActionsElement) { | ||
this._rightHeaderActions = | ||
this.accessor.options.createRightHeaderActionsElement(this.groupPanel); | ||
this.addDisposables(this._rightHeaderActions); | ||
this._rightHeaderActions.init({ | ||
containerApi: new DockviewApi(this.accessor), | ||
api: this.groupPanel.api, | ||
}); | ||
this.tabsContainer.setActionElement(this._control.element); | ||
this.tabsContainer.setRightActionsElement(this._rightHeaderActions.element); | ||
} | ||
if (this.accessor.options.createLeftHeaderActionsElement) { | ||
this._leftHeaderActions = | ||
this.accessor.options.createLeftHeaderActionsElement(this.groupPanel); | ||
this.addDisposables(this._leftHeaderActions); | ||
this._leftHeaderActions.init({ | ||
containerApi: new DockviewApi(this.accessor), | ||
api: this.groupPanel.api, | ||
}); | ||
this.tabsContainer.setLeftActionsElement(this._leftHeaderActions.element); | ||
} | ||
} | ||
@@ -272,3 +298,3 @@ indexOf(panel) { | ||
updateActions(element) { | ||
this.tabsContainer.setActionElement(element); | ||
this.tabsContainer.setRightActionsElement(element); | ||
} | ||
@@ -445,5 +471,6 @@ setActive(isGroupActive, skipFocus = false, force = false) { | ||
dispose() { | ||
var _a, _b; | ||
var _a, _b, _c; | ||
super.dispose(); | ||
(_b = (_a = this.watermark) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a); | ||
(_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove(); | ||
(_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b); | ||
for (const panel of this.panels) { | ||
@@ -450,0 +477,0 @@ panel.dispose(); |
@@ -8,3 +8,3 @@ import { DockviewApi } from '../api/component.api'; | ||
import { IDockviewPanelModel } from './dockviewPanelModel'; | ||
import { IDockviewComponent } from './dockviewComponent'; | ||
import { DockviewComponent } from './dockviewComponent'; | ||
export interface IDockviewPanel extends IDisposable, IPanel { | ||
@@ -33,3 +33,3 @@ readonly view: IDockviewPanelModel; | ||
get group(): DockviewGroupPanel; | ||
constructor(id: string, accessor: IDockviewComponent, containerApi: DockviewApi, group: DockviewGroupPanel, view: IDockviewPanelModel); | ||
constructor(id: string, accessor: DockviewComponent, containerApi: DockviewApi, group: DockviewGroupPanel, view: IDockviewPanelModel); | ||
init(params: IGroupPanelInitParameters): void; | ||
@@ -36,0 +36,0 @@ focus(): void; |
@@ -19,3 +19,3 @@ import { DockviewPanelApiImpl, } from '../api/dockviewPanelApi'; | ||
this._group = group; | ||
this.api = new DockviewPanelApiImpl(this, this._group); | ||
this.api = new DockviewPanelApiImpl(this, this._group, accessor); | ||
this.addDisposables(this.api.onActiveChange(() => { | ||
@@ -22,0 +22,0 @@ accessor.setActivePanel(this); |
@@ -5,3 +5,3 @@ import { DockviewApi } from '../api/component.api'; | ||
import { IContentRenderer, ITabRenderer, WatermarkConstructor, IWatermarkRenderer, DockviewDropTargets } from './types'; | ||
import { DockviewGroupPanel, DockviewGroupPanelApi } from './dockviewGroupPanel'; | ||
import { DockviewGroupPanel } from './dockviewGroupPanel'; | ||
import { ISplitviewStyles, Orientation } from '../splitview/splitview'; | ||
@@ -13,3 +13,4 @@ import { PanelTransfer } from '../dnd/dataTransfer'; | ||
import { FrameworkFactory } from '../panel/componentFactory'; | ||
export interface IGroupControlRenderer extends IDisposable { | ||
import { DockviewGroupPanelApi } from '../api/dockviewGroupPanelApi'; | ||
export interface IHeaderActionsRenderer extends IDisposable { | ||
readonly element: HTMLElement; | ||
@@ -68,5 +69,7 @@ init(params: { | ||
showDndOverlay?: (event: DockviewDndOverlayEvent) => boolean; | ||
createGroupControlElement?: (group: DockviewGroupPanel) => IGroupControlRenderer; | ||
createRightHeaderActionsElement?: (group: DockviewGroupPanel) => IHeaderActionsRenderer; | ||
createLeftHeaderActionsElement?: (group: DockviewGroupPanel) => IHeaderActionsRenderer; | ||
singleTabMode?: 'fullwidth' | 'default'; | ||
parentElement?: HTMLElement; | ||
disableFloatingGroups?: boolean; | ||
} | ||
@@ -96,7 +99,20 @@ export interface PanelOptions { | ||
export declare function isPanelOptionsWithGroup(data: AddPanelPositionOptions): data is RelativeGroup; | ||
export interface AddPanelOptions extends Omit<PanelOptions, 'component' | 'tabComponent'> { | ||
type AddPanelFloatingGroupUnion = { | ||
floating: { | ||
height?: number; | ||
width?: number; | ||
x?: number; | ||
y?: number; | ||
} | true; | ||
position: never; | ||
}; | ||
type AddPanelPositionUnion = { | ||
floating: false | never; | ||
position: AddPanelPositionOptions; | ||
}; | ||
type AddPanelOptionsUnion = AddPanelFloatingGroupUnion | AddPanelPositionUnion; | ||
export type AddPanelOptions = Omit<PanelOptions, 'component' | 'tabComponent'> & { | ||
component: string; | ||
tabComponent?: string; | ||
position?: AddPanelPositionOptions; | ||
} | ||
} & Partial<AddPanelOptionsUnion>; | ||
type AddGroupOptionsWithPanel = { | ||
@@ -103,0 +119,0 @@ referencePanel: string | IDockviewPanel; |
@@ -1,2 +0,2 @@ | ||
import { Event } from './events'; | ||
import { Event as DockviewEvent } from './events'; | ||
import { IDisposable } from './lifecycle'; | ||
@@ -10,7 +10,9 @@ export declare function watchElementResize(element: HTMLElement, cb: (entry: ResizeObserverEntry) => void): IDisposable; | ||
export interface IFocusTracker extends IDisposable { | ||
readonly onDidFocus: Event<void>; | ||
readonly onDidBlur: Event<void>; | ||
readonly onDidFocus: DockviewEvent<void>; | ||
readonly onDidBlur: DockviewEvent<void>; | ||
refreshState?(): void; | ||
} | ||
export declare function trackFocus(element: HTMLElement | Window): IFocusTracker; | ||
export declare function quasiPreventDefault(event: Event): void; | ||
export declare function quasiDefaultPrevented(event: Event): boolean; | ||
//# sourceMappingURL=dom.d.ts.map |
@@ -117,2 +117,12 @@ import { Emitter, addDisposableListener, addDisposableWindowListener, } from './events'; | ||
} | ||
// quasi: apparently, but not really; seemingly | ||
const QUASI_PREVENT_DEFAULT_KEY = 'dv-quasiPreventDefault'; | ||
// mark an event directly for other listeners to check | ||
export function quasiPreventDefault(event) { | ||
event[QUASI_PREVENT_DEFAULT_KEY] = true; | ||
} | ||
// check if this event has been marked | ||
export function quasiDefaultPrevented(event) { | ||
return event[QUASI_PREVENT_DEFAULT_KEY]; | ||
} | ||
//# sourceMappingURL=dom.js.map |
@@ -108,3 +108,3 @@ /*--------------------------------------------------------------------------------------------- | ||
}), | ||
size: this.size, | ||
size: this.orthogonalSize, | ||
}; | ||
@@ -172,3 +172,3 @@ this.children = childDescriptors.map((c) => c.node); | ||
this._orthogonalSize = size; | ||
this.splitview.layout(this.size, this.orthogonalSize); | ||
this.splitview.layout(orthogonalSize, size); | ||
} | ||
@@ -175,0 +175,0 @@ addChild(node, size, index, skipLayout) { |
@@ -183,5 +183,5 @@ /*--------------------------------------------------------------------------------------------- | ||
_deserialize(root, orientation, deserializer, orthogonalSize) { | ||
this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize, true); | ||
this.root = this._deserializeNode(root, orientation, deserializer, orthogonalSize); | ||
} | ||
_deserializeNode(node, orientation, deserializer, orthogonalSize, isRoot = false) { | ||
_deserializeNode(node, orientation, deserializer, orthogonalSize) { | ||
let result; | ||
@@ -196,5 +196,5 @@ if (node.type === 'branch') { | ||
}); | ||
// HORIZONTAL => height=orthogonalsize width=size | ||
// VERTICAL => height=size width=orthogonalsize | ||
result = new BranchNode(orientation, this.proportionalLayout, this.styles, isRoot ? orthogonalSize : node.size, isRoot ? node.size : orthogonalSize, children); | ||
result = new BranchNode(orientation, this.proportionalLayout, this.styles, node.size, // <- orthogonal size - flips at each depth | ||
orthogonalSize, // <- size - flips at each depth | ||
children); | ||
} | ||
@@ -232,3 +232,6 @@ else { | ||
this._root = new BranchNode(orthogonal(oldRoot.orientation), this.proportionalLayout, this.styles, this.root.orthogonalSize, this.root.size); | ||
if (oldRoot.children.length === 1) { | ||
if (oldRoot.children.length === 0) { | ||
// no data so no need to add anything back in | ||
} | ||
else if (oldRoot.children.length === 1) { | ||
// can remove one level of redundant branching if there is only a single child | ||
@@ -235,0 +238,0 @@ const childReference = oldRoot.children[0]; |
@@ -81,2 +81,5 @@ import { getRelativeLocation, getGridLocation, } from './gridview'; | ||
const queue = []; | ||
// take note of the existing dimensions | ||
const width = this.width; | ||
const height = this.height; | ||
this.gridview.deserialize(grid, { | ||
@@ -107,3 +110,3 @@ fromJSON: (node) => { | ||
}); | ||
this.layout(this.width, this.height, true); | ||
this.layout(width, height, true); | ||
queue.forEach((f) => f()); | ||
@@ -110,0 +113,0 @@ if (typeof activePanel === 'string') { |
@@ -18,3 +18,3 @@ import { PanelInitParameters } from '../panel/types'; | ||
} | ||
export interface IGridviewPanel extends BasePanelViewExported<GridviewPanelApi> { | ||
export interface IGridviewPanel<T extends GridviewPanelApi = GridviewPanelApi> extends BasePanelViewExported<T> { | ||
readonly minimumWidth: number; | ||
@@ -27,3 +27,3 @@ readonly maximumWidth: number; | ||
} | ||
export declare abstract class GridviewPanel extends BasePanelView<GridviewPanelApiImpl> implements IGridPanelComponentView, IGridviewPanel { | ||
export declare abstract class GridviewPanel<T extends GridviewPanelApiImpl = GridviewPanelApiImpl> extends BasePanelView<T> implements IGridPanelComponentView, IGridviewPanel { | ||
private _evaluatedMinimumWidth; | ||
@@ -53,3 +53,3 @@ private _evaluatedMaximumWidth; | ||
maximumHeight?: number; | ||
}); | ||
}, api?: T); | ||
setVisible(isVisible: boolean): void; | ||
@@ -56,0 +56,0 @@ setActive(isActive: boolean): void; |
@@ -54,4 +54,4 @@ import { BasePanelView, } from './basePanelView'; | ||
} | ||
constructor(id, component, options) { | ||
super(id, component, new GridviewPanelApiImpl(id)); | ||
constructor(id, component, options, api) { | ||
super(id, component, api !== null && api !== void 0 ? api : new GridviewPanelApiImpl(id)); | ||
this._evaluatedMinimumWidth = 0; | ||
@@ -58,0 +58,0 @@ this._evaluatedMaximumWidth = Number.MAX_SAFE_INTEGER; |
export * from './dnd/dataTransfer'; | ||
export { watchElementResize } from './dom'; | ||
/** | ||
@@ -41,3 +40,4 @@ * Events, Emitters and Disposables are very common concepts that most codebases will contain. | ||
export { ExpansionEvent, PaneviewPanelApi } from './api/paneviewPanelApi'; | ||
export { DockviewGroupPanelApi, DockviewGroupPanelFloatingChangeEvent, } from './api/dockviewGroupPanelApi'; | ||
export { CommonApi, SplitviewApi, PaneviewApi, GridviewApi, DockviewApi, } from './api/component.api'; | ||
//# sourceMappingURL=index.d.ts.map |
export * from './dnd/dataTransfer'; | ||
export { watchElementResize } from './dom'; | ||
/** | ||
@@ -4,0 +3,0 @@ * Events, Emitters and Disposables are very common concepts that most codebases will contain. |
@@ -183,2 +183,5 @@ import { PaneviewApi } from '../api/component.api'; | ||
const queue = []; | ||
// take note of the existing dimensions | ||
const width = this.width; | ||
const height = this.height; | ||
this.paneview = new Paneview(this.element, { | ||
@@ -239,3 +242,3 @@ orientation: Orientation.VERTICAL, | ||
}); | ||
this.layout(this.width, this.height); | ||
this.layout(width, height); | ||
queue.forEach((f) => f()); | ||
@@ -242,0 +245,0 @@ this._onDidLayoutfromJSON.fire(); |
@@ -186,2 +186,5 @@ import { CompositeDisposable, MutableDisposable, } from '../lifecycle'; | ||
const queue = []; | ||
// take note of the existing dimensions | ||
const width = this.width; | ||
const height = this.height; | ||
this.splitview = new Splitview(this.element, { | ||
@@ -223,3 +226,3 @@ orientation, | ||
}); | ||
this.layout(this.width, this.height); | ||
this.layout(width, height); | ||
queue.forEach((f) => f()); | ||
@@ -226,0 +229,0 @@ if (typeof activeView === 'string') { |
{ | ||
"name": "dockview-core", | ||
"version": "1.7.6", | ||
"version": "1.8.0", | ||
"description": "Zero dependency layout manager supporting tabs, grids and splitviews with ReactJS support", | ||
@@ -17,8 +17,8 @@ "main": "./dist/cjs/index.js", | ||
"scripts": { | ||
"build:ci": "npm run build:cjs && npm run build:esm && npm run build:css", | ||
"build:package": "npm run build:cjs && npm run build:esm && npm run build:css", | ||
"build:cjs": "cross-env ../../node_modules/.bin/tsc --project ./tsconfig.json --extendedDiagnostics", | ||
"build:css": "gulp sass", | ||
"build:esm": "cross-env ../../node_modules/.bin/tsc --project ./tsconfig.esm.json --extendedDiagnostics", | ||
"build:modulefiles": "rollup -c", | ||
"build": "npm run build:ci && npm run build:modulefiles", | ||
"build:bundles": "rollup -c", | ||
"build": "npm run build:package && npm run build:bundles", | ||
"clean": "rimraf dist/ .build/ .rollup.cache/", | ||
@@ -69,3 +69,3 @@ "prepublishOnly": "npm run rebuild && npm run test", | ||
}, | ||
"gitHead": "5d1b6c336f066cfc43eb07ad6d27e1e30d1fe16f" | ||
"gitHead": "2202a89c15d628c7245417c796625db3fc742c85" | ||
} |
<div align="center"> | ||
<h1>dockview</h1> | ||
<p>Zero dependency layout manager supporting tabs, grids and splitviews written in TypeScript</p> | ||
<p>Zero dependency layout manager supporting tabs, groups, grids and splitviews written in TypeScript</p> | ||
@@ -28,2 +28,3 @@ </div> | ||
- Tabular docking and Drag and Drop support | ||
- Floating groups, customized header bars and tab | ||
- Documentation and examples | ||
@@ -30,0 +31,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 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 too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is 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
6720159
507
70359
52