Add a user-level projection setting, command, and toggle (#3983)

* Add cameraProjection setting

* Add UI to toggle the user-level projection setting.

* Make cameraProjection setting respected at startup

* Add an E2E test for the perspective toggle

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* A snapshot a day keeps the bugs away! 📷🐛 (OS: windows-latest)

* Don't force user back into perspective when exiting sketch

* Make the projection setting more searchable

* Make `current` label apply to the default option if not set

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* Re-run CI

* Ohh *cargo fmt*

* @lf94 feedback, fix found toggling bug, make command bar instantly toggle setting

* Roll back the instant toggling behavior, it breaks the tests

* Make ortho the default, keep tests using perspective

* Move projection below camera controls setting

* Fix up gizmo tests, which broke because the gizmo moved

* A snapshot a day keeps the bugs away! 📷🐛 (OS: ubuntu-latest)

* Look at this (photo)Graph *in the voice of Nickelback*

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: 49fl <ircsurfer33@gmail.com>
This commit is contained in:
Frank Noirot
2024-09-30 11:40:00 -04:00
committed by GitHub
parent 3949b6acf4
commit 2e72f235dd
55 changed files with 315 additions and 20 deletions

View File

@ -0,0 +1,59 @@
import { Switch } from '@headlessui/react'
import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext'
import { useEffect, useState } from 'react'
export function CameraProjectionToggle() {
const { settings } = useSettingsAuthContext()
const isCameraProjectionPerspective =
settings.context.modeling.cameraProjection.current === 'perspective'
const [checked, setChecked] = useState(isCameraProjectionPerspective)
useEffect(() => {
setChecked(
settings.context.modeling.cameraProjection.current === 'perspective'
)
}, [settings.context.modeling.cameraProjection.current])
return (
<Switch
checked={checked}
onChange={(newValue) => {
settings.send({
type: 'set.modeling.cameraProjection',
data: {
level: 'user',
value: newValue ? 'perspective' : 'orthographic',
},
})
}}
className={`pointer-events-auto p-0 text-xs text-chalkboard-60 dark:text-chalkboard-40 bg-chalkboard-10/70 hover:bg-chalkboard-10 dark:bg-chalkboard-100/80 dark:hover:bg-chalkboard-100 backdrop-blur-sm
border border-primary/10 hover:border-primary/50 focus-visible:border-primary/50 rounded-full`}
>
<span className="sr-only">Camera projection: </span>
<div className="flex items-center gap-2">
<span
aria-hidden={checked}
className={
'border border-solid m-[-1px] rounded-full px-2 py-1 ' +
(!checked
? 'text-primary border-primary -mr-2'
: 'border-transparent')
}
>
Orthographic
</span>
<span
aria-hidden={checked}
className={
'border border-solid m-[-1px] rounded-full px-2 py-1 ' +
(checked
? 'text-primary border-primary -ml-2'
: 'border-transparent')
}
>
Perspective
</span>
</div>
</Switch>
)
}

View File

@ -22,6 +22,7 @@ function CommandComboBox({
const fuse = new Fuse(options, {
keys: ['displayName', 'name', 'description'],
threshold: 0.3,
ignoreLocation: true,
})
useEffect(() => {

View File

@ -104,7 +104,12 @@ export const ModelingMachineProvider = ({
settings: {
context: {
app: { theme, enableSSAO },
modeling: { defaultUnit, highlightEdges, showScaleGrid },
modeling: {
defaultUnit,
cameraProjection,
highlightEdges,
showScaleGrid,
},
},
},
} = useSettingsAuthContext()
@ -145,7 +150,9 @@ export const ModelingMachineProvider = ({
;(async () => {
sceneInfra.camControls.syncDirection = 'clientToEngine'
await sceneInfra.camControls.snapToPerspectiveBeforeHandingBackControlToEngine()
if (cameraProjection.current === 'perspective') {
await sceneInfra.camControls.snapToPerspectiveBeforeHandingBackControlToEngine()
}
sceneInfra.camControls.syncDirection = 'engineToClient'
@ -974,6 +981,7 @@ export const ModelingMachineProvider = ({
highlightEdges: highlightEdges.current,
enableSSAO: enableSSAO.current,
showScaleGrid: showScaleGrid.current,
cameraProjection: cameraProjection.current,
},
token
)