From ab342ce904d73aa2f66a0f8fbef615b815d0c998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 20 Sep 2022 13:50:18 +0200 Subject: [PATCH] Freetext Input with CardKB Take 1 - Also removes FacesKB support, this thing is ancient. --- src/configuration.h | 3 -- src/detect/i2cScan.h | 4 -- src/input/InputBroker.h | 3 ++ src/input/cardKbI2cImpl.cpp | 1 - src/input/facesKbI2cImpl.cpp | 20 -------- src/input/facesKbI2cImpl.h | 20 -------- src/input/kbI2cBase.cpp | 13 ++++- src/main.cpp | 3 -- src/main.h | 1 - src/modules/CannedMessageModule.cpp | 74 +++++++++++++++++++++++++---- src/modules/CannedMessageModule.h | 3 ++ src/modules/Modules.cpp | 3 -- 12 files changed, 83 insertions(+), 65 deletions(-) delete mode 100644 src/input/facesKbI2cImpl.cpp delete mode 100644 src/input/facesKbI2cImpl.h diff --git a/src/configuration.h b/src/configuration.h index b42a76940..f7d42afcd 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -104,9 +104,6 @@ along with this program. If not, see . // The m5stack I2C Keyboard (also RAK14004) #define CARDKB_ADDR 0x5F -// The older M5 Faces I2C Keyboard -#define FACESKB_ADDR 0x88 - // ----------------------------------------------------------------------------- // SENSOR // ----------------------------------------------------------------------------- diff --git a/src/detect/i2cScan.h b/src/detect/i2cScan.h index f5f8effc9..3591d307b 100644 --- a/src/detect/i2cScan.h +++ b/src/detect/i2cScan.h @@ -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"); diff --git a/src/input/InputBroker.h b/src/input/InputBroker.h index e75b0c407..5736a8a65 100644 --- a/src/input/InputBroker.h +++ b/src/input/InputBroker.h @@ -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 diff --git a/src/input/cardKbI2cImpl.cpp b/src/input/cardKbI2cImpl.cpp index 1a101aee7..de0fbbd38 100644 --- a/src/input/cardKbI2cImpl.cpp +++ b/src/input/cardKbI2cImpl.cpp @@ -16,6 +16,5 @@ void CardKbI2cImpl::init() return; } - DEBUG_MSG("registerSource\n"); inputBroker->registerSource(this); } diff --git a/src/input/facesKbI2cImpl.cpp b/src/input/facesKbI2cImpl.cpp deleted file mode 100644 index c91350763..000000000 --- a/src/input/facesKbI2cImpl.cpp +++ /dev/null @@ -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); -} diff --git a/src/input/facesKbI2cImpl.h b/src/input/facesKbI2cImpl.h deleted file mode 100644 index edf73bd05..000000000 --- a/src/input/facesKbI2cImpl.h +++ /dev/null @@ -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; \ No newline at end of file diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index e12b52e5b..9ff7d7e10 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -3,7 +3,6 @@ #include 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; } } diff --git a/src/main.cpp b/src/main.cpp index 260e9aec3..c5e6e8b56 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -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; diff --git a/src/main.h b/src/main.h index ed48a83cd..e1142d36c 100644 --- a/src/main.h +++ b/src/main.h @@ -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; diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 54c02f67f..2ffe221dc 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -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(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(ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) || + (event->inputEvent == static_cast(ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) || + (event->inputEvent == static_cast(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(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); diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index 2bd2927e1..e28b67902 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -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]; diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index 7ff90d9ca..91f3f2edd 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -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();