Extensions can now use studio's project for editing-related objects.
This commit is contained in:
parent
828fbb97b5
commit
b08588e9d6
4 changed files with 91 additions and 104 deletions
|
@ -9,8 +9,7 @@ import studio, {ToolbarIconButton} from '@theatre/studio'
|
|||
import {useVal} from '@theatre/dataverse-react'
|
||||
import styled, {createGlobalStyle, StyleSheetManager} from 'styled-components'
|
||||
import {IoCameraReverseOutline} from 'react-icons/all'
|
||||
import type {ISheetObject, ISheet} from '@theatre/core'
|
||||
import type {$FixMe} from '../types'
|
||||
import type {ISheet} from '@theatre/core'
|
||||
import useSnapshotEditorCamera from './useSnapshotEditorCamera'
|
||||
|
||||
const GlobalStyle = createGlobalStyle`
|
||||
|
@ -95,87 +94,86 @@ const Tools = styled.div`
|
|||
pointer-events: auto;
|
||||
`
|
||||
|
||||
const SnapshotEditor: React.FC<{object: ISheetObject<$FixMe>; paneId: string}> =
|
||||
(props) => {
|
||||
const snapshotEditorSheet = props.object.sheet
|
||||
const paneId = props.paneId
|
||||
const SnapshotEditor: React.FC<{paneId: string}> = (props) => {
|
||||
const snapshotEditorSheet = studio.getStudioProject().sheet('Plugin-R3F')
|
||||
const paneId = props.paneId
|
||||
|
||||
const [editorObject, sceneSnapshot, createSnapshot, sheet] = useEditorStore(
|
||||
(state) => [
|
||||
state.editorObject,
|
||||
state.sceneSnapshot,
|
||||
state.createSnapshot,
|
||||
state.sheet,
|
||||
],
|
||||
shallow,
|
||||
)
|
||||
const [editorObject, sceneSnapshot, createSnapshot, sheet] = useEditorStore(
|
||||
(state) => [
|
||||
state.editorObject,
|
||||
state.sceneSnapshot,
|
||||
state.createSnapshot,
|
||||
state.sheet,
|
||||
],
|
||||
shallow,
|
||||
)
|
||||
|
||||
const editorOpen = true
|
||||
useLayoutEffect(() => {
|
||||
let timeout: NodeJS.Timeout | undefined
|
||||
if (editorOpen) {
|
||||
// a hack to make sure all the scene's props are
|
||||
// applied before we take a snapshot
|
||||
timeout = setTimeout(createSnapshot, 100)
|
||||
const editorOpen = true
|
||||
useLayoutEffect(() => {
|
||||
let timeout: NodeJS.Timeout | undefined
|
||||
if (editorOpen) {
|
||||
// a hack to make sure all the scene's props are
|
||||
// applied before we take a snapshot
|
||||
timeout = setTimeout(createSnapshot, 100)
|
||||
}
|
||||
return () => {
|
||||
if (timeout !== undefined) {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
return () => {
|
||||
if (timeout !== undefined) {
|
||||
clearTimeout(timeout)
|
||||
}
|
||||
}
|
||||
}, [editorOpen])
|
||||
}
|
||||
}, [editorOpen])
|
||||
|
||||
const onPointerMissed = useCallback(() => {
|
||||
if (sheet !== null) studio.__experimental_setSelection([sheet])
|
||||
}, [sheet])
|
||||
const onPointerMissed = useCallback(() => {
|
||||
if (sheet !== null) studio.__experimental_setSelection([sheet])
|
||||
}, [sheet])
|
||||
|
||||
if (!editorObject) return <></>
|
||||
if (!editorObject) return <></>
|
||||
|
||||
return (
|
||||
<root.div>
|
||||
<StyleSheetManager disableVendorPrefixes>
|
||||
<>
|
||||
<GlobalStyle />
|
||||
<Wrapper>
|
||||
<Overlay>
|
||||
<Tools>
|
||||
<ToolbarIconButton
|
||||
icon={<IoCameraReverseOutline />}
|
||||
label="Refresh Snapshot"
|
||||
onClick={createSnapshot}
|
||||
></ToolbarIconButton>
|
||||
</Tools>
|
||||
</Overlay>
|
||||
return (
|
||||
<root.div>
|
||||
<StyleSheetManager disableVendorPrefixes>
|
||||
<>
|
||||
<GlobalStyle />
|
||||
<Wrapper>
|
||||
<Overlay>
|
||||
<Tools>
|
||||
<ToolbarIconButton
|
||||
icon={<IoCameraReverseOutline />}
|
||||
label="Refresh Snapshot"
|
||||
onClick={createSnapshot}
|
||||
></ToolbarIconButton>
|
||||
</Tools>
|
||||
</Overlay>
|
||||
|
||||
{sceneSnapshot ? (
|
||||
<>
|
||||
<CanvasWrapper>
|
||||
<Canvas
|
||||
// @ts-ignore
|
||||
colorManagement
|
||||
onCreated={({gl}) => {
|
||||
gl.setClearColor('white')
|
||||
}}
|
||||
shadowMap
|
||||
dpr={[1, 2]}
|
||||
fog={'red'}
|
||||
frameloop="demand"
|
||||
onPointerMissed={onPointerMissed}
|
||||
>
|
||||
<EditorScene
|
||||
snapshotEditorSheet={snapshotEditorSheet}
|
||||
paneId={paneId}
|
||||
/>
|
||||
</Canvas>
|
||||
</CanvasWrapper>
|
||||
</>
|
||||
) : null}
|
||||
</Wrapper>
|
||||
{/* </PortalContext.Provider> */}
|
||||
</>
|
||||
</StyleSheetManager>
|
||||
</root.div>
|
||||
)
|
||||
}
|
||||
{sceneSnapshot ? (
|
||||
<>
|
||||
<CanvasWrapper>
|
||||
<Canvas
|
||||
// @ts-ignore
|
||||
colorManagement
|
||||
onCreated={({gl}) => {
|
||||
gl.setClearColor('white')
|
||||
}}
|
||||
shadowMap
|
||||
dpr={[1, 2]}
|
||||
fog={'red'}
|
||||
frameloop="demand"
|
||||
onPointerMissed={onPointerMissed}
|
||||
>
|
||||
<EditorScene
|
||||
snapshotEditorSheet={snapshotEditorSheet}
|
||||
paneId={paneId}
|
||||
/>
|
||||
</Canvas>
|
||||
</CanvasWrapper>
|
||||
</>
|
||||
) : null}
|
||||
</Wrapper>
|
||||
{/* </PortalContext.Provider> */}
|
||||
</>
|
||||
</StyleSheetManager>
|
||||
</root.div>
|
||||
)
|
||||
}
|
||||
|
||||
export default SnapshotEditor
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import {prism, val} from '@theatre/dataverse'
|
||||
import {emptyArray} from '@theatre/shared/utils'
|
||||
import SimpleCache from '@theatre/shared/utils/SimpleCache'
|
||||
import type {$FixMe, $IntentionalAny} from '@theatre/shared/utils/types'
|
||||
import type {$IntentionalAny} from '@theatre/shared/utils/types'
|
||||
import type {Studio} from './Studio'
|
||||
import type {PaneInstance} from './TheatreStudio'
|
||||
|
||||
|
@ -43,20 +43,9 @@ export default class PaneManager {
|
|||
const instance = prism.memo(
|
||||
`instance-${instanceDescriptor!.instanceId}`,
|
||||
() => {
|
||||
const object = this._studio
|
||||
.getExtensionSheet(extensionId, core)
|
||||
.object(
|
||||
'Pane: ' + instanceId,
|
||||
null,
|
||||
core.types.compound({
|
||||
panelThingy: core.types.boolean(false),
|
||||
}),
|
||||
) as $FixMe
|
||||
|
||||
const inst: PaneInstance<$IntentionalAny> = {
|
||||
extensionId,
|
||||
instanceId,
|
||||
object,
|
||||
definition,
|
||||
}
|
||||
return inst
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type {ISheet, ISheetObject} from '@theatre/core'
|
||||
import type {IProject, ISheet, ISheetObject} from '@theatre/core'
|
||||
import studioTicker from '@theatre/studio/studioTicker'
|
||||
import type {IDerivation, Pointer} from '@theatre/dataverse'
|
||||
import {prism} from '@theatre/dataverse'
|
||||
|
@ -15,10 +15,7 @@ import {getOutlineSelection} from './selectors'
|
|||
import type SheetObject from '@theatre/core/sheetObjects/SheetObject'
|
||||
import getStudio from './getStudio'
|
||||
import type React from 'react'
|
||||
import type {
|
||||
PropTypeConfig_Boolean,
|
||||
PropTypeConfig_Compound,
|
||||
} from '@theatre/core/propTypes'
|
||||
import type {PropTypeConfig_Compound} from '@theatre/core/propTypes'
|
||||
import {debounce} from 'lodash-es'
|
||||
|
||||
export interface ITransactionAPI {
|
||||
|
@ -33,12 +30,6 @@ export interface PaneClassDefinition<
|
|||
dataType: DataType
|
||||
component: React.ComponentType<{
|
||||
paneId: string
|
||||
object: ISheetObject<
|
||||
PropTypeConfig_Compound<{
|
||||
visible: PropTypeConfig_Boolean
|
||||
data: DataType
|
||||
}>
|
||||
>
|
||||
}>
|
||||
}
|
||||
|
||||
|
@ -53,9 +44,6 @@ export type IExtension = {
|
|||
export type PaneInstance<ClassName extends string> = {
|
||||
extensionId: string
|
||||
instanceId: string
|
||||
object: ISheetObject<
|
||||
PropTypeConfig_Compound<{data: $FixMe; visible: PropTypeConfig_Boolean}>
|
||||
>
|
||||
definition: PaneClassDefinition<$FixMe>
|
||||
}
|
||||
|
||||
|
@ -87,6 +75,8 @@ export interface IStudio {
|
|||
createPane<PaneClass extends string>(
|
||||
paneClass: PaneClass,
|
||||
): PaneInstance<PaneClass>
|
||||
|
||||
getStudioProject(): IProject
|
||||
}
|
||||
|
||||
export default class TheatreStudio implements IStudio {
|
||||
|
@ -163,6 +153,16 @@ export default class TheatreStudio implements IStudio {
|
|||
return getStudio().scrub()
|
||||
}
|
||||
|
||||
getStudioProject() {
|
||||
const core = getStudio().core
|
||||
if (!core) {
|
||||
throw new Error(`You're calling studio.getStudioProject() before \`@theatre/core\` is loaded. To fix this:
|
||||
1. Check if \`@theatre/core\` is import/required in your bundle.
|
||||
2. Check the stack trace of this error and make sure the funciton that calls getStudioProject() is run after \`@theatre/core\` is loaded.`)
|
||||
}
|
||||
return getStudio().getStudioProject(core)
|
||||
}
|
||||
|
||||
debouncedScrub(threshold: number = 1000): Pick<IScrub, 'capture'> {
|
||||
let currentScrub: IScrub | undefined
|
||||
const scheduleCommit = debounce(() => {
|
||||
|
|
|
@ -152,7 +152,7 @@ const Content: React.FC<{paneInstance: PaneInstance<$FixMe>}> = ({
|
|||
</PanelDragZone>
|
||||
<F2>
|
||||
<ErrorBoundary FallbackComponent={ErrorFallback}>
|
||||
<Comp paneId={paneInstance.instanceId} object={paneInstance.object} />
|
||||
<Comp paneId={paneInstance.instanceId} />
|
||||
</ErrorBoundary>
|
||||
</F2>
|
||||
</Container>
|
||||
|
|
Loading…
Reference in a new issue