refactor(B06): 세월교 「측벽 높이(자동)」 줄 지움 — 유입 · 유출 칸 받는 줄 없음(107-3 일부)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013rJwJMVL4EE31y77TB11AP
This commit is contained in:
2026-10-08 16:10:43 +09:00
co-authored by Claude Opus 5.5
parent 331883043e
commit 52994b33af
7 changed files with 19 additions and 50 deletions
+4 -6
View File
@@ -47,14 +47,13 @@ const EXTRA_ROWS = [
".b06-structure-panel__struct--span",
].join(", ");
/** 유입구·유출구·날개벽 칸은 폼에 없는 줄만 받는다 — 읽기(좌우 · 상하 · 구체 길이 · 표고) ·
* 단 수 · 옵션 · 집수정 내공 · 세월교 측벽 높이(24-4a). */
/** 유입구·유출구 칸은 폼에 없는 줄만 받는다 — 읽기(좌우 · 상하 · 구체 길이 · 표고) ·
* 단 수 · 옵션 · 집수정 내공(24-4a). */
const SIDE_ROWS = [
".b06-structure-panel__struct--readout",
".b06-structure-panel__struct--tier",
".b06-structure-panel__struct--options",
".b06-structure-panel__struct--basin-size",
".b06-structure-panel__struct--wall-height",
].join(", ");
/** 배관 칸 = 폼에 자리 없는 집수정 내공 · 유입 단 수만 — 목록에서 골라도 같은 글(54-29).
@@ -64,12 +63,11 @@ const PIPE_INLET_ROWS = [
".b06-structure-panel__struct--basin-size",
].join(", ");
const PIPE_OUTLET_ROWS = ".b06-structure-panel__struct--basin-size";
const WALL_HEIGHT_ROW = ".b06-structure-panel__struct--wall-height";
/** 받을 칸에 맞는 줄 — 배관 유입 · 유출 칸이 아니면 옛 줄 그대로 · 세월교 · 박스 유입 · 유출 칸은
* 세월교 측벽 높이(바닥 손 조정 · 91-2)만 받음(좌우 · 상하 · 바닥판 읽기는 칸에 안 둠 · 65-1). */
* 받는 줄 없음(측벽 높이 줄 지움 · 107-3 · 읽기는 칸에 안 둠 · 65-1). */
function rowsFor(slot: HTMLElement): string | null {
if (slot === sideSlots?.wingInlet || slot === sideSlots?.wingOutlet) return WALL_HEIGHT_ROW;
if (slot === sideSlots?.wingInlet || slot === sideSlots?.wingOutlet) return null;
if (slot === sideSlots?.outlet) return PIPE_OUTLET_ROWS;
return slot === sideSlots?.inlet ? PIPE_INLET_ROWS : SIDE_ROWS;
}
+6 -30
View File
@@ -6,8 +6,8 @@
* `_Cross_Panel_Base.ts`)을 쓴다 — 머리줄(제목·닫기), 2행 항목 구조,
* **십자 조작 세트는 창 맨 아래**, 키보드 방향키 제어 포함(2026-08-25 일원화).
*
* 조작: 측벽 좌우(노견 확장) · 측벽 상하(1:1.2 대각) — 십자 · 그림 끌기. 측벽 높이는 폼 날개벽
* 칸으로 옮겨 붙는 줄 · 관경 · 수량 · 날개벽 제원은 폼 칸 하나(계획서 24-4a).
* 조작: 측벽 좌우(노견 확장) · 측벽 상하(1:1.2 대각) — 십자 · 그림 끌기. 측벽 높이 줄 없음(107-3) ·
* 관경 · 수량 · 날개벽 제원은 폼 칸 하나(계획서 24-4a).
* 바닥판 연장은 날개벽 길이×cos(각도)가 정하므로 읽기 전용으로 보여 준다.
* ========================================================================== */
@@ -19,7 +19,6 @@ import {
buildPanelShell,
dpadButton,
dragReadout,
makeButton,
makeRow,
} from "./B06_Section_UI_Cross_Panel_Base";
@@ -29,8 +28,6 @@ export interface FordPanelDeps {
adjustFor: (role: FordWallRole) => FordWallAdjust;
/** 실제 그려진 벽 높이(m) — 자동일 때도 숫자를 보여 준다. */
heightFor: (role: FordWallRole) => number;
/** 높이 ±0.1m. */
nudgeHeight: (role: FordWallRole, deltaM: number) => void;
/** 좌우: 화면 좌(+)/우(−)로 미는 양(m). 부호 환산은 카드가 한다. */
nudge: (role: FordWallRole, screenDeltaM: number) => void;
/** 상하: 1:1.2 사면을 타는 대각 이동(수평 성분 m, + = 사면 아래). */
@@ -54,7 +51,7 @@ const STEP_M = 0.1;
/** 세월교 측벽 조정 오버레이 창을 만든다. 처음에는 숨어 있다.
* 관경 · 수량 · 날개벽은 좌측 폼 칸이 정본이라 창에 두지 않는다(계획서 24-4a).
* `opts.dock` — 좌측 폼에 옮겨 붙을 줄(읽기 · 측벽 높이)만 만든다 — 폼에 없던 칸이다.
* `opts.dock` — 읽기 줄만 만든다(측벽 높이 줄 없음 · 107-3).
* 오버레이는 읽기 + 십자 + 그림 끌기 손잡이. */
export function buildFordPanel(deps: FordPanelDeps, opts?: { dock?: boolean }): FordPanelHandle {
const shell = buildPanelShell(() => deps.close());
@@ -75,26 +72,6 @@ export function buildFordPanel(deps: FordPanelDeps, opts?: { dock?: boolean }):
if (current) run(current);
};
// 측벽 높이 — 폼에 칸이 없던 값이라 폼 날개벽 칸으로 옮겨 붙는 줄(24-4a).
const heightRow = makeRow("측벽 높이");
heightRow.row.classList.add("b06-structure-panel__struct--wall-height");
const heightLabel = heightRow.row.querySelector<HTMLElement>(".b06-structure-panel__label")!;
const heightValue = document.createElement("span");
heightValue.className = "b06-structure-panel__hval";
heightRow.controls.append(
makeButton(
"−",
"측벽 높이 0.1m 낮추기",
act((role) => deps.nudgeHeight(role, -STEP_M)),
),
heightValue,
makeButton(
"+",
"측벽 높이 0.1m 높이기",
act((role) => deps.nudgeHeight(role, STEP_M)),
),
);
// 십자 조작 세트 — **창 맨 아래**(템플릿 규약).
const moveRow = makeRow("이동");
moveRow.controls.classList.add("b06-structure-panel__buttons");
@@ -126,7 +103,9 @@ export function buildFordPanel(deps: FordPanelDeps, opts?: { dock?: boolean }):
),
);
root.append(value, opts?.dock ? heightRow.row : moveRow.row);
// 측벽 높이 줄 없음 — 세월교 바닥은 노면 − (관경 + 토피) 기본(107-3)
root.append(value);
if (!opts?.dock) root.append(moveRow.row);
const arrows = opts?.dock
? { attach: (): void => undefined, detach: (): void => undefined }
@@ -153,9 +132,6 @@ export function buildFordPanel(deps: FordPanelDeps, opts?: { dock?: boolean }):
`높이 ${deps.heightFor(current).toFixed(2)}m` + (adjust.heightM === null ? " (자동)" : "");
moveLine.textContent = `좌우 ${adjust.lateralM.toFixed(1)}m · 상하 ${adjust.slopeM.toFixed(1)}m`;
slabLine.textContent = `바닥판 ${deps.slabLengthM().toFixed(2)}m`;
heightValue.textContent = `${deps.heightFor(current).toFixed(1)}m`;
// 자동 = 바닥판이 계류 하상을 따라감 · 손 값 = 원지반이 바뀌어도 그대로(91-2) — 값 칸이 좁아 이름표에
heightLabel.textContent = adjust.heightM === null ? "측벽 높이 (자동)" : "측벽 높이";
}
return {
@@ -13,7 +13,7 @@ import type { FordLayout, FordWallRole } from "./B06_Section_UI_Cross_Ford";
export interface FordPanelContext {
section: CrossSection;
ford: FordControl;
/** 마지막 계산의 측벽 높이(m) — 높이 조작의 시작값. */
/** 마지막 계산의 측벽 높이(m) — 읽기 줄. */
heightFor: (role: FordWallRole) => number;
/** 마지막 계산의 바닥판 길이(m). */
slabLengthM: () => number;
@@ -31,8 +31,6 @@ export function fordPanelDeps(context: FordPanelContext): FordPanelDeps {
return {
adjustFor: (role) => ford.adjustFor(chainage)[role],
heightFor: context.heightFor,
nudgeHeight: (role, deltaM) =>
ford.update(chainage, role, { heightM: context.heightFor(role) + deltaM }),
nudge: (role, screenDeltaM) =>
ford.update(chainage, role, {
lateralM: ford.adjustFor(chainage)[role].lateralM + screenDeltaM * outwardOf(section, role),
@@ -186,7 +186,6 @@ for (const [label, key, kind] of [
const fordDeps = {
adjustFor: () => ({ heightM: null, lateralM: 0, slopeM: 0 }),
heightFor: () => 1.5,
nudgeHeight: () => {},
nudge: () => {},
nudgeSlope: () => {},
reset: () => {},
+3 -6
View File
@@ -164,12 +164,9 @@ def test_집계표_세월교_박스_흙막이_상자는_유출_단_수만큼():
assert groups(type_id, "", None) == []
def test_B06_세월교_박스_칸은_측벽_높이_줄만_받음():
def test_B06_세월교_박스_칸은_받는_줄_없음():
"""107-3 — 측벽 높이 줄 지움."""
dock = (ROOT / "B06_Section/B06_Section_UI_Adjust_Dock.ts").read_text(encoding="utf-8")
assert (
"slot === sideSlots?.wingInlet || slot === sideSlots?.wingOutlet) return WALL_HEIGHT_ROW"
in dock
)
assert 'WALL_HEIGHT_ROW = ".b06-structure-panel__struct--wall-height"' in dock
assert "slot === sideSlots?.wingInlet || slot === sideSlots?.wingOutlet) return null" in dock
lists = (ROOT / "B05_Profile/B05_Profile_UI_Structures_List.ts").read_text(encoding="utf-8")
assert "return isNone(c, state[c.id][0])" in lists
+4 -2
View File
@@ -41,9 +41,11 @@ def test_세월교_바닥_손_값은_원지반을_바꿔도_그대로(fit: dict)
assert side["wallBottom"] == pytest.approx(side["slabTop"] - 0.3, abs=1e-3)
def test_세월교_박스_칸은_측벽_높이_줄을_받음() -> None:
def test_세월교_박스_칸은_측벽_높이_줄_없음() -> None:
"""107-3 — 「측벽 높이(자동)」 줄 지움(유입 · 유출)."""
dock = (ROOT / "B06_Section/B06_Section_UI_Adjust_Dock.ts").read_text(encoding="utf-8")
assert "sideSlots?.wingOutlet) return WALL_HEIGHT_ROW" in dock
assert "sideSlots?.wingOutlet) return null" in dock
assert "wall-height" not in dock
def test_다단_자동_자리는_원지반과_무관_사면_1m(fit: dict) -> None:
@@ -41,7 +41,7 @@ def test_폼과_같은_값은_사본_줄로_만들지_않는다(out) -> None:
assert out["dock"]["outlet"] == ["options", "readout", "tier"]
# 집수정 내공 줄은 화면에서 숨김(54-40 · 값 · 그림 그대로)
assert out["dock"]["basin"] == ["options", "readout"]
assert out["dock"]["ford"] == ["readout", "wall-height"]
assert out["dock"]["ford"] == ["readout"] # 측벽 높이 줄 지움(107-3)
assert out["dock"]["box"] == ["readout"]
@@ -86,7 +86,6 @@ def test_사본_줄은_모두_폼_칸으로_옮겨_붙는다() -> None:
"tier",
"options",
"basin-size",
"wall-height",
"form",
"height",
"span",