@@ -23,6 +23,7 @@ import { ICssStyleCollector, ITheme, IThemeService, registerThemingParticipant }
2323import { SettingsTarget } from 'vs/workbench/parts/preferences/browser/preferencesWidgets' ;
2424import { ISearchResult , ISetting , ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences' ;
2525import { DefaultSettingsEditorModel } from 'vs/workbench/services/preferences/common/preferencesModels' ;
26+ import { renderOcticons } from 'vs/base/browser/ui/octiconLabel/octiconLabel' ;
2627
2728const $ = DOM . $ ;
2829
@@ -113,6 +114,8 @@ export class SettingsDataSource implements IDataSource {
113114 id : `${ group . id } _${ setting . key } ` ,
114115 setting,
115116
117+ isExpanded : false ,
118+
116119 value : displayValue ,
117120 isConfigured,
118121 overriddenScopeList,
@@ -210,6 +213,7 @@ export interface ISettingItemTemplate extends IDisposableTemplate {
210213 categoryElement : HTMLElement ;
211214 labelElement : HTMLElement ;
212215 descriptionElement : HTMLElement ;
216+ expandIndicatorElement : HTMLElement ;
213217 valueElement : HTMLElement ;
214218 overridesElement : HTMLElement ;
215219}
@@ -227,9 +231,9 @@ export interface IButtonRowTemplate extends IDisposableTemplate {
227231 entry ?: IButtonElement ;
228232}
229233
230- const SETTINGS_ENTRY_TEMPLATE_ID = 'settings.entry.template' ;
231- const SETTINGS_GROUP_ENTRY_TEMPLATE_ID = 'settings.group.template' ;
232- const BUTTON_ROW_ENTRY_TEMPLATE = 'settings.buttonRow.template' ;
234+ const SETTINGS_ELEMENT_TEMPLATE_ID = 'settings.entry.template' ;
235+ const SETTINGS_GROUP_ELEMENT_TEMPLATE_ID = 'settings.group.template' ;
236+ const BUTTON_ROW_ELEMENT_TEMPLATE = 'settings.buttonRow.template' ;
233237
234238export interface ISettingChangeEvent {
235239 key : string ;
@@ -247,19 +251,29 @@ export class SettingsRenderer implements IRenderer {
247251 private readonly _onDidOpenSettings : Emitter < void > = new Emitter < void > ( ) ;
248252 public readonly onDidOpenSettings : Event < void > = this . _onDidOpenSettings . event ;
249253
254+ private measureContainer : HTMLElement ;
255+
250256 constructor (
251257 private viewState : ISettingsEditorViewState ,
258+ _measureContainer : HTMLElement ,
252259 @IThemeService private themeService : IThemeService ,
253260 @IContextViewService private contextViewService : IContextViewService
254- ) { }
261+ ) {
262+ this . measureContainer = DOM . append ( _measureContainer , $ ( '.setting-measure-container.monaco-tree-row' ) ) ;
263+ }
255264
256265 getHeight ( tree : ITree , element : TreeElement ) : number {
257266 if ( element . type === TreeItemType . groupTitle ) {
258267 return 30 ;
259268 }
260269
261270 if ( element . type === TreeItemType . setting ) {
262- return 68 ;
271+ const isSelected = this . elementIsSelected ( tree , element ) ;
272+ if ( isSelected ) {
273+ return this . measureSettingElementHeight ( tree , element ) ;
274+ } else {
275+ return 68 ;
276+ }
263277 }
264278
265279 if ( element . type === TreeItemType . buttonRow ) {
@@ -269,32 +283,43 @@ export class SettingsRenderer implements IRenderer {
269283 return 0 ;
270284 }
271285
286+ private measureSettingElementHeight ( tree : ITree , element : ISettingElement ) : number {
287+ const measureHelper = DOM . append ( this . measureContainer , $ ( '.setting-measure-helper' ) ) ;
288+
289+ const template = this . renderSettingTemplate ( measureHelper ) ;
290+ this . renderSettingElement ( tree , element , template , true ) ;
291+
292+ const height = measureHelper . offsetHeight ;
293+ this . measureContainer . removeChild ( measureHelper ) ;
294+ return height ;
295+ }
296+
272297 getTemplateId ( tree : ITree , element : TreeElement ) : string {
273298 if ( element . type === TreeItemType . groupTitle ) {
274- return SETTINGS_GROUP_ENTRY_TEMPLATE_ID ;
299+ return SETTINGS_GROUP_ELEMENT_TEMPLATE_ID ;
275300 }
276301
277302 if ( element . type === TreeItemType . buttonRow ) {
278- return BUTTON_ROW_ENTRY_TEMPLATE ;
303+ return BUTTON_ROW_ELEMENT_TEMPLATE ;
279304 }
280305
281306 if ( element . type === TreeItemType . setting ) {
282- return SETTINGS_ENTRY_TEMPLATE_ID ;
307+ return SETTINGS_ELEMENT_TEMPLATE_ID ;
283308 }
284309
285310 return '' ;
286311 }
287312
288313 renderTemplate ( tree : ITree , templateId : string , container : HTMLElement ) {
289- if ( templateId === SETTINGS_GROUP_ENTRY_TEMPLATE_ID ) {
314+ if ( templateId === SETTINGS_GROUP_ELEMENT_TEMPLATE_ID ) {
290315 return this . renderGroupTitleTemplate ( container ) ;
291316 }
292317
293- if ( templateId === BUTTON_ROW_ENTRY_TEMPLATE ) {
318+ if ( templateId === BUTTON_ROW_ELEMENT_TEMPLATE ) {
294319 return this . renderButtonRowTemplate ( container ) ;
295320 }
296321
297- if ( templateId === SETTINGS_ENTRY_TEMPLATE_ID ) {
322+ if ( templateId === SETTINGS_ELEMENT_TEMPLATE_ID ) {
298323 return this . renderSettingTemplate ( container ) ;
299324 }
300325
@@ -347,6 +372,7 @@ export class SettingsRenderer implements IRenderer {
347372 const labelElement = DOM . append ( titleElement , $ ( 'span.setting-item-label' ) ) ;
348373 const overridesElement = DOM . append ( titleElement , $ ( 'span.setting-item-overrides' ) ) ;
349374 const descriptionElement = DOM . append ( leftElement , $ ( '.setting-item-description' ) ) ;
375+ const expandIndicatorElement = DOM . append ( leftElement , $ ( '.expand-indicator' ) ) ;
350376
351377 const valueElement = DOM . append ( rightElement , $ ( '.setting-item-value' ) ) ;
352378
@@ -359,6 +385,7 @@ export class SettingsRenderer implements IRenderer {
359385 categoryElement,
360386 labelElement,
361387 descriptionElement,
388+ expandIndicatorElement,
362389 valueElement,
363390 overridesElement
364391 } ;
@@ -367,25 +394,33 @@ export class SettingsRenderer implements IRenderer {
367394 }
368395
369396 renderElement ( tree : ITree , element : TreeElement , templateId : string , template : any ) : void {
370- if ( templateId === SETTINGS_ENTRY_TEMPLATE_ID ) {
371- return this . renderSettingElement ( < ISettingElement > element , template ) ;
397+ if ( templateId === SETTINGS_ELEMENT_TEMPLATE_ID ) {
398+ return this . renderSettingElement ( tree , < ISettingElement > element , template ) ;
372399 }
373400
374- if ( templateId === SETTINGS_GROUP_ENTRY_TEMPLATE_ID ) {
401+ if ( templateId === SETTINGS_GROUP_ELEMENT_TEMPLATE_ID ) {
375402 ( < IGroupTitleTemplate > template ) . labelElement . textContent = ( < IGroupElement > element ) . group . title ;
376403 return ;
377404 }
378405
379- if ( templateId === BUTTON_ROW_ENTRY_TEMPLATE ) {
406+ if ( templateId === BUTTON_ROW_ELEMENT_TEMPLATE ) {
380407 return this . renderButtonRowElement ( < IButtonElement > element , template ) ;
381408 }
382409 }
383410
384- private renderSettingElement ( element : ISettingElement , template : ISettingItemTemplate ) : void {
411+ private elementIsSelected ( tree : ITree , element : TreeElement ) : boolean {
412+ const selection = tree . getFocus ( ) ;
413+ const selectedElement : TreeElement = selection ;
414+ return selectedElement && selectedElement . id === element . id ;
415+ }
416+
417+ private renderSettingElement ( tree : ITree , element : ISettingElement , template : ISettingItemTemplate , measuring ?: boolean ) : void {
418+ const isSelected = this . elementIsSelected ( tree , element ) ;
385419 const setting = element . setting ;
386420
387421 template . context = element ;
388422 DOM . toggleClass ( template . parent , 'is-configured' , element . isConfigured ) ;
423+ DOM . toggleClass ( template . parent , 'is-expanded' , isSelected ) ;
389424 template . containerElement . id = element . id ;
390425
391426 const titleTooltip = setting . key ;
@@ -398,9 +433,19 @@ export class SettingsRenderer implements IRenderer {
398433 template . descriptionElement . textContent = element . description ;
399434 template . descriptionElement . title = element . description ;
400435
401- // const expandedHeight = measureSettingItemEntry(entry, that.measureContainer);
402- // entry.isExpandable = expandedHeight > 68;
403- // DOM.toggleClass(template.parent, 'is-expandable', entry.isExpandable);
436+ if ( ! measuring ) {
437+ const expandedHeight = this . measureSettingElementHeight ( tree , element ) ;
438+ const isExpandable = expandedHeight > 68 ;
439+ DOM . toggleClass ( template . parent , 'is-expandable' , isExpandable ) ;
440+
441+ if ( isSelected ) {
442+ template . expandIndicatorElement . innerHTML = renderOcticons ( '$(chevron-up)' ) ;
443+ } else if ( isExpandable ) {
444+ template . expandIndicatorElement . innerHTML = renderOcticons ( '$(chevron-down)' ) ;
445+ } else {
446+ template . expandIndicatorElement . innerHTML = '' ;
447+ }
448+ }
404449
405450 this . renderValue ( element , template ) ;
406451
0 commit comments