/* ============================================================================= * B05_Profile_UI_RouteEdit_Mouse.ts * 계획노선 편집(평면) 마우스 배선 — 선 두 번 클릭 = 노드 넣기 · 노드 오른쪽 클릭 = 지움 · 가운데(휠) 버튼 끌기 = * 지도 이동 · 휠 = 확대 · Ctrl+휠 = 돌리기. `B05_Profile_UI_RouteEdit.ts` 에서 뗌(626-3 · 동작 그대로). * 노드 끌기 · 집기는 `_Pointer` 몫 · 집기 셈 · 듣기는 `_Input` 몫. * ========================================================================== */ import type { ViewState } from "../B04_PreProcess/B04_PreProcess_UI_MapRender"; import type { VWorldMeta } from "../B04_PreProcess/B04_PreProcess_Api_Fetch"; import { showToast } from "@ui/ui_template_elements"; import { bindNodeSplice, bindRouteEditNavigation } from "./B05_Profile_UI_RouteEdit_Input"; import type { RouteEditSnapshot } from "./B05_Profile_UI_RouteEdit_History"; import type { MapRotation } from "./B05_Profile_UI_RouteEdit_Rotate"; import * as edits from "./logic/B05_Profile_UI_RouteEdit_Edits"; type Vertex = [number, number]; export interface RouteEditMouseParams { canvas: HTMLCanvasElement; rotation: Pick; pointer: { segmentAt: (px: number, py: number) => number; nodeAt: (px: number, py: number) => number; claimed: () => boolean; }; toMetric: (px: number, py: number) => Vertex; getView: () => ViewState; setView: (next: ViewState) => void; getMeta: () => VWorldMeta | null; /** 지금 편집값(같은 배열 — 넣고 빼면 그대로 바뀜). */ snapshot: () => RouteEditSnapshot; setPicked: (index: number) => void; applyEdit: (message: string) => void; draw: () => void; } export function bindRouteEditMouse(params: RouteEditMouseParams): void { const { canvas, rotation, pointer } = params; bindNodeSplice({ canvas, unrotate: rotation.unrotate, segmentAt: pointer.segmentAt, nodeAt: pointer.nodeAt, insert: (segment, px, py) => { edits.spliceNode(params.snapshot(), segment + 1, params.toMetric(px, py)); // 편집값도 같은 자리에 끼운다. params.setPicked(segment + 1); params.applyEdit("새 노드를 넣었습니다(직선 추가)."); }, remove: (index) => { const snapshot = params.snapshot(); if (snapshot.planned.length <= 2) return showToast("노선은 노드가 2개 이상이어야 합니다.", "error"); if (snapshot.apexLock[index]) return showToast("고정한 점은 못 지웁니다 — 고정을 먼저 푸세요.", "error"); edits.spliceNode(snapshot, index); params.setPicked(-1); params.applyEdit("노드를 지웠습니다(직선 삭제)."); }, }); bindRouteEditNavigation({ canvas, getView: params.getView, setView: params.setView, getMeta: params.getMeta, // 돌린 지도에서는 손이 민 방향과 그림이 움직일 방향이 다르다 — 거꾸로 돌려 넘긴다. unrotateDelta: rotation.unrotateDelta, rotateWheel: rotation.wheel, // Ctrl+휠 = 5° 돌리기(390-3) claimed: pointer.claimed, // 왼쪽 옮기기 = 노드 · 손잡이 · 마커 · 재기 아닌 누름만(588-4) draw: params.draw, }); }