- 고르기: 누름 = 더함 · Shift = 뺌 · Ctrl = 넣고 빼기 · 상자 = 앞 고름 ∪ 상자 · Shift 상자 = 뺌(H4 · H5) · 명령 안 고르기 단계도 누를 때 첫 점 · 스침 강조(ic/selecting.ts) - 그립: 쉴 때만 집음(N7) · 누르고 떼면 대기 → 다음 누름에 놓음 · 끌어 놓기(H3) · 거리 숫자(N8) · 확정 · 읽기 전용 도면은 그립 · Delete 막음(H2) - 직교: F8 = 기준점에서 가로 · 세로 강제 · Shift 누른 동안 뒤집음 · 객체 스냅 점 · 좌표 · 각도 잠금은 안 덮음 · 클릭 사건 snapped 채움(ic/ortho.ts · H8) · 가이드는 F3 와 뗌 · 가이드 잡는 거리 = 화면 픽셀(H9) - 휠: 기본 밂(앞으로 굴리면 확대 · 오토캐드 · 모든 화면 · ☰ 설정 뒤집기 그대로) · 가운데 단추 두 번 = 범위 줌 · ZOOM · ⛶ 앞 화면 기억(ic/zoom-prompt.ts) - 시험: mouse-acad 새로 · 휠 방향 시험 손질(input-wheel · input-prefs-cad · input_prefs · app_settings · 164 · 220_1 · 221_1 · 244_8 기대값 뒤집음 · 266 pull 박음) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Se7ytqbohmBQnfYpwYFnYf
65 lines
3.2 KiB
TypeScript
65 lines
3.2 KiB
TypeScript
/* =============================================================================
|
|
* 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<string, string[]>;
|
|
}
|
|
|
|
/** `stateKey("input-prefs")` 와 같은 키(시험이 맞춰 봄) — 등록표를 불러오면 window 가 딸려 와서 글자로 둠 */
|
|
export const INPUT_PREFS_KEY = "aislo:pref:input-prefs";
|
|
|
|
export const DEFAULT_INPUT_PREFS: InputPrefs = { wheelZoom: "push", cadAliases: {} };
|
|
|
|
const cleanAliases = (raw: unknown): Record<string, string[]> => {
|
|
const out: Record<string, string[]> = {};
|
|
if (!raw || typeof raw !== "object") return out;
|
|
for (const [id, list] of Object.entries(raw as Record<string, unknown>)) {
|
|
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<InputPrefs> | null;
|
|
return {
|
|
wheelZoom: value?.wheelZoom === "pull" ? "pull" : "push",
|
|
cadAliases: cleanAliases(value?.cadAliases),
|
|
};
|
|
} catch {
|
|
return { ...DEFAULT_INPUT_PREFS, cadAliases: {} };
|
|
}
|
|
}
|
|
|
|
/** 휠 한 번이 확대인가 — 설정 방향을 따름 */
|
|
export const wheelIn = (deltaY: number): boolean =>
|
|
inputPrefs().wheelZoom === "pull" ? deltaY > 0 : deltaY < 0;
|
|
|
|
/** 트랙패드 핀치 — 브라우저가 Ctrl+휠 · 잘게 쪼갠 값으로 냄
|
|
* ponytail: |deltaY| < 50 로 마우스 Ctrl+휠(한 칸 ≥ 약 100)과 가름 · 잘게 도는 마우스는 핀치로 봄 */
|
|
export const isTrackpadPinch = (e: Pick<WheelEvent, "ctrlKey" | "deltaY">): boolean =>
|
|
e.ctrlKey && Math.abs(e.deltaY) < 50;
|
|
|
|
/** 휠 사건이 확대인가 — 핀치(`pinch` 손가락 벌림 · 트랙패드)는 늘 벌리면 확대 · 나머지는 설정 방향 */
|
|
export const wheelEventIn = (e: Pick<WheelEvent, "ctrlKey" | "deltaY">, pinch = false): boolean =>
|
|
pinch || isTrackpadPinch(e) ? e.deltaY < 0 : wheelIn(e.deltaY);
|