/* ============================================================================= * M02_MasterTemplete_TreePanel_Pick.ts * 공용 나무 여러 개 고르기 · 복사 붙여넣기 자료(PLAN 30-2 · 화면 없음) — 고름(Ctrl · Shift 클릭) · * 고른 것 → 서버 모양(`TreeRef`) · 복사해 둔 것(나무 종류마다 하나 · 층을 바꿔 화면을 다시 세워도 남음). * 그리기 · 메뉴는 `M02_MasterTemplete_TreePanel.ts`. * ========================================================================== */ import type { TreeClip, TreeItem, TreeRef } from "./M02_MasterTemplete_Api_Fetch"; import { folderOf } from "./M02_MasterTemplete_TreePanel_Model"; /** 나무 줄 하나가 가리키는 것 — 폴더(경로) · 항목 */ export type Target = { kind: "folder"; path: string[] } | { kind: "item"; item: TreeItem }; export const refOf = (target: Target): TreeRef => target.kind === "item" ? { 경로: folderOf(target.item), 키: target.item.key } : { 경로: target.path }; let clip: TreeClip | null = null; /** 이 나무 종류로 복사해 둔 것 — 없으면 null */ export const clipOf = (kind: string): TreeClip | null => (clip?.kind === kind ? clip : null); export const keepClip = (next: TreeClip): void => { clip = next; }; /** 클릭 한 번 뒤 고름 — Ctrl(⌘) = 하나 넣고 빼기 · Shift = 기준에서 여기까지(보이는 줄 차례) · * 그냥 = 이것 하나. `handled` = 줄 본디 동작(항목 열기 · 폴더 접기)을 막음 */ export function pickClick( picked: Set, anchor: string | null, id: string, mod: { ctrl: boolean; shift: boolean }, order: string[], ): { picked: Set; anchor: string | null; handled: boolean } { if (mod.ctrl) { const next = new Set(picked); if (next.has(id)) next.delete(id); else next.add(id); return { picked: next, anchor: id, handled: true }; } if (mod.shift && anchor && order.includes(anchor) && order.includes(id)) { const [a, b] = [order.indexOf(anchor), order.indexOf(id)].sort((x, y) => x - y); return { picked: new Set(order.slice(a, b + 1)), anchor, handled: true }; } return { picked: new Set([id]), anchor: id, handled: false }; }