int32 FSlateTextHighlightRunRenderer::OnPaint( const FPaintArgs& Args, const FTextLayout::FLineView& Line, const TSharedRef< ISlateRun >& Run, const TSharedRef< ILayoutBlock >& Block, const FTextBlockStyle& DefaultStyle, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { FVector2D Location( Block->GetLocationOffset() ); Location.Y = Line.Offset.Y; // The block size and offset values are pre-scaled, so we need to account for that when converting the block offsets into paint geometry const float InverseScale = Inverse(AllottedGeometry.Scale); // Draw the actual highlight rectangle FSlateDrawElement::MakeBox( OutDrawElements, ++LayerId, AllottedGeometry.ToPaintGeometry(TransformVector(InverseScale, FVector2D( Block->GetSize().X, Line.Size.Y )), FSlateLayoutTransform(TransformPoint(InverseScale, Location))), &DefaultStyle.HighlightShape, MyClippingRect, bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, InWidgetStyle.GetColorAndOpacityTint() * DefaultStyle.HighlightColor ); FLinearColor InvertedHighlightColor = FLinearColor::White - DefaultStyle.HighlightColor; InvertedHighlightColor.A = InWidgetStyle.GetForegroundColor().A; FWidgetStyle WidgetStyle( InWidgetStyle ); WidgetStyle.SetForegroundColor( InvertedHighlightColor ); return Run->OnPaint( Args, Line, Block, DefaultStyle, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, WidgetStyle, bParentEnabled ); }
int32 SSplitter::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { FArrangedChildren ArrangedChildren( EVisibility::Visible ); ArrangeChildren( AllottedGeometry, ArrangedChildren ); int32 MaxLayerId = PaintArrangedChildren( Args, ArrangedChildren, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled ); const FSlateBrush* NormalHandleBrush = &Style->HandleNormalBrush; // Draw the splitter above any children MaxLayerId += 1; for( int32 ChildIndex = 0; ChildIndex < ArrangedChildren.Num(); ++ChildIndex ) { const FGeometry& GeometryAfterSplitter = ArrangedChildren[ FMath::Clamp(ChildIndex + 1, 0, ArrangedChildren.Num()-1) ].Geometry; const float HalfHitDetectionSplitterHandleSize = ( HitDetectionSplitterHandleSize / 2 ); const float HalfPhysicalSplitterHandleSize = ( PhysicalSplitterHandleSize / 2 ); FVector2D HandleSize; FVector2D HandlePosition; if ( Orientation == Orient_Horizontal ) { HandleSize.Set( PhysicalSplitterHandleSize, GeometryAfterSplitter.Size.Y ); HandlePosition.Set( -(HalfHitDetectionSplitterHandleSize + HalfPhysicalSplitterHandleSize), 0 ); } else { HandleSize.Set( GeometryAfterSplitter.Size.X, PhysicalSplitterHandleSize ); HandlePosition.Set( 0, -(HalfHitDetectionSplitterHandleSize + HalfPhysicalSplitterHandleSize) ); } if (HoveredHandleIndex != ChildIndex) { FSlateDrawElement::MakeBox( OutDrawElements, MaxLayerId, GeometryAfterSplitter.ToPaintGeometry( HandlePosition, HandleSize, 1.0f ), NormalHandleBrush, MyClippingRect, ShouldBeEnabled( bParentEnabled ), InWidgetStyle.GetColorAndOpacityTint() * NormalHandleBrush->TintColor.GetSpecifiedColor() ); } else { FSlateDrawElement::MakeBox( OutDrawElements, MaxLayerId, GeometryAfterSplitter.ToPaintGeometry( HandlePosition, HandleSize, 1.0f ), &Style->HandleHighlightBrush, MyClippingRect, ShouldBeEnabled( bParentEnabled ), InWidgetStyle.GetColorAndOpacityTint() * Style->HandleHighlightBrush.TintColor.GetSpecifiedColor() ); } } return MaxLayerId; }
int32 SBorder::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const FSlateBrush* BrushResource = BorderImage.Get(); const bool bEnabled = ShouldBeEnabled(bParentEnabled); const bool bShowDisabledEffect = ShowDisabledEffect.Get(); ESlateDrawEffect::Type DrawEffects = bShowDisabledEffect && !bEnabled ? ESlateDrawEffect::DisabledEffect : ESlateDrawEffect::None; if ( BrushResource && BrushResource->DrawAs != ESlateBrushDrawType::NoDrawType ) { FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), BrushResource, MyClippingRect, DrawEffects, BrushResource->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() * BorderBackgroundColor.Get().GetColor( InWidgetStyle ) ); } FWidgetStyle CompoundedWidgetStyle = FWidgetStyle(InWidgetStyle) .BlendColorAndOpacityTint(ColorAndOpacity.Get()) .SetForegroundColor( ForegroundColor.Get() ); return SCompoundWidget::OnPaint(Args, AllottedGeometry, MyClippingRect.IntersectionWith( AllottedGeometry.GetClippingRect() ), OutDrawElements, LayerId, CompoundedWidgetStyle, bEnabled ); }
int32 FSequencerTimeSliderController::OnPaintTimeSlider( bool bMirrorLabels, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const bool bEnabled = bParentEnabled; const ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get(); const float LocalViewRangeMin = LocalViewRange.GetLowerBoundValue(); const float LocalViewRangeMax = LocalViewRange.GetUpperBoundValue(); const float LocalSequenceLength = LocalViewRangeMax-LocalViewRangeMin; FVector2D Scale = FVector2D(1.0f,1.0f); if ( LocalSequenceLength > 0) { FScrubRangeToScreen RangeToScreen( LocalViewRange, AllottedGeometry.Size ); const float MajorTickHeight = 9.0f; FDrawTickArgs Args; Args.AllottedGeometry = AllottedGeometry; Args.bMirrorLabels = bMirrorLabels; Args.bOnlyDrawMajorTicks = false; Args.TickColor = FLinearColor::White; Args.ClippingRect = MyClippingRect; Args.DrawEffects = DrawEffects; Args.StartLayer = LayerId; Args.TickOffset = bMirrorLabels ? 0.0f : FMath::Abs( AllottedGeometry.Size.Y - MajorTickHeight ); Args.MajorTickHeight = MajorTickHeight; DrawTicks( OutDrawElements, RangeToScreen, Args ); const float HandleSize = 13.0f; float HalfSize = FMath::TruncToFloat(HandleSize/2.0f); // Draw the scrub handle const float XPos = RangeToScreen.InputToLocalX( TimeSliderArgs.ScrubPosition.Get() ); // Should draw above the text const int32 ArrowLayer = LayerId + 2; FPaintGeometry MyGeometry = AllottedGeometry.ToPaintGeometry( FVector2D( XPos-HalfSize, 0 ), FVector2D( HandleSize, AllottedGeometry.Size.Y ) ); FLinearColor ScrubColor = InWidgetStyle.GetColorAndOpacityTint(); // @todo Sequencer this color should be specified in the style ScrubColor.A = ScrubColor.A*0.5f; ScrubColor.B *= 0.1f; ScrubColor.G *= 0.2f; FSlateDrawElement::MakeBox( OutDrawElements, ArrowLayer, MyGeometry, bMirrorLabels ? ScrubHandleUp : ScrubHandleDown, MyClippingRect, DrawEffects, ScrubColor ); return ArrowLayer; } return LayerId; }
int32 SPropertyTableCell::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { if ( CellBackground && CellBackground->DrawAs != ESlateBrushDrawType::NoDrawType ) { const FSlateBrush* Background = CellBackground; if ( Cell->GetTable()->GetCurrentCell() == Cell ) { Background = GetCurrentCellBorder(); } else if ( Cell->GetTable()->GetSelectedCells().Contains( Cell.ToSharedRef() ) ) { Background = FEditorStyle::GetBrush( Style, ".ReadOnlySelectedCellBorder" ); } FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), Background, MyClippingRect, ESlateDrawEffect::None, Background->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() ); } return SCompoundWidget::OnPaint( Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled ); }
int32 SSpinningImage::OnPaint( const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const FSlateBrush* ImageBrush = Image.Get(); if ((ImageBrush != NULL) && (ImageBrush->DrawAs != ESlateBrushDrawType::NoDrawType)) { const bool bIsEnabled = ShouldBeEnabled(bParentEnabled); const uint32 DrawEffects = bIsEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const FColor FinalColorAndOpacity( InWidgetStyle.GetColorAndOpacityTint() * ColorAndOpacity.Get().GetColor(InWidgetStyle) * ImageBrush->GetTint( InWidgetStyle ) ); const float Angle = Curve.GetLerpLooping() * 2.0f * PI; FSlateDrawElement::MakeRotatedBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), ImageBrush, MyClippingRect, DrawEffects, Angle, TOptional<FVector2D>(), // Will auto rotate about center FSlateDrawElement::RelativeToElement, FinalColorAndOpacity ); } return LayerId; }
int32 SCircularThrobber::OnPaint( const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const FColor FinalColorAndOpacity( InWidgetStyle.GetColorAndOpacityTint() * PieceImage->GetTint( InWidgetStyle ) ); const float Scale = AllottedGeometry.Scale; const float OffsetX = (AllottedGeometry.Size.X * Scale * 0.5f) - (PieceImage->ImageSize.X * Scale * 0.5f); const float OffsetY = (AllottedGeometry.Size.Y * Scale * 0.5f) - (PieceImage->ImageSize.Y * Scale * 0.5f); FPaintGeometry PaintGeom = AllottedGeometry.ToPaintGeometry(); FVector2D Origin = PaintGeom.DrawPosition; Origin.X += OffsetX; Origin.Y += OffsetY; const float DeltaAngle = NumPieces > 0 ? 2 * PI / NumPieces : 0; const float Phase = Curve.GetLerpLooping() * 2 * PI; for (int32 PieceIdx = 0; PieceIdx < NumPieces; ++PieceIdx) { PaintGeom.DrawPosition.X = Origin.X + FMath::Sin(DeltaAngle * PieceIdx + Phase) * OffsetX; PaintGeom.DrawPosition.Y = Origin.Y + FMath::Cos(DeltaAngle * PieceIdx + Phase) * OffsetY; PaintGeom.DrawSize = PieceImage->ImageSize * Scale * (PieceIdx + 1) / NumPieces; FSlateDrawElement::MakeBox(OutDrawElements, LayerId, PaintGeom, PieceImage, MyClippingRect, ESlateDrawEffect::None, InWidgetStyle.GetColorAndOpacityTint() ); } return LayerId; }
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); }
int32 SGraphBar::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // Used to track the layer ID we will return. int32 RetLayerId = LayerId; bool bEnabled = ShouldBeEnabled( bParentEnabled ); const ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const FLinearColor ColorAndOpacitySRGB = InWidgetStyle.GetColorAndOpacityTint(); static const FLinearColor SelectedBarColor(FLinearColor::White); // Paint inside the border only. const FVector2D BorderPadding = FTaskGraphStyle::Get()->GetVector("TaskGraph.ProgressBar.BorderPadding"); const FSlateRect ForegroundClippingRect = AllottedGeometry.GetClippingRect().InsetBy(FMargin(BorderPadding.X, BorderPadding.Y)).IntersectionWith(MyClippingRect); FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry(), BackgroundImage, MyClippingRect, DrawEffects, ColorAndOpacitySRGB ); // Draw all bars for( int32 EventIndex = 0; EventIndex < Events.Num(); ++EventIndex ) { TSharedPtr< FVisualizerEvent > Event = Events[ EventIndex ]; float StartX, EndX; if( CalculateEventGeometry( Event.Get(), AllottedGeometry, StartX, EndX ) ) { // Draw Event bar FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D( StartX, 0.0f ), FVector2D( EndX - StartX, AllottedGeometry.Size.Y )), Event->IsSelected ? SelectedImage : FillImage, ForegroundClippingRect, DrawEffects, Event->IsSelected ? SelectedBarColor : ColorPalette[Event->ColorIndex % (sizeof(ColorPalette) / sizeof(ColorPalette[0]))] ); } } return RetLayerId - 1; }
int32 FSlateSimpleRunHighlighter::OnPaint( const FTextLayout::FLineView& Line, const TSharedRef< ISlateRun >& Run, const TSharedRef< ILayoutBlock >& Block, const FTextBlockStyle& DefaultStyle, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { FVector2D Location( Block->GetLocationOffset() ); Location.Y = Line.Offset.Y; // Draw the actual highlight rectangle FSlateDrawElement::MakeBox( OutDrawElements, ++LayerId, FPaintGeometry( AllottedGeometry.AbsolutePosition + Location, FVector2D( Block->GetSize().X, Line.Size.Y ), AllottedGeometry.Scale ), &DefaultStyle.HighlightShape, MyClippingRect, bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, InWidgetStyle.GetColorAndOpacityTint() * DefaultStyle.HighlightColor ); FLinearColor InvertedForeground = FLinearColor::White - InWidgetStyle.GetForegroundColor(); InvertedForeground.A = InWidgetStyle.GetForegroundColor().A; FWidgetStyle WidgetStyle( InWidgetStyle ); WidgetStyle.SetForegroundColor( InvertedForeground ); return Run->OnPaint( Line, Block, DefaultStyle, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, WidgetStyle, bParentEnabled ); }
int32 SVirtualJoystick::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { int32 RetLayerId = LayerId; if (bVisible) { FLinearColor ColorAndOpacitySRGB = InWidgetStyle.GetColorAndOpacityTint(); ColorAndOpacitySRGB.A = FMath::RoundToInt(255.f * CurrentOpacity); for (int32 ControlIndex = 0; ControlIndex < Controls.Num(); ControlIndex++) { const FControlInfo& Control = Controls[ControlIndex]; if (Control.Image2.IsValid()) { FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( Control.VisualCenter - FVector2D(Control.CorrectedVisualSize.X * 0.5f, Control.CorrectedVisualSize.Y * 0.5f), Control.CorrectedVisualSize), Control.Image2.Get(), MyClippingRect, ESlateDrawEffect::None, ColorAndOpacitySRGB ); } if (Control.Image1.IsValid()) { FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( Control.VisualCenter + Control.ThumbPosition - FVector2D(Control.CorrectedThumbSize.X * 0.5f, Control.CorrectedThumbSize.Y * 0.5f), Control.CorrectedThumbSize), Control.Image1.Get(), MyClippingRect, ESlateDrawEffect::None, ColorAndOpacitySRGB ); } } } return RetLayerId; }
int32 SCircularThrobber::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const FLinearColor FinalColorAndOpacity( InWidgetStyle.GetColorAndOpacityTint() * PieceImage->GetTint( InWidgetStyle ) ); const FVector2D LocalOffset = (AllottedGeometry.Size - PieceImage->ImageSize) * 0.5f; const float DeltaAngle = NumPieces > 0 ? 2 * PI / NumPieces : 0; const float Phase = Curve.GetLerp() * 2 * PI; for (int32 PieceIdx = 0; PieceIdx < NumPieces; ++PieceIdx) { const float Angle = DeltaAngle * PieceIdx + Phase; // scale each piece linearly until the last piece is full size FSlateLayoutTransform PieceLocalTransform( (PieceIdx + 1) / (float)NumPieces, LocalOffset + LocalOffset * FVector2D(FMath::Sin(Angle), FMath::Cos(Angle))); FPaintGeometry PaintGeom = AllottedGeometry.ToPaintGeometry(PieceImage->ImageSize, PieceLocalTransform); FSlateDrawElement::MakeBox(OutDrawElements, LayerId, PaintGeom, PieceImage, MyClippingRect, ESlateDrawEffect::None, InWidgetStyle.GetColorAndOpacityTint() ); } return LayerId; }
int32 FSlateImageRun::OnPaint( const FPaintArgs& Args, const FTextLayout::FLineView& Line, const TSharedRef< ILayoutBlock >& Block, const FTextBlockStyle& DefaultStyle, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // The block size and offset values are pre-scaled, so we need to account for that when converting the block offsets into paint geometry const float InverseScale = Inverse(AllottedGeometry.Scale); if ( Image->DrawAs != ESlateBrushDrawType::NoDrawType ) { const FColor FinalColorAndOpacity( InWidgetStyle.GetColorAndOpacityTint() * Image->GetTint( InWidgetStyle ) ); const uint32 DrawEffects = bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; FSlateDrawElement::MakeBox( OutDrawElements, ++LayerId, AllottedGeometry.ToPaintGeometry(TransformVector(InverseScale, Block->GetSize()), FSlateLayoutTransform(TransformPoint(InverseScale, Block->GetLocationOffset()))), Image, MyClippingRect, DrawEffects, FinalColorAndOpacity ); } return LayerId; }
int32 FSlateTextLayout::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const FSlateRect ClippingRect = AllottedGeometry.GetClippingRect().IntersectionWith(MyClippingRect); const ESlateDrawEffect::Type DrawEffects = bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; static bool ShowDebug = false; FLinearColor BlockHue( 0, 1.0f, 1.0f, 0.5 ); int32 HighestLayerId = LayerId; for (const FTextLayout::FLineView& LineView : LineViews) { // Is this line visible? const FSlateRect LineViewRect(AllottedGeometry.AbsolutePosition + LineView.Offset, AllottedGeometry.AbsolutePosition + LineView.Offset + LineView.Size); const FSlateRect VisibleLineView = ClippingRect.IntersectionWith(LineViewRect); if (VisibleLineView.IsEmpty()) { continue; } // Render any underlays for this line const int32 HighestUnderlayLayerId = OnPaintHighlights( Args, LineView, LineView.UnderlayHighlights, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled ); const int32 BlockDebugLayer = HighestUnderlayLayerId; const int32 TextLayer = BlockDebugLayer + 1; int32 HighestBlockLayerId = TextLayer; // Render every block for this line for (const TSharedRef< ILayoutBlock >& Block : LineView.Blocks) { if ( ShowDebug ) { BlockHue.R += 50.0f; // The block size and offset values are pre-scaled, so we need to account for that when converting the block offsets into paint geometry const float InverseScale = Inverse(AllottedGeometry.Scale); FSlateDrawElement::MakeBox( OutDrawElements, BlockDebugLayer, AllottedGeometry.ToPaintGeometry(TransformVector(InverseScale, Block->GetSize()), FSlateLayoutTransform(TransformPoint(InverseScale, Block->GetLocationOffset()))), &DefaultTextStyle.HighlightShape, ClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * BlockHue.HSVToLinearRGB() ); } const TSharedRef< ISlateRun > Run = StaticCastSharedRef< ISlateRun >( Block->GetRun() ); int32 HighestRunLayerId = TextLayer; const TSharedPtr< ISlateRunRenderer > RunRenderer = StaticCastSharedPtr< ISlateRunRenderer >( Block->GetRenderer() ); if ( RunRenderer.IsValid() ) { HighestRunLayerId = RunRenderer->OnPaint( Args, LineView, Run, Block, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, TextLayer, InWidgetStyle, bParentEnabled ); } else { HighestRunLayerId = Run->OnPaint( Args, LineView, Block, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, TextLayer, InWidgetStyle, bParentEnabled ); } HighestBlockLayerId = FMath::Max( HighestBlockLayerId, HighestRunLayerId ); } // Render any overlays for this line const int32 HighestOverlayLayerId = OnPaintHighlights( Args, LineView, LineView.OverlayHighlights, DefaultTextStyle, AllottedGeometry, ClippingRect, OutDrawElements, HighestBlockLayerId, InWidgetStyle, bParentEnabled ); HighestLayerId = FMath::Max( HighestLayerId, HighestOverlayLayerId ); } return HighestLayerId; }
int32 SProgressBar::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // Used to track the layer ID we will return. int32 RetLayerId = LayerId; bool bEnabled = ShouldBeEnabled( bParentEnabled ); const ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const FSlateBrush* CurrentFillImage = GetFillImage(); const FLinearColor FillColorAndOpacitySRGB(InWidgetStyle.GetColorAndOpacityTint() * FillColorAndOpacity.Get().GetColor(InWidgetStyle) * CurrentFillImage->GetTint(InWidgetStyle)); const FLinearColor ColorAndOpacitySRGB = InWidgetStyle.GetColorAndOpacityTint(); TOptional<float> ProgressFraction = Percent.Get(); // Paint inside the border only. // Pre-snap the clipping rect to try and reduce common jitter, since the padding is typically only a single pixel. FSlateRect SnappedClippingRect = FSlateRect(FMath::RoundToInt(MyClippingRect.Left), FMath::RoundToInt(MyClippingRect.Top), FMath::RoundToInt(MyClippingRect.Right), FMath::RoundToInt(MyClippingRect.Bottom)); const FSlateRect ForegroundClippingRect = SnappedClippingRect.InsetBy(FMargin(BorderPadding.Get().X, BorderPadding.Get().Y)); const FSlateBrush* CurrentBackgroundImage = GetBackgroundImage(); FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry(), CurrentBackgroundImage, SnappedClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * CurrentBackgroundImage->GetTint( InWidgetStyle ) ); if( ProgressFraction.IsSet() ) { const float ClampedFraction = FMath::Clamp(ProgressFraction.GetValue(), 0.0f, 1.0f); switch (BarFillType) { case EProgressBarFillType::RightToLeft: { FSlateRect ClippedAllotedGeometry = FSlateRect(AllottedGeometry.AbsolutePosition, AllottedGeometry.AbsolutePosition + AllottedGeometry.Size * AllottedGeometry.Scale); ClippedAllotedGeometry.Left = ClippedAllotedGeometry.Right - ClippedAllotedGeometry.GetSize().X * ClampedFraction; // Draw Fill FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D::ZeroVector, FVector2D( AllottedGeometry.Size.X, AllottedGeometry.Size.Y )), CurrentFillImage, ForegroundClippingRect.IntersectionWith(ClippedAllotedGeometry), DrawEffects, FillColorAndOpacitySRGB ); break; } case EProgressBarFillType::FillFromCenter: { // Draw Fill FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D( (AllottedGeometry.Size.X * 0.5f) - ((AllottedGeometry.Size.X * ( ClampedFraction ))*0.5), 0.0f), FVector2D( AllottedGeometry.Size.X * ( ClampedFraction ) , AllottedGeometry.Size.Y )), CurrentFillImage, ForegroundClippingRect, DrawEffects, FillColorAndOpacitySRGB ); break; } case EProgressBarFillType::TopToBottom: { FSlateRect ClippedAllotedGeometry = FSlateRect(AllottedGeometry.AbsolutePosition, AllottedGeometry.AbsolutePosition + AllottedGeometry.Size * AllottedGeometry.Scale); ClippedAllotedGeometry.Bottom = ClippedAllotedGeometry.Top + ClippedAllotedGeometry.GetSize().Y * ClampedFraction; // Draw Fill FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D::ZeroVector, FVector2D( AllottedGeometry.Size.X, AllottedGeometry.Size.Y )), CurrentFillImage, ForegroundClippingRect.IntersectionWith(ClippedAllotedGeometry), DrawEffects, FillColorAndOpacitySRGB ); break; } case EProgressBarFillType::BottomToTop: { FSlateRect ClippedAllotedGeometry = FSlateRect(AllottedGeometry.AbsolutePosition, AllottedGeometry.AbsolutePosition + AllottedGeometry.Size * AllottedGeometry.Scale); ClippedAllotedGeometry.Top = ClippedAllotedGeometry.Bottom - ClippedAllotedGeometry.GetSize().Y * ClampedFraction; // Draw Fill FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D::ZeroVector, FVector2D( AllottedGeometry.Size.X, AllottedGeometry.Size.Y )), CurrentFillImage, ForegroundClippingRect.IntersectionWith(ClippedAllotedGeometry), DrawEffects, FillColorAndOpacitySRGB ); break; } case EProgressBarFillType::LeftToRight: default: { FSlateRect ClippedAllotedGeometry = FSlateRect(AllottedGeometry.AbsolutePosition, AllottedGeometry.AbsolutePosition + AllottedGeometry.Size * AllottedGeometry.Scale); ClippedAllotedGeometry.Right = ClippedAllotedGeometry.Left + ClippedAllotedGeometry.GetSize().X * ClampedFraction; // Draw Fill FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D::ZeroVector, FVector2D( AllottedGeometry.Size.X, AllottedGeometry.Size.Y )), CurrentFillImage, ForegroundClippingRect.IntersectionWith(ClippedAllotedGeometry), DrawEffects, FillColorAndOpacitySRGB ); break; } } } else { const FSlateBrush* CurrentMarqueeImage = GetMarqueeImage(); // Draw Marquee const float MarqueeAnimOffset = CurrentMarqueeImage->ImageSize.X * MarqueeOffset; const float MarqueeImageSize = CurrentMarqueeImage->ImageSize.X; FSlateDrawElement::MakeBox( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry( FVector2D( MarqueeAnimOffset - MarqueeImageSize, 0.0f ), FVector2D( AllottedGeometry.Size.X + MarqueeImageSize, AllottedGeometry.Size.Y )), CurrentMarqueeImage, ForegroundClippingRect, DrawEffects, ColorAndOpacitySRGB ); } return RetLayerId - 1; }
int32 SRealtimeProfilerLineGraph::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // Rendering info bool bEnabled = ShouldBeEnabled( bParentEnabled ); ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const FSlateBrush* TimelineAreaBrush = FEditorStyle::GetBrush("Profiler.LineGraphArea"); const FSlateBrush* WhiteBrush = FEditorStyle::GetBrush("WhiteTexture"); // Draw timeline background FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry( FVector2D(0,0), FVector2D(AllottedGeometry.Size.X,AllottedGeometry.Size.Y) ), TimelineAreaBrush, MyClippingRect, DrawEffects, TimelineAreaBrush->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() ); LayerId++; //Draw axies: TArray<FVector2D> AxisPoints; AxisPoints.Add(GetWidgetPosition(0, 1, AllottedGeometry)); AxisPoints.Add(GetWidgetPosition(0, 0, AllottedGeometry)); AxisPoints.Add(GetWidgetPosition(1, 0, AllottedGeometry)); FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), AxisPoints, MyClippingRect, DrawEffects, WhiteBrush->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() ); LayerId++; //Draw line graph: TArray<FVector2D> LinePoints; //FPS Chart points: TArray<FVector2D> UnitFramePoints; TArray<FVector2D> UnitRenderPoints; TArray<FVector2D> UnitGamePoints; TArray<FVector2D> UnitGPUPoints; float PixelDistanceBetweenPoints = ((float)AllottedGeometry.Size.X/MaxFrames.Get())*Zoom; int32 NumPointsToDraw = (AllottedGeometry.Size.X/PixelDistanceBetweenPoints)+2; //Convert Offset to FrameOffset float FrameOffset = (-Offset/Zoom)*MaxFrames.Get(); int32 StartPointIndex = FMath::FloorToInt( FrameOffset ); if(StartPointIndex <= 0) StartPointIndex = 0; int32 EndPointIndex = StartPointIndex + NumPointsToDraw - 1; for(int i=StartPointIndex; i<=EndPointIndex; ++i) { if(i>=ProfileDataArray.Num()) break; float XPos = i*PixelDistanceBetweenPoints - FrameOffset*PixelDistanceBetweenPoints; float YPos; if(!bDisplayFPSChart) { YPos = ProfileDataArray.GetData()[i]->DurationMs/MaxValue.Get(); YPos = (AllottedGeometry.Size.Y-1) - (YPos*AllottedGeometry.Size.Y); LinePoints.Add(FVector2D((int32)XPos,(int32)YPos)); } else { YPos = FPSChartDataArray.GetData()[i].UnitFrame/MaxValue.Get(); YPos = (AllottedGeometry.Size.Y-1) - (YPos*AllottedGeometry.Size.Y); UnitFramePoints.Add(FVector2D((int32)XPos,(int32)YPos)); YPos = FPSChartDataArray.GetData()[i].UnitRender/MaxValue.Get(); YPos = (AllottedGeometry.Size.Y-1) - (YPos*AllottedGeometry.Size.Y); UnitRenderPoints.Add(FVector2D((int32)XPos,(int32)YPos)); YPos = FPSChartDataArray.GetData()[i].UnitGame/MaxValue.Get(); YPos = (AllottedGeometry.Size.Y-1) - (YPos*AllottedGeometry.Size.Y); UnitGamePoints.Add(FVector2D((int32)XPos,(int32)YPos)); YPos = FPSChartDataArray.GetData()[i].UnitGPU/MaxValue.Get(); YPos = (AllottedGeometry.Size.Y-1) - (YPos*AllottedGeometry.Size.Y); UnitGPUPoints.Add(FVector2D((int32)XPos,(int32)YPos)); } } if(!bDisplayFPSChart) { FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), LinePoints, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * FLinearColor(1.0f, 0.0f, 0.0f, 1.0f) ); LayerId++; } else { FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), UnitFramePoints, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * FLinearColor(0.0f, 1.0f, 0.0f, 1.0f) ); LayerId++; FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), UnitRenderPoints, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * FLinearColor(0.0f, 0.0f, 1.0f, 1.0f) ); LayerId++; FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), UnitGamePoints, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * FLinearColor(1.0f, 0.0f, 0.0f, 1.0f) ); LayerId++; FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), UnitGPUPoints, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * FLinearColor(1.0f, 1.0f, 0.0f, 1.0f) ); LayerId++; } //Draw 30FPS line: TArray<FVector2D> FPS30LinePoints; FPS30LinePoints.Add(GetWidgetPosition(0, 33.3333/MaxValue.Get(), AllottedGeometry)); FPS30LinePoints.Add(GetWidgetPosition(1, 33.3333/MaxValue.Get(), AllottedGeometry)); FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), FPS30LinePoints, MyClippingRect, DrawEffects, WhiteBrush->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() ); LayerId++; //Draw 60FPS line: TArray<FVector2D> FPS60LinePoints; FPS60LinePoints.Add(GetWidgetPosition(0, 16.6666/MaxValue.Get(), AllottedGeometry)); FPS60LinePoints.Add(GetWidgetPosition(1, 16.6666/MaxValue.Get(), AllottedGeometry)); FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), FPS60LinePoints, MyClippingRect, DrawEffects, WhiteBrush->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() ); LayerId++; //Draw mouse cursor: TArray<FVector2D> MouseCursorPoints; MouseCursorPoints.Add(FVector2D(MousePosition.X, 0)); MouseCursorPoints.Add(FVector2D(MousePosition.X, AllottedGeometry.Size.Y)); FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), MouseCursorPoints, MyClippingRect, DrawEffects, WhiteBrush->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() ); LayerId++; // Paint children SCompoundWidget::OnPaint( Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled); return LayerId; }
int32 SHistogram::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { static double TotalTime = 0.0f; static uint32 NumCalls = 0; const double StartTime = FPlatformTime::Seconds(); const TSharedRef< FSlateFontMeasure > FontMeasureService = FSlateApplication::Get().GetRenderer()->GetFontMeasureService(); // Rendering info. const bool bEnabled = ShouldBeEnabled( bParentEnabled ); ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const FSlateBrush* TimelineAreaBrush = FEditorStyle::GetBrush("Profiler.LineGraphArea"); const FSlateBrush* WhiteBrush = FEditorStyle::GetBrush("WhiteTexture"); const FSlateBrush* FillImage = FEditorStyle::GetBrush("TaskGraph.Mono"); // Draw background. FSlateDrawElement::MakeBox ( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry( FVector2D(0,0), FVector2D(AllottedGeometry.Size.X,AllottedGeometry.Size.Y) ), TimelineAreaBrush, MyClippingRect, DrawEffects, TimelineAreaBrush->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() ); LayerId++; const float LabelBuffer = 25.0f; // draw the grid lines uint32 CountX = (uint32)((AllottedGeometry.Size.X-LabelBuffer*2.0f) / Description.GetBinCount()); float StartX = LabelBuffer; static const FLinearColor GridColor = FLinearColor(0.0f,0.0f,0.0f, 0.25f); static const FLinearColor GridTextColor = FLinearColor(1.0f,1.0f,1.0f, 0.25f); static const FLinearColor BorderColor = FLinearColor(0.0f,0.0f,0.0f,1.0f); FSlateFontInfo SummaryFont(FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 8 ); const float MaxFontCharHeight = FontMeasureService->Measure( TEXT("!"), SummaryFont ).Y; TArray<FVector2D> LinePoints; // draw the histogram box LinePoints.Add( FVector2D(StartX-1, LabelBuffer-1) ); LinePoints.Add( FVector2D(StartX + Description.GetBinCount()*CountX+1, LabelBuffer-1) ); LinePoints.Add( FVector2D(StartX + Description.GetBinCount()*CountX+1, AllottedGeometry.Size.Y - LabelBuffer+1) ); LinePoints.Add( FVector2D(StartX-1, AllottedGeometry.Size.Y - LabelBuffer+1) ); LinePoints.Add( FVector2D(StartX-1, LabelBuffer-1) ); FSlateDrawElement::MakeLines ( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), LinePoints, MyClippingRect, DrawEffects, BorderColor ); LinePoints.Empty(); LayerId++; // draw the vertical lines for (int32 Index = 0; Index < Description.GetBinCount(); ++Index) { float MarkerPosX = StartX + Index * CountX; LinePoints.Add( FVector2D(MarkerPosX, LabelBuffer-1) ); LinePoints.Add( FVector2D(MarkerPosX, AllottedGeometry.Size.Y - LabelBuffer+1) ); FSlateDrawElement::MakeLines ( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), LinePoints, MyClippingRect, DrawEffects, GridColor ); LinePoints.Empty(); // Bottom - X-Axes numbers, starting from MinValue const FString XLabel = FString::Printf(TEXT("%.0f"), Description.MinValue + Index*Description.Interval); float FontCharWidth = FontMeasureService->Measure(XLabel, SummaryFont).X; FSlateDrawElement::MakeText ( OutDrawElements, LayerId, AllottedGeometry.ToOffsetPaintGeometry( FVector2D(MarkerPosX-FontCharWidth/2.0f,AllottedGeometry.Size.Y-LabelBuffer/2.0f-MaxFontCharHeight/2.0f) ), XLabel, SummaryFont, MyClippingRect, DrawEffects, FLinearColor::White ); } LayerId++; // draw the horizontal lines float CountY = (AllottedGeometry.Size.Y-LabelBuffer*2.0f) / 4; float StartY = LabelBuffer; for (int32 Index = 0; Index < 5; ++Index) { float MarkerPosY = StartY + Index * CountY; LinePoints.Add( FVector2D(StartX, MarkerPosY) ); LinePoints.Add( FVector2D(StartX + Description.GetBinCount()*CountX, MarkerPosY) ); FSlateDrawElement::MakeLines ( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), LinePoints, MyClippingRect, DrawEffects, GridColor ); LinePoints.Empty(); // Bottom - Y-Axes numbers, starting from 0 const FString YLabel = FString::Printf(TEXT("%i"), Description.Normalize ? 25 * (4-Index) : Description.GetTotalCount() / 4 * Index); float FontCharWidth = FontMeasureService->Measure(YLabel, SummaryFont).X; FSlateDrawElement::MakeText ( OutDrawElements, LayerId, AllottedGeometry.ToOffsetPaintGeometry( FVector2D(LabelBuffer/2.0f-FontCharWidth/2.0f,MarkerPosY-MaxFontCharHeight/2.0f) ), YLabel, SummaryFont, MyClippingRect, DrawEffects, FLinearColor::White ); } LayerId++; for (int32 Index = 0; Index < Description.GetBinCount(); ++Index) { float MarkerPosX = StartX + Index * CountX; float SizeY = (float)Description.GetCount(Index) / (float)Description.GetTotalCount() * (AllottedGeometry.Size.Y - LabelBuffer*2.0f); FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry( FVector2D(MarkerPosX, AllottedGeometry.Size.Y - SizeY- LabelBuffer), FVector2D(CountX, SizeY) ), FillImage, MyClippingRect, DrawEffects, FLinearColor::Green ); } return SCompoundWidget::OnPaint( Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled && IsEnabled() ); }
int32 STestFunctionWidget::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const { // Rendering info bool bEnabled = ShouldBeEnabled(bParentEnabled); ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const FSlateBrush* TimelineAreaBrush = FEditorStyle::GetBrush("Profiler.LineGraphArea"); const FSlateBrush* WhiteBrush = FEditorStyle::GetBrush("WhiteTexture"); // Draw timeline background FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(FVector2D(0, 0), FVector2D(AllottedGeometry.Size.X, AllottedGeometry.Size.Y)), TimelineAreaBrush, MyClippingRect, DrawEffects, TimelineAreaBrush->GetTint(InWidgetStyle) * InWidgetStyle.GetColorAndOpacityTint() ); LayerId++; // Draw filter background if (bShowLowPassFilter) { FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(FVector2D(0, 0), FVector2D(FMath::TruncToInt(FilterLowX * AllottedGeometry.Size.X), AllottedGeometry.Size.Y)), WhiteBrush, MyClippingRect, DrawEffects, WhiteBrush->GetTint(InWidgetStyle) * FLinearColor(1.0f, 0.0f, 0.0f, 0.4f) ); LayerId++; } if (bShowHiPassFilter) { FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(FVector2D(FMath::TruncToInt(FilterHiX * AllottedGeometry.Size.X), 0), FVector2D(AllottedGeometry.Size.X, AllottedGeometry.Size.Y)), WhiteBrush, MyClippingRect, DrawEffects, WhiteBrush->GetTint(InWidgetStyle) * FLinearColor(1.0f, 0.0f, 0.0f, 0.5f) ); LayerId++; } // Draw axies TArray<FVector2D> AxisPoints; AxisPoints.Add(GetWidgetPosition(0, 1, AllottedGeometry)); AxisPoints.Add(GetWidgetPosition(0, 0, AllottedGeometry)); AxisPoints.Add(GetWidgetPosition(1, 0, AllottedGeometry)); FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), AxisPoints, MyClippingRect, DrawEffects, WhiteBrush->GetTint(InWidgetStyle) * InWidgetStyle.GetColorAndOpacityTint() ); LayerId++; // Draw clamping and filtering filters if (bShowClampMin) { TArray<FVector2D> ClampLine; ClampLine.Add(GetWidgetPosition(ClampMinX, 0, AllottedGeometry)); ClampLine.Add(GetWidgetPosition(ClampMinX, 1, AllottedGeometry)); FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), ClampLine, MyClippingRect, DrawEffects, WhiteBrush->GetTint(InWidgetStyle) * FLinearColor(1.0f, 1.0f, 0.0f, 1.0f) ); LayerId++; } if (bShowClampMax) { TArray<FVector2D> ClampLine; ClampLine.Add(GetWidgetPosition(ClampMaxX, 0, AllottedGeometry)); ClampLine.Add(GetWidgetPosition(ClampMaxX, 1, AllottedGeometry)); FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), ClampLine, MyClippingRect, DrawEffects, WhiteBrush->GetTint(InWidgetStyle) * FLinearColor(1.0f, 1.0f, 0.0f, 1.0f) ); LayerId++; } if (bShowLowPassFilter) { TArray<FVector2D> FilterLine; FilterLine.Add(GetWidgetPosition(FilterLowX, 0, AllottedGeometry)); FilterLine.Add(GetWidgetPosition(FilterLowX, 1, AllottedGeometry)); FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), FilterLine, MyClippingRect, DrawEffects, WhiteBrush->GetTint(InWidgetStyle) * FLinearColor(1.0f, 0.0f, 0.0f, 1.0f) ); LayerId++; } if (bShowHiPassFilter) { TArray<FVector2D> FilterLine; FilterLine.Add(GetWidgetPosition(FilterHiX, 0, AllottedGeometry)); FilterLine.Add(GetWidgetPosition(FilterHiX, 1, AllottedGeometry)); FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), FilterLine, MyClippingRect, DrawEffects, WhiteBrush->GetTint(InWidgetStyle) * FLinearColor(1.0f, 0.0f, 0.0f, 1.0f) ); LayerId++; } // Draw line graph TArray<FVector2D> LinePoints; const float DeltaX = ((float)AllottedGeometry.Size.X / (ScoreValues.Num() - 1)); for (int32 Idx = 0; Idx < ScoreValues.Num(); Idx++) { const float XPos = Idx * DeltaX; const float YPos = (AllottedGeometry.Size.Y - 1) - (ScoreValues[Idx] * AllottedGeometry.Size.Y); LinePoints.Add(FVector2D(FMath::TruncToInt(XPos), FMath::TruncToInt(YPos))); } FSlateDrawElement::MakeLines( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), LinePoints, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * FLinearColor(0.0f, 0.0f, 1.0f, 1.0f) ); LayerId++; return LayerId; }
int32 SViewport::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { #if SLATE_HD_STATS SCOPE_CYCLE_COUNTER( STAT_SlateOnPaint_SViewport ); #endif bool bEnabled = ShouldBeEnabled( bParentEnabled ); bool bShowDisabledEffect = ShowDisabledEffect.Get(); ESlateDrawEffect::Type DrawEffects = bShowDisabledEffect && !bEnabled ? ESlateDrawEffect::DisabledEffect : ESlateDrawEffect::None; // Viewport texture alpha channels are often in an indeterminate state, even after the resolve, // so we'll tell the shader to not use the alpha channel when blending if( bIgnoreTextureAlpha ) { DrawEffects |= ESlateDrawEffect::IgnoreTextureAlpha; } TSharedPtr<ISlateViewport> ViewportInterfacePin = ViewportInterface.Pin(); // Tell the interface that we are drawing. if (ViewportInterfacePin.IsValid()) { ViewportInterfacePin->OnDrawViewport( AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled ); } // Only draw a quad if not rendering directly to the backbuffer if( !ShouldRenderDirectly() ) { if( ViewportInterfacePin.IsValid() && ViewportInterfacePin->GetViewportRenderTargetTexture() != nullptr ) { FSlateDrawElement::MakeViewport( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), ViewportInterfacePin, MyClippingRect, bEnableGammaCorrection, bEnableBlending, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() ); } else { // Viewport isn't ready yet, so just draw a black box static FSlateColorBrush BlackBrush( FColor::Black ); FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), &BlackBrush, MyClippingRect, DrawEffects, BlackBrush.GetTint( InWidgetStyle ) ); } } int32 Layer = SCompoundWidget::OnPaint(Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bEnabled ); if( ViewportInterfacePin.IsValid() && ViewportInterfacePin->IsSoftwareCursorVisible() ) { const FVector2D CursorPosScreenSpace = FSlateApplication::Get().GetCursorPos(); // @todo Slate: why are we calling OnCursorQuery in here? FCursorReply Reply = ViewportInterfacePin->OnCursorQuery( AllottedGeometry, FPointerEvent( FSlateApplicationBase::CursorPointerIndex, CursorPosScreenSpace, CursorPosScreenSpace, FVector2D::ZeroVector, TSet<FKey>(), FModifierKeysState() ) ); EMouseCursor::Type CursorType = Reply.GetCursor(); const FSlateBrush* Brush = FCoreStyle::Get().GetBrush(TEXT("SoftwareCursor_Grab")); if( CursorType == EMouseCursor::CardinalCross ) { Brush = FCoreStyle::Get().GetBrush(TEXT("SoftwareCursor_CardinalCross")); } LayerId++; FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry( ViewportInterfacePin->GetSoftwareCursorPosition() - ( Brush->ImageSize / 2 ), Brush->ImageSize ), Brush, MyClippingRect ); } return Layer; }
int32 SObjectNameEditableTextBox::OnPaint( const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { int32 StartLayer = SCompoundWidget::OnPaint( AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled ); const int32 TextLayer = 1; // See if a disabled effect should be used bool bEnabled = ShouldBeEnabled( bParentEnabled ); ESlateDrawEffect::Type DrawEffects = (bEnabled) ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const double CurrentTime = FSlateApplication::Get().GetCurrentTime(); const float DrawPositionY = ( AllottedGeometry.Size.Y / 2 ) - ( AllottedGeometry.Size.Y / 2 ); // Draw highlight targeting effect const float TimeSinceHighlightInteraction = (float)( CurrentTime - LastCommittedTime ); if( TimeSinceHighlightInteraction <= HighlightTargetEffectDuration ) { // Compute animation progress float EffectAlpha = FMath::Clamp( TimeSinceHighlightInteraction / HighlightTargetEffectDuration, 0.0f, 1.0f ); EffectAlpha = 1.0f - EffectAlpha * EffectAlpha; // Inverse square falloff (looks nicer!) float EffectOpacity = EffectAlpha; // Figure out a universally visible highlight color. FColor HighlightTargetColorAndOpacity = ( (FLinearColor::White - ColorAndOpacity.Get())*0.5f + FLinearColor(+0.4f, +0.1f, -0.2f)) * InWidgetStyle.GetColorAndOpacityTint(); HighlightTargetColorAndOpacity.A = HighlightTargetOpacity * EffectOpacity * 255.0f; // Compute the bounds offset of the highlight target from where the highlight target spring // extents currently lie. This is used to "grow" or "shrink" the highlight as needed. const float CommittingAnimOffset = CommittingAnimOffsetPercent * AllottedGeometry.Size.Y; // Choose an offset amount depending on whether we're highlighting, or clearing highlight const float EffectOffset = EffectAlpha * CommittingAnimOffset; const float HighlightLeftX = HighlightTargetLeftSpring.GetPosition() - EffectOffset; const float HighlightRightX = HighlightTargetRightSpring.GetPosition() + EffectOffset; const float HighlightTopY = 0.0f - EffectOffset; const float HighlightBottomY = AllottedGeometry.Size.Y + EffectOffset; const FVector2D DrawPosition = FVector2D( HighlightLeftX, HighlightTopY ); const FVector2D DrawSize = FVector2D( HighlightRightX - HighlightLeftX, HighlightBottomY - HighlightTopY ); const FSlateBrush* StyleInfo = FEditorStyle::GetBrush("DetailsView.NameChangeCommitted"); // NOTE: We rely on scissor clipping for the highlight rectangle FSlateDrawElement::MakeBox( OutDrawElements, LayerId + TextLayer, AllottedGeometry.ToPaintGeometry( DrawPosition, DrawSize ), // Position, Size, Scale StyleInfo, // Style MyClippingRect, // Clipping rect DrawEffects, // Effects to use HighlightTargetColorAndOpacity ); // Color } return LayerId + TextLayer; }
int32 SScrubWidget::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const bool bActiveFeedback = IsHovered() || bDragging; const FSlateBrush* BackgroundImage = bActiveFeedback ? FEditorStyle::GetBrush("SpinBox.Background.Hovered") : FEditorStyle::GetBrush("SpinBox.Background"); const FSlateBrush* FillImage = bActiveFeedback ? FEditorStyle::GetBrush("SpinBox.Fill.Hovered") : FEditorStyle::GetBrush("SpinBox.Fill"); const int32 BackgroundLayer = LayerId; const FSlateFontInfo SmallLayoutFont( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 10 ); const bool bEnabled = ShouldBeEnabled( bParentEnabled ); const ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const int32 TextLayer = BackgroundLayer + 1; const FSlateBrush* StyleInfo = FEditorStyle::GetBrush( TEXT( "ProgressBar.Background" ) ); const float GeomHeight = AllottedGeometry.Size.Y; if ( NumOfKeys.Get() > 0 && SequenceLength.Get() > 0) { const FTrackScaleInfo TimeScaleInfo(ViewInputMin.Get(), ViewInputMax.Get(), 0.f, 0.f, AllottedGeometry.Size); const int32 Divider = SScrubWidget::GetDivider( ViewInputMin.Get(), ViewInputMax.Get(), AllottedGeometry.Size, SequenceLength.Get(), NumOfKeys.Get() ); const float HalfDivider = Divider/2.f; const int32 TotalNumKeys = NumOfKeys.Get(); const float TimePerKey = (TotalNumKeys > 0) ? SequenceLength.Get() / (float)(TotalNumKeys) : 0.0f; for (float KeyVal = 0; KeyVal < TotalNumKeys; KeyVal += HalfDivider) { const float CurValue = KeyVal*TimePerKey; const float XPos = TimeScaleInfo.InputToLocalX(CurValue); if ( FGenericPlatformMath::Fmod(KeyVal, Divider) == 0.f ) { const FVector2D Offset(XPos, 0.f); const FVector2D Size(1, GeomHeight); // draw each box with key frame FSlateDrawElement::MakeBox( OutDrawElements, BackgroundLayer, AllottedGeometry.ToPaintGeometry(Offset, Size), StyleInfo, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() ); const int32 FrameNumber = KeyVal; const FString FrameString = FString::Printf(TEXT("%d"), (FrameNumber)); const FVector2D TextOffset(XPos+2.f, 0.f); const TSharedRef< FSlateFontMeasure > FontMeasureService = FSlateApplication::Get().GetRenderer()->GetFontMeasureService(); const FVector2D TextSize = FontMeasureService->Measure(FrameString, SmallLayoutFont); FSlateDrawElement::MakeText( OutDrawElements, TextLayer, AllottedGeometry.ToPaintGeometry(TextOffset, TextSize), FrameString, SmallLayoutFont, MyClippingRect, DrawEffects); } else if (HalfDivider > 1.f) { const float Height = GeomHeight; const FVector2D Offset(XPos, Height*0.25f); const FVector2D Size(1, Height*0.5f); // draw each box with key frame FSlateDrawElement::MakeBox( OutDrawElements, BackgroundLayer, AllottedGeometry.ToPaintGeometry(Offset, Size), StyleInfo, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() ); } } const int32 ArrowLayer = TextLayer + 1; { const float XPos = TimeScaleInfo.InputToLocalX(ValueAttribute.Get()); const float Height = AllottedGeometry.Size.Y; const FVector2D Offset( XPos - Height*0.25f, 0.f ); FPaintGeometry MyGeometry = AllottedGeometry.ToPaintGeometry( Offset, FVector2D(Height*0.5f, Height) ); FLinearColor ScrubColor = InWidgetStyle.GetColorAndOpacityTint(); ScrubColor.A = ScrubColor.A*0.5f; ScrubColor.B *= 0.1f; ScrubColor.G *= 0.1f; FSlateDrawElement::MakeBox( OutDrawElements, ArrowLayer, MyGeometry, StyleInfo, MyClippingRect, DrawEffects, ScrubColor ); } // Draggable Bars if ( DraggableBars.IsBound() ) { for ( const float BarValue : DraggableBars.Get() ) { const float BarXPos = TimeScaleInfo.InputToLocalX(BarValue); const FVector2D BarOffset(BarXPos-2.f, 0.f); const FVector2D Size(4.f, GeomHeight); FLinearColor BarColor = InWidgetStyle.GetColorAndOpacityTint(); BarColor.R *= 0.1f; BarColor.G *= 0.1f; FSlateDrawElement::MakeBox( OutDrawElements, ArrowLayer+1, AllottedGeometry.ToPaintGeometry(BarOffset, Size), StyleInfo, MyClippingRect, DrawEffects, BarColor ); } } return FMath::Max( ArrowLayer, SCompoundWidget::OnPaint( Args, AllottedGeometry, MyClippingRect, OutDrawElements, ArrowLayer, InWidgetStyle, bEnabled ) ); } return SCompoundWidget::OnPaint( Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bEnabled ); }
int32 SGraphPanel::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { #if SLATE_HD_STATS SCOPE_CYCLE_COUNTER( STAT_SlateOnPaint_SGraphPanel ); #endif CachedAllottedGeometryScaledSize = AllottedGeometry.Size * AllottedGeometry.Scale; //Style used for objects that are the same between revisions FWidgetStyle FadedStyle = InWidgetStyle; FadedStyle.BlendColorAndOpacityTint(FLinearColor(0.45f,0.45f,0.45f,0.45f)); // First paint the background const UEditorExperimentalSettings& Options = *GetDefault<UEditorExperimentalSettings>(); const FSlateBrush* BackgroundImage = FEditorStyle::GetBrush(TEXT("Graph.Panel.SolidBackground")); PaintBackgroundAsLines(BackgroundImage, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId); const float ZoomFactor = AllottedGeometry.Scale * GetZoomAmount(); FArrangedChildren ArrangedChildren(EVisibility::Visible); ArrangeChildNodes(AllottedGeometry, ArrangedChildren); // Determine some 'global' settings based on current LOD const bool bDrawShadowsThisFrame = GetCurrentLOD() > EGraphRenderingLOD::LowestDetail; // Because we paint multiple children, we must track the maximum layer id that they produced in case one of our parents // wants to an overlay for all of its contents. // Save LayerId for comment boxes to ensure they always appear below nodes & wires const int32 CommentNodeShadowLayerId = LayerId++; const int32 CommentNodeLayerId = LayerId++; // Save a LayerId for wires, which appear below nodes but above comments // We will draw them later, along with the arrows which appear above nodes. const int32 WireLayerId = LayerId++; const int32 NodeShadowsLayerId = LayerId; const int32 NodeLayerId = NodeShadowsLayerId + 1; int32 MaxLayerId = NodeLayerId; const FVector2D NodeShadowSize = GetDefault<UGraphEditorSettings>()->GetShadowDeltaSize(); const UEdGraphSchema* Schema = GraphObj->GetSchema(); // Draw the child nodes { // When drawing a marquee, need a preview of what the selection will be. const FGraphPanelSelectionSet* SelectionToVisualize = &(SelectionManager.SelectedNodes); FGraphPanelSelectionSet SelectionPreview; if ( Marquee.IsValid() ) { ApplyMarqueeSelection(Marquee, SelectionManager.SelectedNodes, SelectionPreview); SelectionToVisualize = &SelectionPreview; } // Context for rendering node infos FKismetNodeInfoContext Context(GraphObj); TArray<FGraphDiffControl::FNodeMatch> NodeMatches; for (int32 ChildIndex = 0; ChildIndex < ArrangedChildren.Num(); ++ChildIndex) { FArrangedWidget& CurWidget = ArrangedChildren[ChildIndex]; TSharedRef<SGraphNode> ChildNode = StaticCastSharedRef<SGraphNode>(CurWidget.Widget); // Examine node to see what layers we should be drawing in int32 ShadowLayerId = NodeShadowsLayerId; int32 ChildLayerId = NodeLayerId; // If a comment node, draw in the dedicated comment slots { UObject* NodeObj = ChildNode->GetObjectBeingDisplayed(); if (NodeObj && NodeObj->IsA(UEdGraphNode_Comment::StaticClass())) { ShadowLayerId = CommentNodeShadowLayerId; ChildLayerId = CommentNodeLayerId; } } const bool bNodeIsVisible = FSlateRect::DoRectanglesIntersect( CurWidget.Geometry.GetClippingRect(), MyClippingRect ); if (bNodeIsVisible) { const bool bSelected = SelectionToVisualize->Contains( StaticCastSharedRef<SNodePanel::SNode>(CurWidget.Widget)->GetObjectBeingDisplayed() ); // Handle Node renaming once the node is visible if( bSelected && ChildNode->IsRenamePending() ) { ChildNode->ApplyRename(); } // Draw the node's shadow. if (bDrawShadowsThisFrame || bSelected) { const FSlateBrush* ShadowBrush = ChildNode->GetShadowBrush(bSelected); FSlateDrawElement::MakeBox( OutDrawElements, ShadowLayerId, CurWidget.Geometry.ToInflatedPaintGeometry(NodeShadowSize), ShadowBrush, MyClippingRect ); } // Draw the comments and information popups for this node, if it has any. { const SNodePanel::SNode::FNodeSlot& CommentSlot = ChildNode->GetOrAddSlot( ENodeZone::TopCenter ); float CommentBubbleY = -CommentSlot.Offset.Get().Y; Context.bSelected = bSelected; TArray<FGraphInformationPopupInfo> Popups; { ChildNode->GetNodeInfoPopups(&Context, /*out*/ Popups); } for (int32 PopupIndex = 0; PopupIndex < Popups.Num(); ++PopupIndex) { FGraphInformationPopupInfo& Popup = Popups[PopupIndex]; PaintComment(Popup.Message, CurWidget.Geometry, MyClippingRect, OutDrawElements, ChildLayerId, Popup.BackgroundColor, /*inout*/ CommentBubbleY, InWidgetStyle); } } int32 CurWidgetsMaxLayerId; { UEdGraphNode* NodeObj = Cast<UEdGraphNode>(ChildNode->GetObjectBeingDisplayed()); /** When diffing nodes, nodes that are different between revisions are opaque, nodes that have not changed are faded */ FGraphDiffControl::FNodeMatch NodeMatch = FGraphDiffControl::FindNodeMatch(GraphObjToDiff, NodeObj, NodeMatches); if (NodeMatch.IsValid()) { NodeMatches.Add(NodeMatch); } const bool bNodeIsDifferent = (!GraphObjToDiff || NodeMatch.Diff()); /* When dragging off a pin, we want to duck the alpha of some nodes */ TSharedPtr< SGraphPin > OnlyStartPin = (1 == PreviewConnectorFromPins.Num()) ? PreviewConnectorFromPins[0].FindInGraphPanel(*this) : TSharedPtr< SGraphPin >(); const bool bNodeIsNotUsableInCurrentContext = Schema->FadeNodeWhenDraggingOffPin(NodeObj, OnlyStartPin.IsValid() ? OnlyStartPin.Get()->GetPinObj() : NULL); const FWidgetStyle& NodeStyleToUse = (bNodeIsDifferent && !bNodeIsNotUsableInCurrentContext)? InWidgetStyle : FadedStyle; // Draw the node.O CurWidgetsMaxLayerId = CurWidget.Widget->Paint( Args.WithNewParent(this), CurWidget.Geometry, MyClippingRect, OutDrawElements, ChildLayerId, NodeStyleToUse, ShouldBeEnabled( bParentEnabled ) ); } // Draw the node's overlay, if it has one. { // Get its size const FVector2D WidgetSize = CurWidget.Geometry.Size; { TArray<FOverlayBrushInfo> OverlayBrushes; ChildNode->GetOverlayBrushes(bSelected, WidgetSize, /*out*/ OverlayBrushes); for (int32 BrushIndex = 0; BrushIndex < OverlayBrushes.Num(); ++BrushIndex) { FOverlayBrushInfo& OverlayInfo = OverlayBrushes[BrushIndex]; const FSlateBrush* OverlayBrush = OverlayInfo.Brush; if(OverlayBrush != NULL) { FPaintGeometry BouncedGeometry = CurWidget.Geometry.ToPaintGeometry(OverlayInfo.OverlayOffset, OverlayBrush->ImageSize, 1.f); // Handle bouncing const float BounceValue = FMath::Sin(2.0f * PI * BounceCurve.GetLerpLooping()); BouncedGeometry.DrawPosition += (OverlayInfo.AnimationEnvelope * BounceValue * ZoomFactor); CurWidgetsMaxLayerId++; FSlateDrawElement::MakeBox( OutDrawElements, CurWidgetsMaxLayerId, BouncedGeometry, OverlayBrush, MyClippingRect ); } } } { TArray<FOverlayWidgetInfo> OverlayWidgets = ChildNode->GetOverlayWidgets(bSelected, WidgetSize); for (int32 WidgetIndex = 0; WidgetIndex < OverlayWidgets.Num(); ++WidgetIndex) { FOverlayWidgetInfo& OverlayInfo = OverlayWidgets[WidgetIndex]; if(OverlayInfo.Widget->GetVisibility() == EVisibility::Visible) { // call SlatePrepass as these widgets are not in the 'normal' child hierarchy OverlayInfo.Widget->SlatePrepass(); const FGeometry WidgetGeometry = CurWidget.Geometry.MakeChild(OverlayInfo.OverlayOffset, OverlayInfo.Widget->GetDesiredSize(), 1.f); OverlayInfo.Widget->Paint(Args.WithNewParent(this), WidgetGeometry, MyClippingRect, OutDrawElements, CurWidgetsMaxLayerId, InWidgetStyle, bParentEnabled); } } } } MaxLayerId = FMath::Max( MaxLayerId, CurWidgetsMaxLayerId + 1 ); } } } MaxLayerId += 1; // Draw connections between pins if (Children.Num() > 0 ) { //@TODO: Pull this into a factory like the pin and node ones FConnectionDrawingPolicy* ConnectionDrawingPolicy; { ConnectionDrawingPolicy = Schema->CreateConnectionDrawingPolicy(WireLayerId, MaxLayerId, ZoomFactor, MyClippingRect, OutDrawElements, GraphObj); if (!ConnectionDrawingPolicy) { if (Schema->IsA(UAnimationGraphSchema::StaticClass())) { ConnectionDrawingPolicy = new FAnimGraphConnectionDrawingPolicy(WireLayerId, MaxLayerId, ZoomFactor, MyClippingRect, OutDrawElements, GraphObj); } else if (Schema->IsA(UAnimationStateMachineSchema::StaticClass())) { ConnectionDrawingPolicy = new FStateMachineConnectionDrawingPolicy(WireLayerId, MaxLayerId, ZoomFactor, MyClippingRect, OutDrawElements, GraphObj); } else if (Schema->IsA(UEdGraphSchema_K2::StaticClass())) { ConnectionDrawingPolicy = new FKismetConnectionDrawingPolicy(WireLayerId, MaxLayerId, ZoomFactor, MyClippingRect, OutDrawElements, GraphObj); } else if (Schema->IsA(USoundCueGraphSchema::StaticClass())) { ConnectionDrawingPolicy = new FSoundCueGraphConnectionDrawingPolicy(WireLayerId, MaxLayerId, ZoomFactor, MyClippingRect, OutDrawElements, GraphObj); } else if (Schema->IsA(UMaterialGraphSchema::StaticClass())) { ConnectionDrawingPolicy = new FMaterialGraphConnectionDrawingPolicy(WireLayerId, MaxLayerId, ZoomFactor, MyClippingRect, OutDrawElements, GraphObj); } else { ConnectionDrawingPolicy = new FConnectionDrawingPolicy(WireLayerId, MaxLayerId, ZoomFactor, MyClippingRect, OutDrawElements); } } } TArray<TSharedPtr<SGraphPin>> OverridePins; for (const FGraphPinHandle& Handle : PreviewConnectorFromPins) { TSharedPtr<SGraphPin> Pin = Handle.FindInGraphPanel(*this); if (Pin.IsValid()) { OverridePins.Add(Pin); } } ConnectionDrawingPolicy->SetHoveredPins(CurrentHoveredPins, OverridePins, TimeSinceMouseEnteredPin); ConnectionDrawingPolicy->SetMarkedPin(MarkedPin); // Get the set of pins for all children and synthesize geometry for culled out pins so lines can be drawn to them. TMap<TSharedRef<SWidget>, FArrangedWidget> PinGeometries; TSet< TSharedRef<SWidget> > VisiblePins; for (int32 ChildIndex = 0; ChildIndex < Children.Num(); ++ChildIndex) { TSharedRef<SGraphNode> ChildNode = StaticCastSharedRef<SGraphNode>(Children[ChildIndex]); // If this is a culled node, approximate the pin geometry to the corner of the node it is within if (IsNodeCulled(ChildNode, AllottedGeometry)) { TArray< TSharedRef<SWidget> > NodePins; ChildNode->GetPins(NodePins); const FVector2D NodeLoc = ChildNode->GetPosition(); const FGeometry SynthesizedNodeGeometry(GraphCoordToPanelCoord(NodeLoc), AllottedGeometry.AbsolutePosition, FVector2D::ZeroVector, 1.f); for (TArray< TSharedRef<SWidget> >::TConstIterator NodePinIterator(NodePins); NodePinIterator; ++NodePinIterator) { const SGraphPin& PinWidget = static_cast<const SGraphPin&>((*NodePinIterator).Get()); FVector2D PinLoc = NodeLoc + PinWidget.GetNodeOffset(); const FGeometry SynthesizedPinGeometry(GraphCoordToPanelCoord(PinLoc), AllottedGeometry.AbsolutePosition, FVector2D::ZeroVector, 1.f); PinGeometries.Add(*NodePinIterator, FArrangedWidget(*NodePinIterator, SynthesizedPinGeometry)); } // Also add synthesized geometries for culled nodes ArrangedChildren.AddWidget( FArrangedWidget(ChildNode, SynthesizedNodeGeometry) ); } else { ChildNode->GetPins(VisiblePins); } } // Now get the pin geometry for all visible children and append it to the PinGeometries map TMap<TSharedRef<SWidget>, FArrangedWidget> VisiblePinGeometries; { this->FindChildGeometries(AllottedGeometry, VisiblePins, VisiblePinGeometries); PinGeometries.Append(VisiblePinGeometries); } // Draw preview connections (only connected on one end) if (PreviewConnectorFromPins.Num() > 0) { for (const FGraphPinHandle& Handle : PreviewConnectorFromPins) { TSharedPtr< SGraphPin > CurrentStartPin = Handle.FindInGraphPanel(*this); if (!CurrentStartPin.IsValid()) { continue; } const FArrangedWidget* PinGeometry = PinGeometries.Find( CurrentStartPin.ToSharedRef() ); if (PinGeometry != NULL) { FVector2D StartPoint; FVector2D EndPoint; if (CurrentStartPin->GetDirection() == EGPD_Input) { StartPoint = AllottedGeometry.AbsolutePosition + PreviewConnectorEndpoint; EndPoint = FGeometryHelper::VerticalMiddleLeftOf( PinGeometry->Geometry ) - FVector2D(ConnectionDrawingPolicy->ArrowRadius.X, 0); } else { StartPoint = FGeometryHelper::VerticalMiddleRightOf( PinGeometry->Geometry ); EndPoint = AllottedGeometry.AbsolutePosition + PreviewConnectorEndpoint; } ConnectionDrawingPolicy->DrawPreviewConnector(PinGeometry->Geometry, StartPoint, EndPoint, CurrentStartPin.Get()->GetPinObj()); } //@TODO: Re-evaluate this incompatible mojo; it's mutating every pin state every frame to accomplish a visual effect ConnectionDrawingPolicy->SetIncompatiblePinDrawState(CurrentStartPin, VisiblePins); } } else { //@TODO: Re-evaluate this incompatible mojo; it's mutating every pin state every frame to accomplish a visual effect ConnectionDrawingPolicy->ResetIncompatiblePinDrawState(VisiblePins); } // Draw all regular connections ConnectionDrawingPolicy->Draw(PinGeometries, ArrangedChildren); delete ConnectionDrawingPolicy; } // Draw a shadow overlay around the edges of the graph ++MaxLayerId; PaintSurroundSunkenShadow(FEditorStyle::GetBrush(TEXT("Graph.Shadow")), AllottedGeometry, MyClippingRect, OutDrawElements, MaxLayerId); if(ShowGraphStateOverlay.Get()) { const FSlateBrush* BorderBrush = nullptr; if((GEditor->bIsSimulatingInEditor || GEditor->PlayWorld != NULL)) { // Draw a surrounding indicator when PIE is active, to make it clear that the graph is read-only, etc... BorderBrush = FEditorStyle::GetBrush(TEXT("Graph.PlayInEditor")); } else if(!IsEditable.Get()) { // Draw a different border when we're not simulating but the graph is read-only BorderBrush = FEditorStyle::GetBrush(TEXT("Graph.ReadOnlyBorder")); } if(BorderBrush) { // Actually draw the border FSlateDrawElement::MakeBox( OutDrawElements, MaxLayerId, AllottedGeometry.ToPaintGeometry(), BorderBrush, MyClippingRect ); } } // Draw the marquee selection rectangle PaintMarquee(AllottedGeometry, MyClippingRect, OutDrawElements, MaxLayerId); // Draw the software cursor ++MaxLayerId; PaintSoftwareCursor(AllottedGeometry, MyClippingRect, OutDrawElements, MaxLayerId); return MaxLayerId; }
int32 SSlider::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // we draw the slider like a horizontal slider regardless of the orientation, and apply a render transform to make it display correctly. // However, the AllottedGeometry is computed as it will be rendered, so we have to use the "horizontal orientation" when doing drawing computations. const float AllottedWidth = Orientation == Orient_Horizontal ? AllottedGeometry.GetLocalSize().X : AllottedGeometry.GetLocalSize().Y; const float AllottedHeight = Orientation == Orient_Horizontal ? AllottedGeometry.GetLocalSize().Y : AllottedGeometry.GetLocalSize().X; float HandleRotation; FVector2D HandleTopLeftPoint; FVector2D SliderStartPoint; FVector2D SliderEndPoint; // calculate slider geometry as if it's a horizontal slider (we'll rotate it later if it's vertical) const FVector2D HandleSize = Style->NormalThumbImage.ImageSize; const FVector2D HalfHandleSize = 0.5f * HandleSize; const float Indentation = IndentHandle.Get() ? HandleSize.X : 0.0f; const float SliderLength = AllottedWidth - Indentation; const float SliderPercent = ValueAttribute.Get(); const float SliderHandleOffset = SliderPercent * SliderLength; const float SliderY = 0.5f * AllottedHeight; HandleRotation = 0.0f; HandleTopLeftPoint = FVector2D(SliderHandleOffset - ( HandleSize.X * SliderPercent ) + 0.5f * Indentation, SliderY - HalfHandleSize.Y); SliderStartPoint = FVector2D(HalfHandleSize.X, SliderY); SliderEndPoint = FVector2D(AllottedWidth - HalfHandleSize.X, SliderY); FSlateRect RotatedClippingRect = MyClippingRect; FGeometry SliderGeometry = AllottedGeometry; // rotate the slider 90deg if it's vertical. The 0 side goes on the bottom, the 1 side on the top. if (Orientation == Orient_Vertical) { // Do this by translating along -X by the width of the geometry, then rotating 90 degreess CCW (left-hand coords) FSlateRenderTransform SlateRenderTransform = TransformCast<FSlateRenderTransform>(Concatenate(Inverse(FVector2D(AllottedWidth, 0)), FQuat2D(FMath::DegreesToRadians(-90.0f)))); // create a child geometry matching this one, but with the render transform. SliderGeometry = AllottedGeometry.MakeChild( FVector2D(AllottedWidth, AllottedHeight), FSlateLayoutTransform(), SlateRenderTransform, FVector2D::ZeroVector); // The clipping rect is already given properly in window space. But we do not support layout rotations, so our local space rendering cannot // get the clipping rect into local space properly for the local space clipping we do in the shader. // Thus, we transform the clip coords into local space manually, UNDO the render transform so it will clip properly, // and then bring the clip coords back into window space where DrawElements expect them. RotatedClippingRect = TransformRect( Concatenate( Inverse(SliderGeometry.GetAccumulatedLayoutTransform()), Inverse(SlateRenderTransform), SliderGeometry.GetAccumulatedLayoutTransform()), MyClippingRect); } const bool bEnabled = ShouldBeEnabled(bParentEnabled); const ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; // draw slider bar auto BarTopLeft = FVector2D(SliderStartPoint.X, SliderStartPoint.Y - Style->BarThickness * 0.5f); auto BarSize = FVector2D(SliderEndPoint.X - SliderStartPoint.X, Style->BarThickness); FSlateDrawElement::MakeBox( OutDrawElements, LayerId, SliderGeometry.ToPaintGeometry(BarTopLeft, BarSize), LockedAttribute.Get() ? &Style->DisabledBarImage : &Style->NormalBarImage, RotatedClippingRect, DrawEffects, SliderBarColor.Get().GetColor(InWidgetStyle) * InWidgetStyle.GetColorAndOpacityTint() ); ++LayerId; // draw slider thumb FSlateDrawElement::MakeBox( OutDrawElements, LayerId, SliderGeometry.ToPaintGeometry(HandleTopLeftPoint, Style->NormalThumbImage.ImageSize), LockedAttribute.Get() ? &Style->DisabledThumbImage : &Style->NormalThumbImage, RotatedClippingRect, DrawEffects, SliderHandleColor.Get().GetColor(InWidgetStyle) * InWidgetStyle.GetColorAndOpacityTint() ); return LayerId; }
int32 FSequencerTimeSliderController::OnPaintTimeSlider( bool bMirrorLabels, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const bool bEnabled = bParentEnabled; const ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; TRange<float> LocalViewRange = TimeSliderArgs.ViewRange.Get(); const float LocalViewRangeMin = LocalViewRange.GetLowerBoundValue(); const float LocalViewRangeMax = LocalViewRange.GetUpperBoundValue(); const float LocalSequenceLength = LocalViewRangeMax-LocalViewRangeMin; FVector2D Scale = FVector2D(1.0f,1.0f); if ( LocalSequenceLength > 0) { FScrubRangeToScreen RangeToScreen( LocalViewRange, AllottedGeometry.Size ); const float MajorTickHeight = 9.0f; FDrawTickArgs Args; Args.AllottedGeometry = AllottedGeometry; Args.bMirrorLabels = bMirrorLabels; Args.bOnlyDrawMajorTicks = false; Args.TickColor = FLinearColor::White; Args.ClippingRect = MyClippingRect; Args.DrawEffects = DrawEffects; Args.StartLayer = LayerId; Args.TickOffset = bMirrorLabels ? 0.0f : FMath::Abs( AllottedGeometry.Size.Y - MajorTickHeight ); Args.MajorTickHeight = MajorTickHeight; DrawTicks( OutDrawElements, RangeToScreen, Args ); FPaintPlaybackRangeArgs PlaybackRangeArgs( bMirrorLabels ? FEditorStyle::GetBrush("Sequencer.Timeline.PlayRange_Bottom_L") : FEditorStyle::GetBrush("Sequencer.Timeline.PlayRange_Top_L"), bMirrorLabels ? FEditorStyle::GetBrush("Sequencer.Timeline.PlayRange_Bottom_R") : FEditorStyle::GetBrush("Sequencer.Timeline.PlayRange_Top_R"), 6.f ); LayerId = DrawPlaybackRange(AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, RangeToScreen, PlaybackRangeArgs); float HalfSize = FMath::CeilToFloat(ScrubHandleSize/2.0f); // Draw the scrub handle float XPos = RangeToScreen.InputToLocalX( TimeSliderArgs.ScrubPosition.Get() ); // Should draw above the text const int32 ArrowLayer = LayerId + 2; FPaintGeometry MyGeometry = AllottedGeometry.ToPaintGeometry( FVector2D( XPos-HalfSize, 0 ), FVector2D( ScrubHandleSize, AllottedGeometry.Size.Y ) ); FLinearColor ScrubColor = InWidgetStyle.GetColorAndOpacityTint(); // @todo Sequencer this color should be specified in the style ScrubColor.A = ScrubColor.A*0.75f; ScrubColor.B *= 0.1f; ScrubColor.G *= 0.2f; FSlateDrawElement::MakeBox( OutDrawElements, ArrowLayer, MyGeometry, bMirrorLabels ? ScrubHandleUp : ScrubHandleDown, MyClippingRect, DrawEffects, ScrubColor ); // Draw the current time next to the scrub handle float Time = TimeSliderArgs.ScrubPosition.Get(); FString FrameString; if (SequencerSnapValues::IsTimeSnapIntervalFrameRate(TimeSliderArgs.Settings->GetTimeSnapInterval()) && TimeSliderArgs.Settings->GetShowFrameNumbers()) { float FrameRate = 1.0f/TimeSliderArgs.Settings->GetTimeSnapInterval(); float FrameTime = Time * FrameRate; int32 Frame = SequencerHelpers::TimeToFrame(Time, FrameRate); const float FrameTolerance = 0.001f; if (FMath::IsNearlyEqual(FrameTime, (float)Frame, FrameTolerance)) { FrameString = FString::Printf( TEXT("%d"), TimeToFrame(Time)); } else { FrameString = FString::Printf( TEXT("%.3f"), FrameTime); } } else { FrameString = FString::Printf( TEXT("%.2f"), Time ); } FSlateFontInfo SmallLayoutFont( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 10 ); const TSharedRef< FSlateFontMeasure > FontMeasureService = FSlateApplication::Get().GetRenderer()->GetFontMeasureService(); FVector2D TextSize = FontMeasureService->Measure(FrameString, SmallLayoutFont); // Flip the text position if getting near the end of the view range if ((AllottedGeometry.Size.X - XPos) < (TextSize.X + 14.f)) { XPos = XPos - TextSize.X - 12.f; } else { XPos = XPos + 10.f; } FVector2D TextOffset( XPos, Args.bMirrorLabels ? TextSize.Y-6.f : Args.AllottedGeometry.Size.Y - (Args.MajorTickHeight+TextSize.Y) ); FSlateDrawElement::MakeText( OutDrawElements, Args.StartLayer+1, Args.AllottedGeometry.ToPaintGeometry( TextOffset, TextSize ), FrameString, SmallLayoutFont, Args.ClippingRect, Args.DrawEffects, Args.TickColor ); if (MouseDragType == DRAG_SETTING_RANGE) { float MouseStartPosX = RangeToScreen.InputToLocalX(MouseDownRange[0]); float MouseEndPosX = RangeToScreen.InputToLocalX(MouseDownRange[1]); float RangePosX = MouseStartPosX < MouseEndPosX ? MouseStartPosX : MouseEndPosX; float RangeSizeX = FMath::Abs(MouseStartPosX - MouseEndPosX); FSlateDrawElement::MakeBox( OutDrawElements, LayerId+1, AllottedGeometry.ToPaintGeometry( FVector2D(RangePosX, 0.f), FVector2D(RangeSizeX, AllottedGeometry.Size.Y) ), bMirrorLabels ? ScrubHandleDown : ScrubHandleUp, MyClippingRect, DrawEffects, MouseStartPosX < MouseEndPosX ? FLinearColor(0.5f, 0.5f, 0.5f) : FLinearColor(0.25f, 0.3f, 0.3f) ); } return ArrowLayer; } return LayerId; }
int32 SProfilerThreadView::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // SCOPE_LOG_TIME_FUNC(); // Rendering info. const bool bEnabled = ShouldBeEnabled( bParentEnabled ); const ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const FSlateBrush* BackgroundBrush = FEditorStyle::GetBrush( "Profiler.LineGraphArea" ); const FSlateBrush* WhiteBrush = FEditorStyle::GetBrush( "WhiteTexture" ); // Paint state for this call to OnPaint, valid only in this scope. PaintState = new((void*)PaintStateMemory) FSlateOnPaintState( AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, DrawEffects ); // Draw background. FSlateDrawElement::MakeBox ( PaintState->OutDrawElements, PaintState->LayerId, PaintState->AllottedGeometry.ToPaintGeometry( FVector2D( 0, 0 ), PaintState->Size2D() ), BackgroundBrush, PaintState->AbsoluteClippingRect, PaintState->DrawEffects, BackgroundBrush->GetTint( InWidgetStyle ) * InWidgetStyle.GetColorAndOpacityTint() ); LayerId++; // Draw all cycle counters for each thread nodes. if( IsReady() ) { DrawFramesBackgroundAndTimelines(); DrawUIStackNodes(); DrawFrameMarkers(); } #if 0/*DEBUG_PROFILER_PERFORMANCE*/ LayerId++; // Draw debug information. float GraphDescPosY = PaintState->Size2D().Y - 4.0f * PaintState->SummaryFont8Height; // Debug text. FSlateDrawElement::MakeText ( OutDrawElements, LayerId, AllottedGeometry.ToOffsetPaintGeometry( FVector2D( 16.0f, GraphDescPosY ) ), FString::Printf( TEXT( "Pos X=%f,Y=%f R X=%f,Y=%f TR X=%f,Y=%f ZF X=%f" ), PositionXMS, PositionY, RangeXMS, RangeY, TotalRangeXMS, TotalRangeY, ZoomFactorX ), PaintState->SummaryFont8, MyClippingRect, DrawEffects, FLinearColor::White ); GraphDescPosY -= PaintState->SummaryFont8Height + 1.0f; FSlateDrawElement::MakeText ( OutDrawElements, LayerId, AllottedGeometry.ToOffsetPaintGeometry( FVector2D( 16.0f, GraphDescPosY ) ), FString::Printf( TEXT( "NumMSPerWin=%f H Fr=%i,TID=%i,PX=%f,PY=%f" ), NumMillisecondsPerWindow, HoveredFrameIndex, HoveredThreadID, HoveredPositionX, HoveredPositionY ), PaintState->SummaryFont8, MyClippingRect, DrawEffects, FLinearColor::White ); GraphDescPosY -= PaintState->SummaryFont8Height + 1.0f; FSlateDrawElement::MakeText ( OutDrawElements, LayerId, AllottedGeometry.ToOffsetPaintGeometry( FVector2D( 16.0f, GraphDescPosY ) ), FString::Printf( TEXT( "DistD=%.2f FI=%3i,%3i" ), DistanceDragged, FramesIndices.X, FramesIndices.Y ), PaintState->SummaryFont8, MyClippingRect, DrawEffects, FLinearColor::White ); GraphDescPosY -= PaintState->SummaryFont8Height + 1.0f; #endif // DEBUG_PROFILER_PERFORMANCE // Reset paint state. PaintState = nullptr; return SCompoundWidget::OnPaint( Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled && IsEnabled() ); }
int32 STimeline::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // Used to track the layer ID we will return. int32 RetLayerId = LayerId; const TSharedRef< FSlateFontMeasure > FontMeasureService = FSlateApplication::Get().GetRenderer()->GetFontMeasureService(); bool bEnabled = ShouldBeEnabled( bParentEnabled ); const ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const FLinearColor ColorAndOpacitySRGB = InWidgetStyle.GetColorAndOpacityTint(); static const FLinearColor SelectedBarColor(FLinearColor::White); // Paint inside the border only. const FVector2D BorderPadding = FTaskGraphStyle::Get()->GetVector("TaskGraph.ProgressBar.BorderPadding"); const FSlateRect ForegroundClippingRect = AllottedGeometry.GetClippingRect().InsetBy(FMargin(BorderPadding.X, BorderPadding.Y)).IntersectionWith(MyClippingRect); const float OffsetX = DrawingOffsetX; // BorderPadding.X const float Width = DrawingGeometry.Size.X; // AllottedGeometry.Size.X - - 2.0f * BorderPadding.X FSlateFontInfo MyFont( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 10 ); //FSlateDrawElement::MakeBox( // OutDrawElements, // RetLayerId++, // AllottedGeometry.ToPaintGeometry(), // BackgroundImage, // MyClippingRect, // DrawEffects, // ColorAndOpacitySRGB //); // Create line points const float RoundedMax = FMath::CeilToInt( MaxValue ); const float RoundedMin = FMath::FloorToInt( MinValue ); const float TimeScale = MaxValue - MinValue; const int32 NumValues = FMath::FloorToInt( AllottedGeometry.Size.X * Zoom / FixedLabelSpacing ); TArray< FVector2D > LinePoints; LinePoints.AddUninitialized( 2 ); { LinePoints[0] = FVector2D( OffsetX, BorderPadding.Y + 1.0f ); LinePoints[1] = FVector2D( OffsetX + Width, BorderPadding.Y + 1.0f ); // Draw lines FSlateDrawElement::MakeLines( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry(), LinePoints, MyClippingRect, ESlateDrawEffect::None, FLinearColor::White ); } const FVector2D TextDrawSize = FontMeasureService->Measure(TEXT("0.00"), MyFont); const float LineHeight = AllottedGeometry.Size.Y - BorderPadding.Y - TextDrawSize.Y - 2.0f; for( int32 LineIndex = 0; LineIndex <= NumValues; LineIndex++ ) { const float NormalizedX = (float)LineIndex / NumValues; const float LineX = Offset + NormalizedX * Zoom; if( LineX < 0.0f || LineX > 1.0f ) { continue; } const float LineXPos = OffsetX + Width * LineX; LinePoints[0] = FVector2D( LineXPos, BorderPadding.Y ); LinePoints[1] = FVector2D( LineXPos, LineHeight ); // Draw lines FSlateDrawElement::MakeLines( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry(), LinePoints, MyClippingRect, ESlateDrawEffect::None, FLinearColor::White ); FString ValueText( FString::Printf( TEXT("%.2f"), MinValue + NormalizedX * TimeScale ) ); FVector2D DrawSize = FontMeasureService->Measure(ValueText, MyFont); FVector2D TextPos( LineXPos - DrawSize.X * 0.5f, LineHeight ); if( TextPos.X < 0.0f ) { TextPos.X = 0.0f; } else if( (TextPos.X + DrawSize.X) > AllottedGeometry.Size.X ) { TextPos.X = OffsetX + Width - DrawSize.X; } FSlateDrawElement::MakeText( OutDrawElements, RetLayerId, AllottedGeometry.ToOffsetPaintGeometry( TextPos ), ValueText, MyFont, MyClippingRect, ESlateDrawEffect::None, FLinearColor::White ); } // Always draw lines at the start and at the end of the timeline { LinePoints[0] = FVector2D( OffsetX, BorderPadding.Y ); LinePoints[1] = FVector2D( OffsetX, LineHeight ); // Draw lines FSlateDrawElement::MakeLines( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry(), LinePoints, MyClippingRect, ESlateDrawEffect::None, FLinearColor::White ); } { LinePoints[0] = FVector2D( OffsetX + Width, BorderPadding.Y ); LinePoints[1] = FVector2D( OffsetX + Width, LineHeight ); // Draw lines FSlateDrawElement::MakeLines( OutDrawElements, RetLayerId++, AllottedGeometry.ToPaintGeometry(), LinePoints, MyClippingRect, ESlateDrawEffect::None, FLinearColor::White ); } return RetLayerId - 1; }
int32 SColorWheel::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const bool bIsEnabled = ShouldBeEnabled(bParentEnabled); const uint32 DrawEffects = bIsEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), Image, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * Image->GetTint(InWidgetStyle)); FSlateDrawElement::MakeBox( OutDrawElements, LayerId + 1, AllottedGeometry.ToPaintGeometry(CalcRelativeSelectedPosition() * AllottedGeometry.Size * 0.5f - SelectorImage->ImageSize * 0.5f, SelectorImage->ImageSize), SelectorImage, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * SelectorImage->GetTint(InWidgetStyle)); return LayerId + 1; }
int32 FSlateTextUnderlineLineHighlighter::OnPaint(const FPaintArgs& Args, const FTextLayout::FLineView& Line, const float OffsetX, const float Width, const FTextBlockStyle& DefaultStyle, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled) const { TSharedRef<FSlateFontCache> FontCache = FSlateApplication::Get().GetRenderer()->GetFontCache(); const uint16 MaxHeight = FontCache->GetMaxCharacterHeight(FontInfo, AllottedGeometry.Scale); const int16 Baseline = FontCache->GetBaseline(FontInfo, AllottedGeometry.Scale); int16 UnderlinePos, UnderlineThickness; FontCache->GetUnderlineMetrics(FontInfo, AllottedGeometry.Scale, UnderlinePos, UnderlineThickness); const FVector2D Location(Line.Offset.X + OffsetX, Line.Offset.Y + MaxHeight + Baseline - (UnderlinePos * 0.5f)); const FVector2D Size(Width, FMath::Max<int16>(1, UnderlineThickness)); // The block size and offset values are pre-scaled, so we need to account for that when converting the block offsets into paint geometry const float InverseScale = Inverse(AllottedGeometry.Scale); if (Size.X) { const FLinearColor LineColorAndOpacity = ColorAndOpacity.GetColor(InWidgetStyle); const bool ShouldDropShadow = ShadowColorAndOpacity.A > 0.f && ShadowOffset.SizeSquared() > 0.f; // A negative shadow offset should be applied as a positive offset to the underline to avoid clipping issues const FVector2D DrawShadowOffset( (ShadowOffset.X > 0.0f) ? ShadowOffset.X * AllottedGeometry.Scale : 0.0f, (ShadowOffset.Y > 0.0f) ? ShadowOffset.Y * AllottedGeometry.Scale : 0.0f ); const FVector2D DrawUnderlineOffset( (ShadowOffset.X < 0.0f) ? -ShadowOffset.X * AllottedGeometry.Scale : 0.0f, (ShadowOffset.Y < 0.0f) ? -ShadowOffset.Y * AllottedGeometry.Scale : 0.0f ); // Draw the optional shadow if (ShouldDropShadow) { FSlateDrawElement::MakeBox( OutDrawElements, ++LayerId, AllottedGeometry.ToPaintGeometry(TransformVector(InverseScale, Size), FSlateLayoutTransform(TransformPoint(InverseScale, Location + DrawShadowOffset))), &UnderlineBrush, MyClippingRect, bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, ShadowColorAndOpacity * InWidgetStyle.GetColorAndOpacityTint() ); } // Draw underline FSlateDrawElement::MakeBox( OutDrawElements, ++LayerId, AllottedGeometry.ToPaintGeometry(TransformVector(InverseScale, Size), FSlateLayoutTransform(TransformPoint(InverseScale, Location + DrawUnderlineOffset))), &UnderlineBrush, MyClippingRect, bParentEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect, LineColorAndOpacity * InWidgetStyle.GetColorAndOpacityTint() ); } return LayerId; }
int32 SColorBlock::OnPaint( const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const FSlateBrush* GenericBrush = FCoreStyle::Get().GetBrush( "GenericWhiteBox" ); const ESlateDrawEffect::Type DrawEffects = ESlateDrawEffect::None; FLinearColor InColor = Color.Get(); if (ColorIsHSV.Get()) { InColor = InColor.HSVToLinearRGB(); } if (IgnoreAlpha.Get()) { InColor.A = 1.f; } const FColor DrawColor = InColor.ToFColor(bUseSRGB.Get()); if( ShowBackgroundForAlpha.Get() && DrawColor.A < 255 ) { // If we are showing a background pattern and the colors is transparent, draw a checker pattern const FSlateBrush* CheckerBrush = FCoreStyle::Get().GetBrush("ColorPicker.AlphaBackground"); FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), CheckerBrush, MyClippingRect, DrawEffects ); } // determine if it is HDR const float MaxRGB = FMath::Max3(InColor.R, InColor.G, InColor.B); if (MaxRGB > 1.f) { FLinearColor NormalizedLinearColor = InColor / MaxRGB; NormalizedLinearColor.A = InColor.A; const FColor DrawNormalizedColor = InWidgetStyle.GetColorAndOpacityTint() * NormalizedLinearColor.ToFColor(bUseSRGB.Get()); FLinearColor ClampedLinearColor = InColor; ClampedLinearColor.A = InColor.A * MaxRGB; const FColor DrawClampedColor = InWidgetStyle.GetColorAndOpacityTint() * ClampedLinearColor.ToFColor(bUseSRGB.Get()); TArray<FSlateGradientStop> GradientStops; GradientStops.Add( FSlateGradientStop( FVector2D::ZeroVector, DrawNormalizedColor ) ); GradientStops.Add( FSlateGradientStop( AllottedGeometry.Size * 0.5f, DrawClampedColor ) ); GradientStops.Add( FSlateGradientStop( AllottedGeometry.Size, DrawNormalizedColor ) ); FSlateDrawElement::MakeGradient( OutDrawElements, LayerId + 1, AllottedGeometry.ToPaintGeometry(), GradientStops, (AllottedGeometry.Size.X > AllottedGeometry.Size.Y) ? Orient_Vertical : Orient_Horizontal, MyClippingRect, DrawEffects ); } else { FSlateDrawElement::MakeBox( OutDrawElements, LayerId + 1, AllottedGeometry.ToPaintGeometry(), GenericBrush, MyClippingRect, DrawEffects, InWidgetStyle.GetColorAndOpacityTint() * DrawColor ); } return LayerId + 1; }
int32 SImage::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { #if SLATE_HD_STATS SCOPE_CYCLE_COUNTER( STAT_SlateOnPaint_SImage ); #endif const FSlateBrush* ImageBrush = Image.Get(); if ((ImageBrush != nullptr) && (ImageBrush->DrawAs != ESlateBrushDrawType::NoDrawType)) { const bool bIsEnabled = ShouldBeEnabled(bParentEnabled); const uint32 DrawEffects = bIsEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; const FColor FinalColorAndOpacity( InWidgetStyle.GetColorAndOpacityTint() * ColorAndOpacity.Get().GetColor(InWidgetStyle) * ImageBrush->GetTint( InWidgetStyle ) ); FSlateDrawElement::MakeBox(OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), ImageBrush, MyClippingRect, DrawEffects, FinalColorAndOpacity ); } return LayerId; }