import color from "picocolors"; import { steps } from "./config.js"; import { initKeypress, onKey } from "../keyboard.js"; // 存储结果和状态 let results = []; let completed = new Set(); let currentStep = 0; let currentOption = 0; // 初始化结果 export function initResults() { results = steps.map(s => s.type === "multiselect" ? [...s.default] : s.default); completed = new Set(); currentStep = 0; currentOption = 0; } // 渲染导航栏 function renderNav() { const nav = steps.map((step, i) => { if (completed.has(i)) { return color.green(`☑ ${step.name}`); } else if (i === currentStep) { return color.bgCyan(color.black(` ${step.name} `)); } else { return color.dim(`□ ${step.name}`); } }); return `← ${nav.join(" ")} ${color.green("✓Submit")} →`; } // 渲染选项列表 function renderOptions() { const step = steps[currentStep]; const lines = []; lines.push(color.cyan(step.message)); lines.push(""); step.options.forEach((opt, i) => { const isCurrent = i === currentOption; const isSelected = step.type === "multiselect" ? results[currentStep].includes(opt.value) : results[currentStep] === opt.value; let prefix; if (step.type === "multiselect") { prefix = isSelected ? color.green("◉ ") : "○ "; } else { prefix = isSelected ? color.green("● ") : "○ "; } const cursor = isCurrent ? color.cyan("❯ ") : " "; const label = isCurrent ? color.cyan(opt.label) : opt.label; const check = isSelected ? color.green(" ✓") : ""; lines.push(`${cursor}${prefix}${label}${check}`); if (opt.hint) { lines.push(` ${color.dim(opt.hint)}`); } }); return lines.join("\n"); } // 渲染整个界面 function render() { console.clear(); console.log(color.bgCyan(color.black(" KTX2 纹理压缩工具 "))); console.log("\n" + renderNav()); console.log(color.dim("\n← → 切换步骤 | ↑ ↓ 选择 | Space 选中 | Tab 提交 | Esc 返回\n")); console.log(renderOptions()); } // 主交互循环 export async function runInteractive() { initResults(); initKeypress(); return new Promise((resolve) => { render(); onKey((str, key) => { if (!key) return; const step = steps[currentStep]; const optCount = step.options.length; if (key.name === "left") { if (currentStep > 0) { currentStep--; currentOption = 0; } render(); } else if (key.name === "right") { if (currentStep < steps.length - 1) { currentStep++; currentOption = 0; } render(); } else if (key.name === "up") { currentOption = (currentOption - 1 + optCount) % optCount; render(); } else if (key.name === "down") { currentOption = (currentOption + 1) % optCount; render(); } else if (key.name === "space") { const opt = step.options[currentOption]; if (step.type === "multiselect") { const idx = results[currentStep].indexOf(opt.value); if (idx >= 0) { results[currentStep].splice(idx, 1); } else { results[currentStep].push(opt.value); } } else { results[currentStep] = opt.value; } completed.add(currentStep); render(); } else if (key.name === "return") { if (step.type === "select") { results[currentStep] = step.options[currentOption].value; } completed.add(currentStep); if (currentStep < steps.length - 1) { currentStep++; currentOption = 0; } render(); } else if (key.name === "tab") { resolve(results); } else if (key.name === "escape" || (key.ctrl && key.name === "c")) { resolve(null); } }); }); } // 显示配置摘要 export function showSummary(config) { console.clear(); console.log(color.bgCyan(color.black(" KTX2 纹理压缩工具 "))); console.log("\n" + color.green("配置完成!当前设置:")); console.log(` 文件格式: ${config.exts.join(", ")}`); console.log(` 压缩程度: ${config.quality}`); console.log(` 编码格式: ${config.encoding}`); console.log(` Mipmap: ${config.mipmap}`); console.log(` 输出选项: ${config.outputOpts.join(", ")}\n`); }