/* ============================================================================= * input_prefs.ts * 마우스 · 단축키 설정 읽기 층(PLAN 332) — ☰ [설정] 창이 [저장] 때 계정 pref 로 씀. * * - 값 = `aislo:pref:input-prefs`(등록표 `input-prefs`) JSON 한 벌 · 부를 때마다 읽음(새로고침 없이 바로 따름) * - 없음 · 깨짐 · Node(저장소 없음) = 기본값(= 지금 동작) · 의존 없음 · 불러올 때 window 안 만짐(CAD 도 import) * - 휠 확대 방향 하나로 모든 화면 일체 — 당김 = 휠을 몸 쪽으로(deltaY > 0) 굴리면 확대 * - 핀치(트랙패드 · 손가락)는 설정과 상관없이 늘 벌리면 확대(deltaY < 0) * ========================================================================== */ export type WheelZoom = "pull" | "push"; export interface InputPrefs { /** 휠 확대 방향 — pull = 당기면 확대 · push = 밀면 확대 */ wheelZoom: WheelZoom; /** CAD 내 별칭 `{명령: [별칭]}`(대문자 · acad.pgp 식 — 명령 이름 > 내 별칭 > 기본 별칭) */ cadAliases: Record; } /** `stateKey("input-prefs")` 와 같은 키(시험이 맞춰 봄) — 등록표를 불러오면 window 가 딸려 와서 글자로 둠 */ export const INPUT_PREFS_KEY = "aislo:pref:input-prefs"; export const DEFAULT_INPUT_PREFS: InputPrefs = { wheelZoom: "pull", cadAliases: {} }; const cleanAliases = (raw: unknown): Record => { const out: Record = {}; if (!raw || typeof raw !== "object") return out; for (const [id, list] of Object.entries(raw as Record)) { if (!Array.isArray(list)) continue; const aliases = list .filter((a): a is string => typeof a === "string") .map((a) => a.toUpperCase()); if (aliases.length) out[id.toUpperCase()] = aliases; } return out; }; /** 지금 설정 — 부를 때마다 저장소에서 읽음 */ export function inputPrefs(): InputPrefs { try { const raw = globalThis.localStorage?.getItem(INPUT_PREFS_KEY); if (!raw) return { ...DEFAULT_INPUT_PREFS, cadAliases: {} }; const value = JSON.parse(raw) as Partial | null; return { wheelZoom: value?.wheelZoom === "push" ? "push" : "pull", cadAliases: cleanAliases(value?.cadAliases), }; } catch { return { ...DEFAULT_INPUT_PREFS, cadAliases: {} }; } } /** 휠 한 번이 확대인가 — 설정 방향을 따름 */ export const wheelIn = (deltaY: number): boolean => inputPrefs().wheelZoom === "push" ? deltaY < 0 : deltaY > 0; /** 트랙패드 핀치 — 브라우저가 Ctrl+휠 · 잘게 쪼갠 값으로 냄 * ponytail: |deltaY| < 50 로 마우스 Ctrl+휠(한 칸 ≥ 약 100)과 가름 · 잘게 도는 마우스는 핀치로 봄 */ export const isTrackpadPinch = (e: Pick): boolean => e.ctrlKey && Math.abs(e.deltaY) < 50; /** 휠 사건이 확대인가 — 핀치(`pinch` 손가락 벌림 · 트랙패드)는 늘 벌리면 확대 · 나머지는 설정 방향 */ export const wheelEventIn = (e: Pick, pinch = false): boolean => pinch || isTrackpadPinch(e) ? e.deltaY < 0 : wheelIn(e.deltaY);