/** * 获取波形预览组件的样式内容(纯 CSS,不包含 style 标签) */ export function getWaveformPreviewContent(): string { return ` /* 波形预览组件样式 */ .waveform-preview { margin-top: 12px; border: 1px solid var(--vscode-panel-border); border-radius: 8px; overflow: hidden; background: var(--vscode-editor-background); } .waveform-preview-header { display: flex; align-items: center; justify-content: space-between; padding: 10px 12px; background: var(--vscode-input-background); border-bottom: 1px solid var(--vscode-panel-border); } .waveform-preview-title { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 500; color: var(--vscode-foreground); } .waveform-preview-title svg { width: 16px; height: 16px; color: var(--vscode-button-background); } .waveform-expand-btn { padding: 4px 12px; background: var(--vscode-button-background); color: var(--vscode-button-foreground); border: none; border-radius: 4px; cursor: pointer; font-size: 12px; display: flex; align-items: center; gap: 4px; transition: opacity 0.2s ease; } .waveform-expand-btn:hover { opacity: 0.9; } .waveform-expand-btn svg { width: 14px; height: 14px; } .waveform-preview-content { padding: 0; min-height: 200px; max-height: 300px; overflow: hidden; position: relative; background: var(--vscode-editor-background); } .waveform-preview-canvas { width: 100%; height: 100%; min-height: 200px; } .waveform-preview-placeholder { display: flex; flex-direction: column; align-items: center; justify-content: center; color: var(--vscode-descriptionForeground); font-size: 13px; text-align: center; padding: 20px; } .waveform-preview-placeholder svg { width: 48px; height: 48px; margin-bottom: 12px; opacity: 0.5; } .waveform-info { margin-top: 8px; font-size: 12px; color: var(--vscode-descriptionForeground); } .waveform-mini-viewer { width: 100%; height: 200px; background: var(--vscode-editor-background); position: relative; overflow: hidden; } .waveform-loading { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: var(--vscode-descriptionForeground); font-size: 12px; } `; } /** * 获取波形预览组件的 JavaScript 代码 */ export function getWaveformPreviewScript(): string { return ` /** * 创建波形预览组件 */ function createWaveformPreview(vcdFilePath, fileName) { const previewDiv = document.createElement('div'); previewDiv.className = 'waveform-preview'; // 头部 const header = document.createElement('div'); header.className = 'waveform-preview-header'; const title = document.createElement('div'); title.className = 'waveform-preview-title'; title.innerHTML = \` 波形预览 - \${fileName} \`; const expandBtn = document.createElement('button'); expandBtn.className = 'waveform-expand-btn'; expandBtn.innerHTML = \` 展开查看 \`; expandBtn.onclick = () => openFullWaveform(vcdFilePath); header.appendChild(title); header.appendChild(expandBtn); // 内容区域 - 创建一个唯一ID的容器用于显示波形 const content = document.createElement('div'); content.className = 'waveform-preview-content'; const miniViewerId = 'waveform-mini-' + Date.now(); const miniViewer = document.createElement('div'); miniViewer.id = miniViewerId; miniViewer.className = 'waveform-mini-viewer'; // 添加加载提示 const loadingDiv = document.createElement('div'); loadingDiv.className = 'waveform-loading'; loadingDiv.textContent = '正在加载波形预览...'; miniViewer.appendChild(loadingDiv); content.appendChild(miniViewer); previewDiv.appendChild(header); previewDiv.appendChild(content); // 异步加载波形数据 loadMiniWaveform(miniViewerId, vcdFilePath, loadingDiv); return previewDiv; } /** * 加载迷你波形预览 */ async function loadMiniWaveform(containerId, vcdFilePath, loadingDiv) { try { // 请求 VCD 文件信息 vscode.postMessage({ command: 'getVCDInfo', vcdFilePath: vcdFilePath, containerId: containerId }); } catch (error) { console.error('加载波形预览失败:', error); loadingDiv.textContent = '波形预览加载失败'; loadingDiv.style.color = 'var(--vscode-errorForeground)'; } } /** * 渲染波形预览信息 */ function renderWaveformInfo(containerId, vcdInfo) { const container = document.getElementById(containerId); if (!container) return; // 清空容器 container.innerHTML = ''; // 绘制真实波形 const waveformSvg = document.createElement('div'); waveformSvg.innerHTML = drawRealWaveform(vcdInfo.signals || []); container.appendChild(waveformSvg); } /** * 绘制真实波形 */ function drawRealWaveform(signals) { if (!signals || signals.length === 0) { return \` 无波形数据 \`; } const svgWidth = 800; const svgHeight = Math.max(80, signals.length * 30 + 20); const signalHeight = 20; const signalSpacing = 30; const leftMargin = 80; const rightMargin = 20; const waveformWidth = svgWidth - leftMargin - rightMargin; const colors = ['var(--vscode-charts-blue)', 'var(--vscode-charts-green)', 'var(--vscode-charts-orange)']; let svgContent = \`\`; // 绘制每个信号 signals.forEach((signal, index) => { const y = 10 + index * signalSpacing; const color = colors[index % colors.length]; // 绘制信号名称 svgContent += \`\${signal.name}\`; // 如果没有值变化数据,显示提示 if (!signal.values || signal.values.length === 0) { svgContent += \`无数据\`; return; } // 计算时间范围 const times = signal.values.map(v => v.time); const minTime = Math.min(...times); const maxTime = Math.max(...times); const timeRange = maxTime - minTime || 1; // 绘制波形 let pathData = ''; let lastX = leftMargin; let lastValue = signal.values[0].value; signal.values.forEach((point, i) => { const x = leftMargin + ((point.time - minTime) / timeRange) * waveformWidth; const value = point.value; if (signal.width === 1) { // 单比特信号 - 绘制数字波形 const yHigh = y; const yLow = y + signalHeight; const currentY = (value === '1') ? yHigh : yLow; if (i === 0) { pathData = \`M \${x} \${currentY}\`; } else { // 绘制垂直跳变 const prevY = (lastValue === '1') ? yHigh : yLow; if (prevY !== currentY) { pathData += \` L \${x} \${prevY} L \${x} \${currentY}\`; } else { pathData += \` L \${x} \${currentY}\`; } } lastValue = value; lastX = x; } else { // 多比特信号 - 绘制总线波形(梯形) const yTop = y + 5; const yBottom = y + signalHeight - 5; const transitionWidth = 5; if (i === 0) { pathData = \`M \${x} \${yTop + (yBottom - yTop) / 2}\`; } else { // 绘制梯形过渡 pathData += \` L \${x - transitionWidth} \${yTop} L \${x} \${yTop + (yBottom - yTop) / 2}\`; } lastX = x; } }); // 延伸到右边界 if (signal.width === 1) { const lastY = (lastValue === '1') ? y : (y + signalHeight); pathData += \` L \${leftMargin + waveformWidth} \${lastY}\`; } else { const yMid = y + signalHeight / 2; pathData += \` L \${leftMargin + waveformWidth} \${yMid}\`; } svgContent += \`\`; }); // 绘制时间轴 const timeAxisY = svgHeight - 5; svgContent += \`\`; svgContent += \`\`; return svgContent; } /** * 打开完整波形查看器 */ function openFullWaveform(vcdFilePath) { vscode.postMessage({ command: 'openWaveformViewer', vcdFilePath: vcdFilePath }); } /** * 在消息中添加波形预览 */ function addWaveformPreviewToMessage(messageDiv, vcdFilePath, fileName) { const preview = createWaveformPreview(vcdFilePath, fileName); messageDiv.appendChild(preview); } `; }