Squashed 'external/gainput/' content from commit 2be0a50

git-subtree-dir: external/gainput
git-subtree-split: 2be0a50089eafcc6fccb66142180082e48f27f4c
This commit is contained in:
Simone
2024-01-22 08:51:55 +01:00
commit 4e42229bdd
170 changed files with 31921 additions and 0 deletions

View File

@@ -0,0 +1,47 @@
#ifndef GAINPUTBUTTONSTICKGESTURE_H_
#define GAINPUTBUTTONSTICKGESTURE_H_
#ifdef GAINPUT_ENABLE_BUTTON_STICK_GESTURE
namespace gainput
{
/// Buttons provided by the ButtonStickGesture.
enum ButtonStickAction
{
ButtonStickAxis
};
class GAINPUT_LIBEXPORT ButtonStickGesture : public InputGesture
{
public:
/// Initializes the gesture.
ButtonStickGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant);
/// Uninitializes the gesture.
~ButtonStickGesture();
/// Sets up the gesture for operation with the given axes and buttons.
void Initialize(DeviceId negativeAxisDevice, DeviceButtonId negativeAxis,
DeviceId positiveAxisDevice, DeviceButtonId positiveAxis);
bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == ButtonStickAxis; }
ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_UNUSED(deviceButton); GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return BT_FLOAT; }
protected:
void InternalUpdate(InputDeltaState* delta);
private:
DeviceButtonSpec negativeAxis_;
DeviceButtonSpec positiveAxis_;
};
}
#endif
#endif

View File

@@ -0,0 +1,99 @@
#ifndef GAINPUTDOUBLECLICKGESTURE_H_
#define GAINPUTDOUBLECLICKGESTURE_H_
#ifdef GAINPUT_ENABLE_DOUBLE_CLICK_GESTURE
namespace gainput
{
/// Buttons provided by the DoubleClickGesture.
enum DoubleClickAction
{
DoubleClickTriggered ///< The button triggered by double-clicking.
};
/// A double-click gesture.
/**
* This gesture implements the classic double-click functionality. Its only device button ::DoubleClickTriggered is
* true for one frame after the specified button has been active for a specified number of times in a given
* time frame. It's also possible to disallow the pointer from travelling too far between and during clicks.
*
* After instantiating the gesture like any other input device, call one of the Initialize() functions to properly
* set it up.
*
* In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or
* \c GAINPUT_ENABLE_DOUBLE_CLICK_GESTURE defined.
*
* \sa Initialize
* \sa SetClicksTargetCount
* \sa InputManager::CreateDevice
*/
class GAINPUT_LIBEXPORT DoubleClickGesture : public InputGesture
{
public:
/// Initializes the gesture.
DoubleClickGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant);
/// Uninitializes the gesture.
~DoubleClickGesture();
/// Sets up the gesture for operation without position checking.
/**
* \param actionButtonDevice ID of the input device containing the action button.
* \param actionButton ID of the device button to be used as the action button.
* \param timeSpan Allowed time between clicks in milliseconds.
*/
void Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, uint64_t timeSpan = 300);
/// Sets up the gesture for operation with position checking, i.e. the user may not move the mouse too far between clicks.
/**
* \param actionButtonDevice ID of the input device containing the action button.
* \param actionButton ID of the device button to be used as the action button.
* \param xAxisDevice ID of the input device containing the X coordinate of the pointer.
* \param xAxis ID of the device button/axis to be used for the X coordinate of the pointer.
* \param xTolerance The amount the pointer may travel in the X coordinate to still be valid.
* \param yAxisDevice ID of the input device containing the Y coordinate of the pointer.
* \param yAxis ID of the device button/axis to be used for the Y coordinate of the pointer.
* \param yTolerance The amount the pointer may travel in the Y coordinate to still be valid.
* \param timeSpan Allowed time between clicks in milliseconds.
*/
void Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton,
DeviceId xAxisDevice, DeviceButtonId xAxis, float xTolerance,
DeviceId yAxisDevice, DeviceButtonId yAxis, float yTolerance,
uint64_t timeSpan = 300);
/// Sets the number of clicks to trigger an action.
/**
* \param count The number of clicks that will trigger this gesture; the default is 2, i.e. double-click.
*/
void SetClicksTargetCount(unsigned count) { clicksTargetCount_ = count; }
bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == DoubleClickTriggered; }
ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_UNUSED(deviceButton); GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return BT_BOOL; }
protected:
void InternalUpdate(InputDeltaState* delta);
private:
DeviceButtonSpec actionButton_;
DeviceButtonSpec xAxis_;
float xTolerance_;
DeviceButtonSpec yAxis_;
float yTolerance_;
uint64_t timeSpan_;
uint64_t firstClickTime_;
float firstClickX_;
float firstClickY_;
unsigned clicksRegistered_;
unsigned clicksTargetCount_;
};
}
#endif
#endif

View File

@@ -0,0 +1,69 @@
#ifndef GAINPUTGESTURES_H_
#define GAINPUTGESTURES_H_
#ifdef GAINPUT_ENABLE_ALL_GESTURES
#define GAINPUT_ENABLE_BUTTON_STICK_GESTURE
#define GAINPUT_ENABLE_DOUBLE_CLICK_GESTURE
#define GAINPUT_ENABLE_HOLD_GESTURE
#define GAINPUT_ENABLE_PINCH_GESTURE
#define GAINPUT_ENABLE_ROTATE_GESTURE
#define GAINPUT_ENABLE_SIMULTANEOUSLY_DOWN_GESTURE
#define GAINPUT_ENABLE_TAP_GESTURE
#endif
namespace gainput
{
/// Base class for all input gestures.
/**
* Input gestures are a way to process basic input data into more complex input data. For example,
* multiple buttons may be interpreted over time to form a new button. A very simple gesture would the
* ubiquitous double-click.
*
* Mainly for consistency and convenience reasons, all gestures should derive from this class though it's not
* strictly necessary (deriving from InputDevice would suffice).
*
* Input gestures are basically just input devices that don't get their data from some hardware device
* but from other input devices instead. Therefore gestures must also be created by calling
* InputManager::CreateDevice() or InputManager::CreateAndGetDevice(). Most gestures require further
* initialization which is done by calling one of their \c Initialize() member functions. After that,
* they should be good to go and their buttons can be used like any other input device button, i.e.
* they can be mapped to some user button.
*
* Gestures can be excluded from compilation if they are not required. In order to include all gestures
* \c GAINPUT_ENABLE_ALL_GESTURES should be defined in \c gainput.h . This define must be present when
* the library is built, otherwise the actual functionality won't be present. Similarly, there is one
* define for each gesture. The names of these are documented in the descriptions of the
* individual gesture classes. If no such define is defined, no gesture will be included.
*/
class GAINPUT_LIBEXPORT InputGesture : public InputDevice
{
public:
/// Returns DT_GESTURE.
DeviceType GetType() const { return DT_GESTURE; }
const char* GetTypeName() const { return "gesture"; }
bool IsLateUpdate() const { return true; }
protected:
/// Gesture base constructor.
InputGesture(InputManager& manager, DeviceId device, unsigned index) : InputDevice(manager, device, index == InputDevice::AutoIndex ? manager.GetDeviceCountByType(DT_GESTURE) : 0) { }
DeviceState InternalGetState() const { return DS_OK; }
};
}
#include <gainput/gestures/GainputButtonStickGesture.h>
#include <gainput/gestures/GainputDoubleClickGesture.h>
#include <gainput/gestures/GainputHoldGesture.h>
#include <gainput/gestures/GainputPinchGesture.h>
#include <gainput/gestures/GainputRotateGesture.h>
#include <gainput/gestures/GainputSimultaneouslyDownGesture.h>
#include <gainput/gestures/GainputTapGesture.h>
#endif

View File

@@ -0,0 +1,94 @@
#ifndef GAINPUTHOLDGESTURE_H_
#define GAINPUTHOLDGESTURE_H_
#ifdef GAINPUT_ENABLE_HOLD_GESTURE
namespace gainput
{
/// Buttons provided by the HoldGesture.
enum HoldAction
{
HoldTriggered ///< The button that triggers after holding for the given time.
};
/// A hold-to-trigger gesture.
/**
* This gesture, mainly meant for touch devices, triggers after the specified button has been down for at least
* the specified amount of time. Its button ::HoldTriggered is then either active for one frame or as long as
* the source button is down.
*
* After instantiating the gesture like any other input device, call one of the Initialize() functions to properly
* set it up.
*
* In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or
* \c GAINPUT_ENABLE_HOLD_GESTURE defined.
*
* \sa Initialize
* \sa InputManager::CreateDevice
*/
class GAINPUT_LIBEXPORT HoldGesture : public InputGesture
{
public:
/// Initializes the gesture.
HoldGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant);
/// Uninitializes the gesture.
~HoldGesture();
/// Sets up the gesture for operation without position checking.
/**
* \param actionButtonDevice ID of the input device containing the action button.
* \param actionButton ID of the device button to be used as the action button.
* \param oneShot Specifies if the gesture triggers only once after the given time or if it triggers as long as the source button is down.
* \param timeSpan Time in milliseconds the user needs to hold in order to trigger the gesture.
*/
void Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, bool oneShot = true, uint64_t timeSpan = 800);
/// Sets up the gesture for operation with position checking, i.e. the user may not move the mouse too far while holding.
/**
* \param actionButtonDevice ID of the input device containing the action button.
* \param actionButton ID of the device button to be used as the action button.
* \param xAxisDevice ID of the input device containing the X coordinate of the pointer.
* \param xAxis ID of the device button/axis to be used for the X coordinate of the pointer.
* \param xTolerance The amount the pointer may travel in the X coordinate to still be valid.
* \param yAxisDevice ID of the input device containing the Y coordinate of the pointer.
* \param yAxis ID of the device button/axis to be used for the Y coordinate of the pointer.
* \param yTolerance The amount the pointer may travel in the Y coordinate to still be valid.
* \param oneShot Specifies if the gesture triggers only once after the given time or if it triggers as long as the source button is down.
* \param timeSpan Time in milliseconds the user needs to hold in order to trigger the gesture.
*/
void Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton,
DeviceId xAxisDevice, DeviceButtonId xAxis, float xTolerance,
DeviceId yAxisDevice, DeviceButtonId yAxis, float yTolerance,
bool oneShot = true,
uint64_t timeSpan = 800);
bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == HoldTriggered; }
ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_UNUSED(deviceButton); GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return BT_BOOL; }
protected:
void InternalUpdate(InputDeltaState* delta);
private:
DeviceButtonSpec actionButton_;
DeviceButtonSpec xAxis_;
float xTolerance_;
DeviceButtonSpec yAxis_;
float yTolerance_;
bool oneShot_;
bool oneShotReset_;
uint64_t timeSpan_;
uint64_t firstDownTime_;
float firstDownX_;
float firstDownY_;
};
}
#endif
#endif

View File

@@ -0,0 +1,86 @@
#ifndef GAINPUTPINCHGESTURE_H_
#define GAINPUTPINCHGESTURE_H_
#ifdef GAINPUT_ENABLE_PINCH_GESTURE
namespace gainput
{
/// Buttons provided by the PinchGesture.
enum PinchAction
{
PinchTriggered, ///< The button that triggers when both pinch buttons are down.
PinchScale ///< The current pinch scale value if pinching is active.
};
/// A multi-touch pinch-to-scale gesture.
/**
* This gesture, mainly meant for multi-touch devices, triggers (::PinchTriggered is down) when both specified
* source buttons are down. It will then determine the distance between the two 2D touch points and report
* any change in distance as a factor of the initial distance using ::PinchScale.
*
* After instantiating the gesture like any other input device, call Initialize() to properly
* set it up.
*
* In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or
* \c GAINPUT_ENABLE_PINCH_GESTURE defined.
*
* \sa Initialize
* \sa InputManager::CreateDevice
*/
class GAINPUT_LIBEXPORT PinchGesture : public InputGesture
{
public:
/// Initializes the gesture.
PinchGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant);
/// Uninitializes the gesture.
~PinchGesture();
/// Sets up the gesture for operation with the given axes and buttons.
/**
* \param downDevice ID of the input device containing the first touch button.
* \param downButton ID of the device button to be used as the first touch button.
* \param xAxisDevice ID of the input device containing the X coordinate of the first touch point.
* \param xAxis ID of the device button/axis to be used for the X coordinate of the first touch point.
* \param yAxisDevice ID of the input device containing the Y coordinate of the first touch point.
* \param yAxis ID of the device button/axis to be used for the Y coordinate of the first touch point.
* \param down2Device ID of the input device containing the second touch button.
* \param downButton2 ID of the device button to be used as the second touch button.
* \param xAxis2Device ID of the input device containing the X coordinate of the second touch point.
* \param xAxis2 ID of the device button/axis to be used for the X coordinate of the second touch point.
* \param yAxis2Device ID of the input device containing the Y coordinate of the second touch point.
* \param yAxis2 ID of the device button/axis to be used for the Y coordinate of the second touch point.
*/
void Initialize(DeviceId downDevice, DeviceButtonId downButton,
DeviceId xAxisDevice, DeviceButtonId xAxis,
DeviceId yAxisDevice, DeviceButtonId yAxis,
DeviceId down2Device, DeviceButtonId downButton2,
DeviceId xAxis2Device, DeviceButtonId xAxis2,
DeviceId yAxis2Device, DeviceButtonId yAxis2);
bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == PinchTriggered || deviceButton == PinchScale; }
ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return deviceButton == PinchTriggered ? BT_BOOL : BT_FLOAT; }
protected:
void InternalUpdate(InputDeltaState* delta);
private:
DeviceButtonSpec downButton_;
DeviceButtonSpec xAxis_;
DeviceButtonSpec yAxis_;
DeviceButtonSpec downButton2_;
DeviceButtonSpec xAxis2_;
DeviceButtonSpec yAxis2_;
bool pinching_;
float initialDistance_;
};
}
#endif
#endif

View File

@@ -0,0 +1,87 @@
#ifndef GAINPUTROTATEGESTURE_H_
#define GAINPUTROTATEGESTURE_H_
#ifdef GAINPUT_ENABLE_ROTATE_GESTURE
namespace gainput
{
/// Buttons provided by the RotateGesture.
enum RotateAction
{
RotateTriggered, ///< The button that triggers when both rotate buttons are down.
RotateAngle ///< The current rotation angle in radians if rotation is triggered (::RotateTriggered).
};
/// A multi-touch rotate gesture.
/**
* This gesture, mainly meant for multi-touch devices, triggers (::RotateTriggered is down) when both specified
* source buttons are down. It then determines the angle between the two specified 2D touch points and reports any
* change in angle using ::RotateAngle. The initial angle between the two points is defined as no rotation.
*
* After instantiating the gesture like any other input device, call Initialize() to properly
* set it up.
*
* In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or
* \c GAINPUT_ENABLE_ROTATE_GESTURE defined.
*
* \sa Initialize
* \sa InputManager::CreateDevice
*/
class GAINPUT_LIBEXPORT RotateGesture : public InputGesture
{
public:
/// Initializes the gesture.
RotateGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant);
/// Uninitializes the gesture.
~RotateGesture();
/// Sets up the gesture for operation with the given axes and buttons.
/**
* \param downDevice ID of the input device containing the first touch button.
* \param downButton ID of the device button to be used as the first touch button.
* \param xAxisDevice ID of the input device containing the X coordinate of the first touch point.
* \param xAxis ID of the device button/axis to be used for the X coordinate of the first touch point.
* \param yAxisDevice ID of the input device containing the Y coordinate of the first touch point.
* \param yAxis ID of the device button/axis to be used for the Y coordinate of the first touch point.
* \param down2Device ID of the input device containing the second touch button.
* \param downButton2 ID of the device button to be used as the second touch button.
* \param xAxis2Device ID of the input device containing the X coordinate of the second touch point.
* \param xAxis2 ID of the device button/axis to be used for the X coordinate of the second touch point.
* \param yAxis2Device ID of the input device containing the Y coordinate of the second touch point.
* \param yAxis2 ID of the device button/axis to be used for the Y coordinate of the second touch point.
*/
void Initialize(DeviceId downDevice, DeviceButtonId downButton,
DeviceId xAxisDevice, DeviceButtonId xAxis,
DeviceId yAxisDevice, DeviceButtonId yAxis,
DeviceId down2Device, DeviceButtonId downButton2,
DeviceId xAxis2Device, DeviceButtonId xAxis2,
DeviceId yAxis2Device, DeviceButtonId yAxis2);
bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == RotateTriggered || deviceButton == RotateAngle; }
ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return deviceButton == RotateTriggered ? BT_BOOL : BT_FLOAT; }
protected:
void InternalUpdate(InputDeltaState* delta);
private:
DeviceButtonSpec downButton_;
DeviceButtonSpec xAxis_;
DeviceButtonSpec yAxis_;
DeviceButtonSpec downButton2_;
DeviceButtonSpec xAxis2_;
DeviceButtonSpec yAxis2_;
bool rotating_;
float initialAngle_;
};
}
#endif
#endif

View File

@@ -0,0 +1,66 @@
#ifndef GAINPUTSIMULTANEOUSLYDOWNGESTURE_H_
#define GAINPUTSIMULTANEOUSLYDOWNGESTURE_H_
#ifdef GAINPUT_ENABLE_SIMULTANEOUSLY_DOWN_GESTURE
namespace gainput
{
/// Buttons provided by the SimultaneouslyDownGesture.
enum SimultaneouslyDownAction
{
SimultaneouslyDownTriggered ///< The button triggered by double-clicking.
};
/// A gesture that tracks if a number of buttons is down simultaneously.
/**
* This gesture can be used to detect if multiple buttons are down at the same time. Its only
* device button ::SimultaneouslyDownTriggered is true while all buttons provided through AddButton()
* are down.
*
* After instantiating the gesture like any other input device, call AddButton() as often as necessary
* to properly set it up.
*
* In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or
* \c GAINPUT_ENABLE_SIMULTANEOUSLY_DOWN_GESTURE defined.
*
* \sa AddButton
* \sa InputManager::CreateDevice
*/
class GAINPUT_LIBEXPORT SimultaneouslyDownGesture : public InputGesture
{
public:
/// Initializes the gesture.
SimultaneouslyDownGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant);
/// Uninitializes the gesture.
~SimultaneouslyDownGesture();
/// Adds the given button as a button to check.
/**
* \param device ID of the input device containing the button to be checked.
* \param button ID of the device button to be checked.
*/
void AddButton(DeviceId device, DeviceButtonId button);
/// Removes all buttons previously registered through AddButton().
void ClearButtons();
bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == SimultaneouslyDownTriggered; }
ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_UNUSED(deviceButton); GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return BT_BOOL; }
protected:
void InternalUpdate(InputDeltaState* delta);
private:
Array<DeviceButtonSpec> buttons_;
};
}
#endif
#endif

View File

@@ -0,0 +1,66 @@
#ifndef GAINPUTTAPGESTURE_H_
#define GAINPUTTAPGESTURE_H_
#ifdef GAINPUT_ENABLE_TAP_GESTURE
namespace gainput
{
/// Buttons provided by the TapGesture.
enum TapAction
{
TapTriggered ///< The button that is triggered by tapping.
};
/// A tap-to-trigger gesture.
/**
* This gesture, mainly meant for touch devices, triggers after the specified button has been down and released
* during the specified time frame. If the button is down for a longer time, no action is triggered.
*
* After instantiating the gesture like any other input device, call Initialize() to properly
* set it up.
*
* In order for this gesture to be available, Gainput must be built with \c GAINPUT_ENABLE_ALL_GESTURES or
* \c GAINPUT_ENABLE_TAP_GESTURE defined.
*
* \sa Initialize
* \sa InputManager::CreateDevice
*/
class GAINPUT_LIBEXPORT TapGesture : public InputGesture
{
public:
/// Initializes the gesture.
TapGesture(InputManager& manager, DeviceId device, unsigned index, DeviceVariant variant);
/// Uninitializes the gesture.
~TapGesture();
/// Sets up the gesture.
/**
* \param actionButtonDevice ID of the input device containing the action button.
* \param actionButton ID of the device button to be used as the action button.
* \param timeSpan Time in milliseconds the user may hold at most.
*/
void Initialize(DeviceId actionButtonDevice, DeviceButtonId actionButton, uint64_t timeSpan = 500);
bool IsValidButtonId(DeviceButtonId deviceButton) const { return deviceButton == TapTriggered; }
ButtonType GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_UNUSED(deviceButton); GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return BT_BOOL; }
protected:
void InternalUpdate(InputDeltaState* delta);
private:
DeviceButtonSpec actionButton_;
uint64_t timeSpan_;
uint64_t firstDownTime_;
};
}
#endif
#endif