diff --git a/src/vs/workbench/browser/parts/compositeBar.ts b/src/vs/workbench/browser/parts/compositeBar.ts index 64e86c9a814..5e7e155f34a 100644 --- a/src/vs/workbench/browser/parts/compositeBar.ts +++ b/src/vs/workbench/browser/parts/compositeBar.ts @@ -42,7 +42,7 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop { private moveComposite: (from: string, to: string, before?: Before2D) => void, ) { } - drop(data: CompositeDragAndDropData, targetCompositeId: string | undefined, originalEvent: DragEvent, before?: Before2D): void { + drop(data: CompositeDragAndDropData, targetCompositeId: string, originalEvent: DragEvent, before?: Before2D): void { const dragData = data.getData(); const viewContainerRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); @@ -50,57 +50,48 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop { const currentContainer = viewContainerRegistry.get(dragData.id)!; const currentLocation = viewContainerRegistry.getViewContainerLocation(currentContainer); - // Inserting a composite between composites - if (targetCompositeId) { - // ... on the same composite bar - if (currentLocation === this.targetContainerLocation) { - this.moveComposite(dragData.id, targetCompositeId, before); + // ... on the same composite bar + if (currentLocation === this.targetContainerLocation) { + this.moveComposite(dragData.id, targetCompositeId, before); + } + // ... on a different composite bar + else { + const viewsToMove = this.viewDescriptorService.getViewDescriptors(currentContainer)!.allViewDescriptors; + if (viewsToMove.some(v => !v.canMoveView)) { + return; } - // ... on a different composite bar - else { - const viewsToMove = this.viewDescriptorService.getViewDescriptors(currentContainer)!.allViewDescriptors.filter(vd => vd.canMoveView); - if (viewsToMove.length === 1) { - this.viewDescriptorService.moveViewToLocation(viewsToMove[0], this.targetContainerLocation); - const newContainer = this.viewDescriptorService.getViewContainer(viewsToMove[0].id)!; + this.viewDescriptorService.moveViewToLocation(viewsToMove[0], this.targetContainerLocation); + const newContainer = this.viewDescriptorService.getViewContainer(viewsToMove[0].id)!; + this.moveComposite(newContainer.id, targetCompositeId, before); - this.moveComposite(newContainer.id, targetCompositeId, before); + if (viewsToMove.length > 1) { + this.viewDescriptorService.moveViewsToContainer(viewsToMove.slice(1), newContainer); + } - this.openComposite(newContainer.id, true).then(composite => { - if (composite && viewsToMove.length === 1) { - composite.openView(viewsToMove[0].id, true); - } - }); + this.openComposite(newContainer.id, true).then(composite => { + if (composite && viewsToMove.length === 1) { + composite.openView(viewsToMove[0].id, true); } - } - } else { - const draggedViews = this.viewDescriptorService.getViewDescriptors(currentContainer).allViewDescriptors; - if (draggedViews.length === 1 && draggedViews[0].canMoveView) { - dragData.type = 'view'; - dragData.id = draggedViews[0].id; - } + }); } } if (dragData.type === 'view') { - if (targetCompositeId) { - const viewToMove = this.viewDescriptorService.getViewDescriptor(dragData.id)!; + const viewToMove = this.viewDescriptorService.getViewDescriptor(dragData.id)!; - if (viewToMove && viewToMove.canMoveView) { - this.viewDescriptorService.moveViewToLocation(viewToMove, this.targetContainerLocation); + if (viewToMove && viewToMove.canMoveView) { + this.viewDescriptorService.moveViewToLocation(viewToMove, this.targetContainerLocation); - const newContainer = this.viewDescriptorService.getViewContainer(viewToMove.id)!; + const newContainer = this.viewDescriptorService.getViewContainer(viewToMove.id)!; - this.moveComposite(newContainer.id, targetCompositeId, before); - - this.openComposite(newContainer.id, true).then(composite => { - if (composite) { - composite.openView(viewToMove.id, true); - } - }); - } - } else { + this.moveComposite(newContainer.id, targetCompositeId, before); + this.openComposite(newContainer.id, true).then(composite => { + if (composite) { + composite.openView(viewToMove.id, true); + } + }); } } } @@ -129,12 +120,9 @@ export class CompositeDragAndDrop implements ICompositeDragAndDrop { // ... to another composite location const draggedViews = this.viewDescriptorService.getViewDescriptors(currentContainer)!.allViewDescriptors; - if (draggedViews.length !== 1) { - return false; - } - // ... single view - return !!draggedViews[0].canMoveView; + // ... all views must be movable + return !draggedViews.some(v => !v.canMoveView); } else { // Dragging an individual view const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dragData.id); diff --git a/src/vs/workbench/browser/parts/views/viewPaneContainer.ts b/src/vs/workbench/browser/parts/views/viewPaneContainer.ts index eb444c5f83d..230cbc79552 100644 --- a/src/vs/workbench/browser/parts/views/viewPaneContainer.ts +++ b/src/vs/workbench/browser/parts/views/viewPaneContainer.ts @@ -828,7 +828,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { const oldViewContainer = this.viewDescriptorService.getViewContainer(dropData.id); const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dropData.id); - if (oldViewContainer !== this.viewContainer && (!viewDescriptor || !viewDescriptor.canMoveView)) { + if (oldViewContainer !== this.viewContainer && (!viewDescriptor || !viewDescriptor.canMoveView || this.viewContainer.rejectAddedViews)) { return; } @@ -841,7 +841,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { const container = viewContainerRegistry.get(dropData.id)!; const viewsToMove = this.viewDescriptorService.getViewDescriptors(container).allViewDescriptors; - if (viewsToMove.length === 1 && viewsToMove[0].canMoveView) { + if (!viewsToMove.some(v => !v.canMoveView)) { overlay = new ViewPaneDropOverlay(parent, undefined, this.themeService); } } @@ -855,27 +855,27 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { onDrop: (e) => { if (overlay) { const dropData = e.dragAndDropData.getData(); + const viewsToMove: IViewDescriptor[] = []; if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id) { const viewContainerRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); const container = viewContainerRegistry.get(dropData.id)!; - const viewsToMove = this.viewDescriptorService.getViewDescriptors(container).allViewDescriptors; - - if (viewsToMove.length === 1 && viewsToMove[0].canMoveView) { - dropData.type = 'view'; - dropData.id = viewsToMove[0].id; + const allViews = this.viewDescriptorService.getViewDescriptors(container).allViewDescriptors; + if (!allViews.some(v => !v.canMoveView)) { + viewsToMove.push(...allViews); } - } - - if (dropData.type === 'view') { - + } else if (dropData.type === 'view') { const oldViewContainer = this.viewDescriptorService.getViewContainer(dropData.id); const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dropData.id); if (oldViewContainer !== this.viewContainer && viewDescriptor && viewDescriptor.canMoveView) { this.viewDescriptorService.moveViewsToContainer([viewDescriptor], this.viewContainer); } } + + if (viewsToMove.length > 0) { + this.viewDescriptorService.moveViewsToContainer(viewsToMove, this.viewContainer); + } } overlay?.dispose(); @@ -1261,24 +1261,23 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { const oldViewContainer = this.viewDescriptorService.getViewContainer(dropData.id); const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dropData.id); - if (oldViewContainer !== this.viewContainer && (!viewDescriptor || !viewDescriptor.canMoveView)) { + if (oldViewContainer !== this.viewContainer && (!viewDescriptor || !viewDescriptor.canMoveView || this.viewContainer.rejectAddedViews)) { return; } overlay = new ViewPaneDropOverlay(pane.dropTargetElement, this.orientation ?? Orientation.VERTICAL, this.themeService); } - if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id) { + if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id && !this.viewContainer.rejectAddedViews) { const viewContainerRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); const container = viewContainerRegistry.get(dropData.id)!; const viewsToMove = this.viewDescriptorService.getViewDescriptors(container).allViewDescriptors; - if (viewsToMove.length === 1 && viewsToMove[0].canMoveView) { + if (!viewsToMove.some(v => !v.canMoveView)) { overlay = new ViewPaneDropOverlay(pane.dropTargetElement, this.orientation ?? Orientation.VERTICAL, this.themeService); } } - } }, onDragLeave: (e) => { @@ -1288,31 +1287,40 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { onDrop: (e) => { if (overlay) { const dropData = e.dragAndDropData.getData(); + const viewsToMove: IViewDescriptor[] = []; + let anchorView: IViewDescriptor | undefined; - if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id) { + if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id && !this.viewContainer.rejectAddedViews) { const viewContainerRegistry = Registry.as(ViewContainerExtensions.ViewContainersRegistry); const container = viewContainerRegistry.get(dropData.id)!; - const viewsToMove = this.viewDescriptorService.getViewDescriptors(container).allViewDescriptors; + const allViews = this.viewDescriptorService.getViewDescriptors(container).allViewDescriptors; - if (viewsToMove.length === 1 && viewsToMove[0].canMoveView) { - dropData.type = 'view'; - dropData.id = viewsToMove[0].id; + if (allViews.length > 0 && !allViews.some(v => !v.canMoveView)) { + viewsToMove.push(...allViews); + anchorView = allViews[0]; + } + } else if (dropData.type === 'view') { + const oldViewContainer = this.viewDescriptorService.getViewContainer(dropData.id); + const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dropData.id); + if (oldViewContainer !== this.viewContainer && viewDescriptor && viewDescriptor.canMoveView && !this.viewContainer.rejectAddedViews) { + viewsToMove.push(viewDescriptor); + } + + if (viewDescriptor) { + anchorView = viewDescriptor; } } - if (dropData.type === 'view') { - - const oldViewContainer = this.viewDescriptorService.getViewContainer(dropData.id); - const viewDescriptor = this.viewDescriptorService.getViewDescriptor(dropData.id); - if (oldViewContainer !== this.viewContainer && viewDescriptor && viewDescriptor.canMoveView) { - this.viewDescriptorService.moveViewsToContainer([viewDescriptor], this.viewContainer); - } + if (viewsToMove) { + this.viewDescriptorService.moveViewsToContainer(viewsToMove, this.viewContainer); + } + if (anchorView) { if (overlay.currentDropOperation === DropDirection.DOWN || overlay.currentDropOperation === DropDirection.RIGHT) { - const fromIndex = this.panes.findIndex(p => p.id === dropData.id); + const fromIndex = this.panes.findIndex(p => p.id === anchorView!.id); let toIndex = this.panes.findIndex(p => p.id === pane.id); if (fromIndex >= 0 && toIndex >= 0) { @@ -1328,7 +1336,7 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { if (overlay.currentDropOperation === DropDirection.UP || overlay.currentDropOperation === DropDirection.LEFT) { - const fromIndex = this.panes.findIndex(p => p.id === dropData.id); + const fromIndex = this.panes.findIndex(p => p.id === anchorView!.id); let toIndex = this.panes.findIndex(p => p.id === pane.id); if (fromIndex >= 0 && toIndex >= 0) { @@ -1341,6 +1349,23 @@ export class ViewPaneContainer extends Component implements IViewPaneContainer { } } } + + if (viewsToMove.length > 1) { + viewsToMove.slice(1).forEach(view => { + let toIndex = this.panes.findIndex(p => p.id === anchorView!.id); + let fromIndex = this.panes.findIndex(p => p.id === view.id); + if (fromIndex >= 0 && toIndex >= 0) { + if (fromIndex > toIndex) { + toIndex++; + } + + if (toIndex < this.panes.length && toIndex !== fromIndex) { + this.movePane(this.panes[fromIndex], this.panes[toIndex]); + anchorView = view; + } + } + }); + } } }