mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-02 16:10:43 +00:00
Show specific frame when updating screen (#4264)
* Updated setFrames in Screen.cpp Added code to attempt to revert back to the same frame that user was on prior to setFrame reload. * Space added Screen.cpp * Update Screen.cpp Make screen to revert to Frame 0 if the originally displayed frame is no longer there. * Update Screen.cpp Inserted boolean holdPosition into setFrames to indicate the requirement to stay on the same frame ( if =true) or else it will switch to new frame . Only Screen::handleStatusUpdate calls with setFrame(true). ( For Node Updates) All other types of updates call as before setFrame(), so it will change focus as needed. * Hold position, even if number of frames increases * Hold position, if handling an outgoing text message * Update Screen.cpp * Reverted chnages related to devicestate.has_rx_text_message * Reset to master * CannedMessages only handles routing packets when waiting for ACK Previously, this was calling Screen::setFrames at unexpected times * Gather position info about screen frames while regenerating * Make admin module observable Notify only when relevant. Currently: only to handle remove_nodenum. * Optionally specify which frame to focus when setFrames runs * UIFrameEvent uses enum instead of multiple booleans * Allow modules to request their own frame to be focussed This is done internally by calling MeshModule::requestFocus() Easier this way, insteady of passing the info in the UIFrameEvent: * Modules don't always know whether they should be focussed until after the UIFrameEvent has been raised, in dramFrame * Don't have to pass reference to module instance as parameter though several methods * E-Ink screensaver uses FOCUS_PRESERVE Previously, it had its own basic implementation of this. * Spelling: regional variant * trunk * Fix HAS_SCREEN guarding * More HAS_SCREEN guarding --------- Co-authored-by: BIST <77391720+slash-bit@users.noreply.github.com> Co-authored-by: Ben Meadors <benmmeadors@gmail.com> Co-authored-by: slash-bit <v-b2@live.com>
This commit is contained in:
@@ -200,6 +200,7 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
case meshtastic_AdminMessage_remove_by_nodenum_tag: {
|
||||
LOG_INFO("Client is receiving a remove_nodenum command.\n");
|
||||
nodeDB->removeNodeByNum(r->remove_by_nodenum);
|
||||
this->notifyObservers(r); // Observed by screen
|
||||
break;
|
||||
}
|
||||
case meshtastic_AdminMessage_set_favorite_node_tag: {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
/**
|
||||
* Admin module for admin messages
|
||||
*/
|
||||
class AdminModule : public ProtobufModule<meshtastic_AdminMessage>
|
||||
class AdminModule : public ProtobufModule<meshtastic_AdminMessage>, public Observable<const meshtastic_AdminMessage *>
|
||||
{
|
||||
public:
|
||||
/** Constructor
|
||||
|
||||
@@ -148,8 +148,9 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
||||
if (this->currentMessageIndex == 0) {
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
||||
|
||||
UIFrameEvent e = {false, true};
|
||||
e.frameChanged = true;
|
||||
requestFocus(); // Tell Screen::setFrames to move to our module's frame, next time it runs
|
||||
UIFrameEvent e;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
this->notifyObservers(&e);
|
||||
|
||||
return 0;
|
||||
@@ -166,8 +167,8 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
||||
}
|
||||
}
|
||||
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL)) {
|
||||
UIFrameEvent e = {false, true};
|
||||
e.frameChanged = true;
|
||||
UIFrameEvent e;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
this->currentMessageIndex = -1;
|
||||
|
||||
#if !defined(T_WATCH_S3) && !defined(RAK14014)
|
||||
@@ -353,6 +354,8 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
||||
}
|
||||
|
||||
if (validEvent) {
|
||||
requestFocus(); // Tell Screen::setFrames to move to our module's frame, next time it runs
|
||||
|
||||
// Let runOnce to be called immediately.
|
||||
if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
||||
setIntervalFromNow(0); // on fast keypresses, this isn't fast enough.
|
||||
@@ -378,6 +381,11 @@ void CannedMessageModule::sendText(NodeNum dest, ChannelIndex channel, const cha
|
||||
p->decoded.payload.size++;
|
||||
}
|
||||
|
||||
// Only receive routing messages when expecting ACK for a canned message
|
||||
// Prevents the canned message module from regenerating the screen's frameset at unexpected times,
|
||||
// or raising a UIFrameEvent before another module has the chance
|
||||
this->waitingForAck = true;
|
||||
|
||||
LOG_INFO("Sending message id=%d, dest=%x, msg=%.*s\n", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
|
||||
|
||||
service.sendToMesh(
|
||||
@@ -393,13 +401,13 @@ int32_t CannedMessageModule::runOnce()
|
||||
return INT32_MAX;
|
||||
}
|
||||
// LOG_DEBUG("Check status\n");
|
||||
UIFrameEvent e = {false, true};
|
||||
UIFrameEvent e;
|
||||
if ((this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) ||
|
||||
(this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) || (this->runState == CANNED_MESSAGE_RUN_STATE_MESSAGE)) {
|
||||
// TODO: might have some feedback of sending state
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
temporaryMessage = "";
|
||||
e.frameChanged = true;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
this->currentMessageIndex = -1;
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
@@ -412,7 +420,7 @@ int32_t CannedMessageModule::runOnce()
|
||||
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) &&
|
||||
((millis() - this->lastTouchMillis) > INACTIVATE_AFTER_MS)) {
|
||||
// Reset module
|
||||
e.frameChanged = true;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
this->currentMessageIndex = -1;
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
@@ -449,7 +457,7 @@ int32_t CannedMessageModule::runOnce()
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
||||
}
|
||||
}
|
||||
e.frameChanged = true;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
this->currentMessageIndex = -1;
|
||||
this->freetext = ""; // clear freetext
|
||||
this->cursor = 0;
|
||||
@@ -463,7 +471,7 @@ int32_t CannedMessageModule::runOnce()
|
||||
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
|
||||
this->currentMessageIndex = 0;
|
||||
LOG_DEBUG("First touch (%d):%s\n", this->currentMessageIndex, this->getCurrentMessage());
|
||||
e.frameChanged = true;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
||||
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP) {
|
||||
if (this->messagesCount > 0) {
|
||||
@@ -567,7 +575,7 @@ int32_t CannedMessageModule::runOnce()
|
||||
break;
|
||||
}
|
||||
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||
e.frameChanged = true;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
switch (this->payload) { // code below all trigger the freetext window (where you type to send a message) or reset the
|
||||
// display back to the default window
|
||||
case 0x08: // backspace
|
||||
@@ -706,8 +714,8 @@ int CannedMessageModule::getPrevIndex()
|
||||
void CannedMessageModule::showTemporaryMessage(const String &message)
|
||||
{
|
||||
temporaryMessage = message;
|
||||
UIFrameEvent e = {false, true};
|
||||
e.frameChanged = true;
|
||||
UIFrameEvent e;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
notifyObservers(&e);
|
||||
runState = CANNED_MESSAGE_RUN_STATE_MESSAGE;
|
||||
// run this loop again in 2 seconds, next iteration will clear the display
|
||||
@@ -914,11 +922,13 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
||||
char buffer[50];
|
||||
|
||||
if (temporaryMessage.length() != 0) {
|
||||
requestFocus(); // Tell Screen::setFrames to move to our module's frame
|
||||
LOG_DEBUG("Drawing temporary message: %s", temporaryMessage.c_str());
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->setFont(FONT_MEDIUM);
|
||||
display->drawString(display->getWidth() / 2 + x, 0 + y + 12, temporaryMessage);
|
||||
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) {
|
||||
requestFocus(); // Tell Screen::setFrames to move to our module's frame
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->setFont(FONT_MEDIUM);
|
||||
String displayString;
|
||||
@@ -940,6 +950,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
||||
display->drawStringf(display->getWidth() / 2 + x, y + 130, buffer, rssiString, this->lastRxRssi);
|
||||
}
|
||||
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
|
||||
requestFocus(); // Tell Screen::setFrames to move to our module's frame
|
||||
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||
display->setFont(FONT_MEDIUM);
|
||||
display->drawString(display->getWidth() / 2 + x, 0 + y + 12, "Sending...");
|
||||
@@ -948,7 +959,7 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
||||
display->setFont(FONT_SMALL);
|
||||
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
|
||||
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
||||
|
||||
requestFocus(); // Tell Screen::setFrames to move to our module's frame
|
||||
#if defined(T_WATCH_S3) || defined(RAK14014)
|
||||
drawKeyboard(display, state, 0, 0);
|
||||
#else
|
||||
@@ -1030,16 +1041,18 @@ void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *st
|
||||
|
||||
ProcessMessage CannedMessageModule::handleReceived(const meshtastic_MeshPacket &mp)
|
||||
{
|
||||
if (mp.decoded.portnum == meshtastic_PortNum_ROUTING_APP) {
|
||||
if (mp.decoded.portnum == meshtastic_PortNum_ROUTING_APP && waitingForAck) {
|
||||
// look for a request_id
|
||||
if (mp.decoded.request_id != 0) {
|
||||
UIFrameEvent e = {false, true};
|
||||
e.frameChanged = true;
|
||||
UIFrameEvent e;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
requestFocus(); // Tell Screen::setFrames that our module's frame should be shown, even if not "first" in the frameset
|
||||
this->runState = CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED;
|
||||
this->incoming = service.getNodenumFromRequestId(mp.decoded.request_id);
|
||||
meshtastic_Routing decoded = meshtastic_Routing_init_default;
|
||||
pb_decode_from_bytes(mp.decoded.payload.bytes, mp.decoded.payload.size, meshtastic_Routing_fields, &decoded);
|
||||
this->ack = decoded.error_reason == meshtastic_Routing_Error_NONE;
|
||||
waitingForAck = false; // No longer want routing packets
|
||||
this->notifyObservers(&e);
|
||||
// run the next time 2 seconds later
|
||||
setIntervalFromNow(2000);
|
||||
|
||||
@@ -81,9 +81,8 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
||||
}
|
||||
|
||||
switch (p->decoded.portnum) {
|
||||
case meshtastic_PortNum_TEXT_MESSAGE_APP:
|
||||
case meshtastic_PortNum_ROUTING_APP:
|
||||
return true;
|
||||
return waitingForAck;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -140,7 +139,8 @@ class CannedMessageModule : public SinglePortModule, public Observable<const UIF
|
||||
uint8_t numChannels = 0;
|
||||
ChannelIndex indexChannels[MAX_NUM_CHANNELS] = {0};
|
||||
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)
|
||||
bool waitingForAck = false; // Are currently interested in routing packets?
|
||||
float lastRxSnr = 0;
|
||||
int32_t lastRxRssi = 0;
|
||||
|
||||
|
||||
@@ -16,15 +16,31 @@ ProcessMessage WaypointModule::handleReceived(const meshtastic_MeshPacket &mp)
|
||||
auto &p = mp.decoded;
|
||||
LOG_INFO("Received waypoint msg from=0x%0x, id=0x%x, msg=%.*s\n", mp.from, mp.id, p.payload.size, p.payload.bytes);
|
||||
#endif
|
||||
UIFrameEvent e = {true, true};
|
||||
// We only store/display messages destined for us.
|
||||
// Keep a copy of the most recent text message.
|
||||
devicestate.rx_waypoint = mp;
|
||||
devicestate.has_rx_waypoint = true;
|
||||
|
||||
powerFSM.trigger(EVENT_RECEIVED_MSG);
|
||||
|
||||
#if HAS_SCREEN
|
||||
|
||||
UIFrameEvent e;
|
||||
|
||||
// New or updated waypoint: focus on this frame next time Screen::setFrames runs
|
||||
if (shouldDraw()) {
|
||||
requestFocus();
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET;
|
||||
}
|
||||
|
||||
// Deleting an old waypoint: remove the frame quietly, don't change frame position if possible
|
||||
else
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET_BACKGROUND;
|
||||
|
||||
notifyObservers(&e);
|
||||
|
||||
#endif
|
||||
|
||||
return ProcessMessage::CONTINUE; // Let others look at this message also if they want
|
||||
}
|
||||
|
||||
|
||||
@@ -190,13 +190,13 @@ int32_t AudioModule::runOnce()
|
||||
|
||||
firstTime = false;
|
||||
} else {
|
||||
UIFrameEvent e = {false, true};
|
||||
UIFrameEvent e;
|
||||
// Check if PTT is pressed. TODO hook that into Onebutton/Interrupt drive.
|
||||
if (digitalRead(moduleConfig.audio.ptt_pin ? moduleConfig.audio.ptt_pin : PTT_PIN) == HIGH) {
|
||||
if (radio_state == RadioState::rx) {
|
||||
LOG_INFO("PTT pressed, switching to TX\n");
|
||||
radio_state = RadioState::tx;
|
||||
e.frameChanged = true;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
} else {
|
||||
@@ -209,7 +209,7 @@ int32_t AudioModule::runOnce()
|
||||
}
|
||||
tx_encode_frame_index = sizeof(tx_header);
|
||||
radio_state = RadioState::rx;
|
||||
e.frameChanged = true;
|
||||
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user