diff --git a/B05_wf2_Route/B05_wf2_Route_UI_Drainage_Panel.ts b/B05_wf2_Route/B05_wf2_Route_UI_Drainage_Panel.ts index bc690932..4802f457 100644 --- a/B05_wf2_Route/B05_wf2_Route_UI_Drainage_Panel.ts +++ b/B05_wf2_Route/B05_wf2_Route_UI_Drainage_Panel.ts @@ -46,6 +46,7 @@ import { MAX_PANEL_WIDTH_RATIO, MIN_PANEL_WIDTH, renderBasinRows, + basinIndexOfPipe, pipeMarkerColor, pointInRing, reconcilePipes, @@ -318,15 +319,11 @@ export function createDrainagePanel(callbacks: DrainagePanelCallbacks = {}): Dra const pipeColor = (chainage: number): string => pipeMarkerColor(basins, chainage); - /** 마커 선택 ↔ 유역 목록 선택 동기화 + 삭제 버튼 활성화. */ + /** 마커 선택 ↔ 유역 강조 동기화 + 삭제 버튼 활성화. */ function syncPipeSelection(): void { const index = pipeEditor.selected(); deleteButton.disabled = index === null; - const pipe = index === null ? null : pipeEditor.pipes()[index]; - const basin = pipe - ? basins.find((item) => Math.abs(item.chainage_m - pipe.chainage_m) < 0.51) - : null; - selectBasin(basin ? basin.index : null); + selectBasin(basinIndexOfPipe(basins, index === null ? null : pipeEditor.pipes()[index])); } function scheduleDraw(): void { @@ -338,12 +335,11 @@ export function createDrainagePanel(callbacks: DrainagePanelCallbacks = {}): Dra } /** 유역 제원 목록을 다시 그린다. 항목을 누르면 해당 유역만 진하게 강조한다. */ - /** 유역 제원 목록을 다시 그린다. 항목을 누르면 그 유역만 진하게 강조한다. */ - function renderBasinList(): void { + /** 유역 제원 목록. 항목을 누르면 그 유역만 진하게 강조한다. */ + const renderBasinList = (): void => renderBasinRows(basinList, basins, selectedBasin, (index) => selectBasin(selectedBasin === index ? null : index), ); - } /** 유역 강조를 바꾸는 **유일한 자리**. 지도 클릭·목록 클릭·마커 선택·밖에서 온 요청이 전부 * 여기를 거쳐야 그래프 측점선·사이드 패널과 어긋나지 않는다(2026-08-02 사용자 지시). @@ -532,11 +528,19 @@ export function createDrainagePanel(callbacks: DrainagePanelCallbacks = {}): Dra // 중간 버튼 기본 동작(페이지 자동 스크롤)이 지도 팬과 겹치지 않게 막는다. if (event.button === 1) event.preventDefault(); const rect = viewport.getBoundingClientRect(); - // 배관 마커 클릭/추가가 처리되면 지도 팬은 시작하지 않는다. - if (pipeEditor.handleDown(currentView(), event.clientX - rect.left, event.clientY - rect.top)) { + // 배관 마커는 **좌클릭으로만** 잡는다 — 우클릭은 메뉴, 가운데 버튼은 팬 전용이다 + // (2026-08-01 사용자 지시). + if ( + event.button === 0 && + pipeEditor.handleDown(currentView(), event.clientX - rect.left, event.clientY - rect.top) + ) { + // 마커를 잡은 좌클릭이므로 유역 고르기로는 넘기지 않는다. + pipeClickStart = { x: event.clientX, y: event.clientY }; viewport.setPointerCapture(event.pointerId); return; } + // 마커를 못 잡은 좌클릭은 유역 고르기 후보로 기억한다(끌지 않고 뗐을 때만 고른다). + if (event.button === 0) basinClickStart = { x: event.clientX, y: event.clientY }; // 팬은 가운데(휠) 버튼 전용이다. 좌버튼은 유역선 핸들·배관 마커를 고르고 끄는 데만 쓴다 // (좌버튼이 팬까지 겸하면 마커를 집으려다 지도가 딸려 움직인다 — 2026-08-01 사용자 지시). // 가운데 버튼이 없는 터치·펜은 그대로 끌어서 팬 할 수 있게 둔다. diff --git a/B05_wf2_Route/B05_wf2_Route_UI_Drainage_Parts.ts b/B05_wf2_Route/B05_wf2_Route_UI_Drainage_Parts.ts index 54ee8684..85f710d9 100644 --- a/B05_wf2_Route/B05_wf2_Route_UI_Drainage_Parts.ts +++ b/B05_wf2_Route/B05_wf2_Route_UI_Drainage_Parts.ts @@ -494,3 +494,13 @@ export function pipeMarkerColor(basins: ReadonlyArray, chainageM: n if (!basin) return themeColor("--map-pipe-orphan", "#e5e7eb"); return basinColor(basin.index).replace(/0\.45\)$/, "1)"); } + +/** 배관 마커가 받는 유역 번호. 마커가 없거나 대응 유역이 없으면 null. */ +export function basinIndexOfPipe( + basins: ReadonlyArray, + pipe: { chainage_m: number } | null, +): number | null { + if (!pipe) return null; + const basin = basins.find((item) => Math.abs(item.chainage_m - pipe.chainage_m) < 0.51); + return basin ? basin.index : null; +}