mirror of
https://github.com/kevinporetti/UnrealImGui.git
synced 2025-01-18 00:10: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);
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
bKeyboardInputEnabled = true;
|
||||
|
@ -93,6 +93,8 @@ void FImGuiInputState::ClearUpdateState()
|
||||
MouseButtonsUpdateRange.SetEmpty();
|
||||
|
||||
MouseWheelDelta = 0.f;
|
||||
|
||||
bTouchProcessed = bTouchDown;
|
||||
}
|
||||
|
||||
void FImGuiInputState::ClearCharacters()
|
||||
|
@ -82,11 +82,11 @@ public:
|
||||
// @param DeltaValue - Mouse wheel delta to add
|
||||
void AddMouseWheelDelta(float DeltaValue) { MouseWheelDelta += DeltaValue; }
|
||||
|
||||
// Get the current mouse position.
|
||||
// Get the mouse position.
|
||||
const FVector2D& GetMousePosition() const { return MousePosition; }
|
||||
|
||||
// Set mouse position.
|
||||
// @param Position - New mouse position
|
||||
// Set the mouse position.
|
||||
// @param Position - Mouse position
|
||||
void SetMousePosition(const FVector2D& Position) { MousePosition = Position; }
|
||||
|
||||
// Check whether input has active mouse pointer.
|
||||
@ -96,6 +96,24 @@ public:
|
||||
// @param bHasPointer - True, if input has active mouse pointer
|
||||
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.
|
||||
bool IsControlDown() const { return bIsControlDown; }
|
||||
|
||||
@ -197,6 +215,7 @@ private:
|
||||
void ClearNavigationInputs();
|
||||
|
||||
FVector2D MousePosition = FVector2D::ZeroVector;
|
||||
FVector2D TouchPosition = FVector2D::ZeroVector;
|
||||
float MouseWheelDelta = 0.f;
|
||||
|
||||
FMouseButtonsArray MouseButtonsDown;
|
||||
@ -211,6 +230,8 @@ private:
|
||||
FNavInputArray NavigationInputs;
|
||||
|
||||
bool bHasMousePointer = false;
|
||||
bool bTouchDown = false;
|
||||
bool bTouchProcessed = false;
|
||||
|
||||
bool bIsControlDown = false;
|
||||
bool bIsShiftDown = false;
|
||||
|
@ -247,16 +247,6 @@ namespace ImGuiInterops
|
||||
static const uint32 LeftAlt = GetKeyIndex(EKeys::LeftAlt);
|
||||
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.
|
||||
IO.KeyCtrl = InputState.IsControlDown();
|
||||
IO.KeyShift = InputState.IsShiftDown();
|
||||
@ -287,5 +277,28 @@ namespace ImGuiInterops
|
||||
SetFlag(IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard, InputState.IsKeyboardNavigationEnabled());
|
||||
SetFlag(IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad, InputState.IsGamepadNavigationEnabled());
|
||||
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)
|
||||
{
|
||||
const FSlateRenderTransform ImGuiToScreen = ImGuiTransform.Concatenate(MyGeometry.GetAccumulatedRenderTransform());
|
||||
return InputHandler->OnMouseMove(ImGuiToScreen.Inverse().TransformPoint(MouseEvent.GetScreenSpacePosition()));
|
||||
return InputHandler->OnMouseMove(TransformScreenPointToImGui(MyGeometry, MouseEvent.GetScreenSpacePosition()));
|
||||
}
|
||||
|
||||
FReply SImGuiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent)
|
||||
@ -235,6 +234,22 @@ void SImGuiWidget::OnMouseLeave(const FPointerEvent& MouseEvent)
|
||||
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)
|
||||
{
|
||||
ReleaseInputHandler();
|
||||
@ -446,8 +461,7 @@ void SImGuiWidget::UpdateTransparentMouseInput(const FGeometry& AllottedGeometry
|
||||
{
|
||||
if (!GameViewport->GetGameViewportWidget()->HasMouseCapture())
|
||||
{
|
||||
const FSlateRenderTransform ImGuiToScreen = ImGuiTransform.Concatenate(AllottedGeometry.GetAccumulatedRenderTransform());
|
||||
InputHandler->OnMouseMove(ImGuiToScreen.Inverse().TransformPoint(FSlateApplication::Get().GetCursorPos()));
|
||||
InputHandler->OnMouseMove(TransformScreenPointToImGui(AllottedGeometry, FSlateApplication::Get().GetCursorPos()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -490,6 +504,12 @@ void SImGuiWidget::OnPostImGuiUpdate()
|
||||
UpdateMouseCursor();
|
||||
}
|
||||
|
||||
FVector2D SImGuiWidget::TransformScreenPointToImGui(const FGeometry& MyGeometry, const FVector2D& Point) const
|
||||
{
|
||||
const FSlateRenderTransform ImGuiToScreen = ImGuiTransform.Concatenate(MyGeometry.GetAccumulatedRenderTransform());
|
||||
return ImGuiToScreen.Inverse().TransformPoint(Point);
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
FORCEINLINE FSlateRenderTransform RoundTranslation(const FSlateRenderTransform& Transform)
|
||||
|
@ -70,6 +70,12 @@ public:
|
||||
|
||||
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:
|
||||
|
||||
void CreateInputHandler(const FStringClassReference& HandlerClassReference);
|
||||
@ -101,6 +107,8 @@ private:
|
||||
|
||||
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 FVector2D ComputeDesiredSize(float) const override;
|
||||
|
@ -82,11 +82,35 @@ public:
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
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. */
|
||||
virtual void OnKeyboardInputEnabled();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user