mirror of
https://github.com/kevinporetti/UnrealImGui.git
synced 2025-01-18 08:20:32 +00:00
Added support for touch input (experimental and right now only non-shared):
- Added to SImGuiWidget and FImGuiInputHandler handling of touch started, move and ended events. - Events are passed to FImGuiInputState to be copied to ImGui IO as a mouse move and left button down. - Added one frame lag between touch ending event and ending processing, to allow ImGui handle mouse-up event.
This commit is contained in:
parent
e651b0f88f
commit
5f1dc964cf
@ -145,6 +145,25 @@ FReply UImGuiInputHandler::OnMouseMove(const FVector2D& MousePosition)
|
|||||||
return ToReply(true);
|
return ToReply(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FReply UImGuiInputHandler::OnTouchStarted(const FVector2D& CursorPosition, const FPointerEvent& TouchEvent)
|
||||||
|
{
|
||||||
|
InputState->SetTouchDown(true);
|
||||||
|
InputState->SetTouchPosition(CursorPosition);
|
||||||
|
return ToReply(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
FReply UImGuiInputHandler::OnTouchMoved(const FVector2D& CursorPosition, const FPointerEvent& TouchEvent)
|
||||||
|
{
|
||||||
|
InputState->SetTouchPosition(CursorPosition);
|
||||||
|
return ToReply(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
FReply UImGuiInputHandler::OnTouchEnded(const FVector2D& CursorPosition, const FPointerEvent& TouchEvent)
|
||||||
|
{
|
||||||
|
InputState->SetTouchDown(false);
|
||||||
|
return ToReply(true);
|
||||||
|
}
|
||||||
|
|
||||||
void UImGuiInputHandler::OnKeyboardInputEnabled()
|
void UImGuiInputHandler::OnKeyboardInputEnabled()
|
||||||
{
|
{
|
||||||
bKeyboardInputEnabled = true;
|
bKeyboardInputEnabled = true;
|
||||||
|
@ -93,6 +93,8 @@ void FImGuiInputState::ClearUpdateState()
|
|||||||
MouseButtonsUpdateRange.SetEmpty();
|
MouseButtonsUpdateRange.SetEmpty();
|
||||||
|
|
||||||
MouseWheelDelta = 0.f;
|
MouseWheelDelta = 0.f;
|
||||||
|
|
||||||
|
bTouchProcessed = bTouchDown;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FImGuiInputState::ClearCharacters()
|
void FImGuiInputState::ClearCharacters()
|
||||||
|
@ -82,11 +82,11 @@ public:
|
|||||||
// @param DeltaValue - Mouse wheel delta to add
|
// @param DeltaValue - Mouse wheel delta to add
|
||||||
void AddMouseWheelDelta(float DeltaValue) { MouseWheelDelta += DeltaValue; }
|
void AddMouseWheelDelta(float DeltaValue) { MouseWheelDelta += DeltaValue; }
|
||||||
|
|
||||||
// Get the current mouse position.
|
// Get the mouse position.
|
||||||
const FVector2D& GetMousePosition() const { return MousePosition; }
|
const FVector2D& GetMousePosition() const { return MousePosition; }
|
||||||
|
|
||||||
// Set mouse position.
|
// Set the mouse position.
|
||||||
// @param Position - New mouse position
|
// @param Position - Mouse position
|
||||||
void SetMousePosition(const FVector2D& Position) { MousePosition = Position; }
|
void SetMousePosition(const FVector2D& Position) { MousePosition = Position; }
|
||||||
|
|
||||||
// Check whether input has active mouse pointer.
|
// Check whether input has active mouse pointer.
|
||||||
@ -96,6 +96,24 @@ public:
|
|||||||
// @param bHasPointer - True, if input has active mouse pointer
|
// @param bHasPointer - True, if input has active mouse pointer
|
||||||
void SetMousePointer(bool bInHasMousePointer) { bHasMousePointer = bInHasMousePointer; }
|
void SetMousePointer(bool bInHasMousePointer) { bHasMousePointer = bInHasMousePointer; }
|
||||||
|
|
||||||
|
// Check whether touch input is in progress. True, after touch is started until one frame after it has ended.
|
||||||
|
// One frame delay is used to process mouse release in ImGui since touch-down is simulated with mouse-down.
|
||||||
|
bool IsTouchActive() const { return bTouchDown || bTouchProcessed; }
|
||||||
|
|
||||||
|
// Check whether touch input is down.
|
||||||
|
bool IsTouchDown() const { return bTouchDown; }
|
||||||
|
|
||||||
|
// Set whether touch input is down.
|
||||||
|
// @param bIsDown - True, if touch is down (or started) and false, if touch is up (or ended)
|
||||||
|
void SetTouchDown(bool bIsDown) { bTouchDown = bIsDown; }
|
||||||
|
|
||||||
|
// Get the touch position.
|
||||||
|
const FVector2D& GetTouchPosition() const { return TouchPosition; }
|
||||||
|
|
||||||
|
// Set the touch position.
|
||||||
|
// @param Position - Touch position
|
||||||
|
void SetTouchPosition(const FVector2D& Position) { TouchPosition = Position; }
|
||||||
|
|
||||||
// Get Control down state.
|
// Get Control down state.
|
||||||
bool IsControlDown() const { return bIsControlDown; }
|
bool IsControlDown() const { return bIsControlDown; }
|
||||||
|
|
||||||
@ -197,6 +215,7 @@ private:
|
|||||||
void ClearNavigationInputs();
|
void ClearNavigationInputs();
|
||||||
|
|
||||||
FVector2D MousePosition = FVector2D::ZeroVector;
|
FVector2D MousePosition = FVector2D::ZeroVector;
|
||||||
|
FVector2D TouchPosition = FVector2D::ZeroVector;
|
||||||
float MouseWheelDelta = 0.f;
|
float MouseWheelDelta = 0.f;
|
||||||
|
|
||||||
FMouseButtonsArray MouseButtonsDown;
|
FMouseButtonsArray MouseButtonsDown;
|
||||||
@ -211,6 +230,8 @@ private:
|
|||||||
FNavInputArray NavigationInputs;
|
FNavInputArray NavigationInputs;
|
||||||
|
|
||||||
bool bHasMousePointer = false;
|
bool bHasMousePointer = false;
|
||||||
|
bool bTouchDown = false;
|
||||||
|
bool bTouchProcessed = false;
|
||||||
|
|
||||||
bool bIsControlDown = false;
|
bool bIsControlDown = false;
|
||||||
bool bIsShiftDown = false;
|
bool bIsShiftDown = false;
|
||||||
|
@ -247,16 +247,6 @@ namespace ImGuiInterops
|
|||||||
static const uint32 LeftAlt = GetKeyIndex(EKeys::LeftAlt);
|
static const uint32 LeftAlt = GetKeyIndex(EKeys::LeftAlt);
|
||||||
static const uint32 RightAlt = GetKeyIndex(EKeys::RightAlt);
|
static const uint32 RightAlt = GetKeyIndex(EKeys::RightAlt);
|
||||||
|
|
||||||
// Check whether we need to draw cursor.
|
|
||||||
IO.MouseDrawCursor = InputState.HasMousePointer();
|
|
||||||
|
|
||||||
// Copy mouse position.
|
|
||||||
IO.MousePos.x = InputState.GetMousePosition().X;
|
|
||||||
IO.MousePos.y = InputState.GetMousePosition().Y;
|
|
||||||
|
|
||||||
// Copy mouse wheel delta.
|
|
||||||
IO.MouseWheel += InputState.GetMouseWheelDelta();
|
|
||||||
|
|
||||||
// Copy key modifiers.
|
// Copy key modifiers.
|
||||||
IO.KeyCtrl = InputState.IsControlDown();
|
IO.KeyCtrl = InputState.IsControlDown();
|
||||||
IO.KeyShift = InputState.IsShiftDown();
|
IO.KeyShift = InputState.IsShiftDown();
|
||||||
@ -287,5 +277,28 @@ namespace ImGuiInterops
|
|||||||
SetFlag(IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard, InputState.IsKeyboardNavigationEnabled());
|
SetFlag(IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard, InputState.IsKeyboardNavigationEnabled());
|
||||||
SetFlag(IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad, InputState.IsGamepadNavigationEnabled());
|
SetFlag(IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad, InputState.IsGamepadNavigationEnabled());
|
||||||
SetFlag(IO.BackendFlags, ImGuiBackendFlags_HasGamepad, InputState.HasGamepad());
|
SetFlag(IO.BackendFlags, ImGuiBackendFlags_HasGamepad, InputState.HasGamepad());
|
||||||
|
|
||||||
|
// Check whether we need to draw cursor.
|
||||||
|
IO.MouseDrawCursor = InputState.HasMousePointer();
|
||||||
|
|
||||||
|
// If touch is enabled and active, give it a precedence.
|
||||||
|
if (InputState.IsTouchActive())
|
||||||
|
{
|
||||||
|
// Copy the touch position to mouse position.
|
||||||
|
IO.MousePos.x = InputState.GetTouchPosition().X;
|
||||||
|
IO.MousePos.y = InputState.GetTouchPosition().Y;
|
||||||
|
|
||||||
|
// With touch active one frame longer than it is down, we have one frame to processed touch up.
|
||||||
|
IO.MouseDown[0] = InputState.IsTouchDown();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Copy the mouse position.
|
||||||
|
IO.MousePos.x = InputState.GetMousePosition().X;
|
||||||
|
IO.MousePos.y = InputState.GetMousePosition().Y;
|
||||||
|
|
||||||
|
// Copy mouse wheel delta.
|
||||||
|
IO.MouseWheel += InputState.GetMouseWheelDelta();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,8 +189,7 @@ FReply SImGuiWidget::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEve
|
|||||||
|
|
||||||
FReply SImGuiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
FReply SImGuiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
|
||||||
{
|
{
|
||||||
const FSlateRenderTransform ImGuiToScreen = ImGuiTransform.Concatenate(MyGeometry.GetAccumulatedRenderTransform());
|
return InputHandler->OnMouseMove(TransformScreenPointToImGui(MyGeometry, MouseEvent.GetScreenSpacePosition()));
|
||||||
return InputHandler->OnMouseMove(ImGuiToScreen.Inverse().TransformPoint(MouseEvent.GetScreenSpacePosition()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FReply SImGuiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent)
|
FReply SImGuiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent)
|
||||||
@ -235,6 +234,22 @@ void SImGuiWidget::OnMouseLeave(const FPointerEvent& MouseEvent)
|
|||||||
InputHandler->OnMouseInputDisabled();
|
InputHandler->OnMouseInputDisabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FReply SImGuiWidget::OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent)
|
||||||
|
{
|
||||||
|
return InputHandler->OnTouchStarted(TransformScreenPointToImGui(MyGeometry, TouchEvent.GetScreenSpacePosition()), TouchEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
FReply SImGuiWidget::OnTouchMoved(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent)
|
||||||
|
{
|
||||||
|
return InputHandler->OnTouchMoved(TransformScreenPointToImGui(MyGeometry, TouchEvent.GetScreenSpacePosition()), TouchEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
FReply SImGuiWidget::OnTouchEnded(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent)
|
||||||
|
{
|
||||||
|
UpdateVisibility();
|
||||||
|
return InputHandler->OnTouchEnded(TransformScreenPointToImGui(MyGeometry, TouchEvent.GetScreenSpacePosition()), TouchEvent);
|
||||||
|
}
|
||||||
|
|
||||||
void SImGuiWidget::CreateInputHandler(const FStringClassReference& HandlerClassReference)
|
void SImGuiWidget::CreateInputHandler(const FStringClassReference& HandlerClassReference)
|
||||||
{
|
{
|
||||||
ReleaseInputHandler();
|
ReleaseInputHandler();
|
||||||
@ -446,8 +461,7 @@ void SImGuiWidget::UpdateTransparentMouseInput(const FGeometry& AllottedGeometry
|
|||||||
{
|
{
|
||||||
if (!GameViewport->GetGameViewportWidget()->HasMouseCapture())
|
if (!GameViewport->GetGameViewportWidget()->HasMouseCapture())
|
||||||
{
|
{
|
||||||
const FSlateRenderTransform ImGuiToScreen = ImGuiTransform.Concatenate(AllottedGeometry.GetAccumulatedRenderTransform());
|
InputHandler->OnMouseMove(TransformScreenPointToImGui(AllottedGeometry, FSlateApplication::Get().GetCursorPos()));
|
||||||
InputHandler->OnMouseMove(ImGuiToScreen.Inverse().TransformPoint(FSlateApplication::Get().GetCursorPos()));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -490,6 +504,12 @@ void SImGuiWidget::OnPostImGuiUpdate()
|
|||||||
UpdateMouseCursor();
|
UpdateMouseCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FVector2D SImGuiWidget::TransformScreenPointToImGui(const FGeometry& MyGeometry, const FVector2D& Point) const
|
||||||
|
{
|
||||||
|
const FSlateRenderTransform ImGuiToScreen = ImGuiTransform.Concatenate(MyGeometry.GetAccumulatedRenderTransform());
|
||||||
|
return ImGuiToScreen.Inverse().TransformPoint(Point);
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
FORCEINLINE FSlateRenderTransform RoundTranslation(const FSlateRenderTransform& Transform)
|
FORCEINLINE FSlateRenderTransform RoundTranslation(const FSlateRenderTransform& Transform)
|
||||||
|
@ -70,6 +70,12 @@ public:
|
|||||||
|
|
||||||
virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override;
|
virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override;
|
||||||
|
|
||||||
|
virtual FReply OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override;
|
||||||
|
|
||||||
|
virtual FReply OnTouchMoved(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override;
|
||||||
|
|
||||||
|
virtual FReply OnTouchEnded(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void CreateInputHandler(const FStringClassReference& HandlerClassReference);
|
void CreateInputHandler(const FStringClassReference& HandlerClassReference);
|
||||||
@ -101,6 +107,8 @@ private:
|
|||||||
|
|
||||||
void OnPostImGuiUpdate();
|
void OnPostImGuiUpdate();
|
||||||
|
|
||||||
|
FVector2D TransformScreenPointToImGui(const FGeometry& MyGeometry, const FVector2D& Point) const;
|
||||||
|
|
||||||
virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& WidgetStyle, bool bParentEnabled) const override;
|
virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& WidgetStyle, bool bParentEnabled) const override;
|
||||||
|
|
||||||
virtual FVector2D ComputeDesiredSize(float) const override;
|
virtual FVector2D ComputeDesiredSize(float) const override;
|
||||||
|
@ -82,11 +82,35 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Called to handle mouse move events.
|
* Called to handle mouse move events.
|
||||||
* @param Mouse position (in ImGui space)
|
* @param MousePosition Mouse position (in ImGui space)
|
||||||
* @returns Response whether the event was handled
|
* @returns Response whether the event was handled
|
||||||
*/
|
*/
|
||||||
virtual FReply OnMouseMove(const FVector2D& MousePosition);
|
virtual FReply OnMouseMove(const FVector2D& MousePosition);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to handle touch started event.
|
||||||
|
* @param TouchPosition Touch position (in ImGui space)
|
||||||
|
* @param TouchEvent Touch event passed from Slate
|
||||||
|
* @returns Response whether the event was handled
|
||||||
|
*/
|
||||||
|
virtual FReply OnTouchStarted(const FVector2D& TouchPosition, const FPointerEvent& TouchEvent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to handle touch moved event.
|
||||||
|
* @param TouchPosition Touch position (in ImGui space)
|
||||||
|
* @param TouchEvent Touch event passed from Slate
|
||||||
|
* @returns Response whether the event was handled
|
||||||
|
*/
|
||||||
|
virtual FReply OnTouchMoved(const FVector2D& TouchPosition, const FPointerEvent& TouchEvent);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to handle touch ended event.
|
||||||
|
* @param TouchPosition Touch position (in ImGui space)
|
||||||
|
* @param TouchEvent Touch event passed from Slate
|
||||||
|
* @returns Response whether the event was handled
|
||||||
|
*/
|
||||||
|
virtual FReply OnTouchEnded(const FVector2D& TouchPosition, const FPointerEvent& TouchEvent);
|
||||||
|
|
||||||
/** Called to handle activation of the keyboard input. */
|
/** Called to handle activation of the keyboard input. */
|
||||||
virtual void OnKeyboardInputEnabled();
|
virtual void OnKeyboardInputEnabled();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user