Skip to content

Commit

Permalink
Merge pull request #61482 from Microsoft/sandy081/61313
Browse files Browse the repository at this point in the history
Introduce tree item highlights
  • Loading branch information
sandy081 authored Oct 23, 2018
2 parents e0c3014 + d0849b7 commit 6baf2fd
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 40 deletions.
31 changes: 31 additions & 0 deletions src/vs/vscode.proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1141,4 +1141,35 @@ declare module 'vscode' {
alwaysShow?: boolean;
}
//#endregion

//#region Tree Item Label Highlights
/**
* Label describing the [Tree item](#TreeItem)
*/
export interface TreeItemLabel {

/**
* A human-readable string describing the [Tree item](#TreeItem).
*/
label: string;

/**
* Ranges in the label to highlight.
*/
highlights?: [number, number][];

}

export class TreeItem2 extends TreeItem {
/**
* Label describing this item. When `falsy`, it is derived from [resourceUri](#TreeItem.resourceUri).
*/
label?: string | TreeItemLabel | /* for compilation */ any;

/**
* @param label Label describing this item
* @param collapsibleState [TreeItemCollapsibleState](#TreeItemCollapsibleState) of the tree item. Default is [TreeItemCollapsibleState.None](#TreeItemCollapsibleState.None)
*/
constructor(label: TreeItemLabel, collapsibleState?: TreeItemCollapsibleState);
}
}
1 change: 1 addition & 0 deletions src/vs/workbench/api/node/extHost.api.impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,7 @@ export function createApiFactory(
ThemeColor: extHostTypes.ThemeColor,
ThemeIcon: extHostTypes.ThemeIcon,
TreeItem: extHostTypes.TreeItem,
TreeItem2: extHostTypes.TreeItem,
TreeItemCollapsibleState: extHostTypes.TreeItemCollapsibleState,
Uri: URI,
ViewColumn: extHostTypes.ViewColumn,
Expand Down
29 changes: 25 additions & 4 deletions src/vs/workbench/api/node/extHostTreeViews.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,36 @@ import { URI } from 'vs/base/common/uri';
import { debounceEvent, Emitter, Event } from 'vs/base/common/event';
import { Disposable } from 'vs/base/common/lifecycle';
import { ExtHostTreeViewsShape, MainThreadTreeViewsShape } from './extHost.protocol';
import { ITreeItem, TreeViewItemHandleArg } from 'vs/workbench/common/views';
import { ITreeItem, TreeViewItemHandleArg, ITreeItemLabel } from 'vs/workbench/common/views';
import { ExtHostCommands, CommandsConverter } from 'vs/workbench/api/node/extHostCommands';
import { asThenable } from 'vs/base/common/async';
import { TreeItemCollapsibleState, ThemeIcon } from 'vs/workbench/api/node/extHostTypes';
import { isUndefinedOrNull } from 'vs/base/common/types';
import { isUndefinedOrNull, isString } from 'vs/base/common/types';
import { equals } from 'vs/base/common/arrays';
import { ILogService } from 'vs/platform/log/common/log';

type TreeItemHandle = string;

function toTreeItemLabel(label: any): ITreeItemLabel {
if (isString(label)) {
return { label };
}

if (label
&& typeof label === 'object'
&& typeof label.label === 'string') {
let highlights: [number, number][] = void 0;
if (Array.isArray(label.highlights)) {
highlights = (<[number, number][]>label.highlights).filter((highlight => highlight.length === 2 && typeof highlight[0] === 'number' && typeof highlight[1] === 'number'));
highlights = highlights.length ? highlights : void 0;
}
return { label: label.label, highlights };
}

return void 0;
}


export class ExtHostTreeViews implements ExtHostTreeViewsShape {

private treeViews: Map<string, ExtHostTreeView<any>> = new Map<string, ExtHostTreeView<any>>();
Expand Down Expand Up @@ -383,7 +403,7 @@ class ExtHostTreeView<T> extends Disposable {
const item = {
handle,
parentHandle: parent ? parent.item.handle : void 0,
label: extensionTreeItem.label,
label: toTreeItemLabel(extensionTreeItem.label),
resourceUri: extensionTreeItem.resourceUri,
tooltip: typeof extensionTreeItem.tooltip === 'string' ? extensionTreeItem.tooltip : void 0,
command: extensionTreeItem.command ? this.commands.toInternal(extensionTreeItem.command) : void 0,
Expand All @@ -402,8 +422,9 @@ class ExtHostTreeView<T> extends Disposable {
return `${ExtHostTreeView.ID_HANDLE_PREFIX}/${id}`;
}

const treeItemLabel = toTreeItemLabel(label);
const prefix: string = parent ? parent.item.handle : ExtHostTreeView.LABEL_HANDLE_PREFIX;
let elementId = label ? label : resourceUri ? basename(resourceUri.path) : '';
let elementId = treeItemLabel ? treeItemLabel.label : resourceUri ? basename(resourceUri.path) : '';
elementId = elementId.indexOf('/') !== -1 ? elementId.replace('/', '//') : elementId;
const existingHandle = this.nodes.has(element) ? this.nodes.get(element).item.handle : void 0;
const childrenNodes = (this.getChildrenNodes(parent) || []);
Expand Down
6 changes: 3 additions & 3 deletions src/vs/workbench/api/node/extHostTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1791,16 +1791,16 @@ export enum ProgressLocation {

export class TreeItem {

label?: string;
label?: string | vscode.TreeItemLabel;
resourceUri?: URI;
iconPath?: string | URI | { light: string | URI; dark: string | URI };
command?: vscode.Command;
contextValue?: string;
tooltip?: string;

constructor(label: string, collapsibleState?: vscode.TreeItemCollapsibleState)
constructor(label: string | vscode.TreeItemLabel, collapsibleState?: vscode.TreeItemCollapsibleState)
constructor(resourceUri: URI, collapsibleState?: vscode.TreeItemCollapsibleState)
constructor(arg1: string | URI, public collapsibleState: vscode.TreeItemCollapsibleState = TreeItemCollapsibleState.None) {
constructor(arg1: string | vscode.TreeItemLabel | URI, public collapsibleState: vscode.TreeItemCollapsibleState = TreeItemCollapsibleState.None) {
if (arg1 instanceof URI) {
this.resourceUri = arg1;
} else {
Expand Down
14 changes: 8 additions & 6 deletions src/vs/workbench/browser/parts/views/customView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { IContextMenuService } from 'vs/platform/contextview/browser/contextView
import { IMenuService, MenuId, MenuItemAction } from 'vs/platform/actions/common/actions';
import { ContextAwareMenuItemActionItem, fillInActionBarActions, fillInContextMenuActions } from 'vs/platform/actions/browser/menuItemActionItem';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IViewsService, ITreeViewer, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ICustomViewDescriptor, ViewsRegistry, ViewContainer } from 'vs/workbench/common/views';
import { IViewsService, ITreeViewer, ITreeItem, TreeItemCollapsibleState, ITreeViewDataProvider, TreeViewItemHandleArg, ICustomViewDescriptor, ViewsRegistry, ViewContainer, ITreeItemLabel } from 'vs/workbench/common/views';
import { IViewletViewOptions, FileIconThemableWorkbenchTree } from 'vs/workbench/browser/parts/views/viewsViewlet';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { INotificationService } from 'vs/platform/notification/common/notification';
Expand Down Expand Up @@ -164,7 +164,7 @@ class TitleMenus implements IDisposable {
}

class Root implements ITreeItem {
label = 'root';
label = { label: 'root' };
handle = '0';
parentHandle = null;
collapsibleState = TreeItemCollapsibleState.Expanded;
Expand Down Expand Up @@ -513,7 +513,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, {});
const resourceLabel = this.instantiationService.createInstance(ResourceLabel, container, { supportHighlights: true });
DOM.addClass(resourceLabel.element, 'custom-view-tree-node-item-resourceLabel');
const actionsContainer = DOM.append(resourceLabel.element, DOM.$('.actions'));
const actionBar = new ActionBar(actionsContainer, {
Expand All @@ -526,7 +526,9 @@ class TreeRenderer implements IRenderer {

renderElement(tree: ITree, node: ITreeItem, templateId: string, templateData: ITreeExplorerTemplateData): void {
const resource = node.resourceUri ? URI.revive(node.resourceUri) : null;
const label = node.label ? node.label : resource ? basename(resource.path) : '';
const treeItemLabel: ITreeItemLabel = node.label ? node.label : resource ? { label: basename(resource.path) } : void 0;
const label = treeItemLabel ? treeItemLabel.label : void 0;
const matches = treeItemLabel ? treeItemLabel.highlights.map(([start, end]) => ({ start, end })) : void 0;
const icon = this.themeService.getTheme().type === LIGHT ? node.icon : node.iconDark;
const iconUrl = icon ? URI.revive(icon) : null;
const title = node.tooltip ? node.tooltip : resource ? void 0 : label;
Expand All @@ -537,9 +539,9 @@ class TreeRenderer implements IRenderer {

if (resource || node.themeIcon) {
const fileDecorations = this.configurationService.getValue<{ colors: boolean, badges: boolean }>('explorer.decorations');
templateData.resourceLabel.setLabel({ name: label, resource: resource ? resource : URI.parse('missing:_icon_resource') }, { fileKind: this.getFileKind(node), title, hideIcon: !!iconUrl, fileDecorations, extraClasses: ['custom-view-tree-node-item-resourceLabel'] });
templateData.resourceLabel.setLabel({ name: label, 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 }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'] });
templateData.resourceLabel.setLabel({ name: label }, { title, hideIcon: true, extraClasses: ['custom-view-tree-node-item-resourceLabel'], matches });
}

templateData.icon.style.backgroundImage = iconUrl ? `url('${iconUrl.toString(true)}')` : '';
Expand Down
10 changes: 9 additions & 1 deletion src/vs/workbench/common/views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,14 @@ export enum TreeItemCollapsibleState {
Expanded = 2
}

export interface ITreeItemLabel {

label: string;

highlights?: [number, number][];

}

export interface ITreeItem {

handle: string;
Expand All @@ -288,7 +296,7 @@ export interface ITreeItem {

collapsibleState: TreeItemCollapsibleState;

label?: string;
label?: ITreeItemLabel;

icon?: UriComponents;

Expand Down
Loading

0 comments on commit 6baf2fd

Please sign in to comment.