input_common: touch: Rewrite touch driver to support multiple touch points
This commit is contained in:
parent
4eb7f6c044
commit
c82806f9cb
8 changed files with 140 additions and 92 deletions
|
@ -14,38 +14,93 @@ constexpr PadIdentifier identifier = {
|
|||
|
||||
TouchScreen::TouchScreen(std::string input_engine_) : InputEngine(std::move(input_engine_)) {
|
||||
PreSetController(identifier);
|
||||
ReleaseAllTouch();
|
||||
}
|
||||
|
||||
void TouchScreen::TouchMoved(float x, float y, std::size_t finger) {
|
||||
if (finger >= 16) {
|
||||
void TouchScreen::TouchMoved(float x, float y, std::size_t finger_id) {
|
||||
const auto index = GetIndexFromFingerId(finger_id);
|
||||
if (!index) {
|
||||
// Touch doesn't exist handle it as a new one
|
||||
TouchPressed(x, y, finger_id);
|
||||
return;
|
||||
}
|
||||
TouchPressed(x, y, finger);
|
||||
const auto i = index.value();
|
||||
fingers[i].is_active = true;
|
||||
SetButton(identifier, static_cast<int>(i), true);
|
||||
SetAxis(identifier, static_cast<int>(i * 2), x);
|
||||
SetAxis(identifier, static_cast<int>(i * 2 + 1), y);
|
||||
}
|
||||
|
||||
void TouchScreen::TouchPressed(float x, float y, std::size_t finger) {
|
||||
if (finger >= 16) {
|
||||
void TouchScreen::TouchPressed(float x, float y, std::size_t finger_id) {
|
||||
if (GetIndexFromFingerId(finger_id)) {
|
||||
// Touch already exist. Just update the data
|
||||
TouchMoved(x, y, finger_id);
|
||||
return;
|
||||
}
|
||||
SetButton(identifier, static_cast<int>(finger), true);
|
||||
SetAxis(identifier, static_cast<int>(finger * 2), x);
|
||||
SetAxis(identifier, static_cast<int>(finger * 2 + 1), y);
|
||||
const auto index = GetNextFreeIndex();
|
||||
if (!index) {
|
||||
// No free entries. Ignore input
|
||||
return;
|
||||
}
|
||||
const auto i = index.value();
|
||||
fingers[i].is_enabled = true;
|
||||
fingers[i].finger_id = finger_id;
|
||||
TouchMoved(x, y, finger_id);
|
||||
}
|
||||
|
||||
void TouchScreen::TouchReleased(std::size_t finger) {
|
||||
if (finger >= 16) {
|
||||
void TouchScreen::TouchReleased(std::size_t finger_id) {
|
||||
const auto index = GetIndexFromFingerId(finger_id);
|
||||
if (!index) {
|
||||
return;
|
||||
}
|
||||
SetButton(identifier, static_cast<int>(finger), false);
|
||||
SetAxis(identifier, static_cast<int>(finger * 2), 0.0f);
|
||||
SetAxis(identifier, static_cast<int>(finger * 2 + 1), 0.0f);
|
||||
const auto i = index.value();
|
||||
fingers[i].is_enabled = false;
|
||||
SetButton(identifier, static_cast<int>(i), false);
|
||||
SetAxis(identifier, static_cast<int>(i * 2), 0.0f);
|
||||
SetAxis(identifier, static_cast<int>(i * 2 + 1), 0.0f);
|
||||
}
|
||||
|
||||
std::optional<std::size_t> TouchScreen::GetIndexFromFingerId(std::size_t finger_id) const {
|
||||
for (std::size_t index = 0; index < MAX_FINGER_COUNT; ++index) {
|
||||
const auto& finger = fingers[index];
|
||||
if (!finger.is_enabled) {
|
||||
continue;
|
||||
}
|
||||
if (finger.finger_id == finger_id) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::size_t> TouchScreen::GetNextFreeIndex() const {
|
||||
for (std::size_t index = 0; index < MAX_FINGER_COUNT; ++index) {
|
||||
if (!fingers[index].is_enabled) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void TouchScreen::ClearActiveFlag() {
|
||||
for (auto& finger : fingers) {
|
||||
finger.is_active = false;
|
||||
}
|
||||
}
|
||||
|
||||
void TouchScreen::ReleaseInactiveTouch() {
|
||||
for (const auto& finger : fingers) {
|
||||
if (!finger.is_active) {
|
||||
TouchReleased(finger.finger_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TouchScreen::ReleaseAllTouch() {
|
||||
for (int index = 0; index < 16; ++index) {
|
||||
SetButton(identifier, index, false);
|
||||
SetAxis(identifier, index * 2, 0.0f);
|
||||
SetAxis(identifier, index * 2 + 1, 0.0f);
|
||||
for (const auto& finger : fingers) {
|
||||
if (finger.is_enabled) {
|
||||
TouchReleased(finger.finger_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,41 +3,65 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "input_common/input_engine.h"
|
||||
|
||||
namespace InputCommon {
|
||||
|
||||
/**
|
||||
* A button device factory representing a keyboard. It receives keyboard events and forward them
|
||||
* to all button devices it created.
|
||||
* A touch device factory representing a touch screen. It receives touch events and forward them
|
||||
* to all touch devices it created.
|
||||
*/
|
||||
class TouchScreen final : public InputEngine {
|
||||
public:
|
||||
explicit TouchScreen(std::string input_engine_);
|
||||
|
||||
/**
|
||||
* Signals that mouse has moved.
|
||||
* @param x the x-coordinate of the cursor
|
||||
* @param y the y-coordinate of the cursor
|
||||
* @param center_x the x-coordinate of the middle of the screen
|
||||
* @param center_y the y-coordinate of the middle of the screen
|
||||
* Signals that touch has moved and marks this touch point as active
|
||||
* @param x new horizontal position
|
||||
* @param y new vertical position
|
||||
* @param finger_id of the touch point to be updated
|
||||
*/
|
||||
void TouchMoved(float x, float y, std::size_t finger);
|
||||
void TouchMoved(float x, float y, std::size_t finger_id);
|
||||
|
||||
/**
|
||||
* Sets the status of all buttons bound with the key to pressed
|
||||
* @param key_code the code of the key to press
|
||||
* Signals and creates a new touch point with this finger id
|
||||
* @param x starting horizontal position
|
||||
* @param y starting vertical position
|
||||
* @param finger_id to be assigned to the new touch point
|
||||
*/
|
||||
void TouchPressed(float x, float y, std::size_t finger);
|
||||
void TouchPressed(float x, float y, std::size_t finger_id);
|
||||
|
||||
/**
|
||||
* Sets the status of all buttons bound with the key to released
|
||||
* @param key_code the code of the key to release
|
||||
* Signals and resets the touch point related to the this finger id
|
||||
* @param finger_id to be released
|
||||
*/
|
||||
void TouchReleased(std::size_t finger);
|
||||
void TouchReleased(std::size_t finger_id);
|
||||
|
||||
/// Resets the active flag for each touch point
|
||||
void ClearActiveFlag();
|
||||
|
||||
/// Releases all touch that haven't been marked as active
|
||||
void ReleaseInactiveTouch();
|
||||
|
||||
/// Resets all inputs to their initial value
|
||||
void ReleaseAllTouch();
|
||||
|
||||
private:
|
||||
static constexpr std::size_t MAX_FINGER_COUNT = 16;
|
||||
|
||||
struct TouchStatus {
|
||||
std::size_t finger_id{};
|
||||
bool is_enabled{};
|
||||
bool is_active{};
|
||||
};
|
||||
|
||||
std::optional<std::size_t> GetIndexFromFingerId(std::size_t finger_id) const;
|
||||
|
||||
std::optional<std::size_t> GetNextFreeIndex() const;
|
||||
|
||||
std::array<TouchStatus, MAX_FINGER_COUNT> fingers{};
|
||||
};
|
||||
|
||||
} // namespace InputCommon
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue