예제 #1
0
void FSceneViewport::ApplyModifierKeys( const FModifierKeysState& InKeysState )
{
	if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		if ( InKeysState.IsLeftAltDown() )
		{
			ViewportClient->InputKey( this, 0, EKeys::LeftAlt, IE_Pressed );
		}
		if ( InKeysState.IsRightAltDown() )
		{
			ViewportClient->InputKey( this, 0, EKeys::RightAlt, IE_Pressed );
		}
		if ( InKeysState.IsLeftControlDown() )
		{
			ViewportClient->InputKey( this, 0, EKeys::LeftControl, IE_Pressed );
		}
		if ( InKeysState.IsRightControlDown() )
		{
			ViewportClient->InputKey( this, 0, EKeys::RightControl, IE_Pressed );
		}
		if ( InKeysState.IsLeftShiftDown() )
		{
			ViewportClient->InputKey( this, 0, EKeys::LeftShift, IE_Pressed );
		}
		if ( InKeysState.IsRightShiftDown() )
		{
			ViewportClient->InputKey( this, 0, EKeys::RightShift, IE_Pressed );
		}
	}
}
예제 #2
0
void FSceneViewport::OnDrawViewport( const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& InWidgetStyle, bool bParentEnabled )
{
	// Switch to the viewport clients world before resizing
	FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

	/** Check to see if the viewport should be resized */
	FIntPoint DrawSize = FIntPoint( FMath::RoundToInt( AllottedGeometry.GetDrawSize().X ), FMath::RoundToInt( AllottedGeometry.GetDrawSize().Y ) );
	if( GetSizeXY() != DrawSize )
	{
		TSharedPtr<SWindow> Window = FSlateApplication::Get().FindWidgetWindow( ViewportWidget.Pin().ToSharedRef() );

		check(Window.IsValid());
		ResizeViewport(FMath::Max(0, DrawSize.X), FMath::Max(0, DrawSize.Y), Window->GetWindowMode(), 0, 0);
	}	
	
	// Cannot pass negative canvas positions
	float CanvasMinX = FMath::Max(0.0f, AllottedGeometry.AbsolutePosition.X);
	float CanvasMinY = FMath::Max(0.0f, AllottedGeometry.AbsolutePosition.Y);
	FIntRect CanvasRect(
		FMath::RoundToInt( CanvasMinX ),
		FMath::RoundToInt( CanvasMinY ),
		FMath::RoundToInt( CanvasMinX + AllottedGeometry.Size.X * AllottedGeometry.Scale ), 
		FMath::RoundToInt( CanvasMinY + AllottedGeometry.Size.Y * AllottedGeometry.Scale ) );


	DebugCanvasDrawer->BeginRenderingCanvas( CanvasRect );

	// Draw above everything else
	uint32 MaxLayer = MAX_uint32;
	FSlateDrawElement::MakeCustom( OutDrawElements, MAX_uint32, DebugCanvasDrawer );

}
예제 #3
0
FReply FSceneViewport::OnMouseButtonDoubleClick( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled(); 

	// Note: When double-clicking, the following message sequence is sent:
	//	WM_*BUTTONDOWN
	//	WM_*BUTTONUP
	//	WM_*BUTTONDBLCLK	(Needs to set the KeyStates[*] to true)
	//	WM_*BUTTONUP
	KeyStateMap.Add( InMouseEvent.GetEffectingButton(), true );
	UpdateCachedMousePos( InGeometry, InMouseEvent );
	UpdateCachedGeometry(InGeometry);

	if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue  )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		if( !ViewportClient->InputKey( this, 0, InMouseEvent.GetEffectingButton(), IE_DoubleClick ) )
		{
			CurrentReplyState = FReply::Unhandled(); 
		}
	}
	return CurrentReplyState;
}
예제 #4
0
void FSceneViewport::OnViewportClosed()
{
	if( ViewportClient )
	{
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );
		ViewportClient->CloseRequested( this );
	}
}
예제 #5
0
TOptional<bool> FSceneViewport::OnQueryShowFocus(const EFocusCause InFocusCause) const
{
	if (ViewportClient)
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher(ViewportClient);

		return ViewportClient->QueryShowFocus(InFocusCause);
	}

	return TOptional<bool>();
}
예제 #6
0
FReply FSceneViewport::OnMouseButtonUp( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled();

	KeyStateMap.Add( InMouseEvent.GetEffectingButton(), false );
	UpdateModifierKeys( InMouseEvent );
	UpdateCachedMousePos( InGeometry, InMouseEvent );
	UpdateCachedGeometry(InGeometry);

	// Switch to the viewport clients world before processing input
	FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );
	bool bCursorVisible = true;
	bool bReleaseMouse = true;
	if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue  )
	{
		if (!ViewportClient->InputKey(this, InMouseEvent.GetUserIndex(), InMouseEvent.GetEffectingButton(), IE_Released))
		{
			CurrentReplyState = FReply::Unhandled(); 
		}
		bCursorVisible = ViewportClient->GetCursor(this, GetMouseX(), GetMouseY()) != EMouseCursor::None;
		bReleaseMouse = 
			bCursorVisible || 
			ViewportClient->CaptureMouseOnClick() == EMouseCaptureMode::CaptureDuringMouseDown ||
			( ViewportClient->CaptureMouseOnClick() == EMouseCaptureMode::CaptureDuringRightMouseDown && InMouseEvent.GetEffectingButton() == EKeys::RightMouseButton );
	}
	if (!((FApp::IsGame() && !GIsEditor) || bIsPlayInEditorViewport) || bReleaseMouse)
	{
		// On mouse up outside of the game (editor viewport) or if the cursor is visible in game, we should make sure the mouse is no longer captured
		// as long as the left or right mouse buttons are not still down
		if( !InMouseEvent.IsMouseButtonDown( EKeys::RightMouseButton ) && !InMouseEvent.IsMouseButtonDown( EKeys::LeftMouseButton ))
		{
			if( bCursorHiddenDueToCapture )
			{
				bCursorHiddenDueToCapture = false;
				CurrentReplyState.SetMousePos( MousePosBeforeHiddenDueToCapture );
				MousePosBeforeHiddenDueToCapture = FIntPoint( -1, -1 );
			}

			CurrentReplyState.ReleaseMouseCapture();
			if (bCursorVisible)
			{
				CurrentReplyState.ReleaseMouseLock();
			}
		}
	}
	return CurrentReplyState;
}
예제 #7
0
FReply FSceneViewport::OnKeyChar( const FGeometry& InGeometry, const FCharacterEvent& InCharacterEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled(); 

	if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue  )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		if( !ViewportClient->InputChar( this,0, InCharacterEvent.GetCharacter() ) )
		{
			CurrentReplyState = FReply::Unhandled();
		}
	}
	return CurrentReplyState;
}
예제 #8
0
FReply FSceneViewport::OnMotionDetected( const FGeometry& MyGeometry, const FMotionEvent& MotionEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled(); 

	if( ViewportClient )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		if( !ViewportClient->InputMotion( this, MotionEvent.GetUserIndex(), MotionEvent.GetTilt(), MotionEvent.GetRotationRate(), MotionEvent.GetGravity(), MotionEvent.GetAcceleration()) )
		{
			CurrentReplyState = FReply::Unhandled(); 
		}
	}

	return CurrentReplyState;
}
예제 #9
0
FReply FSceneViewport::OnControllerButtonReleased( const FGeometry& MyGeometry, const FControllerEvent& ControllerEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled(); 

	KeyStateMap.Add( ControllerEvent.GetEffectingButton(), false );

	if( ViewportClient )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		if( !ViewportClient->InputKey( this, ControllerEvent.GetUserIndex(), ControllerEvent.GetEffectingButton(), IE_Released, 1.0f, true ) )
		{
			CurrentReplyState = FReply::Unhandled(); 
		}
	}
	return CurrentReplyState;
}
예제 #10
0
FReply FSceneViewport::OnKeyboardFocusReceived( const FKeyboardFocusEvent& InKeyboardFocusEvent )
{
	CurrentReplyState = FReply::Handled(); 

	if( ViewportClient )
	{
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );
		ViewportClient->ReceivedFocus( this );

		if( ( FApp::IsGame() && !GIsEditor ) || bIsPlayInEditorViewport )
		{
			if( IsForegroundWindow() )
			{
				const bool bIsCursorForcedVisible =
					( ViewportClient != NULL && ViewportClient->GetCursor( this, GetMouseX(), GetMouseY() ) != EMouseCursor::None );

				const bool bPlayInEditorCapture = !bIsPlayInEditorViewport || InKeyboardFocusEvent.GetCause() != EKeyboardFocusCause::SetDirectly || bPlayInEditorGetsMouseControl;

				// capturing the mouse interferes with slate UI (like the virtual joysticks)
				if (FPlatformProperties::SupportsWindowedMode() && bPlayInEditorCapture && !bIsCursorForcedVisible && !FSlateApplication::Get().IsFakingTouchEvents())
				{
					// Only require the user to click in the window the first time - after that return focus to the game so long as it was the last focused widget.
					// Means that tabbing in/out will return the mouse control to where it was & the in-game console won't leave the mouse under editor control.
					bPlayInEditorGetsMouseControl = true;
					CurrentReplyState.UseHighPrecisionMouseMovement( ViewportWidget.Pin().ToSharedRef() );
					CurrentReplyState.LockMouseToWidget( ViewportWidget.Pin().ToSharedRef() );
				}
				else if(!bPlayInEditorCapture)
				{
					FSlateApplication::Get().ClearKeyboardFocus( EKeyboardFocusCause::SetDirectly );
					FSlateApplication::Get().ResetToDefaultInputSettings();
				}
			}
			else
			{
				FSlateApplication::Get().ClearKeyboardFocus( EKeyboardFocusCause::Cleared );
			}
		}
	}

	return CurrentReplyState;
}
예제 #11
0
FReply FSceneViewport::OnControllerAnalogValueChanged( const FGeometry& MyGeometry, const FControllerEvent& ControllerEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled(); 

	KeyStateMap.Add( ControllerEvent.GetEffectingButton(), true );

	if( ViewportClient )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		if (!ViewportClient->InputAxis(this, ControllerEvent.GetUserIndex(), ControllerEvent.GetEffectingButton(), ControllerEvent.GetEffectingButton() == EKeys::Gamepad_RightY ? -ControllerEvent.GetAnalogValue() : ControllerEvent.GetAnalogValue(), FApp::GetDeltaTime(), 1, true))
		{
			CurrentReplyState = FReply::Unhandled(); 
		}
	}

	return CurrentReplyState;
}
예제 #12
0
void FSceneViewport::OnFocusLost( const FFocusEvent& InFocusEvent )
{
	KeyStateMap.Empty();
	if (ViewportClient != nullptr)
	{
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );
		ViewportClient->LostFocus( this );

		TSharedPtr<SWidget> ViewportWidgetPin = ViewportWidget.Pin();
		if( ViewportWidgetPin.IsValid() )
		{
			for (int32 UserIndex = 0; UserIndex < SlateApplicationDefs::MaxUsers; ++UserIndex)
			{
				if (FSlateApplication::Get().GetUserFocusedWidget(UserIndex) == ViewportWidgetPin)
				{
					FSlateApplication::Get().ClearUserFocus(UserIndex);
				}
			}
		}
	}
}
예제 #13
0
void FSceneViewport::OnKeyboardFocusLost( const FKeyboardFocusEvent& InKeyboardFocusEvent )
{
	KeyStateMap.Empty();
	if( ViewportClient )
	{
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );
		ViewportClient->LostFocus( this );

		TSharedPtr<SWidget> ViewportWidgetPin = ViewportWidget.Pin();
		if( ViewportWidgetPin.IsValid() )
		{
			for( int32 UserIndex = 0; UserIndex < SlateApplicationDefs::MaxUsers; ++UserIndex )
			{
				if( FSlateApplication::Get().GetJoystickCaptor(UserIndex) == ViewportWidgetPin )
				{
					FSlateApplication::Get().ReleaseJoystickCapture( UserIndex );
				}
			}
		}
	}
}
예제 #14
0
FReply FSceneViewport::OnKeyDown( const FGeometry& InGeometry, const FKeyboardEvent& InKeyboardEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled(); 

	FKey Key = InKeyboardEvent.GetKey();
	KeyStateMap.Add( Key, true );

	//@todo Slate Viewports: FWindowsViewport checks for Alt+Enter or F11 and toggles fullscreen.  Unknown if fullscreen via this method will be needed for slate viewports. 
	if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue  )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		if( !ViewportClient->InputKey( this, 0, Key, InKeyboardEvent.IsRepeat() ? IE_Repeat : IE_Pressed ) )
		{
			CurrentReplyState = FReply::Unhandled();
		}
	}
	return CurrentReplyState;
}
예제 #15
0
FReply FSceneViewport::OnKeyUp( const FGeometry& InGeometry, const FKeyboardEvent& InKeyboardEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled(); 

	FKey Key = InKeyboardEvent.GetKey();
	KeyStateMap.Add( Key, false );
	
	if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue  )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		if( !ViewportClient->InputKey(this, 0, Key, IE_Released) )
		{
			CurrentReplyState = FReply::Unhandled();
		}
	}

	return CurrentReplyState;
}
예제 #16
0
FReply FSceneViewport::OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& InAnalogInputEvent)
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled();

	FKey Key = InAnalogInputEvent.GetKey();
	KeyStateMap.Add(Key, true);

	if (ViewportClient)
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher(ViewportClient);

		if (!ViewportClient->InputAxis(this, InAnalogInputEvent.GetUserIndex(), Key, Key == EKeys::Gamepad_RightY ? -InAnalogInputEvent.GetAnalogValue() : InAnalogInputEvent.GetAnalogValue(), FApp::GetDeltaTime(), 1, Key.IsGamepadKey()))
		{
			CurrentReplyState = FReply::Unhandled();
		}
	}

	return CurrentReplyState;
}
예제 #17
0
FReply FSceneViewport::OnMouseMove( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled();

	if( !InMouseEvent.GetCursorDelta().IsZero() )
	{
		UpdateCachedMousePos( InGeometry, InMouseEvent );
		UpdateCachedGeometry(InGeometry);

		const bool bViewportHasCapture = ViewportWidget.IsValid() && ViewportWidget.Pin()->HasMouseCapture();
		if( ViewportClient && GetSizeXY() != FIntPoint::ZeroValue )
		{
			// Switch to the viewport clients world before processing input
			FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

			if( bViewportHasCapture )
			{
				ViewportClient->CapturedMouseMove( this, GetMouseX(), GetMouseY() );
			}
			else
			{
				ViewportClient->MouseMove( this, GetMouseX(), GetMouseY() );
			}
		
			if( bViewportHasCapture )
			{
				// Accumulate delta changes to mouse movment.  Depending on the sample frequency of a mouse we may get many per frame.
				//@todo Slate: In directinput, number of samples in x/y could be different...
				const FVector2D CursorDelta = InMouseEvent.GetCursorDelta();
				MouseDelta.X += CursorDelta.X;
				++NumMouseSamplesX;

				MouseDelta.Y -= CursorDelta.Y;
				++NumMouseSamplesY;
			}
		}
	}
	return CurrentReplyState;
}
예제 #18
0
FReply FSceneViewport::OnMouseWheel( const FGeometry& InGeometry, const FPointerEvent& InMouseEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled();

	UpdateCachedMousePos( InGeometry, InMouseEvent );
	UpdateCachedGeometry(InGeometry);

	if( ViewportClient  && GetSizeXY() != FIntPoint::ZeroValue  )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		// The viewport client accepts two different keys depending on the direction of scroll.  
		FKey const ViewportClientKey = InMouseEvent.GetWheelDelta() < 0 ? EKeys::MouseScrollDown : EKeys::MouseScrollUp;

		// Pressed and released should be sent
		ViewportClient->InputKey( this, 0, ViewportClientKey, IE_Pressed );
		ViewportClient->InputKey( this, 0, ViewportClientKey, IE_Released );
	}
	return CurrentReplyState;
}
예제 #19
0
void FSceneViewport::ProcessInput( float DeltaTime )
{
	if( !ViewportClient )
	{
		return;
	}

	// Switch to the viewport clients world before processing input
	FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

	const bool bViewportHasCapture = ViewportWidget.IsValid() && ViewportWidget.Pin()->HasMouseCapture();

	if (NumMouseSamplesX > 0 || NumMouseSamplesY > 0)
	{
		ViewportClient->InputAxis( this, 0, EKeys::MouseX, MouseDelta.X, DeltaTime, NumMouseSamplesX );
		ViewportClient->InputAxis( this, 0, EKeys::MouseY, MouseDelta.Y, DeltaTime, NumMouseSamplesY );
	}

	MouseDelta = FIntPoint::ZeroValue;
	NumMouseSamplesX = 0;
	NumMouseSamplesY = 0;

}
예제 #20
0
FReply FSceneViewport::OnTouchGesture( const FGeometry& MyGeometry, const FPointerEvent& GestureEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled();

	UpdateCachedMousePos( MyGeometry, GestureEvent );
	UpdateCachedGeometry( MyGeometry );

	if( ViewportClient )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		FSlateApplication::Get().SetKeyboardFocus(ViewportWidget.Pin());

		if( !ViewportClient->InputGesture( this, GestureEvent.GetGestureType(), GestureEvent.GetGestureDelta() ) )
		{
			CurrentReplyState = FReply::Unhandled();
		}
	}

	return CurrentReplyState;
}
예제 #21
0
FReply FSceneViewport::OnTouchEnded( const FGeometry& MyGeometry, const FPointerEvent& TouchEvent )
{
	// Start a new reply state
	CurrentReplyState = FReply::Handled(); 

	UpdateCachedMousePos(MyGeometry, TouchEvent);
	UpdateCachedGeometry(MyGeometry);

	if( ViewportClient )
	{
		// Switch to the viewport clients world before processing input
		FScopedConditionalWorldSwitcher WorldSwitcher( ViewportClient );

		const FVector2D TouchPosition = MyGeometry.AbsoluteToLocal(TouchEvent.GetLastScreenSpacePosition());

		if( !ViewportClient->InputTouch( this, TouchEvent.GetUserIndex(), TouchEvent.GetPointerIndex(), ETouchType::Ended, TouchPosition, FDateTime::Now(), TouchEvent.GetTouchpadIndex()) )
		{
			CurrentReplyState = FReply::Unhandled(); 
		}
	}

	return CurrentReplyState;
}
예제 #22
0
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;
}
예제 #23
0
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;
}