67 lines
1.7 KiB
TypeScript
67 lines
1.7 KiB
TypeScript
![]() |
import { reportRejection } from 'lib/trap'
|
||
|
import {
|
||
|
ContextMenu,
|
||
|
ContextMenuDivider,
|
||
|
ContextMenuItem,
|
||
|
ContextMenuItemRefresh,
|
||
|
ContextMenuProps,
|
||
|
} from './ContextMenu'
|
||
|
import { AxisNames, VIEW_NAMES_SEMANTIC } from 'lib/constants'
|
||
|
import { useModelingContext } from 'hooks/useModelingContext'
|
||
|
import { useMemo } from 'react'
|
||
|
import { sceneInfra } from 'lib/singletons'
|
||
|
|
||
|
export function useViewControlMenuItems() {
|
||
|
const { send: modelingSend } = useModelingContext()
|
||
|
const menuItems = useMemo(
|
||
|
() => [
|
||
|
...Object.entries(VIEW_NAMES_SEMANTIC).map(([axisName, axisSemantic]) => (
|
||
|
<ContextMenuItem
|
||
|
key={axisName}
|
||
|
onClick={() => {
|
||
|
sceneInfra.camControls
|
||
|
.updateCameraToAxis(axisName as AxisNames)
|
||
|
.catch(reportRejection)
|
||
|
}}
|
||
|
>
|
||
|
{axisSemantic} view
|
||
|
</ContextMenuItem>
|
||
|
)),
|
||
|
<ContextMenuDivider />,
|
||
|
<ContextMenuItem
|
||
|
onClick={() => {
|
||
|
sceneInfra.camControls.resetCameraPosition().catch(reportRejection)
|
||
|
}}
|
||
|
>
|
||
|
Reset view
|
||
|
</ContextMenuItem>,
|
||
|
<ContextMenuItem
|
||
|
onClick={() => {
|
||
|
modelingSend({ type: 'Center camera on selection' })
|
||
|
}}
|
||
|
>
|
||
|
Center view on selection
|
||
|
</ContextMenuItem>,
|
||
|
<ContextMenuDivider />,
|
||
|
<ContextMenuItemRefresh />,
|
||
|
],
|
||
|
[VIEW_NAMES_SEMANTIC]
|
||
|
)
|
||
|
return menuItems
|
||
|
}
|
||
|
|
||
|
export function ViewControlContextMenu({
|
||
|
menuTargetElement: wrapperRef,
|
||
|
...props
|
||
|
}: ContextMenuProps) {
|
||
|
const menuItems = useViewControlMenuItems()
|
||
|
return (
|
||
|
<ContextMenu
|
||
|
data-testid="view-controls-menu"
|
||
|
menuTargetElement={wrapperRef}
|
||
|
items={menuItems}
|
||
|
{...props}
|
||
|
/>
|
||
|
)
|
||
|
}
|