diff --git a/src/vs/base/browser/dnd.ts b/src/vs/base/browser/dnd.ts index a51f6e64b8e..e7703182722 100644 --- a/src/vs/base/browser/dnd.ts +++ b/src/vs/base/browser/dnd.ts @@ -83,4 +83,17 @@ export function applyDragImage(event: DragEvent, label: string, clazz: string): // Removes the element when the DND operation is done setTimeout(() => document.body.removeChild(dragImage), 0); } -} \ No newline at end of file +} + +export interface IDragAndDropData { + update(dataTransfer: DataTransfer): void; + getData(): any; +} + +export interface IStaticDND { + CurrentDragAndDropData: IDragAndDropData | undefined; +} + +export const StaticDND: IStaticDND = { + CurrentDragAndDropData: undefined +}; \ No newline at end of file diff --git a/src/vs/base/browser/ui/list/list.ts b/src/vs/base/browser/ui/list/list.ts index 7933bcda6b9..7c314a89ad2 100644 --- a/src/vs/base/browser/ui/list/list.ts +++ b/src/vs/base/browser/ui/list/list.ts @@ -7,6 +7,7 @@ import { GestureEvent } from 'vs/base/browser/touch'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { Event } from 'vs/base/common/event'; import { IDisposable } from 'vs/base/common/lifecycle'; +import { IDragAndDropData } from 'vs/base/browser/dnd'; export interface IListVirtualDelegate { getHeight(element: T): number; @@ -95,17 +96,12 @@ export const DragOverReactions = { // acceptCopyBubbleDown(autoExpand = false): IDragOverReaction { return { accept: true, bubble: DragOverBubble.Down, effect: DragOverEffect.Copy, autoExpand }; } }; -export interface IDragAndDropData { - update(dataTransfer: DataTransfer): void; - getData(): any; -} - export interface IDragAndDrop { getDragURI(element: T): string | null; getDragLabel?(elements: T[]): string; onDragStart(data: IDragAndDropData, originalEvent: DragEvent): void; onDragOver(data: IDragAndDropData, targetElement: T | undefined, targetIndex: number | undefined, originalEvent: DragEvent): boolean | IDragOverReaction; - drop(data: IDragAndDropData, targetElement: T | undefined, originalEvent: DragEvent): void; + drop(data: IDragAndDropData, targetElement: T | undefined, targetIndex: number | undefined, originalEvent: DragEvent): void; } /** diff --git a/src/vs/base/browser/ui/list/listView.ts b/src/vs/base/browser/ui/list/listView.ts index c815b43f35b..48b8eb36324 100644 --- a/src/vs/base/browser/ui/list/listView.ts +++ b/src/vs/base/browser/ui/list/listView.ts @@ -12,7 +12,7 @@ import { domEvent } from 'vs/base/browser/event'; import { ScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement'; import { ScrollEvent, ScrollbarVisibility, INewScrollDimensions } from 'vs/base/common/scrollable'; import { RangeMap, shift } from './rangeMap'; -import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListTouchEvent, IListGestureEvent, IListDragEvent, IDragAndDrop, IDragAndDropData } from './list'; +import { IListVirtualDelegate, IListRenderer, IListMouseEvent, IListTouchEvent, IListGestureEvent, IListDragEvent, IDragAndDrop, DragOverEffect } from './list'; import { RowCache, IRow } from './rowCache'; import { isWindows } from 'vs/base/common/platform'; import * as browser from 'vs/base/browser/browser'; @@ -20,7 +20,7 @@ import { ISpliceable } from 'vs/base/common/sequence'; import { memoize } from 'vs/base/common/decorators'; import { Range, IRange } from 'vs/base/common/range'; import { equals, distinct } from 'vs/base/common/arrays'; -import { DataTransfers } from 'vs/base/browser/dnd'; +import { DataTransfers, StaticDND, IDragAndDropData } from 'vs/base/browser/dnd'; function canUseTranslate3d(): boolean { if (browser.isFirefox) { @@ -154,8 +154,6 @@ function equalsDragFeedback(f1: number[] | undefined, f2: number[] | undefined): export class ListView implements ISpliceable, IDisposable { - private static currentExternalDragAndDropData: IDragAndDropData | undefined; - readonly domNode: HTMLElement; private items: IItem[]; @@ -629,14 +627,12 @@ export class ListView implements ISpliceable, IDisposable { } this.currentDragData = new ElementsDragAndDropData(elements); - ListView.currentExternalDragAndDropData = new ExternalElementsDragAndDropData(elements); + StaticDND.CurrentDragAndDropData = new ExternalElementsDragAndDropData(elements); this.dnd.onDragStart(this.currentDragData, event); } private onDragOver(event: IListDragEvent): boolean { - console.log('DRAG OVER'); - this.onDragLeaveTimeout.dispose(); this.setupDragAndDropScrollTopAnimation(event.browserEvent); @@ -646,9 +642,9 @@ export class ListView implements ISpliceable, IDisposable { // Drag over from outside if (!this.currentDragData) { - if (ListView.currentExternalDragAndDropData) { + if (StaticDND.CurrentDragAndDropData) { // Drag over from another list - this.currentDragData = ListView.currentExternalDragAndDropData; + this.currentDragData = StaticDND.CurrentDragAndDropData; } else { // Drag over from the desktop @@ -662,12 +658,13 @@ export class ListView implements ISpliceable, IDisposable { const result = this.dnd.onDragOver(this.currentDragData, event.element, event.index, event.browserEvent); const canDrop = typeof result === 'boolean' ? result : result.accept; - // const reaction = (typeof result !== 'boolean' && result.effect === DragOverEffect.Copy) ? 'copy' : 'move'; if (!canDrop) { return false; } + event.browserEvent.dataTransfer.dropEffect = (typeof result !== 'boolean' && result.effect === DragOverEffect.Copy) ? 'copy' : 'move'; + let feedback: number[]; if (typeof result !== 'boolean' && result.feedback) { @@ -692,8 +689,6 @@ export class ListView implements ISpliceable, IDisposable { return true; } - console.log(this.currentDragFeedback, feedback); - this.currentDragFeedback = feedback; this.currentDragFeedbackDisposable.dispose(); @@ -725,21 +720,31 @@ export class ListView implements ISpliceable, IDisposable { return true; } - private onDragLeave(event: DragEvent): void { - console.log('LEAVE'); + private onDragLeave(): void { this.onDragLeaveTimeout = DOM.timeout(() => this.clearDragOverFeedback(), 100); } - private onDrop(e: IListDragEvent): void { - console.log('DROP'); + private onDrop(event: IListDragEvent): void { + const dragData = this.currentDragData; this.teardownDragAndDropScrollTopAnimation(); this.clearDragOverFeedback(); + this.currentDragData = undefined; + StaticDND.CurrentDragAndDropData = undefined; + + if (!dragData || !event.browserEvent.dataTransfer) { + return; + } + + event.browserEvent.preventDefault(); + dragData.update(event.browserEvent.dataTransfer); + this.dnd.drop(dragData, event.element, event.index, event.browserEvent); } private onDragEnd(): void { - console.log('DRAG END'); this.teardownDragAndDropScrollTopAnimation(); this.clearDragOverFeedback(); + this.currentDragData = undefined; + StaticDND.CurrentDragAndDropData = undefined; } private clearDragOverFeedback(): void { diff --git a/src/vs/base/browser/ui/tree/abstractTree.ts b/src/vs/base/browser/ui/tree/abstractTree.ts index 494fcef7b0e..6e2235e2be6 100644 --- a/src/vs/base/browser/ui/tree/abstractTree.ts +++ b/src/vs/base/browser/ui/tree/abstractTree.ts @@ -35,8 +35,8 @@ function asListOptions(options?: IAbstractTreeOptions(options?: IAsyncDataTreeOpt onDragOver(data, targetNode, targetIndex, originalEvent) { return options.dnd!.onDragOver(data, targetNode && targetNode.element as T, targetIndex, originalEvent); }, - drop(data, targetNode, originalEvent) { - return options.dnd!.drop(data, targetNode && targetNode.element as T, originalEvent); + drop(data, targetNode, targetIndex, originalEvent) { + return options.dnd!.drop(data, targetNode && targetNode.element as T, targetIndex, originalEvent); } }, multipleSelectionController: options.multipleSelectionController && { diff --git a/src/vs/base/parts/tree/browser/tree.ts b/src/vs/base/parts/tree/browser/tree.ts index 0a933b6c663..1de72e5670b 100644 --- a/src/vs/base/parts/tree/browser/tree.ts +++ b/src/vs/base/parts/tree/browser/tree.ts @@ -12,6 +12,7 @@ import { Event } from 'vs/base/common/event'; import { IAction, IActionItem } from 'vs/base/common/actions'; import { Color } from 'vs/base/common/color'; import { IItemCollapseEvent, IItemExpandEvent } from 'vs/base/parts/tree/browser/treeModel'; +import { IDragAndDropData } from 'vs/base/browser/dnd'; export interface ITree { @@ -593,11 +594,6 @@ export const DRAG_OVER_ACCEPT_BUBBLE_DOWN = (autoExpand = false) => ({ accept: t export const DRAG_OVER_ACCEPT_BUBBLE_UP_COPY: IDragOverReaction = { accept: true, bubble: DragOverBubble.BUBBLE_UP, effect: DragOverEffect.COPY }; export const DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY = (autoExpand = false) => ({ accept: true, bubble: DragOverBubble.BUBBLE_DOWN, effect: DragOverEffect.COPY, autoExpand }); -export interface IDragAndDropData { - update(event: Mouse.DragMouseEvent): void; - getData(): any; -} - export interface IDragAndDrop { /** diff --git a/src/vs/base/parts/tree/browser/treeDefaults.ts b/src/vs/base/parts/tree/browser/treeDefaults.ts index 03fd5c05780..1b83c5179b8 100644 --- a/src/vs/base/parts/tree/browser/treeDefaults.ts +++ b/src/vs/base/parts/tree/browser/treeDefaults.ts @@ -13,6 +13,7 @@ import * as mouse from 'vs/base/browser/mouseEvent'; import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import * as _ from 'vs/base/parts/tree/browser/tree'; import { KeyCode, KeyMod, Keybinding, createKeybinding, SimpleKeybinding, createSimpleKeybinding } from 'vs/base/common/keyCodes'; +import { IDragAndDropData } from 'vs/base/browser/dnd'; export interface IKeyBindingCallback { (tree: _.ITree, event: IKeyboardEvent): void; @@ -434,15 +435,15 @@ export class DefaultDragAndDrop implements _.IDragAndDrop { return null; } - public onDragStart(tree: _.ITree, data: _.IDragAndDropData, originalEvent: mouse.DragMouseEvent): void { + public onDragStart(tree: _.ITree, data: IDragAndDropData, originalEvent: mouse.DragMouseEvent): void { return; } - public onDragOver(tree: _.ITree, data: _.IDragAndDropData, targetElement: any, originalEvent: mouse.DragMouseEvent): _.IDragOverReaction | null { + public onDragOver(tree: _.ITree, data: IDragAndDropData, targetElement: any, originalEvent: mouse.DragMouseEvent): _.IDragOverReaction | null { return null; } - public drop(tree: _.ITree, data: _.IDragAndDropData, targetElement: any, originalEvent: mouse.DragMouseEvent): void { + public drop(tree: _.ITree, data: IDragAndDropData, targetElement: any, originalEvent: mouse.DragMouseEvent): void { return; } } diff --git a/src/vs/base/parts/tree/browser/treeDnd.ts b/src/vs/base/parts/tree/browser/treeDnd.ts index 5ba6467296b..810e6ce98ee 100644 --- a/src/vs/base/parts/tree/browser/treeDnd.ts +++ b/src/vs/base/parts/tree/browser/treeDnd.ts @@ -4,9 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import * as _ from 'vs/base/parts/tree/browser/tree'; -import * as Mouse from 'vs/base/browser/mouseEvent'; +import { IDragAndDropData } from 'vs/base/browser/dnd'; -export class ElementsDragAndDropData implements _.IDragAndDropData { +export class ElementsDragAndDropData implements IDragAndDropData { private elements: any[]; @@ -14,7 +14,7 @@ export class ElementsDragAndDropData implements _.IDragAndDropData { this.elements = elements; } - public update(event: Mouse.DragMouseEvent): void { + public update(dataTransfer: DataTransfer): void { // no-op } @@ -23,7 +23,7 @@ export class ElementsDragAndDropData implements _.IDragAndDropData { } } -export class ExternalElementsDragAndDropData implements _.IDragAndDropData { +export class ExternalElementsDragAndDropData implements IDragAndDropData { private elements: any[]; @@ -31,7 +31,7 @@ export class ExternalElementsDragAndDropData implements _.IDragAndDropData { this.elements = elements; } - public update(event: Mouse.DragMouseEvent): void { + public update(dataTransfer: DataTransfer): void { // no-op } @@ -40,7 +40,7 @@ export class ExternalElementsDragAndDropData implements _.IDragAndDropData { } } -export class DesktopDragAndDropData implements _.IDragAndDropData { +export class DesktopDragAndDropData implements IDragAndDropData { private types: any[]; private files: any[]; @@ -50,15 +50,15 @@ export class DesktopDragAndDropData implements _.IDragAndDropData { this.files = []; } - public update(event: Mouse.DragMouseEvent): void { - if (event.dataTransfer.types) { + public update(dataTransfer: DataTransfer): void { + if (dataTransfer.types) { this.types = []; - Array.prototype.push.apply(this.types, event.dataTransfer.types); + Array.prototype.push.apply(this.types, dataTransfer.types as any); } - if (event.dataTransfer.files) { + if (dataTransfer.files) { this.files = []; - Array.prototype.push.apply(this.files, event.dataTransfer.files); + Array.prototype.push.apply(this.files, dataTransfer.files as any); this.files = this.files.filter(f => f.size || f.type); } diff --git a/src/vs/base/parts/tree/browser/treeView.ts b/src/vs/base/parts/tree/browser/treeView.ts index 144344684ea..c61ec47be8b 100644 --- a/src/vs/base/parts/tree/browser/treeView.ts +++ b/src/vs/base/parts/tree/browser/treeView.ts @@ -21,7 +21,7 @@ import { HeightMap, IViewItem } from 'vs/base/parts/tree/browser/treeViewModel'; import * as _ from 'vs/base/parts/tree/browser/tree'; import { KeyCode } from 'vs/base/common/keyCodes'; import { Event, Emitter } from 'vs/base/common/event'; -import { DataTransfers } from 'vs/base/browser/dnd'; +import { DataTransfers, StaticDND, IDragAndDropData } from 'vs/base/browser/dnd'; import { DefaultTreestyler } from './treeDefaults'; import { Delayer, timeout } from 'vs/base/common/async'; @@ -410,8 +410,6 @@ export class TreeView extends HeightMap { private static counter: number = 0; private instance: number; - private static currentExternalDragAndDropData: _.IDragAndDropData = null; - private context: IViewContext; private modelListeners: Lifecycle.IDisposable[]; private model: Model.TreeModel; @@ -438,7 +436,7 @@ export class TreeView extends HeightMap { private isRefreshing = false; private refreshingPreviousChildrenIds: { [id: string]: string[] } = {}; - private currentDragAndDropData: _.IDragAndDropData; + private currentDragAndDropData: IDragAndDropData; private currentDropElement: any; private currentDropElementReaction: _.IDragOverReaction; private currentDropTarget: ViewItem; @@ -1399,7 +1397,7 @@ export class TreeView extends HeightMap { } this.currentDragAndDropData = new dnd.ElementsDragAndDropData(elements); - TreeView.currentExternalDragAndDropData = new dnd.ExternalElementsDragAndDropData(elements); + StaticDND.CurrentDragAndDropData = new dnd.ExternalElementsDragAndDropData(elements); this.context.dnd.onDragStart(this.context.tree, this.currentDragAndDropData, new Mouse.DragMouseEvent(e)); } @@ -1482,8 +1480,8 @@ export class TreeView extends HeightMap { if (!this.currentDragAndDropData) { // just started dragging - if (TreeView.currentExternalDragAndDropData) { - this.currentDragAndDropData = TreeView.currentExternalDragAndDropData; + if (StaticDND.CurrentDragAndDropData) { + this.currentDragAndDropData = StaticDND.CurrentDragAndDropData; } else { if (!event.dataTransfer.types) { return false; @@ -1493,7 +1491,7 @@ export class TreeView extends HeightMap { } } - this.currentDragAndDropData.update(event); + this.currentDragAndDropData.update((event.browserEvent as DragEvent).dataTransfer); let element: any; let item: Model.Item = viewItem.model; @@ -1581,7 +1579,7 @@ export class TreeView extends HeightMap { if (this.currentDropElement) { let event = new Mouse.DragMouseEvent(e); event.preventDefault(); - this.currentDragAndDropData.update(event); + this.currentDragAndDropData.update((event.browserEvent as DragEvent).dataTransfer); this.context.dnd.drop(this.context.tree, this.currentDragAndDropData, this.currentDropElement, event); this.onDragEnd(e); } @@ -1598,7 +1596,7 @@ export class TreeView extends HeightMap { this.cancelDragAndDropScrollInterval(); this.currentDragAndDropData = null; - TreeView.currentExternalDragAndDropData = null; + StaticDND.CurrentDragAndDropData = undefined; this.currentDropElement = null; this.currentDropTarget = null; this.dragAndDropMouseY = null; diff --git a/src/vs/workbench/browser/dnd.ts b/src/vs/workbench/browser/dnd.ts index be3ca78e745..bde4319b2d3 100644 --- a/src/vs/workbench/browser/dnd.ts +++ b/src/vs/workbench/browser/dnd.ts @@ -15,12 +15,12 @@ import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/un import { DefaultEndOfLine } from 'vs/editor/common/model'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IEditorViewState } from 'vs/editor/common/editorCommon'; -import { DataTransfers } from 'vs/base/browser/dnd'; +import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd'; import { DefaultDragAndDrop } from 'vs/base/parts/tree/browser/treeDefaults'; import { DragMouseEvent } from 'vs/base/browser/mouseEvent'; import { normalizeDriveLetter } from 'vs/base/common/labels'; import { MIME_BINARY } from 'vs/base/common/mime'; -import { ITree, IDragAndDropData } from 'vs/base/parts/tree/browser/tree'; +import { ITree } from 'vs/base/parts/tree/browser/tree'; import { isWindows } from 'vs/base/common/platform'; import { coalesce } from 'vs/base/common/arrays'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; diff --git a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts index fd6eb80e7e6..27f648f793a 100644 --- a/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/electron-browser/views/explorerViewer.ts @@ -23,7 +23,7 @@ import { IFilesConfiguration, SortOrder } from 'vs/workbench/parts/files/common/ import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles'; import { FileOperationError, FileOperationResult, IFileService, FileKind } from 'vs/platform/files/common/files'; import { DuplicateFileAction, AddFilesAction, IEditableData, IFileViewletState, FileCopiedContext } from 'vs/workbench/parts/files/electron-browser/fileActions'; -import { IDataSource, ITree, IAccessibilityProvider, IRenderer, ContextMenuEvent, ISorter, IFilter, IDragAndDropData, IDragOverReaction, DRAG_OVER_ACCEPT_BUBBLE_DOWN, DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY, DRAG_OVER_ACCEPT_BUBBLE_UP, DRAG_OVER_ACCEPT_BUBBLE_UP_COPY, DRAG_OVER_REJECT } from 'vs/base/parts/tree/browser/tree'; +import { IDataSource, ITree, IAccessibilityProvider, IRenderer, ContextMenuEvent, ISorter, IFilter, IDragOverReaction, DRAG_OVER_ACCEPT_BUBBLE_DOWN, DRAG_OVER_ACCEPT_BUBBLE_DOWN_COPY, DRAG_OVER_ACCEPT_BUBBLE_UP, DRAG_OVER_ACCEPT_BUBBLE_UP_COPY, DRAG_OVER_REJECT } from 'vs/base/parts/tree/browser/tree'; import { DesktopDragAndDropData, ExternalElementsDragAndDropData } from 'vs/base/parts/tree/browser/treeDnd'; import { ClickBehavior } from 'vs/base/parts/tree/browser/treeDefaults'; import { ExplorerItem, NewStatPlaceholder, Model } from 'vs/workbench/parts/files/common/explorerModel'; @@ -46,7 +46,7 @@ import { IWorkspaceEditingService } from 'vs/workbench/services/workspace/common import { extractResources, SimpleFileResourceDragAndDrop, CodeDataTransfers, fillResourceDataTransfers } from 'vs/workbench/browser/dnd'; import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService'; import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService'; -import { DataTransfers } from 'vs/base/browser/dnd'; +import { DataTransfers, IDragAndDropData } from 'vs/base/browser/dnd'; import { Schemas } from 'vs/base/common/network'; import { IWorkspaceFolderCreationData } from 'vs/platform/workspaces/common/workspaces'; import { rtrim } from 'vs/base/common/strings'; diff --git a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts index d6b6d3a6bcb..19d30856bec 100644 --- a/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts +++ b/src/vs/workbench/parts/scm/electron-browser/scmViewlet.ts @@ -878,19 +878,9 @@ export class RepositoryPanel extends ViewletPanel { new ResourceRenderer(this.listLabels, actionItemProvider, () => this.getSelectedResources(), this.themeService, this.menus) ]; - const that = this; this.list = this.instantiationService.createInstance(WorkbenchList, this.listContainer, delegate, renderers, { identityProvider: scmResourceIdentityProvider, - keyboardNavigationLabelProvider: scmKeyboardNavigationLabelProvider, - dnd: { - getDragURI(element) { return 'file:///foo'; }, - // getDragLabel(elements) { return 'dragging'; }, - onDragStart(data, originalEvent) { }, - onDragOver(data, targetElement, targetIndex, originalEvent) { - return { accept: true, feedback: typeof targetIndex === 'undefined' ? undefined : [targetIndex - 1, targetIndex, targetIndex + 1].filter(i => i >= 0 && i < that.list.length) }; - }, - drop(data, targetElement, originalEvent) { } - } + keyboardNavigationLabelProvider: scmKeyboardNavigationLabelProvider }) as WorkbenchList; Event.chain(this.list.onDidOpen)