Merge remote-tracking branches 'origin/main_laptop_1' and 'origin/sub_laptop_8' into sub_laptop_7
This commit is contained in:
@@ -143,7 +143,7 @@ export function selectionSource(
|
||||
/* ── 모달 배선 ─────────────────────────────────────────────────────────── */
|
||||
|
||||
export interface DetailSelect {
|
||||
/** 그림을 새로 그린 뒤 — 조각 · 판정 선 · 값 칸 다시(고름 지움). */
|
||||
/** 그림을 새로 그린 뒤 — 조각 · 판정 선 · 값 칸 다시(같은 자리 조각 고름은 유지 · 233-2). */
|
||||
redraw: () => void;
|
||||
/** 고르기 갈래(표 우클릭) — 있으면 [칸에 넣기] 단추 · 면적이면 누름 = 늘 더하기. */
|
||||
setMode: (kind: "area" | "length" | null) => void;
|
||||
@@ -152,6 +152,10 @@ export interface DetailSelect {
|
||||
detach: () => void;
|
||||
}
|
||||
|
||||
/** 조각의 자리 이름 — 선 종류 + mm 로 맞춘 꼭짓점(px → m 되짚기의 부동소수 흔들림 거름). */
|
||||
const pieceKey = (piece: SplitPiece | undefined): string =>
|
||||
piece ? `${piece.line}|${piece.points.map((p) => p.map((v) => v.toFixed(3))).join(";")}` : "";
|
||||
|
||||
export function attachDetailSelect(input: {
|
||||
cad: HTMLElement;
|
||||
design: () => CrossDesign | undefined;
|
||||
@@ -209,10 +213,12 @@ export function attachDetailSelect(input: {
|
||||
|
||||
return {
|
||||
redraw() {
|
||||
selected = [];
|
||||
// 다시 그려도(창 크기 · 카드 다시 세움) 같은 자리 조각은 고름 유지 — 지우면 바로 꺼졌음(233-2)
|
||||
const keep = new Set(selected.map((i) => pieceKey(pieces[i])));
|
||||
const axes = input.axes();
|
||||
const layer = cad.querySelector<SVGGElement>("g.b06-chart__plot-layer");
|
||||
pieces = axes && layer ? collectPieces([...layer.querySelectorAll("*")], axes) : [];
|
||||
selected = pieces.flatMap((piece, i) => (keep.has(pieceKey(piece)) ? [i] : []));
|
||||
const toPx = axes ? mToPx(axes) : null;
|
||||
hits = toPx
|
||||
? pieces.map((piece) => {
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/* =============================================================================
|
||||
* B06_Section_UI_Page_Pick_Sync.ts
|
||||
* 횡단 보기 강조를 고름 한 칸에 묶음 (233-2 · 조사 AF (나) ④).
|
||||
*
|
||||
* 고름 한 칸(`structure-pick`)이 유일 원천이다. 횡단 보기가 보일 때 다른 곳(풀기 Esc 등)이 값을
|
||||
* 바꾸면 구독으로 받아 카드 · 범위 테두리(`--span`) · 포장층 · 벽 · 세월교 · BOX 형상 강조를 그 값으로
|
||||
* 다시 세운다 — 값이 비면 모두 풂, 값이 있으면 넘김 적용(`applyStructurePick`)과 같은 길로 다시 얹음.
|
||||
* 횡단 보기 안 누름(카드 · 목록 · 알약 · 형상)은 그 자리에서 그리고 값을 적으므로(from "b06") 되받지 않음.
|
||||
* 풀기(카드 다시 누름 · 목록 다시 누름 · 보기 오감)는 `release` 한 길 — 카드 · 폼 관 · 범위 테두리 ·
|
||||
* 형상까지 모두 끔(카드만 풀고 `--span` 이 남던 구멍 · a4).
|
||||
* ========================================================================== */
|
||||
|
||||
import { subscribeSelection } from "../A00_Common/design/design_selection";
|
||||
import type { CrossSection } from "./B06_Section_Api_Fetch";
|
||||
import type { StationControls } from "./B06_Section_UI_Page_Station_Controls";
|
||||
|
||||
export interface CrossPickDeps {
|
||||
sections: () => ReadonlyArray<CrossSection>;
|
||||
controls: Pick<StationControls, "revetOffset" | "ford" | "box">;
|
||||
releasePipe: () => void;
|
||||
view: {
|
||||
focusStation: (stationId: string | null) => void;
|
||||
refreshCards: (chainages: ReadonlyArray<number>) => void;
|
||||
selectMark: (structureId: string | null, span?: boolean) => void;
|
||||
};
|
||||
/** 지금 값으로 카드 · 형상 · 폼을 다시 세움(넘김 적용 길). */
|
||||
reapply: () => void;
|
||||
}
|
||||
|
||||
let releasing = false;
|
||||
|
||||
/** 횡단 보기 강조를 모두 끔 — 카드 · 벽 · 세월교 · BOX · 폼 관 · 범위 테두리 · 포장층(값은 안 건드림).
|
||||
* 카드를 풀면 카드 리스너가 다시 풀기를 부름 — 되돌아온 부름은 건너뜀. */
|
||||
export function releaseCrossHighlights(deps: CrossPickDeps): void {
|
||||
if (releasing) return;
|
||||
releasing = true;
|
||||
try {
|
||||
releaseAll(deps);
|
||||
} finally {
|
||||
releasing = false;
|
||||
}
|
||||
}
|
||||
|
||||
function releaseAll(deps: CrossPickDeps): void {
|
||||
const { revetOffset, ford, box } = deps.controls;
|
||||
const lit = deps
|
||||
.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);
|
||||
}
|
||||
deps.releasePipe();
|
||||
deps.view.focusStation(null);
|
||||
deps.view.selectMark(null);
|
||||
deps.view.refreshCards(lit.map((s) => s.chainage_m));
|
||||
}
|
||||
|
||||
/** 횡단 보기를 고름 한 칸에 묶음 — 보일 때 · 다른 곳이 바꾼 값만 받음 · 보기를 떠나면 끊음.
|
||||
* `release` = 강조 모두 끔(값은 부르는 쪽이 비움). */
|
||||
export function bindCrossPick(
|
||||
projectId: string | null,
|
||||
host: { visible: () => boolean; onDispose: (fn: () => void) => void },
|
||||
deps: CrossPickDeps,
|
||||
): { release: () => void } {
|
||||
host.onDispose(
|
||||
subscribeSelection(projectId, (selection, from) => {
|
||||
if (!host.visible() || from === "b06") return;
|
||||
if (selection.chainageM === null) releaseCrossHighlights(deps);
|
||||
else deps.reapply();
|
||||
}),
|
||||
);
|
||||
return { release: () => releaseCrossHighlights(deps) };
|
||||
}
|
||||
Reference in New Issue
Block a user