dockview-core 5.1.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/cjs/api/component.api.d.ts +93 -1
- package/dist/cjs/api/component.api.js +146 -0
- package/dist/cjs/api/dockviewGroupPanelApi.d.ts +26 -0
- package/dist/cjs/api/dockviewGroupPanelApi.js +21 -1
- package/dist/cjs/api/entryPoints.js +4 -5
- package/dist/cjs/array.js +7 -8
- package/dist/cjs/dnd/dataTransfer.d.ts +2 -1
- package/dist/cjs/dnd/dataTransfer.js +5 -4
- package/dist/cjs/dnd/droptarget.d.ts +12 -0
- package/dist/cjs/dnd/droptarget.js +38 -10
- package/dist/cjs/dnd/ghost.js +1 -2
- package/dist/cjs/dockview/components/panel/content.js +5 -1
- package/dist/cjs/dockview/components/popupService.d.ts +9 -2
- package/dist/cjs/dockview/components/popupService.js +24 -9
- package/dist/cjs/dockview/components/tab/tab.d.ts +8 -1
- package/dist/cjs/dockview/components/tab/tab.js +94 -6
- package/dist/cjs/dockview/components/titlebar/tabGroupChip.d.ts +30 -0
- package/dist/cjs/dockview/components/titlebar/tabGroupChip.js +95 -0
- package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.d.ts +71 -0
- package/dist/cjs/dockview/components/titlebar/tabGroupIndicator.js +471 -0
- package/dist/cjs/dockview/components/titlebar/tabGroups.d.ts +57 -0
- package/dist/cjs/dockview/components/titlebar/tabGroups.js +612 -0
- package/dist/cjs/dockview/components/titlebar/tabOverflowControl.js +1 -2
- package/dist/cjs/dockview/components/titlebar/tabs.d.ts +67 -0
- package/dist/cjs/dockview/components/titlebar/tabs.js +1464 -34
- package/dist/cjs/dockview/components/titlebar/tabsContainer.d.ts +6 -0
- package/dist/cjs/dockview/components/titlebar/tabsContainer.js +132 -14
- package/dist/cjs/dockview/contextMenu.d.ts +10 -0
- package/dist/cjs/dockview/contextMenu.js +298 -0
- package/dist/cjs/dockview/dockviewComponent.d.ts +60 -3
- package/dist/cjs/dockview/dockviewComponent.js +712 -126
- package/dist/cjs/dockview/dockviewGroupPanelModel.d.ts +83 -0
- package/dist/cjs/dockview/dockviewGroupPanelModel.js +619 -27
- package/dist/cjs/dockview/dockviewShell.d.ts +128 -0
- package/dist/cjs/dockview/dockviewShell.js +681 -0
- package/dist/cjs/dockview/events.d.ts +9 -0
- package/dist/cjs/dockview/framework.d.ts +14 -0
- package/dist/cjs/dockview/options.d.ts +97 -2
- package/dist/cjs/dockview/options.js +10 -5
- package/dist/cjs/dockview/tabGroup.d.ts +99 -0
- package/dist/cjs/dockview/tabGroup.js +219 -0
- package/dist/cjs/dockview/tabGroupAccent.d.ts +65 -0
- package/dist/cjs/dockview/tabGroupAccent.js +128 -0
- package/dist/cjs/dockview/theme.d.ts +56 -1
- package/dist/cjs/dockview/theme.js +103 -6
- package/dist/cjs/dockview/types.d.ts +2 -0
- package/dist/cjs/dom.js +19 -19
- package/dist/cjs/events.js +2 -2
- package/dist/cjs/gridview/baseComponentGridview.d.ts +1 -0
- package/dist/cjs/gridview/baseComponentGridview.js +6 -3
- package/dist/cjs/gridview/gridview.js +7 -7
- package/dist/cjs/index.d.ts +8 -5
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/popoutWindow.js +3 -3
- package/dist/cjs/splitview/splitviewPanel.d.ts +1 -1
- package/dist/dockview-core.js +5188 -729
- package/dist/dockview-core.min.js +2 -2
- package/dist/dockview-core.min.js.map +1 -1
- package/dist/dockview-core.min.noStyle.js +2 -2
- package/dist/dockview-core.min.noStyle.js.map +1 -1
- package/dist/dockview-core.noStyle.js +5186 -727
- package/dist/esm/api/component.api.d.ts +93 -1
- package/dist/esm/api/component.api.js +118 -0
- package/dist/esm/api/dockviewGroupPanelApi.d.ts +26 -0
- package/dist/esm/api/dockviewGroupPanelApi.js +21 -1
- package/dist/esm/dnd/dataTransfer.d.ts +2 -1
- package/dist/esm/dnd/dataTransfer.js +2 -1
- package/dist/esm/dnd/droptarget.d.ts +12 -0
- package/dist/esm/dnd/droptarget.js +33 -5
- package/dist/esm/dockview/components/panel/content.js +5 -1
- package/dist/esm/dockview/components/popupService.d.ts +9 -2
- package/dist/esm/dockview/components/popupService.js +23 -9
- package/dist/esm/dockview/components/tab/tab.d.ts +8 -1
- package/dist/esm/dockview/components/tab/tab.js +96 -6
- package/dist/esm/dockview/components/titlebar/tabGroupChip.d.ts +30 -0
- package/dist/esm/dockview/components/titlebar/tabGroupChip.js +68 -0
- package/dist/esm/dockview/components/titlebar/tabGroupIndicator.d.ts +71 -0
- package/dist/esm/dockview/components/titlebar/tabGroupIndicator.js +354 -0
- package/dist/esm/dockview/components/titlebar/tabGroups.d.ts +57 -0
- package/dist/esm/dockview/components/titlebar/tabGroups.js +406 -0
- package/dist/esm/dockview/components/titlebar/tabs.d.ts +67 -0
- package/dist/esm/dockview/components/titlebar/tabs.js +1212 -25
- package/dist/esm/dockview/components/titlebar/tabsContainer.d.ts +6 -0
- package/dist/esm/dockview/components/titlebar/tabsContainer.js +105 -7
- package/dist/esm/dockview/contextMenu.d.ts +10 -0
- package/dist/esm/dockview/contextMenu.js +213 -0
- package/dist/esm/dockview/dockviewComponent.d.ts +60 -3
- package/dist/esm/dockview/dockviewComponent.js +460 -35
- package/dist/esm/dockview/dockviewGroupPanelModel.d.ts +83 -0
- package/dist/esm/dockview/dockviewGroupPanelModel.js +460 -4
- package/dist/esm/dockview/dockviewShell.d.ts +128 -0
- package/dist/esm/dockview/dockviewShell.js +621 -0
- package/dist/esm/dockview/events.d.ts +9 -0
- package/dist/esm/dockview/framework.d.ts +14 -0
- package/dist/esm/dockview/options.d.ts +97 -2
- package/dist/esm/dockview/options.js +5 -0
- package/dist/esm/dockview/tabGroup.d.ts +99 -0
- package/dist/esm/dockview/tabGroup.js +144 -0
- package/dist/esm/dockview/tabGroupAccent.d.ts +65 -0
- package/dist/esm/dockview/tabGroupAccent.js +116 -0
- package/dist/esm/dockview/theme.d.ts +56 -1
- package/dist/esm/dockview/theme.js +102 -5
- package/dist/esm/dockview/types.d.ts +2 -0
- package/dist/esm/dom.js +1 -1
- package/dist/esm/gridview/baseComponentGridview.d.ts +1 -0
- package/dist/esm/gridview/baseComponentGridview.js +4 -1
- package/dist/esm/index.d.ts +8 -5
- package/dist/esm/index.js +2 -1
- package/dist/esm/popoutWindow.js +1 -1
- package/dist/esm/splitview/splitviewPanel.d.ts +1 -1
- package/dist/package/main.cjs.js +5182 -753
- package/dist/package/main.cjs.min.js +2 -2
- package/dist/package/main.esm.min.mjs +2 -2
- package/dist/package/main.esm.mjs +5168 -753
- package/dist/styles/dockview.css +1968 -195
- package/package.json +5 -1
|
@@ -7,6 +7,7 @@ import { CompositeDisposable, MutableDisposable, } from '../lifecycle';
|
|
|
7
7
|
import { ContentContainer, } from './components/panel/content';
|
|
8
8
|
import { TabsContainer, } from './components/titlebar/tabsContainer';
|
|
9
9
|
import { DockviewUnhandledDragOverEvent, } from './options';
|
|
10
|
+
import { TabGroup, } from './tabGroup';
|
|
10
11
|
export class DockviewDidDropEvent extends DockviewEvent {
|
|
11
12
|
get nativeEvent() {
|
|
12
13
|
return this.options.nativeEvent;
|
|
@@ -41,6 +42,9 @@ export class DockviewWillDropEvent extends DockviewDidDropEvent {
|
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
45
|
+
get tabGroups() {
|
|
46
|
+
return this._tabGroups;
|
|
47
|
+
}
|
|
44
48
|
get element() {
|
|
45
49
|
throw new Error('dockview: not supported');
|
|
46
50
|
}
|
|
@@ -108,6 +112,7 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
108
112
|
this._location = value;
|
|
109
113
|
toggleClass(this.container, 'dv-groupview-floating', false);
|
|
110
114
|
toggleClass(this.container, 'dv-groupview-popout', false);
|
|
115
|
+
toggleClass(this.container, 'dv-groupview-edge', false);
|
|
111
116
|
switch (value.type) {
|
|
112
117
|
case 'grid':
|
|
113
118
|
this.contentContainer.dropTarget.setTargetZones([
|
|
@@ -129,6 +134,10 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
129
134
|
this.contentContainer.dropTarget.setTargetZones(['center']);
|
|
130
135
|
toggleClass(this.container, 'dv-groupview-popout', true);
|
|
131
136
|
break;
|
|
137
|
+
case 'edge':
|
|
138
|
+
this.contentContainer.dropTarget.setTargetZones(['center']);
|
|
139
|
+
toggleClass(this.container, 'dv-groupview-edge', true);
|
|
140
|
+
break;
|
|
132
141
|
}
|
|
133
142
|
this.groupPanel.api._onDidLocationChange.fire({
|
|
134
143
|
location: this.location,
|
|
@@ -157,6 +166,8 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
157
166
|
this._height = 0;
|
|
158
167
|
this._panels = [];
|
|
159
168
|
this._panelDisposables = new Map();
|
|
169
|
+
this._tabGroupDisposables = new Map();
|
|
170
|
+
this._pendingMicrotaskDisposables = new Set();
|
|
160
171
|
this._onMove = new Emitter();
|
|
161
172
|
this.onMove = this._onMove.event;
|
|
162
173
|
this._onDidDrop = new Emitter();
|
|
@@ -181,6 +192,23 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
181
192
|
this.onDidActivePanelChange = this._onDidActivePanelChange.event;
|
|
182
193
|
this._onUnhandledDragOverEvent = new Emitter();
|
|
183
194
|
this.onUnhandledDragOverEvent = this._onUnhandledDragOverEvent.event;
|
|
195
|
+
this._tabGroups = [];
|
|
196
|
+
this._tabGroupMap = new Map();
|
|
197
|
+
this._panelToTabGroup = new Map();
|
|
198
|
+
this._tabGroupIdCounter = 0;
|
|
199
|
+
this._pendingTabGroupUpdate = false;
|
|
200
|
+
this._onDidCreateTabGroup = new Emitter();
|
|
201
|
+
this.onDidCreateTabGroup = this._onDidCreateTabGroup.event;
|
|
202
|
+
this._onDidDestroyTabGroup = new Emitter();
|
|
203
|
+
this.onDidDestroyTabGroup = this._onDidDestroyTabGroup.event;
|
|
204
|
+
this._onDidAddPanelToTabGroup = new Emitter();
|
|
205
|
+
this.onDidAddPanelToTabGroup = this._onDidAddPanelToTabGroup.event;
|
|
206
|
+
this._onDidRemovePanelFromTabGroup = new Emitter();
|
|
207
|
+
this.onDidRemovePanelFromTabGroup = this._onDidRemovePanelFromTabGroup.event;
|
|
208
|
+
this._onDidTabGroupChange = new Emitter();
|
|
209
|
+
this.onDidTabGroupChange = this._onDidTabGroupChange.event;
|
|
210
|
+
this._onDidTabGroupCollapsedChange = new Emitter();
|
|
211
|
+
this.onDidTabGroupCollapsedChange = this._onDidTabGroupCollapsedChange.event;
|
|
184
212
|
toggleClass(this.container, 'dv-groupview', true);
|
|
185
213
|
this._api = new DockviewApi(this.accessor);
|
|
186
214
|
this.tabsContainer = new TabsContainer(this.accessor, this.groupPanel);
|
|
@@ -195,7 +223,38 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
195
223
|
}), this.tabsContainer.onGroupDragStart((event) => {
|
|
196
224
|
this._onGroupDragStart.fire(event);
|
|
197
225
|
}), this.tabsContainer.onDrop((event) => {
|
|
226
|
+
var _a;
|
|
227
|
+
// Capture panel data before handleDropEvent (which may trigger moves)
|
|
228
|
+
const dragData = getPanelData();
|
|
229
|
+
const draggedPanelId = (_a = dragData === null || dragData === void 0 ? void 0 : dragData.panelId) !== null && _a !== void 0 ? _a : null;
|
|
198
230
|
this.handleDropEvent('header', event.event, 'center', event.index);
|
|
231
|
+
// Update tab group membership after the move completes
|
|
232
|
+
if (draggedPanelId && event.targetTabGroupId) {
|
|
233
|
+
// Compute the local index within the target tab group
|
|
234
|
+
// from the global panel index so the panel is inserted
|
|
235
|
+
// at the correct position, not just appended.
|
|
236
|
+
const tabGroup = this._tabGroupMap.get(event.targetTabGroupId);
|
|
237
|
+
let localIndex;
|
|
238
|
+
if (tabGroup) {
|
|
239
|
+
const globalIdx = this._panels.findIndex((p) => p.id === draggedPanelId);
|
|
240
|
+
if (globalIdx !== -1) {
|
|
241
|
+
// Count how many of this group's panels
|
|
242
|
+
// appear before the dragged panel
|
|
243
|
+
localIndex = 0;
|
|
244
|
+
for (const pid of tabGroup.panelIds) {
|
|
245
|
+
const pidIdx = this._panels.findIndex((p) => p.id === pid);
|
|
246
|
+
if (pidIdx < globalIdx) {
|
|
247
|
+
localIndex++;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
this.addPanelToTabGroup(event.targetTabGroupId, draggedPanelId, localIndex);
|
|
253
|
+
}
|
|
254
|
+
else if (draggedPanelId && event.targetTabGroupId === null) {
|
|
255
|
+
// Dropped outside any group — remove from current group
|
|
256
|
+
this.removePanelFromTabGroup(draggedPanelId);
|
|
257
|
+
}
|
|
199
258
|
}), this.contentContainer.onDidFocus(() => {
|
|
200
259
|
this.accessor.doSetGroupActive(this.groupPanel);
|
|
201
260
|
}), this.contentContainer.onDidBlur(() => {
|
|
@@ -212,7 +271,378 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
212
271
|
group: this.groupPanel,
|
|
213
272
|
getData: getPanelData,
|
|
214
273
|
}));
|
|
215
|
-
}), this._onMove, this._onDidChange, this._onDidDrop, this._onWillDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange, this._onUnhandledDragOverEvent, this._onDidPanelTitleChange, this._onDidPanelParametersChange)
|
|
274
|
+
}), this._onMove, this._onDidChange, this._onDidDrop, this._onWillDrop, this._onDidAddPanel, this._onDidRemovePanel, this._onDidActivePanelChange, this._onUnhandledDragOverEvent, this._onDidPanelTitleChange, this._onDidPanelParametersChange, this._onDidCreateTabGroup, this._onDidDestroyTabGroup, this._onDidAddPanelToTabGroup, this._onDidRemovePanelFromTabGroup, this._onDidTabGroupChange, this._onDidTabGroupCollapsedChange, this._onDidCreateTabGroup.event(() => {
|
|
275
|
+
this._scheduleTabGroupUpdate();
|
|
276
|
+
}), this._onDidDestroyTabGroup.event(() => {
|
|
277
|
+
this._scheduleTabGroupUpdate();
|
|
278
|
+
}), this._onDidAddPanelToTabGroup.event(() => {
|
|
279
|
+
this._scheduleTabGroupUpdate();
|
|
280
|
+
}), this._onDidRemovePanelFromTabGroup.event(() => {
|
|
281
|
+
this._scheduleTabGroupUpdate();
|
|
282
|
+
}), this._onDidTabGroupChange.event(() => {
|
|
283
|
+
this._scheduleTabGroupUpdate();
|
|
284
|
+
}), this._onDidTabGroupCollapsedChange.event(() => {
|
|
285
|
+
this._scheduleTabGroupUpdate();
|
|
286
|
+
}));
|
|
287
|
+
}
|
|
288
|
+
_scheduleTabGroupUpdate() {
|
|
289
|
+
if (this._pendingTabGroupUpdate) {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
this._pendingTabGroupUpdate = true;
|
|
293
|
+
queueMicrotask(() => {
|
|
294
|
+
this._pendingTabGroupUpdate = false;
|
|
295
|
+
if (!this.isDisposed) {
|
|
296
|
+
this.tabsContainer.updateTabGroups();
|
|
297
|
+
}
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
createTabGroup(options) {
|
|
301
|
+
var _a;
|
|
302
|
+
const id = (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : `tg-${this.id}-${this._tabGroupIdCounter++}`;
|
|
303
|
+
const tabGroup = new TabGroup(id, {
|
|
304
|
+
label: options === null || options === void 0 ? void 0 : options.label,
|
|
305
|
+
color: options === null || options === void 0 ? void 0 : options.color,
|
|
306
|
+
collapsed: options === null || options === void 0 ? void 0 : options.collapsed,
|
|
307
|
+
componentParams: options === null || options === void 0 ? void 0 : options.componentParams,
|
|
308
|
+
});
|
|
309
|
+
this._tabGroups.push(tabGroup);
|
|
310
|
+
this._tabGroupMap.set(id, tabGroup);
|
|
311
|
+
this._tabGroupDisposables.set(id, new CompositeDisposable(tabGroup.onDidChange(() => {
|
|
312
|
+
this._onDidTabGroupChange.fire({ tabGroup });
|
|
313
|
+
}), tabGroup.onDidCollapseChange((isCollapsed) => {
|
|
314
|
+
if (isCollapsed) {
|
|
315
|
+
this._handleGroupCollapse(tabGroup);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
this._handleGroupExpand(tabGroup);
|
|
319
|
+
}
|
|
320
|
+
this._onDidTabGroupCollapsedChange.fire({
|
|
321
|
+
tabGroup,
|
|
322
|
+
});
|
|
323
|
+
}), tabGroup.onDidDestroy(() => {
|
|
324
|
+
this._removeTabGroupInternal(tabGroup);
|
|
325
|
+
})));
|
|
326
|
+
this._onDidCreateTabGroup.fire({ tabGroup });
|
|
327
|
+
return tabGroup;
|
|
328
|
+
}
|
|
329
|
+
dissolveTabGroup(tabGroupId) {
|
|
330
|
+
const tabGroup = this._tabGroupMap.get(tabGroupId);
|
|
331
|
+
if (!tabGroup) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
// Remove all panels from the group (they stay in the flat panel list)
|
|
335
|
+
const panelIds = [...tabGroup.panelIds];
|
|
336
|
+
for (const panelId of panelIds) {
|
|
337
|
+
tabGroup.removePanel(panelId);
|
|
338
|
+
this._panelToTabGroup.delete(panelId);
|
|
339
|
+
this._onDidRemovePanelFromTabGroup.fire({ tabGroup, panelId });
|
|
340
|
+
}
|
|
341
|
+
tabGroup.dispose();
|
|
342
|
+
}
|
|
343
|
+
addPanelToTabGroup(tabGroupId, panelId, index) {
|
|
344
|
+
const tabGroup = this._tabGroupMap.get(tabGroupId);
|
|
345
|
+
if (!tabGroup) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
// Ensure the panel actually exists in this group model
|
|
349
|
+
if (!this._panels.some((p) => p.id === panelId)) {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
// Remove from any existing group first
|
|
353
|
+
const existingGroup = this.getTabGroupForPanel(panelId);
|
|
354
|
+
if (existingGroup) {
|
|
355
|
+
if (existingGroup.id === tabGroupId) {
|
|
356
|
+
return; // already in this group
|
|
357
|
+
}
|
|
358
|
+
this.removePanelFromTabGroup(panelId);
|
|
359
|
+
}
|
|
360
|
+
tabGroup.addPanel(panelId, index);
|
|
361
|
+
this._panelToTabGroup.set(panelId, tabGroup);
|
|
362
|
+
// Enforce contiguity: move the panel in the flat _panels array
|
|
363
|
+
// to the correct global position matching its group-local index
|
|
364
|
+
this._enforceContiguity(tabGroup, panelId);
|
|
365
|
+
this._onDidAddPanelToTabGroup.fire({ tabGroup, panelId });
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Move a panel to a new index within its tab group.
|
|
369
|
+
* Updates both the group's panelIds order and the flat _panels array.
|
|
370
|
+
*/
|
|
371
|
+
movePanelWithinGroup(tabGroupId, panelId, newIndex) {
|
|
372
|
+
const tabGroup = this._tabGroupMap.get(tabGroupId);
|
|
373
|
+
if (!tabGroup || !tabGroup.containsPanel(panelId)) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
// Remove and re-add at new index within the group
|
|
377
|
+
tabGroup.removePanel(panelId);
|
|
378
|
+
tabGroup.addPanel(panelId, newIndex);
|
|
379
|
+
// Re-enforce contiguity in the flat array
|
|
380
|
+
this._enforceContiguity(tabGroup, panelId);
|
|
381
|
+
this.tabsContainer.updateTabGroups();
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Move a panel from one tab group to another.
|
|
385
|
+
*/
|
|
386
|
+
movePanelBetweenGroups(sourcePanelId, targetTabGroupId, targetIndex) {
|
|
387
|
+
const sourceGroup = this._findTabGroupForPanel(sourcePanelId);
|
|
388
|
+
const targetGroup = this._tabGroupMap.get(targetTabGroupId);
|
|
389
|
+
if (!targetGroup) {
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
if (sourceGroup) {
|
|
393
|
+
sourceGroup.removePanel(sourcePanelId);
|
|
394
|
+
this._panelToTabGroup.delete(sourcePanelId);
|
|
395
|
+
this._onDidRemovePanelFromTabGroup.fire({
|
|
396
|
+
tabGroup: sourceGroup,
|
|
397
|
+
panelId: sourcePanelId,
|
|
398
|
+
});
|
|
399
|
+
// Auto-destroy empty source group
|
|
400
|
+
if (sourceGroup.isEmpty) {
|
|
401
|
+
sourceGroup.dispose();
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
targetGroup.addPanel(sourcePanelId, targetIndex);
|
|
405
|
+
this._panelToTabGroup.set(sourcePanelId, targetGroup);
|
|
406
|
+
this._enforceContiguity(targetGroup, sourcePanelId);
|
|
407
|
+
this._onDidAddPanelToTabGroup.fire({
|
|
408
|
+
tabGroup: targetGroup,
|
|
409
|
+
panelId: sourcePanelId,
|
|
410
|
+
});
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Move an entire tab group to a new position in the tab bar.
|
|
414
|
+
* The group's internal panel order is preserved.
|
|
415
|
+
*/
|
|
416
|
+
moveTabGroup(tabGroupId, targetIndex) {
|
|
417
|
+
const tabGroup = this._tabGroupMap.get(tabGroupId);
|
|
418
|
+
if (!tabGroup || tabGroup.panelIds.length === 0) {
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
// Collect group panels in their current order
|
|
422
|
+
const groupPanelIds = new Set(tabGroup.panelIds);
|
|
423
|
+
const groupPanels = tabGroup.panelIds
|
|
424
|
+
.map((pid) => this._panels.find((p) => p.id === pid))
|
|
425
|
+
.filter((p) => p !== undefined);
|
|
426
|
+
if (groupPanels.length === 0) {
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
// Count how many group panels sit before the target index so
|
|
430
|
+
// we can compensate after removing them from the array.
|
|
431
|
+
let groupPanelsBefore = 0;
|
|
432
|
+
for (let i = 0; i < Math.min(targetIndex, this._panels.length); i++) {
|
|
433
|
+
if (groupPanelIds.has(this._panels[i].id)) {
|
|
434
|
+
groupPanelsBefore++;
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
// Remove group panels from the flat array
|
|
438
|
+
for (const panel of groupPanels) {
|
|
439
|
+
const idx = this._panels.indexOf(panel);
|
|
440
|
+
if (idx !== -1) {
|
|
441
|
+
this._panels.splice(idx, 1);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
// Adjust target index to account for removed panels
|
|
445
|
+
const adjustedIndex = targetIndex - groupPanelsBefore;
|
|
446
|
+
// Clamp target index to valid range after removal
|
|
447
|
+
const insertAt = Math.max(0, Math.min(adjustedIndex, this._panels.length));
|
|
448
|
+
// Insert group panels at the target position
|
|
449
|
+
this._panels.splice(insertAt, 0, ...groupPanels);
|
|
450
|
+
// Rebuild the tabs container to match new order
|
|
451
|
+
for (const panel of this._panels) {
|
|
452
|
+
this.tabsContainer.delete(panel.id);
|
|
453
|
+
}
|
|
454
|
+
for (let i = 0; i < this._panels.length; i++) {
|
|
455
|
+
this.tabsContainer.openPanel(this._panels[i], i);
|
|
456
|
+
}
|
|
457
|
+
this.tabsContainer.updateTabGroups();
|
|
458
|
+
}
|
|
459
|
+
/**
|
|
460
|
+
* Ensure a panel is at the correct global index in _panels
|
|
461
|
+
* to maintain contiguity of its tab group members.
|
|
462
|
+
*/
|
|
463
|
+
_enforceContiguity(tabGroup, panelId) {
|
|
464
|
+
const panel = this._panels.find((p) => p.id === panelId);
|
|
465
|
+
if (!panel) {
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
const localIndex = tabGroup.indexOfPanel(panelId);
|
|
469
|
+
const globalIndex = this._computeGlobalIndex(tabGroup, localIndex);
|
|
470
|
+
const currentIndex = this._panels.indexOf(panel);
|
|
471
|
+
if (currentIndex === globalIndex) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
// Move panel in the flat array
|
|
475
|
+
this._panels.splice(currentIndex, 1);
|
|
476
|
+
const adjustedIndex = globalIndex > currentIndex ? globalIndex - 1 : globalIndex;
|
|
477
|
+
this._panels.splice(adjustedIndex, 0, panel);
|
|
478
|
+
// Reorder in the tabs container to match
|
|
479
|
+
this.tabsContainer.delete(panelId);
|
|
480
|
+
this.tabsContainer.openPanel(panel, adjustedIndex);
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Compute the global index in _panels for a group-local index.
|
|
484
|
+
* Finds where the group's panels start in the flat array and offsets.
|
|
485
|
+
*/
|
|
486
|
+
_computeGlobalIndex(tabGroup, localIndex) {
|
|
487
|
+
const groupPanelIds = tabGroup.panelIds;
|
|
488
|
+
if (groupPanelIds.length <= 1) {
|
|
489
|
+
// Only one panel (the one being added), keep current position
|
|
490
|
+
const panel = this._panels.find((p) => p.id === groupPanelIds[0]);
|
|
491
|
+
return panel ? this._panels.indexOf(panel) : this._panels.length;
|
|
492
|
+
}
|
|
493
|
+
// Find the first existing group member (other than the one at localIndex)
|
|
494
|
+
// to anchor the group position
|
|
495
|
+
for (let i = 0; i < groupPanelIds.length; i++) {
|
|
496
|
+
if (i === localIndex) {
|
|
497
|
+
continue;
|
|
498
|
+
}
|
|
499
|
+
const existingPanel = this._panels.find((p) => p.id === groupPanelIds[i]);
|
|
500
|
+
if (existingPanel) {
|
|
501
|
+
const existingGlobalIndex = this._panels.indexOf(existingPanel);
|
|
502
|
+
// Offset based on relative position within group
|
|
503
|
+
return Math.max(0, existingGlobalIndex + (localIndex - i));
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
return this._panels.length;
|
|
507
|
+
}
|
|
508
|
+
removePanelFromTabGroup(panelId) {
|
|
509
|
+
const tabGroup = this._findTabGroupForPanel(panelId);
|
|
510
|
+
if (!tabGroup) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
tabGroup.removePanel(panelId);
|
|
514
|
+
this._panelToTabGroup.delete(panelId);
|
|
515
|
+
this._onDidRemovePanelFromTabGroup.fire({ tabGroup, panelId });
|
|
516
|
+
// Auto-destroy empty groups
|
|
517
|
+
if (tabGroup.isEmpty) {
|
|
518
|
+
tabGroup.dispose();
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
getTabGroups() {
|
|
522
|
+
return this._tabGroups;
|
|
523
|
+
}
|
|
524
|
+
updateTabGroups() {
|
|
525
|
+
this.tabsContainer.updateTabGroups();
|
|
526
|
+
}
|
|
527
|
+
refreshTabGroupAccent() {
|
|
528
|
+
this.tabsContainer.refreshTabGroupAccent();
|
|
529
|
+
}
|
|
530
|
+
getTabGroupForPanel(panelId) {
|
|
531
|
+
return this._findTabGroupForPanel(panelId);
|
|
532
|
+
}
|
|
533
|
+
_findTabGroupForPanel(panelId) {
|
|
534
|
+
return this._panelToTabGroup.get(panelId);
|
|
535
|
+
}
|
|
536
|
+
_removeTabGroupInternal(tabGroup) {
|
|
537
|
+
const index = this._tabGroups.indexOf(tabGroup);
|
|
538
|
+
if (index !== -1) {
|
|
539
|
+
this._tabGroups.splice(index, 1);
|
|
540
|
+
this._tabGroupMap.delete(tabGroup.id);
|
|
541
|
+
for (const panelId of tabGroup.panelIds) {
|
|
542
|
+
this._panelToTabGroup.delete(panelId);
|
|
543
|
+
}
|
|
544
|
+
this._onDidDestroyTabGroup.fire({ tabGroup });
|
|
545
|
+
// Dispose the external listeners (onDidChange, onDidCollapseChange)
|
|
546
|
+
// we registered on this group. We cannot dispose synchronously
|
|
547
|
+
// here because this method runs inside the onDidDestroy fire
|
|
548
|
+
// loop — disposing the CompositeDisposable that holds the
|
|
549
|
+
// onDidDestroy subscription would splice listeners mid-iteration.
|
|
550
|
+
// Schedule cleanup on the next microtask instead.
|
|
551
|
+
const tabGroupDisposable = this._tabGroupDisposables.get(tabGroup.id);
|
|
552
|
+
this._tabGroupDisposables.delete(tabGroup.id);
|
|
553
|
+
if (tabGroupDisposable) {
|
|
554
|
+
this._pendingMicrotaskDisposables.add(tabGroupDisposable);
|
|
555
|
+
queueMicrotask(() => {
|
|
556
|
+
this._pendingMicrotaskDisposables.delete(tabGroupDisposable);
|
|
557
|
+
tabGroupDisposable.dispose();
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
_handleGroupCollapse(tabGroup) {
|
|
563
|
+
if (!this._activePanel) {
|
|
564
|
+
return;
|
|
565
|
+
}
|
|
566
|
+
// Only act if the active panel belongs to the collapsed group
|
|
567
|
+
if (!tabGroup.containsPanel(this._activePanel.id)) {
|
|
568
|
+
return;
|
|
569
|
+
}
|
|
570
|
+
const activePanelIndex = this._panels.indexOf(this._activePanel);
|
|
571
|
+
// Search right first, then left, for a visible (non-collapsed-group) panel
|
|
572
|
+
for (let i = activePanelIndex + 1; i < this._panels.length; i++) {
|
|
573
|
+
const candidate = this._panels[i];
|
|
574
|
+
const candidateGroup = this._findTabGroupForPanel(candidate.id);
|
|
575
|
+
if (!candidateGroup || !candidateGroup.collapsed) {
|
|
576
|
+
this.doSetActivePanel(candidate);
|
|
577
|
+
this.updateContainer();
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
for (let i = activePanelIndex - 1; i >= 0; i--) {
|
|
582
|
+
const candidate = this._panels[i];
|
|
583
|
+
const candidateGroup = this._findTabGroupForPanel(candidate.id);
|
|
584
|
+
if (!candidateGroup || !candidateGroup.collapsed) {
|
|
585
|
+
this.doSetActivePanel(candidate);
|
|
586
|
+
this.updateContainer();
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
// All tabs are in collapsed groups — show watermark
|
|
591
|
+
this.contentContainer.closePanel();
|
|
592
|
+
this.doSetActivePanel(undefined);
|
|
593
|
+
this.updateContainer();
|
|
594
|
+
}
|
|
595
|
+
_handleGroupExpand(tabGroup) {
|
|
596
|
+
if (this._activePanel) {
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
// Watermark is showing because all groups were collapsed.
|
|
600
|
+
// Activate the first panel in the newly expanded group.
|
|
601
|
+
const firstPanelId = tabGroup.panelIds[0];
|
|
602
|
+
if (firstPanelId) {
|
|
603
|
+
const panel = this._panels.find((p) => p.id === firstPanelId);
|
|
604
|
+
if (panel) {
|
|
605
|
+
this.doSetActivePanel(panel);
|
|
606
|
+
this.updateContainer();
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
/** Restore tab groups from serialized data (used by fromJSON) */
|
|
611
|
+
restoreTabGroups(serializedGroups) {
|
|
612
|
+
// Bump counter past any restored numeric suffixes to avoid ID collisions
|
|
613
|
+
for (const data of serializedGroups) {
|
|
614
|
+
const match = data.id.match(/-(\d+)$/);
|
|
615
|
+
if (match) {
|
|
616
|
+
const num = parseInt(match[1], 10) + 1;
|
|
617
|
+
if (num > this._tabGroupIdCounter) {
|
|
618
|
+
this._tabGroupIdCounter = num;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
for (const data of serializedGroups) {
|
|
623
|
+
const tabGroup = this.createTabGroup({
|
|
624
|
+
id: data.id,
|
|
625
|
+
label: data.label,
|
|
626
|
+
color: data.color,
|
|
627
|
+
componentParams: data.componentParams,
|
|
628
|
+
});
|
|
629
|
+
const concreteGroup = this._tabGroupMap.get(tabGroup.id);
|
|
630
|
+
for (const panelId of data.panelIds) {
|
|
631
|
+
// Only add panels that actually exist in this group model
|
|
632
|
+
if (this._panels.some((p) => p.id === panelId)) {
|
|
633
|
+
tabGroup.addPanel(panelId);
|
|
634
|
+
this._panelToTabGroup.set(panelId, concreteGroup);
|
|
635
|
+
this._enforceContiguity(concreteGroup, panelId);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
if (data.collapsed) {
|
|
639
|
+
tabGroup.collapse();
|
|
640
|
+
}
|
|
641
|
+
// Auto-destroy if no valid panels were added
|
|
642
|
+
if (tabGroup.isEmpty) {
|
|
643
|
+
tabGroup.dispose();
|
|
644
|
+
}
|
|
645
|
+
}
|
|
216
646
|
}
|
|
217
647
|
focusContent() {
|
|
218
648
|
this.contentContainer.element.focus();
|
|
@@ -325,6 +755,9 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
325
755
|
if (this.headerPosition !== 'top') {
|
|
326
756
|
result.headerPosition = this.headerPosition;
|
|
327
757
|
}
|
|
758
|
+
if (this._tabGroups.length > 0) {
|
|
759
|
+
result.tabGroups = this._tabGroups.map((tg) => tg.toJSON());
|
|
760
|
+
}
|
|
328
761
|
return result;
|
|
329
762
|
}
|
|
330
763
|
moveToNext(options) {
|
|
@@ -464,7 +897,13 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
464
897
|
toggleClass(this.container, 'dv-inactive-group', !isGroupActive);
|
|
465
898
|
this.tabsContainer.setActive(this.isActive);
|
|
466
899
|
if (!this._activePanel && this.panels.length > 0) {
|
|
467
|
-
this.
|
|
900
|
+
const candidate = this._panels.find((p) => {
|
|
901
|
+
const tg = this._findTabGroupForPanel(p.id);
|
|
902
|
+
return !tg || !tg.collapsed;
|
|
903
|
+
});
|
|
904
|
+
if (candidate) {
|
|
905
|
+
this.doSetActivePanel(candidate);
|
|
906
|
+
}
|
|
468
907
|
}
|
|
469
908
|
this.updateContainer();
|
|
470
909
|
}
|
|
@@ -511,6 +950,8 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
511
950
|
disposable.dispose();
|
|
512
951
|
this._panelDisposables.delete(panel.id);
|
|
513
952
|
}
|
|
953
|
+
// Remove panel from its tab group (auto-destroys empty groups)
|
|
954
|
+
this.removePanelFromTabGroup(panel.id);
|
|
514
955
|
this._onDidRemovePanel.fire({ panel });
|
|
515
956
|
}
|
|
516
957
|
doAddPanel(panel, index = this.panels.length, options = { skipSetActive: false }) {
|
|
@@ -560,7 +1001,8 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
560
1001
|
updateContainer() {
|
|
561
1002
|
var _a, _b;
|
|
562
1003
|
this.panels.forEach((panel) => panel.runEvents());
|
|
563
|
-
|
|
1004
|
+
const shouldShowWatermark = this.isEmpty || !this._activePanel;
|
|
1005
|
+
if (shouldShowWatermark && !this.watermark) {
|
|
564
1006
|
const watermark = this.accessor.createWatermarkComponent();
|
|
565
1007
|
watermark.init({
|
|
566
1008
|
containerApi: this._api,
|
|
@@ -574,7 +1016,7 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
574
1016
|
});
|
|
575
1017
|
this.contentContainer.element.appendChild(this.watermark.element);
|
|
576
1018
|
}
|
|
577
|
-
if (!
|
|
1019
|
+
if (!shouldShowWatermark && this.watermark) {
|
|
578
1020
|
this.watermark.element.remove();
|
|
579
1021
|
(_b = (_a = this.watermark).dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
580
1022
|
this.watermark = undefined;
|
|
@@ -639,6 +1081,7 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
639
1081
|
target: position,
|
|
640
1082
|
groupId: groupId,
|
|
641
1083
|
index,
|
|
1084
|
+
tabGroupId: data.tabGroupId,
|
|
642
1085
|
});
|
|
643
1086
|
return;
|
|
644
1087
|
}
|
|
@@ -681,6 +1124,19 @@ export class DockviewGroupPanelModel extends CompositeDisposable {
|
|
|
681
1124
|
(_a = this.watermark) === null || _a === void 0 ? void 0 : _a.element.remove();
|
|
682
1125
|
(_c = (_b = this.watermark) === null || _b === void 0 ? void 0 : _b.dispose) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
683
1126
|
this.watermark = undefined;
|
|
1127
|
+
// Dispose all tab groups
|
|
1128
|
+
for (const tabGroup of [...this._tabGroups]) {
|
|
1129
|
+
tabGroup.dispose();
|
|
1130
|
+
}
|
|
1131
|
+
for (const disposable of this._tabGroupDisposables.values()) {
|
|
1132
|
+
disposable.dispose();
|
|
1133
|
+
}
|
|
1134
|
+
this._tabGroupDisposables.clear();
|
|
1135
|
+
// Dispose any microtask-deferred disposables that haven't run yet
|
|
1136
|
+
for (const disposable of this._pendingMicrotaskDisposables) {
|
|
1137
|
+
disposable.dispose();
|
|
1138
|
+
}
|
|
1139
|
+
this._pendingMicrotaskDisposables.clear();
|
|
684
1140
|
for (const panel of this.panels) {
|
|
685
1141
|
panel.dispose();
|
|
686
1142
|
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Event } from '../events';
|
|
2
|
+
import { IDisposable } from '../lifecycle';
|
|
3
|
+
import { IView, LayoutPriority } from '../splitview/splitview';
|
|
4
|
+
export type EdgeGroupPosition = 'top' | 'bottom' | 'left' | 'right';
|
|
5
|
+
export interface EdgeGroupOptions {
|
|
6
|
+
id: string;
|
|
7
|
+
initialSize?: number;
|
|
8
|
+
minimumSize?: number;
|
|
9
|
+
maximumSize?: number;
|
|
10
|
+
collapsedSize?: number;
|
|
11
|
+
collapsed?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface SerializedEdgeGroups {
|
|
14
|
+
top?: {
|
|
15
|
+
size: number;
|
|
16
|
+
visible: boolean;
|
|
17
|
+
collapsed?: boolean;
|
|
18
|
+
group?: unknown;
|
|
19
|
+
};
|
|
20
|
+
bottom?: {
|
|
21
|
+
size: number;
|
|
22
|
+
visible: boolean;
|
|
23
|
+
collapsed?: boolean;
|
|
24
|
+
group?: unknown;
|
|
25
|
+
};
|
|
26
|
+
left?: {
|
|
27
|
+
size: number;
|
|
28
|
+
visible: boolean;
|
|
29
|
+
collapsed?: boolean;
|
|
30
|
+
group?: unknown;
|
|
31
|
+
};
|
|
32
|
+
right?: {
|
|
33
|
+
size: number;
|
|
34
|
+
visible: boolean;
|
|
35
|
+
collapsed?: boolean;
|
|
36
|
+
group?: unknown;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Minimal interface for a edge group host.
|
|
41
|
+
* Avoids circular imports by not referencing DockviewGroupPanel directly.
|
|
42
|
+
*/
|
|
43
|
+
export interface IEdgeGroupHost {
|
|
44
|
+
readonly element: HTMLElement;
|
|
45
|
+
layout(width: number, height: number): void;
|
|
46
|
+
}
|
|
47
|
+
export declare class EdgeGroupView implements IView {
|
|
48
|
+
private readonly _group;
|
|
49
|
+
private readonly _orientation;
|
|
50
|
+
private readonly _onDidChange;
|
|
51
|
+
readonly onDidChange: Event<{
|
|
52
|
+
size?: number;
|
|
53
|
+
orthogonalSize?: number;
|
|
54
|
+
}>;
|
|
55
|
+
readonly snap = false;
|
|
56
|
+
readonly priority = LayoutPriority.Low;
|
|
57
|
+
private _isCollapsed;
|
|
58
|
+
private _lastExpandedSize;
|
|
59
|
+
private _collapsedSize;
|
|
60
|
+
private _expandedMinimumSize;
|
|
61
|
+
private readonly _expandedMaximumSize;
|
|
62
|
+
get minimumSize(): number;
|
|
63
|
+
get maximumSize(): number;
|
|
64
|
+
get element(): HTMLElement;
|
|
65
|
+
get isCollapsed(): boolean;
|
|
66
|
+
get lastExpandedSize(): number;
|
|
67
|
+
get collapsedSize(): number;
|
|
68
|
+
constructor(options: EdgeGroupOptions, group: IEdgeGroupHost, orientation: 'horizontal' | 'vertical');
|
|
69
|
+
layout(size: number, orthogonalSize: number): void;
|
|
70
|
+
setCollapsed(collapsed: boolean): void;
|
|
71
|
+
setVisible(_visible: boolean): void;
|
|
72
|
+
/**
|
|
73
|
+
* Restore the last-expanded size from serialized state without triggering
|
|
74
|
+
* a layout. Must be called before setCollapsed(true) during fromJSON so
|
|
75
|
+
* that expanding after deserialization restores the correct size.
|
|
76
|
+
*/
|
|
77
|
+
restoreExpandedSize(size: number): void;
|
|
78
|
+
/**
|
|
79
|
+
* Apply new effective collapsed and expanded-minimum sizes after a theme
|
|
80
|
+
* or gap change. The caller (ShellManager) is responsible for computing
|
|
81
|
+
* the correct values from the original config and the new gap.
|
|
82
|
+
*/
|
|
83
|
+
updateCollapsedSize(newCollapsedSize: number, newExpandedMinimumSize: number): void;
|
|
84
|
+
dispose(): void;
|
|
85
|
+
}
|
|
86
|
+
export declare class ShellManager implements IDisposable {
|
|
87
|
+
private readonly _outerSplitview;
|
|
88
|
+
private readonly _middleColumn;
|
|
89
|
+
private readonly _shellElement;
|
|
90
|
+
private _topView;
|
|
91
|
+
private _bottomView;
|
|
92
|
+
private _leftView;
|
|
93
|
+
private _rightView;
|
|
94
|
+
private _leftIndex;
|
|
95
|
+
private _middleIndex;
|
|
96
|
+
private _rightIndex;
|
|
97
|
+
private readonly _disposables;
|
|
98
|
+
private readonly _viewConfigs;
|
|
99
|
+
private _currentWidth;
|
|
100
|
+
private _currentHeight;
|
|
101
|
+
private _gap;
|
|
102
|
+
private _defaultCollapsedSize;
|
|
103
|
+
constructor(container: HTMLElement, dockviewElement: HTMLElement, layoutGrid: (width: number, height: number) => void, gap?: number, defaultCollapsedSize?: number);
|
|
104
|
+
get element(): HTMLElement;
|
|
105
|
+
/**
|
|
106
|
+
* Add an edge group view at the given position. The view wraps the
|
|
107
|
+
* provided group element inside the shell's splitview layout.
|
|
108
|
+
* Throws if a group at this position is already registered.
|
|
109
|
+
*/
|
|
110
|
+
addEdgeView(position: EdgeGroupPosition, options: EdgeGroupOptions, group: IEdgeGroupHost): EdgeGroupView;
|
|
111
|
+
layout(width: number, height: number): void;
|
|
112
|
+
/**
|
|
113
|
+
* Called when the active theme changes. Updates splitview margins and
|
|
114
|
+
* edge-group collapsed sizes so the layout matches the new theme's gap
|
|
115
|
+
* and tab-strip dimensions.
|
|
116
|
+
*/
|
|
117
|
+
updateTheme(gap: number, defaultCollapsedSize: number): void;
|
|
118
|
+
removeEdgeView(position: EdgeGroupPosition): void;
|
|
119
|
+
hasEdgeGroup(position: EdgeGroupPosition): boolean;
|
|
120
|
+
setEdgeGroupVisible(position: EdgeGroupPosition, visible: boolean): void;
|
|
121
|
+
isEdgeGroupVisible(position: EdgeGroupPosition): boolean;
|
|
122
|
+
setEdgeGroupCollapsed(position: EdgeGroupPosition, collapsed: boolean): void;
|
|
123
|
+
isEdgeGroupCollapsed(position: EdgeGroupPosition): boolean;
|
|
124
|
+
private _getView;
|
|
125
|
+
toJSON(): SerializedEdgeGroups;
|
|
126
|
+
fromJSON(data: SerializedEdgeGroups): void;
|
|
127
|
+
dispose(): void;
|
|
128
|
+
}
|