import { useState } from 'react'; import { Eye, LayoutGrid, Grid3X3, Box, Ruler, Trash2, Camera, Move, RotateCw, RefreshCw, ChevronUp, ChevronDown, Grip, ClipboardCheck, X, Crosshair, Magnet, HelpCircle, Maximize2, MousePointerClick, EyeOff, Focus, } from 'lucide-react'; import { Button } from '@/components/ui/button'; import { Slider } from '@/components/ui/slider'; import { ScrollArea } from '@/components/ui/scroll-area'; import { useModelStore } from '@/stores/useModelStore'; import { InspectionChecklist } from '@/components/InspectionChecklist'; import { ScaleSelector } from '@/components/ScaleSelector'; import { CloudLoader } from '@/components/CloudLoader'; import { ShareButton } from '@/components/ShareButton'; import { SceneModelList } from '@/components/SceneModelList'; import { toast } from 'sonner'; const POSITION_STEP = 0.001; const ROTATION_STEP = 0.1; interface XRHudProps { freeMove: boolean; onToggleFreeMove: () => void; placementMode?: boolean; onTogglePlacement?: () => void; snapToPlanes?: boolean; onToggleSnap?: () => void; allowScale?: boolean; onToggleAllowScale?: () => void; } const helpItems = [ { title: 'Grip (1 mão) — Pan', icon: '✊', desc: 'Aperte UM grip lateral e mova o controle: a peça é arrastada (translação) sem rotacionar. Solte para fixar.', }, { title: 'Grip (2 mãos) — Zoom + Orbit', icon: '🤲', desc: 'Aperte o grip dos DOIS controles. AFASTE/APROXIME as mãos para dar ZOOM. Gire os punhos em direções opostas para ORBITAR a peça pelo eixo entre as mãos.', }, { title: 'Trigger — Selecionar / Medir', icon: '🔫', desc: 'O gatilho NÃO move a peça. Ele só age dentro dos modos Selecionar, Medir ou Posicionar — escolhendo elementos, marcando pontos ou colocando o modelo na superfície.', }, { title: 'Thumbstick — Locomoção', icon: '🕹️', desc: 'Para FRENTE e solte: teletransporta para o ponto apontado. Para os LADOS: snap-rotate de ±30° na câmera. Para TRÁS: passo de 0,3 m no sentido oposto ao olhar.', }, { title: 'Posicionar (Hit-Test)', icon: '🎯', desc: 'Ative para reposicionar o modelo. Aponte o controle para uma superfície real e aperte o TRIGGER no retículo para fixar o modelo ali.', }, { title: 'Snap (Planos)', icon: '🧲', desc: 'Quando ON, o modelo se alinha automaticamente aos planos detectados (chão, parede, mesa). Retículo azul indica snap ativo.', }, { title: 'Grid', icon: '📐', desc: 'Exibe/oculta a grade de referência para alinhar o modelo com o ambiente.', }, { title: 'Sólido / Wire / Bordas', icon: '🔲', desc: 'Alterna modos de renderização: Sólido (preenchido), Wireframe (malha), Bordas (apenas contornos).', }, { title: 'Medir', icon: '📏', desc: 'Ative e toque o TRIGGER em dois pontos da peça para medir a distância em milímetros. O snap de vértice auxilia a precisão.', }, { title: 'Screenshot', icon: '📸', desc: 'Captura uma imagem da visão AR atual. As capturas ficam na galeria do viewer.', }, { title: 'Inspeção', icon: '📋', desc: 'Abre o checklist para aprovar ou rejeitar itens (dimensões, furos, soldas, posição das chapas).', }, { title: 'Opacidade', icon: '👁️', desc: 'Ajusta a transparência do modelo de 0% a 100% para ver através da peça.', }, { title: 'Ajuste fino (Posição/Rotação)', icon: '↔️', desc: 'Use os botões +/− do painel para ajustes finos em milímetros (posição) e décimos de grau (rotação). O joystick não faz mais ajuste fino — ele agora é só locomoção.', }, { title: 'Botões A/B (Touch Plus direito)', icon: '🎮', desc: 'No modo Medir: A = desfazer último ponto; B = limpar todas as medições. O botão Menu (esquerdo) abre o menu Universal do Quest.', }, ]; export function XRHud({ freeMove, onToggleFreeMove, placementMode = false, onTogglePlacement, snapToPlanes = true, onToggleSnap, allowScale = false, onToggleAllowScale }: XRHudProps) { const [expanded, setExpanded] = useState(false); const [checklistOpen, setChecklistOpen] = useState(false); const [helpOpen, setHelpOpen] = useState(false); const { opacity, setOpacity, renderMode, setRenderMode, showGrid, setShowGrid, measureMode, setMeasureMode, measurements, clearMeasurements, measurePoints, fineTuning, setFineTuning, resetFineTuning, addScreenshot, checklist, selectionMode, setSelectionMode, selectedElementKeys, hiddenElementKeys, isolatedElementKeys, hideSelectedElements, isolateSelectedElements, showAllElements, } = useModelStore(); const hasSelection = selectedElementKeys.size > 0; const hasHidden = hiddenElementKeys.size > 0 || isolatedElementKeys !== null; const approved = checklist.filter(i => i.status === 'approved').length; const rejected = checklist.filter(i => i.status === 'rejected').length; const total = checklist.length; const handleScreenshot = () => { const canvas = document.querySelector('canvas'); if (!canvas) return; const dataUrl = canvas.toDataURL('image/png'); addScreenshot(dataUrl); toast.success('Screenshot capturado!'); }; return ( <> {/* ── Slide-out checklist panel ── */}
{item.desc}