void SInvalidationPanel::Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime ) { if ( GetCanCache() ) { const bool bWasCachingNeeded = bNeedsCaching; if ( bNeedsCaching == false ) { if ( bCacheRelativeTransforms ) { // If the container we're in has changed in either scale or the rotation matrix has changed, if ( AllottedGeometry.GetAccumulatedLayoutTransform().GetScale() != LastAllottedGeometry.GetAccumulatedLayoutTransform().GetScale() || AllottedGeometry.GetAccumulatedRenderTransform().GetMatrix() != LastAllottedGeometry.GetAccumulatedRenderTransform().GetMatrix() ) { InvalidateCache(); } } else { // If the container we're in has changed in any way we need to invalidate for sure. if ( AllottedGeometry.GetAccumulatedLayoutTransform() != LastAllottedGeometry.GetAccumulatedLayoutTransform() || AllottedGeometry.GetAccumulatedRenderTransform() != LastAllottedGeometry.GetAccumulatedRenderTransform() ) { InvalidateCache(); } } if ( AllottedGeometry.GetLocalSize() != LastAllottedGeometry.GetLocalSize() ) { InvalidateCache(); } } LastAllottedGeometry = AllottedGeometry; // TODO We may be double pre-passing here, if the invalidation happened at the end of last frame, // we'll have already done one pre-pass before getting here. if ( bNeedsCaching ) { SlatePrepass(AllottedGeometry.Scale); CachePrepass(SharedThis(this)); } } }
/** 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; }