@@ -630,79 +630,16 @@ abstract class AbstractTreeView extends Disposable implements ITreeView {
630
630
this . _register ( focusTracker . onDidBlur ( ( ) => this . focused = false ) ) ;
631
631
}
632
632
633
- private updateCheckboxes ( items : ITreeItem [ ] ) {
634
- const additionalItems : ITreeItem [ ] = [ ] ;
635
-
636
- if ( ! this . manuallyManageCheckboxes ) {
637
- for ( const item of items ) {
638
- if ( item . checkbox !== undefined ) {
639
-
640
- function checkChildren ( currentItem : ITreeItem ) {
641
- for ( const child of ( currentItem . children ?? [ ] ) ) {
642
- if ( ( child . checkbox !== undefined ) && ( currentItem . checkbox !== undefined ) && ( child . checkbox . isChecked !== currentItem . checkbox . isChecked ) ) {
643
- child . checkbox . isChecked = currentItem . checkbox . isChecked ;
644
- additionalItems . push ( child ) ;
645
- checkChildren ( child ) ;
646
- }
647
- }
648
- }
649
- checkChildren ( item ) ;
650
-
651
- const visitedParents : Set < ITreeItem > = new Set ( ) ;
652
- function checkParents ( currentItem : ITreeItem ) {
653
- if ( currentItem . parent && ( currentItem . parent . checkbox !== undefined ) && currentItem . parent . children ) {
654
- if ( visitedParents . has ( currentItem . parent ) ) {
655
- return ;
656
- } else {
657
- visitedParents . add ( currentItem . parent ) ;
658
- }
659
-
660
- let someUnchecked = false ;
661
- let someChecked = false ;
662
- for ( const child of currentItem . parent . children ) {
663
- if ( someUnchecked && someChecked ) {
664
- break ;
665
- }
666
- if ( child . checkbox !== undefined ) {
667
- if ( child . checkbox . isChecked ) {
668
- someChecked = true ;
669
- } else {
670
- someUnchecked = true ;
671
- }
672
- }
673
- }
674
- if ( someChecked && ! someUnchecked && ( currentItem . parent . checkbox . isChecked !== true ) ) {
675
- currentItem . parent . checkbox . isChecked = true ;
676
- additionalItems . push ( currentItem . parent ) ;
677
- checkParents ( currentItem . parent ) ;
678
- } else if ( someUnchecked && ( currentItem . parent . checkbox . isChecked !== false ) ) {
679
- currentItem . parent . checkbox . isChecked = false ;
680
- additionalItems . push ( currentItem . parent ) ;
681
- checkParents ( currentItem . parent ) ;
682
- }
683
- }
684
- }
685
- checkParents ( item ) ;
686
- }
687
- }
688
- }
689
- items = items . concat ( additionalItems ) ;
690
- items . forEach ( item => this . tree ?. rerender ( item ) ) ;
691
- this . _onDidChangeCheckboxState . fire ( items ) ;
692
- }
693
-
694
-
695
633
protected createTree ( ) {
696
634
const actionViewItemProvider = createActionViewItem . bind ( undefined , this . instantiationService ) ;
697
635
const treeMenus = this . _register ( this . instantiationService . createInstance ( TreeMenus , this . id ) ) ;
698
636
this . treeLabels = this . _register ( this . instantiationService . createInstance ( ResourceLabels , this ) ) ;
699
637
const dataSource = this . instantiationService . createInstance ( TreeDataSource , this , < T > ( task : Promise < T > ) => this . progressService . withProgress ( { location : this . id } , ( ) => task ) ) ;
700
638
const aligner = new Aligner ( this . themeService ) ;
701
639
const checkboxStateHandler = this . _register ( new CheckboxStateHandler ( ) ) ;
702
- this . _register ( checkboxStateHandler . onDidChangeCheckboxState ( items => {
703
- this . updateCheckboxes ( items ) ;
704
- } ) ) ;
705
- const renderer = this . instantiationService . createInstance ( TreeRenderer , this . id , treeMenus , this . treeLabels , actionViewItemProvider , aligner , checkboxStateHandler ) ;
640
+ const renderer = this . instantiationService . createInstance ( TreeRenderer , this . id , treeMenus , this . treeLabels , actionViewItemProvider , aligner , checkboxStateHandler , this . manuallyManageCheckboxes ) ;
641
+ this . _register ( renderer . onDidChangeCheckboxState ( e => this . _onDidChangeCheckboxState . fire ( e ) ) ) ;
642
+
706
643
const widgetAriaLabel = this . _title ;
707
644
708
645
this . tree = this . _register ( this . instantiationService . createInstance ( Tree , this . id , this . treeContainer ! , new TreeViewDelegate ( ) , [ renderer ] ,
@@ -1125,10 +1062,13 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
1125
1062
static readonly ITEM_HEIGHT = 22 ;
1126
1063
static readonly TREE_TEMPLATE_ID = 'treeExplorer' ;
1127
1064
1065
+ private readonly _onDidChangeCheckboxState : Emitter < readonly ITreeItem [ ] > = this . _register ( new Emitter < readonly ITreeItem [ ] > ( ) ) ;
1066
+ readonly onDidChangeCheckboxState : Event < readonly ITreeItem [ ] > = this . _onDidChangeCheckboxState . event ;
1067
+
1128
1068
private _actionRunner : MultipleSelectionActionRunner | undefined ;
1129
1069
private _hoverDelegate : IHoverDelegate ;
1130
1070
private _hasCheckbox : boolean = false ;
1131
- private _renderedElements = new Map < ITreeNode < ITreeItem , FuzzyScore > , ITreeExplorerTemplateData > ( ) ;
1071
+ private _renderedElements = new Map < string , { original : ITreeNode < ITreeItem , FuzzyScore > ; rendered : ITreeExplorerTemplateData } > ( ) ; // tree item handle to template data
1132
1072
1133
1073
constructor (
1134
1074
private treeViewId : string ,
@@ -1137,6 +1077,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
1137
1077
private actionViewItemProvider : IActionViewItemProvider ,
1138
1078
private aligner : Aligner ,
1139
1079
private checkboxStateHandler : CheckboxStateHandler ,
1080
+ private readonly manuallyManageCheckboxes : boolean ,
1140
1081
@IThemeService private readonly themeService : IThemeService ,
1141
1082
@IConfigurationService private readonly configurationService : IConfigurationService ,
1142
1083
@ILabelService private readonly labelService : ILabelService ,
@@ -1151,6 +1092,9 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
1151
1092
} ;
1152
1093
this . _register ( this . themeService . onDidFileIconThemeChange ( ( ) => this . rerender ( ) ) ) ;
1153
1094
this . _register ( this . themeService . onDidColorThemeChange ( ( ) => this . rerender ( ) ) ) ;
1095
+ this . _register ( checkboxStateHandler . onDidChangeCheckboxState ( items => {
1096
+ this . updateCheckboxes ( items ) ;
1097
+ } ) ) ;
1154
1098
}
1155
1099
1156
1100
get templateId ( ) : string {
@@ -1302,7 +1246,7 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
1302
1246
this . treeViewsService . addRenderedTreeItemElement ( node , templateData . container ) ;
1303
1247
1304
1248
// remember rendered element
1305
- this . _renderedElements . set ( element , templateData ) ;
1249
+ this . _renderedElements . set ( element . element . handle , { original : element , rendered : templateData } ) ;
1306
1250
}
1307
1251
1308
1252
private rerender ( ) {
@@ -1312,8 +1256,8 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
1312
1256
for ( const key of keys ) {
1313
1257
const value = this . _renderedElements . get ( key ) ;
1314
1258
if ( value ) {
1315
- this . disposeElement ( key , 0 , value ) ;
1316
- this . renderElement ( key , 0 , value ) ;
1259
+ this . disposeElement ( value . original , 0 , value . rendered ) ;
1260
+ this . renderElement ( value . original , 0 , value . rendered ) ;
1317
1261
}
1318
1262
}
1319
1263
}
@@ -1381,10 +1325,76 @@ class TreeRenderer extends Disposable implements ITreeRenderer<ITreeItem, FuzzyS
1381
1325
return node . collapsibleState === TreeItemCollapsibleState . Collapsed || node . collapsibleState === TreeItemCollapsibleState . Expanded ? FileKind . FOLDER : FileKind . FILE ;
1382
1326
}
1383
1327
1328
+ private updateCheckboxes ( items : ITreeItem [ ] ) {
1329
+ const additionalItems : ITreeItem [ ] = [ ] ;
1330
+
1331
+ if ( ! this . manuallyManageCheckboxes ) {
1332
+ for ( const item of items ) {
1333
+ if ( item . checkbox !== undefined ) {
1334
+
1335
+ function checkChildren ( currentItem : ITreeItem ) {
1336
+ for ( const child of ( currentItem . children ?? [ ] ) ) {
1337
+ if ( ( child . checkbox !== undefined ) && ( currentItem . checkbox !== undefined ) && ( child . checkbox . isChecked !== currentItem . checkbox . isChecked ) ) {
1338
+ child . checkbox . isChecked = currentItem . checkbox . isChecked ;
1339
+ additionalItems . push ( child ) ;
1340
+ checkChildren ( child ) ;
1341
+ }
1342
+ }
1343
+ }
1344
+ checkChildren ( item ) ;
1345
+
1346
+ const visitedParents : Set < ITreeItem > = new Set ( ) ;
1347
+ function checkParents ( currentItem : ITreeItem ) {
1348
+ if ( currentItem . parent && ( currentItem . parent . checkbox !== undefined ) && currentItem . parent . children ) {
1349
+ if ( visitedParents . has ( currentItem . parent ) ) {
1350
+ return ;
1351
+ } else {
1352
+ visitedParents . add ( currentItem . parent ) ;
1353
+ }
1354
+
1355
+ let someUnchecked = false ;
1356
+ let someChecked = false ;
1357
+ for ( const child of currentItem . parent . children ) {
1358
+ if ( someUnchecked && someChecked ) {
1359
+ break ;
1360
+ }
1361
+ if ( child . checkbox !== undefined ) {
1362
+ if ( child . checkbox . isChecked ) {
1363
+ someChecked = true ;
1364
+ } else {
1365
+ someUnchecked = true ;
1366
+ }
1367
+ }
1368
+ }
1369
+ if ( someChecked && ! someUnchecked && ( currentItem . parent . checkbox . isChecked !== true ) ) {
1370
+ currentItem . parent . checkbox . isChecked = true ;
1371
+ additionalItems . push ( currentItem . parent ) ;
1372
+ checkParents ( currentItem . parent ) ;
1373
+ } else if ( someUnchecked && ( currentItem . parent . checkbox . isChecked !== false ) ) {
1374
+ currentItem . parent . checkbox . isChecked = false ;
1375
+ additionalItems . push ( currentItem . parent ) ;
1376
+ checkParents ( currentItem . parent ) ;
1377
+ }
1378
+ }
1379
+ }
1380
+ checkParents ( item ) ;
1381
+ }
1382
+ }
1383
+ }
1384
+ items = items . concat ( additionalItems ) ;
1385
+ items . forEach ( item => {
1386
+ const renderedItem = this . _renderedElements . get ( item . handle ) ;
1387
+ if ( renderedItem ) {
1388
+ renderedItem . rendered . checkbox ?. render ( item ) ;
1389
+ }
1390
+ } ) ;
1391
+ this . _onDidChangeCheckboxState . fire ( items ) ;
1392
+ }
1393
+
1384
1394
disposeElement ( resource : ITreeNode < ITreeItem , FuzzyScore > , index : number , templateData : ITreeExplorerTemplateData ) : void {
1385
1395
templateData . elementDisposable . clear ( ) ;
1386
1396
1387
- this . _renderedElements . delete ( resource ) ;
1397
+ this . _renderedElements . delete ( resource . element . handle ) ;
1388
1398
this . treeViewsService . removeRenderedTreeItemElement ( resource . element ) ;
1389
1399
1390
1400
templateData . checkbox ?. dispose ( ) ;
0 commit comments