bool FSequencerObjectChangeListener::IsTypeKeyable(const UClass& ObjectClass, const IPropertyHandle& PropertyHandle) const
{
	const UProperty* Property = PropertyHandle.GetProperty();
	const UStructProperty* StructProperty = Cast<const UStructProperty>(Property);
	const UStructProperty* ParentStructProperty = nullptr;

	const TSharedPtr<IPropertyHandle> ParentHandle = PropertyHandle.GetParentHandle();
	if(ParentHandle->IsValidHandle())
	{
		ParentStructProperty = Cast<const UStructProperty>(ParentHandle->GetProperty());
	}
	

	FString PropertyVarName;

	bool bFound = false;
	if( StructProperty )
	{
		bFound = FindPropertySetter( ObjectClass, StructProperty->Struct->GetFName(), StructProperty->GetName() );
	}
	
	if( !bFound && ParentStructProperty )
	{
		// If the property parent is a struct, see if this property parent can be keyed. (e.g R,G,B,A for a color)
		bFound = FindPropertySetter( ObjectClass, ParentStructProperty->Struct->GetFName(), ParentStructProperty->GetName() );
	}

	if( !bFound )
	{
		// the property in question is not a struct or an inner of the struct. See if it is directly keyable
		bFound = FindPropertySetter( ObjectClass, Property->GetClass()->GetFName(), Property->GetName() );
	}

	return bFound;
}
Пример #2
0
void PropertyHandleToPropertyPath(const UClass* OwnerClass, const IPropertyHandle& InPropertyHandle, TArray<UProperty*>& PropertyPath)
{
	PropertyPath.Add(InPropertyHandle.GetProperty());
	TSharedPtr<IPropertyHandle> CurrentHandle = InPropertyHandle.GetParentHandle();
	while (CurrentHandle.IsValid() && CurrentHandle->GetProperty() != nullptr)
	{
		PropertyPath.Insert(CurrentHandle->GetProperty(), 0);
		CurrentHandle = CurrentHandle->GetParentHandle();
	}
}
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);
			}
		}
	}
}