Files
kaizen/external/gainput/samples/gesture/gesturesample.cpp

295 lines
9.0 KiB
C++

#include <gainput/gainput.h>
#include "../samplefw/SampleFramework.h"
enum Button
{
ButtonConfirm,
ButtonConfirmDouble,
ButtonConfirmExtra,
ButtonHoldGesture,
ButtonTapGesture,
ButtonPinching,
ButtonPinchScale,
ButtonRotating,
ButtonRotateAngle,
};
const unsigned TouchPointCount = 8;
const unsigned TouchDataElems = 4;
class MultiTouchEmulator : public gainput::InputDevice
{
public:
MultiTouchEmulator(gainput::InputManager& manager, gainput::DeviceId device, unsigned index, gainput::InputDevice::DeviceVariant variant) :
gainput::InputDevice(manager, device, index == InputDevice::AutoIndex ? manager.GetDeviceCountByType(DT_CUSTOM) : 0)
{
state_ = manager.GetAllocator().New<gainput::InputState>(manager.GetAllocator(), TouchPointCount*TouchDataElems);
GAINPUT_ASSERT(state_);
previousState_ = manager.GetAllocator().New<gainput::InputState>(manager.GetAllocator(), TouchPointCount*TouchDataElems);
GAINPUT_ASSERT(previousState_);
}
~MultiTouchEmulator()
{
manager_.GetAllocator().Delete(state_);
manager_.GetAllocator().Delete(previousState_);
}
void Initialize(gainput::DeviceId downDevice, gainput::DeviceButtonId downButton,
gainput::DeviceId xAxisDevice, gainput::DeviceButtonId xAxisButton,
gainput::DeviceId yAxisDevice, gainput::DeviceButtonId yAxisButton,
gainput::DeviceId downDevice2, gainput::DeviceButtonId downButton2,
gainput::DeviceId xAxisDevice2, gainput::DeviceButtonId xAxisButton2,
gainput::DeviceId yAxisDevice2, gainput::DeviceButtonId yAxisButton2)
{
isDown_ = false;
downDevice_ = downDevice;
downButton_ = downButton;
xAxisDevice_ = xAxisDevice;
xAxisButton_ = xAxisButton;
yAxisDevice_ = yAxisDevice;
yAxisButton_ = yAxisButton;
downDevice2_ = downDevice2;
downButton2_ = downButton2;
xAxisDevice2_ = xAxisDevice2;
xAxisButton2_ = xAxisButton2;
yAxisDevice2_ = yAxisDevice2;
yAxisButton2_ = yAxisButton2;
}
DeviceType GetType() const { return DT_CUSTOM; }
const char* GetTypeName() const { return "custom"; }
bool IsValidButtonId(gainput::DeviceButtonId deviceButton) const
{
return deviceButton == gainput::Touch0Down
|| deviceButton == gainput::Touch0X
|| deviceButton == gainput::Touch0Y
|| deviceButton == gainput::Touch1Down
|| deviceButton == gainput::Touch1X
|| deviceButton == gainput::Touch1Y;
}
gainput::ButtonType GetButtonType(gainput::DeviceButtonId deviceButton) const
{
GAINPUT_ASSERT(IsValidButtonId(deviceButton));
return (deviceButton == gainput::Touch0Down || deviceButton == gainput::Touch1Down) ? gainput::BT_BOOL : gainput::BT_FLOAT;
}
protected:
void InternalUpdate(gainput::InputDeltaState* delta)
{
const gainput::InputDevice* downDevice = manager_.GetDevice(downDevice_);
GAINPUT_ASSERT(downDevice);
if (!downDevice->GetBool(downButton_) && downDevice->GetBoolPrevious(downButton_))
{
isDown_ = !isDown_;
const gainput::InputDevice* xDevice = manager_.GetDevice(xAxisDevice_);
GAINPUT_ASSERT(xDevice);
x_ = xDevice->GetFloat(xAxisButton_);
const gainput::InputDevice* yDevice = manager_.GetDevice(yAxisDevice_);
GAINPUT_ASSERT(yDevice);
y_ = yDevice->GetFloat(yAxisButton_);
}
state_->Set(gainput::Touch1Down, isDown_);
state_->Set(gainput::Touch1X, x_);
state_->Set(gainput::Touch1Y, y_);
const gainput::InputDevice* downDevice2 = manager_.GetDevice(downDevice2_);
GAINPUT_ASSERT(downDevice2);
const gainput::InputDevice* xDevice2 = manager_.GetDevice(xAxisDevice2_);
GAINPUT_ASSERT(xDevice2);
const gainput::InputDevice* yDevice2 = manager_.GetDevice(yAxisDevice2_);
GAINPUT_ASSERT(yDevice2);
state_->Set(gainput::Touch0Down, downDevice2->GetBool(downButton2_));
state_->Set(gainput::Touch0X, xDevice2->GetFloat(xAxisButton2_));
state_->Set(gainput::Touch0Y, yDevice2->GetFloat(yAxisButton2_));
}
DeviceState InternalGetState() const { return DS_OK; }
private:
bool isDown_;
float x_;
float y_;
gainput::DeviceId downDevice_;
gainput::DeviceButtonId downButton_;
gainput::DeviceId xAxisDevice_;
gainput::DeviceButtonId xAxisButton_;
gainput::DeviceId yAxisDevice_;
gainput::DeviceButtonId yAxisButton_;
gainput::DeviceId downDevice2_;
gainput::DeviceButtonId downButton2_;
gainput::DeviceId xAxisDevice2_;
gainput::DeviceButtonId xAxisButton2_;
gainput::DeviceId yAxisDevice2_;
gainput::DeviceButtonId yAxisButton2_;
};
void SampleMain()
{
SfwOpenWindow("Gainput: Gesture sample");
gainput::TrackingAllocator allocator(gainput::GetDefaultAllocator());
gainput::InputManager manager(true, allocator);
const gainput::DeviceId keyboardId = manager.CreateDevice<gainput::InputDeviceKeyboard>();
const gainput::DeviceId mouseId = manager.CreateDevice<gainput::InputDeviceMouse>();
gainput::InputDeviceTouch* touchDevice = manager.CreateAndGetDevice<gainput::InputDeviceTouch>();
GAINPUT_ASSERT(touchDevice);
gainput::DeviceId touchId = touchDevice->GetDeviceId();
#if defined(GAINPUT_PLATFORM_LINUX) || defined(GAINPUT_PLATFORM_WIN)
manager.SetDisplaySize(SfwGetWidth(), SfwGetHeight());
#endif
SfwSetInputManager(&manager);
gainput::InputMap map(manager, "testmap", allocator);
map.MapBool(ButtonConfirm, mouseId, gainput::MouseButtonLeft);
gainput::DoubleClickGesture* dcg = manager.CreateAndGetDevice<gainput::DoubleClickGesture>();
GAINPUT_ASSERT(dcg);
dcg->Initialize(mouseId, gainput::MouseButtonLeft,
mouseId, gainput::MouseAxisX, 0.01f,
mouseId, gainput::MouseAxisY, 0.01f,
500);
map.MapBool(ButtonConfirmDouble, dcg->GetDeviceId(), gainput::DoubleClickTriggered);
gainput::SimultaneouslyDownGesture* sdg = manager.CreateAndGetDevice<gainput::SimultaneouslyDownGesture>();
GAINPUT_ASSERT(sdg);
sdg->AddButton(mouseId, gainput::MouseButtonLeft);
sdg->AddButton(keyboardId, gainput::KeyShiftL);
map.MapBool(ButtonConfirmExtra, sdg->GetDeviceId(), gainput::SimultaneouslyDownTriggered);
MultiTouchEmulator* mte = manager.CreateAndGetDevice<MultiTouchEmulator>();
mte->Initialize(sdg->GetDeviceId(), gainput::SimultaneouslyDownTriggered,
mouseId, gainput::MouseAxisX,
mouseId, gainput::MouseAxisY,
mouseId, gainput::MouseButtonLeft,
mouseId, gainput::MouseAxisX,
mouseId, gainput::MouseAxisY);
if (!touchDevice->IsAvailable() || touchDevice->GetVariant() == gainput::InputDevice::DV_NULL)
{
touchId = mte->GetDeviceId();
}
gainput::HoldGesture* hg = manager.CreateAndGetDevice<gainput::HoldGesture>();
GAINPUT_ASSERT(hg);
hg->Initialize(touchId, gainput::Touch0Down,
touchId, gainput::Touch0X, 0.1f,
touchId, gainput::Touch0Y, 0.1f,
true,
800);
map.MapBool(ButtonHoldGesture, hg->GetDeviceId(), gainput::HoldTriggered);
gainput::TapGesture* tg = manager.CreateAndGetDevice<gainput::TapGesture>();
GAINPUT_ASSERT(tg);
tg->Initialize(touchId, gainput::Touch0Down,
500);
map.MapBool(ButtonTapGesture, tg->GetDeviceId(), gainput::TapTriggered);
gainput::PinchGesture* pg = manager.CreateAndGetDevice<gainput::PinchGesture>();
GAINPUT_ASSERT(pg);
pg->Initialize(touchId, gainput::Touch0Down,
touchId, gainput::Touch0X,
touchId, gainput::Touch0Y,
touchId, gainput::Touch1Down,
touchId, gainput::Touch1X,
touchId, gainput::Touch1Y);
map.MapBool(ButtonPinching, pg->GetDeviceId(), gainput::PinchTriggered);
map.MapFloat(ButtonPinchScale, pg->GetDeviceId(), gainput::PinchScale);
gainput::RotateGesture* rg = manager.CreateAndGetDevice<gainput::RotateGesture>();
GAINPUT_ASSERT(rg);
rg->Initialize(touchId, gainput::Touch0Down,
touchId, gainput::Touch0X,
touchId, gainput::Touch0Y,
touchId, gainput::Touch1Down,
touchId, gainput::Touch1X,
touchId, gainput::Touch1Y);
map.MapBool(ButtonRotating, rg->GetDeviceId(), gainput::RotateTriggered);
map.MapFloat(ButtonRotateAngle, rg->GetDeviceId(), gainput::RotateAngle);
bool doExit = false;
while (!SfwIsDone() && !doExit)
{
manager.Update();
#if defined(GAINPUT_PLATFORM_LINUX)
XEvent event;
while (XPending(SfwGetXDisplay()))
{
XNextEvent(SfwGetXDisplay(), &event);
manager.HandleEvent(event);
if (event.type == DestroyNotify || event.type == ClientMessage)
{
doExit = true;
}
}
#elif defined(GAINPUT_PLATFORM_WIN)
MSG msg;
while (PeekMessage(&msg, SfwGetHWnd(), 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
manager.HandleMessage(msg);
}
#endif
SfwUpdate();
if (map.GetBoolWasDown(ButtonConfirm))
{
SFW_LOG("Confirmed!\n");
SFW_LOG("Memory: %u allocs, %u deallocs, %u used bytes\n", static_cast<unsigned>(allocator.GetAllocateCount()), static_cast<unsigned>(allocator.GetDeallocateCount()), static_cast<unsigned>(allocator.GetAllocatedMemory()));
}
if (map.GetBoolWasDown(ButtonConfirmDouble))
{
SFW_LOG("Confirmed doubly!\n");
}
if (map.GetBoolWasDown(ButtonConfirmExtra))
{
SFW_LOG("Confirmed alternatively!\n");
}
if (map.GetBool(ButtonHoldGesture))
{
SFW_LOG("Hold triggered!\n");
}
if (map.GetBoolWasDown(ButtonTapGesture))
{
SFW_LOG("Tapped!\n");
}
if (map.GetBool(ButtonPinching))
{
SFW_LOG("Pinching: %f\n", map.GetFloat(ButtonPinchScale));
}
if (map.GetBool(ButtonRotating))
{
SFW_LOG("Rotation angle: %f\n", map.GetFloat(ButtonRotateAngle));
}
}
SfwCloseWindow();
}