Disallowed sequencing on non-numeric props
* This is temporary until we find a good UX for sequencing discrete values
This commit is contained in:
parent
f6cf3711f4
commit
b5e994f597
6 changed files with 143 additions and 113 deletions
|
@ -15,7 +15,11 @@ const BooleanPropEditor: React.FC<{
|
||||||
pointerToProp: SheetObject['propsP']
|
pointerToProp: SheetObject['propsP']
|
||||||
obj: SheetObject
|
obj: SheetObject
|
||||||
}> = ({propConfig, pointerToProp, obj}) => {
|
}> = ({propConfig, pointerToProp, obj}) => {
|
||||||
const stuff = useEditingToolsForPrimitiveProp<boolean>(pointerToProp, obj)
|
const stuff = useEditingToolsForPrimitiveProp<boolean>(
|
||||||
|
pointerToProp,
|
||||||
|
obj,
|
||||||
|
propConfig,
|
||||||
|
)
|
||||||
|
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(el: React.ChangeEvent<HTMLInputElement>) => {
|
(el: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
|
|
|
@ -10,7 +10,11 @@ const NumberPropEditor: React.FC<{
|
||||||
pointerToProp: SheetObject['propsP']
|
pointerToProp: SheetObject['propsP']
|
||||||
obj: SheetObject
|
obj: SheetObject
|
||||||
}> = ({propConfig, pointerToProp, obj}) => {
|
}> = ({propConfig, pointerToProp, obj}) => {
|
||||||
const stuff = useEditingToolsForPrimitiveProp<number>(pointerToProp, obj)
|
const stuff = useEditingToolsForPrimitiveProp<number>(
|
||||||
|
pointerToProp,
|
||||||
|
obj,
|
||||||
|
propConfig,
|
||||||
|
)
|
||||||
|
|
||||||
const nudge = useCallback(
|
const nudge = useCallback(
|
||||||
(params: {deltaX: number; deltaFraction: number; magnitude: number}) => {
|
(params: {deltaX: number; deltaFraction: number; magnitude: number}) => {
|
||||||
|
|
|
@ -12,7 +12,11 @@ const StringLiteralPropEditor: React.FC<{
|
||||||
pointerToProp: SheetObject['propsP']
|
pointerToProp: SheetObject['propsP']
|
||||||
obj: SheetObject
|
obj: SheetObject
|
||||||
}> = ({propConfig, pointerToProp, obj}) => {
|
}> = ({propConfig, pointerToProp, obj}) => {
|
||||||
const stuff = useEditingToolsForPrimitiveProp<string>(pointerToProp, obj)
|
const stuff = useEditingToolsForPrimitiveProp<string>(
|
||||||
|
pointerToProp,
|
||||||
|
obj,
|
||||||
|
propConfig,
|
||||||
|
)
|
||||||
|
|
||||||
const onChange = useCallback(
|
const onChange = useCallback(
|
||||||
(val: string) => {
|
(val: string) => {
|
||||||
|
|
|
@ -12,6 +12,7 @@ import last from 'lodash-es/last'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import DefaultOrStaticValueIndicator from './DefaultValueIndicator'
|
import DefaultOrStaticValueIndicator from './DefaultValueIndicator'
|
||||||
import NextPrevKeyframeCursors from './NextPrevKeyframeCursors'
|
import NextPrevKeyframeCursors from './NextPrevKeyframeCursors'
|
||||||
|
import type {PropTypeConfig} from '@theatre/core/propTypes'
|
||||||
|
|
||||||
interface CommonStuff<T> {
|
interface CommonStuff<T> {
|
||||||
value: T
|
value: T
|
||||||
|
@ -44,7 +45,11 @@ type Stuff<T> = Default<T> | Static<T> | Sequenced<T>
|
||||||
|
|
||||||
export function useEditingToolsForPrimitiveProp<
|
export function useEditingToolsForPrimitiveProp<
|
||||||
T extends SerializablePrimitive,
|
T extends SerializablePrimitive,
|
||||||
>(pointerToProp: SheetObject['propsP'], obj: SheetObject): Stuff<T> {
|
>(
|
||||||
|
pointerToProp: SheetObject['propsP'],
|
||||||
|
obj: SheetObject,
|
||||||
|
propConfig: PropTypeConfig,
|
||||||
|
): Stuff<T> {
|
||||||
return usePrism(() => {
|
return usePrism(() => {
|
||||||
const pathToProp = getPointerParts(pointerToProp).path
|
const pathToProp = getPointerParts(pointerToProp).path
|
||||||
|
|
||||||
|
@ -114,114 +119,118 @@ export function useEditingToolsForPrimitiveProp<
|
||||||
controlIndicators: <></>,
|
controlIndicators: <></>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const validSequencedTracks = val(
|
const isSequencable = isPropConfSequencable(propConfig)
|
||||||
obj.template.getMapOfValidSequenceTracks_forStudio(),
|
|
||||||
)
|
|
||||||
const possibleSequenceTrackId = getDeep(validSequencedTracks, pathToProp)
|
|
||||||
|
|
||||||
const isSequenced = typeof possibleSequenceTrackId === 'string'
|
if (isSequencable) {
|
||||||
|
const validSequencedTracks = val(
|
||||||
|
obj.template.getMapOfValidSequenceTracks_forStudio(),
|
||||||
|
)
|
||||||
|
const possibleSequenceTrackId = getDeep(validSequencedTracks, pathToProp)
|
||||||
|
|
||||||
if (isSequenced) {
|
const isSequenced = typeof possibleSequenceTrackId === 'string'
|
||||||
contextMenuItems.push({
|
|
||||||
label: 'Make static',
|
if (isSequenced) {
|
||||||
callback: () => {
|
contextMenuItems.push({
|
||||||
getStudio()!.transaction(({stateEditors}) => {
|
label: 'Make static',
|
||||||
const propAddress = {...obj.address, pathToProp}
|
callback: () => {
|
||||||
stateEditors.coreByProject.historic.sheetsById.sequence.setPrimitivePropAsStatic(
|
getStudio()!.transaction(({stateEditors}) => {
|
||||||
{
|
const propAddress = {...obj.address, pathToProp}
|
||||||
...propAddress,
|
stateEditors.coreByProject.historic.sheetsById.sequence.setPrimitivePropAsStatic(
|
||||||
value: obj.getValueByPointer(pointerToProp) as T,
|
{
|
||||||
},
|
...propAddress,
|
||||||
|
value: obj.getValueByPointer(pointerToProp) as T,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const sequenceTrcackId = possibleSequenceTrackId as $FixMe as string
|
||||||
|
const nearbyKeyframes = prism.sub(
|
||||||
|
'lcr',
|
||||||
|
(): NearbyKeyframes => {
|
||||||
|
const track = val(
|
||||||
|
obj.template.project.pointers.historic.sheetsById[
|
||||||
|
obj.address.sheetId
|
||||||
|
].sequence.tracksByObject[obj.address.objectKey].trackData[
|
||||||
|
sequenceTrcackId
|
||||||
|
],
|
||||||
)
|
)
|
||||||
})
|
if (!track || track.keyframes.length === 0) return {}
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
const sequenceTrcackId = possibleSequenceTrackId as $FixMe as string
|
const pos = val(obj.sheet.getSequence().positionDerivation)
|
||||||
const nearbyKeyframes = prism.sub(
|
|
||||||
'lcr',
|
|
||||||
(): NearbyKeyframes => {
|
|
||||||
const track = val(
|
|
||||||
obj.template.project.pointers.historic.sheetsById[
|
|
||||||
obj.address.sheetId
|
|
||||||
].sequence.tracksByObject[obj.address.objectKey].trackData[
|
|
||||||
sequenceTrcackId
|
|
||||||
],
|
|
||||||
)
|
|
||||||
if (!track || track.keyframes.length === 0) return {}
|
|
||||||
|
|
||||||
const pos = val(obj.sheet.getSequence().positionDerivation)
|
const i = track.keyframes.findIndex((kf) => kf.position >= pos)
|
||||||
|
|
||||||
const i = track.keyframes.findIndex((kf) => kf.position >= pos)
|
if (i === -1)
|
||||||
|
return {
|
||||||
|
prev: last(track.keyframes),
|
||||||
|
}
|
||||||
|
|
||||||
if (i === -1)
|
const k = track.keyframes[i]!
|
||||||
return {
|
if (k.position === pos) {
|
||||||
prev: last(track.keyframes),
|
return {
|
||||||
}
|
prev: i > 0 ? track.keyframes[i - 1] : undefined,
|
||||||
|
cur: k,
|
||||||
const k = track.keyframes[i]!
|
next:
|
||||||
if (k.position === pos) {
|
i === track.keyframes.length - 1
|
||||||
return {
|
? undefined
|
||||||
prev: i > 0 ? track.keyframes[i - 1] : undefined,
|
: track.keyframes[i + 1],
|
||||||
cur: k,
|
}
|
||||||
next:
|
|
||||||
i === track.keyframes.length - 1
|
|
||||||
? undefined
|
|
||||||
: track.keyframes[i + 1],
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
next: k,
|
|
||||||
prev: i > 0 ? track.keyframes[i - 1] : undefined,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[sequenceTrcackId],
|
|
||||||
)
|
|
||||||
|
|
||||||
let shade: Shade
|
|
||||||
|
|
||||||
if (common.beingScrubbed) {
|
|
||||||
shade = 'Sequenced_OnKeyframe_BeingScrubbed'
|
|
||||||
} else {
|
|
||||||
if (nearbyKeyframes.cur) {
|
|
||||||
shade = 'Sequenced_OnKeyframe'
|
|
||||||
} else if (nearbyKeyframes.prev?.connectedRight === true) {
|
|
||||||
shade = 'Sequenced_BeingInterpolated'
|
|
||||||
} else {
|
|
||||||
shade = 'Sequened_NotBeingInterpolated'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextPrevKeyframeCursors = (
|
|
||||||
<NextPrevKeyframeCursors
|
|
||||||
{...nearbyKeyframes}
|
|
||||||
jumpToPosition={(position) => {
|
|
||||||
obj.sheet.getSequence().position = position
|
|
||||||
}}
|
|
||||||
toggleKeyframeOnCurrentPosition={() => {
|
|
||||||
if (nearbyKeyframes.cur) {
|
|
||||||
getStudio()!.transaction((api) => {
|
|
||||||
api.unset(pointerToProp)
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
getStudio()!.transaction((api) => {
|
return {
|
||||||
api.set(pointerToProp, common.value)
|
next: k,
|
||||||
})
|
prev: i > 0 ? track.keyframes[i - 1] : undefined,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}}
|
},
|
||||||
/>
|
[sequenceTrcackId],
|
||||||
)
|
)
|
||||||
|
|
||||||
const ret: Sequenced<T> = {
|
let shade: Shade
|
||||||
...common,
|
|
||||||
type: 'Sequenced',
|
if (common.beingScrubbed) {
|
||||||
shade,
|
shade = 'Sequenced_OnKeyframe_BeingScrubbed'
|
||||||
nearbyKeyframes,
|
} else {
|
||||||
controlIndicators: nextPrevKeyframeCursors,
|
if (nearbyKeyframes.cur) {
|
||||||
|
shade = 'Sequenced_OnKeyframe'
|
||||||
|
} else if (nearbyKeyframes.prev?.connectedRight === true) {
|
||||||
|
shade = 'Sequenced_BeingInterpolated'
|
||||||
|
} else {
|
||||||
|
shade = 'Sequened_NotBeingInterpolated'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextPrevKeyframeCursors = (
|
||||||
|
<NextPrevKeyframeCursors
|
||||||
|
{...nearbyKeyframes}
|
||||||
|
jumpToPosition={(position) => {
|
||||||
|
obj.sheet.getSequence().position = position
|
||||||
|
}}
|
||||||
|
toggleKeyframeOnCurrentPosition={() => {
|
||||||
|
if (nearbyKeyframes.cur) {
|
||||||
|
getStudio()!.transaction((api) => {
|
||||||
|
api.unset(pointerToProp)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
getStudio()!.transaction((api) => {
|
||||||
|
api.set(pointerToProp, common.value)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
const ret: Sequenced<T> = {
|
||||||
|
...common,
|
||||||
|
type: 'Sequenced',
|
||||||
|
shade,
|
||||||
|
nearbyKeyframes,
|
||||||
|
controlIndicators: nextPrevKeyframeCursors,
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
contextMenuItems.push({
|
contextMenuItems.push({
|
||||||
|
@ -233,17 +242,19 @@ export function useEditingToolsForPrimitiveProp<
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
contextMenuItems.push({
|
if (isSequencable) {
|
||||||
label: 'Sequence',
|
contextMenuItems.push({
|
||||||
callback: () => {
|
label: 'Sequence',
|
||||||
getStudio()!.transaction(({stateEditors}) => {
|
callback: () => {
|
||||||
const propAddress = {...obj.address, pathToProp}
|
getStudio()!.transaction(({stateEditors}) => {
|
||||||
stateEditors.coreByProject.historic.sheetsById.sequence.setPrimitivePropAsSequenced(
|
const propAddress = {...obj.address, pathToProp}
|
||||||
propAddress,
|
stateEditors.coreByProject.historic.sheetsById.sequence.setPrimitivePropAsSequenced(
|
||||||
)
|
propAddress,
|
||||||
})
|
)
|
||||||
},
|
})
|
||||||
})
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const statics = val(obj.template.getStaticValues())
|
const statics = val(obj.template.getStaticValues())
|
||||||
|
|
||||||
|
@ -296,3 +307,7 @@ type Shade =
|
||||||
| 'Sequenced_OnKeyframe_BeingScrubbed'
|
| 'Sequenced_OnKeyframe_BeingScrubbed'
|
||||||
| 'Sequenced_BeingInterpolated'
|
| 'Sequenced_BeingInterpolated'
|
||||||
| 'Sequened_NotBeingInterpolated'
|
| 'Sequened_NotBeingInterpolated'
|
||||||
|
|
||||||
|
function isPropConfSequencable(conf: PropTypeConfig): boolean {
|
||||||
|
return conf.type === 'number'
|
||||||
|
}
|
||||||
|
|
|
@ -90,6 +90,7 @@ const PrimitivePropRow: React.FC<{
|
||||||
const {controlIndicators} = useEditingToolsForPrimitiveProp(
|
const {controlIndicators} = useEditingToolsForPrimitiveProp(
|
||||||
pointerToProp,
|
pointerToProp,
|
||||||
obj,
|
obj,
|
||||||
|
leaf.propConf,
|
||||||
)
|
)
|
||||||
|
|
||||||
const possibleColor = usePrism(() => {
|
const possibleColor = usePrism(() => {
|
||||||
|
|
|
@ -54,6 +54,7 @@ export type SequenceEditorTree_PrimitiveProp =
|
||||||
sheetObject: SheetObject
|
sheetObject: SheetObject
|
||||||
pathToProp: PathToProp
|
pathToProp: PathToProp
|
||||||
trackId: SequenceTrackId
|
trackId: SequenceTrackId
|
||||||
|
propConf: PropTypeConfig_AllPrimitives
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SequenceEditorTree_AllRowTypes =
|
export type SequenceEditorTree_AllRowTypes =
|
||||||
|
@ -250,7 +251,7 @@ export const calculateSequenceEditorTree = (
|
||||||
sheetObject: SheetObject,
|
sheetObject: SheetObject,
|
||||||
trackId: SequenceTrackId,
|
trackId: SequenceTrackId,
|
||||||
pathToProp: PathToProp,
|
pathToProp: PathToProp,
|
||||||
conf: PropTypeConfig_AllPrimitives,
|
propConf: PropTypeConfig_AllPrimitives,
|
||||||
arrayOfChildren: Array<
|
arrayOfChildren: Array<
|
||||||
SequenceEditorTree_PrimitiveProp | SequenceEditorTree_PropWithChildren
|
SequenceEditorTree_PrimitiveProp | SequenceEditorTree_PropWithChildren
|
||||||
>,
|
>,
|
||||||
|
@ -258,6 +259,7 @@ export const calculateSequenceEditorTree = (
|
||||||
) {
|
) {
|
||||||
const row: SequenceEditorTree_PrimitiveProp = {
|
const row: SequenceEditorTree_PrimitiveProp = {
|
||||||
type: 'primitiveProp',
|
type: 'primitiveProp',
|
||||||
|
propConf: propConf,
|
||||||
depth: level,
|
depth: level,
|
||||||
sheetObject: sheetObject,
|
sheetObject: sheetObject,
|
||||||
pathToProp,
|
pathToProp,
|
||||||
|
|
Loading…
Reference in a new issue