@@ -11,7 +11,7 @@ import { ComposedTreeDelegate, TreeFindMode as TreeFindMode, IAbstractTreeOption
1111import { ICompressedTreeElement , ICompressedTreeNode } from 'vs/base/browser/ui/tree/compressedObjectTreeModel' ;
1212import { getVisibleState , isFilterResult } from 'vs/base/browser/ui/tree/indexTreeModel' ;
1313import { 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' ;
1515import { CancelablePromise , createCancelablePromise , Promises , timeout } from 'vs/base/common/async' ;
1616import { Codicon } from 'vs/base/common/codicons' ;
1717import { ThemeIcon } from 'vs/base/common/themables' ;
@@ -31,13 +31,15 @@ interface IAsyncDataTreeNode<TInput, T> {
3131 hasChildren : boolean ;
3232 stale : boolean ;
3333 slow : boolean ;
34- collapsedByDefault : boolean | undefined ;
34+ readonly defaultCollapseState : undefined | ObjectTreeElementCollapseState . PreserveOrCollapsed | ObjectTreeElementCollapseState . PreserveOrExpanded ;
35+ forceExpanded : boolean ;
3536}
3637
3738interface IAsyncDataTreeNodeRequiredProps < TInput , T > extends Partial < IAsyncDataTreeNode < TInput , T > > {
3839 readonly element : TInput | T ;
3940 readonly parent : IAsyncDataTreeNode < TInput , T > | null ;
4041 readonly hasChildren : boolean ;
42+ readonly defaultCollapseState : undefined | ObjectTreeElementCollapseState . PreserveOrCollapsed | ObjectTreeElementCollapseState . PreserveOrExpanded ;
4143}
4244
4345function createAsyncDataTreeNode < TInput , T > ( props : IAsyncDataTreeNodeRequiredProps < TInput , T > ) : IAsyncDataTreeNode < TInput , T > {
@@ -47,7 +49,7 @@ function createAsyncDataTreeNode<TInput, T>(props: IAsyncDataTreeNodeRequiredPro
4749 refreshPromise : undefined ,
4850 stale : true ,
4951 slow : false ,
50- collapsedByDefault : undefined
52+ forceExpanded : false
5153 } ;
5254}
5355
@@ -321,7 +323,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
321323 protected readonly root : IAsyncDataTreeNode < TInput , T > ;
322324 private readonly nodes = new Map < null | T , IAsyncDataTreeNode < TInput , T > > ( ) ;
323325 private readonly sorter ?: ITreeSorter < T > ;
324- private readonly collapseByDefault ? : { ( e : T ) : boolean } ;
326+ private readonly getDefaultCollapseState : { ( e : T ) : undefined | ObjectTreeElementCollapseState . PreserveOrCollapsed | ObjectTreeElementCollapseState . PreserveOrExpanded } ;
325327
326328 private readonly subTreeRefreshPromises = new Map < IAsyncDataTreeNode < TInput , T > , Promise < void > > ( ) ;
327329 private readonly refreshPromises = new Map < IAsyncDataTreeNode < TInput , T > , CancelablePromise < Iterable < T > > > ( ) ;
@@ -387,15 +389,16 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
387389 this . identityProvider = options . identityProvider ;
388390 this . autoExpandSingleChildren = typeof options . autoExpandSingleChildren === 'undefined' ? false : options . autoExpandSingleChildren ;
389391 this . sorter = options . sorter ;
390- this . collapseByDefault = options . collapseByDefault ;
392+ this . getDefaultCollapseState = e => options . collapseByDefault ? ( options . collapseByDefault ( e ) ? ObjectTreeElementCollapseState . PreserveOrCollapsed : ObjectTreeElementCollapseState . PreserveOrExpanded ) : undefined ;
391393
392394 this . tree = this . createTree ( user , container , delegate , renderers , options ) ;
393395 this . onDidChangeFindMode = this . tree . onDidChangeFindMode ;
394396
395397 this . root = createAsyncDataTreeNode ( {
396398 element : undefined ! ,
397399 parent : null ,
398- hasChildren : true
400+ hasChildren : true ,
401+ defaultCollapseState : undefined
399402 } ) ;
400403
401404 if ( this . identityProvider ) {
@@ -932,10 +935,9 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
932935 const hasChildren = ! ! this . dataSource . hasChildren ( element ) ;
933936
934937 if ( ! this . identityProvider ) {
935- const asyncDataTreeNode = createAsyncDataTreeNode ( { element, parent : node , hasChildren } ) ;
938+ const asyncDataTreeNode = createAsyncDataTreeNode ( { element, parent : node , hasChildren, defaultCollapseState : this . getDefaultCollapseState ( element ) } ) ;
936939
937- if ( hasChildren && this . collapseByDefault && ! this . collapseByDefault ( element ) ) {
938- asyncDataTreeNode . collapsedByDefault = false ;
940+ if ( hasChildren && asyncDataTreeNode . defaultCollapseState === ObjectTreeElementCollapseState . PreserveOrExpanded ) {
939941 childrenToRefresh . push ( asyncDataTreeNode ) ;
940942 }
941943
@@ -963,15 +965,14 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
963965 } else {
964966 childrenToRefresh . push ( asyncDataTreeNode ) ;
965967 }
966- } else if ( hasChildren && this . collapseByDefault && ! this . collapseByDefault ( element ) ) {
967- asyncDataTreeNode . collapsedByDefault = false ;
968+ } else if ( hasChildren && ! result . collapsed ) {
968969 childrenToRefresh . push ( asyncDataTreeNode ) ;
969970 }
970971
971972 return asyncDataTreeNode ;
972973 }
973974
974- const childAsyncDataTreeNode = createAsyncDataTreeNode ( { element, parent : node , id, hasChildren } ) ;
975+ const childAsyncDataTreeNode = createAsyncDataTreeNode ( { element, parent : node , id, hasChildren, defaultCollapseState : this . getDefaultCollapseState ( element ) } ) ;
975976
976977 if ( viewStateContext && viewStateContext . viewState . focus && viewStateContext . viewState . focus . indexOf ( id ) > - 1 ) {
977978 viewStateContext . focus . push ( childAsyncDataTreeNode ) ;
@@ -983,8 +984,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
983984
984985 if ( viewStateContext && viewStateContext . viewState . expanded && viewStateContext . viewState . expanded . indexOf ( id ) > - 1 ) {
985986 childrenToRefresh . push ( childAsyncDataTreeNode ) ;
986- } else if ( hasChildren && this . collapseByDefault && ! this . collapseByDefault ( element ) ) {
987- childAsyncDataTreeNode . collapsedByDefault = false ;
987+ } else if ( hasChildren && childAsyncDataTreeNode . defaultCollapseState === ObjectTreeElementCollapseState . PreserveOrExpanded ) {
988988 childrenToRefresh . push ( childAsyncDataTreeNode ) ;
989989 }
990990
@@ -1003,7 +1003,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
10031003
10041004 // TODO@joao this doesn't take filter into account
10051005 if ( node !== this . root && this . autoExpandSingleChildren && children . length === 1 && childrenToRefresh . length === 0 ) {
1006- children [ 0 ] . collapsedByDefault = false ;
1006+ children [ 0 ] . forceExpanded = true ;
10071007 childrenToRefresh . push ( children [ 0 ] ) ;
10081008 }
10091009
@@ -1039,16 +1039,17 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
10391039 } ;
10401040 }
10411041
1042- let collapsed : boolean | undefined ;
1042+ let collapsed : boolean | ObjectTreeElementCollapseState . PreserveOrCollapsed | ObjectTreeElementCollapseState . PreserveOrExpanded | undefined ;
10431043
10441044 if ( viewStateContext && viewStateContext . viewState . expanded && node . id && viewStateContext . viewState . expanded . indexOf ( node . id ) > - 1 ) {
10451045 collapsed = false ;
1046+ } else if ( node . forceExpanded ) {
1047+ collapsed = false ;
1048+ node . forceExpanded = false ;
10461049 } else {
1047- collapsed = node . collapsedByDefault ;
1050+ collapsed = node . defaultCollapseState ;
10481051 }
10491052
1050- node . collapsedByDefault = undefined ;
1051-
10521053 return {
10531054 element : node ,
10541055 children : node . hasChildren ? Iterable . map ( node . children , child => this . asTreeElement ( child , viewStateContext ) ) : [ ] ,
0 commit comments