|
|
|
@@ -2,6 +2,7 @@
|
|
|
|
|
#if HAS_SCREEN
|
|
|
|
|
#include "CannedMessageModule.h"
|
|
|
|
|
#include "FSCommon.h"
|
|
|
|
|
#include "NodeDB.h"
|
|
|
|
|
#include "MeshService.h"
|
|
|
|
|
#include "PowerFSM.h" // neede for button bypass
|
|
|
|
|
#include "mesh/generated/cannedmessages.pb.h"
|
|
|
|
@@ -222,6 +223,7 @@ int32_t CannedMessageModule::runOnce()
|
|
|
|
|
this->currentMessageIndex = -1;
|
|
|
|
|
this->freetext = ""; // clear freetext
|
|
|
|
|
this->cursor = 0;
|
|
|
|
|
this->destSelect = false;
|
|
|
|
|
this->notifyObservers(&e);
|
|
|
|
|
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) && (millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS) {
|
|
|
|
|
// Reset module
|
|
|
|
@@ -230,17 +232,17 @@ int32_t CannedMessageModule::runOnce()
|
|
|
|
|
this->currentMessageIndex = -1;
|
|
|
|
|
this->freetext = ""; // clear freetext
|
|
|
|
|
this->cursor = 0;
|
|
|
|
|
this->destSelect = false;
|
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
|
|
|
|
this->notifyObservers(&e);
|
|
|
|
|
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
|
|
|
|
if (this->payload == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
|
|
|
|
if (this->freetext.length() > 0) {
|
|
|
|
|
sendText(NODENUM_BROADCAST, this->freetext.c_str(), true);
|
|
|
|
|
sendText(this->dest, this->freetext.c_str(), true);
|
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
|
|
|
|
} else {
|
|
|
|
|
DEBUG_MSG("Reset message is empty.\n");
|
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
|
|
|
|
e.frameChanged = true;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if ((this->messagesCount > this->currentMessageIndex) && (strlen(this->messages[this->currentMessageIndex]) > 0)) {
|
|
|
|
@@ -249,12 +251,13 @@ int32_t CannedMessageModule::runOnce()
|
|
|
|
|
} else {
|
|
|
|
|
DEBUG_MSG("Reset message is empty.\n");
|
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
|
|
|
|
e.frameChanged = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
e.frameChanged = true;
|
|
|
|
|
this->currentMessageIndex = -1;
|
|
|
|
|
this->freetext = ""; // clear freetext
|
|
|
|
|
this->cursor = 0;
|
|
|
|
|
this->destSelect = false;
|
|
|
|
|
this->notifyObservers(&e);
|
|
|
|
|
return 2000;
|
|
|
|
|
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
|
|
|
|
@@ -266,28 +269,70 @@ int32_t CannedMessageModule::runOnce()
|
|
|
|
|
this->currentMessageIndex = getPrevIndex();
|
|
|
|
|
this->freetext = ""; // clear freetext
|
|
|
|
|
this->cursor = 0;
|
|
|
|
|
this->destSelect = false;
|
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
|
|
|
|
DEBUG_MSG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
|
|
|
|
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_DOWN) {
|
|
|
|
|
this->currentMessageIndex = this->getNextIndex();
|
|
|
|
|
this->freetext = ""; // clear freetext
|
|
|
|
|
this->cursor = 0;
|
|
|
|
|
this->destSelect = false;
|
|
|
|
|
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 0xb4: // left
|
|
|
|
|
if (this->cursor > 0) {
|
|
|
|
|
this->cursor--;
|
|
|
|
|
if (this->destSelect){
|
|
|
|
|
size_t numNodes = nodeDB.getNumNodes();
|
|
|
|
|
if(this->dest == NODENUM_BROADCAST) {
|
|
|
|
|
this->dest = nodeDB.getNodeNum();
|
|
|
|
|
DEBUG_MSG("Replacing NodeNum_BROADCAST with %x\n",nodeDB.getNodeNum());
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < numNodes; i++) {
|
|
|
|
|
DEBUG_MSG("Considering %x\n",nodeDB.getNodeByIndex(i)->num);
|
|
|
|
|
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
|
|
|
|
|
DEBUG_MSG("Match - advance %i-\n",i);
|
|
|
|
|
this->dest = (i > 0) ? nodeDB.getNodeByIndex(i-1)->num : nodeDB.getNodeByIndex(numNodes-1)->num;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(this->dest == nodeDB.getNodeNum()) {
|
|
|
|
|
this->dest = NODENUM_BROADCAST;
|
|
|
|
|
DEBUG_MSG("Replacing %x with NodeNum_BROADCAST\n",nodeDB.getNodeNum());
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
if (this->cursor > 0) {
|
|
|
|
|
this->cursor--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0xb7: // right
|
|
|
|
|
if (this->cursor < this->freetext.length()) {
|
|
|
|
|
this->cursor++;
|
|
|
|
|
if (this->destSelect){
|
|
|
|
|
size_t numNodes = nodeDB.getNumNodes();
|
|
|
|
|
if(this->dest == NODENUM_BROADCAST) {
|
|
|
|
|
this->dest = nodeDB.getNodeNum();
|
|
|
|
|
DEBUG_MSG("Replacing NodeNum_BROADCAST with %x\n",nodeDB.getNodeNum());
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < numNodes; i++) {
|
|
|
|
|
DEBUG_MSG("Considering %x\n",nodeDB.getNodeByIndex(i)->num);
|
|
|
|
|
if (nodeDB.getNodeByIndex(i)->num == this->dest) {
|
|
|
|
|
DEBUG_MSG("Match - advance %i+\n",i);
|
|
|
|
|
this->dest = (i < numNodes-1) ? nodeDB.getNodeByIndex(i+1)->num : nodeDB.getNodeByIndex(0)->num;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if(this->dest == nodeDB.getNodeNum()) {
|
|
|
|
|
this->dest = NODENUM_BROADCAST;
|
|
|
|
|
DEBUG_MSG("Replacing %x with NodeNum_BROADCAST\n",nodeDB.getNodeNum());
|
|
|
|
|
}
|
|
|
|
|
}else{
|
|
|
|
|
if (this->cursor < this->freetext.length()) {
|
|
|
|
|
this->cursor++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 8: // backspace
|
|
|
|
|
case 0x08: // backspace
|
|
|
|
|
if (this->freetext.length() > 0) {
|
|
|
|
|
if(this->cursor == this->freetext.length()) {
|
|
|
|
|
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
|
|
|
|
@@ -297,6 +342,13 @@ int32_t CannedMessageModule::runOnce()
|
|
|
|
|
this->cursor--;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 0x09: // tab
|
|
|
|
|
if(this->destSelect) {
|
|
|
|
|
this->destSelect = false;
|
|
|
|
|
} else {
|
|
|
|
|
this->destSelect = true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
if(this->cursor == this->freetext.length()) {
|
|
|
|
|
this->freetext += this->payload;
|
|
|
|
@@ -339,6 +391,19 @@ const char *CannedMessageModule::getNextMessage()
|
|
|
|
|
{
|
|
|
|
|
return this->messages[this->getNextIndex()];
|
|
|
|
|
}
|
|
|
|
|
const char* CannedMessageModule::getNodeName(NodeNum node) {
|
|
|
|
|
if (node == NODENUM_BROADCAST){
|
|
|
|
|
return "Broadcast";
|
|
|
|
|
}else{
|
|
|
|
|
NodeInfo *info = nodeDB.getNode(node);
|
|
|
|
|
if(info != NULL) {
|
|
|
|
|
return info->user.long_name;
|
|
|
|
|
}else{
|
|
|
|
|
return "Unknown";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CannedMessageModule::shouldDraw()
|
|
|
|
|
{
|
|
|
|
|
if (!moduleConfig.canned_message.enabled) {
|
|
|
|
@@ -379,13 +444,18 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|
|
|
|
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "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->setFont(FONT_SMALL);
|
|
|
|
|
if (this->destSelect) {
|
|
|
|
|
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
|
|
|
|
display->setColor(BLACK);
|
|
|
|
|
}
|
|
|
|
|
char buffer[50];
|
|
|
|
|
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
|
|
|
|
|
// used chars right aligned
|
|
|
|
|
char buffer[9];
|
|
|
|
|
sprintf(buffer, "%d left", Constants_DATA_PAYLOAD_LEN - this->freetext.length());
|
|
|
|
|
display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer);
|
|
|
|
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_MEDIUM, cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
|
|
|
|
|
display->setColor(WHITE);
|
|
|
|
|
display->drawStringMaxWidth(0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(), cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
|
|
|
|
|
} else {
|
|
|
|
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
|
|
|
|
display->setFont(FONT_SMALL);
|
|
|
|
|