/* ============================================================================= * map_layer_bar.ts * 공용 지도 겹 줄(PLAN 569-2 · 586-2 · 624-2 · 요구 530) — 겹 단추 한 줄(공용 지도 도구줄 `createMapTools` · 묶음 사이 나눔선) + * 끝에 그래픽 카드 단추(GL ↔ 옛 캔버스). * 보일 겹 · 처음 켬 · 취향 열쇠 = 페이지 표(`map_layer_list` `MAP_LAYER_PAGES`) · 누르면 켬끔 뒤집고 취향에 적고 `onToggle`. * 막힘 = 지형을 아직 안 받음(`sync({ ready: false })`) · 조각만 쓰는 겹은 옛 캔버스에서 「안 보임」 글. * 받기 · 그리기 · 범례는 페이지 몫 — 켬끔 값(`on`)은 같은 객체를 같이 씀. * 쓰는 법 = `createMapLayerBar({ page: "d03", glOn, onToggle, onGl })` → `{ root, bar, on, toggle, save, sync }`. * ========================================================================== */ import { createIconButton } from "@ui/ui_template_button"; import { createMapTools } from "@ui/ui_template_map_tools"; import { writeByKey } from "../b_page_state"; import { tileOnly } from "./map_forest_layers"; import { MAP_LAYER_PAGES, pageGroups, readLayerPref, type MapLayerKey, type MapPage, } from "./map_layer_list"; export interface MapLayerBar { /** 도구줄 감싼 것(자리는 페이지 CSS). */ root: HTMLElement; /** 도구줄 자체(폭 재기). */ bar: HTMLElement; /** 켬끔 — 페이지가 바꾸면 `save` · 받기 실패로 끄는 것은 안 적음. */ on: Record; /** 뒤집고 적고 `onToggle`. */ toggle: (key: MapLayerKey) => void; save: () => void; /** 단추 눌림 · 막힘 · 글을 켬끔 값에 맞춤. */ sync: (state: { ready: boolean; glOn: boolean }) => void; } export function createMapLayerBar(opts: { page: MapPage; glOn: boolean; onToggle: (key: MapLayerKey) => void; /** 그래픽 카드 단추 누름. */ onGl: () => void; }): MapLayerBar { const { page } = opts; const on = readLayerPref(page); const save = (): void => writeByKey(MAP_LAYER_PAGES[page].pref, JSON.stringify(on)); const toggle = (key: MapLayerKey): void => { on[key] = !on[key]; save(); opts.onToggle(key); }; const defs = pageGroups(page); const buttons = new Map(); const groups = defs.map((group) => group.map((def) => { const button = createIconButton({ icon: def.icon, title: def.title, size: 32, pressed: on[def.key], onClick: () => toggle(def.key), }); button.dataset.layer = def.key; buttons.set(def.key, button); return button; }), ); const glButton = createIconButton({ icon: "gauge", title: "그래픽 카드 그림(바탕 겹 · 글을 GPU 로 · 끔 = 옛 캔버스 그림)", size: 32, pressed: opts.glOn, onClick: opts.onGl, }); glButton.dataset.layer = "gl"; groups.push([glButton]); const tools = createMapTools({ label: "지도 겹", groups }); function sync({ ready, glOn }: { ready: boolean; glOn: boolean }): void { for (const def of defs.flat()) { const button = buttons.get(def.key)!; button.setAttribute("aria-pressed", String(on[def.key])); button.disabled = !ready; const title = !ready ? `${def.title} — 지형 받기 뒤 보임` : tileOnly(def.key) && !glOn ? `${def.title} — 옛 그림(그래픽 카드 끔)엔 안 보임` : def.title; button.title = title; button.setAttribute("aria-label", title); } glButton.setAttribute("aria-pressed", String(glOn)); } return { root: tools.root, bar: tools.bar, on, toggle, save, sync }; }