void SMenuAnchor::OnArrangeChildren( const FGeometry& AllottedGeometry, FArrangedChildren& ArrangedChildren ) const { ArrangeSingleChild( AllottedGeometry, ArrangedChildren, Children[0], FVector2D::UnitVector); if ( IsOpen() ) { // @todo umg na AllottedGeometry here is in Window-Space when computed via OnPaint. // The incorrect geometry causes the popup to fail workspace-edge tests. const FGeometry PopupGeometry = ComputeMenuPlacement( AllottedGeometry, Children[1].GetWidget()->GetDesiredSize(), Placement.Get() ); ArrangedChildren.AddWidget( FArrangedWidget( Children[1].GetWidget(), PopupGeometry ) ); } }
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; }
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; }