FReply FSceneViewport::OnMouseButtonDown( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent ) { // Start a new reply state // Prevent throttling when interacting with the viewport so we can move around in it CurrentReplyState = FReply::Handled().PreventThrottling(); KeyStateMap.Add(InMouseEvent.GetEffectingButton(), true); UpdateModifierKeys( InMouseEvent ); UpdateCachedMousePos( InGeometry, InMouseEvent ); UpdateCachedGeometry(InGeometry); // Switch to the viewport clients world before processing input FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient ); if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue ) { // If we're obtaining focus, we have to copy the modifier key states prior to processing this mouse button event, as this is the only point at which the mouse down // event is processed when focus initially changes and the modifier keys need to be in-place to detect any unique drag-like events. if ( !HasFocus() ) { FModifierKeysState KeysState = FSlateApplication::Get().GetModifierKeys(); ApplyModifierKeys( KeysState ); } // Process the mouse event if( !ViewportClient->InputKey( this, 0, InMouseEvent.GetEffectingButton(), IE_Pressed ) ) { CurrentReplyState = FReply::Unhandled(); } if (ViewportClient->CaptureMouseOnClick() != EMouseCaptureMode::NoCapture && !ViewportClient->IgnoreInput()) { TSharedRef<SViewport> ViewportWidgetRef = ViewportWidget.Pin().ToSharedRef(); // Mouse down should focus viewport for keyboard input CurrentReplyState.SetKeyboardFocus(ViewportWidgetRef, EKeyboardFocusCause::Mouse); UWorld* World = ViewportClient->GetWorld(); if (World && World->IsGameWorld() && World->GetFirstPlayerController()) { CurrentReplyState.CaptureMouse(ViewportWidgetRef); CurrentReplyState.LockMouseToWidget(ViewportWidgetRef); bool bShouldShowMouseCursor = World->GetFirstPlayerController()->ShouldShowMouseCursor(); if (ViewportClient->HideCursorDuringCapture() && bShouldShowMouseCursor) { bCursorHiddenDueToCapture = true; } if (bCursorHiddenDueToCapture || !bShouldShowMouseCursor) { CurrentReplyState.UseHighPrecisionMouseMovement(ViewportWidgetRef); } } else { CurrentReplyState.UseHighPrecisionMouseMovement(ViewportWidgetRef); } } } // Re-set prevent throttling here as it can get reset when inside of InputKey() CurrentReplyState.PreventThrottling(); return CurrentReplyState; }
FReply FSceneViewport::OnMouseButtonDown( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent ) { // Start a new reply state // Prevent throttling when interacting with the viewport so we can move around in it CurrentReplyState = FReply::Handled().PreventThrottling(); KeyStateMap.Add(InMouseEvent.GetEffectingButton(), true); UpdateModifierKeys( InMouseEvent ); UpdateCachedMousePos( InGeometry, InMouseEvent ); UpdateCachedGeometry(InGeometry); // Switch to the viewport clients world before processing input FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient ); if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue ) { // If we're obtaining focus, we have to copy the modifier key states prior to processing this mouse button event, as this is the only point at which the mouse down // event is processed when focus initially changes and the modifier keys need to be in-place to detect any unique drag-like events. if ( !HasFocus() ) { FModifierKeysState KeysState = FSlateApplication::Get().GetModifierKeys(); ApplyModifierKeys( KeysState ); } const bool bAnyMenuWasVisible = FSlateApplication::Get().AnyMenusVisible(); // Process the mouse event if (!ViewportClient->InputKey(this, InMouseEvent.GetUserIndex(), InMouseEvent.GetEffectingButton(), IE_Pressed)) { CurrentReplyState = FReply::Unhandled(); } // a new menu was opened if there was previously not a menu visible but now there is const bool bNewMenuWasOpened = !bAnyMenuWasVisible && FSlateApplication::Get().AnyMenusVisible(); if (!ViewportClient->IgnoreInput() && !bNewMenuWasOpened && // We should not focus the viewport if a menu was opened as it would close the menu ( ViewportClient->CaptureMouseOnClick() == EMouseCaptureMode::CapturePermanently || ViewportClient->CaptureMouseOnClick() == EMouseCaptureMode::CaptureDuringMouseDown || ( ViewportClient->CaptureMouseOnClick() == EMouseCaptureMode::CaptureDuringRightMouseDown && InMouseEvent.GetEffectingButton() == EKeys::RightMouseButton ) ) ) { TSharedRef<SViewport> ViewportWidgetRef = ViewportWidget.Pin().ToSharedRef(); // Mouse down should focus viewport for user input CurrentReplyState.SetUserFocus(ViewportWidgetRef, EFocusCause::SetDirectly, true); UWorld* World = ViewportClient->GetWorld(); if (World && World->IsGameWorld() && World->GetFirstPlayerController()) { CurrentReplyState.CaptureMouse(ViewportWidgetRef); CurrentReplyState.LockMouseToWidget(ViewportWidgetRef); bool bShouldShowMouseCursor = World->GetFirstPlayerController()->ShouldShowMouseCursor(); if (ViewportClient->HideCursorDuringCapture() && bShouldShowMouseCursor) { bCursorHiddenDueToCapture = true; MousePosBeforeHiddenDueToCapture = FIntPoint( InMouseEvent.GetScreenSpacePosition().X, InMouseEvent.GetScreenSpacePosition().Y ); } if (bCursorHiddenDueToCapture || !bShouldShowMouseCursor) { CurrentReplyState.UseHighPrecisionMouseMovement(ViewportWidgetRef); } } else { CurrentReplyState.UseHighPrecisionMouseMovement(ViewportWidgetRef); } } } // Re-set prevent throttling here as it can get reset when inside of InputKey() CurrentReplyState.PreventThrottling(); return CurrentReplyState; }