@@ -21,6 +21,7 @@ import { useClipboardStore } from '@/stores/clipboard-store';
2121import { geometryRedo , geometryUndo } from '@/stores/geometry-store' ;
2222import { useRegisterShortcuts } from '@/components/shortcut-provider' ;
2323import { Euler , Matrix4 , Quaternion , Vector3 } from 'three/webgpu' ;
24+ import AddObjectMenu from '@/features/shared/add-object-menu' ;
2425
2526type Props = { onOpenShaderEditor ?: ( ) => void } ;
2627const MenuBar : React . FC < Props > = ( { onOpenShaderEditor } ) => {
@@ -58,7 +59,7 @@ const MenuBar: React.FC<Props> = ({ onOpenShaderEditor }) => {
5859 } ;
5960 } , [ ] ) ;
6061
61- const buildWorkspaceData = useCallback ( ( ) : WorkspaceData => ( {
62+ const buildWorkspaceData = useCallback ( ( ) : WorkspaceData => ( {
6263 meshes : Array . from ( geometryStore . meshes . values ( ) ) ,
6364 materials : Array . from ( geometryStore . materials . values ( ) ) ,
6465 objects : Object . values ( sceneStore . objects ) ,
@@ -72,8 +73,8 @@ const MenuBar: React.FC<Props> = ({ onOpenShaderEditor }) => {
7273 backgroundColor : viewportStore . backgroundColor ,
7374 } ,
7475 selectedObjectId : sceneStore . selectedObjectId ,
75- lights : sceneStore . lights ,
76- cameras : geometryStore . cameras ,
76+ lights : sceneStore . lights ,
77+ cameras : geometryStore . cameras ,
7778 } ) , [ geometryStore , sceneStore , viewportStore ] ) ;
7879
7980 // Save (T3D) with existing handle when possible
@@ -377,78 +378,15 @@ const MenuBar: React.FC<Props> = ({ onOpenShaderEditor }) => {
377378 </ Menu . Portal >
378379 </ Menu . Root >
379380
380- { /* Add */ }
381- < Menu . Root modal = { false } openOnHover >
382- < Menu . Trigger className = "px-2 py-1 text-xs rounded text-gray-300 hover:text-white hover:bg-white/5 data-[open]:bg-white/10 data-[open]:text-white" >
383- Add
384- </ Menu . Trigger >
385- < Menu . Portal container = { portalContainer } >
386- < Menu . Positioner side = "bottom" align = "start" sideOffset = { 4 } className = "z-90" >
387- < Menu . Popup className = "mt-0 min-w-48 rounded border border-white/10 bg-[#0b0e13]/95 shadow-lg py-1 text-xs z-90" style = { { zIndex : 10050 } } >
388- { /* Quick */ }
389- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { handleCreateParticleSystem } > Particle System</ Menu . Item >
390- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { handleCreateFluidSystem } > Fluid System</ Menu . Item >
391- < Menu . Separator className = "my-1 h-px bg-white/10" />
392- { /* Mesh submenu */ }
393- < Menu . SubmenuRoot >
394- < Menu . SubmenuTrigger className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" > Mesh</ Menu . SubmenuTrigger >
395- < Menu . Portal container = { portalContainer } >
396- < Menu . Positioner sideOffset = { 6 } className = "z-90" >
397- < Menu . Popup className = "min-w-44 rounded border border-white/10 bg-[#0b0e13]/95 shadow-lg py-1 text-xs z-90" style = { { zIndex : 10050 } } >
398- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => beginShape ( 'cube' ) } > Cube</ Menu . Item >
399- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => beginShape ( 'plane' ) } > Plane</ Menu . Item >
400- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => beginShape ( 'cylinder' ) } > Cylinder</ Menu . Item >
401- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => beginShape ( 'cone' ) } > Cone</ Menu . Item >
402- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => beginShape ( 'uvsphere' ) } > UV Sphere</ Menu . Item >
403- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => beginShape ( 'icosphere' ) } > Ico Sphere</ Menu . Item >
404- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => beginShape ( 'torus' ) } > Torus</ Menu . Item >
405- </ Menu . Popup >
406- </ Menu . Positioner >
407- </ Menu . Portal >
408- </ Menu . SubmenuRoot >
409- { /* Light submenu */ }
410- < Menu . SubmenuRoot >
411- < Menu . SubmenuTrigger className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" > Light</ Menu . SubmenuTrigger >
412- < Menu . Portal container = { portalContainer } >
413- < Menu . Positioner sideOffset = { 6 } className = "z-90" >
414- < Menu . Popup className = "min-w-44 rounded border border-white/10 bg-[#0b0e13]/95 shadow-lg py-1 text-xs z-90" style = { { zIndex : 10050 } } >
415- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => addLight ( 'directional' ) } > Directional</ Menu . Item >
416- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => addLight ( 'spot' ) } > Spot</ Menu . Item >
417- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => addLight ( 'point' ) } > Point</ Menu . Item >
418- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => addLight ( 'ambient' ) } > Ambient</ Menu . Item >
419- </ Menu . Popup >
420- </ Menu . Positioner >
421- </ Menu . Portal >
422- </ Menu . SubmenuRoot >
423- { /* Camera submenu */ }
424- < Menu . SubmenuRoot >
425- < Menu . SubmenuTrigger className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" > Camera</ Menu . SubmenuTrigger >
426- < Menu . Portal container = { portalContainer } >
427- < Menu . Positioner sideOffset = { 6 } className = "z-90" >
428- < Menu . Popup className = "min-w-44 rounded border border-white/10 bg-[#0b0e13]/95 shadow-lg py-1 text-xs z-90" style = { { zIndex : 10050 } } >
429- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => addCamera ( 'perspective' ) } > Perspective</ Menu . Item >
430- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => addCamera ( 'orthographic' ) } > Orthographic</ Menu . Item >
431- </ Menu . Popup >
432- </ Menu . Positioner >
433- </ Menu . Portal >
434- </ Menu . SubmenuRoot >
435- { /* Force Field submenu */ }
436- < Menu . SubmenuRoot >
437- < Menu . SubmenuTrigger className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" > Force Field</ Menu . SubmenuTrigger >
438- < Menu . Portal container = { portalContainer } >
439- < Menu . Positioner sideOffset = { 6 } className = "z-90" >
440- < Menu . Popup className = "min-w-44 rounded border border-white/10 bg-[#0b0e13]/95 shadow-lg py-1 text-xs z-90" style = { { zIndex : 10050 } } >
441- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => addForce ( 'attractor' ) } > Attractor</ Menu . Item >
442- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => addForce ( 'repulsor' ) } > Repulsor</ Menu . Item >
443- < Menu . Item className = "w-full text-left px-3 py-1.5 hover:bg-white/10 text-gray-200" onClick = { ( ) => addForce ( 'vortex' ) } > Vortex</ Menu . Item >
444- </ Menu . Popup >
445- </ Menu . Positioner >
446- </ Menu . Portal >
447- </ Menu . SubmenuRoot >
448- </ Menu . Popup >
449- </ Menu . Positioner >
450- </ Menu . Portal >
451- </ Menu . Root >
381+ < AddObjectMenu
382+ portalContainer = { portalContainer }
383+ onCreateShape = { beginShape }
384+ onAddLight = { addLight }
385+ onAddCamera = { addCamera }
386+ onAddForce = { addForce }
387+ onAddParticleSystem = { handleCreateParticleSystem }
388+ onAddFluidSystem = { handleCreateFluidSystem }
389+ />
452390
453391 { /* View (placeholders) */ }
454392 < Menu . Root modal = { false } openOnHover >
0 commit comments