diff --git a/src/vs/base/browser/ui/fileLabel/fileLabel.css b/src/vs/base/browser/ui/fileLabel/fileLabel.css deleted file mode 100644 index 6cce52dbc01..00000000000 --- a/src/vs/base/browser/ui/fileLabel/fileLabel.css +++ /dev/null @@ -1,15 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -/* ---------- File label ---------- */ - -.monaco-file-label .file-name { - color: inherit; -} - -.monaco-file-label .file-path { - opacity: 0.7; - margin-left: 0.5em; - font-size: 0.9em; -} \ No newline at end of file diff --git a/src/vs/base/browser/ui/fileLabel/fileLabel.ts b/src/vs/base/browser/ui/fileLabel/fileLabel.ts index 6817c760c32..b5038c1ccc0 100644 --- a/src/vs/base/browser/ui/fileLabel/fileLabel.ts +++ b/src/vs/base/browser/ui/fileLabel/fileLabel.ts @@ -4,69 +4,36 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import 'vs/css!./fileLabel'; -import dom = require('vs/base/browser/dom'); +import {IconLabel} from 'vs/base/browser/ui/iconLabel/iconLabel'; import uri from 'vs/base/common/uri'; import paths = require('vs/base/common/paths'); import types = require('vs/base/common/types'); -import {HighlightedLabel} from 'vs/base/browser/ui/highlightedlabel/highlightedLabel'; -import {IMatch} from 'vs/base/common/filters'; import {IWorkspaceProvider, getPathLabel} from 'vs/base/common/labels'; -export class FileLabel { - private domNode: HTMLElement; - private labelNode: HighlightedLabel; - private directoryNode: HTMLElement; - private basepath: string; - private path: string; - private labelHighlights: IMatch[] = []; +export class FileLabel extends IconLabel { - constructor(container: HTMLElement, arg2?: uri | string, arg3?: uri | string | IWorkspaceProvider) { - this.domNode = dom.append(container, dom.$('.monaco-file-label')); - this.labelNode = new HighlightedLabel(dom.append(this.domNode, dom.$('span.file-name'))); - this.directoryNode = dom.append(this.domNode, dom.$('span.file-path')); + constructor(container: HTMLElement, file: uri, provider: IWorkspaceProvider) { + super(container); - if (arg3) { - this.basepath = getPath(arg3); - } - - if (arg2) { - this.setValue(arg2); - } + this.setFile(file, provider); } - public getHTMLElement(): HTMLElement { - return this.domNode; - } - - public setValue(arg1: uri | string, labelHighlights?: IMatch[]): void { - const newPath = getPath(arg1); - - this.path = newPath; - this.labelHighlights = labelHighlights; - this.render(); - } - - private render(): void { - this.domNode.title = this.path; - this.labelNode.set(paths.basename(this.path), this.labelHighlights); - - const parent = paths.dirname(this.path); - this.directoryNode.textContent = parent && parent !== '.' ? getPathLabel(parent, this.basepath) : ''; + public setFile(file: uri, provider: IWorkspaceProvider): void { + const path = getPath(file); + const parent = paths.dirname(path); + + this.setValue(paths.basename(path), parent && parent !== '.' ? getPathLabel(parent, provider) : '', { title: path }); } } -function getPath(arg1: uri | string | IWorkspaceProvider): string { +function getPath(arg1: uri | IWorkspaceProvider): string { if (!arg1) { return null; } - if (typeof arg1 === 'string') { - return arg1; - } - if (types.isFunction((arg1).getWorkspace)) { const ws = (arg1).getWorkspace(); + return ws ? ws.resource.fsPath : void 0; } diff --git a/src/vs/base/browser/ui/iconLabel/iconLabel.ts b/src/vs/base/browser/ui/iconLabel/iconLabel.ts index bae2db39903..aaf6e567c60 100644 --- a/src/vs/base/browser/ui/iconLabel/iconLabel.ts +++ b/src/vs/base/browser/ui/iconLabel/iconLabel.ts @@ -50,6 +50,12 @@ export class IconLabel { this.descriptionNode.textContent = description || ''; + if (!description) { + dom.addClass(this.descriptionNode, 'empty'); + } else { + dom.removeClass(this.descriptionNode, 'empty'); + } + this.domNode.title = options && options.title ? options.title : ''; const classes = ['monaco-icon-label']; diff --git a/src/vs/base/browser/ui/iconLabel/iconlabel.css b/src/vs/base/browser/ui/iconLabel/iconlabel.css index b2a28b64d04..a1bdfe8645f 100644 --- a/src/vs/base/browser/ui/iconLabel/iconlabel.css +++ b/src/vs/base/browser/ui/iconLabel/iconlabel.css @@ -37,6 +37,10 @@ white-space: pre; /* enable to show labels that include multiple whitespaces */ } +.monaco-icon-label > .label-description.empty { + margin-left: 0; +} + .monaco-icon-label.italic > .label-name, .monaco-icon-label.italic > .label-description { font-style: italic; diff --git a/src/vs/workbench/browser/labels.ts b/src/vs/workbench/browser/labels.ts index 96c9fecb9bd..c7d5ba6e481 100644 --- a/src/vs/workbench/browser/labels.ts +++ b/src/vs/workbench/browser/labels.ts @@ -151,6 +151,7 @@ export class EditorLabel extends ResourceLabel { } export interface IFileLabelOptions extends IResourceLabelOptions { + hideLabel?: boolean; hidePath?: boolean; } @@ -159,7 +160,7 @@ export class FileLabel extends ResourceLabel { public setFile(resource: uri, options: IFileLabelOptions = Object.create(null)): void { this.setLabel({ resource, - name: paths.basename(resource.fsPath), + name: !options.hideLabel ? paths.basename(resource.fsPath) : void 0, description: !options.hidePath ? getPathLabel(paths.dirname(resource.fsPath), this.contextService) : void 0 }, options); } diff --git a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts index eb8935968b1..b9a9717cac3 100644 --- a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts @@ -21,7 +21,7 @@ import {InputBox} from 'vs/base/browser/ui/inputbox/inputBox'; import {$, Builder} from 'vs/base/browser/builder'; import platform = require('vs/base/common/platform'); import glob = require('vs/base/common/glob'); -import {FileLabel} from 'vs/workbench/browser/labels'; +import {FileLabel, IFileLabelOptions} from 'vs/workbench/browser/labels'; import {IDisposable} from 'vs/base/common/lifecycle'; import {ContributableActionProvider} from 'vs/workbench/browser/actionBarRegistry'; import {LocalFileChangeEvent, IFilesConfiguration, ITextFileService} from 'vs/workbench/parts/files/common/files'; @@ -284,10 +284,7 @@ export class FileRenderer extends ActionsRenderer implements IRenderer { // File Rename/Add Input Field const editableData: IEditableData = this.state.getEditableData(stat); if (editableData) { - const item = $('.explorer-item'); - item.appendTo(el); - - return this.renderInputBox(item, tree, stat, editableData); + return this.renderInputBox(el, tree, stat, editableData); } // Label @@ -304,9 +301,15 @@ export class FileRenderer extends ActionsRenderer implements IRenderer { } private renderInputBox(container: Builder, tree: ITree, stat: FileStat, editableData: IEditableData): IElementCallback { + const label = this.instantiationService.createInstance(FileLabel, container.getHTMLElement(), void 0); + + const extraClasses = ['explorer-item']; + const isFolder = stat.isDirectory || (stat instanceof NewStatPlaceholder && stat.isDirectoryPlaceholder()); + const labelOptions: IFileLabelOptions = { hidePath: true, hideLabel: true, isFolder, extraClasses }; + label.setFile(stat.resource, labelOptions); // Input field (when creating a new file or folder or renaming) - const inputBox = new InputBox(container.getHTMLElement(), this.contextViewService, { + const inputBox = new InputBox(label.getHTMLElement(), this.contextViewService, { validationOptions: { validation: editableData.validator, showMessage: true @@ -314,6 +317,11 @@ export class FileRenderer extends ActionsRenderer implements IRenderer { ariaLabel: nls.localize('fileInputAriaLabel', "Type file name. Press Enter to confirm or Escape to cancel.") }); + const parent = paths.dirname(stat.resource.fsPath); + inputBox.onDidChange(value => { + label.setFile(URI.file(paths.join(parent, value)), labelOptions); // update label icon while typing! + }); + const value = stat.name || ''; const lastDot = value.lastIndexOf('.'); @@ -347,7 +355,8 @@ export class FileRenderer extends ActionsRenderer implements IRenderer { }), DOM.addDisposableListener(inputBox.inputElement, 'blur', () => { done(inputBox.isInputValid()); - }) + }), + label ]; return () => done(true); diff --git a/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts b/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts index a64b0c38342..97c8b482681 100644 --- a/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts +++ b/src/vs/workbench/parts/markers/browser/markersTreeViewer.ts @@ -164,6 +164,9 @@ export class Renderer implements IRenderer { } public disposeTemplate(tree: ITree, templateId: string, templateData: any): void { + if (templateId === Renderer.RESOURCE_TEMPLATE_ID) { + (templateData).file.dispose(); + } } }