feat(설정 단축키): CAD 리본 묶음 · 찾기 · 다른 곳 = 실제 동작 등록부 표 · 키 바꾸기 · 겹침 막음 (PLAN 588-1~3 · 요구 445 C2 · C3)

- 새 key_registry.ts — 화면마다 받는 키 · 마우스 동작 한 벌 · keyIs(evt, id) · 바꾼 키만 input-prefs.keys
- ☰ [설정] CAD 탭 = 찾기 칸 + 「키 · 마우스」 + 리본 탭 › 패널 접이 묶음(기타 여섯) · 날 input → 부품 입력
- 다른 곳 탭 = 손글 안내 지우고 등록부 표(B05 방향키 · D03 Delete 등 빠진 것 포함) · 찾기
- 키 기록 칸 · 줄마다 [기본값] · [모두 기본값] · 같은 화면 · 모든 화면 겹침 · 브라우저 몫 · CAD 글자 단독은 저장 막음
- 배선: B05 되돌림 · 자유지정 Enter · Backspace · D03 되돌림 · 그리기 · 지움(한글 자판도 자판 자리) · CAD F3 · F7 · F8 · F10 · Ctrl 명령 · Delete
- 낡은 글 대조 시험 셋(215-1 · 345-3 · 346-4)은 새 배선 글로 고침

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-29 18:50:41 +09:00
co-authored by Claude Opus 5.5
parent efa382ae06
commit 2e4316567c
19 changed files with 1088 additions and 160 deletions
@@ -34,7 +34,7 @@ import { SelectState } from '../tools/select-tool.ts';
import { ActorEvent, type MouseClickEvent } from '../tools/tool.types.ts';
import { activeToolWantsFreeText, activeToolWantsIme, ImeSink, isImeKey, isPlainSpace } from './ime-sink.ts';
import { drawInputField, dynamicInputLine } from './input-field-draw.ts';
import { cadCtrlCommand, ctrlShortcut } from './input-shortcut.ts';
import { CAD_KEY_COMMANDS, cadKeyAction } from './input-shortcut.ts';
import { wheelZoom } from './input-wheel.ts';
import { isObjectSnap, noteShift, snapAt } from './ortho.ts';
import { isWaitingForSecondSelectPoint, selectingActor } from './selecting.ts';
@@ -376,10 +376,11 @@ export class InputController {
if (target !== this.ime.element && target?.closest('input, textarea, select')) {
return;
}
const shortcut = ctrlShortcut(evt);
const cadCommand = cadCtrlCommand(evt);
// 한글 조합 중 — 단축키가 먹지 않게 IME 에 넘김(Ctrl 단축키는 조합 중에도 먹음)
if (isImeKey(evt) && !shortcut && !cadCommand) return;
// 키 동작 = ☰ [설정] 등록부(588-3) — 바꾼 키만 먹고 옛 키는 아래 글자 · 기본 처리로 감
const action = cadKeyAction(evt);
const cadCommand = action ? CAD_KEY_COMMANDS[action] : undefined;
// 한글 조합 중 — 단축키가 먹지 않게 IME 에 넘김(키 동작은 조합 중에도 먹음)
if (isImeKey(evt) && !action) return;
if (!['Shift', 'Control', 'Alt', 'Meta'].includes(evt.key)) notice(null); // 알림 줄은 다음 키까지
console.log(`key pressed: ${evt.key}`);
if (evt.key === 'F12') {
@@ -397,22 +398,22 @@ export class InputController {
return;
}
// 제도 보조 토글 (AutoCAD 상태막대 기능키)
if (evt.key === 'F3') {
if (action === 'cad.snap') {
evt.preventDefault();
setSnapEnabled(!getSnapEnabled());
return;
}
if (evt.key === 'F7') {
if (action === 'cad.grid') {
evt.preventDefault();
setGridEnabled(!getGridEnabled());
return;
}
if (evt.key === 'F8') {
if (action === 'cad.ortho') {
evt.preventDefault();
setAngleStep(getAngleStep() === 90 ? 0 : 90);
return;
}
if (evt.key === 'F10') {
if (action === 'cad.polar45') {
evt.preventDefault();
setAngleStep(getAngleStep() === 45 ? 0 : 45);
return;
@@ -444,16 +445,16 @@ export class InputController {
}
evt.preventDefault();
evt.stopPropagation();
if (shortcut === 'undo') {
if (action === 'cad.undo') {
// User wants to undo the last action
this.handleUndo(evt);
} else if (shortcut === 'redo') {
} else if (action === 'cad.redo') {
// User wants to redo the last action
this.handleRedo(evt);
} else if (shortcut === 'save') {
} else if (action === 'cad.save') {
// 부모 페이지가 저장을 맡은 화면(M02 양식)만 — B07 은 예전처럼 아무 일 없음
if (isHostSave()) requestHostSave();
} else if (shortcut === 'selectAll') {
} else if (action === 'cad.selectAll') {
// User wants to select everything
setSelectedEntityIds(getPickableEntities().map((entity) => entity.id));
} else if (evt.key === 'Backspace') {
@@ -461,7 +462,7 @@ export class InputController {
evt.preventDefault();
this.text = this.text.slice(0, this.text.length - 1);
this.browsing = null;
} else if (evt.key === 'Delete') {
} else if (action === 'cad.delete') {
// User wants to delete the current selection
evt.preventDefault();
getActiveToolActor()?.send({
@@ -2,7 +2,7 @@
* Ctrl 단축키 판정 — 공용 `A00_Common/key_shortcut.ts`(214-2)를 그대로 내보냄.
* 한글 자판은 `key` 가 「ㅋ」·「ㅛ」로 와 글자로는 안 맞아 자판 자리(`code`)로 본다.
*/
import { keyLetter } from '../../../../A00_Common/key_shortcut';
import { keyAction } from '../../../../A00_Common/key_registry';
export {
ctrlShortcut,
@@ -11,22 +11,14 @@ export {
type CtrlShortcut,
} from '../../../../A00_Common/key_shortcut';
/** CAD 만의 Ctrl 단축키 → 명령 이름(오토캐드) — Ctrl+V 는 브라우저 `paste` 사건 몫 */
export function cadCtrlCommand(
evt: Pick<KeyboardEvent, 'code' | 'ctrlKey' | 'altKey' | 'shiftKey'> &
Partial<Pick<KeyboardEvent, 'key' | 'metaKey'>>
): string | null {
if (!(evt.ctrlKey || evt.metaKey) || evt.altKey) return null;
switch (keyLetter(evt)) {
case 'c':
return evt.shiftKey ? 'COPYBASE' : 'COPYCLIP';
case 'x':
return evt.shiftKey ? null : 'CUTCLIP';
case 'v':
return evt.shiftKey ? 'PASTEBLOCK' : null;
case '1':
return evt.shiftKey ? null : 'PROPERTIES';
default:
return null;
}
}
/** CAD 키 동작(☰ [설정] 단축키 등록부 · 588-3) — 사용자가 바꾼 키 있으면 그것만 · 없으면 기본(F3 · Ctrl+Z …) */
export const cadKeyAction = (evt: KeyboardEvent): string | null => keyAction(evt, 'cad');
/** 명령으로 가는 CAD 키 동작 → 명령 이름(오토캐드) — Ctrl+V 는 브라우저 `paste` 사건 몫 */
export const CAD_KEY_COMMANDS: Record<string, string> = {
'cad.copy': 'COPYCLIP',
'cad.copyBase': 'COPYBASE',
'cad.cut': 'CUTCLIP',
'cad.pasteBlock': 'PASTEBLOCK',
'cad.properties': 'PROPERTIES',
};