Freetext Input with CardKB Take 1 - Also removes FacesKB support, this thing is ancient.

This commit is contained in:
Thomas Göttgens 2022-09-20 13:50:18 +02:00
parent 140250ef03
commit ab342ce904
12 changed files with 83 additions and 65 deletions

View File

@ -104,9 +104,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// The m5stack I2C Keyboard (also RAK14004)
#define CARDKB_ADDR 0x5F
// The older M5 Faces I2C Keyboard
#define FACESKB_ADDR 0x88
// -----------------------------------------------------------------------------
// SENSOR
// -----------------------------------------------------------------------------

View File

@ -107,10 +107,6 @@ void scanI2Cdevice(void)
kb_model = 0x00;
}
}
if (addr == FACESKB_ADDR) {
faceskb_found = addr;
DEBUG_MSG("m5 Faces found\n");
}
if (addr == ST7567_ADDRESS) {
screen_found = addr;
DEBUG_MSG("st7567 display found\n");

View File

@ -1,9 +1,12 @@
#pragma once
#include "Observer.h"
#define ANYKEY 0xFF
typedef struct _InputEvent {
const char* source;
char inputEvent;
char kbchar;
} InputEvent;
class InputBroker :
public Observable<const InputEvent *>

View File

@ -16,6 +16,5 @@ void CardKbI2cImpl::init()
return;
}
DEBUG_MSG("registerSource\n");
inputBroker->registerSource(this);
}

View File

@ -1,20 +0,0 @@
#include "facesKbI2cImpl.h"
#include "InputBroker.h"
FacesKbI2cImpl *facesKbI2cImpl;
FacesKbI2cImpl::FacesKbI2cImpl() :
KbI2cBase("facesKB")
{
}
void FacesKbI2cImpl::init()
{
if (faceskb_found != FACESKB_ADDR)
{
// Input device is not detected.
return;
}
inputBroker->registerSource(this);
}

View File

@ -1,20 +0,0 @@
#pragma once
#include "kbI2cBase.h"
#include "main.h"
/**
* @brief The idea behind this class to have static methods for the event handlers.
* Check attachInterrupt() at RotaryEncoderInteruptBase.cpp
* Technically you can have as many rotary encoders hardver attached
* to your device as you wish, but you always need to have separate event
* handlers, thus you need to have a RotaryEncoderInterrupt implementation.
*/
class FacesKbI2cImpl :
public KbI2cBase
{
public:
FacesKbI2cImpl();
void init();
};
extern FacesKbI2cImpl *facesKbI2cImpl;

View File

@ -3,7 +3,6 @@
#include <Wire.h>
extern uint8_t cardkb_found;
extern uint8_t faceskb_found;
KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
{
@ -12,7 +11,7 @@ KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
int32_t KbI2cBase::runOnce()
{
if ((cardkb_found != CARDKB_ADDR) && (faceskb_found != CARDKB_ADDR)){
if (cardkb_found != CARDKB_ADDR){
// Input device is not detected.
return INT32_MAX;
}
@ -30,6 +29,7 @@ int32_t KbI2cBase::runOnce()
break;
case 0x08: // Back
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_BACK;
e.kbchar = c;
break;
case 0xb5: // Up
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_UP;
@ -39,13 +39,22 @@ int32_t KbI2cBase::runOnce()
break;
case 0xb4: // Left
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_LEFT;
e.kbchar = c;
break;
case 0xb7: // Right
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT;
e.kbchar = c;
break;
case 0x0d: // Enter
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_SELECT;
break;
case 0x00: //nopress
e.inputEvent = ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
break;
default: // all other keys
e.inputEvent = ANYKEY;
e.kbchar = c;
break;
}
}

View File

@ -74,9 +74,6 @@ uint8_t cardkb_found;
// 0x02 for RAK14004 and 0x00 for cardkb
uint8_t kb_model;
// The I2C address of the Faces Keyboard (if found)
uint8_t faceskb_found;
// The I2C address of the RTC Module (if found)
uint8_t rtc_found;

View File

@ -11,7 +11,6 @@ extern uint8_t screen_found;
extern uint8_t screen_model;
extern uint8_t cardkb_found;
extern uint8_t kb_model;
extern uint8_t faceskb_found;
extern uint8_t rtc_found;
extern bool eink_found;

View File

@ -116,10 +116,40 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
powerFSM.trigger(EVENT_PRESS);
} else {
this->payload = this->runState;
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
validEvent = true;
}
}
if (event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL)) {
DEBUG_MSG("Canned message event Cancel\n");
// emulate a timeout. Same result
this->lastTouchMillis = 0;
validEvent = true;
}
if ((event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) ||
(event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
(event->inputEvent == static_cast<char>(ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
DEBUG_MSG("Canned message event (back/left/right)\n");
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
// pass the pressed key
this->payload = event->kbchar;
this->lastTouchMillis = millis();
validEvent = true;
}
}
if (event->inputEvent == static_cast<char>(ANYKEY)) {
DEBUG_MSG("Canned message event any key pressed\n");
// when inactive, this will switch to the freetext mode
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
}
// pass the pressed key
this->payload = event->kbchar;
this->lastTouchMillis = millis();
validEvent = true;
}
if (validEvent) {
// Let runOnce to be called immediately.
@ -160,25 +190,32 @@ int32_t CannedMessageModule::runOnce()
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
e.frameChanged = true;
this->currentMessageIndex = -1;
this->freetext = ""; // clear freetext
this->notifyObservers(&e);
} else if ((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) && (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS) {
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS) {
// Reset module
DEBUG_MSG("Reset due the lack of activity.\n");
e.frameChanged = true;
this->currentMessageIndex = -1;
this->freetext = ""; // clear freetext
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
this->notifyObservers(&e);
} else if (this->currentMessageIndex == -1) {
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
if (this->payload == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
sendText(NODENUM_BROADCAST, this->freetext.c_str(), true);
} else {
sendText(NODENUM_BROADCAST, this->messages[this->currentMessageIndex], true);
}
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
this->currentMessageIndex = -1;
this->freetext = ""; // clear freetext
this->notifyObservers(&e);
return 2000;
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
this->currentMessageIndex = 0;
DEBUG_MSG("First touch (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
e.frameChanged = true;
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
sendText(NODENUM_BROADCAST, this->messages[this->currentMessageIndex], true);
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
this->currentMessageIndex = -1;
this->notifyObservers(&e);
return 2000;
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP) {
this->currentMessageIndex = getPrevIndex();
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
@ -187,6 +224,22 @@ int32_t CannedMessageModule::runOnce()
this->currentMessageIndex = this->getNextIndex();
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
DEBUG_MSG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
e.frameChanged = true;
switch (this->payload) {
case 8: // backspace
if (this->freetext.length() > 0) {
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
}
break;
default:
this->freetext += this->payload;
break;
}
this->lastTouchMillis = millis();
this->notifyObservers(&e);
return INACTIVATE_AFTER_MS;
}
if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) {
@ -248,6 +301,11 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);
display->drawString(10 + x, 0 + y + 16, "Canned Message\nModule disabled.");
}else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_MEDIUM);
display->drawString(0 + x, 0 + y, "To: Broadcast");
display->drawString(0 + x, 0 + y + 16, this->freetext);
} else {
display->setTextAlignment(TEXT_ALIGN_LEFT);
display->setFont(FONT_SMALL);

View File

@ -8,6 +8,7 @@ enum cannedMessageModuleRunState
CANNED_MESSAGE_RUN_STATE_DISABLED,
CANNED_MESSAGE_RUN_STATE_INACTIVE,
CANNED_MESSAGE_RUN_STATE_ACTIVE,
CANNED_MESSAGE_RUN_STATE_FREETEXT,
CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE,
CANNED_MESSAGE_RUN_STATE_ACTION_SELECT,
CANNED_MESSAGE_RUN_STATE_ACTION_UP,
@ -70,6 +71,8 @@ class CannedMessageModule :
int currentMessageIndex = -1;
cannedMessageModuleRunState runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
char payload;
String freetext; // Text Buffer for Freetext Editor
char messageStore[CANNED_MESSAGE_MODULE_MESSAGES_SIZE+1];
char *messages[CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT];

View File

@ -3,7 +3,6 @@
#include "input/RotaryEncoderInterruptImpl1.h"
#include "input/UpDownInterruptImpl1.h"
#include "input/cardKbI2cImpl.h"
#include "input/facesKbI2cImpl.h"
#include "modules/AdminModule.h"
#include "modules/CannedMessageModule.h"
#include "modules/NodeInfoModule.h"
@ -53,8 +52,6 @@ void setupModules()
upDownInterruptImpl1->init();
cardKbI2cImpl = new CardKbI2cImpl();
cardKbI2cImpl->init();
facesKbI2cImpl = new FacesKbI2cImpl();
facesKbI2cImpl->init();
#endif
#if HAS_SCREEN
cannedMessageModule = new CannedMessageModule();