提交 a2e8a03d 编写于 作者: S Sandeep Somavarapu

#69955 Adopt to new tree

上级 f0772536
......@@ -5,19 +5,20 @@
import * as dom from 'vs/base/browser/dom';
import { localize } from 'vs/nls';
import { IMouseEvent } from 'vs/base/browser/mouseEvent';
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import { IDataSource, ITree, IRenderer } from 'vs/base/parts/tree/browser/tree';
import { Action } from 'vs/base/common/actions';
import { IExtensionsWorkbenchService, IExtension } from 'vs/workbench/contrib/extensions/common/extensions';
import { Event } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
import { WorkbenchTreeController, WorkbenchTree, IListService } from 'vs/platform/list/browser/listService';
import { IListService, WorkbenchAsyncDataTree } from 'vs/platform/list/browser/listService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { IAsyncDataSource, ITreeNode } from 'vs/base/browser/ui/tree/tree';
import { IListVirtualDelegate, IListRenderer } from 'vs/base/browser/ui/list/list';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
export interface IExtensionTemplateData {
icon: HTMLImageElement;
......@@ -39,49 +40,40 @@ export interface IExtensionData {
parent: IExtensionData | null;
}
export class DataSource implements IDataSource {
export class AsyncDataSource implements IAsyncDataSource<IExtensionData, any> {
public getId(tree: ITree, { extension, parent }: IExtensionData): string {
return parent ? this.getId(tree, parent) + '/' + extension.identifier.id : extension.identifier.id;
}
public hasChildren(tree: ITree, { hasChildren }: IExtensionData): boolean {
public hasChildren({ hasChildren }: IExtensionData): boolean {
return hasChildren;
}
public getChildren(tree: ITree, extensionData: IExtensionData): Promise<any> {
public getChildren(extensionData: IExtensionData): Promise<any> {
return extensionData.getChildren();
}
public getParent(tree: ITree, { parent }: IExtensionData): Promise<any> {
return Promise.resolve(parent);
}
}
export class Renderer implements IRenderer {
export class VirualDelegate implements IListVirtualDelegate<IExtensionData> {
private static readonly EXTENSION_TEMPLATE_ID = 'extension-template';
private static readonly UNKNOWN_EXTENSION_TEMPLATE_ID = 'unknown-extension-template';
constructor(@IInstantiationService private readonly instantiationService: IInstantiationService) {
}
public getHeight(tree: ITree, element: IExtensionData): number {
public getHeight(element: IExtensionData): number {
return 62;
}
public getTemplateId({ extension }: IExtensionData): string {
return extension ? ExtensionRenderer.TEMPLATE_ID : UnknownExtensionRenderer.TEMPLATE_ID;
}
}
export class ExtensionRenderer implements IListRenderer<ITreeNode<IExtensionData>, IExtensionTemplateData> {
static readonly TEMPLATE_ID = 'extension-template';
public getTemplateId(tree: ITree, { extension }: IExtensionData): string {
return extension ? Renderer.EXTENSION_TEMPLATE_ID : Renderer.UNKNOWN_EXTENSION_TEMPLATE_ID;
constructor(@IInstantiationService private readonly instantiationService: IInstantiationService) {
}
public renderTemplate(tree: ITree, templateId: string, container: HTMLElement): any {
if (Renderer.EXTENSION_TEMPLATE_ID === templateId) {
return this.renderExtensionTemplate(tree, container);
}
return this.renderUnknownExtensionTemplate(tree, container);
public get templateId(): string {
return ExtensionRenderer.TEMPLATE_ID;
}
private renderExtensionTemplate(tree: ITree, container: HTMLElement): IExtensionTemplateData {
public renderTemplate(container: HTMLElement): IExtensionTemplateData {
dom.addClass(container, 'extension');
const icon = dom.append(container, dom.$<HTMLImageElement>('img.icon'));
......@@ -91,8 +83,6 @@ export class Renderer implements IRenderer {
const name = dom.append(header, dom.$('span.name'));
const openExtensionAction = this.instantiationService.createInstance(OpenExtensionAction);
const extensionDisposables = [dom.addDisposableListener(name, 'click', (e: MouseEvent) => {
tree.setFocus(openExtensionAction.extensionData);
tree.setSelection([openExtensionAction.extensionData]);
openExtensionAction.run(e.ctrlKey || e.metaKey);
e.stopPropagation();
e.preventDefault();
......@@ -113,25 +103,8 @@ export class Renderer implements IRenderer {
};
}
private renderUnknownExtensionTemplate(tree: ITree, container: HTMLElement): IUnknownExtensionTemplateData {
const messageContainer = dom.append(container, dom.$('div.unknown-extension'));
dom.append(messageContainer, dom.$('span.error-marker')).textContent = localize('error', "Error");
dom.append(messageContainer, dom.$('span.message')).textContent = localize('Unknown Extension', "Unknown Extension:");
const identifier = dom.append(messageContainer, dom.$('span.message'));
return { identifier };
}
public renderElement(tree: ITree, element: IExtensionData, templateId: string, templateData: any): void {
if (templateId === Renderer.EXTENSION_TEMPLATE_ID) {
this.renderExtension(tree, element, templateData);
return;
}
this.renderUnknownExtension(tree, element, templateData);
}
private renderExtension(tree: ITree, extensionData: IExtensionData, data: IExtensionTemplateData): void {
const extension = extensionData.extension;
public renderElement(node: ITreeNode<IExtensionData>, index: number, data: IExtensionTemplateData): void {
const extension = node.element.extension;
const onError = Event.once(domEvent(data.icon, 'error'));
onError(() => data.icon.src = extension.iconUrlFallback, null, data.extensionDisposables);
data.icon.src = extension.iconUrl;
......@@ -146,54 +119,36 @@ export class Renderer implements IRenderer {
data.name.textContent = extension.displayName;
data.identifier.textContent = extension.identifier.id;
data.author.textContent = extension.publisherDisplayName;
data.extensionData = extensionData;
}
private renderUnknownExtension(tree: ITree, { extension }: IExtensionData, data: IUnknownExtensionTemplateData): void {
data.identifier.textContent = extension.identifier.id;
data.extensionData = node.element;
}
public disposeTemplate(tree: ITree, templateId: string, templateData: any): void {
if (templateId === Renderer.EXTENSION_TEMPLATE_ID) {
templateData.extensionDisposables = dispose((<IExtensionTemplateData>templateData).extensionDisposables);
}
public disposeTemplate(templateData: IExtensionTemplateData): void {
templateData.extensionDisposables = dispose((<IExtensionTemplateData>templateData).extensionDisposables);
}
}
export class Controller extends WorkbenchTreeController {
export class UnknownExtensionRenderer implements IListRenderer<ITreeNode<IExtensionData>, IUnknownExtensionTemplateData> {
constructor(
@IExtensionsWorkbenchService private readonly extensionsWorkdbenchService: IExtensionsWorkbenchService,
@IConfigurationService configurationService: IConfigurationService
) {
super({}, configurationService);
static readonly TEMPLATE_ID = 'unknown-extension-template';
// TODO@Sandeep this should be a command
this.downKeyBindingDispatcher.set(KeyMod.CtrlCmd | KeyCode.Enter, (tree: ITree, event: any) => this.openExtension(tree, true));
public get templateId(): string {
return UnknownExtensionRenderer.TEMPLATE_ID;
}
protected onLeftClick(tree: ITree, element: IExtensionData, event: IMouseEvent): boolean {
let currentFocused = tree.getFocus();
if (super.onLeftClick(tree, element, event)) {
if (element.parent === null) {
if (currentFocused) {
tree.setFocus(currentFocused);
} else {
tree.focusFirst();
}
return true;
}
}
return false;
public renderTemplate(container: HTMLElement): IUnknownExtensionTemplateData {
const messageContainer = dom.append(container, dom.$('div.unknown-extension'));
dom.append(messageContainer, dom.$('span.error-marker')).textContent = localize('error', "Error");
dom.append(messageContainer, dom.$('span.message')).textContent = localize('Unknown Extension', "Unknown Extension:");
const identifier = dom.append(messageContainer, dom.$('span.message'));
return { identifier };
}
public openExtension(tree: ITree, sideByside: boolean): boolean {
const element: IExtensionData = tree.getFocus();
if (element.extension) {
this.extensionsWorkdbenchService.open(element.extension, sideByside);
return true;
}
return false;
public renderElement(node: ITreeNode<IExtensionData>, index: number, data: IUnknownExtensionTemplateData): void {
data.identifier.textContent = node.element.extension.identifier.id;
}
public disposeTemplate(data: IUnknownExtensionTemplateData): void {
}
}
......@@ -218,7 +173,8 @@ class OpenExtensionAction extends Action {
}
}
export class ExtensionsTree extends WorkbenchTree {
//TODO: Ctrl Enter, Indentation
export class ExtensionsTree extends WorkbenchAsyncDataTree<IExtensionData, any> {
constructor(
input: IExtensionData,
......@@ -227,29 +183,38 @@ export class ExtensionsTree extends WorkbenchTree {
@IListService listService: IListService,
@IThemeService themeService: IThemeService,
@IInstantiationService instantiationService: IInstantiationService,
@IConfigurationService configurationService: IConfigurationService
@IConfigurationService configurationService: IConfigurationService,
@IKeybindingService keybindingService: IKeybindingService,
@IAccessibilityService accessibilityService: IAccessibilityService,
@IExtensionsWorkbenchService extensionsWorkdbenchService: IExtensionsWorkbenchService
) {
const renderer = instantiationService.createInstance(Renderer);
const controller = instantiationService.createInstance(Controller);
const delegate = new VirualDelegate();
const dataSource = new AsyncDataSource();
const renderers = [instantiationService.createInstance(ExtensionRenderer), instantiationService.createInstance(UnknownExtensionRenderer)];
const identityProvider = {
getId({ extension, parent }: IExtensionData): string {
return parent ? this.getId(parent) + '/' + extension.identifier.id : extension.identifier.id;
}
};
super(
container,
delegate,
renderers,
dataSource,
{
dataSource: new DataSource(),
renderer,
controller
}, {
indentPixels: 40,
twistiePixels: 20
indent: 40,
identityProvider,
multipleSelectionSupport: false
},
contextKeyService, listService, themeService, instantiationService, configurationService
contextKeyService, listService, themeService, configurationService, keybindingService, accessibilityService
);
this.setInput(input);
this.disposables.push(this.onDidChangeSelection(event => {
if (event && event.payload && event.payload.origin === 'keyboard') {
controller.openExtension(this, false);
if (event.browserEvent && event.browserEvent instanceof KeyboardEvent) {
extensionsWorkdbenchService.open(event.elements[0], false);
}
}));
}
......
......@@ -33,7 +33,6 @@ import { WebviewElement } from 'vs/workbench/contrib/webview/electron-browser/we
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { Tree } from 'vs/base/parts/tree/browser/treeImpl';
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { KeybindingLabel } from 'vs/base/browser/ui/keybindingLabel/keybindingLabel';
......@@ -654,7 +653,7 @@ export class ExtensionEditor extends BaseEditor {
});
}
private renderDependencies(container: HTMLElement, extensionDependencies: IExtensionDependencies): Tree {
private renderDependencies(container: HTMLElement, extensionDependencies: IExtensionDependencies): ExtensionsTree {
class ExtensionData implements IExtensionData {
private readonly extensionDependencies: IExtensionDependencies;
......@@ -703,7 +702,7 @@ export class ExtensionEditor extends BaseEditor {
return Promise.resolve({ focus() { extensionsPackTree.domFocus(); } });
}
private renderExtensionPack(container: HTMLElement, extension: IExtension): Tree {
private renderExtensionPack(container: HTMLElement, extension: IExtension): ExtensionsTree {
const extensionsWorkbenchService = this.extensionsWorkbenchService;
class ExtensionData implements IExtensionData {
......
......@@ -300,11 +300,11 @@
border-color: rgb(238, 238, 238);
}
.extension-editor .subcontent .monaco-tree-row .content .unknown-extension {
.extension-editor .subcontent .monaco-list-row .content .unknown-extension {
line-height: 62px;
}
.extension-editor .subcontent .monaco-tree-row .content .unknown-extension > .error-marker {
.extension-editor .subcontent .monaco-list-row .content .unknown-extension > .error-marker {
background-color: #BE1100;
padding: 2px 4px;
font-weight: bold;
......@@ -312,46 +312,46 @@
color: #CCC;
}
.extension-editor .subcontent .monaco-tree-row .unknown-extension > .message {
.extension-editor .subcontent .monaco-list-row .unknown-extension > .message {
padding-left: 10px;
font-weight: bold;
font-size: 14px;
}
.extension-editor .subcontent .monaco-tree-row .extension {
.extension-editor .subcontent .monaco-list-row .extension {
display: flex;
align-items: center;
}
.extension-editor .subcontent .monaco-tree-row .extension > .details {
.extension-editor .subcontent .monaco-list-row .extension > .details {
flex: 1;
overflow: hidden;
padding-left: 10px;
}
.extension-editor .subcontent .monaco-tree-row .extension > .details > .header {
.extension-editor .subcontent .monaco-list-row .extension > .details > .header {
display: flex;
align-items: center;
height: 19px;
line-height: 19px;
overflow: hidden;
}
.extension-editor .subcontent .monaco-tree-row .extension > .icon {
.extension-editor .subcontent .monaco-list-row .extension > .icon {
height: 40px;
width: 40px;
object-fit: contain;
}
.extension-editor .subcontent .monaco-tree-row .extension > .details > .header > .name {
.extension-editor .subcontent .monaco-list-row .extension > .details > .header > .name {
font-weight: bold;
font-size: 16px;
}
.extension-editor .subcontent .monaco-tree-row .extension > .details > .header > .name:hover {
.extension-editor .subcontent .monaco-list-row .extension > .details > .header > .name:hover {
text-decoration: underline;
}
.extension-editor .subcontent .monaco-tree-row .extension > .details > .header > .identifier {
.extension-editor .subcontent .monaco-list-row .extension > .details > .header > .identifier {
font-size: 90%;
opacity: 0.6;
margin-left: 10px;
......@@ -360,14 +360,14 @@
border-radius: 4px;
}
.extension-editor .subcontent .monaco-tree-row .extension > .details > .footer {
.extension-editor .subcontent .monaco-list-row .extension > .details > .footer {
display: flex;
height: 19px;
line-height: 19px;
overflow: hidden;
padding-top: 5px;
}
.extension-editor .subcontent .monaco-tree-row .extension > .details > .footer > .author {
.extension-editor .subcontent .monaco-list-row .extension > .details > .footer > .author {
font-size: 90%;
font-weight: 600;
opacity: 0.6;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册