diff --git a/B06_Section/B06_Section_UI_Cross_Design.ts b/B06_Section/B06_Section_UI_Cross_Design.ts index 8e691cb0..e6cc50f5 100644 --- a/B06_Section/B06_Section_UI_Cross_Design.ts +++ b/B06_Section/B06_Section_UI_Cross_Design.ts @@ -69,11 +69,19 @@ function L(key: keyof typeof ui_locales): string { return ui_locales[key][currentLanguageIndex]; } -const GROUND_OPTIONS: Array<[GroundType, keyof typeof ui_locales]> = [ - ["soil", "B06_Design_Ground_Soil"], - ["ripping_rock", "B06_Design_Ground_Ripping"], - ["blasting_rock", "B06_Design_Ground_Blasting"], -]; +/** + * 지반유형은 **「토사」 토글 하나**다(2026-09-07 사용자 확정) — 켜면 토사, **끄면 암**(기본). + * + * 사용자 원문 — 「리핑암과 발파암 버튼을 삭제하면서 구분의 의미가 없어졌어. … 토사버튼만 + * 존재하고 이값은 활성화/비활성화로 반영(기본값은 비활성화)」. 까닭은 **암반 지정·범위가 + * 실무에서 애매해** 측점마다 암질을 못 박는 것이 오히려 틀리기 때문이고, 연암:경암 · + * 발파암:리핑암은 **설계내역에서 설계자가 비율로** 넣기로 했다(계획서 8-1). + * + * ⚠ 저장값은 종전 그대로 쓴다 — 끔 = `ripping_rock`, 켬 = `soil`. 옛 자료의 `blasting_rock` + * 도 「암(끔)」으로 읽힌다. 유토곡선·수량은 암을 한 종류(리핑암)로 잡으며, 갈라 넣는 것은 + * 설계내역 몫이다. + */ +const GROUND_ROCK_DEFAULT: GroundType = "ripping_rock"; const MODE_OPTIONS: Array<[SectionMode, keyof typeof ui_locales]> = [ ["left_cut", "B06_Design_Mode_LeftCut"], ["right_cut", "B06_Design_Mode_RightCut"], @@ -321,7 +329,8 @@ export function buildDesignControls( twoStage: boolean; ditchEnabled: boolean | null; } = { - ground: design?.ground_type ?? "soil", + // 설계가 아직 없는 측점의 기본은 **암**이다(2026-09-07 사용자: 「기본값은 비활성화」). + ground: design?.ground_type ?? GROUND_ROCK_DEFAULT, mode: design?.section_mode ?? (section.uphill_side === "right" ? "right_cut" : "left_cut"), ditch: design?.ditch_side ?? null, ditchType: design?.ditch_type ?? "standard", @@ -353,11 +362,24 @@ export function buildDesignControls( }); }; - // 지반유형: 제목행 배치용으로 분리 반환(D-6). 라벨 삭제(3번) — 버튼만. - const groundSegment = segment("", GROUND_OPTIONS, state.ground, (value) => { - state.ground = value; - emit(); - }); + // 지반유형: 제목행 배치용으로 분리 반환(D-6). 「토사」 토글 하나 — 끄면 암이다(2026-09-07). + // 버튼명은 「토사」로 고정하고 **켜짐/꺼짐(색)**으로 상태를 보인다 — 측구 토글과 같은 꼴 + // (사용자 원문: 「토사버튼만 존재하고 이값은 활성화/비활성화로 반영」). + const groundToggle = toggle( + "", + state.ground === "soil", + L("B06_Design_Ground_Soil"), + L("B06_Design_Ground_Soil"), + () => { + state.ground = state.ground === "soil" ? GROUND_ROCK_DEFAULT : "soil"; + emit(); + }, + ); + groundToggle.button.title = + state.ground === "soil" + ? "토사 — 암반이 없어 절토는 토사 경사 하나로만 그린다. 누르면 암으로 바뀐다." + : "암 — 암 경계선이 서고 그 아래는 암 절토각, 위는 토사 경사로 그린다. 누르면 토사로 바뀐다."; + const groundSegment = groundToggle.wrap; groundSegment.classList.add("b06-design__seg--header"); // 단면 유형은 지형에서 자동 판정되며(D-2), 제목행 pill로 표시한다(E-3, Cross_View에서 생성). // 아래 옵션은 상시 노출하되 선행 조건 미충족 시 비활성 처리한다(E-6). diff --git a/B06_Section/B06_Section_UI_Standard_Panel.ts b/B06_Section/B06_Section_UI_Standard_Panel.ts index 9279ab3b..fed5075f 100644 --- a/B06_Section/B06_Section_UI_Standard_Panel.ts +++ b/B06_Section/B06_Section_UI_Standard_Panel.ts @@ -27,6 +27,7 @@ import { import { currentLanguageIndex, ui_locales } from "@ui/ui_template_locale"; import { createButton, createInputField, createSelectField } from "@ui/ui_template_elements"; import { buildStandardDiagram } from "./B06_Section_UI_Standard_Diagram"; +import { ratioToDegrees } from "./B06_Section_UI_Cross_CutSlope"; import { getCompanyStandard, listCompanyStandards, @@ -303,6 +304,19 @@ export function createStandardPanel( }); field.input.step = "0.1"; field.input.min = "0"; + // 경사 칸은 **각도도 함께 보인다** — 카드의 개별 절토각 칸이 도(°)로 받으므로 두 자리의 + // 말이 갈리지 않게 한다(2026-09-07). 1:0.4 = 68.2° · 1:1.0 = 45° · 1:1.5 = 33.7°. + if (spec.label === "B06_Std_Field_CutSlope" || spec.label === "B06_Std_Field_FillSlope") { + const showAngle = (): void => { + const ratio = Number(field.input.value); + field.input.title = + Number.isFinite(ratio) && ratio > 0 + ? `1:${ratio} = ${ratioToDegrees(ratio).toFixed(1)}° (횡단 카드의 각도 칸과 같은 값)` + : ""; + }; + showAngle(); + field.input.addEventListener("input", showAngle); + } grid.append(field.root); };