mirror of
https://github.com/microsoft/vscode.git
synced 2026-02-24 03:35:38 +00:00
Merge pull request #43261 from vbfox/file_as_folder_in_custom_tree
Allow extensions to specify custom tree view resoure type
This commit is contained in:
27
src/vs/vscode.d.ts
vendored
27
src/vs/vscode.d.ts
vendored
@@ -5063,6 +5063,25 @@ declare module 'vscode' {
|
||||
getChildren(element?: T): ProviderResult<T[]>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A category in a File Icon Theme, either [file](#ThemeIcon.file) or [folder](#ThemeIcon.folder)
|
||||
*/
|
||||
export class ThemeIcon {
|
||||
/**
|
||||
* Use the File Icon Theme for files
|
||||
*/
|
||||
static readonly File: ThemeIcon;
|
||||
|
||||
/**
|
||||
* Use the File Icon Theme for files
|
||||
*/
|
||||
static readonly Folder: ThemeIcon;
|
||||
|
||||
readonly id: string;
|
||||
|
||||
private constructor(id: string);
|
||||
}
|
||||
|
||||
export class TreeItem {
|
||||
/**
|
||||
* A human-readable string describing this item. When `falsy`, it is derived from [resourceUri](#TreeItem.resourceUri).
|
||||
@@ -5077,15 +5096,17 @@ declare module 'vscode' {
|
||||
id?: string;
|
||||
|
||||
/**
|
||||
* The icon path for the tree item. When `falsy`, it is derived from [resourceUri](#TreeItem.resourceUri).
|
||||
* The icon path for the tree item.
|
||||
* When `falsy` it is derived from [resourceUri](#TreeItem.resourceUri) and the current theme (As a file if the node isn't collapsible or for folders otherwise)
|
||||
* When a [ThemeIcon](#ThemeIcon) is specified it is derived from [resourceUri](#TreeItem.resourceUri) and the current theme for the specified category.
|
||||
*/
|
||||
iconPath?: string | Uri | { light: string | Uri; dark: string | Uri };
|
||||
iconPath?: string | Uri | { light: string | Uri | ThemeIcon; dark: string | Uri | ThemeIcon } | ThemeIcon;
|
||||
|
||||
/**
|
||||
* The [uri](#Uri) of the resource representing this item.
|
||||
*
|
||||
* Will be used to derive the [label](#TreeItem.label), when it is not provided.
|
||||
* Will be used to derive the icon from current file icon theme, when [iconPath](#TreeItem.iconPath) is not provided.
|
||||
* Will be used to derive the icon from current icon theme, when [iconPath](#TreeItem.iconPath) is not provided or is a [ThemeIcon](#ThemeIcon).
|
||||
*/
|
||||
resourceUri?: Uri;
|
||||
|
||||
|
||||
@@ -623,6 +623,7 @@ export function createApiFactory(
|
||||
WorkspaceEdit: extHostTypes.WorkspaceEdit,
|
||||
ProgressLocation: extHostTypes.ProgressLocation,
|
||||
TreeItemCollapsibleState: extHostTypes.TreeItemCollapsibleState,
|
||||
ThemeIcon: extHostTypes.ThemeIcon,
|
||||
TreeItem: extHostTypes.TreeItem,
|
||||
ThemeColor: extHostTypes.ThemeColor,
|
||||
// functions
|
||||
|
||||
@@ -12,10 +12,10 @@ import { debounceEvent } from 'vs/base/common/event';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { ExtHostTreeViewsShape, MainThreadTreeViewsShape } from './extHost.protocol';
|
||||
import { ITreeItem, TreeViewItemHandleArg } from 'vs/workbench/common/views';
|
||||
import { ITreeItem, TreeViewItemHandleArg, IThemeIcon } from 'vs/workbench/common/views';
|
||||
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands';
|
||||
import { asWinJsPromise } from 'vs/base/common/async';
|
||||
import { TreeItemCollapsibleState } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { TreeItemCollapsibleState, ThemeIcon } from 'vs/workbench/api/node/extHostTypes';
|
||||
import { isUndefinedOrNull } from 'vs/base/common/types';
|
||||
|
||||
type TreeItemHandle = string;
|
||||
@@ -315,9 +315,11 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
throw new Error('This should not be reached');
|
||||
}
|
||||
|
||||
private getLightIconPath(extensionTreeItem: vscode.TreeItem): string {
|
||||
private getLightIconPath(extensionTreeItem: vscode.TreeItem): string | IThemeIcon {
|
||||
if (extensionTreeItem.iconPath) {
|
||||
if (typeof extensionTreeItem.iconPath === 'string' || extensionTreeItem.iconPath instanceof URI) {
|
||||
if (typeof extensionTreeItem.iconPath === 'string'
|
||||
|| extensionTreeItem.iconPath instanceof URI
|
||||
|| extensionTreeItem.iconPath instanceof ThemeIcon) {
|
||||
return this.getIconPath(extensionTreeItem.iconPath);
|
||||
}
|
||||
return this.getIconPath(extensionTreeItem.iconPath['light']);
|
||||
@@ -325,17 +327,20 @@ class ExtHostTreeView<T> extends Disposable {
|
||||
return void 0;
|
||||
}
|
||||
|
||||
private getDarkIconPath(extensionTreeItem: vscode.TreeItem): string {
|
||||
private getDarkIconPath(extensionTreeItem: vscode.TreeItem): string | IThemeIcon {
|
||||
if (extensionTreeItem.iconPath && extensionTreeItem.iconPath['dark']) {
|
||||
return this.getIconPath(extensionTreeItem.iconPath['dark']);
|
||||
}
|
||||
return void 0;
|
||||
}
|
||||
|
||||
private getIconPath(iconPath: string | URI): string {
|
||||
private getIconPath(iconPath: string | URI | ThemeIcon): string | IThemeIcon {
|
||||
if (iconPath instanceof URI) {
|
||||
return iconPath.toString();
|
||||
}
|
||||
if (iconPath instanceof ThemeIcon) {
|
||||
return { id: iconPath.id };
|
||||
}
|
||||
return URI.file(iconPath).toString();
|
||||
}
|
||||
|
||||
|
||||
@@ -1544,6 +1544,18 @@ export enum TreeItemCollapsibleState {
|
||||
Expanded = 2
|
||||
}
|
||||
|
||||
export class ThemeIcon {
|
||||
static readonly File = new ThemeIcon('file');
|
||||
|
||||
static readonly Folder = new ThemeIcon('folder');
|
||||
|
||||
readonly id: string;
|
||||
|
||||
private constructor(id: string) {
|
||||
this.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
export class ThemeColor {
|
||||
id: string;
|
||||
constructor(id: string) {
|
||||
|
||||
@@ -13,7 +13,7 @@ import * as DOM from 'vs/base/browser/dom';
|
||||
import { $ } from 'vs/base/browser/builder';
|
||||
import { LIGHT } from 'vs/platform/theme/common/themeService';
|
||||
import { ITree, IDataSource, IRenderer, ContextMenuEvent } from 'vs/base/parts/tree/browser/tree';
|
||||
import { TreeItemCollapsibleState, ITreeItem, ITreeViewer, ICustomViewsService, ITreeViewDataProvider, ViewsRegistry, IViewDescriptor, TreeViewItemHandleArg, ICustomViewDescriptor, IViewsViewlet } from 'vs/workbench/common/views';
|
||||
import { TreeItemCollapsibleState, ITreeItem, ITreeViewer, ICustomViewsService, ITreeViewDataProvider, ViewsRegistry, IViewDescriptor, TreeViewItemHandleArg, ICustomViewDescriptor, IViewsViewlet, FileThemeIconId, FolderThemeIconId } from 'vs/workbench/common/views';
|
||||
import { IWorkbenchThemeService } from 'vs/workbench/services/themes/common/workbenchThemeService';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IProgressService2, ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
@@ -447,8 +447,19 @@ class TreeRenderer implements IRenderer {
|
||||
DOM.removeClass(templateData.label, 'custom-view-tree-node-item-label');
|
||||
DOM.removeClass(templateData.resourceLabel.element, 'custom-view-tree-node-item-resourceLabel');
|
||||
|
||||
if (resource && !icon) {
|
||||
templateData.resourceLabel.setLabel({ name: label, resource }, { fileKind: node.collapsibleState === TreeItemCollapsibleState.Collapsed || node.collapsibleState === TreeItemCollapsibleState.Expanded ? FileKind.FOLDER : FileKind.FILE, title: node.tooltip });
|
||||
if (resource && (typeof icon !== 'string')) {
|
||||
let fileKind = node.collapsibleState === TreeItemCollapsibleState.Collapsed || node.collapsibleState === TreeItemCollapsibleState.Expanded ? FileKind.FOLDER : FileKind.FILE;
|
||||
if (icon && icon.id) {
|
||||
switch (icon.id) {
|
||||
case FileThemeIconId:
|
||||
fileKind = FileKind.FILE;
|
||||
break;
|
||||
case FolderThemeIconId:
|
||||
fileKind = FileKind.FOLDER;
|
||||
break;
|
||||
}
|
||||
}
|
||||
templateData.resourceLabel.setLabel({ name: label, resource }, { fileKind, title: node.tooltip });
|
||||
DOM.addClass(templateData.resourceLabel.element, 'custom-view-tree-node-item-resourceLabel');
|
||||
} else {
|
||||
templateData.label.textContent = label;
|
||||
@@ -494,7 +505,7 @@ class TreeItemIcon extends Disposable {
|
||||
const fileIconTheme = this.themeService.getFileIconTheme();
|
||||
const contributedIcon = this.themeService.getTheme().type === LIGHT ? this._treeItem.icon : this._treeItem.iconDark;
|
||||
|
||||
const hasContributedIcon = !!contributedIcon;
|
||||
const hasContributedIcon = typeof contributedIcon === 'string';
|
||||
const hasChildren = this._treeItem.collapsibleState !== TreeItemCollapsibleState.None;
|
||||
const hasResource = !!this._treeItem.resourceUri;
|
||||
const isFolder = hasResource && hasChildren;
|
||||
|
||||
@@ -202,6 +202,13 @@ export enum TreeItemCollapsibleState {
|
||||
Expanded = 2
|
||||
}
|
||||
|
||||
export const FileThemeIconId = 'file';
|
||||
export const FolderThemeIconId = 'folder';
|
||||
|
||||
export interface IThemeIcon {
|
||||
readonly id: string;
|
||||
}
|
||||
|
||||
export interface ITreeItem {
|
||||
|
||||
handle: string;
|
||||
@@ -212,9 +219,9 @@ export interface ITreeItem {
|
||||
|
||||
label?: string;
|
||||
|
||||
icon?: string;
|
||||
icon?: string | IThemeIcon;
|
||||
|
||||
iconDark?: string;
|
||||
iconDark?: string | IThemeIcon;
|
||||
|
||||
resourceUri?: UriComponents;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user