From dad05d7873a84abb76b4fb186b146c1e551dbaa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 11 Dec 2023 23:49:33 +0100 Subject: [PATCH] Select Node and channel in Canned Message module. --- src/modules/CannedMessageModule.cpp | 84 ++++++++++++++++++++++------- src/modules/CannedMessageModule.h | 15 ++++-- 2 files changed, 77 insertions(+), 22 deletions(-) diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 419507952..554326057 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -4,6 +4,7 @@ #endif #if HAS_SCREEN #include "CannedMessageModule.h" +#include "Channels.h" #include "FSCommon.h" #include "MeshService.h" #include "NodeDB.h" @@ -187,10 +188,10 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) if (!event->kbchar) { if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) { this->payload = 0xb4; - this->destSelect = true; + this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE; } else if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) { this->payload = 0xb7; - this->destSelect = true; + this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE; } } else { // pass the pressed key @@ -234,10 +235,11 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) return 0; } -void CannedMessageModule::sendText(NodeNum dest, const char *message, bool wantReplies) +void CannedMessageModule::sendText(NodeNum dest, ChannelIndex channel, const char *message, bool wantReplies) { meshtastic_MeshPacket *p = allocDataPacket(); p->to = dest; + p->channel = channel; p->want_ack = true; p->decoded.payload.size = strlen(message); memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size); @@ -270,7 +272,7 @@ int32_t CannedMessageModule::runOnce() this->currentMessageIndex = -1; this->freetext = ""; // clear freetext this->cursor = 0; - this->destSelect = false; + this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; 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)) { @@ -280,13 +282,13 @@ int32_t CannedMessageModule::runOnce() this->currentMessageIndex = -1; this->freetext = ""; // clear freetext this->cursor = 0; - this->destSelect = false; + this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; 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(this->dest, this->freetext.c_str(), true); + sendText(this->dest, indexChannels[this->channel], this->freetext.c_str(), true); this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE; } else { LOG_DEBUG("Reset message is empty.\n"); @@ -298,7 +300,7 @@ int32_t CannedMessageModule::runOnce() powerFSM.trigger(EVENT_PRESS); return INT32_MAX; } else { - sendText(NODENUM_BROADCAST, this->messages[this->currentMessageIndex], true); + sendText(NODENUM_BROADCAST, channels.getPrimaryIndex(), this->messages[this->currentMessageIndex], true); } this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE; } else { @@ -310,7 +312,7 @@ int32_t CannedMessageModule::runOnce() this->currentMessageIndex = -1; this->freetext = ""; // clear freetext this->cursor = 0; - this->destSelect = false; + this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; this->notifyObservers(&e); return 2000; } else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) { @@ -323,7 +325,7 @@ int32_t CannedMessageModule::runOnce() this->currentMessageIndex = getPrevIndex(); this->freetext = ""; // clear freetext this->cursor = 0; - this->destSelect = false; + this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE; LOG_DEBUG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage()); } @@ -332,14 +334,14 @@ int32_t CannedMessageModule::runOnce() this->currentMessageIndex = this->getNextIndex(); this->freetext = ""; // clear freetext this->cursor = 0; - this->destSelect = false; + this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE; LOG_DEBUG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage()); } } else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT || this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) { switch (this->payload) { case 0xb4: // left - if (this->destSelect) { + if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) { size_t numMeshNodes = nodeDB.getNumMeshNodes(); if (this->dest == NODENUM_BROADCAST) { this->dest = nodeDB.getNodeNum(); @@ -354,6 +356,19 @@ int32_t CannedMessageModule::runOnce() if (this->dest == nodeDB.getNodeNum()) { this->dest = NODENUM_BROADCAST; } + } else if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL) { + for (unsigned int i = 0; i < channels.getNumChannels(); i++) { + if ((channels.getByIndex(i).role == meshtastic_Channel_Role_SECONDARY) || + (channels.getByIndex(i).role == meshtastic_Channel_Role_PRIMARY)) { + indexChannels[numChannels] = i; + numChannels++; + } + } + if (this->channel == 0) { + this->channel = numChannels - 1; + } else { + this->channel--; + } } else { if (this->cursor > 0) { this->cursor--; @@ -361,7 +376,7 @@ int32_t CannedMessageModule::runOnce() } break; case 0xb7: // right - if (this->destSelect) { + if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) { size_t numMeshNodes = nodeDB.getNumMeshNodes(); if (this->dest == NODENUM_BROADCAST) { this->dest = nodeDB.getNodeNum(); @@ -376,6 +391,19 @@ int32_t CannedMessageModule::runOnce() if (this->dest == nodeDB.getNodeNum()) { this->dest = NODENUM_BROADCAST; } + } else if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL) { + for (unsigned int i = 0; i < channels.getNumChannels(); i++) { + if ((channels.getByIndex(i).role == meshtastic_Channel_Role_SECONDARY) || + (channels.getByIndex(i).role == meshtastic_Channel_Role_PRIMARY)) { + indexChannels[numChannels] = i; + numChannels++; + } + } + if (this->channel == numChannels - 1) { + this->channel = 0; + } else { + this->channel++; + } } else { if (this->cursor < this->freetext.length()) { this->cursor++; @@ -400,10 +428,12 @@ int32_t CannedMessageModule::runOnce() } break; case 0x09: // tab - if (this->destSelect) { - this->destSelect = false; + if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL) { + this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE; + } else if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) { + this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL; } else { - this->destSelect = true; + this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE; } break; case 0xb4: // left @@ -524,18 +554,34 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st } else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) { display->setTextAlignment(TEXT_ALIGN_LEFT); display->setFont(FONT_SMALL); - if (this->destSelect) { + if (this->destSelect != CANNED_MESSAGE_DESTINATION_TYPE_NONE) { display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL); display->setColor(BLACK); - display->drawStringf(1 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest)); } - display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest)); + switch (this->destSelect) { + case CANNED_MESSAGE_DESTINATION_TYPE_NODE: + display->drawStringf(1 + x, 0 + y, buffer, "To: >%s<@%s", cannedMessageModule->getNodeName(this->dest), + channels.getName(indexChannels[this->channel])); + display->drawStringf(0 + x, 0 + y, buffer, "To: >%s<@%s", cannedMessageModule->getNodeName(this->dest), + channels.getName(indexChannels[this->channel])); + break; + case CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL: + display->drawStringf(1 + x, 0 + y, buffer, "To: %s@>%s<", cannedMessageModule->getNodeName(this->dest), + channels.getName(indexChannels[this->channel])); + display->drawStringf(0 + x, 0 + y, buffer, "To: %s@>%s<", cannedMessageModule->getNodeName(this->dest), + channels.getName(indexChannels[this->channel])); + break; + default: + display->drawStringf(0 + x, 0 + y, buffer, "To: %s@%s", cannedMessageModule->getNodeName(this->dest), + channels.getName(indexChannels[this->channel])); + break; + } // used chars right aligned uint16_t charsLeft = meshtastic_Constants_DATA_PAYLOAD_LEN - this->freetext.length() - (moduleConfig.canned_message.send_bell ? 1 : 0); snprintf(buffer, sizeof(buffer), "%d left", charsLeft); display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer); - if (this->destSelect) { + if (this->destSelect != CANNED_MESSAGE_DESTINATION_TYPE_NONE) { display->drawString(x + display->getWidth() - display->getStringWidth(buffer) - 1, y + 0, buffer); } display->setColor(WHITE); diff --git a/src/modules/CannedMessageModule.h b/src/modules/CannedMessageModule.h index b41fba045..4802be078 100644 --- a/src/modules/CannedMessageModule.h +++ b/src/modules/CannedMessageModule.h @@ -15,6 +15,12 @@ enum cannedMessageModuleRunState { CANNED_MESSAGE_RUN_STATE_ACTION_DOWN, }; +enum cannedMessageDestinationType { + CANNED_MESSAGE_DESTINATION_TYPE_NONE, + CANNED_MESSAGE_DESTINATION_TYPE_NODE, + CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL +}; + #define CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT 50 /** * Sum of CannedMessageModuleConfig part sizes. @@ -64,7 +70,7 @@ class CannedMessageModule : public SinglePortModule, public Observable