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 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 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 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 SGridPanel::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { FArrangedChildren ArrangedChildren(EVisibility::All); this->ArrangeChildren(AllottedGeometry, ArrangedChildren); // 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. int32 MaxLayerId = LayerId; // We need to iterate over slots, because slots know the GridLayers. This isn't available in the arranged children. // Some slots do not show up (they are hidden/collapsed). We need a 2nd index to skip over them. // // GridLayers must ensure that everything in LayerN is below LayerN+1. In other words, // every grid layer group must start at the current MaxLayerId (similar to how SOverlay works). int32 LastGridLayer = 0; for (int32 ChildIndex = 0; ChildIndex < Slots.Num(); ++ChildIndex) { FArrangedWidget& CurWidget = ArrangedChildren[ChildIndex]; if (CurWidget.Widget->GetVisibility().IsVisible()) { const FSlot& CurSlot = Slots[ChildIndex]; FSlateRect ChildClipRect = MyClippingRect.IntersectionWith( CurWidget.Geometry.GetClippingRect() ); if ( LastGridLayer != CurSlot.LayerParam ) { // We starting a new grid layer group? LastGridLayer = CurSlot.LayerParam; // Ensure that everything here is drawn on top of // previously drawn grid content. LayerId = MaxLayerId+1; } const int32 CurWidgetsMaxLayerId = CurWidget.Widget->Paint( Args.WithNewParent(this), CurWidget.Geometry, ChildClipRect, OutDrawElements, LayerId, InWidgetStyle, ShouldBeEnabled( bParentEnabled ) ); MaxLayerId = FMath::Max( MaxLayerId, CurWidgetsMaxLayerId ); } } //#define LAYOUT_DEBUG #ifdef LAYOUT_DEBUG LayerId = LayoutDebugPaint( AllottedGeometry, MyClippingRect, OutDrawElements, LayerId ); #endif return MaxLayerId; }
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 SResponsiveGridPanel::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { FArrangedChildren ArrangedChildren(EVisibility::All); this->ArrangeChildren(AllottedGeometry, ArrangedChildren); // 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. int32 MaxLayerId = LayerId; // We need to iterate over slots, because slots know the GridLayers. This isn't available in the arranged children. // Some slots do not show up (they are hidden/collapsed). We need a 2nd index to skip over them. for (int32 ChildIndex = 0; ChildIndex < ArrangedChildren.Num(); ++ChildIndex) { FArrangedWidget& CurWidget = ArrangedChildren[ChildIndex]; if (CurWidget.Widget->GetVisibility().IsVisible()) { FSlateRect ChildClipRect = MyClippingRect.IntersectionWith( CurWidget.Geometry.GetClippingRect() ); const int32 CurWidgetsMaxLayerId = CurWidget.Widget->Paint( Args.WithNewParent(this), CurWidget.Geometry, ChildClipRect, OutDrawElements, LayerId, InWidgetStyle, ShouldBeEnabled( bParentEnabled ) ); MaxLayerId = FMath::Max( MaxLayerId, CurWidgetsMaxLayerId ); } } #ifdef LAYOUT_DEBUG LayerId = LayoutDebugPaint( AllottedGeometry, MyClippingRect, OutDrawElements, LayerId ); #endif return MaxLayerId; }
int32 SWeakWidget::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // Just draw the children. FArrangedChildren ArrangedChildren(EVisibility::Visible); this->ArrangeChildren(AllottedGeometry, ArrangedChildren); // There may be zero elements in this array if our child collapsed/hidden if( ArrangedChildren.Num() > 0 ) { check( ArrangedChildren.Num() == 1 ); FArrangedWidget& TheChild = ArrangedChildren[0]; return TheChild.Widget->Paint( Args.WithNewParent(this), TheChild.Geometry, MyClippingRect, OutDrawElements, LayerId + 1, InWidgetStyle, ShouldBeEnabled( bParentEnabled ) ); } 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() ); }
/** SWidget Interface */ int32 SSequencerSectionAreaView::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); if( SectionAreaNode.IsValid() ) { // Draw a region around the entire section area FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), BackgroundBrush, MyClippingRect, ESlateDrawEffect::None, SequencerSectionAreaConstants::BackgroundColor ); } for (int32 ChildIndex = 0; ChildIndex < ArrangedChildren.Num(); ++ChildIndex) { FArrangedWidget& CurWidget = ArrangedChildren[ChildIndex]; FSlateRect ChildClipRect = MyClippingRect.IntersectionWith( CurWidget.Geometry.GetClippingRect() ); const int32 CurWidgetsMaxLayerId = CurWidget.Widget->Paint( Args.WithNewParent(this), CurWidget.Geometry, ChildClipRect, OutDrawElements, LayerId+1, InWidgetStyle, ShouldBeEnabled( bParentEnabled ) ); } return LayerId+1; }
int32 SSequencerTrackArea::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); for (int32 ChildIndex = 0; ChildIndex < ArrangedChildren.Num(); ++ChildIndex) { FArrangedWidget& CurWidget = ArrangedChildren[ChildIndex]; FSlateRect ChildClipRect = MyClippingRect.IntersectionWith( CurWidget.Geometry.GetClippingRect() ); const int32 ThisWidgetLayerId = CurWidget.Widget->Paint( Args.WithNewParent(this), CurWidget.Geometry, ChildClipRect, OutDrawElements, LayerId + 1, InWidgetStyle, ShouldBeEnabled( bParentEnabled ) ); LayerId = FMath::Max(LayerId, ThisWidgetLayerId); } auto SequencerPin = SequencerWidget.Pin(); if (SequencerPin.IsValid()) { return SequencerPin->GetEditTool().OnPaint(AllottedGeometry, MyClippingRect, OutDrawElements, LayerId + 1); } return LayerId; }
int32 SRichTextBlock::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // OnPaint will also update the text layout cache if required LayerId = TextLayoutCache->OnPaint(Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, ShouldBeEnabled(bParentEnabled)); return LayerId; }
int32 STextBlock::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { SCOPE_CYCLE_COUNTER(Stat_SlateTextBlockOnPaint); //FPlatformMisc::BeginNamedEvent(FColor::Orange, "STextBlock"); // OnPaint will also update the text layout cache if required LayerId = TextLayoutCache->OnPaint(Args, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, ShouldBeEnabled(bParentEnabled)); //FPlatformMisc::EndNamedEvent(); return LayerId; }
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 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 SMenuAnchor::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 ); // There may be zero elements in this array if our child collapsed/hidden if ( ArrangedChildren.Num() > 0 ) { const FArrangedWidget& FirstChild = ArrangedChildren[0]; // In the case where the user doesn't provide content to the menu anchor, the null widget // wont appear in the visible set of arranged children, so only immediately paint the first child, // if it's visible and matches the first slot content. const bool bHasArrangedAnchorContent = FirstChild.Widget == Children[0].GetWidget(); if ( bHasArrangedAnchorContent ) { const FSlateRect ChildClippingRect = AllottedGeometry.GetClippingRect().IntersectionWith(MyClippingRect); LayerId = FirstChild.Widget->Paint(Args.WithNewParent(this), FirstChild.Geometry, ChildClippingRect, OutDrawElements, LayerId + 1, InWidgetStyle, ShouldBeEnabled(bParentEnabled)); } const bool bIsOpen = IsOpen(); if ( bIsOpen ) { // In the case where the anchor content is present and visible, it's the 1 index child, in the case // where the anchor content is invisible, it's the 0 index child. FArrangedWidget* PopupChild = nullptr; if ( bHasArrangedAnchorContent && ArrangedChildren.Num() > 1 ) { PopupChild = &ArrangedChildren[1]; } else if ( !bHasArrangedAnchorContent && ArrangedChildren.Num() == 1 ) { PopupChild = &ArrangedChildren[0]; } if ( PopupChild != nullptr ) { OutDrawElements.QueueDeferredPainting( FSlateWindowElementList::FDeferredPaint(PopupChild->Widget, Args, PopupChild->Geometry, MyClippingRect, InWidgetStyle, bParentEnabled)); } } } 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 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; }
/** * This widget was created before render transforms existed for each widget, and it chose to apply the render transform AFTER the layout transform. * This means leveraging the render transform of FGeometry would be expensive, as we would need to use Concat(LayoutTransform, RenderTransform, Inverse(LayoutTransform). * Instead, we maintain the old way of doing it by modifying the AllottedGeometry only during rendering to append the widget's implied RenderTransform to the existing LayoutTransform. */ int32 SFxWidget::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // Convert the 0..1 origin into local space extents. const FVector2D ScaleOrigin = RenderScaleOrigin.Get() * AllottedGeometry.Size; const FVector2D Offset = VisualOffset.Get() * AllottedGeometry.Size; // create the render transform as a scale around ScaleOrigin and offset it by Offset. const auto RenderTransform = Concatenate(Inverse(ScaleOrigin), RenderScale.Get(), ScaleOrigin, Offset); // This will append the render transform to the layout transform, and we only use it for rendering. FGeometry ModifiedGeometry = AllottedGeometry.MakeChild(AllottedGeometry.Size, RenderTransform); FArrangedChildren ArrangedChildren(EVisibility::Visible); this->ArrangeChildren(ModifiedGeometry, ArrangedChildren); // There may be zero elements in this array if our child collapsed/hidden if( ArrangedChildren.Num() > 0 ) { // We can only have one direct descendant. check( ArrangedChildren.Num() == 1 ); const FArrangedWidget& TheChild = ArrangedChildren[0]; // SFxWidgets are able to ignore parent clipping. const FSlateRect ChildClippingRect = (bIgnoreClipping.Get()) ? ModifiedGeometry.GetClippingRect() : MyClippingRect.IntersectionWith(ModifiedGeometry.GetClippingRect()); FWidgetStyle CompoundedWidgetStyle = FWidgetStyle(InWidgetStyle) .BlendColorAndOpacityTint(ColorAndOpacity.Get()) .SetForegroundColor( ForegroundColor ); return TheChild.Widget->Paint( Args.WithNewParent(this), TheChild.Geometry, ChildClippingRect, OutDrawElements, LayerId + 1, CompoundedWidgetStyle, ShouldBeEnabled( bParentEnabled ) ); } return LayerId; }
int32 SColorGradientEditor::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { const TSharedRef< FSlateFontMeasure > FontMeasureService = FSlateApplication::Get().GetRenderer()->GetFontMeasureService(); if( CurveOwner ) { // Split the geometry into areas for stops and the gradient FGeometry ColorMarkAreaGeometry = GetColorMarkAreaGeometry( AllottedGeometry ); FGeometry AlphaMarkAreaGeometry = GetAlphaMarkAreaGeometry( AllottedGeometry ); FGeometry GradientAreaGeometry = AllottedGeometry.MakeChild( FVector2D(0.0f, 16.0f), FVector2D( AllottedGeometry.Size.X, AllottedGeometry.Size.Y - 30.0f ) ); bool bEnabled = ShouldBeEnabled( bParentEnabled ); ESlateDrawEffect::Type DrawEffects = bEnabled ? ESlateDrawEffect::None : ESlateDrawEffect::DisabledEffect; // Pixel to value input converter FTrackScaleInfo ScaleInfo(ViewMinInput.Get(), ViewMaxInput.Get(), 0.0f, 1.0f, GradientAreaGeometry.Size); // The start and end location in slate units of the area to draw int32 Start = 0; int32 Finish = FMath::TruncToInt( AllottedGeometry.Size.X ); TArray<FSlateGradientStop> Stops; // If no alpha keys are available, treat the curve as being completely opaque for drawing purposes bool bHasAnyAlphaKeys = CurveOwner->HasAnyAlphaKeys(); // If any transpareny (A < 1) is found, we'll draw a checkerboard to visualize the color with alpha bool bHasTransparency = false; // Sample the curve every 2 units. THe curve could be non-linear so sampling at each stop would display an incorrect gradient for( int32 CurrentStep = Start; CurrentStep < Finish; CurrentStep+=2 ) { // Figure out the time from the current screen unit float Time = ScaleInfo.LocalXToInput(CurrentStep); // Sample the curve FLinearColor Color = CurveOwner->GetLinearColorValue( Time ); if( !bHasAnyAlphaKeys ) { // Only show alpha if there is at least one key. For some curves, alpha may not be important Color.A = 1.0f; bHasTransparency = false; } else { bHasTransparency |= (Color.A < 1.0f); } Stops.Add( FSlateGradientStop( FVector2D( CurrentStep, 0.0f ), Color ) ); } if( Stops.Num() > 0 ) { if( bHasTransparency ) { // Draw a checkerboard behind there is any transparency visible FSlateDrawElement::MakeBox ( OutDrawElements, LayerId, GradientAreaGeometry.ToPaintGeometry(), FEditorStyle::GetBrush("Checkerboard"), MyClippingRect, DrawEffects ); } // Draw the color gradient FSlateDrawElement::MakeGradient ( OutDrawElements, LayerId, GradientAreaGeometry.ToPaintGeometry(), Stops, Orient_Vertical, MyClippingRect, DrawEffects, false ); } // Get actual editable stop marks TArray<FGradientStopMark> ColorMarks; TArray<FGradientStopMark> AlphaMarks; GetGradientStopMarks( ColorMarks, AlphaMarks ); // Draw each color stop for( int32 ColorIndex = 0; ColorIndex < ColorMarks.Num(); ++ColorIndex ) { const FGradientStopMark& Mark = ColorMarks[ColorIndex]; float XVal = ScaleInfo.InputToLocalX( Mark.Time ); // Dont draw stops which are not visible if( XVal >= 0 && XVal <= ColorMarkAreaGeometry.Size.X ) { FLinearColor Color = CurveOwner->GetLinearColorValue( Mark.Time ); Color.A = 1.0f; DrawGradientStopMark( Mark, ColorMarkAreaGeometry, XVal, Color, OutDrawElements, LayerId, MyClippingRect, DrawEffects, true, InWidgetStyle ); } } // Draw each alpha stop for( int32 ColorIndex = 0; ColorIndex < AlphaMarks.Num(); ++ColorIndex ) { const FGradientStopMark& Mark = AlphaMarks[ColorIndex]; float XVal = ScaleInfo.InputToLocalX( Mark.Time ); // Dont draw stops which are not visible if( XVal >= 0 && XVal <= AlphaMarkAreaGeometry.Size.X ) { float Alpha = CurveOwner->GetLinearColorValue( Mark.Time ).A; DrawGradientStopMark( Mark, AlphaMarkAreaGeometry, XVal, FLinearColor( Alpha, Alpha, Alpha, 1.0f ), OutDrawElements, LayerId, MyClippingRect, DrawEffects, false, InWidgetStyle ); } } // Draw some hint messages about how to add stops if no stops exist if( ColorMarks.Num() == 0 && AlphaMarks.Num() == 0 && IsEditingEnabled.Get() == true ) { static FString GradientColorMessage( LOCTEXT("ClickToAddColorStop", "Click in this area add color stops").ToString() ); static FString GradientAlphaMessage( LOCTEXT("ClickToAddAlphaStop", "Click in this area add opacity stops").ToString() ); // Draw the text centered in the color region { FVector2D StringSize = FontMeasureService->Measure( GradientColorMessage, FSlateFontInfo( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 8 ) ); FPaintGeometry PaintGeom = ColorMarkAreaGeometry.ToPaintGeometry(FSlateLayoutTransform(FVector2D((ColorMarkAreaGeometry.Size.X - StringSize.X) * 0.5f, 1.0f))); FSlateDrawElement::MakeText ( OutDrawElements, LayerId, PaintGeom, GradientColorMessage, FSlateFontInfo( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 8 ), MyClippingRect, DrawEffects, FLinearColor( .5f, .5f, .5f, .85f ) ); } // Draw the text centered in the alpha region { FVector2D StringSize = FontMeasureService->Measure( GradientAlphaMessage, FSlateFontInfo( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 8 ) ); FPaintGeometry PaintGeom = AlphaMarkAreaGeometry.ToPaintGeometry(FSlateLayoutTransform(FVector2D((AlphaMarkAreaGeometry.Size.X - StringSize.X) * 0.5f, 1.0f))); FSlateDrawElement::MakeText ( OutDrawElements, LayerId, PaintGeom, GradientAlphaMessage, FSlateFontInfo( FPaths::EngineContentDir() / TEXT("Slate/Fonts/Roboto-Regular.ttf"), 8 ), MyClippingRect, DrawEffects, FLinearColor( .5f, .5f, .5f, .85f ) ); } } } return LayerId; }
int32 SDockingTabWell::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // When we are dragging a tab, it must be painted on top of the other tabs, so we cannot // just reuse the Panel's default OnPaint. // The TabWell has no visualization of its own; it just visualizes its child tabs. FArrangedChildren ArrangedChildren(EVisibility::Visible); this->ArrangeChildren(AllottedGeometry, ArrangedChildren); // 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. int32 MaxLayerId = LayerId; TSharedPtr<SDockTab> ForegroundTab = GetForegroundTab(); FArrangedWidget* ForegroundTabGeometry = NULL; // Draw all inactive tabs first for (int32 ChildIndex = 0; ChildIndex < ArrangedChildren.Num(); ++ChildIndex) { FArrangedWidget& CurWidget = ArrangedChildren[ChildIndex]; if (CurWidget.Widget == ForegroundTab) { ForegroundTabGeometry = &CurWidget; } else { FSlateRect ChildClipRect = MyClippingRect.IntersectionWith( CurWidget.Geometry.GetClippingRect() ); const int32 CurWidgetsMaxLayerId = CurWidget.Widget->Paint( Args.WithNewParent(this), CurWidget.Geometry, ChildClipRect, OutDrawElements, MaxLayerId, InWidgetStyle, ShouldBeEnabled( bParentEnabled ) ); MaxLayerId = FMath::Max( MaxLayerId, CurWidgetsMaxLayerId ); } } // Draw active tab in front if (ForegroundTab != TSharedPtr<SDockTab>()) { FSlateRect ChildClipRect = MyClippingRect.IntersectionWith( ForegroundTabGeometry->Geometry.GetClippingRect() ); const int32 CurWidgetsMaxLayerId = ForegroundTabGeometry->Widget->Paint( Args.WithNewParent(this), ForegroundTabGeometry->Geometry, ChildClipRect, OutDrawElements, MaxLayerId, InWidgetStyle, ShouldBeEnabled( bParentEnabled ) ); MaxLayerId = FMath::Max( MaxLayerId, CurWidgetsMaxLayerId ); } return MaxLayerId; }
/** SWidget interface */ virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const override { // First paint the background { LayerId = PaintBackground(AllottedGeometry, MyClippingRect, OutDrawElements, LayerId); LayerId++; } FArrangedChildren ArrangedChildren(EVisibility::Visible); ArrangeChildren(AllottedGeometry, ArrangedChildren); // Draw the child nodes // When drawing a marquee, need a preview of what the selection will be. const auto* SelectionToVisualize = &(SelectionManager.SelectedNodes); FGraphPanelSelectionSet SelectionPreview; if (Marquee.IsValid()) { ApplyMarqueeSelection(Marquee, SelectionManager.SelectedNodes, SelectionPreview); SelectionToVisualize = &SelectionPreview; } int32 NodesLayerId = LayerId; for (int32 ChildIndex = 0; ChildIndex < ArrangedChildren.Num(); ++ChildIndex) { FArrangedWidget& CurWidget = ArrangedChildren[ChildIndex]; TSharedRef<SWorldTileItem> ChildNode = StaticCastSharedRef<SWorldTileItem>(CurWidget.Widget); ChildNode->bAffectedByMarquee = SelectionToVisualize->Contains(ChildNode->GetObjectBeingDisplayed()); LayerId = CurWidget.Widget->Paint(Args.WithNewParent(this), CurWidget.Geometry, MyClippingRect, OutDrawElements, NodesLayerId, InWidgetStyle, ShouldBeEnabled(bParentEnabled)); ChildNode->bAffectedByMarquee = false; } // Draw editable world bounds if (!WorldModel->IsSimulating()) { float ScreenSpaceSize = FLevelCollectionModel::EditableAxisLength()*GetZoomAmount()*2.f; FVector2D PaintSize = FVector2D(ScreenSpaceSize, ScreenSpaceSize); FVector2D PaintPosition = GraphCoordToPanelCoord(FVector2D::ZeroVector) - (PaintSize*0.5f); float Scale = 0.2f; // Scale down drawing border FSlateLayoutTransform LayoutTransform(Scale, AllottedGeometry.GetAccumulatedLayoutTransform().GetTranslation() + PaintPosition); FSlateRenderTransform RenderTransform(Scale, AllottedGeometry.GetAccumulatedRenderTransform().GetTranslation() + PaintPosition); FPaintGeometry EditableArea(LayoutTransform, RenderTransform, PaintSize/Scale); FLinearColor PaintColor = FLinearColor::Yellow; PaintColor.A = 0.4f; FSlateDrawElement::MakeBox( OutDrawElements, ++LayerId, EditableArea, FEditorStyle::GetBrush(TEXT("Graph.CompactNode.ShadowSelected")), MyClippingRect, ESlateDrawEffect::None, PaintColor ); } // Draw the marquee selection rectangle PaintMarquee(AllottedGeometry, MyClippingRect, OutDrawElements, ++LayerId); // Draw the software cursor PaintSoftwareCursor(AllottedGeometry, MyClippingRect, OutDrawElements, ++LayerId); if(WorldModel->IsSimulating()) { // Draw a surrounding indicator when PIE is active, to make it clear that the graph is read-only, etc... FSlateDrawElement::MakeBox( OutDrawElements, LayerId, AllottedGeometry.ToPaintGeometry(), FEditorStyle::GetBrush(TEXT("Graph.PlayInEditor")), MyClippingRect ); } // Draw observer location { FVector ObserverPosition; FRotator ObserverRotation; if (WorldModel->GetObserverView(ObserverPosition, ObserverRotation)) { FVector2D ObserverPositionScreen = GraphCoordToPanelCoord(FVector2D(ObserverPosition.X, ObserverPosition.Y)); const FSlateBrush* CameraImage = FEditorStyle::GetBrush(TEXT("WorldBrowser.SimulationViewPositon")); FPaintGeometry PaintGeometry = AllottedGeometry.ToPaintGeometry( ObserverPositionScreen - CameraImage->ImageSize*0.5f, CameraImage->ImageSize ); FSlateDrawElement::MakeRotatedBox( OutDrawElements, ++LayerId, PaintGeometry, CameraImage, MyClippingRect, ESlateDrawEffect::None, FMath::DegreesToRadians(ObserverRotation.Yaw), CameraImage->ImageSize*0.5f, FSlateDrawElement::RelativeToElement ); } FVector PlayerPosition; FRotator PlayerRotation; if (WorldModel->GetPlayerView(PlayerPosition, PlayerRotation)) { FVector2D PlayerPositionScreen = GraphCoordToPanelCoord(FVector2D(PlayerPosition.X, PlayerPosition.Y)); const FSlateBrush* CameraImage = FEditorStyle::GetBrush(TEXT("WorldBrowser.SimulationViewPositon")); FPaintGeometry PaintGeometry = AllottedGeometry.ToPaintGeometry( PlayerPositionScreen - CameraImage->ImageSize*0.5f, CameraImage->ImageSize ); FSlateDrawElement::MakeRotatedBox( OutDrawElements, ++LayerId, PaintGeometry, CameraImage, MyClippingRect, ESlateDrawEffect::None, FMath::DegreesToRadians(PlayerRotation.Yaw), CameraImage->ImageSize*0.5f, FSlateDrawElement::RelativeToElement, FLinearColor(FColorList::Orange) ); } } LayerId = PaintScaleRuler(AllottedGeometry, MyClippingRect, OutDrawElements, LayerId); return LayerId; }
int32 STimeSlider::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { int32 NewLayer = TimeSliderController->OnPaintTimeSlider( bMirrorLabels, AllottedGeometry, MyClippingRect, OutDrawElements, LayerId, InWidgetStyle, bParentEnabled ); return FMath::Max( NewLayer, SCompoundWidget::OnPaint(Args, AllottedGeometry, MyClippingRect, OutDrawElements, NewLayer, InWidgetStyle, ShouldBeEnabled( bParentEnabled ) ) ); }
int32 SBox::OnPaint( const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled ) const { // An SBox just draws its only child FArrangedChildren ArrangedChildren(EVisibility::Visible); this->ArrangeChildren(AllottedGeometry, ArrangedChildren); // Maybe none of our children are visible if( ArrangedChildren.Num() > 0 ) { check( ArrangedChildren.Num() == 1 ); FArrangedWidget& TheChild = ArrangedChildren[0]; const FSlateRect ChildClippingRect = AllottedGeometry.GetClippingRect().InsetBy( ChildSlot.SlotPadding.Get() * AllottedGeometry.Scale ).IntersectionWith(MyClippingRect); return TheChild.Widget->Paint( Args.WithNewParent(this), TheChild.Geometry, ChildClippingRect, OutDrawElements, LayerId, InWidgetStyle, ShouldBeEnabled( bParentEnabled ) ); } return LayerId; }
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 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 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 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 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; }