diff --git a/theatre/core/src/sheetObjects/SheetObjectTemplate.ts b/theatre/core/src/sheetObjects/SheetObjectTemplate.ts index 3b3ffbf..6b518dc 100644 --- a/theatre/core/src/sheetObjects/SheetObjectTemplate.ts +++ b/theatre/core/src/sheetObjects/SheetObjectTemplate.ts @@ -33,6 +33,13 @@ import { } from '@theatre/shared/propTypes/utils' import getOrderingOfPropTypeConfig from './getOrderingOfPropTypeConfig' 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}}}`, @@ -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 { + 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( pointer: Pointer, ): SerializableValue | undefined { diff --git a/theatre/studio/src/propEditors/useEditingToolsForCompoundProp.tsx b/theatre/studio/src/propEditors/useEditingToolsForCompoundProp.tsx index ed34192..368002b 100644 --- a/theatre/studio/src/propEditors/useEditingToolsForCompoundProp.tsx +++ b/theatre/studio/src/propEditors/useEditingToolsForCompoundProp.tsx @@ -26,6 +26,7 @@ import type {NearbyKeyframesControls} from './NextPrevKeyframeCursors' import NextPrevKeyframeCursors from './NextPrevKeyframeCursors' import {getNearbyKeyframesOfTrack} from './getNearbyKeyframesOfTrack' import type {KeyframeWithTrack} from '@theatre/studio/panels/SequenceEditorPanel/DopeSheet/Right/collectAggregateKeyframes' +import {emptyObject} from '@theatre/shared/utils' interface CommonStuff { beingScrubbed: boolean @@ -56,11 +57,6 @@ export function useEditingToolsForCompoundProp( ): Stuff { const pathToProp = getPointerParts(pointerToProp).path - const pointerToStaticOverrides = pointerDeep( - obj.template.pointerToStaticOverrides, - pathToProp, - ) - return usePrism((): Stuff => { // if the compound has no simple descendants, then there isn't much the user can do with it if (!compoundHasSimpleDescendants(propConfig)) { @@ -101,11 +97,6 @@ export function useEditingToolsForCompoundProp( obj.template.getMapOfValidSequenceTracks_forStudio(), ) - const staticOverrides = getDeep( - val(obj.template.getStaticValues()), - pathToProp, - ) - const possibleSequenceTrackIds = getDeep( validSequencedTracks, pathToProp, @@ -116,7 +107,16 @@ export function useEditingToolsForCompoundProp( Object.keys(possibleSequenceTrackIds).length !== 0 // check if object is empty or undefined 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) { for (const descendant of iteratePropType(propConfig, [])) { if (isPropConfigComposite(descendant.conf)) continue @@ -125,46 +125,22 @@ export function useEditingToolsForCompoundProp( descendant.path, ) as SequenceTrackId | undefined if (typeof sequencedTrackIdBelongingToDescendant !== 'string') { - hasOneOrMoreStatics = true + hasStatics = true } else { listOfDescendantTrackIds.push(sequencedTrackIdBelongingToDescendant) } } } - if (hasOneOrMoreStatics) { - contextMenuItems.push( - /** - * TODO This is surely confusing for the user if the descendants don't have overrides. - */ - { - label: 'Reset all to default', - callback: () => { - getStudio()!.transaction(({unset}) => { - unset(pointerToProp) - }) - }, + if (hasStatics || hasOneOrMoreSequencedTracks) { + contextMenuItems.push({ + 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) { @@ -195,6 +171,31 @@ export function useEditingToolsForCompoundProp( }) } + 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) { const controlIndicators = prism.memo( `controlIndicators`, @@ -223,9 +224,7 @@ export function useEditingToolsForCompoundProp( ...common, type: 'AllStatic', controlIndicators: ( - + ), } }