Fix the regression where some compound props were not sequence-able
This commit is contained in:
parent
1ce3fd1ca6
commit
72222e5eeb
2 changed files with 91 additions and 47 deletions
|
@ -33,6 +33,13 @@ import {
|
||||||
} from '@theatre/shared/propTypes/utils'
|
} from '@theatre/shared/propTypes/utils'
|
||||||
import getOrderingOfPropTypeConfig from './getOrderingOfPropTypeConfig'
|
import getOrderingOfPropTypeConfig from './getOrderingOfPropTypeConfig'
|
||||||
import type {SheetState_Historic} from '@theatre/core/projects/store/types/SheetState_Historic'
|
import type {SheetState_Historic} from '@theatre/core/projects/store/types/SheetState_Historic'
|
||||||
|
import {cloneDeep, unset} from 'lodash-es'
|
||||||
|
|
||||||
|
function isObjectEmpty(obj: unknown): boolean {
|
||||||
|
return (
|
||||||
|
typeof obj === 'object' && obj !== null && Object.keys(obj).length === 0
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an object like: `{transform: {type: 'absolute', position: {x: 0}}}`,
|
* Given an object like: `{transform: {type: 'absolute', position: {x: 0}}}`,
|
||||||
|
@ -247,6 +254,44 @@ export default class SheetObjectTemplate {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns The static overrides that are not sequenced. Returns undefined if there are no static overrides,
|
||||||
|
* or if all those static overrides are sequenced.
|
||||||
|
*/
|
||||||
|
getStaticButNotSequencedOverrides(): Prism<SerializableMap | undefined> {
|
||||||
|
return this._cache.get('getStaticButNotSequencedOverrides', () =>
|
||||||
|
prism(() => {
|
||||||
|
const staticOverrides = val(this.getStaticValues())
|
||||||
|
const arrayOfValidSequenceTracks = val(
|
||||||
|
this.getArrayOfValidSequenceTracks(),
|
||||||
|
)
|
||||||
|
|
||||||
|
const staticButNotSequencedOverrides = cloneDeep(staticOverrides)
|
||||||
|
|
||||||
|
for (const {pathToProp} of arrayOfValidSequenceTracks) {
|
||||||
|
unset(staticButNotSequencedOverrides, pathToProp)
|
||||||
|
// also unset the parent if it's empty, and so on
|
||||||
|
let parentPath = pathToProp.slice(0, -1)
|
||||||
|
while (parentPath.length > 0) {
|
||||||
|
const parentValue = getDeep(
|
||||||
|
staticButNotSequencedOverrides,
|
||||||
|
parentPath,
|
||||||
|
)
|
||||||
|
if (!isObjectEmpty(parentValue)) break
|
||||||
|
unset(staticButNotSequencedOverrides, parentPath)
|
||||||
|
parentPath = parentPath.slice(0, -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isObjectEmpty(staticButNotSequencedOverrides)) {
|
||||||
|
return undefined
|
||||||
|
} else {
|
||||||
|
return staticButNotSequencedOverrides
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
getDefaultsAtPointer(
|
getDefaultsAtPointer(
|
||||||
pointer: Pointer<unknown>,
|
pointer: Pointer<unknown>,
|
||||||
): SerializableValue | undefined {
|
): SerializableValue | undefined {
|
||||||
|
|
|
@ -26,6 +26,7 @@ import type {NearbyKeyframesControls} from './NextPrevKeyframeCursors'
|
||||||
import NextPrevKeyframeCursors from './NextPrevKeyframeCursors'
|
import NextPrevKeyframeCursors from './NextPrevKeyframeCursors'
|
||||||
import {getNearbyKeyframesOfTrack} from './getNearbyKeyframesOfTrack'
|
import {getNearbyKeyframesOfTrack} from './getNearbyKeyframesOfTrack'
|
||||||
import type {KeyframeWithTrack} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/collectAggregateKeyframes'
|
import type {KeyframeWithTrack} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/collectAggregateKeyframes'
|
||||||
|
import {emptyObject} from '@theatre/shared/utils'
|
||||||
|
|
||||||
interface CommonStuff {
|
interface CommonStuff {
|
||||||
beingScrubbed: boolean
|
beingScrubbed: boolean
|
||||||
|
@ -56,11 +57,6 @@ export function useEditingToolsForCompoundProp<T extends SerializablePrimitive>(
|
||||||
): Stuff {
|
): Stuff {
|
||||||
const pathToProp = getPointerParts(pointerToProp).path
|
const pathToProp = getPointerParts(pointerToProp).path
|
||||||
|
|
||||||
const pointerToStaticOverrides = pointerDeep(
|
|
||||||
obj.template.pointerToStaticOverrides,
|
|
||||||
pathToProp,
|
|
||||||
)
|
|
||||||
|
|
||||||
return usePrism((): Stuff => {
|
return usePrism((): Stuff => {
|
||||||
// if the compound has no simple descendants, then there isn't much the user can do with it
|
// if the compound has no simple descendants, then there isn't much the user can do with it
|
||||||
if (!compoundHasSimpleDescendants(propConfig)) {
|
if (!compoundHasSimpleDescendants(propConfig)) {
|
||||||
|
@ -101,11 +97,6 @@ export function useEditingToolsForCompoundProp<T extends SerializablePrimitive>(
|
||||||
obj.template.getMapOfValidSequenceTracks_forStudio(),
|
obj.template.getMapOfValidSequenceTracks_forStudio(),
|
||||||
)
|
)
|
||||||
|
|
||||||
const staticOverrides = getDeep(
|
|
||||||
val(obj.template.getStaticValues()),
|
|
||||||
pathToProp,
|
|
||||||
)
|
|
||||||
|
|
||||||
const possibleSequenceTrackIds = getDeep(
|
const possibleSequenceTrackIds = getDeep(
|
||||||
validSequencedTracks,
|
validSequencedTracks,
|
||||||
pathToProp,
|
pathToProp,
|
||||||
|
@ -116,7 +107,16 @@ export function useEditingToolsForCompoundProp<T extends SerializablePrimitive>(
|
||||||
Object.keys(possibleSequenceTrackIds).length !== 0 // check if object is empty or undefined
|
Object.keys(possibleSequenceTrackIds).length !== 0 // check if object is empty or undefined
|
||||||
const listOfDescendantTrackIds: SequenceTrackId[] = []
|
const listOfDescendantTrackIds: SequenceTrackId[] = []
|
||||||
|
|
||||||
let hasOneOrMoreStatics = staticOverrides !== undefined
|
const allStaticOverrides = val(
|
||||||
|
obj.template.getStaticButNotSequencedOverrides(),
|
||||||
|
)
|
||||||
|
const staticOverrides = getDeep(
|
||||||
|
allStaticOverrides ?? emptyObject,
|
||||||
|
pathToProp,
|
||||||
|
)
|
||||||
|
|
||||||
|
let hasStatics = staticOverrides !== undefined
|
||||||
|
|
||||||
if (hasOneOrMoreSequencedTracks) {
|
if (hasOneOrMoreSequencedTracks) {
|
||||||
for (const descendant of iteratePropType(propConfig, [])) {
|
for (const descendant of iteratePropType(propConfig, [])) {
|
||||||
if (isPropConfigComposite(descendant.conf)) continue
|
if (isPropConfigComposite(descendant.conf)) continue
|
||||||
|
@ -125,46 +125,22 @@ export function useEditingToolsForCompoundProp<T extends SerializablePrimitive>(
|
||||||
descendant.path,
|
descendant.path,
|
||||||
) as SequenceTrackId | undefined
|
) as SequenceTrackId | undefined
|
||||||
if (typeof sequencedTrackIdBelongingToDescendant !== 'string') {
|
if (typeof sequencedTrackIdBelongingToDescendant !== 'string') {
|
||||||
hasOneOrMoreStatics = true
|
hasStatics = true
|
||||||
} else {
|
} else {
|
||||||
listOfDescendantTrackIds.push(sequencedTrackIdBelongingToDescendant)
|
listOfDescendantTrackIds.push(sequencedTrackIdBelongingToDescendant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasOneOrMoreStatics) {
|
if (hasStatics || hasOneOrMoreSequencedTracks) {
|
||||||
contextMenuItems.push(
|
contextMenuItems.push({
|
||||||
/**
|
label: 'Reset all to default',
|
||||||
* TODO This is surely confusing for the user if the descendants don't have overrides.
|
callback: () => {
|
||||||
*/
|
getStudio()!.transaction(({unset}) => {
|
||||||
{
|
unset(pointerToProp)
|
||||||
label: 'Reset all to default',
|
})
|
||||||
callback: () => {
|
|
||||||
getStudio()!.transaction(({unset}) => {
|
|
||||||
unset(pointerToProp)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
})
|
||||||
label: 'Sequence all',
|
|
||||||
callback: () => {
|
|
||||||
getStudio()!.transaction(({stateEditors}) => {
|
|
||||||
for (const {path, conf} of iteratePropType(
|
|
||||||
propConfig,
|
|
||||||
pathToProp,
|
|
||||||
)) {
|
|
||||||
if (isPropConfigComposite(conf)) continue
|
|
||||||
const propAddress = {...obj.address, pathToProp: path}
|
|
||||||
|
|
||||||
stateEditors.coreByProject.historic.sheetsById.sequence.setPrimitivePropAsSequenced(
|
|
||||||
propAddress,
|
|
||||||
propConfig,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasOneOrMoreSequencedTracks) {
|
if (hasOneOrMoreSequencedTracks) {
|
||||||
|
@ -195,6 +171,31 @@ export function useEditingToolsForCompoundProp<T extends SerializablePrimitive>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!hasOneOrMoreSequencedTracks ||
|
||||||
|
(hasOneOrMoreSequencedTracks && hasStatics)
|
||||||
|
) {
|
||||||
|
contextMenuItems.push({
|
||||||
|
label: 'Sequence all',
|
||||||
|
callback: () => {
|
||||||
|
getStudio()!.transaction(({stateEditors}) => {
|
||||||
|
for (const {path, conf} of iteratePropType(
|
||||||
|
propConfig,
|
||||||
|
pathToProp,
|
||||||
|
)) {
|
||||||
|
if (isPropConfigComposite(conf)) continue
|
||||||
|
const propAddress = {...obj.address, pathToProp: path}
|
||||||
|
|
||||||
|
stateEditors.coreByProject.historic.sheetsById.sequence.setPrimitivePropAsSequenced(
|
||||||
|
propAddress,
|
||||||
|
propConfig,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if (hasOneOrMoreSequencedTracks) {
|
if (hasOneOrMoreSequencedTracks) {
|
||||||
const controlIndicators = prism.memo(
|
const controlIndicators = prism.memo(
|
||||||
`controlIndicators`,
|
`controlIndicators`,
|
||||||
|
@ -223,9 +224,7 @@ export function useEditingToolsForCompoundProp<T extends SerializablePrimitive>(
|
||||||
...common,
|
...common,
|
||||||
type: 'AllStatic',
|
type: 'AllStatic',
|
||||||
controlIndicators: (
|
controlIndicators: (
|
||||||
<DefaultOrStaticValueIndicator
|
<DefaultOrStaticValueIndicator hasStaticOverride={hasStatics} />
|
||||||
hasStaticOverride={hasOneOrMoreStatics}
|
|
||||||
/>
|
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue