Adding screen frame

This commit is contained in:
Balazs Kelemen 2022-01-04 19:43:06 +01:00
parent 2b588f1567
commit 7b8849493f
4 changed files with 118 additions and 20 deletions

View File

@ -34,6 +34,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "mesh-pb-constants.h" #include "mesh-pb-constants.h"
#include "mesh/Channels.h" #include "mesh/Channels.h"
#include "plugins/TextMessagePlugin.h" #include "plugins/TextMessagePlugin.h"
#include "plugins/CannedMessagePlugin.h"
#include "sleep.h" #include "sleep.h"
#include "target_specific.h" #include "target_specific.h"
#include "utils.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); 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 /// 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) 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); nodeStatusObserver.observe(&nodeStatus->onNewStatus);
if (textMessagePlugin) if (textMessagePlugin)
textMessageObserver.observe(textMessagePlugin); textMessageObserver.observe(textMessagePlugin);
if (cannedMessagePlugin)
cannedMessageObserver.observe(cannedMessagePlugin);
} }
void Screen::forceDisplay() void Screen::forceDisplay()
@ -996,6 +1014,9 @@ void Screen::setFrames()
if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) { if (devicestate.has_rx_text_message && shouldDrawMessage(&devicestate.rx_text_message)) {
normalFrames[numframes++] = drawTextMessageFrame; normalFrames[numframes++] = drawTextMessageFrame;
} }
if (cannedMessagePlugin->shouldDraw()) {
normalFrames[numframes++] = drawCannedMessageFrame;
}
// then all the nodes // then all the nodes
// We only show a few nodes in our scrolling list - because meshes with many nodes would have too many screens // 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; 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 } // namespace graphics

View File

@ -90,6 +90,8 @@ class Screen : public concurrency::OSThread
CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleStatusUpdate); CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleStatusUpdate);
CallbackObserver<Screen, const MeshPacket *> textMessageObserver = CallbackObserver<Screen, const MeshPacket *> textMessageObserver =
CallbackObserver<Screen, const MeshPacket *>(this, &Screen::handleTextMessage); CallbackObserver<Screen, const MeshPacket *>(this, &Screen::handleTextMessage);
CallbackObserver<Screen, const meshtastic::Status *> cannedMessageObserver =
CallbackObserver<Screen, const meshtastic::Status *>(this, &Screen::handleCannedMessage);
public: public:
Screen(uint8_t address, int sda = -1, int scl = -1); 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 handleStatusUpdate(const meshtastic::Status *arg);
int handleTextMessage(const MeshPacket *arg); int handleTextMessage(const MeshPacket *arg);
int handleCannedMessage(const meshtastic::Status *arg);
/// Used to force (super slow) eink displays to draw critical frames /// Used to force (super slow) eink displays to draw critical frames
void forceDisplay(); void forceDisplay();

View File

@ -45,7 +45,9 @@ CannedMessagePlugin::CannedMessagePlugin()
#endif #endif
} }
void CannedMessagePlugin::sendText(NodeNum dest, bool wantReplies) void CannedMessagePlugin::sendText(NodeNum dest,
const char* message,
bool wantReplies)
{ {
MeshPacket *p = allocDataPacket(); MeshPacket *p = allocDataPacket();
p->to = dest; p->to = dest;
@ -63,28 +65,57 @@ void CannedMessagePlugin::sendText(NodeNum dest, bool wantReplies)
int32_t CannedMessagePlugin::runOnce() int32_t CannedMessagePlugin::runOnce()
{ {
/* if ((this->action != ACTION_NONE)
if (this->action == ACTION_PRESSED) && (this->currentMessageIndex == -1))
{ {
sendText(NODENUM_BROADCAST, true); this->currentMessageIndex = 0;
needSend = false; DEBUG_MSG("First touch. Current message:%s\n",
this->getCurrentSelection());
} }
*/ else if (this->action == ACTION_PRESSED)
if (this->action == ACTION_PRESSED)
{ {
DEBUG_MSG("SELECTED\n"); sendText(
NODENUM_BROADCAST,
cannedMessagePluginMessages[this->currentMessageIndex],
true);
} }
else if (this->action == ACTION_UP) 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) 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());
}
if (this->action != ACTION_NONE)
{
this->action = ACTION_NONE; this->action = ACTION_NONE;
this->notifyObservers(NULL);
}
DEBUG_MSG("Current selection index:%d\n",
this->currentMessageIndex);
return UINT32_MAX; return 3000;
} }
void CannedMessagePlugin::select() void CannedMessagePlugin::select()

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "SinglePortPlugin.h" #include "SinglePortPlugin.h"
enum cannedMessagePluginRotatyStateType enum cannedMessagePluginRotaryStateType
{ {
EVENT_OCCURRED, EVENT_OCCURRED,
EVENT_CLEARED EVENT_CLEARED
@ -15,13 +15,44 @@ enum cannedMessagePluginActionType
ACTION_DOWN 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<const meshtastic::Status *>,
private concurrency::OSThread
{ {
public: public:
CannedMessagePlugin(); CannedMessagePlugin();
void select(); void select();
void directionA(); void directionA();
void directionB(); void directionB();
String getCurrentSelection()
{
return cannedMessagePluginMessages[this->currentMessageIndex];
}
bool shouldDraw()
{
return currentMessageIndex != -1;
}
protected: protected:
@ -29,18 +60,20 @@ class CannedMessagePlugin : public SinglePortPlugin, private concurrency::OSThre
MeshPacket *preparePacket(); MeshPacket *preparePacket();
void sendText(NodeNum dest, bool wantReplies); void sendText(
NodeNum dest,
const char* message,
bool wantReplies);
// TODO: make this configurable // TODO: make this configurable
volatile cannedMessagePluginActionType cwRotationMeaning = ACTION_UP; volatile cannedMessagePluginActionType cwRotationMeaning = ACTION_UP;
bool needSend = false;
volatile cannedMessagePluginActionType action = ACTION_NONE; volatile cannedMessagePluginActionType action = ACTION_NONE;
volatile cannedMessagePluginRotatyStateType rotaryStateCW = EVENT_CLEARED; volatile cannedMessagePluginRotaryStateType rotaryStateCW = EVENT_CLEARED;
volatile cannedMessagePluginRotatyStateType rotaryStateCCW = EVENT_CLEARED; volatile cannedMessagePluginRotaryStateType rotaryStateCCW = EVENT_CLEARED;
volatile int rotaryLevelA = LOW; volatile int rotaryLevelA = LOW;
volatile int rotaryLevelB = LOW; volatile int rotaryLevelB = LOW;
// volatile bool enableEvent = true; int currentMessageIndex = -1;
}; };
extern CannedMessagePlugin *cannedMessagePlugin; extern CannedMessagePlugin *cannedMessagePlugin;