InputDeviceTouch::InputDeviceTouch(InputManager& manager, DeviceId device, unsigned index, DeviceVariant /*variant*/) : InputDevice(manager, device, index == InputDevice::AutoIndex ? manager.GetDeviceCountByType(DT_TOUCH) : 0), impl_(0) { state_ = manager.GetAllocator().New<InputState>(manager.GetAllocator(), TouchPointCount*TouchDataElems); GAINPUT_ASSERT(state_); previousState_ = manager.GetAllocator().New<InputState>(manager.GetAllocator(), TouchPointCount*TouchDataElems); GAINPUT_ASSERT(previousState_); #if defined(GAINPUT_PLATFORM_ANDROID) if (variant != DV_NULL) { impl_ = manager.GetAllocator().New<InputDeviceTouchImplAndroid>(manager, *this, *state_, *previousState_); } #elif defined(GAINPUT_PLATFORM_IOS) if (variant != DV_NULL) { impl_ = manager.GetAllocator().New<InputDeviceTouchImplIos>(manager, *this, *state_, *previousState_); } #endif if (!impl_) { impl_ = manager.GetAllocator().New<InputDeviceTouchImplNull>(manager, *this); } GAINPUT_ASSERT(impl_); }
size_t InputDeviceTouch::GetAnyButtonDown(DeviceButtonSpec* outButtons, size_t maxButtonCount) const { GAINPUT_ASSERT(outButtons); GAINPUT_ASSERT(maxButtonCount > 0); return CheckAllButtonsDown(outButtons, maxButtonCount, Touch0Down, TouchCount_); }
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_); }
size_t InputDeviceTouch::GetButtonName(DeviceButtonId deviceButton, char* buffer, size_t bufferLength) const { GAINPUT_ASSERT(IsValidButtonId(deviceButton)); GAINPUT_ASSERT(buffer); GAINPUT_ASSERT(bufferLength > 0); strncpy(buffer, deviceButtonInfos[deviceButton].name, bufferLength); buffer[bufferLength-1] = 0; const size_t nameLen = strlen(deviceButtonInfos[deviceButton].name); return nameLen >= bufferLength ? bufferLength : nameLen+1; }
TapGesture::TapGesture(InputManager& manager, DeviceId device, DeviceVariant variant) : InputGesture(manager, device), firstDownTime_(0) { actionButton_.buttonId = InvalidDeviceButtonId; state_ = manager_.GetAllocator().New<InputState>(manager.GetAllocator(), 1); GAINPUT_ASSERT(state_); previousState_ = manager_.GetAllocator().New<InputState>(manager.GetAllocator(), 1); GAINPUT_ASSERT(previousState_); }
void TapGesture::InternalUpdate(InputDeltaState* delta) { if (actionButton_.buttonId == InvalidDeviceButtonId) { return; } const InputDevice* actionDevice = manager_.GetDevice(actionButton_.deviceId); GAINPUT_ASSERT(actionDevice); HandleButton(deviceId_, *state_, *previousState_, delta, TapTriggered, false); if (actionDevice->GetBool(actionButton_.buttonId)) { if (firstDownTime_ == 0) { firstDownTime_ = manager_.GetTime(); } } else { if (firstDownTime_ > 0 && firstDownTime_ + timeSpan_ >= manager_.GetTime()) { HandleButton(deviceId_, *state_, *previousState_, delta, TapTriggered, true); } firstDownTime_ = 0; } }
float InputDevice::GetDeadZone(DeviceButtonId buttonId) const { if (!deadZones_ || !IsValidButtonId(buttonId)) { return 0.0f; } GAINPUT_ASSERT(buttonId < state_->GetButtonCount()); return deadZones_[buttonId]; }
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_)); }
DeviceButtonId InputDeviceTouch::GetButtonByName(const char* name) const { GAINPUT_ASSERT(name); for (unsigned i = 0; i < TouchPointCount*TouchDataElems; ++i) { if (strcmp(name, deviceButtonInfos[i].name) == 0) { return DeviceButtonId(i); } } return InvalidDeviceButtonId; }
void InputRecorder::Start() { isRecording_ = true; if (recording_) { recording_->Clear(); } else { recording_ = manager_.GetAllocator().New<InputRecording>(manager_.GetAllocator()); } startTime_ = manager_.GetTime(); recordingListener_ = manager_.GetAllocator().New<RecordingListener>(manager_, *this); recordingListenerId_ = manager_.AddListener(recordingListener_); // Record the initial state for (InputManager::iterator it = manager_.begin(); it != manager_.end(); ++it) { InputDevice* device = it->second; const DeviceId deviceId = device->GetDeviceId(); if (!IsDeviceToRecord(deviceId)) { continue; } GAINPUT_ASSERT(device->GetInputState()); for (DeviceButtonId buttonId = 0; buttonId < device->GetInputState()->GetButtonCount(); ++buttonId) { if (device->IsValidButtonId(buttonId)) { if (device->GetButtonType(buttonId) == BT_BOOL) { recording_->AddChange(0, deviceId, buttonId, device->GetBool(buttonId)); } else { recording_->AddChange(0, deviceId, buttonId, device->GetFloat(buttonId)); } } } } }
void InputDevice::SetDeadZone(DeviceButtonId buttonId, float value) { if (!IsValidButtonId(buttonId)) { return; } if (!deadZones_) { const size_t size = sizeof(float) * state_->GetButtonCount(); deadZones_ = reinterpret_cast<float*>(manager_.GetAllocator().Allocate(size)); memset(deadZones_, 0, size); } GAINPUT_ASSERT(buttonId < state_->GetButtonCount()); deadZones_[buttonId] = value; }
ButtonType InputDeviceTouch::GetButtonType(DeviceButtonId deviceButton) const { GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return deviceButtonInfos[deviceButton].type; }
gainput::ButtonType GetButtonType(gainput::DeviceButtonId deviceButton) const { GAINPUT_ASSERT(IsValidButtonId(deviceButton)); return (deviceButton == gainput::Touch0Down || deviceButton == gainput::Touch1Down) ? gainput::BT_BOOL : gainput::BT_FLOAT; }
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(); }