void FSequencerObjectChangeListener::BroadcastPropertyChanged( FKeyPropertyParams KeyPropertyParams, bool bRequireAutoKey ) const { const UStructProperty* StructProperty = Cast<const UStructProperty>(KeyPropertyParams.PropertyPath.Last()); const UStructProperty* ParentStructProperty = nullptr; if (KeyPropertyParams.PropertyPath.Num() > 1) { ParentStructProperty = Cast<const UStructProperty>(KeyPropertyParams.PropertyPath[KeyPropertyParams.PropertyPath.Num() - 2]); } FPropertyChangedParams Params; Params.bRequireAutoKey = bRequireAutoKey; Params.ObjectsThatChanged = KeyPropertyParams.ObjectsToKey; Params.StructPropertyNameToKey = NAME_None; bool bFoundAndBroadcastedDelegate = false; if (ParentStructProperty) { Params.PropertyPath.Append(KeyPropertyParams.PropertyPath.GetData(), KeyPropertyParams.PropertyPath.Num() - 1); // If the property parent is a struct, see if this property parent can be keyed. (e.g R,G,B,A for a color) FOnAnimatablePropertyChanged Delegate = ClassToPropertyChangedMap.FindRef(ParentStructProperty->Struct->GetFName()); if (Delegate.IsBound()) { if (!bRequireAutoKey) { Params.StructPropertyNameToKey = KeyPropertyParams.PropertyPath.Last()->GetFName(); } bFoundAndBroadcastedDelegate = true; Delegate.Broadcast(Params); } } if (!bFoundAndBroadcastedDelegate) { Params.PropertyPath = KeyPropertyParams.PropertyPath; if (StructProperty) { ClassToPropertyChangedMap.FindRef(StructProperty->Struct->GetFName()).Broadcast(Params); } else { // the property in question is not a struct or an inner of the struct. See if it is directly keyable ClassToPropertyChangedMap.FindRef(KeyPropertyParams.PropertyPath.Last()->GetClass()->GetFName()).Broadcast(Params); } } }
void FSequencerObjectChangeListener::OnPropertyChanged( const TArray<UObject*>& ChangedObjects, const IPropertyHandle& PropertyHandle, bool bRequireAutoKey ) const { bool bIsKeyable = false; for( UObject* Object : ChangedObjects ) { if( Object ) { bIsKeyable |= IsTypeKeyable( *Object->GetClass(), PropertyHandle ); } } if( bIsKeyable ) { const UProperty* Property = PropertyHandle.GetProperty(); const UStructProperty* StructProperty = Cast<const UStructProperty>(Property); const UStructProperty* ParentStructProperty = nullptr; TSharedPtr<IPropertyHandle> ParentHandle; ParentHandle = PropertyHandle.GetParentHandle(); if (ParentHandle->IsValidHandle()) { ParentStructProperty = Cast<const UStructProperty>(ParentHandle->GetProperty()); } FString PropertyVarName; // If not in auto-key allow partial keying of specific inner struct property values; FName InnerStructPropName = !bRequireAutoKey && ParentStructProperty ? Property->GetFName() : NAME_None; FKeyPropertyParams Params; Params.bRequireAutoKey = bRequireAutoKey; Params.ObjectsThatChanged = ChangedObjects; bool bFoundAndBroadcastedDelegate = false; if (ParentStructProperty) { Params.PropertyHandle = ParentHandle.Get(); Params.PropertyPath = ParentHandle->GeneratePathToProperty(); // If the property parent is a struct, see if this property parent can be keyed. (e.g R,G,B,A for a color) FOnAnimatablePropertyChanged Delegate = ClassToPropertyChangedMap.FindRef(ParentStructProperty->Struct->GetFName()); if (Delegate.IsBound()) { Params.InnerStructPropertyName = InnerStructPropName; bFoundAndBroadcastedDelegate = true; Delegate.Broadcast(Params); } } if (!bFoundAndBroadcastedDelegate) { if (StructProperty) { Params.PropertyHandle = &PropertyHandle; Params.PropertyPath = PropertyHandle.GeneratePathToProperty(); ClassToPropertyChangedMap.FindRef(StructProperty->Struct->GetFName()).Broadcast(Params); } else { Params.PropertyHandle = &PropertyHandle; Params.PropertyPath = PropertyHandle.GeneratePathToProperty(); // the property in question is not a struct or an inner of the struct. See if it is directly keyable ClassToPropertyChangedMap.FindRef(Property->GetClass()->GetFName()).Broadcast(Params); } } } }