mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-24 17:32:18 +00:00
Select Node and channel in Canned Message module.
This commit is contained in:
parent
4b7fbeca29
commit
dad05d7873
@ -4,6 +4,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#if HAS_SCREEN
|
#if HAS_SCREEN
|
||||||
#include "CannedMessageModule.h"
|
#include "CannedMessageModule.h"
|
||||||
|
#include "Channels.h"
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
@ -187,10 +188,10 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
if (!event->kbchar) {
|
if (!event->kbchar) {
|
||||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
||||||
this->payload = 0xb4;
|
this->payload = 0xb4;
|
||||||
this->destSelect = true;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
|
||||||
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
||||||
this->payload = 0xb7;
|
this->payload = 0xb7;
|
||||||
this->destSelect = true;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// pass the pressed key
|
// pass the pressed key
|
||||||
@ -234,10 +235,11 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
|||||||
return 0;
|
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();
|
meshtastic_MeshPacket *p = allocDataPacket();
|
||||||
p->to = dest;
|
p->to = dest;
|
||||||
|
p->channel = channel;
|
||||||
p->want_ack = true;
|
p->want_ack = true;
|
||||||
p->decoded.payload.size = strlen(message);
|
p->decoded.payload.size = strlen(message);
|
||||||
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
|
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
|
||||||
@ -270,7 +272,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->currentMessageIndex = -1;
|
this->currentMessageIndex = -1;
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
this->destSelect = false;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) &&
|
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) &&
|
||||||
((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
|
((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
|
||||||
@ -280,13 +282,13 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->currentMessageIndex = -1;
|
this->currentMessageIndex = -1;
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
this->destSelect = false;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
||||||
if (this->payload == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
if (this->payload == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||||
if (this->freetext.length() > 0) {
|
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;
|
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
||||||
} else {
|
} else {
|
||||||
LOG_DEBUG("Reset message is empty.\n");
|
LOG_DEBUG("Reset message is empty.\n");
|
||||||
@ -298,7 +300,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
powerFSM.trigger(EVENT_PRESS);
|
powerFSM.trigger(EVENT_PRESS);
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
} else {
|
} 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;
|
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
||||||
} else {
|
} else {
|
||||||
@ -310,7 +312,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->currentMessageIndex = -1;
|
this->currentMessageIndex = -1;
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
this->destSelect = false;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
return 2000;
|
return 2000;
|
||||||
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
|
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
|
||||||
@ -323,7 +325,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->currentMessageIndex = getPrevIndex();
|
this->currentMessageIndex = getPrevIndex();
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
this->destSelect = false;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||||
LOG_DEBUG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
LOG_DEBUG("MOVE UP (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||||
}
|
}
|
||||||
@ -332,14 +334,14 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
this->currentMessageIndex = this->getNextIndex();
|
this->currentMessageIndex = this->getNextIndex();
|
||||||
this->freetext = ""; // clear freetext
|
this->freetext = ""; // clear freetext
|
||||||
this->cursor = 0;
|
this->cursor = 0;
|
||||||
this->destSelect = false;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||||
LOG_DEBUG("MOVE DOWN (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
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) {
|
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT || this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) {
|
||||||
switch (this->payload) {
|
switch (this->payload) {
|
||||||
case 0xb4: // left
|
case 0xb4: // left
|
||||||
if (this->destSelect) {
|
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
|
||||||
size_t numMeshNodes = nodeDB.getNumMeshNodes();
|
size_t numMeshNodes = nodeDB.getNumMeshNodes();
|
||||||
if (this->dest == NODENUM_BROADCAST) {
|
if (this->dest == NODENUM_BROADCAST) {
|
||||||
this->dest = nodeDB.getNodeNum();
|
this->dest = nodeDB.getNodeNum();
|
||||||
@ -354,6 +356,19 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
if (this->dest == nodeDB.getNodeNum()) {
|
if (this->dest == nodeDB.getNodeNum()) {
|
||||||
this->dest = NODENUM_BROADCAST;
|
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 {
|
} else {
|
||||||
if (this->cursor > 0) {
|
if (this->cursor > 0) {
|
||||||
this->cursor--;
|
this->cursor--;
|
||||||
@ -361,7 +376,7 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xb7: // right
|
case 0xb7: // right
|
||||||
if (this->destSelect) {
|
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
|
||||||
size_t numMeshNodes = nodeDB.getNumMeshNodes();
|
size_t numMeshNodes = nodeDB.getNumMeshNodes();
|
||||||
if (this->dest == NODENUM_BROADCAST) {
|
if (this->dest == NODENUM_BROADCAST) {
|
||||||
this->dest = nodeDB.getNodeNum();
|
this->dest = nodeDB.getNodeNum();
|
||||||
@ -376,6 +391,19 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
if (this->dest == nodeDB.getNodeNum()) {
|
if (this->dest == nodeDB.getNodeNum()) {
|
||||||
this->dest = NODENUM_BROADCAST;
|
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 {
|
} else {
|
||||||
if (this->cursor < this->freetext.length()) {
|
if (this->cursor < this->freetext.length()) {
|
||||||
this->cursor++;
|
this->cursor++;
|
||||||
@ -400,10 +428,12 @@ int32_t CannedMessageModule::runOnce()
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x09: // tab
|
case 0x09: // tab
|
||||||
if (this->destSelect) {
|
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL) {
|
||||||
this->destSelect = false;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
|
} else if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
|
||||||
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL;
|
||||||
} else {
|
} else {
|
||||||
this->destSelect = true;
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xb4: // left
|
case 0xb4: // left
|
||||||
@ -524,18 +554,34 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
|||||||
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||||
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
||||||
display->setFont(FONT_SMALL);
|
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->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
||||||
display->setColor(BLACK);
|
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
|
// used chars right aligned
|
||||||
uint16_t charsLeft =
|
uint16_t charsLeft =
|
||||||
meshtastic_Constants_DATA_PAYLOAD_LEN - this->freetext.length() - (moduleConfig.canned_message.send_bell ? 1 : 0);
|
meshtastic_Constants_DATA_PAYLOAD_LEN - this->freetext.length() - (moduleConfig.canned_message.send_bell ? 1 : 0);
|
||||||
snprintf(buffer, sizeof(buffer), "%d left", charsLeft);
|
snprintf(buffer, sizeof(buffer), "%d left", charsLeft);
|
||||||
display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer);
|
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->drawString(x + display->getWidth() - display->getStringWidth(buffer) - 1, y + 0, buffer);
|
||||||
}
|
}
|
||||||
display->setColor(WHITE);
|
display->setColor(WHITE);
|
||||||
|
@ -15,6 +15,12 @@ enum cannedMessageModuleRunState {
|
|||||||
CANNED_MESSAGE_RUN_STATE_ACTION_DOWN,
|
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
|
#define CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT 50
|
||||||
/**
|
/**
|
||||||
* Sum of CannedMessageModuleConfig part sizes.
|
* Sum of CannedMessageModuleConfig part sizes.
|
||||||
@ -64,7 +70,7 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
protected:
|
protected:
|
||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
|
|
||||||
void sendText(NodeNum dest, const char *message, bool wantReplies);
|
void sendText(NodeNum dest, ChannelIndex channel, const char *message, bool wantReplies);
|
||||||
|
|
||||||
int splitConfiguredMessages();
|
int splitConfiguredMessages();
|
||||||
int getNextIndex();
|
int getNextIndex();
|
||||||
@ -94,8 +100,11 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
|||||||
char payload = 0x00;
|
char payload = 0x00;
|
||||||
unsigned int cursor = 0;
|
unsigned int cursor = 0;
|
||||||
String freetext = ""; // Text Buffer for Freetext Editor
|
String freetext = ""; // Text Buffer for Freetext Editor
|
||||||
bool destSelect = false; // Freetext Editor Mode
|
|
||||||
NodeNum dest = NODENUM_BROADCAST;
|
NodeNum dest = NODENUM_BROADCAST;
|
||||||
|
ChannelIndex channel = 0;
|
||||||
|
cannedMessageDestinationType destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
||||||
|
uint8_t numChannels = 0;
|
||||||
|
ChannelIndex indexChannels[MAX_NUM_CHANNELS] = {0};
|
||||||
NodeNum incoming = NODENUM_BROADCAST;
|
NodeNum incoming = NODENUM_BROADCAST;
|
||||||
bool ack = false; // True means ACK, false means NAK (error_reason != NONE)
|
bool ack = false; // True means ACK, false means NAK (error_reason != NONE)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user