@ifc-lite/viewer 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +78 -0
- package/dist/assets/{Arrow.dom-BjDQoB2M.js → Arrow.dom-BGPQieQQ.js} +1 -1
- package/dist/assets/ifc-lite_bg-DyIN_nBM.wasm +0 -0
- package/dist/assets/{index-YBtrHPu3.js → index-dgdgiQ9p.js} +40212 -30008
- package/dist/assets/index-yTqs8kgX.css +1 -0
- package/dist/assets/{native-bridge-CULtTDX3.js → native-bridge-DD0SNyQ5.js} +1 -1
- package/dist/assets/{wasm-bridge-CjL-lSak.js → wasm-bridge-D54YMO7X.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +18 -15
- package/src/components/viewer/BCFPanel.tsx +7 -789
- package/src/components/viewer/Drawing2DCanvas.tsx +1048 -0
- package/src/components/viewer/DrawingSettingsPanel.tsx +3 -3
- package/src/components/viewer/HierarchyPanel.tsx +110 -842
- package/src/components/viewer/IDSExportDialog.tsx +281 -0
- package/src/components/viewer/IDSPanel.tsx +126 -17
- package/src/components/viewer/KeyboardShortcutsDialog.tsx +9 -0
- package/src/components/viewer/LensPanel.tsx +603 -0
- package/src/components/viewer/MainToolbar.tsx +188 -21
- package/src/components/viewer/PropertiesPanel.tsx +171 -663
- package/src/components/viewer/PropertyEditor.tsx +866 -77
- package/src/components/viewer/Section2DPanel.tsx +76 -2648
- package/src/components/viewer/ToolOverlays.tsx +3 -1097
- package/src/components/viewer/ViewerLayout.tsx +132 -45
- package/src/components/viewer/Viewport.tsx +237 -1659
- package/src/components/viewer/ViewportContainer.tsx +11 -3
- package/src/components/viewer/bcf/BCFCreateTopicForm.tsx +134 -0
- package/src/components/viewer/bcf/BCFTopicDetail.tsx +388 -0
- package/src/components/viewer/bcf/BCFTopicList.tsx +239 -0
- package/src/components/viewer/bcf/bcfHelpers.tsx +109 -0
- package/src/components/viewer/hierarchy/HierarchyNode.tsx +328 -0
- package/src/components/viewer/hierarchy/treeDataBuilder.ts +464 -0
- package/src/components/viewer/hierarchy/types.ts +54 -0
- package/src/components/viewer/hierarchy/useHierarchyTree.ts +280 -0
- package/src/components/viewer/lists/ListBuilder.tsx +486 -0
- package/src/components/viewer/lists/ListPanel.tsx +540 -0
- package/src/components/viewer/lists/ListResultsTable.tsx +193 -0
- package/src/components/viewer/properties/ClassificationCard.tsx +70 -0
- package/src/components/viewer/properties/CoordinateDisplay.tsx +49 -0
- package/src/components/viewer/properties/DocumentCard.tsx +89 -0
- package/src/components/viewer/properties/MaterialCard.tsx +201 -0
- package/src/components/viewer/properties/ModelMetadataPanel.tsx +335 -0
- package/src/components/viewer/properties/PropertySetCard.tsx +132 -0
- package/src/components/viewer/properties/QuantitySetCard.tsx +79 -0
- package/src/components/viewer/properties/RelationshipsCard.tsx +100 -0
- package/src/components/viewer/properties/encodingUtils.ts +29 -0
- package/src/components/viewer/tools/MeasurePanel.tsx +218 -0
- package/src/components/viewer/tools/MeasurementVisuals.tsx +644 -0
- package/src/components/viewer/tools/SectionPanel.tsx +183 -0
- package/src/components/viewer/tools/SectionVisualization.tsx +78 -0
- package/src/components/viewer/tools/formatDistance.ts +18 -0
- package/src/components/viewer/tools/sectionConstants.ts +14 -0
- package/src/components/viewer/useAnimationLoop.ts +166 -0
- package/src/components/viewer/useGeometryStreaming.ts +398 -0
- package/src/components/viewer/useKeyboardControls.ts +221 -0
- package/src/components/viewer/useMouseControls.ts +1009 -0
- package/src/components/viewer/useRenderUpdates.ts +165 -0
- package/src/components/viewer/useTouchControls.ts +245 -0
- package/src/hooks/ids/idsColorSystem.ts +125 -0
- package/src/hooks/ids/idsDataAccessor.ts +237 -0
- package/src/hooks/ids/idsExportService.ts +444 -0
- package/src/hooks/useBCF.ts +7 -0
- package/src/hooks/useDrawingExport.ts +627 -0
- package/src/hooks/useDrawingGeneration.ts +627 -0
- package/src/hooks/useFloorplanView.ts +108 -0
- package/src/hooks/useIDS.ts +270 -463
- package/src/hooks/useIfc.ts +26 -1628
- package/src/hooks/useIfcFederation.ts +803 -0
- package/src/hooks/useIfcLoader.ts +508 -0
- package/src/hooks/useIfcServer.ts +465 -0
- package/src/hooks/useKeyboardShortcuts.ts +1 -1
- package/src/hooks/useLens.ts +129 -0
- package/src/hooks/useMeasure2D.ts +365 -0
- package/src/hooks/useViewControls.ts +218 -0
- package/src/lib/ifc4-pset-definitions.test.ts +161 -0
- package/src/lib/ifc4-pset-definitions.ts +621 -0
- package/src/lib/ifc4-qto-definitions.ts +315 -0
- package/src/lib/lens/adapter.ts +138 -0
- package/src/lib/lens/index.ts +5 -0
- package/src/lib/lists/adapter.ts +69 -0
- package/src/lib/lists/index.ts +28 -0
- package/src/lib/lists/persistence.ts +64 -0
- package/src/services/fs-cache.ts +1 -1
- package/src/services/tauri-modules.d.ts +25 -0
- package/src/store/index.ts +38 -2
- package/src/store/slices/cameraSlice.ts +14 -1
- package/src/store/slices/dataSlice.ts +14 -1
- package/src/store/slices/lensSlice.ts +184 -0
- package/src/store/slices/listSlice.ts +74 -0
- package/src/store/slices/pinboardSlice.ts +114 -0
- package/src/store/types.ts +5 -0
- package/src/utils/ifcConfig.ts +16 -3
- package/src/utils/serverDataModel.ts +64 -101
- package/src/vite-env.d.ts +3 -0
- package/dist/assets/ifc-lite_bg-C6kblxf9.wasm +0 -0
- package/dist/assets/index-v3mcCUPN.css +0 -1
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
Eye,
|
|
16
16
|
EyeOff,
|
|
17
17
|
Focus,
|
|
18
|
+
Crosshair,
|
|
18
19
|
Home,
|
|
19
20
|
Maximize2,
|
|
20
21
|
Grid3x3,
|
|
@@ -35,6 +36,11 @@ import {
|
|
|
35
36
|
Plus,
|
|
36
37
|
MessageSquare,
|
|
37
38
|
ClipboardCheck,
|
|
39
|
+
Pin,
|
|
40
|
+
PinOff,
|
|
41
|
+
Palette,
|
|
42
|
+
Orbit,
|
|
43
|
+
Trash2,
|
|
38
44
|
} from 'lucide-react';
|
|
39
45
|
import { Button } from '@/components/ui/button';
|
|
40
46
|
import { Separator } from '@/components/ui/separator';
|
|
@@ -60,6 +66,7 @@ import { ExportDialog } from './ExportDialog';
|
|
|
60
66
|
import { BulkPropertyEditor } from './BulkPropertyEditor';
|
|
61
67
|
import { DataConnector } from './DataConnector';
|
|
62
68
|
import { ExportChangesButton } from './ExportChangesButton';
|
|
69
|
+
import { useFloorplanView } from '@/hooks/useFloorplanView';
|
|
63
70
|
|
|
64
71
|
type Tool = 'select' | 'pan' | 'orbit' | 'walk' | 'measure' | 'section';
|
|
65
72
|
|
|
@@ -141,6 +148,9 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
141
148
|
const addModelInputRef = useRef<HTMLInputElement>(null);
|
|
142
149
|
const { loadFile, loading, progress, geometryResult, ifcDataStore, models, clearAllModels, loadFilesSequentially, loadFederatedIfcx, addIfcxOverlays, addModel } = useIfc();
|
|
143
150
|
|
|
151
|
+
// Floorplan view
|
|
152
|
+
const { availableStoreys, activateFloorplan } = useFloorplanView();
|
|
153
|
+
|
|
144
154
|
// Check if we have models loaded (for showing add model button)
|
|
145
155
|
const hasModelsLoaded = models.size > 0 || (geometryResult?.meshes && geometryResult.meshes.length > 0);
|
|
146
156
|
const activeTool = useViewerStore((state) => state.activeTool);
|
|
@@ -163,7 +173,21 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
163
173
|
const toggleBcfPanel = useViewerStore((state) => state.toggleBcfPanel);
|
|
164
174
|
const idsPanelVisible = useViewerStore((state) => state.idsPanelVisible);
|
|
165
175
|
const toggleIdsPanel = useViewerStore((state) => state.toggleIdsPanel);
|
|
176
|
+
const listPanelVisible = useViewerStore((state) => state.listPanelVisible);
|
|
177
|
+
const toggleListPanel = useViewerStore((state) => state.toggleListPanel);
|
|
166
178
|
const setRightPanelCollapsed = useViewerStore((state) => state.setRightPanelCollapsed);
|
|
179
|
+
const projectionMode = useViewerStore((state) => state.projectionMode);
|
|
180
|
+
const toggleProjectionMode = useViewerStore((state) => state.toggleProjectionMode);
|
|
181
|
+
// Pinboard state
|
|
182
|
+
const pinboardEntities = useViewerStore((state) => state.pinboardEntities);
|
|
183
|
+
const addToPinboard = useViewerStore((state) => state.addToPinboard);
|
|
184
|
+
const removeFromPinboard = useViewerStore((state) => state.removeFromPinboard);
|
|
185
|
+
const showPinboard = useViewerStore((state) => state.showPinboard);
|
|
186
|
+
const clearPinboard = useViewerStore((state) => state.clearPinboard);
|
|
187
|
+
const selectedEntity = useViewerStore((state) => state.selectedEntity);
|
|
188
|
+
// Lens state
|
|
189
|
+
const lensPanelVisible = useViewerStore((state) => state.lensPanelVisible);
|
|
190
|
+
const toggleLensPanel = useViewerStore((state) => state.toggleLensPanel);
|
|
167
191
|
|
|
168
192
|
// Check which type geometries exist across ALL loaded models (federation-aware)
|
|
169
193
|
const typeGeometryExists = useMemo(() => {
|
|
@@ -387,7 +411,7 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
387
411
|
|
|
388
412
|
return (
|
|
389
413
|
<div className="flex items-center gap-1 px-2 h-12 border-b bg-white dark:bg-black border-zinc-200 dark:border-zinc-800 relative z-50">
|
|
390
|
-
{/* File Operations */}
|
|
414
|
+
{/* ── File Operations ── */}
|
|
391
415
|
<input
|
|
392
416
|
ref={fileInputRef}
|
|
393
417
|
type="file"
|
|
@@ -541,6 +565,7 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
541
565
|
{/* Export Changes Button - shows when there are pending mutations */}
|
|
542
566
|
<ExportChangesButton />
|
|
543
567
|
|
|
568
|
+
{/* ── Panels ── */}
|
|
544
569
|
{/* BCF Issues Button */}
|
|
545
570
|
<Tooltip>
|
|
546
571
|
<TooltipTrigger asChild>
|
|
@@ -585,9 +610,30 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
585
610
|
<TooltipContent>IDS Validation</TooltipContent>
|
|
586
611
|
</Tooltip>
|
|
587
612
|
|
|
613
|
+
{/* Lists Button */}
|
|
614
|
+
<Tooltip>
|
|
615
|
+
<TooltipTrigger asChild>
|
|
616
|
+
<Button
|
|
617
|
+
variant={listPanelVisible ? 'default' : 'ghost'}
|
|
618
|
+
size="icon-sm"
|
|
619
|
+
onClick={(e) => {
|
|
620
|
+
(e.currentTarget as HTMLButtonElement).blur();
|
|
621
|
+
if (!listPanelVisible) {
|
|
622
|
+
setRightPanelCollapsed(false);
|
|
623
|
+
}
|
|
624
|
+
toggleListPanel();
|
|
625
|
+
}}
|
|
626
|
+
className={cn(listPanelVisible && 'bg-primary text-primary-foreground')}
|
|
627
|
+
>
|
|
628
|
+
<FileSpreadsheet className="h-4 w-4" />
|
|
629
|
+
</Button>
|
|
630
|
+
</TooltipTrigger>
|
|
631
|
+
<TooltipContent>Lists</TooltipContent>
|
|
632
|
+
</Tooltip>
|
|
633
|
+
|
|
588
634
|
<Separator orientation="vertical" className="h-6 mx-1" />
|
|
589
635
|
|
|
590
|
-
{/* Navigation Tools */}
|
|
636
|
+
{/* ── Navigation Tools ── */}
|
|
591
637
|
<ToolButton tool="select" icon={MousePointer2} label="Select" shortcut="V" activeTool={activeTool} onToolChange={setActiveTool} />
|
|
592
638
|
<ToolButton tool="pan" icon={Hand} label="Pan" shortcut="P" activeTool={activeTool} onToolChange={setActiveTool} />
|
|
593
639
|
<ToolButton tool="orbit" icon={Rotate3d} label="Orbit" shortcut="O" activeTool={activeTool} onToolChange={setActiveTool} />
|
|
@@ -595,16 +641,52 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
595
641
|
|
|
596
642
|
<Separator orientation="vertical" className="h-6 mx-1" />
|
|
597
643
|
|
|
598
|
-
{/* Measurement & Section */}
|
|
644
|
+
{/* ── Measurement & Section ── */}
|
|
599
645
|
<ToolButton tool="measure" icon={Ruler} label="Measure" shortcut="M" activeTool={activeTool} onToolChange={setActiveTool} />
|
|
600
646
|
<ToolButton tool="section" icon={Scissors} label="Section" shortcut="X" activeTool={activeTool} onToolChange={setActiveTool} />
|
|
601
647
|
|
|
648
|
+
{/* Floorplan dropdown */}
|
|
649
|
+
{availableStoreys.length > 0 && (
|
|
650
|
+
<DropdownMenu>
|
|
651
|
+
<Tooltip>
|
|
652
|
+
<TooltipTrigger asChild>
|
|
653
|
+
<DropdownMenuTrigger asChild>
|
|
654
|
+
<Button variant="ghost" size="icon-sm">
|
|
655
|
+
<Building2 className="h-4 w-4" />
|
|
656
|
+
</Button>
|
|
657
|
+
</DropdownMenuTrigger>
|
|
658
|
+
</TooltipTrigger>
|
|
659
|
+
<TooltipContent>Quick Floorplan</TooltipContent>
|
|
660
|
+
</Tooltip>
|
|
661
|
+
<DropdownMenuContent>
|
|
662
|
+
{availableStoreys.map((storey) => (
|
|
663
|
+
<DropdownMenuItem
|
|
664
|
+
key={`${storey.modelId}-${storey.expressId}`}
|
|
665
|
+
onClick={() => activateFloorplan(storey)}
|
|
666
|
+
>
|
|
667
|
+
<Building2 className="h-4 w-4 mr-2" />
|
|
668
|
+
{storey.name}
|
|
669
|
+
<span className="ml-auto text-xs opacity-60">{storey.elevation.toFixed(1)}m</span>
|
|
670
|
+
</DropdownMenuItem>
|
|
671
|
+
))}
|
|
672
|
+
</DropdownMenuContent>
|
|
673
|
+
</DropdownMenu>
|
|
674
|
+
)}
|
|
675
|
+
|
|
602
676
|
<Separator orientation="vertical" className="h-6 mx-1" />
|
|
603
677
|
|
|
604
|
-
{/* Visibility */}
|
|
678
|
+
{/* ── Visibility & Filtering (all together) ── */}
|
|
605
679
|
<ActionButton icon={Focus} label="Isolate Selection" onClick={handleIsolate} shortcut="I" disabled={!selectedEntityId} />
|
|
606
680
|
<ActionButton icon={EyeOff} label="Hide Selection" onClick={handleHide} shortcut="Del" disabled={!selectedEntityId} />
|
|
607
681
|
<ActionButton icon={Eye} label="Show All (Reset Filters)" onClick={handleShowAll} shortcut="A" />
|
|
682
|
+
<ActionButton icon={Maximize2} label="Fit All" onClick={() => cameraCallbacks.fitAll?.()} shortcut="Z" />
|
|
683
|
+
<ActionButton
|
|
684
|
+
icon={Crosshair}
|
|
685
|
+
label="Frame Selection"
|
|
686
|
+
onClick={() => cameraCallbacks.frameSelection?.()}
|
|
687
|
+
shortcut="F"
|
|
688
|
+
disabled={!selectedEntityId}
|
|
689
|
+
/>
|
|
608
690
|
|
|
609
691
|
<DropdownMenu>
|
|
610
692
|
<Tooltip>
|
|
@@ -615,7 +697,7 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
615
697
|
</Button>
|
|
616
698
|
</DropdownMenuTrigger>
|
|
617
699
|
</TooltipTrigger>
|
|
618
|
-
<TooltipContent>
|
|
700
|
+
<TooltipContent>Class Visibility</TooltipContent>
|
|
619
701
|
</Tooltip>
|
|
620
702
|
<DropdownMenuContent>
|
|
621
703
|
{typeGeometryExists.spaces && (
|
|
@@ -648,16 +730,113 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
648
730
|
</DropdownMenuContent>
|
|
649
731
|
</DropdownMenu>
|
|
650
732
|
|
|
733
|
+
{/* Pinboard dropdown */}
|
|
734
|
+
<DropdownMenu>
|
|
735
|
+
<Tooltip>
|
|
736
|
+
<TooltipTrigger asChild>
|
|
737
|
+
<DropdownMenuTrigger asChild>
|
|
738
|
+
<Button
|
|
739
|
+
variant={pinboardEntities.size > 0 ? 'default' : 'ghost'}
|
|
740
|
+
size="icon-sm"
|
|
741
|
+
className={cn(pinboardEntities.size > 0 && 'bg-primary text-primary-foreground relative')}
|
|
742
|
+
>
|
|
743
|
+
<Pin className="h-4 w-4" />
|
|
744
|
+
{pinboardEntities.size > 0 && (
|
|
745
|
+
<span className="absolute -top-1 -right-1 bg-primary text-primary-foreground text-[9px] font-bold rounded-full min-w-[14px] h-[14px] flex items-center justify-center px-0.5 border border-background">
|
|
746
|
+
{pinboardEntities.size}
|
|
747
|
+
</span>
|
|
748
|
+
)}
|
|
749
|
+
</Button>
|
|
750
|
+
</DropdownMenuTrigger>
|
|
751
|
+
</TooltipTrigger>
|
|
752
|
+
<TooltipContent>Pinboard ({pinboardEntities.size})</TooltipContent>
|
|
753
|
+
</Tooltip>
|
|
754
|
+
<DropdownMenuContent>
|
|
755
|
+
<DropdownMenuItem
|
|
756
|
+
onClick={() => { if (selectedEntity) addToPinboard([selectedEntity]); }}
|
|
757
|
+
disabled={!selectedEntity}
|
|
758
|
+
>
|
|
759
|
+
<Pin className="h-4 w-4 mr-2" />
|
|
760
|
+
Pin Selection
|
|
761
|
+
</DropdownMenuItem>
|
|
762
|
+
<DropdownMenuItem
|
|
763
|
+
onClick={() => { if (selectedEntity) removeFromPinboard([selectedEntity]); }}
|
|
764
|
+
disabled={!selectedEntity}
|
|
765
|
+
>
|
|
766
|
+
<PinOff className="h-4 w-4 mr-2" />
|
|
767
|
+
Unpin Selection
|
|
768
|
+
</DropdownMenuItem>
|
|
769
|
+
<DropdownMenuSeparator />
|
|
770
|
+
<DropdownMenuItem
|
|
771
|
+
onClick={() => showPinboard()}
|
|
772
|
+
disabled={pinboardEntities.size === 0}
|
|
773
|
+
>
|
|
774
|
+
<Eye className="h-4 w-4 mr-2" />
|
|
775
|
+
Show Pinboard
|
|
776
|
+
</DropdownMenuItem>
|
|
777
|
+
<DropdownMenuItem
|
|
778
|
+
onClick={() => clearPinboard()}
|
|
779
|
+
disabled={pinboardEntities.size === 0}
|
|
780
|
+
>
|
|
781
|
+
<Trash2 className="h-4 w-4 mr-2" />
|
|
782
|
+
Clear Pinboard
|
|
783
|
+
</DropdownMenuItem>
|
|
784
|
+
</DropdownMenuContent>
|
|
785
|
+
</DropdownMenu>
|
|
786
|
+
|
|
787
|
+
{/* Lens (rule-based filtering) */}
|
|
788
|
+
<Tooltip>
|
|
789
|
+
<TooltipTrigger asChild>
|
|
790
|
+
<Button
|
|
791
|
+
variant={lensPanelVisible ? 'default' : 'ghost'}
|
|
792
|
+
size="icon-sm"
|
|
793
|
+
onClick={(e) => {
|
|
794
|
+
(e.currentTarget as HTMLButtonElement).blur();
|
|
795
|
+
if (!lensPanelVisible) {
|
|
796
|
+
setRightPanelCollapsed(false);
|
|
797
|
+
}
|
|
798
|
+
toggleLensPanel();
|
|
799
|
+
}}
|
|
800
|
+
className={cn(lensPanelVisible && 'bg-primary text-primary-foreground')}
|
|
801
|
+
>
|
|
802
|
+
<Palette className="h-4 w-4" />
|
|
803
|
+
</Button>
|
|
804
|
+
</TooltipTrigger>
|
|
805
|
+
<TooltipContent>Lens (Color Rules)</TooltipContent>
|
|
806
|
+
</Tooltip>
|
|
807
|
+
|
|
651
808
|
<Separator orientation="vertical" className="h-6 mx-1" />
|
|
652
809
|
|
|
653
|
-
{/*
|
|
810
|
+
{/* ── Camera & View ── */}
|
|
811
|
+
<ActionButton icon={Home} label="Home (Isometric)" onClick={() => cameraCallbacks.home?.()} shortcut="H" />
|
|
812
|
+
|
|
813
|
+
{/* Orthographic / Perspective toggle */}
|
|
814
|
+
<Tooltip>
|
|
815
|
+
<TooltipTrigger asChild>
|
|
816
|
+
<Button
|
|
817
|
+
variant={projectionMode === 'orthographic' ? 'default' : 'ghost'}
|
|
818
|
+
size="icon-sm"
|
|
819
|
+
onClick={(e) => {
|
|
820
|
+
(e.currentTarget as HTMLButtonElement).blur();
|
|
821
|
+
toggleProjectionMode();
|
|
822
|
+
}}
|
|
823
|
+
className={cn(projectionMode === 'orthographic' && 'bg-primary text-primary-foreground')}
|
|
824
|
+
>
|
|
825
|
+
<Orbit className="h-4 w-4" />
|
|
826
|
+
</Button>
|
|
827
|
+
</TooltipTrigger>
|
|
828
|
+
<TooltipContent>
|
|
829
|
+
{projectionMode === 'orthographic' ? 'Switch to Perspective' : 'Switch to Orthographic'}
|
|
830
|
+
</TooltipContent>
|
|
831
|
+
</Tooltip>
|
|
832
|
+
|
|
833
|
+
{/* Hover Tooltips toggle */}
|
|
654
834
|
<Tooltip>
|
|
655
835
|
<TooltipTrigger asChild>
|
|
656
836
|
<Button
|
|
657
837
|
variant={hoverTooltipsEnabled ? 'default' : 'ghost'}
|
|
658
838
|
size="icon-sm"
|
|
659
839
|
onClick={(e) => {
|
|
660
|
-
// Blur button to close tooltip after click
|
|
661
840
|
(e.currentTarget as HTMLButtonElement).blur();
|
|
662
841
|
toggleHoverTooltips();
|
|
663
842
|
}}
|
|
@@ -671,19 +850,7 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
671
850
|
</TooltipContent>
|
|
672
851
|
</Tooltip>
|
|
673
852
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
{/* Camera */}
|
|
677
|
-
<ActionButton icon={Home} label="Home (Isometric)" onClick={() => cameraCallbacks.home?.()} shortcut="H" />
|
|
678
|
-
<ActionButton icon={Maximize2} label="Fit All" onClick={() => cameraCallbacks.fitAll?.()} shortcut="Z" />
|
|
679
|
-
<ActionButton
|
|
680
|
-
icon={Focus}
|
|
681
|
-
label="Frame Selection"
|
|
682
|
-
onClick={() => cameraCallbacks.frameSelection?.()}
|
|
683
|
-
shortcut="F"
|
|
684
|
-
disabled={!selectedEntityId}
|
|
685
|
-
/>
|
|
686
|
-
|
|
853
|
+
{/* Preset Views dropdown */}
|
|
687
854
|
<DropdownMenu>
|
|
688
855
|
<Tooltip>
|
|
689
856
|
<TooltipTrigger asChild>
|
|
@@ -693,7 +860,7 @@ export function MainToolbar({ onShowShortcuts }: MainToolbarProps = {} as MainTo
|
|
|
693
860
|
</Button>
|
|
694
861
|
</DropdownMenuTrigger>
|
|
695
862
|
</TooltipTrigger>
|
|
696
|
-
<TooltipContent>Preset Views
|
|
863
|
+
<TooltipContent>Preset Views</TooltipContent>
|
|
697
864
|
</Tooltip>
|
|
698
865
|
<DropdownMenuContent>
|
|
699
866
|
<DropdownMenuItem onClick={() => cameraCallbacks.home?.()}>
|