133 lines
4.6 KiB
C++
133 lines
4.6 KiB
C++
// Copyright Sam Bonifacio. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "Blueprint/UserWidget.h"
|
|
#include "Misc/AutoSettingsInputConfig.h"
|
|
#include "BindCapturePrompt.generated.h"
|
|
|
|
USTRUCT(BlueprintType)
|
|
struct AUTOSETTINGSINPUT_API FCapturedInput
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
|
|
FInputChord Chord;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Input")
|
|
float AxisScale = 0.f;
|
|
};
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FChordCapturedEvent, FCapturedInput, CapturedInput);
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FChordRejectedEvent, FCapturedInput, CapturedInput);
|
|
|
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FCapturePromptClosedEvent, bool, bWasCancelled);
|
|
|
|
UENUM()
|
|
enum class EBindingCaptureMode : uint8
|
|
{
|
|
// Capture keys when they are released (default)
|
|
OnReleased,
|
|
// Capture keys when they are pressed. This will prevent use of modifiers, since a modifier will be captured by itself when it is pressed.
|
|
OnPressed,
|
|
};
|
|
|
|
/**
|
|
* Prompt that listens for an input chord and fires an event when it captures one
|
|
*/
|
|
UCLASS(abstract)
|
|
class AUTOSETTINGSINPUT_API UBindCapturePrompt : public UUserWidget
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UBindCapturePrompt(const FObjectInitializer& ObjectInitializer);
|
|
|
|
// If true, then will tell viewport to ignore all game input (leaving only UI input)
|
|
// while capturing, then restore if when closed. If the game supports multiple local players
|
|
// binding at the same time then this may be undesirable.
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Bind Capture Prompt")
|
|
bool bIgnoreGameViewportInputWhileCapturing;
|
|
|
|
// If true, only allow capturing keys in the passed in Key Group, otherwise the keys will be captured anyway
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Bind Capture Prompt")
|
|
bool bRestrictKeyGroup;
|
|
|
|
// Should keys and mouse clicks be captured when they are pressed, or when they are released?
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Bind Capture Prompt")
|
|
EBindingCaptureMode CaptureMode;
|
|
|
|
// If valid and bRestrictKeyGroup is true, then only keys allowed by this Key Group will be captured
|
|
// If a key is rejected for not being in the Key Group, then OnChordRejected will be fired
|
|
UPROPERTY()
|
|
FGameplayTag KeyGroup;
|
|
|
|
// Fired when an input chord is captured
|
|
UPROPERTY(BlueprintAssignable, Category = "Bind Capture Prompt")
|
|
FChordCapturedEvent OnChordCaptured;
|
|
|
|
// Fired when an input chord is rejected
|
|
UPROPERTY(BlueprintAssignable, Category = "Bind Capture Prompt")
|
|
FChordRejectedEvent OnChordRejected;
|
|
|
|
// Fired when the capture prompt is closed
|
|
UPROPERTY(BlueprintAssignable, Category = "Bind Capture Prompt")
|
|
FCapturePromptClosedEvent OnCapturePromptClosed;
|
|
|
|
// Cancel listening and close the prompt
|
|
UFUNCTION(BlueprintCallable, Category = "Bind Capture Prompt")
|
|
void Cancel();
|
|
|
|
// Returns the key group used for this prompt
|
|
UFUNCTION(BlueprintPure, Category = "Bind Capture Prompt")
|
|
FGameplayTag GetKeyGroup() const { return KeyGroup; }
|
|
|
|
protected:
|
|
|
|
// Keys that are currently down, used to collect modifiers
|
|
UPROPERTY()
|
|
TArray<FKey> KeysDown;
|
|
|
|
// Value of viewport's "ignore input" before the prompt was opened
|
|
UPROPERTY()
|
|
bool PreviousIgnoreInput;
|
|
|
|
virtual void NativeConstruct() override;
|
|
virtual void NativeDestruct() override;
|
|
|
|
// Start listening for capture input (called in Construct by default)
|
|
virtual void StartListening();
|
|
|
|
// Stop listening for capture input (called automatically after a binding is captured)
|
|
virtual void StopListening();
|
|
|
|
// Subclasses can override to disallow keys based on the prompt
|
|
UFUNCTION(BlueprintNativeEvent)
|
|
bool IsKeyAllowed(FKey PrimaryKey);
|
|
|
|
void Capture(FKey PrimaryKey = EKeys::Invalid, float AxisScale = 1.f);
|
|
|
|
virtual FReply NativeOnKeyDown(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) override;
|
|
virtual FReply NativeOnKeyUp(const FGeometry& InGeometry, const FKeyEvent& InKeyEvent) override;
|
|
virtual FReply NativeOnMouseButtonDown(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override;
|
|
virtual FReply NativeOnMouseButtonUp(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override;
|
|
virtual FReply NativeOnMouseWheel(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override;
|
|
virtual FReply NativeOnMouseMove(const FGeometry& InGeometry, const FPointerEvent& InMouseEvent) override;
|
|
|
|
private:
|
|
|
|
// Total delta the mouse has moved
|
|
UPROPERTY()
|
|
FVector2D AccumulatedMouseDelta;
|
|
|
|
bool ShouldIgnoreEvent(const FInputEvent& InputEvent) const;
|
|
|
|
void ConfirmCapture(FCapturedInput CapturedInput);
|
|
|
|
void RejectCapture(FCapturedInput CapturedInput);
|
|
|
|
void ClosePrompt(bool bWasCancelled);
|
|
|
|
};
|