diff --git a/packages/dockview/src/dnd/groupDragHandler.ts b/packages/dockview/src/dnd/groupDragHandler.ts new file mode 100644 index 000000000..28ab895a0 --- /dev/null +++ b/packages/dockview/src/dnd/groupDragHandler.ts @@ -0,0 +1,60 @@ +import { GroupPanel } from '../groupview/groupviewPanel'; +import { IDisposable } from '../lifecycle'; +import { DragHandler } from './abstractDragHandler'; +import { LocalSelectionTransfer, PanelTransfer } from './dataTransfer'; +import { addGhostImage } from './ghost'; + +export class GroupDragHandler extends DragHandler { + private readonly panelTransfer = + LocalSelectionTransfer.getInstance(); + + constructor( + element: HTMLElement, + private readonly accessorId: string, + private readonly group: GroupPanel + ) { + super(element); + } + + getData(dataTransfer: DataTransfer | null): IDisposable { + this.panelTransfer.setData( + [new PanelTransfer(this.accessorId, this.group.id, null)], + PanelTransfer.prototype + ); + + const style = window.getComputedStyle(this.el); + + const bgColor = style.getPropertyValue( + '--dv-activegroup-visiblepanel-tab-background-color' + ); + const color = style.getPropertyValue( + '--dv-activegroup-visiblepanel-tab-color' + ); + + if (dataTransfer) { + const ghostElement = document.createElement('div'); + + ghostElement.style.backgroundColor = bgColor; + ghostElement.style.color = color; + ghostElement.style.padding = '2px 8px'; + ghostElement.style.height = '24px'; + ghostElement.style.fontSize = '11px'; + ghostElement.style.lineHeight = '20px'; + ghostElement.style.borderRadius = '12px'; + ghostElement.style.position = 'absolute'; + ghostElement.textContent = `Multiple Panels (${this.group.size})`; + + addGhostImage(dataTransfer, ghostElement); + } + + return { + dispose: () => { + this.panelTransfer.clearData(PanelTransfer.prototype); + }, + }; + } + + public dispose(): void { + // + } +} diff --git a/packages/dockview/src/dockview/dockviewComponent.ts b/packages/dockview/src/dockview/dockviewComponent.ts index 2867e8fd2..ee3881794 100644 --- a/packages/dockview/src/dockview/dockviewComponent.ts +++ b/packages/dockview/src/dockview/dockviewComponent.ts @@ -575,38 +575,9 @@ export class DockviewComponent if(itemId === undefined) { - - if(sourceGroup) { - if (!target || target === Position.Center) { - const activePanel = sourceGroup.activePanel; - const panels = [...sourceGroup.panels].map(p => sourceGroup.model.removePanel(p.id)); - - if (sourceGroup?.model.size === 0) { - this.doRemoveGroup(sourceGroup); - } - - for(const panel of panels) { - referenceGroup.model.openPanel(panel,{skipSetPanelActive:panel !== activePanel}); - } - } - else { - - this.gridview.removeView(getGridLocation(sourceGroup.element)); - - const referenceLocation = getGridLocation(referenceGroup.element); - const dropLocation = getRelativeLocation( - this.gridview.orientation, - referenceLocation, - target - ); - - - - this.gridview.addView(sourceGroup, Sizing.Distribute, dropLocation); - } + this.moveGroup(sourceGroup, referenceGroup, target); } - return; } @@ -684,6 +655,38 @@ export class DockviewComponent } } + private moveGroup(sourceGroup: GroupPanel, referenceGroup: GroupPanel, target: Position): void { + if(sourceGroup) { + if (!target || target === Position.Center) { + const activePanel = sourceGroup.activePanel; + const panels = [...sourceGroup.panels].map(p => sourceGroup.model.removePanel(p.id)); + + if (sourceGroup?.model.size === 0) { + this.doRemoveGroup(sourceGroup); + } + + for(const panel of panels) { + referenceGroup.model.openPanel(panel,{skipSetPanelActive:panel !== activePanel}); + } + } + else { + + this.gridview.removeView(getGridLocation(sourceGroup.element)); + + const referenceLocation = getGridLocation(referenceGroup.element); + const dropLocation = getRelativeLocation( + this.gridview.orientation, + referenceLocation, + target + ); + + + + this.gridview.addView(sourceGroup, Sizing.Distribute, dropLocation); + } + } + } + override doSetGroupActive( group: GroupPanel | undefined, skipFocus?: boolean diff --git a/packages/dockview/src/groupview/groupview.ts b/packages/dockview/src/groupview/groupview.ts index ecb56cdf2..5b7735321 100644 --- a/packages/dockview/src/groupview/groupview.ts +++ b/packages/dockview/src/groupview/groupview.ts @@ -699,7 +699,9 @@ export class Groupview extends CompositeDisposable implements IGroupview { if (data) { if (data.panelId === null) { + // this is a group move dnd event const { groupId } = data; + this._onMove.fire({ target: position, groupId: groupId, diff --git a/packages/dockview/src/groupview/titlebar/voidContainer.ts b/packages/dockview/src/groupview/titlebar/voidContainer.ts index c140001d6..8eadede55 100644 --- a/packages/dockview/src/groupview/titlebar/voidContainer.ts +++ b/packages/dockview/src/groupview/titlebar/voidContainer.ts @@ -1,73 +1,13 @@ import { last } from '../../array'; -import { DragHandler } from '../../dnd/abstractDragHandler'; -import { - getPanelData, - LocalSelectionTransfer, - PanelTransfer, -} from '../../dnd/dataTransfer'; +import { getPanelData } from '../../dnd/dataTransfer'; import { Droptarget, DroptargetEvent } from '../../dnd/droptarget'; -import { addGhostImage } from '../../dnd/ghost'; +import { GroupDragHandler } from '../../dnd/groupDragHandler'; import { DockviewComponent } from '../../dockview/dockviewComponent'; import { addDisposableListener, Emitter, Event } from '../../events'; -import { CompositeDisposable, IDisposable } from '../../lifecycle'; +import { CompositeDisposable } from '../../lifecycle'; import { DockviewDropTargets } from '../dnd'; import { GroupPanel } from '../groupviewPanel'; -class CustomDragHandler extends DragHandler { - private readonly panelTransfer = - LocalSelectionTransfer.getInstance(); - - constructor( - element: HTMLElement, - private readonly accessorId: string, - private readonly group: GroupPanel - ) { - super(element); - } - - getData(dataTransfer: DataTransfer | null): IDisposable { - this.panelTransfer.setData( - [new PanelTransfer(this.accessorId, this.group.id, null)], - PanelTransfer.prototype - ); - - const style = window.getComputedStyle(this.el); - - const bgColor = style.getPropertyValue( - '--dv-activegroup-visiblepanel-tab-background-color' - ); - const color = style.getPropertyValue( - '--dv-activegroup-visiblepanel-tab-color' - ); - - if (dataTransfer) { - const ghostElement = document.createElement('div'); - - ghostElement.style.backgroundColor = bgColor; - ghostElement.style.color = color; - ghostElement.style.padding = '2px 8px'; - ghostElement.style.height = '24px'; - ghostElement.style.fontSize = '11px'; - ghostElement.style.lineHeight = '20px'; - ghostElement.style.borderRadius = '12px'; - ghostElement.style.position = 'absolute'; - ghostElement.textContent = `Multiple Panels (${this.group.size})`; - - addGhostImage(dataTransfer, ghostElement); - } - - return { - dispose: () => { - this.panelTransfer.clearData(PanelTransfer.prototype); - }, - }; - } - - public dispose(): void { - // - } -} - export class VoidContainer extends CompositeDisposable { private readonly _element: HTMLElement; private readonly voidDropTarget: Droptarget; @@ -98,11 +38,7 @@ export class VoidContainer extends CompositeDisposable { }) ); - const handler = new CustomDragHandler( - this._element, - accessor.id, - group - ); + const handler = new GroupDragHandler(this._element, accessor.id, group); this.voidDropTarget = new Droptarget(this._element, { validOverlays: 'none',