@@ -26,6 +26,7 @@ import Event, { Emitter } from 'vs/base/common/event';
2626import { IDomNodePagePosition } from 'vs/base/browser/dom' ;
2727import { DataTransfers } from 'vs/base/browser/dnd' ;
2828import { DefaultTreestyler } from './treeDefaults' ;
29+ import { Delayer } from 'vs/base/common/async' ;
2930
3031export interface IRow {
3132 element : HTMLElement ;
@@ -101,6 +102,7 @@ export class RowCache implements Lifecycle.IDisposable {
101102
102103export interface IViewContext extends _ . ITreeContext {
103104 cache : RowCache ;
105+ horizontalScrolling : boolean ;
104106}
105107
106108export class ViewItem implements IViewItem {
@@ -113,6 +115,7 @@ export class ViewItem implements IViewItem {
113115
114116 public top : number ;
115117 public height : number ;
118+ public width : number = 0 ;
116119 public onDragStart : ( e : DragEvent ) => void ;
117120
118121 public needsRender : boolean ;
@@ -251,8 +254,32 @@ export class ViewItem implements IViewItem {
251254 }
252255
253256 if ( ! skipUserRender ) {
257+ const style = window . getComputedStyle ( this . element ) ;
258+ const paddingLeft = parseFloat ( style . paddingLeft ) ;
259+
260+ if ( this . context . horizontalScrolling ) {
261+ this . element . style . width = 'fit-content' ;
262+ }
263+
254264 this . context . renderer . renderElement ( this . context . tree , this . model . getElement ( ) , this . templateId , this . row . templateData ) ;
265+
266+ if ( this . context . horizontalScrolling ) {
267+ this . width = DOM . getContentWidth ( this . element ) + paddingLeft ;
268+ this . element . style . width = '' ;
269+ }
270+ }
271+ }
272+
273+ updateWidth ( ) : any {
274+ if ( ! this . context . horizontalScrolling ) {
275+ return ;
255276 }
277+
278+ const style = window . getComputedStyle ( this . element ) ;
279+ const paddingLeft = parseFloat ( style . paddingLeft ) ;
280+ this . element . style . width = 'fit-content' ;
281+ this . width = DOM . getContentWidth ( this . element ) + paddingLeft ;
282+ this . element . style . width = '' ;
256283 }
257284
258285 public insertInDOM ( container : HTMLElement , afterElement : HTMLElement ) : void {
@@ -386,6 +413,9 @@ export class TreeView extends HeightMap {
386413 private lastPointerType : string ;
387414 private lastClickTimeStamp : number = 0 ;
388415
416+ private horizontalScrolling : boolean = true ;
417+ private contentWidthUpdateDelayer = new Delayer < void > ( 50 ) ;
418+
389419 private lastRenderTop : number ;
390420 private lastRenderHeight : number ;
391421
@@ -422,6 +452,9 @@ export class TreeView extends HeightMap {
422452 TreeView . counter ++ ;
423453 this . instance = TreeView . counter ;
424454
455+ const horizontalScrollMode = typeof context . options . horizontalScrollMode === 'undefined' ? ScrollbarVisibility . Hidden : context . options . horizontalScrollMode ;
456+ const horizontalScrolling = horizontalScrollMode !== ScrollbarVisibility . Hidden ;
457+
425458 this . context = {
426459 dataSource : context . dataSource ,
427460 renderer : context . renderer ,
@@ -432,7 +465,8 @@ export class TreeView extends HeightMap {
432465 tree : context . tree ,
433466 accessibilityProvider : context . accessibilityProvider ,
434467 options : context . options ,
435- cache : new RowCache ( context )
468+ cache : new RowCache ( context ) ,
469+ horizontalScrolling
436470 } ;
437471
438472 this . modelListeners = [ ] ;
@@ -471,12 +505,12 @@ export class TreeView extends HeightMap {
471505 this . wrapper . className = 'monaco-tree-wrapper' ;
472506 this . scrollableElement = new ScrollableElement ( this . wrapper , {
473507 alwaysConsumeMouseWheel : true ,
474- horizontal : ScrollbarVisibility . Hidden ,
508+ horizontal : horizontalScrollMode ,
475509 vertical : ( typeof context . options . verticalScrollMode !== 'undefined' ? context . options . verticalScrollMode : ScrollbarVisibility . Auto ) ,
476510 useShadows : context . options . useShadows
477511 } ) ;
478512 this . scrollableElement . onScroll ( ( e ) => {
479- this . render ( e . scrollTop , e . height ) ;
513+ this . render ( e . scrollTop , e . height , e . scrollLeft , e . width , e . scrollWidth ) ;
480514 } ) ;
481515
482516 if ( Browser . isIE ) {
@@ -609,9 +643,14 @@ export class TreeView extends HeightMap {
609643 }
610644
611645 this . viewHeight = height || DOM . getContentHeight ( this . wrapper ) ; // render
646+ this . scrollHeight = this . getContentHeight ( ) ;
647+
648+ if ( this . horizontalScrolling ) {
649+ this . viewWidth = DOM . getContentWidth ( this . wrapper ) ;
650+ }
612651 }
613652
614- private render ( scrollTop : number , viewHeight : number ) : void {
653+ private render ( scrollTop : number , viewHeight : number , scrollLeft : number , viewWidth : number , scrollWidth : number ) : void {
615654 var i : number ;
616655 var stop : number ;
617656
@@ -645,6 +684,11 @@ export class TreeView extends HeightMap {
645684 this . rowsContainer . style . top = ( topItem . top - renderTop ) + 'px' ;
646685 }
647686
687+ if ( this . horizontalScrolling ) {
688+ this . rowsContainer . style . left = - scrollLeft + 'px' ;
689+ this . rowsContainer . style . width = `${ Math . max ( scrollWidth , viewWidth ) } px` ;
690+ }
691+
648692 this . lastRenderTop = renderTop ;
649693 this . lastRenderHeight = renderBottom - renderTop ;
650694 }
@@ -685,6 +729,24 @@ export class TreeView extends HeightMap {
685729 }
686730
687731 this . scrollTop = scrollTop ;
732+ this . updateScrollWidth ( ) ;
733+ }
734+
735+ private updateScrollWidth ( ) : void {
736+ if ( ! this . horizontalScrolling ) {
737+ return ;
738+ }
739+
740+ this . contentWidthUpdateDelayer . trigger ( ( ) => {
741+ const keys = Object . keys ( this . items ) ;
742+ let scrollWidth = 0 ;
743+
744+ for ( const key of keys ) {
745+ scrollWidth = Math . max ( scrollWidth , this . items [ key ] . width ) ;
746+ }
747+
748+ this . scrollWidth = scrollWidth + 10 /* scrollbar */ ;
749+ } ) ;
688750 }
689751
690752 public focusNextPage ( eventPayload ?: any ) : void {
@@ -742,11 +804,25 @@ export class TreeView extends HeightMap {
742804 return scrollDimensions . height ;
743805 }
744806
745- public set viewHeight ( viewHeight : number ) {
746- this . scrollableElement . setScrollDimensions ( {
747- height : viewHeight ,
748- scrollHeight : this . getTotalHeight ( )
749- } ) ;
807+ public set viewHeight ( height : number ) {
808+ this . scrollableElement . setScrollDimensions ( { height } ) ;
809+ }
810+
811+ private set scrollHeight ( scrollHeight : number ) {
812+ this . scrollableElement . setScrollDimensions ( { scrollHeight } ) ;
813+ }
814+
815+ public get viewWidth ( ) : number {
816+ const scrollDimensions = this . scrollableElement . getScrollDimensions ( ) ;
817+ return scrollDimensions . width ;
818+ }
819+
820+ public set viewWidth ( viewWidth : number ) {
821+ this . scrollableElement . setScrollDimensions ( { width : viewWidth } ) ;
822+ }
823+
824+ private set scrollWidth ( scrollWidth : number ) {
825+ this . scrollableElement . setScrollDimensions ( { scrollWidth } ) ;
750826 }
751827
752828 public get scrollTop ( ) : number {
@@ -756,20 +832,20 @@ export class TreeView extends HeightMap {
756832
757833 public set scrollTop ( scrollTop : number ) {
758834 this . scrollableElement . setScrollDimensions ( {
759- scrollHeight : this . getTotalHeight ( )
835+ scrollHeight : this . getContentHeight ( )
760836 } ) ;
761837 this . scrollableElement . setScrollPosition ( {
762838 scrollTop : scrollTop
763839 } ) ;
764840 }
765841
766842 public getScrollPosition ( ) : number {
767- const height = this . getTotalHeight ( ) - this . viewHeight ;
843+ const height = this . getContentHeight ( ) - this . viewHeight ;
768844 return height <= 0 ? 1 : this . scrollTop / height ;
769845 }
770846
771847 public setScrollPosition ( pos : number ) : void {
772- const height = this . getTotalHeight ( ) - this . viewHeight ;
848+ const height = this . getContentHeight ( ) - this . viewHeight ;
773849 this . scrollTop = height * pos ;
774850 }
775851
@@ -938,6 +1014,21 @@ export class TreeView extends HeightMap {
9381014 }
9391015 }
9401016
1017+ public updateWidth ( item : Model . Item ) : void {
1018+ if ( ! item || ! item . isVisible ( ) ) {
1019+ return ;
1020+ }
1021+
1022+ const viewItem = this . items [ item . id ] ;
1023+
1024+ if ( ! viewItem ) {
1025+ return ;
1026+ }
1027+
1028+ viewItem . updateWidth ( ) ;
1029+ this . updateScrollWidth ( ) ;
1030+ }
1031+
9411032 public getRelativeTop ( item : Model . Item ) : number {
9421033 if ( item && item . isVisible ( ) ) {
9431034 var viewItem = this . items [ item . id ] ;
0 commit comments