@@ -38,7 +38,9 @@ import { textLinkForeground, textCodeBlockBackground, focusBorder, listFilterMat
38
38
import { isString } from 'vs/base/common/types' ;
39
39
import { ILabelService } from 'vs/platform/label/common/label' ;
40
40
import { IListVirtualDelegate , IIdentityProvider } from 'vs/base/browser/ui/list/list' ;
41
- import { ITreeRenderer , ITreeNode , IAsyncDataSource , ITreeContextMenuEvent } from 'vs/base/browser/ui/tree/tree' ;
41
+ import { ITreeRenderer , ITreeNode , IAsyncDataSource , ITreeContextMenuEvent , ITreeDragAndDrop , ITreeDragOverReaction , TreeDragOverBubble } from 'vs/base/browser/ui/tree/tree' ;
42
+ import { ElementsDragAndDropData } from 'vs/base/browser/ui/list/listView' ;
43
+ import { IDragAndDropData } from 'vs/base/browser/dnd' ;
42
44
import { FuzzyScore , createMatches } from 'vs/base/common/filters' ;
43
45
import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults' ;
44
46
import { isFalsyOrWhitespace } from 'vs/base/common/strings' ;
@@ -87,6 +89,7 @@ export class TreeViewPane extends ViewPane {
87
89
if ( options . titleDescription !== this . treeView . description ) {
88
90
this . updateTitleDescription ( this . treeView . description ) ;
89
91
}
92
+
90
93
this . updateTreeVisibility ( ) ;
91
94
}
92
95
@@ -156,6 +159,7 @@ export class TreeView extends Disposable implements ITreeView {
156
159
private treeContainer ! : HTMLElement ;
157
160
private _messageValue : string | undefined ;
158
161
private _canSelectMany : boolean = false ;
162
+ private _canDragAndDrop = false ;
159
163
private messageElement ! : HTMLDivElement ;
160
164
private tree : Tree | undefined ;
161
165
private treeLabels : ResourceLabels | undefined ;
@@ -277,6 +281,12 @@ export class TreeView extends Disposable implements ITreeView {
277
281
}
278
282
return children ;
279
283
}
284
+
285
+ async setParent ( nodes : ITreeItem [ ] , parentNode : ITreeItem ) : Promise < void > {
286
+ if ( dataProvider . setParent ) {
287
+ await dataProvider . setParent ( nodes , parentNode ) ;
288
+ }
289
+ }
280
290
} ;
281
291
if ( this . _dataProvider . onDidChangeEmpty ) {
282
292
this . _register ( this . _dataProvider . onDidChangeEmpty ( ( ) => this . _onDidChangeWelcomeState . fire ( ) ) ) ;
@@ -329,6 +339,14 @@ export class TreeView extends Disposable implements ITreeView {
329
339
this . _canSelectMany = canSelectMany ;
330
340
}
331
341
342
+ get canDragAndDrop ( ) : boolean {
343
+ return this . _canDragAndDrop ;
344
+ }
345
+
346
+ set canDragAndDrop ( canDragAndDrop : boolean ) {
347
+ this . _canDragAndDrop = canDragAndDrop ;
348
+ }
349
+
332
350
get hasIconForParentNode ( ) : boolean {
333
351
return this . _hasIconForParentNode ;
334
352
}
@@ -503,6 +521,7 @@ export class TreeView extends Disposable implements ITreeView {
503
521
return e . collapsibleState !== TreeItemCollapsibleState . Expanded ;
504
522
} ,
505
523
multipleSelectionSupport : this . canSelectMany ,
524
+ dnd : this . canDragAndDrop ? this . instantiationService . createInstance ( CustomTreeViewDragAndDrop , dataSource ) : undefined ,
506
525
overrideStyles : {
507
526
listBackground : this . viewLocation === ViewContainerLocation . Sidebar ? SIDE_BAR_BACKGROUND : PANEL_BACKGROUND
508
527
}
@@ -795,6 +814,18 @@ class TreeDataSource implements IAsyncDataSource<ITreeItem, ITreeItem> {
795
814
}
796
815
return result ;
797
816
}
817
+
818
+ async setParent ( elements : ITreeItem [ ] , newParentElement : ITreeItem ) : Promise < void > {
819
+ if ( this . treeView . dataProvider && this . treeView . dataProvider . setParent ) {
820
+ try {
821
+ await this . withProgress ( this . treeView . dataProvider . setParent ( elements , newParentElement ) ) ;
822
+ } catch ( e ) {
823
+ if ( ! ( < string > e . message ) . startsWith ( 'Bad progress location:' ) ) {
824
+ throw e ;
825
+ }
826
+ }
827
+ }
828
+ }
798
829
}
799
830
800
831
// todo@jrieken ,sandy make this proper and contributable from extensions
@@ -1183,3 +1214,32 @@ export class CustomTreeView extends TreeView {
1183
1214
}
1184
1215
}
1185
1216
}
1217
+
1218
+ export class CustomTreeViewDragAndDrop implements ITreeDragAndDrop < ITreeItem > {
1219
+ constructor ( private dataSource : TreeDataSource , @ILabelService private readonly labelService : ILabelService ) { }
1220
+
1221
+ onDragOver ( data : IDragAndDropData , targetElement : ITreeItem , targetIndex : number , originalEvent : DragEvent ) : boolean | ITreeDragOverReaction {
1222
+ return { accept : true , bubble : TreeDragOverBubble . Down , autoExpand : true } ;
1223
+ }
1224
+
1225
+ getDragURI ( element : ITreeItem ) : string | null {
1226
+ return element . resourceUri ? URI . revive ( element . resourceUri ) . toString ( ) : element . handle ;
1227
+ }
1228
+
1229
+ getDragLabel ?( elements : ITreeItem [ ] ) : string | undefined {
1230
+ if ( elements . length > 1 ) {
1231
+ return String ( elements . length ) ;
1232
+ }
1233
+ const element = elements [ 0 ] ;
1234
+ return element . label ? element . label . label : ( element . resourceUri ? this . labelService . getUriLabel ( URI . revive ( element . resourceUri ) ) : undefined ) ;
1235
+ }
1236
+
1237
+ async drop ( data : IDragAndDropData , targetNode : ITreeItem | undefined , targetIndex : number | undefined , originalEvent : DragEvent ) : Promise < void > {
1238
+ if ( data instanceof ElementsDragAndDropData ) {
1239
+ const elements = data . elements ;
1240
+ if ( targetNode ) {
1241
+ await this . dataSource . setParent ( elements , targetNode ) ;
1242
+ }
1243
+ }
1244
+ }
1245
+ }
0 commit comments