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;
	}
}
int32 SClippingHorizontalBox::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const
{
	// Get the clipped children info
	FArrangedChildren ClippedArrangedChildren(EVisibility::Visible);
	ArrangeChildren(AllottedGeometry, ClippedArrangedChildren);
	
	// Get the non-clipped children info
	// @todo umg: One should not call the virtual OnArrangeChildren, one should only call ArrangeChildren.
	FArrangedChildren ArrangedChildren(EVisibility::Visible);
	SBoxPanel::OnArrangeChildren(AllottedGeometry, ArrangedChildren);
	
	if ((ClippedArrangedChildren.Num() != 0) && (ArrangedChildren.Num() != 0))
	{
		int32 IndexClippedAt = ClippedArrangedChildren.Num() - 1;
		const FArrangedWidget& LastCippedChild = ClippedArrangedChildren[IndexClippedAt];
		const FArrangedWidget& FirstChild = ArrangedChildren[0];
		const FArrangedWidget& LastChild = ArrangedChildren[ArrangedChildren.Num() - 1];
		float BorderLocalWidth = AllottedGeometry.Size.X;
	
		// If only the last child/block, which is the wrap button, is being clipped
		if (IndexClippedAt == ArrangedChildren.Num() - 2)
		{
			// Only recalculate the alloted geometry size if said size is fitted to the toolbar/menubar
			if (FMath::TruncToInt(AllottedGeometry.AbsolutePosition.X + AllottedGeometry.Size.X * AllottedGeometry.Scale) <= FMath::TruncToInt(LastChild.Geometry.AbsolutePosition.X + LastChild.Geometry.Size.X * LastChild.Geometry.Scale))
			{
				// Calculate the size of the custom border
				BorderLocalWidth = (LastCippedChild.Geometry.AbsolutePosition.X + LastCippedChild.Geometry.Size.X * LastCippedChild.Geometry.Scale - FirstChild.Geometry.AbsolutePosition.X) / AllottedGeometry.Scale;
			}
		}
		else
		{
			// Children/blocks are being clipped, calculate the size of the custom border
			const FArrangedWidget& NextChild = (IndexClippedAt + 1 < ClippedArrangedChildren.Num())? ClippedArrangedChildren[IndexClippedAt + 1]: LastCippedChild;
			BorderLocalWidth = (NextChild.Geometry.AbsolutePosition.X + NextChild.Geometry.Size.X * NextChild.Geometry.Scale - FirstChild.Geometry.AbsolutePosition.X) / AllottedGeometry.Scale;
		}
	
		bool bEnabled = ShouldBeEnabled( bParentEnabled );
		ESlateDrawEffect::Type DrawEffects = !bEnabled ? ESlateDrawEffect::DisabledEffect : ESlateDrawEffect::None;
		FSlateColor BorderBackgroundColor = FLinearColor::White;

		// Draw the custom border
		FSlateDrawElement::MakeBox(
			OutDrawElements,
			LayerId,
			AllottedGeometry.ToPaintGeometry(FVector2D(BorderLocalWidth, AllottedGeometry.Size.Y), FSlateLayoutTransform()),
			BackgroundBrush,
			MyClippingRect,
			DrawEffects,
			BackgroundBrush->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() * BorderBackgroundColor.GetColor(InWidgetStyle)
			);
	}

	return SHorizontalBox::OnPaint(Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled);
}
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;
	}
}