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; } }