import * as vscode from "vscode"; import * as path from "path"; import * as fs from "fs"; /** * VCD 波形查看器面板 */ export class VCDViewerPanel { public static currentPanel: VCDViewerPanel | undefined; private readonly _panel: vscode.WebviewPanel; private readonly _extensionUri: vscode.Uri; private _disposables: vscode.Disposable[] = []; private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri) { this._panel = panel; this._extensionUri = extensionUri; // 设置初始 HTML 内容 this._panel.webview.html = this._getLoadingHtml(); // 监听面板关闭事件 this._panel.onDidDispose(() => this.dispose(), null, this._disposables); // 监听来自 webview 的消息 this._panel.webview.onDidReceiveMessage( (message) => { switch (message.command) { case "loadVCD": if (message.filePath) { this.loadVCDFile(message.filePath); } break; } }, null, this._disposables ); } /** * 创建或显示 VCD 查看器面板 */ public static createOrShow(extensionUri: vscode.Uri, vcdFilePath?: string) { const column = vscode.ViewColumn.One; // 如果已经有面板打开,则显示它 if (VCDViewerPanel.currentPanel) { VCDViewerPanel.currentPanel._panel.reveal(column); if (vcdFilePath) { VCDViewerPanel.currentPanel.loadVCDFile(vcdFilePath); } return; } // 创建新面板 const panel = vscode.window.createWebviewPanel( "vcdViewer", "VCD 波形查看器", column, { enableScripts: true, retainContextWhenHidden: true, localResourceRoots: [extensionUri], } ); VCDViewerPanel.currentPanel = new VCDViewerPanel(panel, extensionUri); // 如果提供了 VCD 文件路径,加载它 if (vcdFilePath) { VCDViewerPanel.currentPanel.loadVCDFile(vcdFilePath); } } /** * 加载 VCD 文件 */ public loadVCDFile(vcdFilePath: string) { try { // 检查文件是否存在 if (!fs.existsSync(vcdFilePath)) { vscode.window.showErrorMessage(`VCD 文件不存在: ${vcdFilePath}`); return; } // 更新面板标题 const fileName = path.basename(vcdFilePath); this._panel.title = `VCD 波形查看器 - ${fileName}`; // 设置 HTML 内容 this._panel.webview.html = this._getWebviewContent(vcdFilePath); } catch (error) { vscode.window.showErrorMessage( `加载 VCD 文件失败: ${error instanceof Error ? error.message : "未知错误"}` ); } } /** * 清理资源 */ public dispose() { VCDViewerPanel.currentPanel = undefined; this._panel.dispose(); while (this._disposables.length) { const disposable = this._disposables.pop(); if (disposable) { disposable.dispose(); } } } /** * 获取加载中的 HTML */ private _getLoadingHtml(): string { return ` VCD 波形查看器

正在加载 VCD 波形查看器...

`; } /** * 获取 Webview 的 HTML 内容 */ private _getWebviewContent(vcdFilePath: string): string { // 获取资源 URI const vcdromJsUri = this._panel.webview.asWebviewUri( vscode.Uri.joinPath(this._extensionUri, "media", "vcdrom", "vcdrom.js") ); const vcdWasmUri = this._panel.webview.asWebviewUri( vscode.Uri.joinPath(this._extensionUri, "media", "vcdrom", "vcd.wasm") ); const fontRegularUri = this._panel.webview.asWebviewUri( vscode.Uri.joinPath(this._extensionUri, "media", "vcdrom", "IosevkaDrom-Regular.woff2") ); const fontObliqueUri = this._panel.webview.asWebviewUri( vscode.Uri.joinPath(this._extensionUri, "media", "vcdrom", "IosevkaDrom-Oblique.woff2") ); const fontItalicUri = this._panel.webview.asWebviewUri( vscode.Uri.joinPath(this._extensionUri, "media", "vcdrom", "IosevkaDrom-Italic.woff2") ); // 读取 VCD 文件内容并转换为 base64 const vcdContent = fs.readFileSync(vcdFilePath, "utf-8"); const vcdBase64 = Buffer.from(vcdContent).toString("base64"); return ` VCD 波形查看器

正在加载 VCD 波形...

`; } }