Merge remote-tracking branches 'origin/main_laptop_1' and 'origin/sub_laptop_8' into sub_laptop_7
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
/* =============================================================================
|
||||
* A00_Common/design/design_pick_profile.ts
|
||||
* 종단도 고름 강조(측점 세로선 · 알약 · 구간 띠) = 고름 한 칸에서 파생 (233-1 · 조사 AF (나) ②).
|
||||
* 종단 보기 고름 강조 = 고름 한 칸에서 파생 — 종단도(측점 세로선 · 알약 · 구간 띠 · 233-1) ·
|
||||
* 3D(측점 띠 · 핀 · 부재 · 233-2) (조사 AF (나) ② ③).
|
||||
*
|
||||
* 고름 한 칸(`structure-pick`)이 유일 원천이다. 값이 바뀌면(구독) 그 값으로 종단도를 다시 세우고,
|
||||
* 관 · 구조물 목록이 바뀐 뒤에도 같은 값으로 다시 얹는다(`paint`) — 화면끼리 손으로 부르던 길이
|
||||
@@ -70,18 +71,53 @@ export function paintProfilePick(target: ProfilePickTarget, pick: ProfilePick):
|
||||
else target.setSelectedStation(pick.stationId);
|
||||
}
|
||||
|
||||
export interface ViewerPickTarget {
|
||||
markers: { selectStation: (stationId: string | null, notify?: boolean) => void };
|
||||
structurePick: {
|
||||
select: (pick: { chainageM: number; kind: string; key?: string } | null) => void;
|
||||
};
|
||||
}
|
||||
|
||||
/** 고름 값 → 3D 가 켤 것 — 띠(+핀) = 종단 측점선과 같은 측점(구조물 고름은 그 자리 구조물 측점만) ·
|
||||
* 부재 = 고른 측점의 부재 전부(부재키가 있으면 그 부재 하나). */
|
||||
export function viewerPickOf(
|
||||
selection: (DesignSelection & { partKey?: string }) | null,
|
||||
source: ProfilePickSource,
|
||||
): { stationId: string | null; member: { chainageM: number; kind: string; key?: string } | null } {
|
||||
if (!selection || selection.chainageM === null) return { stationId: null, member: null };
|
||||
const at = selection.chainageM;
|
||||
const pick = profilePickOf(selection, source);
|
||||
const own = selection.structureId
|
||||
? nearestWithin(source.irregular(), at, (entry) => entry.chainage_m)
|
||||
: undefined;
|
||||
const stationId = "stationId" in pick ? pick.stationId : own ? irregularStationId(own.id) : null;
|
||||
return { stationId, member: { chainageM: at, kind: "", key: selection.partKey } };
|
||||
}
|
||||
|
||||
export function paintViewerPick(
|
||||
target: ViewerPickTarget,
|
||||
pick: ReturnType<typeof viewerPickOf>,
|
||||
): void {
|
||||
target.markers.selectStation(pick.stationId, false); // 칠하기만 — 알림이 사슬을 다시 돌리지 않게
|
||||
target.structurePick.select(pick.member);
|
||||
}
|
||||
|
||||
/**
|
||||
* 종단도를 고름 한 칸에 묶음 — 값이 바뀔 때마다 그림 · `paint()` = 목록이 바뀐 뒤 같은 값으로 다시 얹음.
|
||||
* 보기가 숨어 있으면(다른 보기가 종단도를 쥠) 안 그림 — 그 보기가 제 규칙으로 그림 · 보기를 떠나면 구독 끊음.
|
||||
* 종단 보기(종단도 · 3D)를 고름 한 칸에 묶음 — 값이 바뀔 때마다 그림 · `paint()` = 목록이 바뀐 뒤 ·
|
||||
* 폼이 닫힌 뒤 같은 값으로 다시 얹음. 보기가 숨어 있으면(횡단 보기가 종단도를 쥠) 안 그림 — 그 보기가
|
||||
* 제 규칙으로 그림 · 보기를 떠나면 구독 끊음.
|
||||
*/
|
||||
export function bindProfilePick(
|
||||
projectId: string | null,
|
||||
target: ProfilePickTarget,
|
||||
target: { profile: ProfilePickTarget; viewer?: ViewerPickTarget },
|
||||
host: { visible: () => boolean; onDispose: (fn: () => void) => void },
|
||||
source: ProfilePickSource,
|
||||
): { paint: () => void } {
|
||||
const paint = (): void => {
|
||||
if (host.visible()) paintProfilePick(target, profilePickOf(readSelection(projectId), source));
|
||||
if (!host.visible()) return;
|
||||
const selection = readSelection(projectId);
|
||||
paintProfilePick(target.profile, profilePickOf(selection, source));
|
||||
if (target.viewer) paintViewerPick(target.viewer, viewerPickOf(selection, source));
|
||||
};
|
||||
host.onDispose(subscribeSelection(projectId, paint));
|
||||
return { paint };
|
||||
|
||||
@@ -39,6 +39,7 @@ import { readStructurePick } from "../../B05_Profile/B05_Profile_UI_Structure_Pi
|
||||
import { NO_SELECTION, PIPE_MATCH_M, selectDesign } from "./design_selection";
|
||||
import { readPendingPipes } from "../../B05_Profile/B05_Profile_Api_Pipes_Draft";
|
||||
import { applyStructurePick } from "../../B06_Section/B06_Section_UI_Page_Structure_Pick";
|
||||
import { bindCrossPick } from "../../B06_Section/B06_Section_UI_Page_Pick_Sync";
|
||||
import { createSectionView } from "../../B06_Section/B06_Section_UI_Section_View";
|
||||
import { revetFormOf, revetWallSpec } from "../../B06_Section/B06_Section_UI_Cross_Culvert_Const";
|
||||
import {
|
||||
@@ -387,7 +388,7 @@ export async function mountCrossView(
|
||||
: null;
|
||||
if (!target) {
|
||||
structuresPanel.showAtChainage(null);
|
||||
selectDesign(projectId, NO_SELECTION, { from: "b06" }); // 카드 해제 — 선택도 비운다.
|
||||
releaseCross(); // 카드 다시 누름 = 풀기 한 길(범위 테두리 · 형상까지 · 233-2)
|
||||
return;
|
||||
}
|
||||
const owner = isWallSelecting() ? stationControls.structureSpan.ownerOf(target) : null;
|
||||
@@ -494,23 +495,20 @@ export async function mountCrossView(
|
||||
if (applied) appliedPick = signature;
|
||||
}
|
||||
|
||||
/** 고름을 다 풂(54-38) — 카드 · 벽 · 세월교 · BOX 강조 · 넘김 되얹기 표시 · 선택 칸. */
|
||||
// 횡단 보기 강조 = 고름 한 칸 구독 · 다른 곳(Esc 등)이 바꾼 값으로 다시 세움(233-2)
|
||||
const crossPick = bindCrossPick(projectId, host, {
|
||||
sections: () => sectionDetail?.cross_sections ?? [],
|
||||
controls: stationControls,
|
||||
releasePipe: () => structuresPanel.releasePipe(),
|
||||
view: sectionView,
|
||||
reapply: () => {
|
||||
appliedPick = null;
|
||||
restoreStructurePick();
|
||||
},
|
||||
});
|
||||
/** 고름을 다 풂(54-38) — 강조 모두 끄고 넘김 되얹기 표시 · 선택 칸 비움(풀기 한 길 · 233-2). */
|
||||
function releaseCross(): void {
|
||||
const { revetOffset, ford, box } = stationControls;
|
||||
const lit = (sectionDetail?.cross_sections ?? []).filter(
|
||||
(s) =>
|
||||
revetOffset.highlightFor(s) ||
|
||||
ford.selectedFor(s.chainage_m) ||
|
||||
box.selectedFor(s.chainage_m),
|
||||
);
|
||||
for (const s of lit) {
|
||||
if (revetOffset.selectedFor(s)) revetOffset.select(s.chainage_m, null);
|
||||
if (ford.selectedFor(s.chainage_m)) ford.select(s.chainage_m, null);
|
||||
if (box.selectedFor(s.chainage_m)) box.select(s.chainage_m, null);
|
||||
}
|
||||
structuresPanel.releasePipe();
|
||||
sectionView.focusStation(null);
|
||||
sectionView.refreshCards(lit.map((s) => s.chainage_m));
|
||||
crossPick.release();
|
||||
appliedPick = null;
|
||||
selectDesign(projectId, NO_SELECTION, { from: "b06" });
|
||||
}
|
||||
|
||||
@@ -411,8 +411,8 @@ export async function mountProfileView(
|
||||
},
|
||||
isRestoring: () => restoring,
|
||||
});
|
||||
// 종단도 강조 = 고름 한 칸에서 파생 · 이 보기가 보일 때만(횡단 보기는 제 규칙 · 233-1)
|
||||
const profilePick = bindProfilePick(activeProjectId, profilePanel, host, {
|
||||
// 종단도 · 3D 강조 = 고름 한 칸에서 파생 · 이 보기가 보일 때만(횡단 보기는 제 규칙 · 233-1 · 233-2)
|
||||
const profilePick = bindProfilePick(activeProjectId, { profile: profilePanel, viewer }, host, {
|
||||
irregular: () => bridge.irregularStations(),
|
||||
pipes: () => lastPipes ?? [],
|
||||
sections: () => currentSectionDetail?.cross_sections ?? [],
|
||||
@@ -573,7 +573,6 @@ export async function mountProfileView(
|
||||
);
|
||||
return;
|
||||
}
|
||||
viewer.markers.selectStation(null);
|
||||
profilePick.paint();
|
||||
},
|
||||
// 보기를 떠나는 자리 = 코리도 영구저장 시점(2026-08-23 사용자 확정) — 이동은 막지 않는다.
|
||||
|
||||
Reference in New Issue
Block a user