in src/vs/workbench/browser/parts/views/viewPaneContainer.ts [834:991]
private addPane(pane: ViewPane, size: number, index = this.paneItems.length - 1): void {
const onDidFocus = pane.onDidFocus(() => {
this._onDidFocusView.fire(pane);
this.lastFocusedPane = pane;
});
const onDidBlur = pane.onDidBlur(() => this._onDidBlurView.fire(pane));
const onDidChangeTitleArea = pane.onDidChangeTitleArea(() => {
if (this.isViewMergedWithContainer()) {
this.updateTitleArea();
}
});
const onDidChangeVisibility = pane.onDidChangeBodyVisibility(() => this._onDidChangeViewVisibility.fire(pane));
const onDidChange = pane.onDidChange(() => {
if (pane === this.lastFocusedPane && !pane.isExpanded()) {
this.lastFocusedPane = undefined;
}
});
const isPanel = this.viewDescriptorService.getViewContainerLocation(this.viewContainer) === ViewContainerLocation.Panel;
const paneStyler = attachStyler<IPaneColors>(this.themeService, {
headerForeground: isPanel ? PANEL_SECTION_HEADER_FOREGROUND : SIDE_BAR_SECTION_HEADER_FOREGROUND,
headerBackground: isPanel ? PANEL_SECTION_HEADER_BACKGROUND : SIDE_BAR_SECTION_HEADER_BACKGROUND,
headerBorder: isPanel ? PANEL_SECTION_HEADER_BORDER : SIDE_BAR_SECTION_HEADER_BORDER,
dropBackground: isPanel ? PANEL_SECTION_DRAG_AND_DROP_BACKGROUND : SIDE_BAR_DRAG_AND_DROP_BACKGROUND,
leftBorder: isPanel ? PANEL_SECTION_BORDER : undefined
}, pane);
const disposable = combinedDisposable(pane, onDidFocus, onDidBlur, onDidChangeTitleArea, paneStyler, onDidChange, onDidChangeVisibility);
const paneItem: IViewPaneItem = { pane, disposable };
this.paneItems.splice(index, 0, paneItem);
assertIsDefined(this.paneview).addPane(pane, size, index);
let overlay: ViewPaneDropOverlay | undefined;
this._register(CompositeDragAndDropObserver.INSTANCE.registerDraggable(pane.draggableElement, () => { return { type: 'view', id: pane.id }; }, {}));
this._register(CompositeDragAndDropObserver.INSTANCE.registerTarget(pane.dropTargetElement, {
onDragEnter: (e) => {
if (!overlay) {
const dropData = e.dragAndDropData.getData();
if (dropData.type === 'view' && dropData.id !== pane.id) {
const oldViewContainer = this.viewDescriptorService.getViewContainerByViewId(dropData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptorById(dropData.id);
if (oldViewContainer !== this.viewContainer && (!viewDescriptor || !viewDescriptor.canMoveView || this.viewContainer.rejectAddedViews)) {
return;
}
overlay = new ViewPaneDropOverlay(pane.dropTargetElement, this.orientation ?? Orientation.VERTICAL, undefined, this.viewDescriptorService.getViewContainerLocation(this.viewContainer)!, this.themeService);
}
if (dropData.type === 'composite' && dropData.id !== this.viewContainer.id && !this.viewContainer.rejectAddedViews) {
const container = this.viewDescriptorService.getViewContainerById(dropData.id)!;
const viewsToMove = this.viewDescriptorService.getViewContainerModel(container).allViewDescriptors;
if (!viewsToMove.some(v => !v.canMoveView) && viewsToMove.length > 0) {
overlay = new ViewPaneDropOverlay(pane.dropTargetElement, this.orientation ?? Orientation.VERTICAL, undefined, this.viewDescriptorService.getViewContainerLocation(this.viewContainer)!, this.themeService);
}
}
}
},
onDragOver: (e) => {
toggleDropEffect(e.eventData.dataTransfer, 'move', overlay !== undefined);
},
onDragLeave: (e) => {
overlay?.dispose();
overlay = undefined;
},
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 && !this.viewContainer.rejectAddedViews) {
const container = this.viewDescriptorService.getViewContainerById(dropData.id)!;
const allViews = this.viewDescriptorService.getViewContainerModel(container).allViewDescriptors;
if (allViews.length > 0 && !allViews.some(v => !v.canMoveView)) {
viewsToMove.push(...allViews);
anchorView = allViews[0];
}
} else if (dropData.type === 'view') {
const oldViewContainer = this.viewDescriptorService.getViewContainerByViewId(dropData.id);
const viewDescriptor = this.viewDescriptorService.getViewDescriptorById(dropData.id);
if (oldViewContainer !== this.viewContainer && viewDescriptor && viewDescriptor.canMoveView && !this.viewContainer.rejectAddedViews) {
viewsToMove.push(viewDescriptor);
}
if (viewDescriptor) {
anchorView = viewDescriptor;
}
}
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 === anchorView!.id);
let toIndex = this.panes.findIndex(p => p.id === pane.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]);
}
}
}
if (overlay.currentDropOperation === DropDirection.UP ||
overlay.currentDropOperation === DropDirection.LEFT) {
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) {
if (fromIndex < toIndex) {
toIndex--;
}
if (toIndex >= 0 && toIndex !== fromIndex) {
this.movePane(this.panes[fromIndex], this.panes[toIndex]);
}
}
}
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;
}
}
});
}
}
}
overlay?.dispose();
overlay = undefined;
}
}));
}