void FMovieSceneColorTrackInstance::Update(EMovieSceneUpdateData& UpdateData, const TArray<TWeakObjectPtr<UObject>>& RuntimeObjects, class IMovieScenePlayer& Player, FMovieSceneSequenceInstance& SequenceInstance) 
{
	for (auto ObjectPtr : RuntimeObjects)
	{
		UObject* Object = ObjectPtr.Get();
		if ( Object != nullptr )
		{
			if ( ColorType == EColorType::Slate )
			{
				FSlateColor ColorValue = PropertyBindings->GetCurrentValue<FSlateColor>( Object );
				FLinearColor LinearColor = ColorValue.GetSpecifiedColor();

				if ( ColorTrack->Eval( UpdateData.Position, UpdateData.LastPosition, LinearColor ) )
				{
					FSlateColor NewColor( LinearColor );
					PropertyBindings->CallFunction<FSlateColor>( Object, &NewColor );
				}
			}
			else if ( ColorType == EColorType::Color )
			{
				// We assume the color we get back is in sRGB, assigning it to a linear color will implicitly
				// convert it to a linear color instead of using ReinterpretAsLinear which will just change the
				// bytes into floats using divide by 255.
				FColor SrgbColor = PropertyBindings->GetCurrentValue<FColor>( Object );
				FLinearColor LinearColorValue = SrgbColor;
				bool bConvertBackToSRgb = true;
				if ( ColorTrack->Eval( UpdateData.Position, UpdateData.LastPosition, LinearColorValue ) )
				{
					// Light components have to be handled specially here because their set function takes two values, the linear color
					// and whether or not the linear color needs to be converted back to sRGB.  All other other set function cases should
					// follow the sequencer convention of having a single parameter of the correct type, which in this case is an FColor
					// already in sRGB format.
					ULightComponent* LightComponent = Cast<ULightComponent>( Object );
					if ( LightComponent != nullptr )
					{
						LightComponent->SetLightColor( LinearColorValue, bConvertBackToSRgb );
					}
					else
					{
						FColor SRgbColorValue = LinearColorValue.ToFColor( bConvertBackToSRgb );
						PropertyBindings->CallFunction<FColor>( Object, &SRgbColorValue );
					}
				}
			}
			else
			{
				FLinearColor ColorValue = PropertyBindings->GetCurrentValue<FLinearColor>( Object );

				if ( ColorTrack->Eval( UpdateData.Position, UpdateData.LastPosition, ColorValue ) )
				{
					PropertyBindings->CallFunction<FLinearColor>( Object, &ColorValue );
				}
			}
		}
	}
}
FSlateColor Fixup(const FSlateColor& Src)
{
	Prepare();

	if (Src.IsColorSpecified())
	{
		return FSlateColor(Src.GetSpecifiedColor());
	}
	else
	{
		return Src;
	}
}
void FMovieSceneColorTrackInstance::Update( float Position, float LastPosition, const TArray<UObject*>& RuntimeObjects, class IMovieScenePlayer& Player ) 
{
	for(UObject* Object : RuntimeObjects)
	{
		if( ColorTrack->IsSlateColor() )
		{
			FSlateColor ColorValue = PropertyBindings->GetCurrentValue<FSlateColor>(Object);
			FLinearColor LinearColor = ColorValue.GetSpecifiedColor();
			if(ColorTrack->Eval(Position, LastPosition, LinearColor))
			{
				FSlateColor NewColor(LinearColor);
				PropertyBindings->CallFunction(Object, &NewColor);
			}
		}
		else
		{
			FLinearColor ColorValue = PropertyBindings->GetCurrentValue<FLinearColor>(Object);
			if(ColorTrack->Eval(Position, LastPosition, ColorValue))
			{
				PropertyBindings->CallFunction(Object, &ColorValue);
			}
		}
	}
}
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
TSharedRef<SWidget> SReflectorTreeWidgetItem::GenerateWidgetForColumn(const FName& ColumnName)
{
	if (ColumnName == TEXT("WidgetName"))
	{
		return SNew(SHorizontalBox)

		+ SHorizontalBox::Slot()
		.AutoWidth()
		.VAlign(VAlign_Center)
		[
			SNew(SExpanderArrow, SharedThis(this))
		]

		+ SHorizontalBox::Slot()
		.AutoWidth()
		.Padding(2.0f, 0.0f)
		.VAlign(VAlign_Center)
		[
			SNew(STextBlock)
			.Text(this, &SReflectorTreeWidgetItem::GetWidgetType)
			.ColorAndOpacity(this, &SReflectorTreeWidgetItem::GetTint)
		];
	}
	else if (ColumnName == TEXT("WidgetInfo"))
	{
		return SNew(SBox)
			.HAlign(HAlign_Left)
			.VAlign(VAlign_Center)
			.Padding(FMargin(2.0f, 0.0f))
			[
				SNew(SHyperlink)
				.Text(this, &SReflectorTreeWidgetItem::GetReadableLocationAsText)
				.OnNavigate(this, &SReflectorTreeWidgetItem::HandleHyperlinkNavigate)
			];
	}
	else if (ColumnName == "Visibility")
	{
		return SNew(SBox)
			.HAlign(HAlign_Center)
			.VAlign(VAlign_Center)
			.Padding(FMargin(2.0f, 0.0f))
			[
				SNew(STextBlock)
					.Text(this, &SReflectorTreeWidgetItem::GetVisibilityAsString)
			];
	}
	else if (ColumnName == "ForegroundColor")
	{
		const FSlateColor Foreground = WidgetInfo->GetWidgetForegroundColor();

		return SNew(SBorder)
			// Show unset color as an empty space.
			.Visibility(Foreground.IsColorSpecified() ? EVisibility::Visible : EVisibility::Hidden)
			// Show a checkerboard background so we can see alpha values well
			.BorderImage(FCoreStyle::Get().GetBrush("Checkerboard"))
			.VAlign(VAlign_Center)
			.Padding(FMargin(2.0f, 0.0f))
			[
				// Show a color block
				SNew(SColorBlock)
					.Color(Foreground.GetSpecifiedColor())
					.Size(FVector2D(16.0f, 16.0f))
			];
	}
	else if (ColumnName == "Address")
	{
		const FText Address = FText::FromString(WidgetInfo->GetWidgetAddress());
		
		return SNew(SBox)
			.HAlign(HAlign_Left)
			.VAlign(VAlign_Center)
			.Padding(FMargin(2.0f, 0.0f))
			[
				SNew(SHyperlink)
				.ToolTipText(NSLOCTEXT("SWidgetReflector", "ClickToCopy", "Click to copy address."))
				.Text(Address)
				.OnNavigate_Lambda([Address](){ FPlatformMisc::ClipboardCopy(*Address.ToString()); })
			];
	}
	else
	{
		return SNullWidget::NullWidget;
	}
}