mirror of
https://github.com/Microsoft/vscode
synced 2024-09-18 01:58:27 +00:00
Merge pull request #65408 from Microsoft/ben/labels
introduce ResourceLabels
This commit is contained in:
commit
51582b9dfe
|
@ -7,7 +7,7 @@ import 'vs/css!./iconlabel';
|
|||
import * as dom from 'vs/base/browser/dom';
|
||||
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
|
||||
import { IMatch } from 'vs/base/common/filters';
|
||||
import { IDisposable, combinedDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export interface IIconLabelCreationOptions {
|
||||
supportHighlights?: boolean;
|
||||
|
@ -116,13 +116,7 @@ export class IconLabel extends Disposable {
|
|||
return this.domNode.element;
|
||||
}
|
||||
|
||||
onClick(callback: (event: MouseEvent) => void): IDisposable {
|
||||
return combinedDisposable([
|
||||
dom.addDisposableListener(this.labelDescriptionContainer.element, dom.EventType.CLICK, (e: MouseEvent) => callback(e)),
|
||||
]);
|
||||
}
|
||||
|
||||
setValue(label?: string, description?: string, options?: IIconLabelValueOptions): void {
|
||||
setLabel(label?: string, description?: string, options?: IIconLabelValueOptions): void {
|
||||
const classes = ['monaco-icon-label'];
|
||||
if (options) {
|
||||
if (options.extraClasses) {
|
||||
|
|
|
@ -468,7 +468,7 @@ class Renderer implements IRenderer<QuickOpenEntry> {
|
|||
options.title = entry.getTooltip();
|
||||
options.descriptionTitle = entry.getDescriptionTooltip() || entry.getDescription(); // tooltip over description because it could overflow
|
||||
options.descriptionMatches = descriptionHighlights || [];
|
||||
data.label.setValue(entry.getLabel(), entry.getDescription(), options);
|
||||
data.label.setLabel(entry.getLabel(), entry.getDescription(), options);
|
||||
|
||||
// Meta
|
||||
data.detail.set(entry.getDetail(), detailHighlights);
|
||||
|
|
|
@ -118,7 +118,7 @@ class FileReferencesTemplate extends Disposable {
|
|||
|
||||
set(element: FileReferences) {
|
||||
let parent = dirname(element.uri);
|
||||
this.file.setValue(getBaseLabel(element.uri), parent ? this._uriLabel.getUriLabel(parent, { relative: true }) : undefined, { title: this._uriLabel.getUriLabel(element.uri) });
|
||||
this.file.setLabel(getBaseLabel(element.uri), parent ? this._uriLabel.getUriLabel(parent, { relative: true }) : undefined, { title: this._uriLabel.getUriLabel(element.uri) });
|
||||
const len = element.children.length;
|
||||
this.badge.setCount(len);
|
||||
if (element.failure) {
|
||||
|
|
|
@ -185,7 +185,7 @@ class Renderer implements IListRenderer<CompletionItem, ISuggestionTemplateData>
|
|||
];
|
||||
}
|
||||
|
||||
data.iconLabel.setValue(suggestion.label, undefined, labelOptions);
|
||||
data.iconLabel.setLabel(suggestion.label, undefined, labelOptions);
|
||||
data.typeLabel.textContent = (suggestion.detail || '').replace(/\n.*$/m, '');
|
||||
|
||||
if (canExpandCompletionItem(element)) {
|
||||
|
|
|
@ -22,11 +22,13 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
|
|||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { getIconClasses, getConfiguredLangId } from 'vs/editor/common/services/getIconClasses';
|
||||
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export interface IResourceLabel {
|
||||
export interface IResourceLabelProps {
|
||||
resource?: uri;
|
||||
name: string;
|
||||
description?: string;
|
||||
resource?: uri;
|
||||
}
|
||||
|
||||
export interface IResourceLabelOptions extends IIconLabelValueOptions {
|
||||
|
@ -34,56 +36,211 @@ export interface IResourceLabelOptions extends IIconLabelValueOptions {
|
|||
fileDecorations?: { colors: boolean, badges: boolean, data?: IDecorationData };
|
||||
}
|
||||
|
||||
export class ResourceLabel extends IconLabel {
|
||||
export interface IFileLabelOptions extends IResourceLabelOptions {
|
||||
hideLabel?: boolean;
|
||||
hidePath?: boolean;
|
||||
}
|
||||
|
||||
export interface IResourceLabel extends IDisposable {
|
||||
readonly element: HTMLElement;
|
||||
readonly onDidRender: Event<void>;
|
||||
|
||||
/**
|
||||
* Most generic way to apply a label with raw information.
|
||||
*/
|
||||
setLabel(label?: string, description?: string, options?: IIconLabelValueOptions): void;
|
||||
|
||||
/**
|
||||
* Convinient method to apply a label by passing a resource along.
|
||||
*
|
||||
* Note: for file resources consider to use the #setFile() method instead.
|
||||
*/
|
||||
setResource(label: IResourceLabelProps, options?: IResourceLabelOptions): void;
|
||||
|
||||
/**
|
||||
* Convinient method to render a file label based on a resource.
|
||||
*/
|
||||
setFile(resource: uri, options?: IFileLabelOptions): void;
|
||||
|
||||
/**
|
||||
* Convinient method to apply a label by passing an editor along.
|
||||
*/
|
||||
setEditor(editor: IEditorInput, options?: IResourceLabelOptions): void;
|
||||
|
||||
/**
|
||||
* Resets the label to be empty.
|
||||
*/
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
export class ResourceLabels extends Disposable {
|
||||
private _widgets: ResourceLabelWidget[] = [];
|
||||
private _labels: IResourceLabel[] = [];
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IExtensionService private extensionService: IExtensionService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IModelService private modelService: IModelService,
|
||||
@IDecorationsService private decorationsService: IDecorationsService,
|
||||
@IThemeService private themeService: IThemeService
|
||||
) {
|
||||
super();
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
get(index: number): IResourceLabel {
|
||||
return this._labels[index];
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
|
||||
// notify when extensions are registered with potentially new languages
|
||||
this._register(this.extensionService.onDidRegisterExtensions(() => this._widgets.forEach(widget => widget.notifyExtensionsRegistered())));
|
||||
|
||||
// notify when model mode changes
|
||||
this._register(this.modelService.onModelModeChanged(e => this._widgets.forEach(widget => widget.notifyModelModeChanged(e))));
|
||||
|
||||
// notify when file decoration changes
|
||||
this._register(this.decorationsService.onDidChangeDecorations(e => this._widgets.forEach(widget => widget.notifyFileDecorationsChanges(e))));
|
||||
|
||||
// notify when theme changes
|
||||
this._register(this.themeService.onThemeChange(() => this._widgets.forEach(widget => widget.notifyThemeChange())));
|
||||
|
||||
// notify when files.associations changes
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(FILES_ASSOCIATIONS_CONFIG)) {
|
||||
this._widgets.forEach(widget => widget.notifyFileAssociationsChange());
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
create(container: HTMLElement, options?: IIconLabelCreationOptions): IResourceLabel {
|
||||
const widget = this.instantiationService.createInstance(ResourceLabelWidget, container, options);
|
||||
|
||||
// Only expose a handle to the outside
|
||||
const label: IResourceLabel = {
|
||||
element: widget.element,
|
||||
onDidRender: widget.onDidRender,
|
||||
setLabel: (label?: string, description?: string, options?: IIconLabelValueOptions) => widget.setLabel(label, description, options),
|
||||
setResource: (label: IResourceLabelProps, options?: IResourceLabelOptions) => widget.setResource(label, options),
|
||||
setEditor: (editor: IEditorInput, options?: IResourceLabelOptions) => widget.setEditor(editor, options),
|
||||
setFile: (resource: uri, options?: IFileLabelOptions) => widget.setFile(resource, options),
|
||||
clear: () => widget.clear(),
|
||||
dispose: () => this.disposeWidget(widget)
|
||||
};
|
||||
|
||||
// Store
|
||||
this._labels.push(label);
|
||||
this._widgets.push(widget);
|
||||
|
||||
return label;
|
||||
}
|
||||
|
||||
private disposeWidget(widget: ResourceLabelWidget): void {
|
||||
const index = this._widgets.indexOf(widget);
|
||||
if (index > -1) {
|
||||
this._widgets.splice(index, 1);
|
||||
this._labels.splice(index, 1);
|
||||
}
|
||||
|
||||
dispose(widget);
|
||||
}
|
||||
|
||||
onVisible(): void {
|
||||
this._widgets.forEach(widget => widget.notifyVisibilityChanged(true));
|
||||
}
|
||||
|
||||
onHidden(): void {
|
||||
this._widgets.forEach(widget => widget.notifyVisibilityChanged(false));
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this._widgets = dispose(this._widgets);
|
||||
this._labels = [];
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
super.dispose();
|
||||
|
||||
this.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: please consider to use ResourceLabels if you are in need
|
||||
* of more than one label for your widget.
|
||||
*/
|
||||
export class ResourceLabel extends ResourceLabels {
|
||||
|
||||
private _label: IResourceLabel;
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
options: IIconLabelCreationOptions,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IModelService modelService: IModelService,
|
||||
@IDecorationsService decorationsService: IDecorationsService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@ILabelService labelService: ILabelService
|
||||
) {
|
||||
super(instantiationService, extensionService, configurationService, modelService, decorationsService, themeService);
|
||||
|
||||
this._label = this._register(this.create(container, options));
|
||||
}
|
||||
|
||||
get element(): IResourceLabel {
|
||||
return this._label;
|
||||
}
|
||||
}
|
||||
|
||||
enum Redraw {
|
||||
Basic = 1,
|
||||
Full = 2
|
||||
}
|
||||
|
||||
class ResourceLabelWidget extends IconLabel {
|
||||
|
||||
private _onDidRender = this._register(new Emitter<void>());
|
||||
get onDidRender(): Event<void> { return this._onDidRender.event; }
|
||||
|
||||
private label: IResourceLabel;
|
||||
private label: IResourceLabelProps;
|
||||
private options: IResourceLabelOptions;
|
||||
private computedIconClasses: string[];
|
||||
private lastKnownConfiguredLangId: string;
|
||||
private computedPathLabel: string;
|
||||
|
||||
private needsRedraw: Redraw;
|
||||
private isHidden: boolean = false;
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
options: IIconLabelCreationOptions,
|
||||
@IExtensionService private extensionService: IExtensionService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IModeService private modeService: IModeService,
|
||||
@IModelService private modelService: IModelService,
|
||||
@IDecorationsService protected decorationsService: IDecorationsService,
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@ILabelService protected labelService: ILabelService
|
||||
@IDecorationsService private decorationsService: IDecorationsService,
|
||||
@ILabelService private labelService: ILabelService,
|
||||
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService
|
||||
) {
|
||||
super(container, options);
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
private registerListeners(): void {
|
||||
notifyVisibilityChanged(visible: boolean): void {
|
||||
if (visible === this.isHidden) {
|
||||
this.isHidden = !visible;
|
||||
|
||||
// update when extensions are registered with potentially new languages
|
||||
this._register(this.extensionService.onDidRegisterExtensions(() => this.render(true /* clear cache */)));
|
||||
|
||||
// react to model mode changes
|
||||
this._register(this.modelService.onModelModeChanged(e => this.onModelModeChanged(e)));
|
||||
|
||||
// react to file decoration changes
|
||||
this._register(this.decorationsService.onDidChangeDecorations(this.onFileDecorationsChanges, this));
|
||||
|
||||
// react to theme changes
|
||||
this._register(this.themeService.onThemeChange(() => this.render(false)));
|
||||
|
||||
// react to files.associations changes
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(FILES_ASSOCIATIONS_CONFIG)) {
|
||||
this.render(true /* clear cache */);
|
||||
if (visible && this.needsRedraw) {
|
||||
this.render(this.needsRedraw === Redraw.Basic ? false : true);
|
||||
this.needsRedraw = void 0;
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
private onModelModeChanged(e: { model: ITextModel; oldModeId: string; }): void {
|
||||
notifyModelModeChanged(e: { model: ITextModel; oldModeId: string; }): void {
|
||||
if (!this.label || !this.label.resource) {
|
||||
return; // only update if label exists
|
||||
}
|
||||
|
@ -103,7 +260,7 @@ export class ResourceLabel extends IconLabel {
|
|||
}
|
||||
}
|
||||
|
||||
private onFileDecorationsChanges(e: IResourceDecorationChangeEvent): void {
|
||||
notifyFileDecorationsChanges(e: IResourceDecorationChangeEvent): void {
|
||||
if (!this.options || !this.label || !this.label.resource) {
|
||||
return;
|
||||
}
|
||||
|
@ -113,7 +270,19 @@ export class ResourceLabel extends IconLabel {
|
|||
}
|
||||
}
|
||||
|
||||
setLabel(label: IResourceLabel, options?: IResourceLabelOptions): void {
|
||||
notifyExtensionsRegistered(): void {
|
||||
this.render(true);
|
||||
}
|
||||
|
||||
notifyThemeChange(): void {
|
||||
this.render(false);
|
||||
}
|
||||
|
||||
notifyFileAssociationsChange(): void {
|
||||
this.render(true);
|
||||
}
|
||||
|
||||
setResource(label: IResourceLabelProps, options?: IResourceLabelOptions): void {
|
||||
const hasResourceChanged = this.hasResourceChanged(label, options);
|
||||
|
||||
this.label = label;
|
||||
|
@ -126,7 +295,7 @@ export class ResourceLabel extends IconLabel {
|
|||
this.render(hasResourceChanged);
|
||||
}
|
||||
|
||||
private hasResourceChanged(label: IResourceLabel, options: IResourceLabelOptions): boolean {
|
||||
private hasResourceChanged(label: IResourceLabelProps, options: IResourceLabelOptions): boolean {
|
||||
const newResource = label ? label.resource : void 0;
|
||||
const oldResource = this.label ? this.label.resource : void 0;
|
||||
|
||||
|
@ -152,6 +321,39 @@ export class ResourceLabel extends IconLabel {
|
|||
return true;
|
||||
}
|
||||
|
||||
setEditor(editor: IEditorInput, options?: IResourceLabelOptions): void {
|
||||
this.setResource({
|
||||
resource: toResource(editor, { supportSideBySide: true }),
|
||||
name: editor.getName(),
|
||||
description: editor.getDescription()
|
||||
}, options);
|
||||
}
|
||||
|
||||
setFile(resource: uri, options?: IFileLabelOptions): void {
|
||||
const hideLabel = options && options.hideLabel;
|
||||
let name: string;
|
||||
if (!hideLabel) {
|
||||
if (options && options.fileKind === FileKind.ROOT_FOLDER) {
|
||||
const workspaceFolder = this.contextService.getWorkspaceFolder(resource);
|
||||
if (workspaceFolder) {
|
||||
name = workspaceFolder.name;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
name = resources.basenameOrAuthority(resource);
|
||||
}
|
||||
}
|
||||
|
||||
let description: string;
|
||||
const hidePath = (options && options.hidePath) || (resource.scheme === Schemas.untitled && !this.untitledEditorService.hasAssociatedFilePath(resource));
|
||||
if (!hidePath) {
|
||||
description = this.labelService.getUriLabel(resources.dirname(resource), { relative: true });
|
||||
}
|
||||
|
||||
this.setResource({ resource, name, description }, options);
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
this.label = void 0;
|
||||
this.options = void 0;
|
||||
|
@ -159,10 +361,22 @@ export class ResourceLabel extends IconLabel {
|
|||
this.computedIconClasses = void 0;
|
||||
this.computedPathLabel = void 0;
|
||||
|
||||
this.setValue();
|
||||
this.setLabel();
|
||||
}
|
||||
|
||||
private render(clearIconCache: boolean): void {
|
||||
if (this.isHidden) {
|
||||
if (!this.needsRedraw) {
|
||||
this.needsRedraw = clearIconCache ? Redraw.Full : Redraw.Basic;
|
||||
}
|
||||
|
||||
if (this.needsRedraw === Redraw.Basic && clearIconCache) {
|
||||
this.needsRedraw = Redraw.Full;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.label) {
|
||||
const configuredLangId = getConfiguredLangId(this.modelService, this.label.resource);
|
||||
if (this.lastKnownConfiguredLangId !== configuredLangId) {
|
||||
|
@ -231,7 +445,7 @@ export class ResourceLabel extends IconLabel {
|
|||
}
|
||||
}
|
||||
|
||||
this.setValue(label, this.label.description, iconLabelOptions);
|
||||
this.setLabel(label, this.label.description, iconLabelOptions);
|
||||
|
||||
this._onDidRender.fire();
|
||||
}
|
||||
|
@ -246,63 +460,3 @@ export class ResourceLabel extends IconLabel {
|
|||
this.computedPathLabel = void 0;
|
||||
}
|
||||
}
|
||||
|
||||
export class EditorLabel extends ResourceLabel {
|
||||
|
||||
setEditor(editor: IEditorInput, options?: IResourceLabelOptions): void {
|
||||
this.setLabel({
|
||||
resource: toResource(editor, { supportSideBySide: true }),
|
||||
name: editor.getName(),
|
||||
description: editor.getDescription()
|
||||
}, options);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IFileLabelOptions extends IResourceLabelOptions {
|
||||
hideLabel?: boolean;
|
||||
hidePath?: boolean;
|
||||
}
|
||||
|
||||
export class FileLabel extends ResourceLabel {
|
||||
|
||||
constructor(
|
||||
container: HTMLElement,
|
||||
options: IIconLabelCreationOptions,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IModeService modeService: IModeService,
|
||||
@IModelService modelService: IModelService,
|
||||
@IDecorationsService decorationsService: IDecorationsService,
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IUntitledEditorService private untitledEditorService: IUntitledEditorService,
|
||||
@ILabelService labelService: ILabelService
|
||||
) {
|
||||
super(container, options, extensionService, configurationService, modeService, modelService, decorationsService, themeService, labelService);
|
||||
}
|
||||
|
||||
setFile(resource: uri, options?: IFileLabelOptions): void {
|
||||
const hideLabel = options && options.hideLabel;
|
||||
let name: string;
|
||||
if (!hideLabel) {
|
||||
if (options && options.fileKind === FileKind.ROOT_FOLDER) {
|
||||
const workspaceFolder = this.contextService.getWorkspaceFolder(resource);
|
||||
if (workspaceFolder) {
|
||||
name = workspaceFolder.name;
|
||||
}
|
||||
}
|
||||
|
||||
if (!name) {
|
||||
name = resources.basenameOrAuthority(resource);
|
||||
}
|
||||
}
|
||||
|
||||
let description: string;
|
||||
const hidePath = (options && options.hidePath) || (resource.scheme === Schemas.untitled && !this.untitledEditorService.hasAssociatedFilePath(resource));
|
||||
if (!hidePath) {
|
||||
description = this.labelService.getUriLabel(resources.dirname(resource), { relative: true });
|
||||
}
|
||||
|
||||
this.setLabel({ resource, name, description }, options);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ import { ColorIdentifier, ColorFunction } from 'vs/platform/theme/common/colorRe
|
|||
import { attachBreadcrumbsStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { FileLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { BreadcrumbsConfig, IBreadcrumbsService } from 'vs/workbench/browser/parts/editor/breadcrumbs';
|
||||
import { BreadcrumbElement, EditorBreadcrumbsModel, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel';
|
||||
import { BreadcrumbsPicker, createBreadcrumbsPicker } from 'vs/workbench/browser/parts/editor/breadcrumbsPicker';
|
||||
|
@ -78,8 +78,8 @@ class Item extends BreadcrumbsItem {
|
|||
render(container: HTMLElement): void {
|
||||
if (this.element instanceof FileElement) {
|
||||
// file/folder
|
||||
let label = this._instantiationService.createInstance(FileLabel, container, {});
|
||||
label.setFile(this.element.uri, {
|
||||
let label = this._instantiationService.createInstance(ResourceLabel, container, {});
|
||||
label.element.setFile(this.element.uri, {
|
||||
hidePath: true,
|
||||
hideIcon: this.element.kind === FileKind.FOLDER || !this.options.showFileIcons,
|
||||
fileKind: this.element.kind,
|
||||
|
@ -98,7 +98,7 @@ class Item extends BreadcrumbsItem {
|
|||
} else if (this.element instanceof OutlineGroup) {
|
||||
// provider
|
||||
let label = new IconLabel(container);
|
||||
label.setValue(this.element.provider.displayName);
|
||||
label.setLabel(this.element.provider.displayName);
|
||||
this._disposables.push(label);
|
||||
|
||||
} else if (this.element instanceof OutlineElement) {
|
||||
|
@ -111,7 +111,7 @@ class Item extends BreadcrumbsItem {
|
|||
}
|
||||
let label = new IconLabel(container);
|
||||
let title = this.element.symbol.name.replace(/\r|\n|\r\n/g, '\u23CE');
|
||||
label.setValue(title);
|
||||
label.setLabel(title);
|
||||
this._disposables.push(label);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ import { IConstructorSignature1, IInstantiationService } from 'vs/platform/insta
|
|||
import { HighlightingWorkbenchTree, IHighlighter, IHighlightingTreeConfiguration, IHighlightingTreeOptions } from 'vs/platform/list/browser/listService';
|
||||
import { breadcrumbsPickerBackground, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IWorkspace, IWorkspaceContextService, IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
import { FileLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { BreadcrumbsConfig } from 'vs/workbench/browser/parts/editor/breadcrumbs';
|
||||
import { BreadcrumbElement, FileElement } from 'vs/workbench/browser/parts/editor/breadcrumbsModel';
|
||||
import { IFileIconTheme, IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
|
@ -329,7 +329,7 @@ export class FileHighlighter implements IHighlighter {
|
|||
export class FileRenderer implements IRenderer {
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
private readonly _labels: ResourceLabels,
|
||||
@IConfigurationService private readonly _configService: IConfigurationService,
|
||||
) { }
|
||||
|
||||
|
@ -342,10 +342,10 @@ export class FileRenderer implements IRenderer {
|
|||
}
|
||||
|
||||
renderTemplate(tree: ITree, templateId: string, container: HTMLElement) {
|
||||
return this._instantiationService.createInstance(FileLabel, container, { supportHighlights: true });
|
||||
return this._labels.create(container, { supportHighlights: true });
|
||||
}
|
||||
|
||||
renderElement(tree: ITree, element: IFileStat | IWorkspaceFolder, templateId: string, templateData: FileLabel): void {
|
||||
renderElement(tree: ITree, element: IFileStat | IWorkspaceFolder, templateId: string, templateData: IResourceLabel): void {
|
||||
let fileDecorations = this._configService.getValue<{ colors: boolean, badges: boolean }>('explorer.decorations');
|
||||
let resource: URI;
|
||||
let fileKind: FileKind;
|
||||
|
@ -365,7 +365,7 @@ export class FileRenderer implements IRenderer {
|
|||
});
|
||||
}
|
||||
|
||||
disposeTemplate(tree: ITree, templateId: string, templateData: FileLabel): void {
|
||||
disposeTemplate(tree: ITree, templateId: string, templateData: IResourceLabel): void {
|
||||
templateData.dispose();
|
||||
}
|
||||
}
|
||||
|
@ -427,7 +427,9 @@ export class BreadcrumbsFilePicker extends BreadcrumbsPicker {
|
|||
this._disposables.push(filter);
|
||||
|
||||
config.dataSource = this._instantiationService.createInstance(FileDataSource);
|
||||
config.renderer = this._instantiationService.createInstance(FileRenderer);
|
||||
const labels = this._instantiationService.createInstance(ResourceLabels);
|
||||
this._disposables.push(labels);
|
||||
config.renderer = this._instantiationService.createInstance(FileRenderer, labels);
|
||||
config.sorter = new FileSorter();
|
||||
config.highlighter = new FileHighlighter();
|
||||
config.filter = filter;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import 'vs/css!./media/notabstitlecontrol';
|
||||
import { toResource, Verbosity, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { TitleControl, IToolbarActions } from 'vs/workbench/browser/parts/editor/titleControl';
|
||||
import { ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabel, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { TAB_ACTIVE_FOREGROUND, TAB_UNFOCUSED_ACTIVE_FOREGROUND } from 'vs/workbench/common/theme';
|
||||
import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
|
||||
import { addDisposableListener, EventType, addClass, EventHelper, removeClass, toggleClass } from 'vs/base/browser/dom';
|
||||
|
@ -22,7 +22,7 @@ interface IRenderedEditorLabel {
|
|||
|
||||
export class NoTabsTitleControl extends TitleControl {
|
||||
private titleContainer: HTMLElement;
|
||||
private editorLabel: ResourceLabel;
|
||||
private editorLabel: IResourceLabel;
|
||||
private activeLabel: IRenderedEditorLabel = Object.create(null);
|
||||
|
||||
protected create(parent: HTMLElement): void {
|
||||
|
@ -40,8 +40,8 @@ export class NoTabsTitleControl extends TitleControl {
|
|||
this.titleContainer.appendChild(labelContainer);
|
||||
|
||||
// Editor Label
|
||||
this.editorLabel = this._register(this.instantiationService.createInstance(ResourceLabel, labelContainer, void 0));
|
||||
this._register(this.editorLabel.onClick(e => this.onTitleLabelClick(e)));
|
||||
this.editorLabel = this._register(this.instantiationService.createInstance(ResourceLabel, labelContainer, void 0)).element;
|
||||
this._register(addDisposableListener(this.editorLabel.element, EventType.CLICK, e => this.onTitleLabelClick(e)));
|
||||
|
||||
// Breadcrumbs
|
||||
this.createBreadcrumbsControl(labelContainer, { showFileIcons: false, showSymbolIcons: true, showDecorationColors: false, breadcrumbsBackground: () => Color.transparent });
|
||||
|
@ -244,7 +244,7 @@ export class NoTabsTitleControl extends TitleControl {
|
|||
title = ''; // dont repeat what is already shown
|
||||
}
|
||||
|
||||
this.editorLabel.setLabel({ name, description, resource }, { title, italic: !isEditorPinned, extraClasses: ['no-tabs', 'title-label'] });
|
||||
this.editorLabel.setResource({ name, description, resource }, { title, italic: !isEditorPinned, extraClasses: ['no-tabs', 'title-label'] });
|
||||
if (isGroupActive) {
|
||||
this.editorLabel.element.style.color = this.getColor(TAB_ACTIVE_FOREGROUND);
|
||||
} else {
|
||||
|
|
|
@ -10,7 +10,7 @@ import { toResource, GroupIdentifier, IEditorInput, Verbosity, EditorCommandsCon
|
|||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { EventType as TouchEventType, GestureEvent, Gesture } from 'vs/base/browser/touch';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
@ -57,7 +57,7 @@ export class TabsTitleControl extends TitleControl {
|
|||
private tabsScrollbar: ScrollableElement;
|
||||
private closeOneEditorAction: CloseOneEditorAction;
|
||||
|
||||
private tabLabelWidgets: ResourceLabel[] = [];
|
||||
private tabResourceLabels: ResourceLabels;
|
||||
private tabLabels: IEditorInputLabel[] = [];
|
||||
private tabDisposeables: IDisposable[] = [];
|
||||
|
||||
|
@ -123,6 +123,9 @@ export class TabsTitleControl extends TitleControl {
|
|||
addClass(breadcrumbsContainer, 'tabs-breadcrumbs');
|
||||
this.titleContainer.appendChild(breadcrumbsContainer);
|
||||
this.createBreadcrumbsControl(breadcrumbsContainer, { showFileIcons: true, showSymbolIcons: true, showDecorationColors: false, breadcrumbsBackground: breadcrumbsBackground });
|
||||
|
||||
// Tab Labels
|
||||
this.tabResourceLabels = this._register(this.instantiationService.createInstance(ResourceLabels));
|
||||
}
|
||||
|
||||
private createTabsScrollbar(scrollable: HTMLElement): ScrollableElement {
|
||||
|
@ -295,7 +298,6 @@ export class TabsTitleControl extends TitleControl {
|
|||
(this.tabsContainer.lastChild as HTMLElement).remove();
|
||||
|
||||
// Remove associated tab label and widget
|
||||
this.tabLabelWidgets.pop();
|
||||
this.tabDisposeables.pop().dispose();
|
||||
}
|
||||
|
||||
|
@ -311,7 +313,7 @@ export class TabsTitleControl extends TitleControl {
|
|||
clearNode(this.tabsContainer);
|
||||
|
||||
this.tabDisposeables = dispose(this.tabDisposeables);
|
||||
this.tabLabelWidgets = [];
|
||||
this.tabResourceLabels.clear();
|
||||
this.tabLabels = [];
|
||||
|
||||
this.clearEditorActionsToolbar();
|
||||
|
@ -395,12 +397,12 @@ export class TabsTitleControl extends TitleControl {
|
|||
this.redraw();
|
||||
}
|
||||
|
||||
private withTab(editor: IEditorInput, fn: (tabContainer: HTMLElement, tabLabelWidget: ResourceLabel, tabLabel: IEditorInputLabel) => void): void {
|
||||
private withTab(editor: IEditorInput, fn: (tabContainer: HTMLElement, tabLabelWidget: IResourceLabel, tabLabel: IEditorInputLabel) => void): void {
|
||||
const editorIndex = this.group.getIndexOfEditor(editor);
|
||||
|
||||
const tabContainer = this.tabsContainer.children[editorIndex] as HTMLElement;
|
||||
if (tabContainer) {
|
||||
fn(tabContainer, this.tabLabelWidgets[editorIndex], this.tabLabels[editorIndex]);
|
||||
fn(tabContainer, this.tabResourceLabels.get(editorIndex), this.tabLabels[editorIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -422,8 +424,7 @@ export class TabsTitleControl extends TitleControl {
|
|||
tabContainer.appendChild(tabBorderTopContainer);
|
||||
|
||||
// Tab Editor Label
|
||||
const editorLabel = this.instantiationService.createInstance(ResourceLabel, tabContainer, void 0);
|
||||
this.tabLabelWidgets.push(editorLabel);
|
||||
const editorLabel = this.tabResourceLabels.create(tabContainer);
|
||||
|
||||
// Tab Close Button
|
||||
const tabCloseContainer = document.createElement('div');
|
||||
|
@ -806,16 +807,16 @@ export class TabsTitleControl extends TitleControl {
|
|||
this.layout(this.dimension);
|
||||
}
|
||||
|
||||
private forEachTab(fn: (editor: IEditorInput, index: number, tabContainer: HTMLElement, tabLabelWidget: ResourceLabel, tabLabel: IEditorInputLabel) => void): void {
|
||||
private forEachTab(fn: (editor: IEditorInput, index: number, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel, tabLabel: IEditorInputLabel) => void): void {
|
||||
this.group.editors.forEach((editor, index) => {
|
||||
const tabContainer = this.tabsContainer.children[index] as HTMLElement;
|
||||
if (tabContainer) {
|
||||
fn(editor, index, tabContainer, this.tabLabelWidgets[index], this.tabLabels[index]);
|
||||
fn(editor, index, tabContainer, this.tabResourceLabels.get(index), this.tabLabels[index]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private redrawTab(editor: IEditorInput, index: number, tabContainer: HTMLElement, tabLabelWidget: ResourceLabel, tabLabel: IEditorInputLabel): void {
|
||||
private redrawTab(editor: IEditorInput, index: number, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel, tabLabel: IEditorInputLabel): void {
|
||||
|
||||
// Label
|
||||
this.redrawLabel(editor, tabContainer, tabLabelWidget, tabLabel);
|
||||
|
@ -848,7 +849,7 @@ export class TabsTitleControl extends TitleControl {
|
|||
this.redrawEditorActiveAndDirty(this.accessor.activeGroup === this.group, editor, tabContainer, tabLabelWidget);
|
||||
}
|
||||
|
||||
private redrawLabel(editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: ResourceLabel, tabLabel: IEditorInputLabel): void {
|
||||
private redrawLabel(editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel, tabLabel: IEditorInputLabel): void {
|
||||
const name = tabLabel.name;
|
||||
const description = tabLabel.description || '';
|
||||
const title = tabLabel.title || '';
|
||||
|
@ -858,10 +859,10 @@ export class TabsTitleControl extends TitleControl {
|
|||
tabContainer.title = title;
|
||||
|
||||
// Label
|
||||
tabLabelWidget.setLabel({ name, description, resource: toResource(editor, { supportSideBySide: true }) }, { title, extraClasses: ['tab-label'], italic: !this.group.isPinned(editor) });
|
||||
tabLabelWidget.setResource({ name, description, resource: toResource(editor, { supportSideBySide: true }) }, { title, extraClasses: ['tab-label'], italic: !this.group.isPinned(editor) });
|
||||
}
|
||||
|
||||
private redrawEditorActiveAndDirty(isGroupActive: boolean, editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: ResourceLabel): void {
|
||||
private redrawEditorActiveAndDirty(isGroupActive: boolean, editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel): void {
|
||||
const isTabActive = this.group.isActive(editor);
|
||||
|
||||
const hasModifiedBorderTop = this.doRedrawEditorDirty(isGroupActive, isTabActive, editor, tabContainer);
|
||||
|
@ -869,7 +870,7 @@ export class TabsTitleControl extends TitleControl {
|
|||
this.doRedrawEditorActive(isGroupActive, !hasModifiedBorderTop, editor, tabContainer, tabLabelWidget);
|
||||
}
|
||||
|
||||
private doRedrawEditorActive(isGroupActive: boolean, allowBorderTop: boolean, editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: ResourceLabel): void {
|
||||
private doRedrawEditorActive(isGroupActive: boolean, allowBorderTop: boolean, editor: IEditorInput, tabContainer: HTMLElement, tabLabelWidget: IResourceLabel): void {
|
||||
|
||||
// Tab is active
|
||||
if (this.group.isActive(editor)) {
|
||||
|
|
|
@ -144,7 +144,7 @@ class ListElementRenderer implements IListRenderer<ListElement, IListElementTemp
|
|||
options.descriptionTitle = element.saneDescription;
|
||||
options.descriptionMatches = descriptionHighlights || [];
|
||||
options.extraClasses = element.item.iconClasses;
|
||||
data.label.setValue(element.saneLabel, element.saneDescription, options);
|
||||
data.label.setLabel(element.saneLabel, element.saneDescription, options);
|
||||
|
||||
// Meta
|
||||
data.detail.set(element.saneDetail, detailHighlights);
|
||||
|
|
|
@ -23,7 +23,7 @@ import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/work
|
|||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import * as DOM from 'vs/base/browser/dom';
|
||||
import { IDataSource, ITree, IRenderer, ContextMenuEvent } from 'vs/base/parts/tree/browser/tree';
|
||||
import { ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ActionBar, IActionItemProvider, ActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { basename } from 'vs/base/common/paths';
|
||||
|
@ -194,6 +194,7 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
|||
private _messageValue: string | IMarkdownString | undefined;
|
||||
private messageElement: HTMLDivElement;
|
||||
private tree: FileIconThemableWorkbenchTree;
|
||||
private treeLabels: ResourceLabels;
|
||||
private root: ITreeItem;
|
||||
private elementsToRefresh: ITreeItem[] = [];
|
||||
private menus: TitleMenus;
|
||||
|
@ -349,6 +350,14 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
|||
}
|
||||
}
|
||||
|
||||
if (this.treeLabels) {
|
||||
if (this.isVisible) {
|
||||
this.treeLabels.onVisible();
|
||||
} else {
|
||||
this.treeLabels.onHidden();
|
||||
}
|
||||
}
|
||||
|
||||
this._onDidChangeVisibility.fire(this.isVisible);
|
||||
}
|
||||
|
||||
|
@ -382,13 +391,13 @@ export class CustomTreeView extends Disposable implements ITreeView {
|
|||
|
||||
private createTree() {
|
||||
const actionItemProvider = (action: IAction) => action instanceof MenuItemAction ? this.instantiationService.createInstance(ContextAwareMenuItemActionItem, action) : undefined;
|
||||
const menus = this.instantiationService.createInstance(TreeMenus, this.id);
|
||||
const menus = this._register(this.instantiationService.createInstance(TreeMenus, this.id));
|
||||
this.treeLabels = this._register(this.instantiationService.createInstance(ResourceLabels));
|
||||
const dataSource = this.instantiationService.createInstance(TreeDataSource, this, this.container);
|
||||
const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, menus, actionItemProvider);
|
||||
const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, menus, this.treeLabels, actionItemProvider);
|
||||
const controller = this.instantiationService.createInstance(TreeController, this.id, menus);
|
||||
this.tree = this.instantiationService.createInstance(FileIconThemableWorkbenchTree, this.treeContainer, { dataSource, renderer, controller }, {});
|
||||
this.tree = this._register(this.instantiationService.createInstance(FileIconThemableWorkbenchTree, this.treeContainer, { dataSource, renderer, controller }, {}));
|
||||
this.tree.contextKeyService.createKey<boolean>(this.id, true);
|
||||
this._register(this.tree);
|
||||
this._register(this.tree.onDidChangeSelection(e => this.onSelection(e)));
|
||||
this._register(this.tree.onDidExpandItem(e => this._onDidExpandItem.fire(e.item.getElement())));
|
||||
this._register(this.tree.onDidCollapseItem(e => this._onDidCollapseItem.fire(e.item.getElement())));
|
||||
|
@ -593,7 +602,7 @@ class TreeDataSource implements IDataSource {
|
|||
}
|
||||
|
||||
interface ITreeExplorerTemplateData {
|
||||
resourceLabel: ResourceLabel;
|
||||
resourceLabel: IResourceLabel;
|
||||
icon: HTMLElement;
|
||||
actionBar: ActionBar;
|
||||
aligner: Aligner;
|
||||
|
@ -632,8 +641,8 @@ class TreeRenderer implements IRenderer {
|
|||
constructor(
|
||||
private treeViewId: string,
|
||||
private menus: TreeMenus,
|
||||
private labels: ResourceLabels,
|
||||
private actionItemProvider: IActionItemProvider,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IWorkbenchThemeService private themeService: IWorkbenchThemeService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@ILabelService private labelService: ILabelService
|
||||
|
@ -652,7 +661,7 @@ class TreeRenderer implements IRenderer {
|
|||
DOM.addClass(container, 'custom-view-tree-node-item');
|
||||
|
||||
const icon = DOM.append(container, DOM.$('.custom-view-tree-node-item-icon'));
|
||||
const resourceLabel = this.instantiationService.createInstance(ResourceLabel, container, { supportHighlights: true, donotSupportOcticons: true });
|
||||
const resourceLabel = this.labels.create(container, { supportHighlights: true, donotSupportOcticons: true });
|
||||
DOM.addClass(resourceLabel.element, 'custom-view-tree-node-item-resourceLabel');
|
||||
const actionsContainer = DOM.append(resourceLabel.element, DOM.$('.actions'));
|
||||
const actionBar = new ActionBar(actionsContainer, {
|
||||
|
@ -674,14 +683,13 @@ class TreeRenderer implements IRenderer {
|
|||
const title = node.tooltip ? node.tooltip : resource ? void 0 : label;
|
||||
|
||||
// reset
|
||||
templateData.resourceLabel.clear();
|
||||
templateData.actionBar.clear();
|
||||
|
||||
if (resource || node.themeIcon) {
|
||||
const fileDecorations = this.configurationService.getValue<{ colors: boolean, badges: boolean }>('explorer.decorations');
|
||||
templateData.resourceLabel.setLabel({ name: label, description, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, hideIcon: !!iconUrl, fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
|
||||
templateData.resourceLabel.setResource({ name: label, description, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, hideIcon: !!iconUrl, fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
|
||||
} else {
|
||||
templateData.resourceLabel.setLabel({ name: label, description }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
|
||||
templateData.resourceLabel.setResource({ name: label, description }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
|
||||
}
|
||||
|
||||
templateData.icon.style.backgroundImage = iconUrl ? `url('${iconUrl.toString(true)}')` : '';
|
||||
|
|
|
@ -23,11 +23,13 @@ import { ICommandService } from 'vs/platform/commands/common/commands';
|
|||
import { textLinkForeground, textLinkActiveForeground, focusBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { ResourceLabels } from 'vs/workbench/browser/labels';
|
||||
|
||||
export const COMMENTS_PANEL_ID = 'workbench.panel.comments';
|
||||
export const COMMENTS_PANEL_TITLE = 'Comments';
|
||||
|
||||
export class CommentsPanel extends Panel {
|
||||
private treeLabels: ResourceLabels;
|
||||
private tree: WorkbenchTree;
|
||||
private treeContainer: HTMLElement;
|
||||
private messageBoxContainer: HTMLElement;
|
||||
|
@ -129,9 +131,11 @@ export class CommentsPanel extends Panel {
|
|||
}
|
||||
|
||||
private createTree(): void {
|
||||
this.tree = this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, {
|
||||
this.treeLabels = this._register(this.instantiationService.createInstance(ResourceLabels));
|
||||
|
||||
this.tree = this._register(this.instantiationService.createInstance(WorkbenchTree, this.treeContainer, {
|
||||
dataSource: new CommentsDataSource(),
|
||||
renderer: new CommentsModelRenderer(this.instantiationService, this.openerService),
|
||||
renderer: new CommentsModelRenderer(this.treeLabels, this.openerService),
|
||||
accessibilityProvider: new DefaultAccessibilityProvider,
|
||||
controller: new DefaultController(),
|
||||
dnd: new DefaultDragAndDrop(),
|
||||
|
@ -139,7 +143,7 @@ export class CommentsPanel extends Panel {
|
|||
}, {
|
||||
twistiePixels: 20,
|
||||
ariaLabel: COMMENTS_PANEL_TITLE
|
||||
});
|
||||
}));
|
||||
|
||||
const commentsNavigator = this._register(new TreeResourceNavigator(this.tree, { openOnFocus: true }));
|
||||
this._register(Event.debounce(commentsNavigator.openResource, (last, event) => event, 100, true)(options => {
|
||||
|
@ -172,7 +176,6 @@ export class CommentsPanel extends Panel {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
const threadToReveal = element instanceof ResourceWithCommentThreads ? element.commentThreads[0].threadId : element.threadId;
|
||||
const commentToReveal = element instanceof ResourceWithCommentThreads ? element.commentThreads[0].comment : element.comment;
|
||||
|
||||
|
@ -237,6 +240,14 @@ export class CommentsPanel extends Panel {
|
|||
this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.treeLabels) {
|
||||
if (visible) {
|
||||
this.treeLabels.onVisible();
|
||||
} else {
|
||||
this.treeLabels.onHidden();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private refresh(): void {
|
||||
|
|
|
@ -10,9 +10,8 @@ import { onUnexpectedError } from 'vs/base/common/errors';
|
|||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IDataSource, IFilter, IRenderer as ITreeRenderer, ITree } from 'vs/base/parts/tree/browser/tree';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { FileLabel } from 'vs/workbench/browser/labels';
|
||||
import { IResourceLabel, ResourceLabels } from 'vs/workbench/browser/labels';
|
||||
import { CommentNode, CommentsModel, ResourceWithCommentThreads } from 'vs/workbench/parts/comments/common/commentModel';
|
||||
|
||||
export class CommentsDataSource implements IDataSource {
|
||||
|
@ -56,7 +55,7 @@ export class CommentsDataSource implements IDataSource {
|
|||
}
|
||||
|
||||
interface IResourceTemplateData {
|
||||
resourceLabel: FileLabel;
|
||||
resourceLabel: IResourceLabel;
|
||||
}
|
||||
|
||||
interface ICommentThreadTemplateData {
|
||||
|
@ -70,9 +69,8 @@ export class CommentsModelRenderer implements ITreeRenderer {
|
|||
private static RESOURCE_ID = 'resource-with-comments';
|
||||
private static COMMENT_ID = 'comment-node';
|
||||
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
private labels: ResourceLabels,
|
||||
@IOpenerService private openerService: IOpenerService
|
||||
) {
|
||||
}
|
||||
|
@ -124,7 +122,7 @@ export class CommentsModelRenderer implements ITreeRenderer {
|
|||
private renderResourceTemplate(container: HTMLElement): IResourceTemplateData {
|
||||
const data = <IResourceTemplateData>Object.create(null);
|
||||
const labelContainer = dom.append(container, dom.$('.resource-container'));
|
||||
data.resourceLabel = this.instantiationService.createInstance(FileLabel, labelContainer, {});
|
||||
data.resourceLabel = this.labels.create(labelContainer);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import { isWindows } from 'vs/base/common/platform';
|
|||
import { URI } from 'vs/base/common/uri';
|
||||
import { ltrim } from 'vs/base/common/strings';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { ResourceLabel, IResourceLabel, IResourceLabelOptions } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IResourceLabelProps, IResourceLabelOptions, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { FileKind } from 'vs/platform/files/common/files';
|
||||
import { IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeRenderer, ITreeNode, ITreeFilter, TreeVisibility, TreeFilterResult, IAsyncDataSource } from 'vs/base/browser/ui/tree/tree';
|
||||
|
@ -32,6 +32,7 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
|
|||
import { WorkbenchAsyncDataTree, IListService, TreeResourceNavigator2 } from 'vs/platform/list/browser/listService';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { DebugContentProvider } from 'vs/workbench/parts/debug/browser/debugContentProvider';
|
||||
import { dispose } from 'vs/base/common/lifecycle';
|
||||
|
||||
const SMART = true;
|
||||
|
||||
|
@ -363,6 +364,7 @@ export class LoadedScriptsView extends ViewletPanel {
|
|||
private treeContainer: HTMLElement;
|
||||
private loadedScriptsItemType: IContextKey<string>;
|
||||
private tree: WorkbenchAsyncDataTree<LoadedScriptsItem, LoadedScriptsItem>;
|
||||
private treeLabels: ResourceLabels;
|
||||
private changeScheduler: RunOnceScheduler;
|
||||
private treeNeedsRefreshOnVisible: boolean;
|
||||
private filter: LoadedScriptsFilter;
|
||||
|
@ -395,10 +397,11 @@ export class LoadedScriptsView extends ViewletPanel {
|
|||
|
||||
const root = new RootTreeItem(this.debugService.getModel(), this.environmentService, this.contextService);
|
||||
|
||||
this.treeLabels = this.instantiationService.createInstance(ResourceLabels);
|
||||
this.disposables.push(this.treeLabels);
|
||||
|
||||
this.tree = new WorkbenchAsyncDataTree(this.treeContainer, new LoadedScriptsDelegate(),
|
||||
[
|
||||
this.instantiationService.createInstance(LoadedScriptsRenderer)
|
||||
],
|
||||
[new LoadedScriptsRenderer(this.treeLabels)],
|
||||
new LoadedScriptsDataSource(),
|
||||
{
|
||||
identityProvider: {
|
||||
|
@ -507,6 +510,13 @@ export class LoadedScriptsView extends ViewletPanel {
|
|||
if (visible && this.treeNeedsRefreshOnVisible) {
|
||||
this.changeScheduler.schedule();
|
||||
}
|
||||
if (this.treeLabels) {
|
||||
if (visible) {
|
||||
this.treeLabels.onVisible();
|
||||
} else {
|
||||
this.treeLabels.onHidden();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -518,7 +528,8 @@ export class LoadedScriptsView extends ViewletPanel {
|
|||
*/
|
||||
|
||||
dispose(): void {
|
||||
this.tree = undefined;
|
||||
this.tree = dispose(this.tree);
|
||||
this.treeLabels = dispose(this.treeLabels);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
@ -549,7 +560,7 @@ class LoadedScriptsDataSource implements IAsyncDataSource<LoadedScriptsItem, Loa
|
|||
}
|
||||
|
||||
interface ILoadedScriptsItemTemplateData {
|
||||
label: ResourceLabel;
|
||||
label: IResourceLabel;
|
||||
}
|
||||
|
||||
class LoadedScriptsRenderer implements ITreeRenderer<BaseTreeItem, void, ILoadedScriptsItemTemplateData> {
|
||||
|
@ -557,7 +568,7 @@ class LoadedScriptsRenderer implements ITreeRenderer<BaseTreeItem, void, ILoaded
|
|||
static readonly ID = 'lsrenderer';
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private instantiationService: IInstantiationService
|
||||
private labels: ResourceLabels
|
||||
) {
|
||||
}
|
||||
|
||||
|
@ -567,7 +578,7 @@ class LoadedScriptsRenderer implements ITreeRenderer<BaseTreeItem, void, ILoaded
|
|||
|
||||
renderTemplate(container: HTMLElement): ILoadedScriptsItemTemplateData {
|
||||
let data: ILoadedScriptsItemTemplateData = Object.create(null);
|
||||
data.label = this.instantiationService.createInstance(ResourceLabel, container, void 0);
|
||||
data.label = this.labels.create(container);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
@ -575,7 +586,7 @@ class LoadedScriptsRenderer implements ITreeRenderer<BaseTreeItem, void, ILoaded
|
|||
|
||||
const element = node.element;
|
||||
|
||||
const label: IResourceLabel = {
|
||||
const label: IResourceLabelProps = {
|
||||
name: element.getLabel()
|
||||
};
|
||||
const options: IResourceLabelOptions = {
|
||||
|
@ -602,7 +613,7 @@ class LoadedScriptsRenderer implements ITreeRenderer<BaseTreeItem, void, ILoaded
|
|||
}
|
||||
}
|
||||
|
||||
data.label.setLabel(label, options);
|
||||
data.label.setResource(label, options);
|
||||
}
|
||||
|
||||
disposeTemplate(templateData: ILoadedScriptsItemTemplateData): void {
|
||||
|
|
|
@ -42,6 +42,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
|
|||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IViewletPanelOptions } from 'vs/workbench/browser/parts/views/panelViewlet';
|
||||
import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { ResourceLabels } from 'vs/workbench/browser/labels';
|
||||
|
||||
export interface IExplorerViewOptions extends IViewletViewOptions {
|
||||
fileViewletState: FileViewletState;
|
||||
|
@ -59,6 +60,7 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView
|
|||
public readonly id: string = ExplorerView.ID;
|
||||
|
||||
private explorerViewer: WorkbenchTree;
|
||||
private explorerLabels: ResourceLabels;
|
||||
private filter: FileFilter;
|
||||
private fileViewletState: FileViewletState;
|
||||
|
||||
|
@ -371,6 +373,14 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView
|
|||
this.openFocusedElement();
|
||||
});
|
||||
}
|
||||
|
||||
if (this.explorerLabels) {
|
||||
if (visible) {
|
||||
this.explorerLabels.onVisible();
|
||||
} else {
|
||||
this.explorerLabels.onHidden();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private openFocusedElement(preserveFocus?: boolean): void {
|
||||
|
@ -406,7 +416,9 @@ export class ExplorerView extends TreeViewsViewletPanel implements IExplorerView
|
|||
|
||||
private createViewer(container: HTMLElement): WorkbenchTree {
|
||||
const dataSource = this.instantiationService.createInstance(FileDataSource);
|
||||
const renderer = this.instantiationService.createInstance(FileRenderer, this.fileViewletState);
|
||||
this.explorerLabels = this.instantiationService.createInstance(ResourceLabels);
|
||||
this.disposables.push(this.explorerLabels);
|
||||
const renderer = this.instantiationService.createInstance(FileRenderer, this.fileViewletState, this.explorerLabels);
|
||||
const controller = this.instantiationService.createInstance(FileController);
|
||||
this.disposables.push(controller);
|
||||
const sorter = this.instantiationService.createInstance(FileSorter);
|
||||
|
|
|
@ -17,7 +17,7 @@ import * as comparers from 'vs/base/common/comparers';
|
|||
import { InputBox, MessageType } from 'vs/base/browser/ui/inputbox/inputBox';
|
||||
import { isMacintosh, isLinux } from 'vs/base/common/platform';
|
||||
import * as glob from 'vs/base/common/glob';
|
||||
import { FileLabel, IFileLabelOptions } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IFileLabelOptions, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IFilesConfiguration, SortOrder } from 'vs/workbench/parts/files/common/files';
|
||||
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
|
@ -180,7 +180,7 @@ export class ActionRunner extends BaseActionRunner implements IActionRunner {
|
|||
|
||||
export interface IFileTemplateData {
|
||||
elementDisposable: IDisposable;
|
||||
label: FileLabel;
|
||||
label: IResourceLabel;
|
||||
container: HTMLElement;
|
||||
}
|
||||
|
||||
|
@ -190,20 +190,17 @@ export class FileRenderer implements IRenderer {
|
|||
private static readonly ITEM_HEIGHT = 22;
|
||||
private static readonly FILE_TEMPLATE_ID = 'file';
|
||||
|
||||
private state: FileViewletState;
|
||||
private config: IFilesConfiguration;
|
||||
private configListener: IDisposable;
|
||||
|
||||
constructor(
|
||||
state: FileViewletState,
|
||||
private state: FileViewletState,
|
||||
private labels: ResourceLabels,
|
||||
@IContextViewService private contextViewService: IContextViewService,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IWorkspaceContextService private contextService: IWorkspaceContextService
|
||||
|
||||
) {
|
||||
this.state = state;
|
||||
this.config = this.configurationService.getValue<IFilesConfiguration>();
|
||||
this.configListener = this.configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration('explorer')) {
|
||||
|
@ -231,7 +228,7 @@ export class FileRenderer implements IRenderer {
|
|||
|
||||
public renderTemplate(tree: ITree, templateId: string, container: HTMLElement): IFileTemplateData {
|
||||
const elementDisposable = Disposable.None;
|
||||
const label = this.instantiationService.createInstance(FileLabel, container, void 0);
|
||||
const label = this.labels.create(container);
|
||||
|
||||
return { elementDisposable, label, container };
|
||||
}
|
||||
|
@ -268,7 +265,7 @@ export class FileRenderer implements IRenderer {
|
|||
private renderInputBox(container: HTMLElement, tree: ITree, stat: ExplorerItem, editableData: IEditableData): void {
|
||||
|
||||
// Use a file label only for the icon next to the input box
|
||||
const label = this.instantiationService.createInstance(FileLabel, container, void 0);
|
||||
const label = this.labels.create(container);
|
||||
const extraClasses = ['explorer-item', 'explorer-item-edited'];
|
||||
const fileKind = stat.isRoot ? FileKind.ROOT_FOLDER : (stat.isDirectory || (stat instanceof NewStatPlaceholder && stat.isDirectoryPlaceholder())) ? FileKind.FOLDER : FileKind.FILE;
|
||||
const labelOptions: IFileLabelOptions = { hidePath: true, hideLabel: true, fileKind, extraClasses };
|
||||
|
|
|
@ -26,7 +26,7 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
|
|||
import { badgeBackground, badgeForeground, contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { WorkbenchList } from 'vs/platform/list/browser/listService';
|
||||
import { IListVirtualDelegate, IListRenderer, IListContextMenuEvent } from 'vs/base/browser/ui/list/list';
|
||||
import { EditorLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
@ -51,6 +51,7 @@ export class OpenEditorsView extends ViewletPanel {
|
|||
private listRefreshScheduler: RunOnceScheduler;
|
||||
private structuralRefreshDelay: number;
|
||||
private list: WorkbenchList<OpenEditor | IEditorGroup>;
|
||||
private listLabels: ResourceLabels;
|
||||
private contributedContextMenu: IMenu;
|
||||
private needsRefresh: boolean;
|
||||
private resourceContext: ResourceContextKey;
|
||||
|
@ -213,14 +214,19 @@ export class OpenEditorsView extends ViewletPanel {
|
|||
if (this.list) {
|
||||
this.list.dispose();
|
||||
}
|
||||
if (this.listLabels) {
|
||||
this.listLabels.clear();
|
||||
}
|
||||
this.listLabels = this.instantiationService.createInstance(ResourceLabels);
|
||||
this.list = this.instantiationService.createInstance(WorkbenchList, container, delegate, [
|
||||
new EditorGroupRenderer(this.keybindingService, this.instantiationService, this.editorGroupService),
|
||||
new OpenEditorRenderer(getSelectedElements, this.instantiationService, this.keybindingService, this.configurationService, this.editorGroupService)
|
||||
new OpenEditorRenderer(this.listLabels, getSelectedElements, this.instantiationService, this.keybindingService, this.configurationService, this.editorGroupService)
|
||||
], {
|
||||
identityProvider: { getId: (element: OpenEditor | IEditorGroup) => element instanceof OpenEditor ? element.getId() : element.id.toString() },
|
||||
selectOnMouseDown: false /* disabled to better support DND */
|
||||
}) as WorkbenchList<OpenEditor | IEditorGroup>;
|
||||
this.disposables.push(this.list);
|
||||
this.disposables.push(this.listLabels);
|
||||
|
||||
this.contributedContextMenu = this.menuService.createMenu(MenuId.OpenEditorsContext, this.list.contextKeyService);
|
||||
this.disposables.push(this.contributedContextMenu);
|
||||
|
@ -327,6 +333,13 @@ export class OpenEditorsView extends ViewletPanel {
|
|||
dom.hide(this.list.getHTMLElement()); // make sure the list goes out of the tabindex world by hiding it
|
||||
}
|
||||
}
|
||||
if (this.listLabels) {
|
||||
if (isVisible) {
|
||||
this.listLabels.onVisible();
|
||||
} else {
|
||||
this.listLabels.onHidden();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private get showGroups(): boolean {
|
||||
|
@ -478,7 +491,7 @@ export class OpenEditorsView extends ViewletPanel {
|
|||
|
||||
interface IOpenEditorTemplateData {
|
||||
container: HTMLElement;
|
||||
root: EditorLabel;
|
||||
root: IResourceLabel;
|
||||
actionBar: ActionBar;
|
||||
actionRunner: OpenEditorActionRunner;
|
||||
openEditor: OpenEditor;
|
||||
|
@ -619,6 +632,7 @@ class OpenEditorRenderer implements IListRenderer<OpenEditor, IOpenEditorTemplat
|
|||
private transfer = LocalSelectionTransfer.getInstance<OpenEditor>();
|
||||
|
||||
constructor(
|
||||
private labels: ResourceLabels,
|
||||
private getSelectedElements: () => Array<OpenEditor | IEditorGroup>,
|
||||
private instantiationService: IInstantiationService,
|
||||
private keybindingService: IKeybindingService,
|
||||
|
@ -643,7 +657,7 @@ class OpenEditorRenderer implements IListRenderer<OpenEditor, IOpenEditorTemplat
|
|||
const key = this.keybindingService.lookupKeybinding(closeEditorAction.id);
|
||||
editorTemplate.actionBar.push(closeEditorAction, { icon: true, label: false, keybinding: key ? key.getLabel() : void 0 });
|
||||
|
||||
editorTemplate.root = this.instantiationService.createInstance(EditorLabel, container, void 0);
|
||||
editorTemplate.root = this.labels.create(container);
|
||||
|
||||
editorTemplate.toDispose = [];
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ import { IExpression, getEmptyExpression } from 'vs/base/common/glob';
|
|||
import { mixin, deepClone } from 'vs/base/common/objects';
|
||||
import { IWorkspaceFolder, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { isAbsolute, join } from 'vs/base/common/paths';
|
||||
import { FilterData, FileResourceMarkersRenderer, Filter, VirtualDelegate, ResourceMarkersRenderer, MarkerRenderer, RelatedInformationRenderer, TreeElement, MarkersTreeAccessibilityProvider, MarkersViewState } from 'vs/workbench/parts/markers/electron-browser/markersTreeViewer';
|
||||
import { FilterData, Filter, VirtualDelegate, ResourceMarkersRenderer, MarkerRenderer, RelatedInformationRenderer, TreeElement, MarkersTreeAccessibilityProvider, MarkersViewState } from 'vs/workbench/parts/markers/electron-browser/markersTreeViewer';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { Separator, ActionItem } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IMenuService, MenuId } from 'vs/platform/actions/common/actions';
|
||||
|
@ -42,6 +42,7 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
|||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { domEvent } from 'vs/base/browser/event';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { ResourceLabels } from 'vs/workbench/browser/labels';
|
||||
|
||||
function createModelIterator(model: MarkersModel): Iterator<ITreeElement<TreeElement>> {
|
||||
const resourcesIt = Iterator.fromArray(model.resourceMarkers);
|
||||
|
@ -66,6 +67,7 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
|
|||
private currentActiveResource: URI | null = null;
|
||||
|
||||
private tree: WorkbenchObjectTree<TreeElement, FilterData>;
|
||||
private treeLabels: ResourceLabels;
|
||||
private rangeHighlightDecorations: RangeHighlightDecorations;
|
||||
|
||||
private actions: IAction[];
|
||||
|
@ -170,6 +172,14 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
|
|||
} else {
|
||||
this.rangeHighlightDecorations.removeHighlightRange();
|
||||
}
|
||||
|
||||
if (this.treeLabels) {
|
||||
if (visible) {
|
||||
this.treeLabels.onVisible();
|
||||
} else {
|
||||
this.treeLabels.onHidden();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getActions(): IAction[] {
|
||||
|
@ -287,10 +297,11 @@ export class MarkersPanel extends Panel implements IMarkerFilterController {
|
|||
|
||||
const onDidChangeRenderNodeCount = new Relay<ITreeNode<any, any>>();
|
||||
|
||||
this.treeLabels = this._register(this.instantiationService.createInstance(ResourceLabels));
|
||||
|
||||
const virtualDelegate = new VirtualDelegate(this.markersViewState);
|
||||
const renderers = [
|
||||
this.instantiationService.createInstance(FileResourceMarkersRenderer, onDidChangeRenderNodeCount.event),
|
||||
this.instantiationService.createInstance(ResourceMarkersRenderer, onDidChangeRenderNodeCount.event),
|
||||
this.instantiationService.createInstance(ResourceMarkersRenderer, this.treeLabels, onDidChangeRenderNodeCount.event),
|
||||
this.instantiationService.createInstance(MarkerRenderer, this.markersViewState, a => this.getActionItem(a)),
|
||||
this.instantiationService.createInstance(RelatedInformationRenderer)
|
||||
];
|
||||
|
|
|
@ -7,7 +7,7 @@ import * as dom from 'vs/base/browser/dom';
|
|||
import * as network from 'vs/base/common/network';
|
||||
import * as paths from 'vs/base/common/paths';
|
||||
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
|
||||
import { FileLabel, ResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
|
||||
import { IMarker, MarkerSeverity } from 'vs/platform/markers/common/markers';
|
||||
import { ResourceMarkers, Marker, RelatedInformation } from 'vs/workbench/parts/markers/electron-browser/markersModel';
|
||||
|
@ -34,7 +34,7 @@ import { localize } from 'vs/nls';
|
|||
export type TreeElement = ResourceMarkers | Marker | RelatedInformation;
|
||||
|
||||
interface IResourceMarkersTemplateData {
|
||||
resourceLabel: ResourceLabel;
|
||||
resourceLabel: IResourceLabel;
|
||||
count: CountBadge;
|
||||
styler: IDisposable;
|
||||
}
|
||||
|
@ -69,7 +69,6 @@ export class MarkersTreeAccessibilityProvider implements IAccessibilityProvider<
|
|||
}
|
||||
|
||||
const enum TemplateId {
|
||||
FileResourceMarkers = 'frm',
|
||||
ResourceMarkers = 'rm',
|
||||
Marker = 'm',
|
||||
RelatedInformation = 'ri'
|
||||
|
@ -90,11 +89,7 @@ export class VirtualDelegate implements IListVirtualDelegate<TreeElement> {
|
|||
|
||||
getTemplateId(element: TreeElement): string {
|
||||
if (element instanceof ResourceMarkers) {
|
||||
if ((element).resource.scheme === network.Schemas.file || (<ResourceMarkers>element).resource.scheme === network.Schemas.untitled) {
|
||||
return TemplateId.FileResourceMarkers;
|
||||
} else {
|
||||
return TemplateId.ResourceMarkers;
|
||||
}
|
||||
return TemplateId.ResourceMarkers;
|
||||
} else if (element instanceof Marker) {
|
||||
return TemplateId.Marker;
|
||||
} else {
|
||||
|
@ -135,8 +130,8 @@ export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, R
|
|||
private disposables: IDisposable[] = [];
|
||||
|
||||
constructor(
|
||||
private labels: ResourceLabels,
|
||||
onDidChangeRenderNodeCount: Event<ITreeNode<ResourceMarkers, ResourceMarkersFilterData>>,
|
||||
@IInstantiationService protected instantiationService: IInstantiationService,
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@ILabelService private labelService: ILabelService
|
||||
) {
|
||||
|
@ -149,7 +144,7 @@ export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, R
|
|||
const data = <IResourceMarkersTemplateData>Object.create(null);
|
||||
|
||||
const resourceLabelContainer = dom.append(container, dom.$('.resource-label-container'));
|
||||
data.resourceLabel = this.createResourceLabel(resourceLabelContainer);
|
||||
data.resourceLabel = this.labels.create(resourceLabelContainer, { supportHighlights: true });
|
||||
|
||||
const badgeWrapper = dom.append(container, dom.$('.count-badge-wrapper'));
|
||||
data.count = new CountBadge(badgeWrapper);
|
||||
|
@ -162,10 +157,10 @@ export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, R
|
|||
const resourceMarkers = node.element;
|
||||
const uriMatches = node.filterData && node.filterData.uriMatches || [];
|
||||
|
||||
if (templateData.resourceLabel instanceof FileLabel) {
|
||||
if (resourceMarkers.resource.scheme === network.Schemas.file || resourceMarkers.resource.scheme === network.Schemas.untitled) {
|
||||
templateData.resourceLabel.setFile(resourceMarkers.resource, { matches: uriMatches });
|
||||
} else {
|
||||
templateData.resourceLabel.setLabel({ name: resourceMarkers.name, description: this.labelService.getUriLabel(dirname(resourceMarkers.resource), { relative: true }), resource: resourceMarkers.resource }, { matches: uriMatches });
|
||||
templateData.resourceLabel.setResource({ name: resourceMarkers.name, description: this.labelService.getUriLabel(dirname(resourceMarkers.resource), { relative: true }), resource: resourceMarkers.resource }, { matches: uriMatches });
|
||||
}
|
||||
|
||||
this.updateCount(node, templateData);
|
||||
|
@ -181,10 +176,6 @@ export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, R
|
|||
templateData.styler.dispose();
|
||||
}
|
||||
|
||||
protected createResourceLabel(container: HTMLElement): ResourceLabel {
|
||||
return this.instantiationService.createInstance(ResourceLabel, container, { supportHighlights: true });
|
||||
}
|
||||
|
||||
private onDidChangeRenderNodeCount(node: ITreeNode<ResourceMarkers, ResourceMarkersFilterData>): void {
|
||||
const templateData = this.renderedNodes.get(node);
|
||||
|
||||
|
@ -205,12 +196,6 @@ export class ResourceMarkersRenderer implements ITreeRenderer<ResourceMarkers, R
|
|||
}
|
||||
|
||||
export class FileResourceMarkersRenderer extends ResourceMarkersRenderer {
|
||||
|
||||
templateId = TemplateId.FileResourceMarkers;
|
||||
|
||||
protected createResourceLabel(container: HTMLElement): ResourceLabel {
|
||||
return this.instantiationService.createInstance(FileLabel, container, { supportHighlights: true });
|
||||
}
|
||||
}
|
||||
|
||||
export class MarkerRenderer implements ITreeRenderer<Marker, MarkerFilterData, IMarkerTemplateData> {
|
||||
|
|
|
@ -15,7 +15,7 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
|||
import { List } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IListVirtualDelegate, IListRenderer, IListContextMenuEvent, IListEvent, IKeyboardNavigationLabelProvider, IIdentityProvider } from 'vs/base/browser/ui/list/list';
|
||||
import { VIEWLET_ID, VIEW_CONTAINER } from 'vs/workbench/parts/scm/common/scm';
|
||||
import { FileLabel } from 'vs/workbench/browser/labels';
|
||||
import { ResourceLabels, IResourceLabel } from 'vs/workbench/browser/labels';
|
||||
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
|
||||
import { ISCMService, ISCMRepository, ISCMResourceGroup, ISCMResource, InputValidationType } from 'vs/workbench/services/scm/common/scm';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
@ -444,7 +444,7 @@ class ResourceGroupRenderer implements IListRenderer<ISCMResourceGroup, Resource
|
|||
interface ResourceTemplate {
|
||||
element: HTMLElement;
|
||||
name: HTMLElement;
|
||||
fileLabel: FileLabel;
|
||||
fileLabel: IResourceLabel;
|
||||
decorationIcon: HTMLElement;
|
||||
actionBar: ActionBar;
|
||||
elementDisposable: IDisposable;
|
||||
|
@ -479,17 +479,17 @@ class ResourceRenderer implements IListRenderer<ISCMResource, ResourceTemplate>
|
|||
get templateId(): string { return ResourceRenderer.TEMPLATE_ID; }
|
||||
|
||||
constructor(
|
||||
private labels: ResourceLabels,
|
||||
private actionItemProvider: IActionItemProvider,
|
||||
private getSelectedResources: () => ISCMResource[],
|
||||
private themeService: IThemeService,
|
||||
private instantiationService: IInstantiationService,
|
||||
private menus: SCMMenus
|
||||
) { }
|
||||
|
||||
renderTemplate(container: HTMLElement): ResourceTemplate {
|
||||
const element = append(container, $('.resource'));
|
||||
const name = append(element, $('.name'));
|
||||
const fileLabel = this.instantiationService.createInstance(FileLabel, name, void 0);
|
||||
const fileLabel = this.labels.create(name);
|
||||
const actionsContainer = append(fileLabel.element, $('.actions'));
|
||||
const actionBar = new ActionBar(actionsContainer, {
|
||||
actionItemProvider: this.actionItemProvider,
|
||||
|
@ -728,6 +728,7 @@ export class RepositoryPanel extends ViewletPanel {
|
|||
private inputBox: InputBox;
|
||||
private listContainer: HTMLElement;
|
||||
private list: List<ISCMResourceGroup | ISCMResource>;
|
||||
private listLabels: ResourceLabels;
|
||||
private menus: SCMMenus;
|
||||
private visibilityDisposables: IDisposable[] = [];
|
||||
protected contextKeyService: IContextKeyService;
|
||||
|
@ -869,9 +870,12 @@ export class RepositoryPanel extends ViewletPanel {
|
|||
|
||||
const actionItemProvider = (action: IAction) => this.getActionItem(action);
|
||||
|
||||
this.listLabels = this.instantiationService.createInstance(ResourceLabels);
|
||||
this.disposables.push(this.listLabels);
|
||||
|
||||
const renderers = [
|
||||
new ResourceGroupRenderer(actionItemProvider, this.themeService, this.menus),
|
||||
new ResourceRenderer(actionItemProvider, () => this.getSelectedResources(), this.themeService, this.instantiationService, this.menus)
|
||||
new ResourceRenderer(this.listLabels, actionItemProvider, () => this.getSelectedResources(), this.themeService, this.menus)
|
||||
];
|
||||
|
||||
this.list = this.instantiationService.createInstance(WorkbenchList, this.listContainer, delegate, renderers, {
|
||||
|
@ -907,6 +911,18 @@ export class RepositoryPanel extends ViewletPanel {
|
|||
this.inputBox.setEnabled(this.isVisible() && this.isExpanded());
|
||||
}
|
||||
|
||||
setVisible(visible: boolean): void {
|
||||
super.setVisible(visible);
|
||||
|
||||
if (this.listLabels) {
|
||||
if (visible) {
|
||||
this.listLabels.onVisible();
|
||||
} else {
|
||||
this.listLabels.onHidden();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setExpanded(expanded: boolean): void {
|
||||
super.setExpanded(expanded);
|
||||
this.inputBox.setEnabled(this.isVisible() && this.isExpanded());
|
||||
|
|
|
@ -23,7 +23,7 @@ import { ISearchConfigurationProperties } from 'vs/platform/search/common/search
|
|||
import { attachBadgeStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { FileLabel } from 'vs/workbench/browser/labels';
|
||||
import { IResourceLabel, ResourceLabels } from 'vs/workbench/browser/labels';
|
||||
import { RemoveAction, ReplaceAction, ReplaceAllAction, ReplaceAllInFolderAction } from 'vs/workbench/parts/search/browser/searchActions';
|
||||
import { SearchView } from 'vs/workbench/parts/search/browser/searchView';
|
||||
import { FileMatch, FolderMatch, Match, RenderableMatch, searchMatchComparer, SearchModel } from 'vs/workbench/parts/search/common/searchModel';
|
||||
|
@ -35,14 +35,14 @@ export class SearchSorter implements ISorter {
|
|||
}
|
||||
|
||||
interface IFolderMatchTemplate {
|
||||
label: FileLabel;
|
||||
label: IResourceLabel;
|
||||
badge: CountBadge;
|
||||
actions: ActionBar;
|
||||
}
|
||||
|
||||
interface IFileMatchTemplate {
|
||||
el: HTMLElement;
|
||||
label: FileLabel;
|
||||
label: IResourceLabel;
|
||||
badge: CountBadge;
|
||||
actions: ActionBar;
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ export class FolderMatchRenderer extends Disposable implements ITreeRenderer<Fol
|
|||
constructor(
|
||||
private searchModel: SearchModel,
|
||||
private searchView: SearchView,
|
||||
private labels: ResourceLabels,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@IWorkspaceContextService protected contextService: IWorkspaceContextService
|
||||
|
@ -93,7 +94,7 @@ export class FolderMatchRenderer extends Disposable implements ITreeRenderer<Fol
|
|||
|
||||
renderTemplate(container: HTMLElement): IFolderMatchTemplate {
|
||||
let folderMatchElement = DOM.append(container, DOM.$('.foldermatch'));
|
||||
const label = this.instantiationService.createInstance(FileLabel, folderMatchElement, void 0);
|
||||
const label = this.labels.create(folderMatchElement);
|
||||
const badge = new CountBadge(DOM.append(folderMatchElement, DOM.$('.badge')));
|
||||
this._register(attachBadgeStyler(badge, this.themeService));
|
||||
const actionBarContainer = DOM.append(folderMatchElement, DOM.$('.actionBarContainer'));
|
||||
|
@ -112,7 +113,7 @@ export class FolderMatchRenderer extends Disposable implements ITreeRenderer<Fol
|
|||
templateData.label.setFile(folderMatch.resource(), { fileKind: FileKind.FOLDER });
|
||||
}
|
||||
} else {
|
||||
templateData.label.setValue(nls.localize('searchFolderMatch.other.label', "Other files"));
|
||||
templateData.label.setLabel(nls.localize('searchFolderMatch.other.label', "Other files"));
|
||||
}
|
||||
let count = folderMatch.fileCount();
|
||||
templateData.badge.setCount(count);
|
||||
|
@ -146,6 +147,7 @@ export class FileMatchRenderer extends Disposable implements ITreeRenderer<FileM
|
|||
constructor(
|
||||
private searchModel: SearchModel,
|
||||
private searchView: SearchView,
|
||||
private labels: ResourceLabels,
|
||||
@IInstantiationService private instantiationService: IInstantiationService,
|
||||
@IThemeService private themeService: IThemeService,
|
||||
@IWorkspaceContextService protected contextService: IWorkspaceContextService
|
||||
|
@ -155,7 +157,7 @@ export class FileMatchRenderer extends Disposable implements ITreeRenderer<FileM
|
|||
|
||||
renderTemplate(container: HTMLElement): IFileMatchTemplate {
|
||||
let fileMatchElement = DOM.append(container, DOM.$('.filematch'));
|
||||
const label = this.instantiationService.createInstance(FileLabel, fileMatchElement, void 0);
|
||||
const label = this.labels.create(fileMatchElement);
|
||||
const badge = new CountBadge(DOM.append(fileMatchElement, DOM.$('.badge')));
|
||||
this._register(attachBadgeStyler(badge, this.themeService));
|
||||
const actionBarContainer = DOM.append(fileMatchElement, DOM.$('.actionBarContainer'));
|
||||
|
|
|
@ -62,6 +62,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorG
|
|||
import { IPartService } from 'vs/workbench/services/part/common/partService';
|
||||
import { IPreferencesService, ISettingsEditorOptions } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { IUntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService';
|
||||
import { ResourceLabels } from 'vs/workbench/browser/labels';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
|
@ -136,6 +137,7 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
|
|||
private contextMenu: IMenu;
|
||||
|
||||
private tree: WorkbenchObjectTree<RenderableMatch>;
|
||||
private treeLabels: ResourceLabels;
|
||||
private viewletState: object;
|
||||
private globalMemento: object;
|
||||
private messagesElement: HTMLElement;
|
||||
|
@ -584,18 +586,19 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
|
|||
}
|
||||
};
|
||||
|
||||
this.tree = <WorkbenchObjectTree<RenderableMatch, any>>this.instantiationService.createInstance(WorkbenchObjectTree,
|
||||
this.treeLabels = this._register(this.instantiationService.createInstance(ResourceLabels));
|
||||
this.tree = this._register(<WorkbenchObjectTree<RenderableMatch, any>>this.instantiationService.createInstance(WorkbenchObjectTree,
|
||||
this.resultsElement,
|
||||
delegate,
|
||||
[
|
||||
this._register(this.instantiationService.createInstance(FolderMatchRenderer, this.viewModel, this)),
|
||||
this._register(this.instantiationService.createInstance(FileMatchRenderer, this.viewModel, this)),
|
||||
this._register(this.instantiationService.createInstance(FolderMatchRenderer, this.viewModel, this, this.treeLabels)),
|
||||
this._register(this.instantiationService.createInstance(FileMatchRenderer, this.viewModel, this, this.treeLabels)),
|
||||
this._register(this.instantiationService.createInstance(MatchRenderer, this.viewModel, this)),
|
||||
],
|
||||
{
|
||||
identityProvider,
|
||||
accessibilityProvider: this.instantiationService.createInstance(SearchAccessibilityProvider, this.viewModel)
|
||||
});
|
||||
}));
|
||||
this._register(this.tree.onContextMenu(e => this.onContextMenu(e)));
|
||||
|
||||
const resourceNavigator = this._register(new TreeResourceNavigator2(this.tree, { openOnFocus: true }));
|
||||
|
@ -766,6 +769,14 @@ export class SearchView extends Viewlet implements IViewlet, IPanel {
|
|||
this.onFocus(focus, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.treeLabels) {
|
||||
if (visible) {
|
||||
this.treeLabels.onVisible();
|
||||
} else {
|
||||
this.treeLabels.onHidden();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public moveFocusToResults(): void {
|
||||
|
|
Loading…
Reference in a new issue