FReply STableViewBase::OnMouseButtonUp( const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if ( MouseEvent.GetEffectingButton() == EKeys::RightMouseButton ) { OnRightMouseButtonUp( MouseEvent ); FReply Reply = FReply::Handled().ReleaseMouseCapture(); bShowSoftwareCursor = false; // If we have mouse capture, snap the mouse back to the closest location that is within the list's bounds if ( HasMouseCapture() ) { FSlateRect ListScreenSpaceRect = MyGeometry.GetClippingRect(); FVector2D CursorPosition = MyGeometry.LocalToAbsolute( SoftwareCursorPosition ); FIntPoint BestPositionInList( FMath::RoundToInt( FMath::Clamp( CursorPosition.X, ListScreenSpaceRect.Left, ListScreenSpaceRect.Right ) ), FMath::RoundToInt( FMath::Clamp( CursorPosition.Y, ListScreenSpaceRect.Top, ListScreenSpaceRect.Bottom ) ) ); Reply.SetMousePos(BestPositionInList); } return Reply; } return FReply::Unhandled(); }
FReply FScrollyZoomy::OnMouseButtonUp( const TSharedRef<SWidget> MyWidget, const FGeometry& MyGeometry, const FPointerEvent& MouseEvent ) { if (MouseEvent.GetEffectingButton() == EKeys::RightMouseButton) { AmountScrolledWhileRightMouseDown = 0; FReply Reply = FReply::Handled().ReleaseMouseCapture(); bShowSoftwareCursor = false; // If we have mouse capture, snap the mouse back to the closest location that is within the panel's bounds if (MyWidget->HasMouseCapture()) { FSlateRect PanelScreenSpaceRect = MyGeometry.GetClippingRect(); FVector2D CursorPosition = MyGeometry.LocalToAbsolute( SoftwareCursorPosition ); FIntPoint BestPositionInPanel( FMath::RoundToInt( FMath::Clamp( CursorPosition.X, PanelScreenSpaceRect.Left, PanelScreenSpaceRect.Right ) ), FMath::RoundToInt( FMath::Clamp( CursorPosition.Y, PanelScreenSpaceRect.Top, PanelScreenSpaceRect.Bottom ) ) ); Reply.SetMousePos( BestPositionInPanel ); } if (!bUseIntertialScrolling) { HorizontalIntertia.ClearScrollVelocity(); VerticalIntertia.ClearScrollVelocity(); } return Reply; } return FReply::Unhandled(); }
FReply SPaperEditorViewport::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) { // Did the user move the cursor sufficiently far, or is it in a dead zone? // In Dead zone - implies actions like summoning context menus and general clicking. // Out of Dead Zone - implies dragging actions like moving nodes and marquee selection. const bool bCursorInDeadZone = TotalMouseDelta <= FSlateApplication::Get().GetDragTriggerDistance(); if (MouseEvent.GetEffectingButton() == EKeys::RightMouseButton) { FReply ReplyState = FReply::Handled(); if (HasMouseCapture()) { FSlateRect ThisPanelScreenSpaceRect = MyGeometry.GetClippingRect(); const FVector2D ScreenSpaceCursorPos = MyGeometry.LocalToAbsolute( GraphCoordToPanelCoord( SoftwareCursorPosition ) ); FIntPoint BestPositionInViewport( FMath::RoundToInt( FMath::Clamp( ScreenSpaceCursorPos.X, ThisPanelScreenSpaceRect.Left, ThisPanelScreenSpaceRect.Right ) ), FMath::RoundToInt( FMath::Clamp( ScreenSpaceCursorPos.Y, ThisPanelScreenSpaceRect.Top, ThisPanelScreenSpaceRect.Bottom ) ) ); if (!bCursorInDeadZone) { ReplyState.SetMousePos(BestPositionInViewport); } } TSharedPtr<SWidget> WidgetToFocus; if (bCursorInDeadZone) { //WidgetToFocus = OnSummonContextMenu(MyGeometry, MouseEvent); } bShowSoftwareCursor = false; bIsPanning = false; return (WidgetToFocus.IsValid()) ? ReplyState.ReleaseMouseCapture().SetUserFocus(WidgetToFocus.ToSharedRef(), EFocusCause::SetDirectly) : ReplyState.ReleaseMouseCapture(); } else if (MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton) { if (OnHandleLeftMouseRelease(MyGeometry, MouseEvent)) { } else if (bCursorInDeadZone) { //@TODO: Move to selection manager // if ( NodeUnderMousePtr.IsValid() ) // { // // We clicked on a node! // TSharedRef<SNode> NodeWidgetUnderMouse = NodeUnderMousePtr.Pin().ToSharedRef(); // // SelectionManager.ClickedOnNode(NodeWidgetUnderMouse->GetObjectBeingDisplayed(), MouseEvent); // // // We're done interacting with this node. // NodeUnderMousePtr.Reset(); // } // else if (HasMouseCapture()) { // We clicked on the panel background //@TODO: There isn't a marquee operation for clear, need to signal to remove existing sets too! //Marquee.End(); //OnSelectionChanged.ExecuteIfBound(Marquee, false); } } else if (Marquee.IsValid()) { //ApplyMarqueeSelection(Marquee, SelectionManager.SelectedNodes, SelectionManager.SelectedNodes); //SelectionManager.OnSelectionChanged.ExecuteIfBound(SelectionManager.SelectedNodes); OnSelectionChanged.ExecuteIfBound(Marquee, true); } // The existing marquee operation ended; reset it. Marquee = FMarqueeOperation(); if (bIsPanning) { // We have released the left mouse button. But we're still panning // (i.e. RIGHT MOUSE is down), so we want to hold on to capturing mouse input. return FReply::Handled(); } else { // We aren't panning, so we can release the mouse capture. return FReply::Handled().ReleaseMouseCapture(); } } return FReply::Unhandled(); }
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; }
void USlateBlueprintLibrary::LocalToViewport(UObject* WorldContextObject, const FGeometry& Geometry, FVector2D LocalCoordinate, FVector2D& ScreenPosition, FVector2D& ViewportPosition) { FVector2D AbsoluteCoordinate = Geometry.LocalToAbsolute(LocalCoordinate); return AbsoluteToViewport(WorldContextObject, Geometry, AbsoluteCoordinate, ScreenPosition, ViewportPosition); }
FVector2D USlateBlueprintLibrary::LocalToAbsolute(const FGeometry& Geometry, FVector2D LocalCoordinate) { return Geometry.LocalToAbsolute(LocalCoordinate); }