提交 0a66ff1c 编写于 作者: S Sandeep Somavarapu

Fix #43531

上级 79e6a07c
......@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
import 'vs/css!./media/views';
import Event, { Emitter } from 'vs/base/common/event';
import * as errors from 'vs/base/common/errors';
import { IDisposable, Disposable, dispose } from 'vs/base/common/lifecycle';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
......@@ -102,14 +101,10 @@ class CustomTreeViewer extends Disposable implements ITreeViewer {
private _hasIconForParentNode = false;
private _hasIconForLeafNode = false;
private _onDidIconsChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidIconsChange: Event<void> = this._onDidIconsChange.event;
private treeContainer: HTMLElement;
private tree: FileIconThemableWorkbenchTree;
private root: ITreeItem;
private elementsToRefresh: ITreeItem[] = [];
private refreshing = 0;
private _dataProvider: ITreeViewDataProvider;
private dataProviderDisposables: IDisposable[] = [];
......@@ -134,7 +129,6 @@ class CustomTreeViewer extends Disposable implements ITreeViewer {
set dataProvider(dataProvider: ITreeViewDataProvider) {
dispose(this.dataProviderDisposables);
if (dataProvider) {
const customTreeView: CustomTreeViewer = this;
this._dataProvider = new class implements ITreeViewDataProvider {
onDidChange = dataProvider.onDidChange;
onDispose = dataProvider.onDispose;
......@@ -145,9 +139,6 @@ class CustomTreeViewer extends Disposable implements ITreeViewer {
const promise = node instanceof Root ? dataProvider.getChildren() : dataProvider.getChildren(node);
return promise.then(children => {
node.children = children;
if (!customTreeView.refreshing) {
customTreeView.updateIconsAvailability(node);
}
return children;
});
}
......@@ -223,7 +214,7 @@ class CustomTreeViewer extends Disposable implements ITreeViewer {
const actionItemProvider = (action: IAction) => action instanceof MenuItemAction ? this.instantiationService.createInstance(ContextAwareMenuItemActionItem, action) : undefined;
const menus = this.instantiationService.createInstance(Menus, this.id);
const dataSource = this.instantiationService.createInstance(TreeDataSource, this);
const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, this, menus, actionItemProvider);
const renderer = this.instantiationService.createInstance(TreeRenderer, this.id, menus, actionItemProvider);
const controller = this.instantiationService.createInstance(TreeController, this.id, menus);
this.tree = this.instantiationService.createInstance(FileIconThemableWorkbenchTree, this.treeContainer, { dataSource, renderer, controller }, {});
this.tree.contextKeyService.createKey<boolean>(this.id, true);
......@@ -290,60 +281,11 @@ class CustomTreeViewer extends Disposable implements ITreeViewer {
private doRefresh(elements: ITreeItem[]): TPromise<void> {
if (this.tree) {
return TPromise.join(elements.map(e => {
this.refreshing++;
return this.tree.refresh(e).then(() => this.refreshing--, () => this.refreshing--);
})).then(() => this.updateIconsAvailability(this.root));
return TPromise.join(elements.map(e => this.tree.refresh(e))).then(() => null);
}
return TPromise.as(null);
}
private updateIconsAvailability(parent: ITreeItem): void {
if (this.activated && this.tree) {
const initialResult = parent instanceof Root ? { hasIconForParentNode: false, hasIconForLeafNode: false } : { hasIconForParentNode: this.hasIconForParentNode, hasIconForLeafNode: this.hasIconForLeafNode };
const { hasIconForParentNode, hasIconForLeafNode } = this.computeIconsAvailability(parent.children || [], initialResult);
const changed = this.hasIconForParentNode !== hasIconForParentNode || this.hasIconForLeafNode !== hasIconForLeafNode;
this._hasIconForParentNode = hasIconForParentNode;
this._hasIconForLeafNode = hasIconForLeafNode;
if (changed) {
this._onDidIconsChange.fire();
}
DOM.toggleClass(this.treeContainer, 'custom-view-align-icons-and-twisties', this.hasIconForLeafNode && !this.hasIconForParentNode);
}
}
private computeIconsAvailability(nodes: ITreeItem[], result: { hasIconForParentNode: boolean, hasIconForLeafNode: boolean }): { hasIconForParentNode: boolean, hasIconForLeafNode: boolean } {
if (!result.hasIconForLeafNode || !result.hasIconForParentNode) {
for (const node of nodes) {
if (this.hasIcon(node)) {
result.hasIconForParentNode = result.hasIconForParentNode || node.collapsibleState !== TreeItemCollapsibleState.None;
result.hasIconForLeafNode = result.hasIconForLeafNode || node.collapsibleState === TreeItemCollapsibleState.None;
}
this.computeIconsAvailability(node.children || [], result);
if (result.hasIconForLeafNode && result.hasIconForParentNode) {
return result;
}
}
}
return result;
}
private hasIcon(node: ITreeItem): boolean {
const icon = this.themeService.getTheme().type === LIGHT ? node.icon : node.iconDark;
if (icon) {
return true;
}
if (node.resourceUri || node.themeIcon) {
const fileIconTheme = this.themeService.getFileIconTheme();
const isFolder = node.themeIcon ? node.themeIcon.id === FolderThemeIcon.id : node.collapsibleState !== TreeItemCollapsibleState.None;
if (isFolder) {
return fileIconTheme.hasFileIcons && fileIconTheme.hasFolderIcons;
}
return fileIconTheme.hasFileIcons;
}
return false;
}
private onSelection({ payload }: any): void {
const selection: ITreeItem = this.tree.getSelection()[0];
if (selection) {
......@@ -395,7 +337,7 @@ class TreeDataSource implements IDataSource {
interface ITreeExplorerTemplateData {
label: HTMLElement;
resourceLabel: ResourceLabel;
icon: TreeItemIcon;
icon: HTMLElement;
actionBar: ActionBar;
}
......@@ -406,7 +348,6 @@ class TreeRenderer implements IRenderer {
constructor(
private treeViewId: string,
private treeViewer: ITreeViewer,
private menus: Menus,
private actionItemProvider: IActionItemProvider,
@IInstantiationService private instantiationService: IInstantiationService,
......@@ -425,7 +366,7 @@ class TreeRenderer implements IRenderer {
public renderTemplate(tree: ITree, templateId: string, container: HTMLElement): ITreeExplorerTemplateData {
DOM.addClass(container, 'custom-view-tree-node-item');
const icon = this.instantiationService.createInstance(TreeItemIcon, container, this.treeViewer);
const icon = DOM.append(container, DOM.$('.custom-view-tree-node-item-icon'));
const label = DOM.append(container, DOM.$('.custom-view-tree-node-item-label'));
const resourceLabel = this.instantiationService.createInstance(ResourceLabel, container, {});
const actionsContainer = DOM.append(container, DOM.$('.actions'));
......@@ -459,7 +400,8 @@ class TreeRenderer implements IRenderer {
templateData.label.title = typeof node.tooltip === 'string' ? node.tooltip : label;
}
templateData.icon.treeItem = node;
templateData.icon.style.backgroundImage = icon ? `url('${icon}')` : '';
DOM.toggleClass(templateData.icon, 'custom-view-tree-node-item-icon', !!icon);
templateData.actionBar.context = (<TreeViewItemHandleArg>{ $treeViewId: this.treeViewId, $treeItemHandle: node.handle });
templateData.actionBar.push(this.menus.getResourceActions(node), { icon: true, label: false });
}
......@@ -479,55 +421,6 @@ class TreeRenderer implements IRenderer {
public disposeTemplate(tree: ITree, templateId: string, templateData: ITreeExplorerTemplateData): void {
templateData.resourceLabel.dispose();
templateData.actionBar.dispose();
templateData.icon.dispose();
}
}
class TreeItemIcon extends Disposable {
private _treeItem: ITreeItem;
private iconElement: HTMLElement;
constructor(
container: HTMLElement,
private treeViewer: CustomTreeViewer,
@IInstantiationService instantiationService: IInstantiationService,
@IWorkbenchThemeService private themeService: IWorkbenchThemeService
) {
super();
this.iconElement = DOM.append(container, DOM.$('.custom-view-tree-node-item-icon'));
this._register(this.treeViewer.onDidIconsChange(() => this.render()));
}
set treeItem(treeItem: ITreeItem) {
this._treeItem = treeItem;
this.render();
}
private render(): void {
if (this._treeItem) {
const fileIconTheme = this.themeService.getFileIconTheme();
const contributedIcon = this.themeService.getTheme().type === LIGHT ? this._treeItem.icon : this._treeItem.iconDark;
const hasContributedIcon = !!contributedIcon;
const hasChildren = this._treeItem.collapsibleState !== TreeItemCollapsibleState.None;
const hasThemeIcon = !!this._treeItem.resourceUri || !!this._treeItem.themeIcon;
const isFolder = hasThemeIcon ? (this._treeItem.themeIcon ? this._treeItem.themeIcon.id === FolderThemeIcon.id : hasChildren) : false;
const isFile = hasThemeIcon ? (this._treeItem.themeIcon ? this._treeItem.themeIcon.id === FileThemeIcon.id : !hasChildren) : false;
const hasThemeFolderIcon = isFolder && fileIconTheme.hasFileIcons && fileIconTheme.hasFolderIcons;
const hasThemeFileIcon = isFile && fileIconTheme.hasFileIcons;
const hasIcon = hasContributedIcon || hasThemeFolderIcon || hasThemeFileIcon;
const hasFolderPlaceHolderIcon = hasIcon ? false : isFolder && this.treeViewer.hasIconForParentNode;
const hasFilePlaceHolderIcon = hasIcon ? false : isFile && this.treeViewer.hasIconForLeafNode;
const hasContainerPlaceHolderIcon = hasIcon || hasFolderPlaceHolderIcon ? false : hasChildren && this.treeViewer.hasIconForParentNode;
const hasLeafPlaceHolderIcon = hasIcon || hasFilePlaceHolderIcon ? false : !hasChildren && (this.treeViewer.hasIconForParentNode || this.treeViewer.hasIconForLeafNode);
this.iconElement.style.backgroundImage = hasContributedIcon ? `url('${contributedIcon}')` : '';
DOM.toggleClass(this.iconElement, 'folder-icon', hasFolderPlaceHolderIcon);
DOM.toggleClass(this.iconElement, 'file-icon', hasFilePlaceHolderIcon);
DOM.toggleClass(this.iconElement, 'placeholder-icon', hasContainerPlaceHolderIcon);
DOM.toggleClass(this.iconElement, 'custom-view-tree-node-item-icon', hasContributedIcon || hasFolderPlaceHolderIcon || hasFilePlaceHolderIcon || hasContainerPlaceHolderIcon || hasLeafPlaceHolderIcon);
}
}
}
......
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-bg{fill:#656565;} .icon-vs-fg{fill:#F0EFF1;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M4 15c-.97 0-2-.701-2-2v-10c0-1.299 1.03-2 2-2h6.061l3.939 3.556v8.444c0 .97-.701 2-2 2h-8z" id="outline"/><path class="icon-vs-bg" d="M9.641,2H3.964C3.964,2,3,2,3,3c0,0.805,0,7.442,0,10c0,1,0.965,1,0.965,1s7,0,8,0S13,13,13,13V5L9.641,2zM12,13H4V3h5v3h3V13z" id="iconBg"/><path class="icon-vs-fg" d="M4 3h5v3h3v7h-8v-10z" id="iconFg"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-bg{fill:#C5C5C5;} .icon-vs-fg{opacity:0;fill:#F0EFF1;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M4 15c-.97 0-2-.701-2-2v-10c0-1.299 1.03-2 2-2h6.061l3.939 3.556v8.444c0 .97-.701 2-2 2h-8z" id="outline"/><path class="icon-vs-bg" d="M9.641,2H3.964C3.964,2,3,2,3,3c0,0.805,0,7.442,0,10c0,1,0.965,1,0.965,1s7,0,8,0S13,13,13,13V5L9.641,2zM12,13H4V3h5v3h3V13z" id="iconBg"/><path class="icon-vs-fg" d="M4 3h5v3h3v7h-8v-10z" id="iconFg"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-fg{fill:#F0EFF1;} .icon-folder{fill:#656565;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M14 .969h-7.116l-1 2h-2.884c-.97 0-2 .701-2 2v2h-1v1.196l2.323 5.804h11.677s.86-.021 1.43-.565c.344-.332.57-.817.57-1.435v-9c0-1.303-1.005-2-2-2z" id="outline"/><path class="icon-folder" d="M14,2c0,0,1,0,1,1c0,2.36,0,8.205,0,9c0,1-1,0.984-1,0.984V3H8L7,5H3v3h8l3,5H3L1,8h1c0,0,0-2,0-3s1.236-1,1-1h3.5l1-2H14z" id="iconBg"/><path class="icon-vs-fg" d="M3 7.969v-3h4l1-2h6v10l-3-5h-8z" id="iconFg"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-fg{opacity:0;fill:#F0EFF1;} .icon-folder{fill:#C5C5C5;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M14 .969h-7.116l-1 2h-2.884c-.97 0-2 .701-2 2v2h-1v1.196l2.323 5.804h11.677s.86-.021 1.43-.565c.344-.332.57-.817.57-1.435v-9c0-1.303-1.005-2-2-2z" id="outline"/><path class="icon-folder" d="M14,2c0,0,1,0,1,1c0,2.36,0,8.205,0,9c0,1-1,0.984-1,0.984V3H8L7,5H3v3h8l3,5H3L1,8h1c0,0,0-2,0-3s1.236-1,1-1h3.5l1-2H14z" id="iconBg"/><path class="icon-vs-fg" d="M3 7.969v-3h4l1-2h6v10l-3-5h-8z" id="iconFg"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-fg{fill:#F0EFF1;} .icon-folder{fill:#656565;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M16 2.5v10c0 .827-.673 1.5-1.5 1.5h-11.996c-.827 0-1.5-.673-1.5-1.5v-8c0-.827.673-1.5 1.5-1.5h2.886l1-2h8.11c.827 0 1.5.673 1.5 1.5z" id="outline"/><path class="icon-folder" d="M14.5 2h-7.492l-1 2h-3.504c-.277 0-.5.224-.5.5v8c0 .276.223.5.5.5h11.996c.275 0 .5-.224.5-.5v-10c0-.276-.225-.5-.5-.5zm-.496 2h-6.496l.5-1h5.996v1z" id="iconBg"/><path class="icon-vs-fg" d="M14 3v1h-6.5l.5-1h6z" id="iconFg"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-fg{opacity:0;fill:#F0EFF1;} .icon-folder{fill:#C5C5C5;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M16 2.5v10c0 .827-.673 1.5-1.5 1.5h-11.996c-.827 0-1.5-.673-1.5-1.5v-8c0-.827.673-1.5 1.5-1.5h2.886l1-2h8.11c.827 0 1.5.673 1.5 1.5z" id="outline"/><path class="icon-folder" d="M14.5 2h-7.492l-1 2h-3.504c-.277 0-.5.224-.5.5v8c0 .276.223.5.5.5h11.996c.275 0 .5-.224.5-.5v-10c0-.276-.225-.5-.5-.5zm-.496 2h-6.496l.5-1h5.996v1z" id="iconBg"/><path class="icon-vs-fg" d="M14 3v1h-6.5l.5-1h6z" id="iconFg"/></svg>
\ No newline at end of file
......@@ -50,14 +50,6 @@
display: none;
}
.tree-explorer-viewlet-tree-view.file-icon-themable-tree.custom-view-align-icons-and-twisties .monaco-tree-row:not(.has-children) .content::before {
display: none;
}
.tree-explorer-viewlet-tree-view.file-icon-themable-tree.align-icons-and-twisties:not(.custom-view-align-icons-and-twisties) .monaco-tree-row:not(.has-children) .content::before {
display: block;
}
.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item {
display: flex;
height: 22px;
......@@ -85,48 +77,6 @@
-webkit-font-smoothing: antialiased;
}
.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon.placeholder-icon {
border: 1px;
border-style:dashed;
border-radius: 1px;
margin: 5px 6px 5px 2px;
height: 12px;
width: 6px;
}
.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon.file-icon {
content: ' ';
background-image: url('Document_16x.svg');
}
.hs-black .tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon.file-icon,
.vs-dark .tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon.file-icon {
content: ' ';
background-image: url('Document_16x_inverse.svg');
}
.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon.folder-icon {
content: ' ';
background-image: url('Folder_16x.svg');
}
.hs-black .tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon.folder-icon,
.vs-dark .tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .custom-view-tree-node-item-icon.folder-icon {
content: ' ';
background-image: url('Folder_16x_inverse.svg');
}
.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row.expanded .custom-view-tree-node-item > .custom-view-tree-node-item-icon.folder-icon {
content: ' ';
background-image: url('FolderOpen_16x.svg');
}
.hc-black .tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row.expanded .custom-view-tree-node-item > .custom-view-tree-node-item-icon.folder-icon,
.vs-dark .tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row.expanded .custom-view-tree-node-item > .custom-view-tree-node-item-icon.folder-icon {
content: ' ';
background-image: url('FolderOpen_16x_inverse.svg');
}
.tree-explorer-viewlet-tree-view .monaco-tree .monaco-tree-row .custom-view-tree-node-item > .actions {
display: none;
padding-right: 6px;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册