Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QfHKQs7J3hQELKMWQMUJEy
88 lines
3.4 KiB
TypeScript
88 lines
3.4 KiB
TypeScript
/* =============================================================================
|
|
* design_plan_peek.ts
|
|
* 횡단 보기 위 **평면 겹침 패널**(요구 258 · 계획서 425) — 종단 보기의 평면(노선 편집) 노드를
|
|
* 그대로 옮겨 붙여 보여 줌(둘째 캔버스 없음 · 편집기는 페이지에 하나). 열 때 옮기고 · 닫을 때 ·
|
|
* 횡단 보기가 숨을 때 제자리(자리표 주석)로 돌림. 누름 · 휠은 캔버스에 붙어 함께 옴.
|
|
*
|
|
* 보기 · 가운데 버튼 팬 · 휠 확대만 — 왼쪽 · 오른쪽 누름(끌기 · 끼우기 · 지우기 · 재기)은 패널이
|
|
* 캡처에서 먼저 받아 캔버스로 안 보냄(편집은 B05 평면). 단추 줄 · 상태줄 등은 `design_page.css`.
|
|
* ========================================================================== */
|
|
|
|
import { createWorkflowPanelHandle } from "@ui/ui_template_overlay";
|
|
import type { DesignPageHost } from "./design_page";
|
|
import type { DesignPageShared } from "./design_shared";
|
|
|
|
/** 횡단 보기 가운데(`center`)에 겹침 패널 · 손잡이를 세운다. */
|
|
export function mountPlanPeek(
|
|
center: HTMLElement,
|
|
host: DesignPageHost,
|
|
shared: DesignPageShared,
|
|
): void {
|
|
const root = document.createElement("div");
|
|
root.className = "design-plan-peek";
|
|
const body = document.createElement("div");
|
|
body.className = "design-plan-peek__body";
|
|
const note = document.createElement("p");
|
|
note.className = "design-plan-peek__note";
|
|
body.append(note);
|
|
const handle = createWorkflowPanelHandle("bottom", "up", "평면");
|
|
root.append(body, handle.root);
|
|
center.append(root);
|
|
|
|
// 편집 몫 누름 막음 — 가운데 버튼(팬)만 통과 · 두 번 클릭(끼우기) · 오른쪽 클릭(지우기)도 막음.
|
|
// ponytail: 손가락 팬도 막힘(왼쪽 누름과 같은 단추 0) — 터치 기기에서 필요하면 pointerType 으로 가름.
|
|
body.addEventListener(
|
|
"pointerdown",
|
|
(event) => {
|
|
if (event.button !== 1) event.stopPropagation();
|
|
},
|
|
true,
|
|
);
|
|
for (const type of ["dblclick", "contextmenu"])
|
|
body.addEventListener(
|
|
type,
|
|
(event) => {
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
},
|
|
true,
|
|
);
|
|
|
|
let opened = false;
|
|
let plan: HTMLElement | null = null;
|
|
let home: Comment | null = null;
|
|
|
|
const setOpen = (open: boolean): void => {
|
|
opened = open;
|
|
root.classList.toggle("is-open", open);
|
|
handle.setOpen(open);
|
|
};
|
|
|
|
const close = (): void => {
|
|
setOpen(false);
|
|
if (plan && home) home.replaceWith(plan);
|
|
home = null;
|
|
};
|
|
|
|
const open = async (): Promise<void> => {
|
|
setOpen(true);
|
|
note.hidden = false;
|
|
note.textContent = "평면을 여는 중…";
|
|
await shared.ensureView("profile"); // B06 바로 열기 = 종단 보기를 숨긴 채 세움
|
|
if (!opened || !host.visible() || home) return;
|
|
plan =
|
|
center
|
|
.closest(".design-page__center")
|
|
?.querySelector<HTMLElement>(".b05-route__main > .b05-routeedit") ?? null;
|
|
if (!plan) return void (note.textContent = "평면을 불러오지 못했습니다.");
|
|
note.hidden = true;
|
|
home = document.createComment("design-plan-peek");
|
|
plan.replaceWith(home);
|
|
body.append(plan); // 크기 0 → 첫 크기 알림에 편집기가 다시 그림
|
|
};
|
|
|
|
handle.root.addEventListener("click", () => (opened ? close() : void open()));
|
|
host.onHide(close);
|
|
setOpen(false);
|
|
}
|