import type { Ref } from "vue"; import type { ProjectFile } from "../../domain/project"; import type { Node } from "../../domain/phy"; import { longPressColumn, treeIndex, treeNodes } from "./logic"; export function usePhyTreeModel(project: () => ProjectFile, focus: Ref) { function allNodes(nodes = project().phy.root): Node[] { return treeNodes(nodes); } function node(id: string): Node | undefined { return treeIndex(project().phy.root).nodes.get(id); } function parentId(id: string): string | null { return treeIndex(project().phy.root).selectableParent(id); } function isAncestor(candidate: string, id: string): boolean { let parent = parentId(id); while (parent) { if (parent === candidate) return true; parent = parentId(parent); } return false; } function selectedContainer(id: string): string | null { return treeIndex(project().phy.root).insertionContainer(id); } function groupForVariant(id: string): string | null { return treeIndex(project().phy.root).groupForVariant(id); } function parentLabel(id: string | null): string { if (!id) return "root"; const item = node(id); if (item?.type === "variantGroup") return item.name; if (item?.type === "cluster") return item.name || "クラスター"; const variant = allNodes() .flatMap((item) => (item.type === "variantGroup" ? item.children : [])) .find((item) => item.id === id); return variant?.name || id; } function pressTargets(id: string): string[] { const ancestors: string[] = []; let parent = parentId(id); while (parent) { const group = allNodes().find( (item) => item.type === "variantGroup" && item.children.some((variant) => variant.id === parent), ); if (group) { ancestors.push(group.id); parent = parentId(group.id); } else { ancestors.push(parent); parent = parentId(parent); } if (ancestors.at(-1) === focus.value) break; } return longPressColumn(id, ancestors, focus.value || undefined); } return { allNodes, node, parentId, isAncestor, selectedContainer, groupForVariant, parentLabel, pressTargets, }; }