void FSlateDrawElement::MakeCustom( FSlateWindowElementList& ElementList, uint32 InLayer, TSharedPtr<ICustomSlateElement, ESPMode::ThreadSafe> CustomDrawer ) { FSlateDrawElement& DrawElt = ElementList.AddUninitialized(); DrawElt.Init(InLayer, FPaintGeometry(), FSlateRect(1,1,1,1), ESlateDrawEffect::None); DrawElt.RenderTransform = FSlateRenderTransform(); DrawElt.ElementType = ET_Custom; DrawElt.DataPayload.SetCustomDrawerPayloadProperties( CustomDrawer ); }
void FSlateDrawElement::MakeCustom( FSlateWindowElementList& ElementList, uint32 InLayer, TSharedPtr<ICustomSlateElement, ESPMode::ThreadSafe> CustomDrawer ) { FSlateDrawElement& DrawElt = ElementList.AddUninitialized(); DrawElt.ElementType = ET_Custom; DrawElt.Layer = InLayer; DrawElt.DataPayload.SetCustomDrawerPayloadProperties( CustomDrawer ); DrawElt.ClippingRect = FSlateRect(1,1,1,1); }
FSlateRect SPaperEditorViewport::PanelRectToGraphRect( const FSlateRect& PanelSpaceRect ) const { FVector2D UpperLeft = PanelCoordToGraphCoord( FVector2D(PanelSpaceRect.Left, PanelSpaceRect.Top) ); FVector2D LowerRight = PanelCoordToGraphCoord( FVector2D(PanelSpaceRect.Right, PanelSpaceRect.Bottom) ); return FSlateRect( UpperLeft.X, UpperLeft.Y, LowerRight.X, LowerRight.Y ); }
/** * Called when the mouse was moved during a drag and drop operation * * @param DragDropEvent The event that describes this drag drop operation. */ void FDockingDragOperation::OnDragged( const FDragDropEvent& DragDropEvent ) { const bool bPreviewingTarget = HoveredDockTarget.TargetNode.IsValid(); if ( !bPreviewingTarget ) { // The tab is being dragged. Move the the decorator window to match the cursor position. FVector2D TargetPosition = DragDropEvent.GetScreenSpacePosition() - GetDecoratorOffsetFromCursor(); CursorDecoratorWindow->UpdateMorphTargetShape( FSlateRect(TargetPosition.X, TargetPosition.Y, TargetPosition.X + LastContentSize.X, TargetPosition.Y + LastContentSize.Y) ); CursorDecoratorWindow->MoveWindowTo( TargetPosition ); } }
void SMenuAnchor::Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime ) { SPanel::Tick(AllottedGeometry, InCurrentTime, InDeltaTime); TSharedPtr<SWindow> PopupWindow = PopupWindowPtr.Pin(); if ( PopupWindow.IsValid() && Method == CreateNewWindow ) { // Figure out where our attached pop-up window should be placed. const FVector2D PopupContentDesiredSize = PopupWindow->GetContent()->GetDesiredSize(); FGeometry PopupGeometry = ComputeMenuPlacement( AllottedGeometry, PopupContentDesiredSize, Placement.Get( ) ); const FVector2D NewPosition = PopupGeometry.AbsolutePosition; const FVector2D NewSize = PopupGeometry.GetDrawSize( ); const FSlateRect NewShape = FSlateRect( NewPosition.X, NewPosition.Y, NewPosition.X + NewSize.X, NewPosition.Y + NewSize.Y ); // We made a window for showing the popup. // Update the window's position! if( PopupWindow->IsMorphing() ) { if( NewShape != PopupWindow->GetMorphTargetShape() ) { // Update the target shape PopupWindow->UpdateMorphTargetShape( NewShape ); // Set size immediately if not morphing size if(!PopupWindow->IsMorphingSize()) { PopupWindow->ReshapeWindow( PopupWindow->GetPositionInScreen(), NewSize ); } } } else { const FVector2D WindowPosition = PopupWindow->GetPositionInScreen(); const FVector2D WindowSize = PopupWindow->GetSizeInScreen(); if ( NewPosition != WindowPosition || NewSize != WindowSize ) { #if PLATFORM_LINUX // @FIXME: for some reason, popups reshaped here do not trigger OnWindowMoved() callback, // so we manually set cached position to where we expect it to be. Note the order of operations - (before Reshape) - // still giving the callback a chance to change it. // This needs to be investigated (tracked as TTP #347674). PopupWindow->SetCachedScreenPosition( NewPosition ); #endif // PLATFORM_LINUX PopupWindow->ReshapeWindow( NewShape ); } } } /** The tick is ending, so the window was not dismissed this tick. */ bDismissedThisTick = false; }
// !!! WRH 2014/08/25 - this is a brute-force, not efficient implementation, uses a bunch of extra conditionals. FSlateRect FSlateRotatedRect::ToBoundingRect() const { FVector2D Points[4] = { TopLeft, TopLeft + ExtentX, TopLeft + ExtentY, TopLeft + ExtentX + ExtentY }; return FSlateRect( FMath::Min(Points[0].X, FMath::Min3(Points[1].X, Points[2].X, Points[3].X)), FMath::Min(Points[0].Y, FMath::Min3(Points[1].Y, Points[2].Y, Points[3].Y)), FMath::Max(Points[0].X, FMath::Max3(Points[1].X, Points[2].X, Points[3].X)), FMath::Max(Points[0].Y, FMath::Max3(Points[1].Y, Points[2].Y, Points[3].Y)) ); }
void IHeadMountedDisplay::PopPreFullScreenRect(FSlateRect& OutPreFullScreenRect) { OutPreFullScreenRect = PreFullScreenRect; PreFullScreenRect = FSlateRect(-1.f, -1.f, -1.f, -1.f); }
IHeadMountedDisplay::IHeadMountedDisplay() { PreFullScreenRect = FSlateRect(-1.f, -1.f, -1.f, -1.f); }
void SProfilerThreadView::DrawUIStackNodes() const { // SCOPE_LOG_TIME_FUNC(); check( PaintState ); const double ThreadViewOffsetPx = PositionXMS*NumPixelsPerMillisecond; PaintState->LayerId++; static const FSlateBrush* BorderBrush = FEditorStyle::GetBrush( "Profiler.ThreadView.SampleBorder" ); const FColor GameThreadColor = FColorList::Red; const FColor RenderThreadColor = FColorList::Blue; const FColor ThreadColors[2] = {GameThreadColor, RenderThreadColor}; // Draw nodes. for( const auto& RowOfNodes : ProfilerUIStream.LinearRowsOfNodes ) { int32 NodeIndex = 0; for( const auto& UIStackNode : RowOfNodes ) { NodeIndex++; // Check if the node is visible. //if( UIStackNode->IsVisible() ) { const FVector2D PositionPx = UIStackNode->GetLocalPosition( ThreadViewOffsetPx, PositionY ) * FVector2D( 1.0f, NUM_PIXELS_PER_ROW ); const FVector2D SizePx = FVector2D( FMath::Max( UIStackNode->WidthPx - 1.0, 0.0 ), NUM_PIXELS_PER_ROW ); const FSlateRect ClippedNodeRect = PaintState->LocalClippingRect.IntersectionWith( FSlateRect( PositionPx, PositionPx + SizePx ) ); // Check if this node is inside the visible area. if( ClippedNodeRect.IsEmpty() ) { continue; } FColor NodeColor = UIStackNode->bIsCombined ? ThreadColors[UIStackNode->ThreadIndex].WithAlpha( 64 ) : ThreadColors[UIStackNode->ThreadIndex].WithAlpha( 192 ); NodeColor.G += NodeIndex % 2 ? 0 : 64; // Draw a cycle counter for this profiler UI stack node. FSlateDrawElement::MakeBox ( PaintState->OutDrawElements, PaintState->LayerId, PaintState->AllottedGeometry.ToPaintGeometry( ClippedNodeRect.GetTopLeft(), ClippedNodeRect.GetSize() ), BorderBrush, PaintState->AbsoluteClippingRect, PaintState->DrawEffects, NodeColor ); } } } // @TODO yrx 2014-04-29 Separate layer for makebox, makeshadowtext, maketext. PaintState->LayerId++; const float MarkerPosYOffsetPx = ((float)NUM_PIXELS_PER_ROW - PaintState->SummaryFont8Height)*0.5f; // Draw nodes' descriptions. for( const auto& RowOfNodes : ProfilerUIStream.LinearRowsOfNodes ) { for( const auto& UIStackNode : RowOfNodes ) { const FVector2D PositionPx = UIStackNode->GetLocalPosition( ThreadViewOffsetPx, PositionY ) * FVector2D( 1.0f, NUM_PIXELS_PER_ROW ); const FVector2D SizePx = FVector2D( UIStackNode->WidthPx, NUM_PIXELS_PER_ROW ); const FSlateRect ClippedNodeRect = PaintState->LocalClippingRect.IntersectionWith( FSlateRect( PositionPx, PositionPx + SizePx ) ); // Check if this node is inside the visible area. if( ClippedNodeRect.IsEmpty() ) { continue; } FString StringStatName = UIStackNode->StatName.GetPlainNameString(); FString StringStatNameWithTime = StringStatName + FString::Printf( TEXT( " (%.4f MS)" ), UIStackNode->GetDurationMS() ); if( UIStackNode->bIsCulled ) { StringStatName += TEXT( " [C]" ); StringStatNameWithTime += TEXT( " [C]" ); } // Update position of the text to be always visible and try to center it. const float StatNameWidthPx = PaintState->FontMeasureService->Measure( StringStatName, PaintState->SummaryFont8 ).X; const float StatNameWithTimeWidthPx = PaintState->FontMeasureService->Measure( StringStatNameWithTime, PaintState->SummaryFont8 ).X; const float TextAreaWidthPx = ClippedNodeRect.GetSize().X; bool bUseShortVersion = true; FVector2D AdjustedPositionPx; // Center the stat name with timing if we can. if( TextAreaWidthPx > StatNameWithTimeWidthPx ) { AdjustedPositionPx = FVector2D( ClippedNodeRect.Left + (TextAreaWidthPx - StatNameWithTimeWidthPx)*0.5f, PositionPx.Y + MarkerPosYOffsetPx ); bUseShortVersion = false; } // Center the stat name. else if( TextAreaWidthPx > StatNameWidthPx ) { AdjustedPositionPx = FVector2D( ClippedNodeRect.Left + (TextAreaWidthPx - StatNameWidthPx)*0.5f, PositionPx.Y + MarkerPosYOffsetPx ); } // Move to the edge. else { AdjustedPositionPx = FVector2D( ClippedNodeRect.Left, PositionPx.Y + MarkerPosYOffsetPx ); } const FVector2D AbsolutePositionPx = PaintState->AllottedGeometry.LocalToAbsolute( ClippedNodeRect.GetTopLeft() ); const FSlateRect AbsoluteClippingRect = FSlateRect( AbsolutePositionPx, AbsolutePositionPx + ClippedNodeRect.GetSize() ); DrawText( bUseShortVersion ? StringStatName : StringStatNameWithTime, PaintState->SummaryFont8, AdjustedPositionPx, FColorList::White, FColorList::Black, FVector2D( 1.0f, 1.0f ), &AbsoluteClippingRect ); } } }
void SProfilerThreadView::DrawFramesBackgroundAndTimelines() const { static const FSlateColorBrush SolidWhiteBrush = FSlateColorBrush( FColorList::White ); check( PaintState ); const double ThreadViewOffsetPx = PositionXMS*NumPixelsPerMillisecond; PaintState->LayerId++; TArray<FVector2D> LinePoints; // Draw frames background for easier reading. for( const auto& ThreadNode : ProfilerUIStream.ThreadNodes ) { if( ThreadNode.StatName == NAME_GameThread ) { const FVector2D PositionPx = ThreadNode.GetLocalPosition( ThreadViewOffsetPx, -1.0f ); const FVector2D SizePx = FVector2D( ThreadNode.WidthPx, PaintState->Size2D().Y ); const FSlateRect ClippedFrameBackgroundRect = PaintState->LocalClippingRect.IntersectionWith( FSlateRect( PositionPx, PositionPx + SizePx ) ); FSlateDrawElement::MakeBox ( PaintState->OutDrawElements, PaintState->LayerId, PaintState->AllottedGeometry.ToPaintGeometry( ClippedFrameBackgroundRect.GetTopLeft(), ClippedFrameBackgroundRect.GetSize() ), &SolidWhiteBrush, PaintState->AbsoluteClippingRect, PaintState->DrawEffects, ThreadNode.FrameIndex % 2 ? FColorList::White.WithAlpha( 64 ) : FColorList::White.WithAlpha( 128 ) ); // Check if this frame time marker is inside the visible area. const float LocalPositionXPx = PositionPx.X + SizePx.X; if( LocalPositionXPx < 0.0f || LocalPositionXPx > PaintState->Size2D().X ) { continue; } LinePoints.Reset( 2 ); LinePoints.Add( FVector2D( LocalPositionXPx, 0.0f ) ); LinePoints.Add( FVector2D( LocalPositionXPx, PaintState->Size2D().Y ) ); // Draw frame time marker. FSlateDrawElement::MakeLines ( PaintState->OutDrawElements, PaintState->LayerId, PaintState->AllottedGeometry.ToPaintGeometry(), LinePoints, PaintState->AbsoluteClippingRect, PaintState->DrawEffects, PaintState->WidgetStyle.GetColorAndOpacityTint() * FColorList::SkyBlue, false ); } } PaintState->LayerId++; const double PositionXStartPx = FMath::TruncToFloat( PositionXMS*NumPixelsPerMillisecond / (double)NUM_PIXELS_BETWEEN_TIMELINE )*(double)NUM_PIXELS_BETWEEN_TIMELINE; const double PositionXEndPx = PositionXStartPx + RangeXMS*NumPixelsPerMillisecond; for( double TimelinePosXPx = PositionXStartPx; TimelinePosXPx < PositionXEndPx; TimelinePosXPx += (double)NUM_PIXELS_BETWEEN_TIMELINE ) { LinePoints.Reset( 2 ); LinePoints.Add( FVector2D( TimelinePosXPx - ThreadViewOffsetPx, 0.0f ) ); LinePoints.Add( FVector2D( TimelinePosXPx - ThreadViewOffsetPx, PaintState->Size2D().Y ) ); // Draw time line. FSlateDrawElement::MakeLines ( PaintState->OutDrawElements, PaintState->LayerId, PaintState->AllottedGeometry.ToPaintGeometry(), LinePoints, PaintState->AbsoluteClippingRect, PaintState->DrawEffects, PaintState->WidgetStyle.GetColorAndOpacityTint() * FColorList::LimeGreen, false ); } }
bool FGeometry::IsUnderLocation(const FVector2D& AbsoluteCoordinate) const { // this render transform invert is a little expensive. We might consider caching it. return FSlateRect(FVector2D(0.0f, 0.0f), Size).ContainsPoint(TransformPoint(Inverse(GetAccumulatedRenderTransform()), AbsoluteCoordinate)); }
FSlateRect FGeometry::GetClippingRect() const { return TransformRect(GetAccumulatedLayoutTransform(), FSlateRect(FVector2D(0.0f,0.0f), Size)); }
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; }
FSlateRect FSlateRect::InsetBy( const FMargin& InsetAmount ) const { return FSlateRect( Left + InsetAmount.Left, Top + InsetAmount.Top, Right - InsetAmount.Right, Bottom - InsetAmount.Bottom ); }
void SMenuAnchor::Tick( const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime ) { TSharedPtr<SWindow> PopupWindow = PopupWindowPtr.Pin(); if ( PopupWindow.IsValid() && IsOpenViaCreatedWindow() ) { // Figure out where our attached pop-up window should be placed. const FVector2D PopupContentDesiredSize = PopupWindow->GetContent()->GetDesiredSize(); FGeometry PopupGeometry = ComputeMenuPlacement( AllottedGeometry, PopupContentDesiredSize, Placement.Get() ); const FVector2D NewPosition = PopupGeometry.LocalToAbsolute(FVector2D::ZeroVector); // For the CreateWindow case, don't transform the size; it will always use the ApplicationScale const FVector2D NewSize = PopupGeometry.GetLocalSize(); const FSlateRect NewShape = FSlateRect( NewPosition.X, NewPosition.Y, NewPosition.X + NewSize.X, NewPosition.Y + NewSize.Y ); // We made a window for showing the popup. // Update the window's position! if (false /*PopupWindow->IsMorphing()*/ ) { if( NewShape != PopupWindow->GetMorphTargetShape() ) { // Update the target shape PopupWindow->UpdateMorphTargetShape( NewShape ); // Set size immediately if not morphing size if(!PopupWindow->IsMorphingSize()) { PopupWindow->ReshapeWindow( PopupWindow->GetPositionInScreen(), NewSize ); } } } else { const FVector2D WindowPosition = PopupWindow->GetPositionInScreen(); const FVector2D WindowSize = PopupWindow->GetSizeInScreen(); if ( NewPosition != WindowPosition || NewSize != WindowSize ) { #if PLATFORM_LINUX // @FIXME: for some reason, popups reshaped here do not trigger OnWindowMoved() callback, // so we manually set cached position to where we expect it to be. Note the order of operations - (before Reshape) - // still giving the callback a chance to change it. // This needs to be investigated (tracked as TTP #347674). PopupWindow->SetCachedScreenPosition( NewPosition ); #endif // PLATFORM_LINUX PopupWindow->ReshapeWindow( NewShape ); } } } else if (PopupWindow.IsValid() && IsOpenAndReusingWindow()) { // Ideally, do this in OnArrangeChildren(); currently not possible because OnArrangeChildren() // can be called in DesktopSpace or WindowSpace, and we will not know which version of the Window // geometry to use. Tick() is always in DesktopSpace, so cache the solution here and just use // it in OnArrangeChildren(). const FPopupPlacement LocalPlacement(AllottedGeometry, Children[1].GetWidget()->GetDesiredSize(), Placement.Get()); const FSlateRect WindowRectLocalSpace = TransformRect(Inverse(AllottedGeometry.GetAccumulatedLayoutTransform()), PopupWindow->GetClientRectInScreen()); const FVector2D FittedPlacement = ComputePopupFitInRect( LocalPlacement.AnchorLocalSpace, FSlateRect(LocalPlacement.LocalPopupOffset, LocalPlacement.LocalPopupOffset + LocalPlacement.LocalPopupSize), LocalPlacement.Orientation, WindowRectLocalSpace); LocalPopupPosition = FittedPlacement; ScreenPopupPosition = AllottedGeometry.GetAccumulatedLayoutTransform().TransformPoint(LocalPopupPosition); } /** The tick is ending, so the window was not dismissed this tick. */ bDismissedThisTick = false; }