@@ -11,7 +11,7 @@ import { ComposedTreeDelegate, TreeFindMode as TreeFindMode, IAbstractTreeOption
11
11
import { ICompressedTreeElement , ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel' ;
12
12
import { getVisibleState , isFilterResult } from 'vs/base/browser/ui/tree/indexTreeModel' ;
13
13
import { CompressibleObjectTree , ICompressibleKeyboardNavigationLabelProvider , ICompressibleObjectTreeOptions , ICompressibleTreeRenderer , IObjectTreeOptions , IObjectTreeSetChildrenOptions , ObjectTree } from 'vs/base/browser/ui/tree/objectTree' ;
14
- import { IAsyncDataSource , ICollapseStateChangeEvent , IObjectTreeElement , ITreeContextMenuEvent , ITreeDragAndDrop , ITreeEvent , ITreeFilter , ITreeMouseEvent , ITreeNode , ITreeRenderer , ITreeSorter , TreeError , TreeFilterResult , TreeVisibility , WeakMapper } from 'vs/base/browser/ui/tree/tree' ;
14
+ import { IAsyncDataSource , ICollapseStateChangeEvent , IObjectTreeElement , ITreeContextMenuEvent , ITreeDragAndDrop , ITreeEvent , ITreeFilter , ITreeMouseEvent , ITreeNode , ITreeRenderer , ITreeSorter , ObjectTreeElementCollapseState , TreeError , TreeFilterResult , TreeVisibility , WeakMapper } from 'vs/base/browser/ui/tree/tree' ;
15
15
import { CancelablePromise , createCancelablePromise , Promises , timeout } from 'vs/base/common/async' ;
16
16
import { Codicon } from 'vs/base/common/codicons' ;
17
17
import { ThemeIcon } from 'vs/base/common/themables' ;
@@ -31,13 +31,15 @@ interface IAsyncDataTreeNode<TInput, T> {
31
31
hasChildren : boolean ;
32
32
stale : boolean ;
33
33
slow : boolean ;
34
- collapsedByDefault : boolean | undefined ;
34
+ readonly defaultCollapseState : undefined | ObjectTreeElementCollapseState . PreserveOrCollapsed | ObjectTreeElementCollapseState . PreserveOrExpanded ;
35
+ forceExpanded : boolean ;
35
36
}
36
37
37
38
interface IAsyncDataTreeNodeRequiredProps < TInput , T > extends Partial < IAsyncDataTreeNode < TInput , T > > {
38
39
readonly element : TInput | T ;
39
40
readonly parent : IAsyncDataTreeNode < TInput , T > | null ;
40
41
readonly hasChildren : boolean ;
42
+ readonly defaultCollapseState : undefined | ObjectTreeElementCollapseState . PreserveOrCollapsed | ObjectTreeElementCollapseState . PreserveOrExpanded ;
41
43
}
42
44
43
45
function createAsyncDataTreeNode < TInput , T > ( props : IAsyncDataTreeNodeRequiredProps < TInput , T > ) : IAsyncDataTreeNode < TInput , T > {
@@ -47,7 +49,7 @@ function createAsyncDataTreeNode<TInput, T>(props: IAsyncDataTreeNodeRequiredPro
47
49
refreshPromise : undefined ,
48
50
stale : true ,
49
51
slow : false ,
50
- collapsedByDefault : undefined
52
+ forceExpanded : false
51
53
} ;
52
54
}
53
55
@@ -321,7 +323,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
321
323
protected readonly root : IAsyncDataTreeNode < TInput , T > ;
322
324
private readonly nodes = new Map < null | T , IAsyncDataTreeNode < TInput , T > > ( ) ;
323
325
private readonly sorter ?: ITreeSorter < T > ;
324
- private readonly collapseByDefault ? : { ( e : T ) : boolean } ;
326
+ private readonly getDefaultCollapseState : { ( e : T ) : undefined | ObjectTreeElementCollapseState . PreserveOrCollapsed | ObjectTreeElementCollapseState . PreserveOrExpanded } ;
325
327
326
328
private readonly subTreeRefreshPromises = new Map < IAsyncDataTreeNode < TInput , T > , Promise < void > > ( ) ;
327
329
private readonly refreshPromises = new Map < IAsyncDataTreeNode < TInput , T > , CancelablePromise < Iterable < T > > > ( ) ;
@@ -387,15 +389,16 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
387
389
this . identityProvider = options . identityProvider ;
388
390
this . autoExpandSingleChildren = typeof options . autoExpandSingleChildren === 'undefined' ? false : options . autoExpandSingleChildren ;
389
391
this . sorter = options . sorter ;
390
- this . collapseByDefault = options . collapseByDefault ;
392
+ this . getDefaultCollapseState = e => options . collapseByDefault ? ( options . collapseByDefault ( e ) ? ObjectTreeElementCollapseState . PreserveOrCollapsed : ObjectTreeElementCollapseState . PreserveOrExpanded ) : undefined ;
391
393
392
394
this . tree = this . createTree ( user , container , delegate , renderers , options ) ;
393
395
this . onDidChangeFindMode = this . tree . onDidChangeFindMode ;
394
396
395
397
this . root = createAsyncDataTreeNode ( {
396
398
element : undefined ! ,
397
399
parent : null ,
398
- hasChildren : true
400
+ hasChildren : true ,
401
+ defaultCollapseState : undefined
399
402
} ) ;
400
403
401
404
if ( this . identityProvider ) {
@@ -932,10 +935,9 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
932
935
const hasChildren = ! ! this . dataSource . hasChildren ( element ) ;
933
936
934
937
if ( ! this . identityProvider ) {
935
- const asyncDataTreeNode = createAsyncDataTreeNode ( { element, parent : node , hasChildren } ) ;
938
+ const asyncDataTreeNode = createAsyncDataTreeNode ( { element, parent : node , hasChildren, defaultCollapseState : this . getDefaultCollapseState ( element ) } ) ;
936
939
937
- if ( hasChildren && this . collapseByDefault && ! this . collapseByDefault ( element ) ) {
938
- asyncDataTreeNode . collapsedByDefault = false ;
940
+ if ( hasChildren && asyncDataTreeNode . defaultCollapseState === ObjectTreeElementCollapseState . PreserveOrExpanded ) {
939
941
childrenToRefresh . push ( asyncDataTreeNode ) ;
940
942
}
941
943
@@ -963,15 +965,14 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
963
965
} else {
964
966
childrenToRefresh . push ( asyncDataTreeNode ) ;
965
967
}
966
- } else if ( hasChildren && this . collapseByDefault && ! this . collapseByDefault ( element ) ) {
967
- asyncDataTreeNode . collapsedByDefault = false ;
968
+ } else if ( hasChildren && ! result . collapsed ) {
968
969
childrenToRefresh . push ( asyncDataTreeNode ) ;
969
970
}
970
971
971
972
return asyncDataTreeNode ;
972
973
}
973
974
974
- const childAsyncDataTreeNode = createAsyncDataTreeNode ( { element, parent : node , id, hasChildren } ) ;
975
+ const childAsyncDataTreeNode = createAsyncDataTreeNode ( { element, parent : node , id, hasChildren, defaultCollapseState : this . getDefaultCollapseState ( element ) } ) ;
975
976
976
977
if ( viewStateContext && viewStateContext . viewState . focus && viewStateContext . viewState . focus . indexOf ( id ) > - 1 ) {
977
978
viewStateContext . focus . push ( childAsyncDataTreeNode ) ;
@@ -983,8 +984,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
983
984
984
985
if ( viewStateContext && viewStateContext . viewState . expanded && viewStateContext . viewState . expanded . indexOf ( id ) > - 1 ) {
985
986
childrenToRefresh . push ( childAsyncDataTreeNode ) ;
986
- } else if ( hasChildren && this . collapseByDefault && ! this . collapseByDefault ( element ) ) {
987
- childAsyncDataTreeNode . collapsedByDefault = false ;
987
+ } else if ( hasChildren && childAsyncDataTreeNode . defaultCollapseState === ObjectTreeElementCollapseState . PreserveOrExpanded ) {
988
988
childrenToRefresh . push ( childAsyncDataTreeNode ) ;
989
989
}
990
990
@@ -1003,7 +1003,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
1003
1003
1004
1004
// TODO@joao this doesn't take filter into account
1005
1005
if ( node !== this . root && this . autoExpandSingleChildren && children . length === 1 && childrenToRefresh . length === 0 ) {
1006
- children [ 0 ] . collapsedByDefault = false ;
1006
+ children [ 0 ] . forceExpanded = true ;
1007
1007
childrenToRefresh . push ( children [ 0 ] ) ;
1008
1008
}
1009
1009
@@ -1039,16 +1039,17 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
1039
1039
} ;
1040
1040
}
1041
1041
1042
- let collapsed : boolean | undefined ;
1042
+ let collapsed : boolean | ObjectTreeElementCollapseState . PreserveOrCollapsed | ObjectTreeElementCollapseState . PreserveOrExpanded | undefined ;
1043
1043
1044
1044
if ( viewStateContext && viewStateContext . viewState . expanded && node . id && viewStateContext . viewState . expanded . indexOf ( node . id ) > - 1 ) {
1045
1045
collapsed = false ;
1046
+ } else if ( node . forceExpanded ) {
1047
+ collapsed = false ;
1048
+ node . forceExpanded = false ;
1046
1049
} else {
1047
- collapsed = node . collapsedByDefault ;
1050
+ collapsed = node . defaultCollapseState ;
1048
1051
}
1049
1052
1050
- node . collapsedByDefault = undefined ;
1051
-
1052
1053
return {
1053
1054
element : node ,
1054
1055
children : node . hasChildren ? Iterable . map ( node . children , child => this . asTreeElement ( child , viewStateContext ) ) : [ ] ,
0 commit comments