style: 优化界面样式和用户体验

- 调整工具调用显示的间距和字体大小
   - 优化低调工具调用的视觉效果
   - 改进整体界面的可读性
This commit is contained in:
Roe-xin
2026-02-26 21:44:58 +08:00
parent c3e3012a94
commit a479e81682
6 changed files with 90 additions and 51 deletions

View File

@ -6,8 +6,13 @@ import { VCDFileServer } from "../services/vcdFileServer";
/**
* VCD 波形查看器自定义编辑器提供者
*/
export class VCDViewerEditorProvider implements vscode.CustomReadonlyEditorProvider {
public static register(context: vscode.ExtensionContext, vcdFileServer: VCDFileServer): vscode.Disposable {
export class VCDViewerEditorProvider
implements vscode.CustomReadonlyEditorProvider
{
public static register(
context: vscode.ExtensionContext,
vcdFileServer: VCDFileServer,
): vscode.Disposable {
const provider = new VCDViewerEditorProvider(context, vcdFileServer);
const providerRegistration = vscode.window.registerCustomEditorProvider(
"ic-coder.vcdViewer",
@ -16,20 +21,20 @@ export class VCDViewerEditorProvider implements vscode.CustomReadonlyEditorProvi
webviewOptions: {
retainContextWhenHidden: true,
},
}
},
);
return providerRegistration;
}
constructor(
private readonly context: vscode.ExtensionContext,
private readonly vcdFileServer: VCDFileServer
private readonly vcdFileServer: VCDFileServer,
) {}
async openCustomDocument(
uri: vscode.Uri,
openContext: vscode.CustomDocumentOpenContext,
token: vscode.CancellationToken
token: vscode.CancellationToken,
): Promise<vscode.CustomDocument> {
return {
uri,
@ -40,7 +45,7 @@ export class VCDViewerEditorProvider implements vscode.CustomReadonlyEditorProvi
async resolveCustomEditor(
document: vscode.CustomDocument,
webviewPanel: vscode.WebviewPanel,
token: vscode.CancellationToken
token: vscode.CancellationToken,
): Promise<void> {
webviewPanel.webview.options = {
enableScripts: true,
@ -52,7 +57,7 @@ export class VCDViewerEditorProvider implements vscode.CustomReadonlyEditorProvi
webviewPanel,
this.context.extensionUri,
document.uri.fsPath,
this.vcdFileServer
this.vcdFileServer,
);
}
}
@ -68,7 +73,11 @@ export class VCDViewerPanel {
private _currentVcdPath: string | undefined;
private _vcdFileServer: VCDFileServer | undefined;
private constructor(panel: vscode.WebviewPanel, extensionUri: vscode.Uri, vcdFileServer?: VCDFileServer) {
private constructor(
panel: vscode.WebviewPanel,
extensionUri: vscode.Uri,
vcdFileServer?: VCDFileServer,
) {
this._panel = panel;
this._extensionUri = extensionUri;
this._vcdFileServer = vcdFileServer;
@ -91,7 +100,10 @@ export class VCDViewerPanel {
break;
case "loaded":
// Surfer iframe 加载完成,发送 VCD 文件
console.log("[VCDViewerPanel] Surfer 已加载,当前 VCD 路径:", this._currentVcdPath);
console.log(
"[VCDViewerPanel] Surfer 已加载,当前 VCD 路径:",
this._currentVcdPath,
);
if (this._currentVcdPath) {
this.sendVcdToSurfer(this._currentVcdPath);
}
@ -99,14 +111,18 @@ export class VCDViewerPanel {
}
},
null,
this._disposables
this._disposables,
);
}
/**
* 创建或显示 VCD 查看器面板
*/
public static createOrShow(extensionUri: vscode.Uri, vcdFilePath?: string, vcdFileServer?: VCDFileServer) {
public static createOrShow(
extensionUri: vscode.Uri,
vcdFilePath?: string,
vcdFileServer?: VCDFileServer,
) {
// 在当前活动编辑器旁边打开新列
const column = vscode.ViewColumn.Beside;
@ -128,10 +144,14 @@ export class VCDViewerPanel {
enableScripts: true,
retainContextWhenHidden: true,
localResourceRoots: [extensionUri],
}
},
);
VCDViewerPanel.currentPanel = new VCDViewerPanel(panel, extensionUri, vcdFileServer);
VCDViewerPanel.currentPanel = new VCDViewerPanel(
panel,
extensionUri,
vcdFileServer,
);
// 如果提供了 VCD 文件路径,加载它
if (vcdFilePath) {
@ -146,7 +166,7 @@ export class VCDViewerPanel {
panel: vscode.WebviewPanel,
extensionUri: vscode.Uri,
vcdFilePath: string,
vcdFileServer?: VCDFileServer
vcdFileServer?: VCDFileServer,
) {
const viewer = new VCDViewerPanel(panel, extensionUri, vcdFileServer);
viewer.loadVCDFile(vcdFilePath);
@ -172,14 +192,14 @@ export class VCDViewerPanel {
// 更新面板标题
const fileName = path.basename(vcdFilePath);
this._panel.title = `Surfer 波形查看器 - ${fileName}`;
this._panel.title = `波形查看器 - ${fileName}`;
// 设置 HTML 内容
this._panel.webview.html = this._getWebviewContent();
console.log("[VCDViewerPanel] Webview HTML 已设置");
} catch (error) {
vscode.window.showErrorMessage(
`加载 VCD 文件失败: ${error instanceof Error ? error.message : "未知错误"}`
`加载 VCD 文件失败: ${error instanceof Error ? error.message : "未知错误"}`,
);
}
}
@ -190,8 +210,8 @@ export class VCDViewerPanel {
private parseVcdRootScope(vcdFilePath: string): string[] {
try {
// 读取 VCD 文件
const buffer = fs.readFileSync(vcdFilePath, { encoding: 'utf8' });
const lines = buffer.split('\n');
const buffer = fs.readFileSync(vcdFilePath, { encoding: "utf8" });
const lines = buffer.split("\n");
const scopeNames: string[] = [];
let scopeDepth = 0;
@ -201,7 +221,7 @@ export class VCDViewerPanel {
const trimmed = line.trim();
// 遇到 $enddefinitions 就停止解析
if (trimmed.startsWith('$enddefinitions')) {
if (trimmed.startsWith("$enddefinitions")) {
break;
}
@ -212,22 +232,22 @@ export class VCDViewerPanel {
const scopeName = scopeMatch[2];
// 记录顶层 module (depth = 0)
if (scopeDepth === 0 && scopeType === 'module') {
if (scopeDepth === 0 && scopeType === "module") {
scopeStack.push(scopeName);
console.log("[VCDViewerPanel] 找到顶层作用域:", scopeName);
}
// 记录顶层下的直接子模块 (depth = 1)
else if (scopeDepth === 1 && scopeType === 'module') {
else if (scopeDepth === 1 && scopeType === "module") {
const fullPath = [...scopeStack, scopeName];
scopeNames.push(fullPath.join('.'));
console.log("[VCDViewerPanel] 找到子模块:", fullPath.join('.'));
scopeNames.push(fullPath.join("."));
console.log("[VCDViewerPanel] 找到子模块:", fullPath.join("."));
}
scopeDepth++;
}
// 遇到 $upscope 减少深度
if (trimmed.startsWith('$upscope')) {
if (trimmed.startsWith("$upscope")) {
scopeDepth--;
if (scopeDepth === 0) {
scopeStack.pop();
@ -277,7 +297,7 @@ export class VCDViewerPanel {
} catch (error) {
console.error("[VCDViewerPanel] 发送 VCD 数据失败:", error);
vscode.window.showErrorMessage(
`发送 VCD 数据失败: ${error instanceof Error ? error.message : "未知错误"}`
`发送 VCD 数据失败: ${error instanceof Error ? error.message : "未知错误"}`,
);
}
}
@ -352,13 +372,23 @@ export class VCDViewerPanel {
private _getWebviewContent(): string {
// 获取 surfer 资源 URI
const surferJsUri = this._panel.webview.asWebviewUri(
vscode.Uri.joinPath(this._extensionUri, "media", "surfer", "surfer.js")
vscode.Uri.joinPath(this._extensionUri, "media", "surfer", "surfer.js"),
);
const surferWasmUri = this._panel.webview.asWebviewUri(
vscode.Uri.joinPath(this._extensionUri, "media", "surfer", "surfer_bg.wasm")
vscode.Uri.joinPath(
this._extensionUri,
"media",
"surfer",
"surfer_bg.wasm",
),
);
const integrationJsUri = this._panel.webview.asWebviewUri(
vscode.Uri.joinPath(this._extensionUri, "media", "surfer", "integration.js")
vscode.Uri.joinPath(
this._extensionUri,
"media",
"surfer",
"integration.js",
),
);
return `<!DOCTYPE html>
@ -367,7 +397,7 @@ export class VCDViewerPanel {
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'unsafe-inline' 'unsafe-eval' ${this._panel.webview.cspSource}; worker-src blob:; connect-src ${this._panel.webview.cspSource} blob: http://127.0.0.1:*;">
<title>Surfer 波形查看器</title>
<title>波形查看器</title>
<script>
// 获取 VS Code API只能调用一次