提交 48a98604 编写于 作者: B Benjamin Pasero

introduce and use editorLabel for icons in "opened editors"

上级 08d96455
......@@ -73,34 +73,36 @@ function getPath(arg1: uri | string | IWorkspaceProvider): string {
return (<uri>arg1).fsPath;
}
export function getFileIconClasses(arg1: uri | string, getLanguageId: (path: string) => string, isFolder?: boolean): string[] {
export function getFileIconClasses(arg1?: uri | string, getLanguageId?: (path: string) => string, isFolder?: boolean): string[] {
let path: string;
if (typeof arg1 === 'string') {
path = arg1;
} else {
} else if (arg1) {
path = arg1.fsPath;
}
const classes = isFolder ? ['folder-icon'] : ['file-icon'];
const basename = paths.basename(path);
const dotSegments = basename.split('.');
if (path) {
const basename = paths.basename(path);
const dotSegments = basename.split('.');
const name = dotSegments[0]; // file.txt => "file", .dockerfile => "", file.some.txt => "file"
if (name) {
classes.push(`${cssEscape(name.toLowerCase())}-name-file-icon`);
}
const name = dotSegments[0]; // file.txt => "file", .dockerfile => "", file.some.txt => "file"
if (name) {
classes.push(`${cssEscape(name.toLowerCase())}-name-file-icon`);
}
const extensions = dotSegments.splice(1);
if (extensions.length > 0) {
for (let i = 0; i < extensions.length; i++) {
classes.push(`${cssEscape(extensions.slice(i).join('.').toLowerCase())}-ext-file-icon`); // add each combination of all found extensions if more than one
const extensions = dotSegments.splice(1);
if (extensions.length > 0) {
for (let i = 0; i < extensions.length; i++) {
classes.push(`${cssEscape(extensions.slice(i).join('.').toLowerCase())}-ext-file-icon`); // add each combination of all found extensions if more than one
}
}
}
const langId = getLanguageId(path);
if (langId) {
classes.push(`${cssEscape(langId)}-lang-file-icon`);
const langId = getLanguageId(path);
if (langId) {
classes.push(`${cssEscape(langId)}-lang-file-icon`);
}
}
return classes;
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import 'vs/css!./iconLabel';
import dom = require('vs/base/browser/dom');
export interface IIconLabelOptions {
title?: string;
extraClasses?: string[];
italic?: boolean;
}
export class IconLabel {
private domNode: HTMLElement;
private labelNode: HTMLElement;
private descriptionNode: HTMLElement;
constructor(container: HTMLElement, label?: string, description?: string, options?: IIconLabelOptions) {
this.domNode = dom.append(container, dom.$('.monaco-icon-label'));
this.labelNode = dom.append(this.domNode, dom.$('span.label-name'));
this.descriptionNode = dom.append(this.domNode, dom.$('span.label-description'));
if (label) {
this.setValue(label, description, options);
}
}
public getHTMLElement(): HTMLElement {
return this.domNode;
}
public setValue(label: string, description?: string, options?: IIconLabelOptions): void {
this.labelNode.textContent = label || '';
this.descriptionNode.textContent = description || '';
this.domNode.title = options && options.title ? options.title : '';
const classes = ['monaco-icon-label'];
if (options) {
if (options.extraClasses) {
classes.push(...options.extraClasses);
}
if (options.italic) {
classes.push('italic');
}
}
this.domNode.className = classes.join(' ');
}
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/* ---------- Icon label ---------- */
.monaco-icon-label {
display: inline-block; /* required for icons support :before rule */
}
.monaco-icon-label::before {
/* svg icons rendered as background image */
background-size: 16px;
background-position: left center;
background-repeat: no-repeat;
padding-right: 6px;
width: 16px;
height: 22px;
display: inline-block;
/* fonts icons */
-webkit-font-smoothing: antialiased;
vertical-align: top;
}
.monaco-icon-label > .label-name {
color: inherit;
}
.monaco-icon-label > .label-description {
opacity: 0.7;
margin-left: 0.5em;
font-size: 0.9em;
}
.monaco-icon-label.italic > .label-name,
.monaco-icon-label.italic > .label-description {
font-style: italic;
}
\ No newline at end of file
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {getFileIconClasses} from 'vs/base/browser/ui/fileLabel/fileLabel';
import {IconLabel, IIconLabelOptions} from 'vs/base/browser/ui/iconLabel/iconLabel';
import {IExtensionService} from 'vs/platform/extensions/common/extensions';
import {IModeService} from 'vs/editor/common/services/modeService';
import {IEditorInput} from 'vs/platform/editor/common/editor';
import {getResource} from 'vs/workbench/common/editor';
export class EditorLabel extends IconLabel {
private input: IEditorInput;
private options: IIconLabelOptions;
constructor(
container: HTMLElement,
@IExtensionService private extensionService: IExtensionService,
@IModeService private modeService: IModeService
) {
super(container);
this.extensionService.onReady().then(() => {
this.render(); // there can be additional modes once the extension host is ready so we need to render again
});
}
public setInput(input: IEditorInput, options: IIconLabelOptions): void {
this.input = input;
this.options = options;
this.render();
}
private render(): void {
if (!this.input) {
return;
}
const resource = getResource(this.input);
let title = '';
if (this.options && this.options.title) {
title = this.options.title;
} else if (resource) {
title = resource.fsPath;
}
const italic = this.options && this.options.italic;
const extraClasses = getFileIconClasses(resource, path => this.modeService.getModeIdByFilenameOrFirstLine(path));
if (this.options && this.options.extraClasses) {
extraClasses.push(...this.options.extraClasses);
}
this.setValue(this.input.getName(), this.input.getDescription(), { title, extraClasses, italic });
}
}
\ No newline at end of file
......@@ -145,15 +145,6 @@
border: none;
}
.explorer-viewlet .explorer-open-editors .monaco-tree .monaco-tree-row .open-editor > .description {
opacity: .7;
margin-left: .5em;
font-size: .9em;
}
.explorer-viewlet .explorer-open-editors .monaco-tree .monaco-tree-row .open-editor.preview {
font-style: italic;
}
/* High Contrast Theming */
.hc-black .monaco-workbench .explorer-viewlet .explorer-item,
......
......@@ -88,6 +88,7 @@ export class OpenEditorsView extends AdaptiveCollapsibleViewletView {
public renderBody(container: HTMLElement): void {
this.treeContainer = super.renderViewTree(container);
dom.addClass(this.treeContainer, 'explorer-open-editors');
dom.addClass(this.treeContainer, 'show-file-icons');
const dataSource = this.instantiationService.createInstance(DataSource);
const actionProvider = this.instantiationService.createInstance(ActionProvider, this.model);
......
......@@ -8,6 +8,7 @@ import uri from 'vs/base/common/uri';
import errors = require('vs/base/common/errors');
import {TPromise} from 'vs/base/common/winjs.base';
import {IAction} from 'vs/base/common/actions';
import {EditorLabel} from 'vs/workbench/browser/parts/editor/editorLabel';
import treedefaults = require('vs/base/parts/tree/browser/treeDefaults');
import {IDataSource, ITree, IAccessibilityProvider, IDragAndDropData, IDragOverReaction, DRAG_OVER_ACCEPT, DRAG_OVER_REJECT, ContextMenuEvent, IRenderer} from 'vs/base/parts/tree/browser/tree';
import {ExternalElementsDragAndDropData, ElementsDragAndDropData, DesktopDragAndDropData} from 'vs/base/parts/tree/browser/treeDnd';
......@@ -106,9 +107,7 @@ export class DataSource implements IDataSource {
interface IOpenEditorTemplateData {
container: HTMLElement;
root: HTMLElement;
name: HTMLSpanElement;
description: HTMLSpanElement;
root: EditorLabel;
actionBar: ActionBar;
}
......@@ -126,6 +125,7 @@ export class Renderer implements IRenderer {
constructor(private actionProvider: ActionProvider, private model: IEditorStacksModel,
@ITextFileService private textFileService: ITextFileService,
@IInstantiationService private instantiationService: IInstantiationService,
@IUntitledEditorService private untitledEditorService: IUntitledEditorService
) {
// noop
......@@ -149,7 +149,7 @@ export class Renderer implements IRenderer {
editorGroupTemplate.root = dom.append(container, $('.editor-group'));
editorGroupTemplate.name = dom.append(editorGroupTemplate.root, $('span.name'));
editorGroupTemplate.actionBar = new ActionBar(container);
editorGroupTemplate.actionBar.push(this.actionProvider.getEditorGroupActions(), { icon: true, label: false});
editorGroupTemplate.actionBar.push(this.actionProvider.getEditorGroupActions(), { icon: true, label: false });
return editorGroupTemplate;
}
......@@ -157,12 +157,8 @@ export class Renderer implements IRenderer {
const editorTemplate: IOpenEditorTemplateData = Object.create(null);
editorTemplate.container = container;
editorTemplate.actionBar = new ActionBar(container);
editorTemplate.actionBar.push(this.actionProvider.getOpenEditorActions(), { icon: true, label: false});
editorTemplate.root = dom.append(container, $('.open-editor'));
editorTemplate.name = dom.append(editorTemplate.root, $('span.name'));
editorTemplate.description = dom.append(editorTemplate.root, $('span.description'));
editorTemplate.actionBar.push(this.actionProvider.getOpenEditorActions(), { icon: true, label: false });
editorTemplate.root = this.instantiationService.createInstance(EditorLabel, container);
return editorTemplate;
}
......@@ -175,18 +171,14 @@ export class Renderer implements IRenderer {
}
}
private renderEditorGroup(tree: ITree, editorGroup: IEditorGroup, templateData: IOpenEditorTemplateData): void {
private renderEditorGroup(tree: ITree, editorGroup: IEditorGroup, templateData: IEditorGroupTemplateData): void {
templateData.name.textContent = editorGroup.label;
templateData.actionBar.context = { group: editorGroup };
}
private renderOpenEditor(tree: ITree, editor: OpenEditor, templateData: IOpenEditorTemplateData): void {
editor.isPreview() ? dom.addClass(templateData.root, 'preview') : dom.removeClass(templateData.root, 'preview');
editor.isDirty() ? dom.addClass(templateData.container, 'dirty') : dom.removeClass(templateData.container, 'dirty');
const resource = editor.getResource();
templateData.root.title = resource ? resource.fsPath : '';
templateData.name.textContent = editor.editorInput.getName();
templateData.description.textContent = editor.editorInput.getDescription();
templateData.root.setInput(editor.editorInput, { italic: editor.isPreview(), extraClasses: ['open-editor'] });
templateData.actionBar.context = { group: editor.editorGroup, editor: editor.editorInput };
}
......@@ -494,7 +486,7 @@ export class DragAndDrop extends treedefaults.DefaultDragAndDrop {
return resource ? resource.toString() : element.editorInput.getName();
}
public onDragOver(tree: ITree, data: IDragAndDropData, target: OpenEditor|EditorGroup, originalEvent: DragMouseEvent): IDragOverReaction {
public onDragOver(tree: ITree, data: IDragAndDropData, target: OpenEditor | EditorGroup, originalEvent: DragMouseEvent): IDragOverReaction {
if (!(target instanceof OpenEditor) && !(target instanceof EditorGroup)) {
return DRAG_OVER_REJECT;
}
......@@ -520,10 +512,10 @@ export class DragAndDrop extends treedefaults.DefaultDragAndDrop {
return DRAG_OVER_ACCEPT;
}
public drop(tree: ITree, data: IDragAndDropData, target: OpenEditor|EditorGroup, originalEvent: DragMouseEvent): void {
let draggedElement: OpenEditor|EditorGroup;
public drop(tree: ITree, data: IDragAndDropData, target: OpenEditor | EditorGroup, originalEvent: DragMouseEvent): void {
let draggedElement: OpenEditor | EditorGroup;
const model = this.editorGroupService.getStacksModel();
const positionOfTargetGroup = model.positionOfGroup(target instanceof EditorGroup ? target : target.editorGroup);
const positionOfTargetGroup = model.positionOfGroup(target instanceof EditorGroup ? target : target.editorGroup);
const index = target instanceof OpenEditor ? target.editorGroup.indexOf(target.editorInput) : undefined;
// Support drop from explorer viewer
if (data instanceof ExternalElementsDragAndDropData) {
......@@ -534,7 +526,7 @@ export class DragAndDrop extends treedefaults.DefaultDragAndDrop {
// Drop within viewer
else {
let source: OpenEditor|EditorGroup[] = data.getData();
let source: OpenEditor | EditorGroup[] = data.getData();
if (Array.isArray(source)) {
draggedElement = source[0];
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册