Keep machine dialogs open when file picker is cancelled

This commit is contained in:
2026-09-22 05:24:55 +08:00
parent d4d0088daf
commit b15af28034
13 changed files with 37 additions and 12 deletions

View File

@@ -12,6 +12,8 @@ export function TrtGeometryPanel({ bundle, disabled, busy, onApply, onReload }:
const [message, setMessage] = useState("");
const [pending, setPending] = useState(false);
const file = useRef<HTMLInputElement>(null);
const filePickerOpen = useRef(false);
const openFilePicker = () => { if (locked || !file.current) return; filePickerOpen.current = true; file.current.click(); const clear = () => { window.removeEventListener("focus", clear); setTimeout(() => { filePickerOpen.current = false; }, 0); }; window.addEventListener("focus", clear, { once: true }); };
const geometry = useMemo(() => bundle ? readTrtGeometry(bundle) : null, [bundle]);
useEffect(() => {
setValues(Object.fromEntries(TRT_GEOMETRY_KEYS.map((key: string) => [key, String(geometry?.offsets[key] ?? 0)])));
@@ -50,13 +52,13 @@ export function TrtGeometryPanel({ bundle, disabled, busy, onApply, onReload }:
const tool = (id: string, label: string, asset: string, action: () => void, off = locked) => <button type="button" data-axis-control={`geometry-${id}`} aria-label={label} title={label} disabled={off} onClick={action}><img src={axisIcon(asset)} alt="" /></button>;
return <section className="trt-geometry" aria-label="机床几何参数" aria-busy={pending || busy} data-dirty={dirty}>
<div className="trt-geometry-toolbar"><button type="button" data-axis-control="geometry-settings" aria-haspopup="dialog" onClick={() => setOpen(true)}>机床参数</button></div>
<DraggableDialog open={open} title="机床几何参数" className="geometry-dialog" onClose={() => setOpen(false)}>
<DraggableDialog open={open} title="机床几何参数" className="geometry-dialog" cancelGuard={() => filePickerOpen.current} onClose={() => setOpen(false)}>
<header><strong>{bundle?.entrypoint.split("/").at(-1) ?? "INI"}</strong><span>mm</span><output>{dirty ? "待应用" : "已生效"}</output></header>
<div className="trt-geometry-fields">{["旋转中心", "轴间偏置"].map((title, index) => <fieldset key={title}><legend>{title}</legend>{TRT_GEOMETRY_KEYS.slice(index * 3, index * 3 + 3).map((key: string) => <label key={key} title={key === geometry?.unsupported ? "此机型原生运动学不使用该偏置" : key.replaceAll("_", "-")}><span>{key.replaceAll("_", "-")}</span><input aria-label={key.replaceAll("_", "-")} type="number" step="any" disabled={locked || key === geometry?.unsupported} value={values[key] ?? "0"} onChange={(e) => setValues({ ...values, [key]: e.target.value })} /></label>)}</fieldset>)}</div>
<footer>
<button type="button" data-axis-control="geometry-apply" disabled={locked || !dirty} onClick={() => void run(() => onApply(edited()), "参数已应用,待重新回零")}><img src={axisIcon("tool_verify.gif")} alt="" />应用参数</button>
{tool("reload", "重新读取 INI", "tool_reload.gif", () => void run(onReload, "已重新读取 INI"))}
{tool("import", "导入 INI 参数", "tool_open.gif", () => file.current?.click())}
{tool("import", "导入 INI 参数", "tool_open.gif", openFilePicker)}
<button type="button" data-axis-control="geometry-save" disabled={locked} onClick={() => void run(exportIni, "INI 已保存或导出")}>保存 INI</button>
<output role="status">{message || (disabled ? "关机且程序空闲后可修改" : "")}</output>
</footer>