Skip to content

Commit

Permalink
Support ThemeIcon color property (#11243)
Browse files Browse the repository at this point in the history
* Add optional color property to ThemeIcon
* Hand over the ThemeIcon instead of just its id from ext to main
* Apply the color in the `PluginTree`
* Adapt `TreeViewNode.is` to also recognize sub types such as `CompositeTreeViewNode`

Fixes #11128

Contributed on behalf of STMicroelectronics

Signed-off-by: Lucas Koehler <[email protected]>
  • Loading branch information
lucas-koehler authored Jun 9, 2022
1 parent b2e44a9 commit 0398116
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
## v1.27.0 - Unreleased

- [plugin] moved `WebviewViewResolveContext` from `window` to `root` namespace [#11216](https://github.com/eclipse-theia/theia/pull/11216) - Contributed on behalf of STMicroelectronics
- [plugin] Add support for property `color` of `ThemeIcon`. [#11243](https://github.com/eclipse-theia/theia/pull/11243) - Contributed on behalf of STMicroelectronics

<a name="breaking_changes_1.27.0">[Breaking Changes:](#breaking_changes_1.27.0)</a>

Expand Down
7 changes: 6 additions & 1 deletion packages/plugin-ext/src/common/plugin-api-rpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ export interface TreeViewItem {
icon?: string;
iconUrl?: IconUrl;

themeIconId?: string;
themeIcon?: ThemeIcon;

resourceUri?: UriComponents;

Expand Down Expand Up @@ -1077,6 +1077,11 @@ export interface ThemeColor {
id: string;
}

export interface ThemeIcon {
id: string;
color?: ThemeColor;
}

/**
* Describes the behavior of decorations when typing/editing near their edges.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export class PluginTreeViewNodeLabelProvider implements LabelProviderContributio

// eslint-disable-next-line @typescript-eslint/no-explicit-any
canHandle(element: TreeViewNode | any): number {
if (TreeNode.is(element) && ('resourceUri' in element || 'themeIconId' in element)) {
if (TreeNode.is(element) && ('resourceUri' in element || 'themeIcon' in element)) {
return this.treeLabelProvider.canHandle(element) + 1;
}
return 0;
Expand All @@ -43,12 +43,14 @@ export class PluginTreeViewNodeLabelProvider implements LabelProviderContributio
if (node.icon) {
return node.icon;
}
if (node.themeIconId) {
if (node.themeIconId === 'file' || node.themeIconId === 'folder') {
if (node.themeIcon) {
if (node.themeIcon.id === 'file' || node.themeIcon.id === 'folder') {
const uri = node.resourceUri && new URI(node.resourceUri) || undefined;
return this.labelProvider.getIcon(URIIconReference.create(node.themeIconId, uri));
if (uri) {
return this.labelProvider.getIcon(URIIconReference.create(node.themeIcon.id, uri));
}
}
return ThemeIcon.asClassName({ id: node.themeIconId });
return ThemeIcon.asClassName(node.themeIcon);
}
if (node.resourceUri) {
return this.labelProvider.getIcon(new URI(node.resourceUri));
Expand Down
25 changes: 18 additions & 7 deletions packages/plugin-ext/src/main/browser/view/tree-view-widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import { URI } from '@theia/core/shared/vscode-uri';
import { injectable, inject, postConstruct } from '@theia/core/shared/inversify';
import { TreeViewsExt, TreeViewItemCollapsibleState, TreeViewItem, TreeViewSelection } from '../../../common/plugin-api-rpc';
import { TreeViewsExt, TreeViewItemCollapsibleState, TreeViewItem, TreeViewSelection, ThemeIcon } from '../../../common/plugin-api-rpc';
import { Command } from '../../../common/plugin-api-rpc-model';
import {
TreeNode,
Expand Down Expand Up @@ -46,6 +46,7 @@ import * as markdownit from '@theia/core/shared/markdown-it';
import { MarkdownString } from '@theia/core/lib/common/markdown-rendering';
import { LabelParser } from '@theia/core/lib/browser/label-parser';
import { AccessibilityInformation } from '@theia/plugin';
import { ColorRegistry } from '@theia/core/lib/browser/color-registry';

export const TREE_NODE_HYPERLINK = 'theia-TreeNodeHyperlink';
export const VIEW_ITEM_CONTEXT_MENU: MenuPath = ['view-item-context-menu'];
Expand All @@ -60,15 +61,15 @@ export interface TreeViewNode extends SelectableTreeNode {
contextValue?: string;
command?: Command;
resourceUri?: string;
themeIconId?: string | 'folder' | 'file';
themeIcon?: ThemeIcon;
tooltip?: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
description?: string | boolean | any;
accessibilityInformation?: AccessibilityInformation;
}
export namespace TreeViewNode {
export function is(arg: TreeNode | undefined): arg is TreeViewNode {
return !!arg && SelectableTreeNode.is(arg) && !ExpandableTreeNode.is(arg) && !CompositeTreeNode.is(arg);
return !!arg && SelectableTreeNode.is(arg);
}
}

Expand Down Expand Up @@ -151,12 +152,12 @@ export class PluginTree extends TreeImpl {
protected createTreeNode(item: TreeViewItem, parent: CompositeTreeNode): TreeNode {
const icon = this.toIconClass(item);
const resourceUri = item.resourceUri && URI.revive(item.resourceUri).toString();
const themeIconId = item.themeIconId ? item.themeIconId : item.collapsibleState !== TreeViewItemCollapsibleState.None ? 'folder' : 'file';
const themeIcon = item.themeIcon ? item.themeIcon : item.collapsibleState !== TreeViewItemCollapsibleState.None ? { id: 'folder' } : { id: 'file' };
const update: Partial<TreeViewNode> = {
name: item.label,
icon,
description: item.description,
themeIconId,
themeIcon,
resourceUri,
tooltip: item.tooltip,
contextValue: item.contextValue,
Expand All @@ -178,7 +179,7 @@ export class PluginTree extends TreeImpl {
command: item.command
}, update);
}
if (TreeViewNode.is(node)) {
if (TreeViewNode.is(node) && !ExpandableTreeNode.is(node)) {
return Object.assign(node, update, { command: item.command });
}
return Object.assign({
Expand Down Expand Up @@ -257,6 +258,9 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
@inject(LabelParser)
protected readonly labelParser: LabelParser;

@inject(ColorRegistry)
protected readonly colorRegistry: ColorRegistry;

protected readonly markdownIt = markdownit();

@postConstruct()
Expand Down Expand Up @@ -286,7 +290,14 @@ export class TreeViewWidget extends TreeViewWelcomeWidget {
protected override renderIcon(node: TreeNode, props: NodeProps): React.ReactNode {
const icon = this.toNodeIcon(node);
if (icon) {
return <div className={icon + ' theia-tree-view-icon'}></div>;
let style: React.CSSProperties | undefined;
if (TreeViewNode.is(node) && node.themeIcon?.color) {
const color = this.colorRegistry.getCurrentColor(node.themeIcon.color.id);
if (color) {
style = { color };
}
}
return <div className={icon + ' theia-tree-view-icon'} style={style}></div>;
}
return undefined;
}
Expand Down
6 changes: 3 additions & 3 deletions packages/plugin-ext/src/plugin/tree/tree-views.ts
Original file line number Diff line number Diff line change
Expand Up @@ -366,12 +366,12 @@ class TreeViewExtImpl<T> implements Disposable {

let icon;
let iconUrl;
let themeIconId;
let themeIcon;
const { iconPath } = treeItem;
if (typeof iconPath === 'string' && iconPath.indexOf('fa-') !== -1) {
icon = iconPath;
} else if (ThemeIcon.is(iconPath)) {
themeIconId = iconPath.id;
themeIcon = iconPath;
} else {
iconUrl = PluginIconPath.toUrl(<PluginIconPath | undefined>iconPath, this.plugin);
}
Expand All @@ -381,7 +381,7 @@ class TreeViewExtImpl<T> implements Disposable {
label,
icon,
iconUrl,
themeIconId,
themeIcon,
description: treeItem.description,
resourceUri: treeItem.resourceUri,
tooltip: treeItem.tooltip,
Expand Down
2 changes: 1 addition & 1 deletion packages/plugin-ext/src/plugin/types-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ export class ThemeIcon {

static readonly Folder: ThemeIcon = new ThemeIcon('folder');

private constructor(public id: string) {
private constructor(public id: string, public color?: ThemeColor) {
}

}
Expand Down
17 changes: 16 additions & 1 deletion packages/plugin/src/theia.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2652,7 +2652,22 @@ export module '@theia/plugin' {
*/
static readonly Folder: ThemeIcon;

private constructor(public id: string);
/**
* The id of the icon. The available icons are listed in https://code.visualstudio.com/api/references/icons-in-labels#icon-listing.
*/
readonly id: string;

/**
* The optional ThemeColor of the icon. The color is currently only used in {@link TreeItem}.
*/
readonly color?: ThemeColor | undefined;

/**
* Creates a reference to a theme icon.
* @param id id of the icon. The available icons are listed in https://code.visualstudio.com/api/references/icons-in-labels#icon-listing.
* @param color optional `ThemeColor` for the icon. The color is currently only used in {@link TreeItem}.
*/
private constructor(public id: string, public color?: ThemeColor);
}

/**
Expand Down

0 comments on commit 0398116

Please sign in to comment.