diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp
index 4e4a98454..c7bc0fe36 100644
--- a/src/graphics/Screen.cpp
+++ b/src/graphics/Screen.cpp
@@ -34,7 +34,6 @@ 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"
@@ -821,9 +820,9 @@ void Screen::setup()
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
if (textMessagePlugin)
textMessageObserver.observe(textMessagePlugin);
- // TODO: find a nicer way to notify screen about refresh
- if (cannedMessagePlugin)
- cannedMessageObserver.observe(cannedMessagePlugin);
+
+ // Plugins can notify screen about refresh
+ MeshPlugin::observeUIEvents(&uiFrameEventObserver);
}
void Screen::forceDisplay()
@@ -1461,14 +1460,21 @@ int Screen::handleTextMessage(const MeshPacket *packet)
return 0;
}
-int Screen::handleCannedMessage(const meshtastic::Status *packet)
+int Screen::handleUIFrameEvent(const UIFrameEvent *event)
{
if (showingNormalScreen) {
- setFrames(); // Regen the list of screens (will show new text message)
+ if (event->frameChanged)
+ {
+ setFrames(); // Regen the list of screens (will show new text message)
+ }
+ else if (event->needRedraw)
+ {
+ setFastFramerate();
+ // TODO: We might also want switch to corresponding frame,
+ // but we don't know the exact frame number.
+ //ui.switchToFrame(0);
+ }
}
- // TODO: We might also want switch to corresponding frame,
- // but we don't know the exact frame number.
- //ui.switchToFrame(0);
return 0;
}
diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h
index 68815328e..10b2b6ff7 100644
--- a/src/graphics/Screen.h
+++ b/src/graphics/Screen.h
@@ -40,6 +40,7 @@ class Screen
#include "concurrency/OSThread.h"
#include "power.h"
#include
+#include "mesh/MeshPlugin.h"
// 0 to 255, though particular variants might define different defaults
#ifndef BRIGHTNESS_DEFAULT
@@ -90,8 +91,8 @@ class Screen : public concurrency::OSThread
CallbackObserver(this, &Screen::handleStatusUpdate);
CallbackObserver textMessageObserver =
CallbackObserver(this, &Screen::handleTextMessage);
- CallbackObserver cannedMessageObserver =
- CallbackObserver(this, &Screen::handleCannedMessage);
+ CallbackObserver uiFrameEventObserver =
+ CallbackObserver(this, &Screen::handleUIFrameEvent);
public:
Screen(uint8_t address, int sda = -1, int scl = -1);
@@ -220,7 +221,7 @@ class Screen : public concurrency::OSThread
int handleStatusUpdate(const meshtastic::Status *arg);
int handleTextMessage(const MeshPacket *arg);
- int handleCannedMessage(const meshtastic::Status *arg);
+ int handleUIFrameEvent(const UIFrameEvent *arg);
/// Used to force (super slow) eink displays to draw critical frames
void forceDisplay();
diff --git a/src/mesh/MeshPlugin.cpp b/src/mesh/MeshPlugin.cpp
index 85988ec7b..985a7060f 100644
--- a/src/mesh/MeshPlugin.cpp
+++ b/src/mesh/MeshPlugin.cpp
@@ -235,3 +235,18 @@ std::vector MeshPlugin::GetMeshPluginsWithUIFrames()
}
return pluginsWithUIFrames;
}
+
+void MeshPlugin::observeUIEvents(
+ Observer *observer)
+{
+ std::vector pluginsWithUIFrames;
+ for (auto i = plugins->begin(); i != plugins->end(); ++i) {
+ auto &pi = **i;
+ Observable *observable =
+ pi.getUIFrameObservable();
+ if (observable != NULL) {
+ DEBUG_MSG("Plugin wants a UI Frame\n");
+ observer->observe(observable);
+ }
+ }
+}
diff --git a/src/mesh/MeshPlugin.h b/src/mesh/MeshPlugin.h
index 0143814a7..b6bcf22b8 100644
--- a/src/mesh/MeshPlugin.h
+++ b/src/mesh/MeshPlugin.h
@@ -21,6 +21,14 @@ enum class ProcessMessage
STOP = 1,
};
+/*
+ * This struct is used by Screen to figure out whether screen frame should be updated.
+ */
+typedef struct _UIFrameEvent {
+ bool frameChanged;
+ bool needRedraw;
+} UIFrameEvent;
+
/** A baseclass for any mesh "plugin".
*
* A plugin allows you to add new features to meshtastic device code, without needing to know messaging details.
@@ -48,6 +56,7 @@ class MeshPlugin
static void callPlugins(const MeshPacket &mp, RxSource src = RX_SRC_RADIO);
static std::vector GetMeshPluginsWithUIFrames();
+ static void observeUIEvents(Observer *observer);
#ifndef NO_SCREEN
virtual void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) { return; }
#endif
@@ -119,6 +128,7 @@ class MeshPlugin
* @return true if you want to be alloced a UI screen frame
*/
virtual bool wantUIFrame() { return false; }
+ virtual Observable* getUIFrameObservable() { return NULL; }
MeshPacket *allocAckNak(Routing_Error err, NodeNum to, PacketId idFrom, ChannelIndex chIndex);
diff --git a/src/plugins/CannedMessagePlugin.cpp b/src/plugins/CannedMessagePlugin.cpp
index 251a9c2f5..26ef6cce8 100644
--- a/src/plugins/CannedMessagePlugin.cpp
+++ b/src/plugins/CannedMessagePlugin.cpp
@@ -146,17 +146,19 @@ int32_t CannedMessagePlugin::runOnce()
return 30000; // TODO: should return MAX_VAL
}
DEBUG_MSG("Check status\n");
+ UIFrameEvent e = {false, true};
if (this->sendingState == SENDING_STATE_ACTIVE)
{
// TODO: might have some feedback of sendig state
this->sendingState = SENDING_STATE_NONE;
- this->notifyObservers(NULL);
+ this->notifyObservers(&e);
}
else if ((this->action != CANNED_MESSAGE_ACTION_NONE)
&& (this->currentMessageIndex == -1))
{
this->currentMessageIndex = 0;
DEBUG_MSG("First touch.\n");
+ e.frameChanged = true;
}
else if (this->action == CANNED_MESSAGE_ACTION_SELECT)
{
@@ -166,7 +168,7 @@ int32_t CannedMessagePlugin::runOnce()
true);
this->sendingState = SENDING_STATE_ACTIVE;
this->currentMessageIndex = -1;
- this->notifyObservers(NULL);
+ this->notifyObservers(&e);
return 2000;
}
else if (this->action == CANNED_MESSAGE_ACTION_UP)
@@ -182,7 +184,7 @@ int32_t CannedMessagePlugin::runOnce()
if (this->action != CANNED_MESSAGE_ACTION_NONE)
{
this->action = CANNED_MESSAGE_ACTION_NONE;
- this->notifyObservers(NULL);
+ this->notifyObservers(&e);
}
return 30000; // TODO: should return MAX_VAL
diff --git a/src/plugins/CannedMessagePlugin.h b/src/plugins/CannedMessagePlugin.h
index 91c394466..10b8f6742 100644
--- a/src/plugins/CannedMessagePlugin.h
+++ b/src/plugins/CannedMessagePlugin.h
@@ -17,11 +17,12 @@ enum cannedMessagePluginSendigState
SENDING_STATE_ACTIVE
};
+
#define CANNED_MESSAGE_PLUGIN_MESSAGE_MAX_COUNT 50
class CannedMessagePlugin :
public SinglePortPlugin,
- public Observable,
+ public Observable,
private concurrency::OSThread
{
CallbackObserver inputObserver =
@@ -53,6 +54,7 @@ class CannedMessagePlugin :
int handleInputEvent(const InputEvent *event);
virtual bool wantUIFrame() { return this->shouldDraw(); }
+ virtual Observable* getUIFrameObservable() { return this; }
virtual void drawFrame(
OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
diff --git a/src/plugins/input/RotaryEncoderInterruptBase.cpp b/src/plugins/input/RotaryEncoderInterruptBase.cpp
index bff01edb2..e4635eb1a 100644
--- a/src/plugins/input/RotaryEncoderInterruptBase.cpp
+++ b/src/plugins/input/RotaryEncoderInterruptBase.cpp
@@ -65,7 +65,7 @@ int32_t RotaryEncoderInterruptBase::runOnce()
this->action = ROTARY_ACTION_NONE;
- return 30000;
+ return 30000; // TODO: technically this can be MAX_INT
}
@@ -73,7 +73,7 @@ void RotaryEncoderInterruptBase::intPressHandler()
{
this->action = ROTARY_ACTION_PRESSED;
runned(millis());
- setInterval(20);
+ setInterval(20); // TODO: this modifies a non-volatile variable!
}
void RotaryEncoderInterruptBase::intAHandler()
@@ -144,7 +144,7 @@ RotaryEncoderInterruptBaseStateType RotaryEncoderInterruptBase::intHandler(
newState = ROTARY_EVENT_CLEARED;
}
runned(millis());
- setInterval(50);
+ setInterval(50); // TODO: this modifies a non-volatile variable!
return newState;
}