From 7b8849493fde5c5568501db47434e93c9715f792 Mon Sep 17 00:00:00 2001 From: Balazs Kelemen <10376327+prampec@users.noreply.github.com> Date: Tue, 4 Jan 2022 19:43:06 +0100 Subject: [PATCH] Adding screen frame --- src/graphics/Screen.cpp | 31 ++++++++++++++++ src/graphics/Screen.h | 3 ++ src/plugins/CannedMessagePlugin.cpp | 57 ++++++++++++++++++++++------- src/plugins/CannedMessagePlugin.h | 47 ++++++++++++++++++++---- 4 files changed, 118 insertions(+), 20 deletions(-) diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index cdf5ab1a5..22bfb8afb 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -34,6 +34,7 @@ along with this program. If not, see . #include "mesh-pb-constants.h" #include "mesh/Channels.h" #include "plugins/TextMessagePlugin.h" +#include "plugins/CannedMessagePlugin.h" #include "sleep.h" #include "target_specific.h" #include "utils.h" @@ -285,6 +286,21 @@ static void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state display->drawStringMaxWidth(4 + x, 10 + y, SCREEN_WIDTH - (6 + x), tempBuf); } +static void drawCannedMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) +{ + displayedNodeNum = 0; // Not currently showing a node pane + + display->setTextAlignment(TEXT_ALIGN_LEFT); + display->setFont(FONT_MEDIUM); + display->drawString(0 + x, 0 + y, cannedMessagePlugin->getCurrentSelection()); + + // the max length of this buffer is much longer than we can possibly print +// static char tempBuf[96]; +// snprintf(tempBuf, sizeof(tempBuf), " %s", mp.decoded.payload.bytes); + +// display->drawStringMaxWidth(4 + x, 10 + y, SCREEN_WIDTH - (6 + x), tempBuf); +} + /// Draw a series of fields in a column, wrapping to multiple colums if needed static void drawColumns(OLEDDisplay *display, int16_t x, int16_t y, const char **fields) { @@ -820,6 +836,8 @@ void Screen::setup() nodeStatusObserver.observe(&nodeStatus->onNewStatus); if (textMessagePlugin) textMessageObserver.observe(textMessagePlugin); + if (cannedMessagePlugin) + cannedMessageObserver.observe(cannedMessagePlugin); } void Screen::forceDisplay() @@ -996,6 +1014,9 @@ void Screen::setFrames() if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) { normalFrames[numframes++] = drawTextMessageFrame; } + if (cannedMessagePlugin->shouldDraw()) { + normalFrames[numframes++] = drawCannedMessageFrame; + } // then all the nodes // We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens @@ -1457,4 +1478,14 @@ int Screen::handleTextMessage(const MeshPacket *packet) return 0; } +int Screen::handleCannedMessage(const meshtastic::Status *packet) +{ + if (showingNormalScreen) { + setFrames(); // Regen the list of screens (will show new text message) + } + ui.switchToFrame(1); + + return 0; +} + } // namespace graphics diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index 9334fe43c..68815328e 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -90,6 +90,8 @@ class Screen : public concurrency::OSThread CallbackObserver(this, &Screen::handleStatusUpdate); CallbackObserver textMessageObserver = CallbackObserver(this, &Screen::handleTextMessage); + CallbackObserver cannedMessageObserver = + CallbackObserver(this, &Screen::handleCannedMessage); public: Screen(uint8_t address, int sda = -1, int scl = -1); @@ -218,6 +220,7 @@ class Screen : public concurrency::OSThread int handleStatusUpdate(const meshtastic::Status *arg); int handleTextMessage(const MeshPacket *arg); + int handleCannedMessage(const meshtastic::Status *arg); /// Used to force (super slow) eink displays to draw critical frames void forceDisplay(); diff --git a/src/plugins/CannedMessagePlugin.cpp b/src/plugins/CannedMessagePlugin.cpp index 996e0b696..b104460b4 100644 --- a/src/plugins/CannedMessagePlugin.cpp +++ b/src/plugins/CannedMessagePlugin.cpp @@ -45,7 +45,9 @@ CannedMessagePlugin::CannedMessagePlugin() #endif } -void CannedMessagePlugin::sendText(NodeNum dest, bool wantReplies) +void CannedMessagePlugin::sendText(NodeNum dest, + const char* message, + bool wantReplies) { MeshPacket *p = allocDataPacket(); p->to = dest; @@ -63,28 +65,57 @@ void CannedMessagePlugin::sendText(NodeNum dest, bool wantReplies) int32_t CannedMessagePlugin::runOnce() { - /* - if (this->action == ACTION_PRESSED) + if ((this->action != ACTION_NONE) + && (this->currentMessageIndex == -1)) { - sendText(NODENUM_BROADCAST, true); - needSend = false; + this->currentMessageIndex = 0; + DEBUG_MSG("First touch. Current message:%s\n", + this->getCurrentSelection()); } - */ - if (this->action == ACTION_PRESSED) + else if (this->action == ACTION_PRESSED) { - DEBUG_MSG("SELECTED\n"); + sendText( + NODENUM_BROADCAST, + cannedMessagePluginMessages[this->currentMessageIndex], + true); } else if (this->action == ACTION_UP) { - DEBUG_MSG("MOVE UP\n"); + if (this->currentMessageIndex <= 0) + { + this->currentMessageIndex = + sizeof(cannedMessagePluginMessages) / CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_LEN - 1; + } + else + { + this->currentMessageIndex -= 1; + } + DEBUG_MSG("MOVE UP. Current message:%s\n", + this->getCurrentSelection()); } else if (this->action == ACTION_DOWN) { - DEBUG_MSG("MOVE_DOWN\n"); + if (this->currentMessageIndex >= + (sizeof(cannedMessagePluginMessages) / CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_LEN) - 1) + { + this->currentMessageIndex = 0; + } + else + { + this->currentMessageIndex += 1; + } + DEBUG_MSG("MOVE DOWN. Current message:%s\n", + this->getCurrentSelection()); } - this->action = ACTION_NONE; - - return UINT32_MAX; + if (this->action != ACTION_NONE) + { + this->action = ACTION_NONE; + this->notifyObservers(NULL); + } + DEBUG_MSG("Current selection index:%d\n", + this->currentMessageIndex); + + return 3000; } void CannedMessagePlugin::select() diff --git a/src/plugins/CannedMessagePlugin.h b/src/plugins/CannedMessagePlugin.h index 24e3ac7f9..437726205 100644 --- a/src/plugins/CannedMessagePlugin.h +++ b/src/plugins/CannedMessagePlugin.h @@ -1,7 +1,7 @@ #pragma once #include "SinglePortPlugin.h" -enum cannedMessagePluginRotatyStateType +enum cannedMessagePluginRotaryStateType { EVENT_OCCURRED, EVENT_CLEARED @@ -15,13 +15,44 @@ enum cannedMessagePluginActionType ACTION_DOWN }; -class CannedMessagePlugin : public SinglePortPlugin, private concurrency::OSThread +#define CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_LEN 50 + +static char cannedMessagePluginMessages[][CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_LEN] = +{ + "I need a helping hand", + "I need help with saw", + "I need an alpinist", + "I need ambulance", + "I'm fine", + "I'm already waiting", + "I will be late", + "I couldn't join", + "We have got company" +}; + +typedef struct _CannedMessagePluginStatus +{ + int dummy; +} CannedMessagePluginStatus; + +class CannedMessagePlugin : + public SinglePortPlugin, + public Observable, + private concurrency::OSThread { public: CannedMessagePlugin(); void select(); void directionA(); void directionB(); + String getCurrentSelection() + { + return cannedMessagePluginMessages[this->currentMessageIndex]; + } + bool shouldDraw() + { + return currentMessageIndex != -1; + } protected: @@ -29,18 +60,20 @@ class CannedMessagePlugin : public SinglePortPlugin, private concurrency::OSThre MeshPacket *preparePacket(); - void sendText(NodeNum dest, bool wantReplies); + void sendText( + NodeNum dest, + const char* message, + bool wantReplies); // TODO: make this configurable volatile cannedMessagePluginActionType cwRotationMeaning = ACTION_UP; - bool needSend = false; volatile cannedMessagePluginActionType action = ACTION_NONE; - volatile cannedMessagePluginRotatyStateType rotaryStateCW = EVENT_CLEARED; - volatile cannedMessagePluginRotatyStateType rotaryStateCCW = EVENT_CLEARED; + volatile cannedMessagePluginRotaryStateType rotaryStateCW = EVENT_CLEARED; + volatile cannedMessagePluginRotaryStateType rotaryStateCCW = EVENT_CLEARED; volatile int rotaryLevelA = LOW; volatile int rotaryLevelB = LOW; -// volatile bool enableEvent = true; + int currentMessageIndex = -1; }; extern CannedMessagePlugin *cannedMessagePlugin;