mirror of
https://github.com/meshtastic/firmware.git
synced 2025-12-21 02:02:23 +00:00
T deck: support keyboard, trackball and touchscreen (#2665)
* add hwid for auto-detection * fix: heltec-wireless-tracker USB serial * T-Deck support * trunk fmt * set FRAMERATE to 1 * fix some defines * trunk fmt * corrected vendor link * T-Deck: support keyboard, trackball & touch screen * T-Watch add touchscreen defs, remove getTouch * fix warnings * getTouch uint16 -> int16 * fix touch x,y * fix I2C port * CannedMsgModule: use entire display height * trunk fmt * fix I2C issue for T-Watch * allow dest selection in canned mode * fix: allow dest selection in canned mode * use tft.setBrightness() to poweroff display * Increased t-watch framerate and added back haptic feedback * add da ref * Move to touched * improved sensitivity and accuracy of touch events * use double tap to send canned message * fix warning * trunk fmt * Remove extra hapticFeedback() --------- Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
137
src/input/TouchScreenBase.cpp
Normal file
137
src/input/TouchScreenBase.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#include "TouchScreenBase.h"
|
||||
#include "main.h"
|
||||
|
||||
#ifndef TIME_LONG_PRESS
|
||||
#define TIME_LONG_PRESS 400
|
||||
#endif
|
||||
|
||||
// move a minimum distance over the screen to detect a "swipe"
|
||||
#ifndef TOUCH_THRESHOLD_X
|
||||
#define TOUCH_THRESHOLD_X 30
|
||||
#endif
|
||||
|
||||
#ifndef TOUCH_THRESHOLD_Y
|
||||
#define TOUCH_THRESHOLD_Y 20
|
||||
#endif
|
||||
|
||||
TouchScreenBase::TouchScreenBase(const char *name, uint16_t width, uint16_t height)
|
||||
: concurrency::OSThread(name), _display_width(width), _display_height(height), _first_x(0), _last_x(0), _first_y(0),
|
||||
_last_y(0), _start(0), _tapped(false), _originName(name)
|
||||
{
|
||||
}
|
||||
|
||||
void TouchScreenBase::init(bool hasTouch)
|
||||
{
|
||||
if (hasTouch) {
|
||||
LOG_INFO("TouchScreen initialized %d %d\n", TOUCH_THRESHOLD_X, TOUCH_THRESHOLD_Y);
|
||||
this->setInterval(100);
|
||||
} else {
|
||||
disable();
|
||||
this->setInterval(UINT_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t TouchScreenBase::runOnce()
|
||||
{
|
||||
TouchEvent e;
|
||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_NONE);
|
||||
|
||||
// process touch events
|
||||
int16_t x, y;
|
||||
bool touched = getTouch(x, y);
|
||||
if (touched) {
|
||||
hapticFeedback();
|
||||
this->setInterval(20);
|
||||
_last_x = x;
|
||||
_last_y = y;
|
||||
}
|
||||
if (touched != _touchedOld) {
|
||||
if (touched) {
|
||||
_state = TOUCH_EVENT_OCCURRED;
|
||||
_start = millis();
|
||||
_first_x = x;
|
||||
_first_y = y;
|
||||
} else {
|
||||
_state = TOUCH_EVENT_CLEARED;
|
||||
time_t duration = millis() - _start;
|
||||
x = _last_x;
|
||||
y = _last_y;
|
||||
this->setInterval(50);
|
||||
|
||||
// compute distance
|
||||
int16_t dx = x - _first_x;
|
||||
int16_t dy = y - _first_y;
|
||||
uint16_t adx = abs(dx);
|
||||
uint16_t ady = abs(dy);
|
||||
|
||||
// swipe horizontal
|
||||
if (adx > ady && adx > TOUCH_THRESHOLD_X) {
|
||||
if (0 > dx) { // swipe right to left
|
||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_LEFT);
|
||||
LOG_DEBUG("action SWIPE: right to left\n");
|
||||
} else { // swipe left to right
|
||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_RIGHT);
|
||||
LOG_DEBUG("action SWIPE: left to right\n");
|
||||
}
|
||||
}
|
||||
// swipe vertical
|
||||
else if (ady > adx && ady > TOUCH_THRESHOLD_Y) {
|
||||
if (0 > dy) { // swipe bottom to top
|
||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_UP);
|
||||
LOG_DEBUG("action SWIPE: bottom to top\n");
|
||||
} else { // swipe top to bottom
|
||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOWN);
|
||||
LOG_DEBUG("action SWIPE: top to bottom\n");
|
||||
}
|
||||
}
|
||||
// tap
|
||||
else {
|
||||
if (duration > 0 && duration < TIME_LONG_PRESS) {
|
||||
if (_tapped) {
|
||||
_tapped = false;
|
||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_DOUBLE_TAP);
|
||||
LOG_DEBUG("action DOUBLE TAP(%d/%d)\n", x, y);
|
||||
} else {
|
||||
_tapped = true;
|
||||
}
|
||||
} else {
|
||||
_tapped = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_touchedOld = touched;
|
||||
|
||||
// fire TAP event when no 2nd tap occured within time
|
||||
if (_tapped && (time_t(millis()) - _start) > TIME_LONG_PRESS - 50) {
|
||||
_tapped = false;
|
||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_TAP);
|
||||
LOG_DEBUG("action TAP(%d/%d)\n", _last_x, _last_y);
|
||||
}
|
||||
|
||||
// fire LONG_PRESS event without the need for release
|
||||
if (touched && (time_t(millis()) - _start) > TIME_LONG_PRESS) {
|
||||
// tricky: prevent reoccurring events and another touch event when releasing
|
||||
_start = millis() + 30000;
|
||||
e.touchEvent = static_cast<char>(TOUCH_ACTION_LONG_PRESS);
|
||||
LOG_DEBUG("action LONG PRESS(%d/%d)\n", _last_x, _last_y);
|
||||
}
|
||||
|
||||
if (e.touchEvent != TOUCH_ACTION_NONE) {
|
||||
e.source = this->_originName;
|
||||
e.x = _last_x;
|
||||
e.y = _last_y;
|
||||
onEvent(e);
|
||||
}
|
||||
|
||||
return interval;
|
||||
}
|
||||
|
||||
void TouchScreenBase::hapticFeedback()
|
||||
{
|
||||
#ifdef T_WATCH_S3
|
||||
drv.setWaveform(0, 75);
|
||||
drv.setWaveform(1, 0); // end waveform
|
||||
drv.go();
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user