Skip to content

Commit

Permalink
touchhandler: custom gesture detection
Browse files Browse the repository at this point in the history
  • Loading branch information
KaffeinatedKat committed Feb 4, 2024
1 parent 2135e12 commit 6a8c601
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 38 deletions.
86 changes: 48 additions & 38 deletions src/touchhandler/TouchHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,64 +3,74 @@
using namespace Pinetime::Controllers;
using namespace Pinetime::Applications;

namespace {
TouchEvents ConvertGesture(Pinetime::Drivers::Cst816S::Gestures gesture) {
switch (gesture) {
case Pinetime::Drivers::Cst816S::Gestures::SingleTap:
return TouchEvents::Tap;
case Pinetime::Drivers::Cst816S::Gestures::LongPress:
return TouchEvents::LongTap;
case Pinetime::Drivers::Cst816S::Gestures::DoubleTap:
return TouchEvents::DoubleTap;
case Pinetime::Drivers::Cst816S::Gestures::SlideRight:
return TouchEvents::SwipeRight;
case Pinetime::Drivers::Cst816S::Gestures::SlideLeft:
return TouchEvents::SwipeLeft;
case Pinetime::Drivers::Cst816S::Gestures::SlideDown:
return TouchEvents::SwipeDown;
case Pinetime::Drivers::Cst816S::Gestures::SlideUp:
return TouchEvents::SwipeUp;
case Pinetime::Drivers::Cst816S::Gestures::None:
default:
return TouchEvents::None;
}
}
}

Pinetime::Applications::TouchEvents TouchHandler::GestureGet() {
auto returnGesture = gesture;
gesture = Pinetime::Applications::TouchEvents::None;
return returnGesture;
}

bool TouchHandler::ProcessTouchInfo(Drivers::Cst816S::TouchInfos info) {
bool swiping = false;

if (!info.isValid) {
return false;
}

// Only a single gesture per touch
if (info.gesture != Pinetime::Drivers::Cst816S::Gestures::None) {
if (gestureReleased) {
if (info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideDown ||
info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideLeft ||
info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideUp ||
info.gesture == Pinetime::Drivers::Cst816S::Gestures::SlideRight ||
info.gesture == Pinetime::Drivers::Cst816S::Gestures::LongPress) {
if (info.touching) {
gesture = ConvertGesture(info.gesture);
gestureReleased = false;
}
// Keep the swipe state enabled till we stop touching the screen
if (currentTouchPoint.swiping) {
xSwipeDistance += currentTouchPoint.x - info.x;
ySwipeDistance += currentTouchPoint.y - info.y;
// Prevent the longTapCounter from increasing while swiping
longTapCounter = 0;
swiping = true;
// Enable the swipe state if we were touching last check, and the previous values are different from the current ones
} else if (currentTouchPoint.touching && (currentTouchPoint.x != info.x || currentTouchPoint.y != info.y)) {
swiping = true;
}


if (gestureReleased) {
// Vertical Swipes
if (std::abs(ySwipeDistance) >= minimumSwipeDistance) {
if (std::signbit(ySwipeDistance)) {
gesture = TouchEvents::SwipeDown;
gestureReleased = false;
} else {
gesture = TouchEvents::SwipeUp;
gestureReleased = false;
}
// Horizontal Swipes
} else if (std::abs(xSwipeDistance) >= minimumSwipeDistance) {
if (std::signbit(xSwipeDistance)) {
gesture = TouchEvents::SwipeRight;
gestureReleased = false;
} else {
gesture = ConvertGesture(info.gesture);
gesture = TouchEvents::SwipeLeft;
gestureReleased = false;
}
// Long Tap
} else if (longTapCounter >= longTapHoldTime) {
gesture = TouchEvents::LongTap;
gestureReleased = false;
// Double Tap
} else if (info.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap) {
gesture = TouchEvents::DoubleTap;
// Single Tap
} else if (info.touching) {
gesture = TouchEvents::Tap;
longTapCounter += 1;
}
}

if (!info.touching) {
gestureReleased = true;
swiping = false;
xSwipeDistance = 0;
ySwipeDistance = 0;
longTapCounter = 0;
}

currentTouchPoint = {info.x, info.y, info.touching};
currentTouchPoint = {info.x, info.y, currentTouchPoint.x, currentTouchPoint.y, info.touching, swiping};

return true;
}
12 changes: 12 additions & 0 deletions src/touchhandler/TouchHandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
#include "drivers/Cst816s.h"
#include "displayapp/TouchEvents.h"

#include <cmath>

namespace Pinetime {
namespace Controllers {
class TouchHandler {
public:
struct TouchPoint {
int x;
int y;
int previousX;
int previousY;
bool touching;
bool swiping;
};

bool ProcessTouchInfo(Drivers::Cst816S::TouchInfos info);
Expand All @@ -29,9 +34,16 @@ namespace Pinetime {
Pinetime::Applications::TouchEvents GestureGet();

private:
const uint8_t minimumSwipeDistance = 65;
const uint8_t longTapHoldTime = 50;

Pinetime::Applications::TouchEvents gesture;
TouchPoint currentTouchPoint = {};
bool gestureReleased = true;
// Total distance for a given swipe
int16_t xSwipeDistance = 0;
int16_t ySwipeDistance = 0;
uint16_t longTapCounter = 0;
};
}
}

0 comments on commit 6a8c601

Please sign in to comment.