109 lines
3.1 KiB
C++
109 lines
3.1 KiB
C++
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
|
|
|
|
|
|
#include "UI/Mobile/GUIS_JoystickWidget.h"
|
|
|
|
#include "CommonHardwareVisibilityBorder.h"
|
|
#include "Components/Image.h"
|
|
|
|
#include UE_INLINE_GENERATED_CPP_BY_NAME(GUIS_JoystickWidget)
|
|
|
|
#define LOCTEXT_NAMESPACE "GUIS_Joystick"
|
|
|
|
UGUIS_JoystickWidget::UGUIS_JoystickWidget(const FObjectInitializer& ObjectInitializer)
|
|
: Super(ObjectInitializer)
|
|
{
|
|
SetConsumePointerInput(true);
|
|
}
|
|
|
|
FReply UGUIS_JoystickWidget::NativeOnTouchStarted(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent)
|
|
{
|
|
Super::NativeOnTouchStarted(InGeometry, InGestureEvent);
|
|
|
|
TouchOrigin = InGestureEvent.GetScreenSpacePosition();
|
|
|
|
FReply Reply = FReply::Handled();
|
|
if (!HasMouseCaptureByUser(InGestureEvent.GetUserIndex(), InGestureEvent.GetPointerIndex()))
|
|
{
|
|
Reply.CaptureMouse(GetCachedWidget().ToSharedRef());
|
|
}
|
|
return Reply;
|
|
}
|
|
|
|
FReply UGUIS_JoystickWidget::NativeOnTouchMoved(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent)
|
|
{
|
|
Super::NativeOnTouchMoved(InGeometry, InGestureEvent);
|
|
HandleTouchDelta(InGeometry, InGestureEvent);
|
|
|
|
FReply Reply = FReply::Handled();
|
|
if (!HasMouseCaptureByUser(InGestureEvent.GetUserIndex(), InGestureEvent.GetPointerIndex()))
|
|
{
|
|
Reply.CaptureMouse(GetCachedWidget().ToSharedRef());
|
|
}
|
|
return Reply;
|
|
}
|
|
|
|
FReply UGUIS_JoystickWidget::NativeOnTouchEnded(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent)
|
|
{
|
|
StopInputSimulation();
|
|
return FReply::Handled().ReleaseMouseCapture();
|
|
}
|
|
|
|
void UGUIS_JoystickWidget::NativeOnMouseLeave(const FPointerEvent& InMouseEvent)
|
|
{
|
|
Super::NativeOnMouseLeave(InMouseEvent);
|
|
StopInputSimulation();
|
|
}
|
|
|
|
void UGUIS_JoystickWidget::NativeTick(const FGeometry& MyGeometry, float InDeltaTime)
|
|
{
|
|
Super::NativeTick(MyGeometry, InDeltaTime);
|
|
|
|
if (!CommonVisibilityBorder || CommonVisibilityBorder->IsVisible())
|
|
{
|
|
// Move the inner stick icon around with the vector
|
|
if (JoystickForeground && JoystickBackground)
|
|
{
|
|
JoystickForeground->SetRenderTranslation(
|
|
(bNegateYAxis ? FVector2D(1.0f, -1.0f) : FVector2D(1.0f)) *
|
|
StickVector *
|
|
(JoystickBackground->GetDesiredSize() * 0.5f)
|
|
);
|
|
}
|
|
InputKeyValue2D(StickVector);
|
|
}
|
|
}
|
|
|
|
void UGUIS_JoystickWidget::HandleTouchDelta(const FGeometry& InGeometry, const FPointerEvent& InGestureEvent)
|
|
{
|
|
const FVector2D& ScreenSpacePos = InGestureEvent.GetScreenSpacePosition();
|
|
|
|
// The center of the geo locally is just its size
|
|
FVector2D LocalStickCenter = InGeometry.GetAbsoluteSize();
|
|
|
|
FVector2D ScreenSpaceStickCenter = InGeometry.LocalToAbsolute(LocalStickCenter);
|
|
// Get the offset from the origin
|
|
FVector2D MoveStickOffset = (ScreenSpacePos - ScreenSpaceStickCenter);
|
|
if (bNegateYAxis)
|
|
{
|
|
MoveStickOffset *= FVector2D(1.0f, -1.0f);
|
|
}
|
|
|
|
FVector2D MoveStickDir = FVector2D::ZeroVector;
|
|
float MoveStickLength = 0.0f;
|
|
MoveStickOffset.ToDirectionAndLength(MoveStickDir, MoveStickLength);
|
|
|
|
MoveStickLength = FMath::Min(MoveStickLength, StickRange);
|
|
MoveStickOffset = MoveStickDir * MoveStickLength;
|
|
|
|
StickVector = MoveStickOffset / StickRange;
|
|
}
|
|
|
|
void UGUIS_JoystickWidget::StopInputSimulation()
|
|
{
|
|
TouchOrigin = FVector2D::ZeroVector;
|
|
StickVector = FVector2D::ZeroVector;
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE
|