Skip to content

Commit

Permalink
更新树形视图管理
Browse files Browse the repository at this point in the history
  • Loading branch information
sumneko committed Jun 3, 2024
1 parent 89d3cf5 commit b10ee53
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 74 deletions.
1 change: 0 additions & 1 deletion src/console/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { randomInt } from '../utility';
import * as tools from '../tools';
import { ConsoleServer } from './server';
import { registerMethod } from './client';
import * as vscode from 'vscode';

function setPort(port: number) {
if (!env.scriptUri) {
Expand Down
129 changes: 56 additions & 73 deletions src/console/treeView.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as vscode from 'vscode';
import { Client, registerMethod } from './client';
import { Client } from './client';

class TreeItem extends vscode.TreeItem {
childs?: number[];
Expand All @@ -11,23 +11,28 @@ class TreeItem extends vscode.TreeItem {
}

class TreeDataProvider implements vscode.TreeDataProvider<number> {
constructor(private treeView: TreeView, private root: number) {
constructor(private manager: TreeViewManager) {
}

private onDidChange = new vscode.EventEmitter<number | undefined>();
readonly onDidChange = new vscode.EventEmitter<number | undefined>();
onDidChangeTreeData = this.onDidChange.event;

itemMap = new Map<number, TreeItem>();

async getTreeItem(id: number): Promise<TreeItem> {
let data = await this.treeView.manager.requestGetTreeNode(id);
let item = this.getItem(id) ?? this.createItem(id, data);
return item;
let data = await this.manager.requestGetTreeNode(id);
if (this.getItem(id)) {
return this.getItem(id)!;
}
if (!data) {
return new TreeItem(id, 'Loading...');
}
return this.createItem(id, data);
}

async getChildren(id: number | undefined): Promise<number[]> {
if (id === undefined) {
return [this.root];
return this.manager.treeViews.map(view => view.root);
}
let item = this.itemMap.get(id);
if (!item) {
Expand All @@ -36,20 +41,22 @@ class TreeDataProvider implements vscode.TreeDataProvider<number> {
if (item.childs) {
return item.childs;
}
let childs = await this.treeView.manager.requestGetChildTreeNodes(id);
let childs = await this.manager.requestGetChildTreeNodes(id);
item.childs = childs;
if (!childs) {
return [];
}
return childs;
}

private getItem(id: number) {
getItem(id: number) {
return this.itemMap.get(id);
}

private createItem(id: number, data: getTreeNodeResponse) {
createItem(id: number, data: getTreeNodeResponse) {
this.removeItem(id);
let item = new TreeItem(id, data.name);
this.itemMap.set(id, item);
this.treeView.addOwnedID(id);
if (typeof data.desc === 'string') {
item.description = data.desc;
}
Expand All @@ -60,50 +67,63 @@ class TreeDataProvider implements vscode.TreeDataProvider<number> {
item.iconPath = new vscode.ThemeIcon(data.icon);
}
if (data.hasChilds) {
if (id === this.root) {
if (this.manager.treeViews.find(view => view.root === id)) {
item.collapsibleState = vscode.TreeItemCollapsibleState.Expanded;
} else {
item.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
}
}
return item;
}
private removeItem(id: number) {

removeItem(id: number) {
let item = this.itemMap.get(id);
if (!item) {
return;
}
this.itemMap.delete(id);
this.treeView.removeOwnedID(id);
if (item.childs) {
for (const child of item.childs) {
this.removeItem(child);
}
}
}

refresh(id: number) {
this.removeItem(id);
refresh(id: number | undefined) {
if (id) {
this.removeItem(id);
}
this.onDidChange.fire(id);
}
}

export class TreeView extends vscode.Disposable {
private view: vscode.TreeView<number>;
readonly ownedIDs = new Set<number>();
private treeDataProvider: TreeDataProvider;
export class TreeView {

constructor(
readonly manager: TreeViewManager,
readonly id: number,
readonly name: string,
private root: number,
readonly root: number,
) {
vscode.commands.executeCommand('y3-helper.client.focus');
}
}

interface getTreeNodeResponse {
name: string;
desc?: string;
tip?: string;
icon?: string;
hasChilds?: boolean;
}

export class TreeViewManager extends vscode.Disposable {
constructor(private client: Client) {
super(() => {
this.view.dispose();
});

this.treeDataProvider = new TreeDataProvider(this, root);
this.treeDataProvider = new TreeDataProvider(this);

this.view = vscode.window.createTreeView('y3-helper.client', {
treeDataProvider: this.treeDataProvider,
Expand All @@ -112,88 +132,51 @@ export class TreeView extends vscode.Disposable {
this.view.onDidExpandElement(e => {
let item = this.treeDataProvider.itemMap.get(e.element);
if (item && item.childs) {
this.manager.notifyChangeTreeNodeVisible(item.childs, true);
this.notifyChangeTreeNodeVisible(item.childs, true);
}
});
this.view.onDidCollapseElement(e => {
let item = this.treeDataProvider.itemMap.get(e.element);
if (item && item.childs) {
this.manager.notifyChangeTreeNodeVisible(item.childs, false);
this.notifyChangeTreeNodeVisible(item.childs, false);
}
});
vscode.commands.executeCommand('y3-helper.client.focus');
}

refresh(id: number) {
this.treeDataProvider.refresh(id);
}

addOwnedID(id: number) {
this.ownedIDs.add(id);
}

removeOwnedID(id: number) {
this.ownedIDs.delete(id);
}
}

interface getTreeNodeResponse {
name: string;
desc?: string;
tip?: string;
icon?: string;
hasChilds?: boolean;
}

export class TreeViewManager extends vscode.Disposable {
constructor(private client: Client) {
super(() => {
this.treeViews.forEach(view => view.dispose());
});
}

private treeViews = new Map<number, TreeView>();
private view: vscode.TreeView<number>;
private treeDataProvider: TreeDataProvider;

findTreeViewByNodeID(id: number): TreeView | undefined {
for (const view of this.treeViews.values()) {
if (view.ownedIDs.has(id)) {
return view;
}
}
return undefined;
}
readonly treeViews = new Array<TreeView>();

// 从客户端中获取节点信息
async requestGetTreeNode(id: number): Promise<getTreeNodeResponse> {
async requestGetTreeNode(id: number): Promise<getTreeNodeResponse|undefined> {
return await this.client.request('getTreeNode', { id });
}

// 从客户端中获取子节点
async requestGetChildTreeNodes(id: number): Promise<number[]> {
async requestGetChildTreeNodes(id: number): Promise<number[]|undefined> {
return await this.client.request('getChildTreeNodes', { id });
}

async createTreeView(id: number, name: string, root: number) {
let treeView = new TreeView(this, id, name, root);
this.treeViews.set(id, treeView);
this.treeViews.push(treeView);
this.treeDataProvider.refresh(undefined);
return treeView;
}

async removeTreeView(id: number) {
let treeView = this.treeViews.get(id);
let treeView = this.treeViews.find(view => view.id === id);
if (!treeView) {
return;
}
this.treeViews.delete(id);
treeView.dispose();
this.treeViews.splice(this.treeViews.indexOf(treeView), 1);
this.treeDataProvider.removeItem(treeView.root);
this.treeDataProvider.refresh(undefined);
}

refreshTreeNode(id: number) {
let treeView = this.findTreeViewByNodeID(id);
if (!treeView) {
return;
}
treeView.refresh(id);
this.treeDataProvider.refresh(id);
}

notifyChangeTreeNodeVisible(ids: number[], visible: boolean) {
Expand Down

0 comments on commit b10ee53

Please sign in to comment.