import { WheelEvent, useRef, useMemo } from 'react' import { isCursorInSketchCommandRange } from 'lang/util' import { engineCommandManager } from './lang/std/engineConnection' import { useModelingContext } from 'hooks/useModelingContext' import { useCommandsContext } from 'hooks/useCommandsContext' import { ActionButton } from 'components/ActionButton' export const Toolbar = () => { const { setCommandBarOpen } = useCommandsContext() const { state, send, context } = useModelingContext() const toolbarButtonsRef = useRef(null) const bgClassName = 'group-enabled:group-hover:bg-energy-10 group-pressed:bg-energy-10 dark:group-enabled:group-hover:bg-chalkboard-80 dark:group-pressed:bg-chalkboard-80' const pathId = useMemo( () => isCursorInSketchCommandRange( engineCommandManager.artifactMap, context.selectionRanges ), [engineCommandManager.artifactMap, context.selectionRanges] ) function handleToolbarButtonsWheelEvent(ev: WheelEvent) { const span = toolbarButtonsRef.current if (!span) { return } span.scrollLeft = span.scrollLeft += ev.deltaY } function ToolbarButtons({ className = '', ...props }: React.HTMLAttributes) { return (
    {state.nextEvents.includes('Enter sketch') && (
  • send({ type: 'Enter sketch' })} icon={{ icon: 'sketch', bgClassName, }} > Start Sketch
  • )} {state.nextEvents.includes('Enter sketch') && pathId && (
  • send({ type: 'Enter sketch' })} icon={{ icon: 'sketch', bgClassName, }} > Edit Sketch
  • )} {state.nextEvents.includes('Cancel') && !state.matches('idle') && (
  • send({ type: 'Cancel' })} icon={{ icon: 'arrowLeft', bgClassName, }} > Exit Sketch
  • )} {state.matches('Sketch') && !state.matches('idle') && (
  • state.matches('Sketch.Line Tool') ? send('CancelSketch') : send('Equip tool') } aria-pressed={state.matches('Sketch.Line Tool')} className="pressed:bg-energy-10/20 dark:pressed:bg-energy-80" icon={{ icon: 'line', bgClassName, }} > Line
  • )} {state.matches('Sketch') && (
  • state.matches('Sketch.Move Tool') ? send('CancelSketch') : send('Equip move tool') } aria-pressed={state.matches('Sketch.Move Tool')} className="pressed:bg-energy-10/20 dark:pressed:bg-energy-80" icon={{ icon: 'move', bgClassName, }} > Move
  • )} {state.matches('Sketch.SketchIdle') && state.nextEvents .filter( (eventName) => eventName.includes('Make segment') || eventName.includes('Constrain') ) .sort((a, b) => { const aisEnabled = state.nextEvents .filter((event) => state.can(event as any)) .includes(a) const bIsEnabled = state.nextEvents .filter((event) => state.can(event as any)) .includes(b) if (aisEnabled && !bIsEnabled) { return -1 } if (!aisEnabled && bIsEnabled) { return 1 } return 0 }) .map((eventName) => (
  • send(eventName)} disabled={ !state.nextEvents .filter((event) => state.can(event as any)) .includes(eventName) } title={eventName} icon={{ icon: 'line', bgClassName, }} > {eventName .replace('Make segment ', '') .replace('Constrain ', '')}
  • ))} {state.matches('idle') && (
  • send('extrude intent')} disabled={!state.can('extrude intent')} title={ state.can('extrude intent') ? 'extrude' : 'sketches need to be closed, or not already extruded' } icon={{ icon: 'extrude', bgClassName, }} > Extrude
  • )}
) } return (
setCommandBarOpen(true)} className="rounded-r-full pr-4 self-stretch border-energy-10 hover:border-energy-10 dark:border-chalkboard-80 bg-energy-10/50 hover:bg-energy-10 dark:bg-chalkboard-80 dark:text-energy-10" > ⌘K
) }