2022-01-04 18:42:28 +00:00
|
|
|
#include "configuration.h"
|
2024-01-12 08:00:31 +00:00
|
|
|
#if ARCH_PORTDUINO
|
2023-12-13 02:27:31 +00:00
|
|
|
#include "PortduinoGlue.h"
|
|
|
|
#endif
|
2022-07-31 12:11:47 +00:00
|
|
|
#if HAS_SCREEN
|
2022-02-27 08:18:35 +00:00
|
|
|
#include "CannedMessageModule.h"
|
2023-12-11 22:49:33 +00:00
|
|
|
#include "Channels.h"
|
2022-02-21 05:29:15 +00:00
|
|
|
#include "FSCommon.h"
|
2022-05-07 10:31:21 +00:00
|
|
|
#include "MeshService.h"
|
2023-01-18 20:51:48 +00:00
|
|
|
#include "NodeDB.h"
|
2023-07-14 21:25:20 +00:00
|
|
|
#include "PowerFSM.h" // needed for button bypass
|
2023-03-09 03:13:46 +00:00
|
|
|
#include "detect/ScanI2C.h"
|
2024-08-06 22:16:56 +00:00
|
|
|
#include "input/ScanAndSelect.h"
|
2023-01-18 14:56:47 +00:00
|
|
|
#include "mesh/generated/meshtastic/cannedmessages.pb.h"
|
Toggle Bluetooth with Fn+b shortcut (#4977)
* Toggle Blutooth with Fn+b shortcut
Problem:
As many are aware, ESP32 devices are known for their high power consumption. For instance, the Heltec ESP32 V3 draws around 110mA when powered on with the screen active and connected to a phone via Bluetooth. The Bluetooth radio alone is responsible for approximately 50mA of that consumption. For keyboard-based standalone devices, which rarely need Bluetooth other than for changing settings, users were forced to keep Bluetooth on regardless of necessity. There was no way to toggle Bluetooth on or off without physically connecting the device to a computer via serial or using the admin channel, which required another node for access.
Solution:
I implemented a new feature that allows users to turn off Bluetooth on keyboard devices by pressing Fn+b and turn it back on when needed. This enhancement significantly improves power efficiency for these devices.
Result:
With Bluetooth off, the device now consumes only 55mA. When combined with Power Save mode, the consumption can drop as low as 11mA, a substantial reduction from the previous 110mA. Users can still easily reconnect to a phone using the shortcut when necessary, offering greater flexibility and extended battery life.
* Remove 1 reboot at least.
I was able to prevent a reboot using the disableBluetooth(); command, current tested at 47-55mA, it doesn't require a reboot to turn off, but it does need reboot to turn back on.
* Update CannedMessageModule.cpp
2024-10-07 20:16:10 +00:00
|
|
|
#include "modules/AdminModule.h"
|
2022-01-04 18:42:28 +00:00
|
|
|
|
2024-04-07 00:12:57 +00:00
|
|
|
#include "main.h" // for cardkb_found
|
|
|
|
#include "modules/ExternalNotificationModule.h" // for buzzer control
|
|
|
|
#if !MESHTASTIC_EXCLUDE_GPS
|
|
|
|
#include "GPS.h"
|
|
|
|
#endif
|
2024-08-02 02:03:59 +00:00
|
|
|
#if defined(USE_EINK) && defined(USE_EINK_DYNAMICDISPLAY)
|
|
|
|
#include "graphics/EInkDynamicDisplay.h" // To select between full and fast refresh on E-Ink displays
|
|
|
|
#endif
|
2023-03-09 03:13:46 +00:00
|
|
|
|
2023-08-07 17:57:47 +00:00
|
|
|
#ifndef INPUTBROKER_MATRIX_TYPE
|
|
|
|
#define INPUTBROKER_MATRIX_TYPE 0
|
|
|
|
#endif
|
|
|
|
|
2024-02-27 18:49:46 +00:00
|
|
|
#include "graphics/ScreenFonts.h"
|
2024-09-23 13:58:14 +00:00
|
|
|
#include <Throttle.h>
|
2022-01-13 07:08:16 +00:00
|
|
|
|
2022-01-13 11:51:36 +00:00
|
|
|
// Remove Canned message screen if no action is taken for some milliseconds
|
|
|
|
#define INACTIVATE_AFTER_MS 20000
|
2022-01-13 07:08:16 +00:00
|
|
|
|
2023-03-09 03:13:46 +00:00
|
|
|
extern ScanI2C::DeviceAddress cardkb_found;
|
2022-11-13 13:56:52 +00:00
|
|
|
|
2022-02-21 05:29:15 +00:00
|
|
|
static const char *cannedMessagesConfigFile = "/prefs/cannedConf.proto";
|
|
|
|
|
2023-01-21 17:22:19 +00:00
|
|
|
meshtastic_CannedMessageModuleConfig cannedMessageModuleConfig;
|
2022-02-21 05:29:15 +00:00
|
|
|
|
2022-02-27 09:20:23 +00:00
|
|
|
CannedMessageModule *cannedMessageModule;
|
2022-01-04 18:42:28 +00:00
|
|
|
|
2022-02-27 09:20:23 +00:00
|
|
|
CannedMessageModule::CannedMessageModule()
|
2024-11-04 18:16:25 +00:00
|
|
|
: SinglePortModule("canned", meshtastic_PortNum_TEXT_MESSAGE_APP), concurrency::OSThread("CannedMessage")
|
2022-01-04 18:42:28 +00:00
|
|
|
{
|
2023-08-16 20:07:22 +00:00
|
|
|
if (moduleConfig.canned_message.enabled || CANNED_MESSAGE_MODULE_ENABLE) {
|
2022-02-27 10:21:02 +00:00
|
|
|
this->loadProtoForModule();
|
2023-08-19 13:37:42 +00:00
|
|
|
if ((this->splitConfiguredMessages() <= 0) && (cardkb_found.address == 0x00) && !INPUTBROKER_MATRIX_TYPE &&
|
|
|
|
!CANNED_MESSAGE_MODULE_ENABLE) {
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_INFO("CannedMessageModule: No messages are configured. Module is disabled");
|
2022-02-21 05:29:15 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
|
2022-12-29 22:26:25 +00:00
|
|
|
disable();
|
2022-05-07 10:31:21 +00:00
|
|
|
} else {
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_INFO("CannedMessageModule is enabled");
|
2024-05-23 12:21:27 +00:00
|
|
|
|
|
|
|
// T-Watch interface currently has no way to select destination type, so default to 'node'
|
2024-06-15 00:36:20 +00:00
|
|
|
#if defined(T_WATCH_S3) || defined(RAK14014)
|
2024-05-23 12:21:27 +00:00
|
|
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
|
|
|
|
#endif
|
|
|
|
|
2022-02-21 05:29:15 +00:00
|
|
|
this->inputObserver.observe(inputBroker);
|
2022-01-12 08:26:42 +00:00
|
|
|
}
|
2022-12-29 14:45:49 +00:00
|
|
|
} else {
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
|
2022-12-29 22:26:25 +00:00
|
|
|
disable();
|
2022-01-11 15:02:55 +00:00
|
|
|
}
|
2022-01-04 18:42:28 +00:00
|
|
|
}
|
|
|
|
|
2022-01-12 08:26:42 +00:00
|
|
|
/**
|
|
|
|
* @brief Items in array this->messages will be set to be pointing on the right
|
2022-01-18 22:15:54 +00:00
|
|
|
* starting points of the string this->messageStore
|
2022-02-21 05:29:15 +00:00
|
|
|
*
|
2022-01-12 08:26:42 +00:00
|
|
|
* @return int Returns the number of messages found.
|
|
|
|
*/
|
2022-08-16 02:06:55 +00:00
|
|
|
// FIXME: This is just one set of messages now
|
2022-02-27 09:20:23 +00:00
|
|
|
int CannedMessageModule::splitConfiguredMessages()
|
2022-01-12 08:26:42 +00:00
|
|
|
{
|
|
|
|
int messageIndex = 0;
|
|
|
|
int i = 0;
|
2022-01-18 22:15:54 +00:00
|
|
|
|
2024-09-26 00:09:06 +00:00
|
|
|
String canned_messages = cannedMessageModuleConfig.messages;
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if defined(T_WATCH_S3) || defined(RAK14014)
|
2024-09-26 00:09:06 +00:00
|
|
|
String separator = canned_messages.length() ? "|" : "";
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2024-09-26 00:09:06 +00:00
|
|
|
canned_messages = "[---- Free Text ----]" + separator + canned_messages;
|
2024-05-24 04:02:03 +00:00
|
|
|
#endif
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2022-02-21 05:29:15 +00:00
|
|
|
// collect all the message parts
|
2024-09-26 00:09:06 +00:00
|
|
|
strncpy(this->messageStore, canned_messages.c_str(), sizeof(this->messageStore));
|
2022-01-18 22:15:54 +00:00
|
|
|
|
2022-02-21 05:29:15 +00:00
|
|
|
// The first message points to the beginning of the store.
|
2022-05-07 10:31:21 +00:00
|
|
|
this->messages[messageIndex++] = this->messageStore;
|
|
|
|
int upTo = strlen(this->messageStore) - 1;
|
|
|
|
|
|
|
|
while (i < upTo) {
|
|
|
|
if (this->messageStore[i] == '|') {
|
2022-01-12 08:26:42 +00:00
|
|
|
// Message ending found, replace it with string-end character.
|
2022-01-18 22:15:54 +00:00
|
|
|
this->messageStore[i] = '\0';
|
2022-01-12 08:26:42 +00:00
|
|
|
|
2022-02-21 05:29:15 +00:00
|
|
|
// hit our max messages, bail
|
2022-05-07 10:31:21 +00:00
|
|
|
if (messageIndex >= CANNED_MESSAGE_MODULE_MESSAGE_MAX_COUNT) {
|
2022-01-12 08:26:42 +00:00
|
|
|
this->messagesCount = messageIndex;
|
|
|
|
return this->messagesCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Next message starts after pipe (|) just found.
|
2022-05-07 10:31:21 +00:00
|
|
|
this->messages[messageIndex++] = (this->messageStore + i + 1);
|
2022-01-12 08:26:42 +00:00
|
|
|
}
|
|
|
|
i += 1;
|
|
|
|
}
|
2022-05-07 10:31:21 +00:00
|
|
|
if (strlen(this->messages[messageIndex - 1]) > 0) {
|
2022-02-21 05:29:15 +00:00
|
|
|
// We have a last message.
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_DEBUG("CannedMessage %d is: '%s'", messageIndex - 1, this->messages[messageIndex - 1]);
|
2022-01-12 08:26:42 +00:00
|
|
|
this->messagesCount = messageIndex;
|
2022-05-07 10:31:21 +00:00
|
|
|
} else {
|
|
|
|
this->messagesCount = messageIndex - 1;
|
2022-01-12 08:26:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return this->messagesCount;
|
|
|
|
}
|
|
|
|
|
2022-02-27 09:20:23 +00:00
|
|
|
int CannedMessageModule::handleInputEvent(const InputEvent *event)
|
2022-01-04 18:42:28 +00:00
|
|
|
{
|
2022-05-22 11:27:56 +00:00
|
|
|
if ((strlen(moduleConfig.canned_message.allow_input_source) > 0) &&
|
2023-07-08 16:32:36 +00:00
|
|
|
(strcasecmp(moduleConfig.canned_message.allow_input_source, event->source) != 0) &&
|
|
|
|
(strcasecmp(moduleConfig.canned_message.allow_input_source, "_any") != 0)) {
|
2022-01-13 13:06:10 +00:00
|
|
|
// Event source is not accepted.
|
2022-02-21 05:29:15 +00:00
|
|
|
// Event only accepted if source matches the configured one, or
|
|
|
|
// the configured one is "_any" (or if there is no configured
|
|
|
|
// source at all)
|
2022-01-11 15:02:55 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2023-12-17 04:20:53 +00:00
|
|
|
if (this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
|
|
|
|
return 0; // Ignore input while sending
|
|
|
|
}
|
2022-01-09 09:08:31 +00:00
|
|
|
bool validEvent = false;
|
2023-01-21 17:22:19 +00:00
|
|
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP)) {
|
2023-12-11 15:00:26 +00:00
|
|
|
if (this->messagesCount > 0) {
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_UP;
|
|
|
|
validEvent = true;
|
|
|
|
}
|
2022-01-09 09:08:31 +00:00
|
|
|
}
|
2023-01-21 17:22:19 +00:00
|
|
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN)) {
|
2023-12-11 15:00:26 +00:00
|
|
|
if (this->messagesCount > 0) {
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_DOWN;
|
|
|
|
validEvent = true;
|
|
|
|
}
|
2022-01-09 09:08:31 +00:00
|
|
|
}
|
2023-01-21 17:22:19 +00:00
|
|
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT)) {
|
2024-05-24 04:02:03 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if defined(T_WATCH_S3) || defined(RAK14014)
|
2024-05-23 12:21:27 +00:00
|
|
|
if (this->currentMessageIndex == 0) {
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
|
|
|
|
2024-07-11 23:51:26 +00:00
|
|
|
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
|
2024-05-23 12:21:27 +00:00
|
|
|
this->notifyObservers(&e);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2024-05-24 04:02:03 +00:00
|
|
|
#endif
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2022-03-25 11:27:14 +00:00
|
|
|
// when inactive, call the onebutton shortpress instead. Activate Module only on up/down
|
|
|
|
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
|
|
|
|
powerFSM.trigger(EVENT_PRESS);
|
2022-05-07 10:31:21 +00:00
|
|
|
} else {
|
2022-09-20 11:50:18 +00:00
|
|
|
this->payload = this->runState;
|
2022-03-25 11:27:14 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
|
|
|
validEvent = true;
|
|
|
|
}
|
2022-01-09 09:08:31 +00:00
|
|
|
}
|
2023-01-21 17:22:19 +00:00
|
|
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL)) {
|
2024-07-11 23:51:26 +00:00
|
|
|
UIFrameEvent e;
|
|
|
|
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
2023-12-13 02:27:31 +00:00
|
|
|
this->currentMessageIndex = -1;
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if !defined(T_WATCH_S3) && !defined(RAK14014)
|
2023-12-13 02:27:31 +00:00
|
|
|
this->freetext = ""; // clear freetext
|
|
|
|
this->cursor = 0;
|
2023-12-13 02:53:14 +00:00
|
|
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
2024-05-23 12:21:27 +00:00
|
|
|
#endif
|
|
|
|
|
2023-12-13 02:27:31 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
|
|
|
this->notifyObservers(&e);
|
2022-09-20 11:50:18 +00:00
|
|
|
}
|
2023-01-21 17:22:19 +00:00
|
|
|
if ((event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK)) ||
|
|
|
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) ||
|
|
|
|
(event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) {
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if defined(T_WATCH_S3) || defined(RAK14014)
|
2024-05-23 12:21:27 +00:00
|
|
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
2024-09-06 02:32:24 +00:00
|
|
|
this->payload = INPUT_BROKER_MSG_LEFT;
|
2024-05-23 12:21:27 +00:00
|
|
|
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
2024-09-06 02:32:24 +00:00
|
|
|
this->payload = INPUT_BROKER_MSG_RIGHT;
|
2024-05-23 12:21:27 +00:00
|
|
|
}
|
|
|
|
#else
|
2023-08-23 07:44:20 +00:00
|
|
|
// tweak for left/right events generated via trackball/touch with empty kbchar
|
2023-07-30 12:51:26 +00:00
|
|
|
if (!event->kbchar) {
|
|
|
|
if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) {
|
2024-09-06 02:32:24 +00:00
|
|
|
this->payload = INPUT_BROKER_MSG_LEFT;
|
2023-07-30 12:51:26 +00:00
|
|
|
} else if (event->inputEvent == static_cast<char>(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT)) {
|
2024-09-06 02:32:24 +00:00
|
|
|
this->payload = INPUT_BROKER_MSG_RIGHT;
|
2023-07-30 12:51:26 +00:00
|
|
|
}
|
|
|
|
} else {
|
2022-09-20 11:50:18 +00:00
|
|
|
// pass the pressed key
|
|
|
|
this->payload = event->kbchar;
|
|
|
|
}
|
2024-05-23 12:21:27 +00:00
|
|
|
#endif
|
|
|
|
|
2023-07-30 12:51:26 +00:00
|
|
|
this->lastTouchMillis = millis();
|
|
|
|
validEvent = true;
|
2022-09-20 11:50:18 +00:00
|
|
|
}
|
|
|
|
if (event->inputEvent == static_cast<char>(ANYKEY)) {
|
|
|
|
// when inactive, this will switch to the freetext mode
|
2023-01-18 20:51:48 +00:00
|
|
|
if ((this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) ||
|
|
|
|
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED)) {
|
2022-09-20 11:50:18 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
|
|
|
}
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
|
|
|
|
validEvent = false; // If key is normal than it will be set to true.
|
|
|
|
|
|
|
|
// Run modifier key code below, (doesnt inturrupt typing or reset to start screen page)
|
|
|
|
switch (event->kbchar) {
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_BRIGHTNESS_UP: // make screen brighter
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
if (screen)
|
|
|
|
screen->increaseBrightness();
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_DEBUG("increasing Screen Brightness");
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
break;
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_BRIGHTNESS_DOWN: // make screen dimmer
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
if (screen)
|
|
|
|
screen->decreaseBrightness();
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_DEBUG("Decreasing Screen Brightness");
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
break;
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_FN_SYMBOL_ON: // draw modifier (function) symbal
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
if (screen)
|
|
|
|
screen->setFunctionSymbal("Fn");
|
|
|
|
break;
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_FN_SYMBOL_OFF: // remove modifier (function) symbal
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
if (screen)
|
|
|
|
screen->removeFunctionSymbal("Fn");
|
|
|
|
break;
|
|
|
|
// mute (switch off/toggle) external notifications on fn+m
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_MUTE_TOGGLE:
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
if (moduleConfig.external_notification.enabled == true) {
|
|
|
|
if (externalNotificationModule->getMute()) {
|
|
|
|
externalNotificationModule->setMute(false);
|
|
|
|
showTemporaryMessage("Notifications \nEnabled");
|
|
|
|
if (screen)
|
|
|
|
screen->removeFunctionSymbal("M"); // remove the mute symbol from the bottom right corner
|
|
|
|
} else {
|
|
|
|
externalNotificationModule->stopNow(); // this will turn off all GPIO and sounds and idle the loop
|
|
|
|
externalNotificationModule->setMute(true);
|
|
|
|
showTemporaryMessage("Notifications \nDisabled");
|
|
|
|
if (screen)
|
|
|
|
screen->setFunctionSymbal("M"); // add the mute symbol to the bottom right corner
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_GPS_TOGGLE: // toggle GPS like triple press does
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
#if !MESHTASTIC_EXCLUDE_GPS
|
|
|
|
if (gps != nullptr) {
|
|
|
|
gps->toggleGpsMode();
|
|
|
|
}
|
|
|
|
if (screen)
|
|
|
|
screen->forceDisplay();
|
|
|
|
showTemporaryMessage("GPS Toggled");
|
|
|
|
#endif
|
|
|
|
break;
|
Toggle Bluetooth with Fn+b shortcut (#4977)
* Toggle Blutooth with Fn+b shortcut
Problem:
As many are aware, ESP32 devices are known for their high power consumption. For instance, the Heltec ESP32 V3 draws around 110mA when powered on with the screen active and connected to a phone via Bluetooth. The Bluetooth radio alone is responsible for approximately 50mA of that consumption. For keyboard-based standalone devices, which rarely need Bluetooth other than for changing settings, users were forced to keep Bluetooth on regardless of necessity. There was no way to toggle Bluetooth on or off without physically connecting the device to a computer via serial or using the admin channel, which required another node for access.
Solution:
I implemented a new feature that allows users to turn off Bluetooth on keyboard devices by pressing Fn+b and turn it back on when needed. This enhancement significantly improves power efficiency for these devices.
Result:
With Bluetooth off, the device now consumes only 55mA. When combined with Power Save mode, the consumption can drop as low as 11mA, a substantial reduction from the previous 110mA. Users can still easily reconnect to a phone using the shortcut when necessary, offering greater flexibility and extended battery life.
* Remove 1 reboot at least.
I was able to prevent a reboot using the disableBluetooth(); command, current tested at 47-55mA, it doesn't require a reboot to turn off, but it does need reboot to turn back on.
* Update CannedMessageModule.cpp
2024-10-07 20:16:10 +00:00
|
|
|
case INPUT_BROKER_MSG_BLUETOOTH_TOGGLE: // toggle Bluetooth on/off
|
|
|
|
if (config.bluetooth.enabled == true) {
|
|
|
|
config.bluetooth.enabled = false;
|
|
|
|
LOG_INFO("User toggled Bluetooth");
|
|
|
|
nodeDB->saveToDisk();
|
|
|
|
disableBluetooth();
|
|
|
|
showTemporaryMessage("Bluetooth OFF");
|
|
|
|
} else if (config.bluetooth.enabled == false) {
|
|
|
|
config.bluetooth.enabled = true;
|
|
|
|
LOG_INFO("User toggled Bluetooth");
|
|
|
|
nodeDB->saveToDisk();
|
|
|
|
rebootAtMsec = millis() + 2000;
|
|
|
|
showTemporaryMessage("Bluetooth ON\nReboot");
|
|
|
|
}
|
|
|
|
break;
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_SEND_PING: // fn+space send network ping like double press does
|
2024-08-02 00:29:49 +00:00
|
|
|
service->refreshLocalMeshNode();
|
|
|
|
if (service->trySendPosition(NODENUM_BROADCAST, true)) {
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
showTemporaryMessage("Position \nUpdate Sent");
|
|
|
|
} else {
|
|
|
|
showTemporaryMessage("Node Info \nUpdate Sent");
|
|
|
|
}
|
|
|
|
break;
|
2024-09-25 11:27:04 +00:00
|
|
|
case INPUT_BROKER_MSG_DISMISS_FRAME: // fn+del: dismiss screen frames like text or waypoint
|
|
|
|
// Avoid opening the canned message screen frame
|
|
|
|
// We're only handling the keypress here by convention, this has nothing to do with canned messages
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
|
|
|
// Attempt to close whatever frame is currently shown on display
|
|
|
|
screen->dismissCurrentFrame();
|
|
|
|
return 0;
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
default:
|
|
|
|
// pass the pressed key
|
2024-10-14 04:11:43 +00:00
|
|
|
// LOG_DEBUG("Canned message ANYKEY (%x)", event->kbchar);
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
this->payload = event->kbchar;
|
|
|
|
this->lastTouchMillis = millis();
|
|
|
|
validEvent = true;
|
|
|
|
break;
|
|
|
|
}
|
2024-09-06 02:32:24 +00:00
|
|
|
if (screen && (event->kbchar != INPUT_BROKER_MSG_FN_SYMBOL_ON)) {
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
screen->removeFunctionSymbal("Fn"); // remove modifier (function) symbal
|
|
|
|
}
|
2022-09-20 11:50:18 +00:00
|
|
|
}
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if defined(T_WATCH_S3) || defined(RAK14014)
|
2024-05-23 12:21:27 +00:00
|
|
|
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
|
|
|
String keyTapped = keyForCoordinates(event->touchX, event->touchY);
|
|
|
|
|
|
|
|
if (keyTapped == "⇧") {
|
|
|
|
this->highlight = -1;
|
|
|
|
|
|
|
|
this->payload = 0x00;
|
|
|
|
|
|
|
|
validEvent = true;
|
|
|
|
|
|
|
|
this->shift = !this->shift;
|
|
|
|
} else if (keyTapped == "⌫") {
|
|
|
|
this->highlight = keyTapped[0];
|
|
|
|
|
|
|
|
this->payload = 0x08;
|
|
|
|
|
|
|
|
validEvent = true;
|
|
|
|
|
|
|
|
this->shift = false;
|
|
|
|
} else if (keyTapped == "123" || keyTapped == "ABC") {
|
|
|
|
this->highlight = -1;
|
|
|
|
|
|
|
|
this->payload = 0x00;
|
|
|
|
|
|
|
|
this->charSet = this->charSet == 0 ? 1 : 0;
|
|
|
|
|
|
|
|
validEvent = true;
|
|
|
|
} else if (keyTapped == " ") {
|
|
|
|
this->highlight = keyTapped[0];
|
|
|
|
|
|
|
|
this->payload = keyTapped[0];
|
|
|
|
|
|
|
|
validEvent = true;
|
|
|
|
|
|
|
|
this->shift = false;
|
|
|
|
} else if (keyTapped == "↵") {
|
|
|
|
this->highlight = 0x00;
|
|
|
|
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
|
|
|
|
|
|
|
this->payload = CANNED_MESSAGE_RUN_STATE_FREETEXT;
|
|
|
|
|
|
|
|
this->currentMessageIndex = event->kbchar - 1;
|
|
|
|
|
|
|
|
validEvent = true;
|
|
|
|
|
|
|
|
this->shift = false;
|
|
|
|
} else if (keyTapped != "") {
|
|
|
|
this->highlight = keyTapped[0];
|
|
|
|
|
|
|
|
this->payload = this->shift ? keyTapped[0] : std::tolower(keyTapped[0]);
|
|
|
|
|
|
|
|
validEvent = true;
|
|
|
|
|
|
|
|
this->shift = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2022-10-06 14:00:33 +00:00
|
|
|
if (event->inputEvent == static_cast<char>(MATRIXKEY)) {
|
|
|
|
// this will send the text immediately on matrix press
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTION_SELECT;
|
2022-11-20 19:59:48 +00:00
|
|
|
this->payload = MATRIXKEY;
|
2023-01-18 20:51:48 +00:00
|
|
|
this->currentMessageIndex = event->kbchar - 1;
|
2022-10-06 14:00:33 +00:00
|
|
|
this->lastTouchMillis = millis();
|
|
|
|
validEvent = true;
|
|
|
|
}
|
2022-01-04 18:42:28 +00:00
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
if (validEvent) {
|
2024-07-11 23:51:26 +00:00
|
|
|
requestFocus(); // Tell Screen::setFrames to move to our module's frame, next time it runs
|
|
|
|
|
2022-01-09 09:08:31 +00:00
|
|
|
// Let runOnce to be called immediately.
|
2023-12-13 02:27:31 +00:00
|
|
|
if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
|
|
|
setIntervalFromNow(0); // on fast keypresses, this isn't fast enough.
|
|
|
|
} else {
|
|
|
|
runOnce();
|
|
|
|
}
|
2022-01-09 09:08:31 +00:00
|
|
|
}
|
2022-01-04 18:42:28 +00:00
|
|
|
|
2022-01-09 09:08:31 +00:00
|
|
|
return 0;
|
2022-01-04 18:42:28 +00:00
|
|
|
}
|
|
|
|
|
2023-12-11 22:49:33 +00:00
|
|
|
void CannedMessageModule::sendText(NodeNum dest, ChannelIndex channel, const char *message, bool wantReplies)
|
2022-01-04 18:42:28 +00:00
|
|
|
{
|
2023-01-21 17:22:19 +00:00
|
|
|
meshtastic_MeshPacket *p = allocDataPacket();
|
2022-01-04 18:42:28 +00:00
|
|
|
p->to = dest;
|
2023-12-11 22:49:33 +00:00
|
|
|
p->channel = channel;
|
2022-01-13 11:51:36 +00:00
|
|
|
p->want_ack = true;
|
2022-01-04 21:02:16 +00:00
|
|
|
p->decoded.payload.size = strlen(message);
|
|
|
|
memcpy(p->decoded.payload.bytes, message, p->decoded.payload.size);
|
2023-08-08 18:02:29 +00:00
|
|
|
if (moduleConfig.canned_message.send_bell && p->decoded.payload.size < meshtastic_Constants_DATA_PAYLOAD_LEN) {
|
2023-08-08 16:06:39 +00:00
|
|
|
p->decoded.payload.bytes[p->decoded.payload.size] = 7; // Bell character
|
|
|
|
p->decoded.payload.bytes[p->decoded.payload.size + 1] = '\0'; // Bell character
|
2022-01-12 08:26:42 +00:00
|
|
|
p->decoded.payload.size++;
|
|
|
|
}
|
|
|
|
|
2024-07-11 23:51:26 +00:00
|
|
|
// 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;
|
|
|
|
|
2024-11-04 18:16:25 +00:00
|
|
|
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
|
2022-01-04 18:42:28 +00:00
|
|
|
|
2024-08-02 00:29:49 +00:00
|
|
|
service->sendToMesh(
|
2023-12-11 14:11:10 +00:00
|
|
|
p, RX_SRC_LOCAL,
|
|
|
|
true); // send to mesh, cc to phone. Even if there's no phone connected, this stores the message to match ACKs
|
2022-01-04 18:42:28 +00:00
|
|
|
}
|
|
|
|
|
2022-02-27 09:20:23 +00:00
|
|
|
int32_t CannedMessageModule::runOnce()
|
2022-01-04 18:42:28 +00:00
|
|
|
{
|
2023-08-16 20:07:22 +00:00
|
|
|
if (((!moduleConfig.canned_message.enabled) && !CANNED_MESSAGE_MODULE_ENABLE) ||
|
|
|
|
(this->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) || (this->runState == CANNED_MESSAGE_RUN_STATE_INACTIVE)) {
|
2024-04-27 16:08:25 +00:00
|
|
|
temporaryMessage = "";
|
2022-10-06 14:00:33 +00:00
|
|
|
return INT32_MAX;
|
2022-01-12 08:26:42 +00:00
|
|
|
}
|
2024-10-14 04:11:43 +00:00
|
|
|
// LOG_DEBUG("Check status");
|
2024-07-11 23:51:26 +00:00
|
|
|
UIFrameEvent e;
|
2023-08-22 14:23:02 +00:00
|
|
|
if ((this->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) ||
|
2024-04-27 16:08:25 +00:00
|
|
|
(this->runState == CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED) || (this->runState == CANNED_MESSAGE_RUN_STATE_MESSAGE)) {
|
2024-04-27 13:54:06 +00:00
|
|
|
// TODO: might have some feedback of sending state
|
2022-01-19 08:55:06 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
2024-04-27 16:08:25 +00:00
|
|
|
temporaryMessage = "";
|
2024-07-11 23:51:26 +00:00
|
|
|
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
2022-01-19 08:55:06 +00:00
|
|
|
this->currentMessageIndex = -1;
|
2022-09-20 11:50:18 +00:00
|
|
|
this->freetext = ""; // clear freetext
|
2022-09-20 14:21:32 +00:00
|
|
|
this->cursor = 0;
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if !defined(T_WATCH_S3) && !defined(RAK14014)
|
2023-12-11 22:49:33 +00:00
|
|
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
2024-05-23 12:21:27 +00:00
|
|
|
#endif
|
|
|
|
|
2022-01-19 08:55:06 +00:00
|
|
|
this->notifyObservers(&e);
|
2023-01-18 20:51:48 +00:00
|
|
|
} else if (((this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) || (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT)) &&
|
2024-09-23 13:58:14 +00:00
|
|
|
!Throttle::isWithinTimespanMs(this->lastTouchMillis, INACTIVATE_AFTER_MS)) {
|
2022-02-27 08:29:05 +00:00
|
|
|
// Reset module
|
2024-07-11 23:51:26 +00:00
|
|
|
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
2022-01-19 08:55:06 +00:00
|
|
|
this->currentMessageIndex = -1;
|
2022-09-20 11:50:18 +00:00
|
|
|
this->freetext = ""; // clear freetext
|
2022-09-20 14:21:32 +00:00
|
|
|
this->cursor = 0;
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if !defined(T_WATCH_S3) && !defined(RAK14014)
|
2023-12-11 22:49:33 +00:00
|
|
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
2024-05-23 12:21:27 +00:00
|
|
|
#endif
|
|
|
|
|
2022-01-19 08:55:06 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
2022-01-13 08:19:36 +00:00
|
|
|
this->notifyObservers(&e);
|
2022-05-07 10:31:21 +00:00
|
|
|
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_SELECT) {
|
2022-09-20 11:50:18 +00:00
|
|
|
if (this->payload == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
2022-09-21 08:42:10 +00:00
|
|
|
if (this->freetext.length() > 0) {
|
2023-12-11 22:49:33 +00:00
|
|
|
sendText(this->dest, indexChannels[this->channel], this->freetext.c_str(), true);
|
2022-09-21 08:42:10 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
|
|
|
} else {
|
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
|
|
|
}
|
2022-09-20 11:50:18 +00:00
|
|
|
} else {
|
2022-10-06 14:00:33 +00:00
|
|
|
if ((this->messagesCount > this->currentMessageIndex) && (strlen(this->messages[this->currentMessageIndex]) > 0)) {
|
2023-01-18 20:51:48 +00:00
|
|
|
if (strcmp(this->messages[this->currentMessageIndex], "~") == 0) {
|
2022-11-20 19:59:48 +00:00
|
|
|
powerFSM.trigger(EVENT_PRESS);
|
|
|
|
return INT32_MAX;
|
|
|
|
} else {
|
2024-06-15 00:36:20 +00:00
|
|
|
#if defined(T_WATCH_S3) || defined(RAK14014)
|
2024-05-23 12:21:27 +00:00
|
|
|
sendText(this->dest, indexChannels[this->channel], this->messages[this->currentMessageIndex], true);
|
|
|
|
#else
|
2023-12-11 22:49:33 +00:00
|
|
|
sendText(NODENUM_BROADCAST, channels.getPrimaryIndex(), this->messages[this->currentMessageIndex], true);
|
2024-05-23 12:21:27 +00:00
|
|
|
#endif
|
2022-11-20 19:59:48 +00:00
|
|
|
}
|
2022-09-21 08:42:10 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE;
|
|
|
|
} else {
|
2024-11-04 12:09:23 +00:00
|
|
|
// LOG_DEBUG("Reset message is empty");
|
2022-09-21 08:42:10 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
|
|
|
}
|
2022-09-20 11:50:18 +00:00
|
|
|
}
|
2024-07-11 23:51:26 +00:00
|
|
|
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
2022-01-04 21:02:16 +00:00
|
|
|
this->currentMessageIndex = -1;
|
2022-09-20 11:50:18 +00:00
|
|
|
this->freetext = ""; // clear freetext
|
2022-09-20 14:21:32 +00:00
|
|
|
this->cursor = 0;
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if !defined(T_WATCH_S3) && !defined(RAK14014)
|
2023-12-11 22:49:33 +00:00
|
|
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
2024-05-23 12:21:27 +00:00
|
|
|
#endif
|
|
|
|
|
2022-01-13 08:19:36 +00:00
|
|
|
this->notifyObservers(&e);
|
2022-01-04 21:02:16 +00:00
|
|
|
return 2000;
|
2023-01-18 20:51:48 +00:00
|
|
|
} else if ((this->runState != CANNED_MESSAGE_RUN_STATE_FREETEXT) && (this->currentMessageIndex == -1)) {
|
2022-09-20 11:50:18 +00:00
|
|
|
this->currentMessageIndex = 0;
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_DEBUG("First touch (%d):%s", this->currentMessageIndex, this->getCurrentMessage());
|
2024-07-11 23:51:26 +00:00
|
|
|
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
2022-09-20 11:50:18 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
2022-05-07 10:31:21 +00:00
|
|
|
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_UP) {
|
2022-10-08 09:20:54 +00:00
|
|
|
if (this->messagesCount > 0) {
|
|
|
|
this->currentMessageIndex = getPrevIndex();
|
|
|
|
this->freetext = ""; // clear freetext
|
|
|
|
this->cursor = 0;
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if !defined(T_WATCH_S3) && !defined(RAK14014)
|
2023-12-11 22:49:33 +00:00
|
|
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
2024-05-23 12:21:27 +00:00
|
|
|
#endif
|
|
|
|
|
2022-10-08 09:20:54 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_DEBUG("MOVE UP (%d):%s", this->currentMessageIndex, this->getCurrentMessage());
|
2022-10-08 09:20:54 +00:00
|
|
|
}
|
2022-05-07 10:31:21 +00:00
|
|
|
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTION_DOWN) {
|
2022-10-08 09:20:54 +00:00
|
|
|
if (this->messagesCount > 0) {
|
|
|
|
this->currentMessageIndex = this->getNextIndex();
|
|
|
|
this->freetext = ""; // clear freetext
|
|
|
|
this->cursor = 0;
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if !defined(T_WATCH_S3) && !defined(RAK14014)
|
2023-12-11 22:49:33 +00:00
|
|
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
2024-05-23 12:21:27 +00:00
|
|
|
#endif
|
|
|
|
|
2022-10-08 09:20:54 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACTIVE;
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_DEBUG("MOVE DOWN (%d):%s", this->currentMessageIndex, this->getCurrentMessage());
|
2022-10-08 09:20:54 +00:00
|
|
|
}
|
2023-07-30 12:51:26 +00:00
|
|
|
} else if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT || this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) {
|
2022-09-20 11:50:18 +00:00
|
|
|
switch (this->payload) {
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_LEFT:
|
2023-12-11 22:49:33 +00:00
|
|
|
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
|
2024-03-21 14:06:37 +00:00
|
|
|
size_t numMeshNodes = nodeDB->getNumMeshNodes();
|
2023-01-18 20:51:48 +00:00
|
|
|
if (this->dest == NODENUM_BROADCAST) {
|
2024-03-21 14:06:37 +00:00
|
|
|
this->dest = nodeDB->getNodeNum();
|
2022-09-20 14:21:32 +00:00
|
|
|
}
|
2023-06-17 14:10:09 +00:00
|
|
|
for (unsigned int i = 0; i < numMeshNodes; i++) {
|
2024-03-21 14:06:37 +00:00
|
|
|
if (nodeDB->getMeshNodeByIndex(i)->num == this->dest) {
|
2023-06-17 14:10:09 +00:00
|
|
|
this->dest =
|
2024-03-21 14:06:37 +00:00
|
|
|
(i > 0) ? nodeDB->getMeshNodeByIndex(i - 1)->num : nodeDB->getMeshNodeByIndex(numMeshNodes - 1)->num;
|
2023-01-18 20:51:48 +00:00
|
|
|
break;
|
2022-10-07 16:40:15 +00:00
|
|
|
}
|
2022-09-20 14:21:32 +00:00
|
|
|
}
|
2024-03-21 14:06:37 +00:00
|
|
|
if (this->dest == nodeDB->getNodeNum()) {
|
2023-01-18 20:51:48 +00:00
|
|
|
this->dest = NODENUM_BROADCAST;
|
|
|
|
}
|
2023-12-11 22:49:33 +00:00
|
|
|
} 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--;
|
|
|
|
}
|
2023-01-18 20:51:48 +00:00
|
|
|
} else {
|
|
|
|
if (this->cursor > 0) {
|
2022-09-20 14:21:32 +00:00
|
|
|
this->cursor--;
|
2022-09-20 11:50:18 +00:00
|
|
|
}
|
2023-01-18 20:51:48 +00:00
|
|
|
}
|
|
|
|
break;
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_RIGHT:
|
2023-12-11 22:49:33 +00:00
|
|
|
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
|
2024-03-21 14:06:37 +00:00
|
|
|
size_t numMeshNodes = nodeDB->getNumMeshNodes();
|
2023-01-18 20:51:48 +00:00
|
|
|
if (this->dest == NODENUM_BROADCAST) {
|
2024-03-21 14:06:37 +00:00
|
|
|
this->dest = nodeDB->getNodeNum();
|
2022-10-06 20:34:55 +00:00
|
|
|
}
|
2023-06-17 14:10:09 +00:00
|
|
|
for (unsigned int i = 0; i < numMeshNodes; i++) {
|
2024-03-21 14:06:37 +00:00
|
|
|
if (nodeDB->getMeshNodeByIndex(i)->num == this->dest) {
|
2023-06-17 14:10:09 +00:00
|
|
|
this->dest =
|
2024-03-21 14:06:37 +00:00
|
|
|
(i < numMeshNodes - 1) ? nodeDB->getMeshNodeByIndex(i + 1)->num : nodeDB->getMeshNodeByIndex(0)->num;
|
2023-01-18 20:51:48 +00:00
|
|
|
break;
|
|
|
|
}
|
2022-09-20 14:21:32 +00:00
|
|
|
}
|
2024-03-21 14:06:37 +00:00
|
|
|
if (this->dest == nodeDB->getNodeNum()) {
|
2023-01-18 20:51:48 +00:00
|
|
|
this->dest = NODENUM_BROADCAST;
|
2022-09-20 14:21:32 +00:00
|
|
|
}
|
2023-12-11 22:49:33 +00:00
|
|
|
} 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++;
|
|
|
|
}
|
2023-01-18 20:51:48 +00:00
|
|
|
} else {
|
|
|
|
if (this->cursor < this->freetext.length()) {
|
|
|
|
this->cursor++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2023-07-30 12:51:26 +00:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (this->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
2024-07-11 23:51:26 +00:00
|
|
|
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
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
|
2024-05-23 12:21:27 +00:00
|
|
|
if (this->freetext.length() > 0 && this->highlight == 0x00) {
|
2023-07-30 12:51:26 +00:00
|
|
|
if (this->cursor == this->freetext.length()) {
|
|
|
|
this->freetext = this->freetext.substring(0, this->freetext.length() - 1);
|
|
|
|
} else {
|
|
|
|
this->freetext = this->freetext.substring(0, this->cursor - 1) +
|
|
|
|
this->freetext.substring(this->cursor, this->freetext.length());
|
|
|
|
}
|
|
|
|
this->cursor--;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x09: // tab
|
2023-12-11 22:49:33 +00:00
|
|
|
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL) {
|
|
|
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NONE;
|
|
|
|
} else if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NODE) {
|
|
|
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_CHANNEL;
|
2023-07-30 12:51:26 +00:00
|
|
|
} else {
|
2023-12-11 22:49:33 +00:00
|
|
|
this->destSelect = CANNED_MESSAGE_DESTINATION_TYPE_NODE;
|
2023-07-30 12:51:26 +00:00
|
|
|
}
|
|
|
|
break;
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_LEFT:
|
|
|
|
case INPUT_BROKER_MSG_RIGHT:
|
2023-07-30 12:51:26 +00:00
|
|
|
// already handled above
|
|
|
|
break;
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
// handle fn+s for shutdown
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_SHUTDOWN:
|
2024-04-07 00:12:57 +00:00
|
|
|
if (screen)
|
2024-06-25 16:26:02 +00:00
|
|
|
screen->startAlert("Shutting down...");
|
2024-03-24 18:41:45 +00:00
|
|
|
shutdownAtMsec = millis() + DEFAULT_SHUTDOWN_SECONDS * 1000;
|
2024-04-07 00:12:57 +00:00
|
|
|
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
2024-03-24 18:41:45 +00:00
|
|
|
break;
|
|
|
|
// and fn+r for reboot
|
2024-09-06 02:32:24 +00:00
|
|
|
case INPUT_BROKER_MSG_REBOOT:
|
2024-04-07 00:12:57 +00:00
|
|
|
if (screen)
|
2024-06-25 16:26:02 +00:00
|
|
|
screen->startAlert("Rebooting...");
|
2024-03-24 18:41:45 +00:00
|
|
|
rebootAtMsec = millis() + DEFAULT_REBOOT_SECONDS * 1000;
|
2024-04-07 00:12:57 +00:00
|
|
|
runState = CANNED_MESSAGE_RUN_STATE_INACTIVE;
|
|
|
|
break;
|
2023-07-30 12:51:26 +00:00
|
|
|
default:
|
2024-05-23 12:21:27 +00:00
|
|
|
if (this->highlight != 0x00) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-01-18 20:51:48 +00:00
|
|
|
if (this->cursor == this->freetext.length()) {
|
2023-07-30 12:51:26 +00:00
|
|
|
this->freetext += this->payload;
|
2023-01-18 20:51:48 +00:00
|
|
|
} else {
|
2023-07-30 12:51:26 +00:00
|
|
|
this->freetext =
|
|
|
|
this->freetext.substring(0, this->cursor) + this->payload + this->freetext.substring(this->cursor);
|
2023-01-18 20:51:48 +00:00
|
|
|
}
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2023-07-30 12:51:26 +00:00
|
|
|
this->cursor += 1;
|
2024-05-23 12:21:27 +00:00
|
|
|
|
2023-08-08 18:14:12 +00:00
|
|
|
uint16_t maxChars = meshtastic_Constants_DATA_PAYLOAD_LEN - (moduleConfig.canned_message.send_bell ? 1 : 0);
|
|
|
|
if (this->freetext.length() > maxChars) {
|
|
|
|
this->cursor = maxChars;
|
|
|
|
this->freetext = this->freetext.substring(0, maxChars);
|
2023-07-30 12:51:26 +00:00
|
|
|
}
|
|
|
|
break;
|
2023-01-18 20:51:48 +00:00
|
|
|
}
|
Added modifier key combination to allow keyboard shortcuts on t-deck (#3668)
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Updated kbI2cBase.cpp
Updated keyboard settings for t-deck to allow a modifier key to trigger 'tab', mute notifications, or quit. To trigger the modifier press the shift key and mic (0) button at the same time. Then press q (quit), m (mute), or t (tab).
* Update kbI2cBase.cpp
* fixed formatting issues in kbI2cBase.cpp
* Removed keyboard shortcut code that doesnt work
alt+t does not work on a t-deck so I removed it to avoid confusion.
* Changed modifier key to alt+c
* Added screen brightness functionality
Use modifier key with o(+) to increase brightness or i(-) to decrease.
Currently there are 4 levels of brightness, (L, ML, MH, H). I would like to add a popup message to tell you the brightness.
* Added checks to disable screen brightness changes on unsupported hardware
* Setting the brightness code to work on only applicable devices
* Added "function symbol" display to bottom right corner of screen. Now shows when mute is active or modifier key is pressed. Also fixed some other minor issues.
* commented out a log
* Reworked how modifier functions worked, added
I wasn’t happy with my previous implementation, and I think it would have caused issues with other devices. This should work on all devices.
* Added back the function I moved causing issue with versions
* Fixed the version conflicts, everything seems to work fine now
---------
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
2024-05-08 12:37:50 +00:00
|
|
|
if (screen)
|
|
|
|
screen->removeFunctionSymbal("Fn");
|
2022-09-20 11:50:18 +00:00
|
|
|
}
|
2023-01-18 20:51:48 +00:00
|
|
|
|
2022-09-20 11:50:18 +00:00
|
|
|
this->lastTouchMillis = millis();
|
|
|
|
this->notifyObservers(&e);
|
|
|
|
return INACTIVATE_AFTER_MS;
|
2022-01-04 18:42:28 +00:00
|
|
|
}
|
2022-01-19 08:55:06 +00:00
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
if (this->runState == CANNED_MESSAGE_RUN_STATE_ACTIVE) {
|
2022-01-13 11:51:36 +00:00
|
|
|
this->lastTouchMillis = millis();
|
2022-01-13 08:19:36 +00:00
|
|
|
this->notifyObservers(&e);
|
2022-01-13 11:51:36 +00:00
|
|
|
return INACTIVATE_AFTER_MS;
|
|
|
|
}
|
2022-01-04 18:43:06 +00:00
|
|
|
|
2023-01-18 20:51:48 +00:00
|
|
|
return INT32_MAX;
|
2022-01-04 18:42:28 +00:00
|
|
|
}
|
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
const char *CannedMessageModule::getCurrentMessage()
|
2022-01-04 18:42:28 +00:00
|
|
|
{
|
2022-01-12 08:26:42 +00:00
|
|
|
return this->messages[this->currentMessageIndex];
|
2022-01-09 09:08:31 +00:00
|
|
|
}
|
2022-05-07 10:31:21 +00:00
|
|
|
const char *CannedMessageModule::getPrevMessage()
|
2022-01-09 09:08:31 +00:00
|
|
|
{
|
2022-01-12 08:26:42 +00:00
|
|
|
return this->messages[this->getPrevIndex()];
|
2022-01-09 09:08:31 +00:00
|
|
|
}
|
2022-05-07 10:31:21 +00:00
|
|
|
const char *CannedMessageModule::getNextMessage()
|
2022-01-09 09:08:31 +00:00
|
|
|
{
|
2022-01-12 08:26:42 +00:00
|
|
|
return this->messages[this->getNextIndex()];
|
2022-01-09 09:08:31 +00:00
|
|
|
}
|
2023-07-30 12:51:26 +00:00
|
|
|
const char *CannedMessageModule::getMessageByIndex(int index)
|
|
|
|
{
|
|
|
|
return (index >= 0 && index < this->messagesCount) ? this->messages[index] : "";
|
|
|
|
}
|
|
|
|
|
2023-01-18 20:51:48 +00:00
|
|
|
const char *CannedMessageModule::getNodeName(NodeNum node)
|
|
|
|
{
|
|
|
|
if (node == NODENUM_BROADCAST) {
|
2022-10-07 16:40:15 +00:00
|
|
|
return "Broadcast";
|
2023-01-18 20:51:48 +00:00
|
|
|
} else {
|
2024-03-21 14:06:37 +00:00
|
|
|
meshtastic_NodeInfoLite *info = nodeDB->getMeshNode(node);
|
2023-01-18 20:51:48 +00:00
|
|
|
if (info != NULL) {
|
2022-10-07 16:40:15 +00:00
|
|
|
return info->user.long_name;
|
2023-01-18 20:51:48 +00:00
|
|
|
} else {
|
2022-10-07 16:40:15 +00:00
|
|
|
return "Unknown";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-27 09:20:23 +00:00
|
|
|
bool CannedMessageModule::shouldDraw()
|
2022-01-09 09:08:31 +00:00
|
|
|
{
|
2023-08-16 20:07:22 +00:00
|
|
|
if (!moduleConfig.canned_message.enabled && !CANNED_MESSAGE_MODULE_ENABLE) {
|
2022-01-13 07:08:16 +00:00
|
|
|
return false;
|
|
|
|
}
|
2024-08-06 22:16:56 +00:00
|
|
|
|
|
|
|
// If using "scan and select" input, don't draw the module frame just to say "disabled"
|
|
|
|
// The scanAndSelectInput class will draw its own temporary alert for user, when the input button is pressed
|
|
|
|
else if (scanAndSelectInput != nullptr && !hasMessages())
|
|
|
|
return false;
|
|
|
|
|
2022-01-19 08:55:06 +00:00
|
|
|
return (currentMessageIndex != -1) || (this->runState != CANNED_MESSAGE_RUN_STATE_INACTIVE);
|
2022-01-04 18:42:28 +00:00
|
|
|
}
|
|
|
|
|
2024-08-06 22:16:56 +00:00
|
|
|
// Has the user defined any canned messages?
|
|
|
|
// Expose publicly whether canned message module is ready for use
|
|
|
|
bool CannedMessageModule::hasMessages()
|
|
|
|
{
|
|
|
|
return (this->messagesCount > 0);
|
|
|
|
}
|
|
|
|
|
2022-02-27 09:20:23 +00:00
|
|
|
int CannedMessageModule::getNextIndex()
|
2022-01-04 18:42:28 +00:00
|
|
|
{
|
2022-05-07 10:31:21 +00:00
|
|
|
if (this->currentMessageIndex >= (this->messagesCount - 1)) {
|
2022-01-09 09:08:31 +00:00
|
|
|
return 0;
|
2022-05-07 10:31:21 +00:00
|
|
|
} else {
|
2022-01-09 09:08:31 +00:00
|
|
|
return this->currentMessageIndex + 1;
|
2022-01-04 18:42:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-27 09:20:23 +00:00
|
|
|
int CannedMessageModule::getPrevIndex()
|
2022-01-04 18:42:28 +00:00
|
|
|
{
|
2022-05-07 10:31:21 +00:00
|
|
|
if (this->currentMessageIndex <= 0) {
|
2022-01-12 08:26:42 +00:00
|
|
|
return this->messagesCount - 1;
|
2022-05-07 10:31:21 +00:00
|
|
|
} else {
|
2022-01-09 09:08:31 +00:00
|
|
|
return this->currentMessageIndex - 1;
|
2022-01-04 18:42:28 +00:00
|
|
|
}
|
2022-01-13 07:08:16 +00:00
|
|
|
}
|
2024-04-27 16:08:25 +00:00
|
|
|
void CannedMessageModule::showTemporaryMessage(const String &message)
|
|
|
|
{
|
|
|
|
temporaryMessage = message;
|
2024-07-11 23:51:26 +00:00
|
|
|
UIFrameEvent e;
|
|
|
|
e.action = UIFrameEvent::Action::REGENERATE_FRAMESET; // We want to change the list of frames shown on-screen
|
2024-04-27 16:08:25 +00:00
|
|
|
notifyObservers(&e);
|
|
|
|
runState = CANNED_MESSAGE_RUN_STATE_MESSAGE;
|
|
|
|
// run this loop again in 2 seconds, next iteration will clear the display
|
|
|
|
setIntervalFromNow(2000);
|
|
|
|
}
|
2022-01-13 07:08:16 +00:00
|
|
|
|
2024-06-15 00:36:20 +00:00
|
|
|
#if defined(T_WATCH_S3) || defined(RAK14014)
|
2024-05-23 12:21:27 +00:00
|
|
|
|
|
|
|
String CannedMessageModule::keyForCoordinates(uint x, uint y)
|
|
|
|
{
|
|
|
|
int outerSize = *(&this->keyboard[this->charSet] + 1) - this->keyboard[this->charSet];
|
|
|
|
|
|
|
|
for (int8_t outerIndex = 0; outerIndex < outerSize; outerIndex++) {
|
|
|
|
int innerSize = *(&this->keyboard[this->charSet][outerIndex] + 1) - this->keyboard[this->charSet][outerIndex];
|
|
|
|
|
|
|
|
for (int8_t innerIndex = 0; innerIndex < innerSize; innerIndex++) {
|
|
|
|
Letter letter = this->keyboard[this->charSet][outerIndex][innerIndex];
|
|
|
|
|
|
|
|
if (x > letter.rectX && x < (letter.rectX + letter.rectWidth) && y > letter.rectY &&
|
|
|
|
y < (letter.rectY + letter.rectHeight)) {
|
|
|
|
return letter.character;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
void CannedMessageModule::drawKeyboard(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
|
|
|
{
|
|
|
|
int outerSize = *(&this->keyboard[this->charSet] + 1) - this->keyboard[this->charSet];
|
|
|
|
|
|
|
|
int xOffset = 0;
|
|
|
|
|
|
|
|
int yOffset = 56;
|
|
|
|
|
|
|
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
|
|
|
|
|
|
|
display->setFont(FONT_SMALL);
|
|
|
|
|
|
|
|
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
|
|
|
|
|
|
|
display->drawStringMaxWidth(0, 0, display->getWidth(),
|
|
|
|
cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
|
|
|
|
|
|
|
|
display->setFont(FONT_MEDIUM);
|
|
|
|
|
|
|
|
int cellHeight = round((display->height() - 64) / outerSize);
|
|
|
|
|
|
|
|
int yCorrection = 8;
|
|
|
|
|
|
|
|
for (int8_t outerIndex = 0; outerIndex < outerSize; outerIndex++) {
|
|
|
|
yOffset += outerIndex > 0 ? cellHeight : 0;
|
|
|
|
|
|
|
|
int innerSizeBound = *(&this->keyboard[this->charSet][outerIndex] + 1) - this->keyboard[this->charSet][outerIndex];
|
|
|
|
|
|
|
|
int innerSize = 0;
|
|
|
|
|
|
|
|
for (int8_t innerIndex = 0; innerIndex < innerSizeBound; innerIndex++) {
|
|
|
|
if (this->keyboard[this->charSet][outerIndex][innerIndex].character != "") {
|
|
|
|
innerSize++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int cellWidth = display->width() / innerSize;
|
|
|
|
|
|
|
|
for (int8_t innerIndex = 0; innerIndex < innerSize; innerIndex++) {
|
|
|
|
xOffset += innerIndex > 0 ? cellWidth : 0;
|
|
|
|
|
|
|
|
Letter letter = this->keyboard[this->charSet][outerIndex][innerIndex];
|
|
|
|
|
|
|
|
Letter updatedLetter = {letter.character, letter.width, xOffset, yOffset, cellWidth, cellHeight};
|
|
|
|
|
|
|
|
this->keyboard[this->charSet][outerIndex][innerIndex] = updatedLetter;
|
|
|
|
|
|
|
|
float characterOffset = ((cellWidth / 2) - (letter.width / 2));
|
|
|
|
|
|
|
|
if (letter.character == "⇧") {
|
|
|
|
if (this->shift) {
|
|
|
|
display->fillRect(xOffset, yOffset, cellWidth, cellHeight);
|
|
|
|
|
|
|
|
display->setColor(OLEDDISPLAY_COLOR::BLACK);
|
|
|
|
|
|
|
|
drawShiftIcon(display, xOffset + characterOffset, yOffset + yCorrection + 5, 1.2);
|
|
|
|
|
|
|
|
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
|
|
|
} else {
|
|
|
|
display->drawRect(xOffset, yOffset, cellWidth, cellHeight);
|
|
|
|
|
|
|
|
drawShiftIcon(display, xOffset + characterOffset, yOffset + yCorrection + 5, 1.2);
|
|
|
|
}
|
|
|
|
} else if (letter.character == "⌫") {
|
|
|
|
if (this->highlight == letter.character[0]) {
|
|
|
|
display->fillRect(xOffset, yOffset, cellWidth, cellHeight);
|
|
|
|
|
|
|
|
display->setColor(OLEDDISPLAY_COLOR::BLACK);
|
|
|
|
|
|
|
|
drawBackspaceIcon(display, xOffset + characterOffset, yOffset + yCorrection + 5, 1.2);
|
|
|
|
|
|
|
|
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
|
|
|
|
|
|
|
setIntervalFromNow(0);
|
|
|
|
} else {
|
|
|
|
display->drawRect(xOffset, yOffset, cellWidth, cellHeight);
|
|
|
|
|
|
|
|
drawBackspaceIcon(display, xOffset + characterOffset, yOffset + yCorrection + 5, 1.2);
|
|
|
|
}
|
|
|
|
} else if (letter.character == "↵") {
|
|
|
|
display->drawRect(xOffset, yOffset, cellWidth, cellHeight);
|
|
|
|
|
|
|
|
drawEnterIcon(display, xOffset + characterOffset, yOffset + yCorrection + 5, 1.7);
|
|
|
|
} else {
|
|
|
|
if (this->highlight == letter.character[0]) {
|
|
|
|
display->fillRect(xOffset, yOffset, cellWidth, cellHeight);
|
|
|
|
|
|
|
|
display->setColor(OLEDDISPLAY_COLOR::BLACK);
|
|
|
|
|
|
|
|
display->drawString(xOffset + characterOffset, yOffset + yCorrection,
|
|
|
|
letter.character == " " ? "space" : letter.character);
|
|
|
|
|
|
|
|
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
|
|
|
|
|
|
|
setIntervalFromNow(0);
|
|
|
|
} else {
|
|
|
|
display->drawRect(xOffset, yOffset, cellWidth, cellHeight);
|
|
|
|
|
|
|
|
display->drawString(xOffset + characterOffset, yOffset + yCorrection,
|
|
|
|
letter.character == " " ? "space" : letter.character);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
xOffset = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
this->highlight = 0x00;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CannedMessageModule::drawShiftIcon(OLEDDisplay *display, int x, int y, float scale)
|
|
|
|
{
|
|
|
|
PointStruct shiftIcon[10] = {{8, 0}, {15, 7}, {15, 8}, {12, 8}, {12, 12}, {4, 12}, {4, 8}, {1, 8}, {1, 7}, {8, 0}};
|
|
|
|
|
|
|
|
int size = 10;
|
|
|
|
|
|
|
|
for (int i = 0; i < size - 1; i++) {
|
|
|
|
int x0 = x + (shiftIcon[i].x * scale);
|
|
|
|
int y0 = y + (shiftIcon[i].y * scale);
|
|
|
|
int x1 = x + (shiftIcon[i + 1].x * scale);
|
|
|
|
int y1 = y + (shiftIcon[i + 1].y * scale);
|
|
|
|
|
|
|
|
display->drawLine(x0, y0, x1, y1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CannedMessageModule::drawBackspaceIcon(OLEDDisplay *display, int x, int y, float scale)
|
|
|
|
{
|
|
|
|
PointStruct backspaceIcon[6] = {{0, 7}, {5, 2}, {15, 2}, {15, 12}, {5, 12}, {0, 7}};
|
|
|
|
|
|
|
|
int size = 6;
|
|
|
|
|
|
|
|
for (int i = 0; i < size - 1; i++) {
|
|
|
|
int x0 = x + (backspaceIcon[i].x * scale);
|
|
|
|
int y0 = y + (backspaceIcon[i].y * scale);
|
|
|
|
int x1 = x + (backspaceIcon[i + 1].x * scale);
|
|
|
|
int y1 = y + (backspaceIcon[i + 1].y * scale);
|
|
|
|
|
|
|
|
display->drawLine(x0, y0, x1, y1);
|
|
|
|
}
|
|
|
|
|
|
|
|
PointStruct backspaceIconX[4] = {{7, 4}, {13, 10}, {7, 10}, {13, 4}};
|
|
|
|
|
|
|
|
size = 4;
|
|
|
|
|
|
|
|
for (int i = 0; i < size - 1; i++) {
|
|
|
|
int x0 = x + (backspaceIconX[i].x * scale);
|
|
|
|
int y0 = y + (backspaceIconX[i].y * scale);
|
|
|
|
int x1 = x + (backspaceIconX[i + 1].x * scale);
|
|
|
|
int y1 = y + (backspaceIconX[i + 1].y * scale);
|
|
|
|
|
|
|
|
display->drawLine(x0, y0, x1, y1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CannedMessageModule::drawEnterIcon(OLEDDisplay *display, int x, int y, float scale)
|
|
|
|
{
|
|
|
|
PointStruct enterIcon[6] = {{0, 7}, {4, 3}, {4, 11}, {0, 7}, {15, 7}, {15, 0}};
|
|
|
|
|
|
|
|
int size = 6;
|
|
|
|
|
|
|
|
for (int i = 0; i < size - 1; i++) {
|
|
|
|
int x0 = x + (enterIcon[i].x * scale);
|
|
|
|
int y0 = y + (enterIcon[i].y * scale);
|
|
|
|
int x1 = x + (enterIcon[i + 1].x * scale);
|
|
|
|
int y1 = y + (enterIcon[i + 1].y * scale);
|
|
|
|
|
|
|
|
display->drawLine(x0, y0, x1, y1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2024-09-25 11:27:04 +00:00
|
|
|
// Indicate to screen class that module is handling keyboard input specially (at certain times)
|
|
|
|
// This prevents the left & right keys being used for nav. between screen frames during text entry.
|
|
|
|
bool CannedMessageModule::interceptingKeyboardInput()
|
|
|
|
{
|
|
|
|
switch (runState) {
|
|
|
|
case CANNED_MESSAGE_RUN_STATE_DISABLED:
|
|
|
|
case CANNED_MESSAGE_RUN_STATE_INACTIVE:
|
|
|
|
return false;
|
|
|
|
default:
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
void CannedMessageModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
2022-01-13 07:08:16 +00:00
|
|
|
{
|
2022-10-13 13:22:57 +00:00
|
|
|
char buffer[50];
|
|
|
|
|
2024-04-27 16:08:25 +00:00
|
|
|
if (temporaryMessage.length() != 0) {
|
2024-07-11 23:51:26 +00:00
|
|
|
requestFocus(); // Tell Screen::setFrames to move to our module's frame
|
2024-04-27 16:08:25 +00:00
|
|
|
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) {
|
2024-08-06 22:16:56 +00:00
|
|
|
requestFocus(); // Tell Screen::setFrames to move to our module's frame
|
|
|
|
EINK_ADD_FRAMEFLAG(display, COSMETIC); // Clean after this popup. Layout makes ghosting particularly obvious
|
|
|
|
|
|
|
|
#ifdef USE_EINK
|
|
|
|
display->setFont(FONT_SMALL); // No chunky text
|
|
|
|
#else
|
|
|
|
display->setFont(FONT_MEDIUM); // Chunky text
|
|
|
|
#endif
|
2024-08-02 02:03:59 +00:00
|
|
|
|
2023-08-22 18:29:52 +00:00
|
|
|
String displayString;
|
2024-08-06 22:16:56 +00:00
|
|
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
2023-12-11 14:11:10 +00:00
|
|
|
if (this->ack) {
|
2023-08-22 18:29:52 +00:00
|
|
|
displayString = "Delivered to\n%s";
|
2023-12-11 14:11:10 +00:00
|
|
|
} else {
|
2023-08-22 18:29:52 +00:00
|
|
|
displayString = "Delivery failed\nto %s";
|
2023-12-11 14:11:10 +00:00
|
|
|
}
|
2023-08-22 18:29:52 +00:00
|
|
|
display->drawStringf(display->getWidth() / 2 + x, 0 + y + 12, buffer, displayString,
|
2023-08-22 14:23:02 +00:00
|
|
|
cannedMessageModule->getNodeName(this->incoming));
|
2024-05-23 12:21:27 +00:00
|
|
|
|
|
|
|
display->setFont(FONT_SMALL);
|
|
|
|
|
|
|
|
String snrString = "Last Rx SNR: %f";
|
|
|
|
String rssiString = "Last Rx RSSI: %d";
|
|
|
|
|
2024-08-06 22:16:56 +00:00
|
|
|
// Don't bother drawing snr and rssi for tiny displays
|
|
|
|
if (display->getHeight() > 100) {
|
|
|
|
|
|
|
|
// Original implementation used constants of y = 100 and y = 130. Shrink this if screen is *slightly* small
|
|
|
|
int16_t snrY = 100;
|
|
|
|
int16_t rssiY = 130;
|
|
|
|
|
|
|
|
// If dislay is *slighly* too small for the original consants, squish up a bit
|
2024-10-02 10:37:08 +00:00
|
|
|
if (display->getHeight() < rssiY + FONT_HEIGHT_SMALL) {
|
2024-08-06 22:16:56 +00:00
|
|
|
snrY = display->getHeight() - ((1.5) * FONT_HEIGHT_SMALL);
|
|
|
|
rssiY = display->getHeight() - ((2.5) * FONT_HEIGHT_SMALL);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this->ack) {
|
|
|
|
display->drawStringf(display->getWidth() / 2 + x, snrY + y, buffer, snrString, this->lastRxSnr);
|
|
|
|
display->drawStringf(display->getWidth() / 2 + x, rssiY + y, buffer, rssiString, this->lastRxRssi);
|
|
|
|
}
|
2024-05-23 12:21:27 +00:00
|
|
|
}
|
2023-08-22 14:23:02 +00:00
|
|
|
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_SENDING_ACTIVE) {
|
2024-08-02 02:03:59 +00:00
|
|
|
// E-Ink: clean the screen *after* this pop-up
|
|
|
|
EINK_ADD_FRAMEFLAG(display, COSMETIC);
|
|
|
|
|
2024-07-11 23:51:26 +00:00
|
|
|
requestFocus(); // Tell Screen::setFrames to move to our module's frame
|
2024-08-06 22:16:56 +00:00
|
|
|
|
|
|
|
#ifdef USE_EINK
|
|
|
|
display->setFont(FONT_SMALL); // No chunky text
|
|
|
|
#else
|
|
|
|
display->setFont(FONT_MEDIUM); // Chunky text
|
|
|
|
#endif
|
|
|
|
|
2022-01-19 08:55:06 +00:00
|
|
|
display->setTextAlignment(TEXT_ALIGN_CENTER);
|
2022-05-07 10:31:21 +00:00
|
|
|
display->drawString(display->getWidth() / 2 + x, 0 + y + 12, "Sending...");
|
|
|
|
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_DISABLED) {
|
2022-03-31 12:59:42 +00:00
|
|
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
|
|
|
display->setFont(FONT_SMALL);
|
2022-09-20 14:21:32 +00:00
|
|
|
display->drawString(10 + x, 0 + y + FONT_HEIGHT_SMALL, "Canned Message\nModule disabled.");
|
2023-01-18 20:51:48 +00:00
|
|
|
} else if (cannedMessageModule->runState == CANNED_MESSAGE_RUN_STATE_FREETEXT) {
|
2024-07-11 23:51:26 +00:00
|
|
|
requestFocus(); // Tell Screen::setFrames to move to our module's frame
|
2024-06-15 00:36:20 +00:00
|
|
|
#if defined(T_WATCH_S3) || defined(RAK14014)
|
2024-05-23 12:21:27 +00:00
|
|
|
drawKeyboard(display, state, 0, 0);
|
|
|
|
#else
|
|
|
|
|
2022-09-20 11:50:18 +00:00
|
|
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
2022-10-06 15:24:08 +00:00
|
|
|
display->setFont(FONT_SMALL);
|
2023-12-11 22:49:33 +00:00
|
|
|
if (this->destSelect != CANNED_MESSAGE_DESTINATION_TYPE_NONE) {
|
2022-10-07 16:40:15 +00:00
|
|
|
display->fillRect(0 + x, 0 + y, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
|
|
|
display->setColor(BLACK);
|
|
|
|
}
|
2023-12-11 22:49:33 +00:00
|
|
|
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:
|
2023-12-12 21:28:50 +00:00
|
|
|
if (display->getWidth() > 128) {
|
|
|
|
display->drawStringf(0 + x, 0 + y, buffer, "To: %s@%s", cannedMessageModule->getNodeName(this->dest),
|
|
|
|
channels.getName(indexChannels[this->channel]));
|
|
|
|
} else {
|
|
|
|
display->drawStringf(0 + x, 0 + y, buffer, "To: %.5s@%.5s", cannedMessageModule->getNodeName(this->dest),
|
|
|
|
channels.getName(indexChannels[this->channel]));
|
|
|
|
}
|
2023-12-11 22:49:33 +00:00
|
|
|
break;
|
|
|
|
}
|
2023-12-12 21:28:50 +00:00
|
|
|
// used chars right aligned, only when not editing the destination
|
|
|
|
if (this->destSelect == CANNED_MESSAGE_DESTINATION_TYPE_NONE) {
|
|
|
|
uint16_t charsLeft =
|
|
|
|
meshtastic_Constants_DATA_PAYLOAD_LEN - this->freetext.length() - (moduleConfig.canned_message.send_bell ? 1 : 0);
|
|
|
|
snprintf(buffer, sizeof(buffer), "%d left", charsLeft);
|
|
|
|
display->drawString(x + display->getWidth() - display->getStringWidth(buffer), y + 0, buffer);
|
2022-12-18 13:47:28 +00:00
|
|
|
}
|
2022-10-07 16:40:15 +00:00
|
|
|
display->setColor(WHITE);
|
2023-01-18 20:51:48 +00:00
|
|
|
display->drawStringMaxWidth(
|
|
|
|
0 + x, 0 + y + FONT_HEIGHT_SMALL, x + display->getWidth(),
|
|
|
|
cannedMessageModule->drawWithCursor(cannedMessageModule->freetext, cannedMessageModule->cursor));
|
2024-05-23 12:21:27 +00:00
|
|
|
#endif
|
2022-05-07 10:31:21 +00:00
|
|
|
} else {
|
2022-10-08 12:52:21 +00:00
|
|
|
if (this->messagesCount > 0) {
|
|
|
|
display->setTextAlignment(TEXT_ALIGN_LEFT);
|
|
|
|
display->setFont(FONT_SMALL);
|
2022-10-13 13:22:57 +00:00
|
|
|
display->drawStringf(0 + x, 0 + y, buffer, "To: %s", cannedMessageModule->getNodeName(this->dest));
|
2023-07-30 12:51:26 +00:00
|
|
|
int lines = (display->getHeight() / FONT_HEIGHT_SMALL) - 1;
|
|
|
|
if (lines == 3) {
|
|
|
|
// static (old) behavior for small displays
|
|
|
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL, cannedMessageModule->getPrevMessage());
|
|
|
|
display->fillRect(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, x + display->getWidth(), y + FONT_HEIGHT_SMALL);
|
|
|
|
display->setColor(BLACK);
|
|
|
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 2, cannedMessageModule->getCurrentMessage());
|
|
|
|
display->setColor(WHITE);
|
|
|
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * 3, cannedMessageModule->getNextMessage());
|
|
|
|
} else {
|
|
|
|
// use entire display height for larger displays
|
|
|
|
int topMsg = (messagesCount > lines && currentMessageIndex >= lines - 1) ? currentMessageIndex - lines + 2 : 0;
|
|
|
|
for (int i = 0; i < std::min(messagesCount, lines); i++) {
|
|
|
|
if (i == currentMessageIndex - topMsg) {
|
2024-08-06 22:16:56 +00:00
|
|
|
#ifdef USE_EINK
|
|
|
|
// Avoid drawing solid black with fillRect: harder to clear for E-Ink
|
|
|
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * (i + 1), ">");
|
|
|
|
display->drawString(12 + x, 0 + y + FONT_HEIGHT_SMALL * (i + 1),
|
|
|
|
cannedMessageModule->getCurrentMessage());
|
|
|
|
#else
|
2023-07-30 12:51:26 +00:00
|
|
|
display->fillRect(0 + x, 0 + y + FONT_HEIGHT_SMALL * (i + 1), x + display->getWidth(),
|
|
|
|
y + FONT_HEIGHT_SMALL);
|
|
|
|
display->setColor(BLACK);
|
|
|
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * (i + 1), cannedMessageModule->getCurrentMessage());
|
|
|
|
display->setColor(WHITE);
|
2024-08-06 22:16:56 +00:00
|
|
|
#endif
|
2023-07-30 12:51:26 +00:00
|
|
|
} else {
|
|
|
|
display->drawString(0 + x, 0 + y + FONT_HEIGHT_SMALL * (i + 1),
|
|
|
|
cannedMessageModule->getMessageByIndex(topMsg + i));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-10-08 12:52:21 +00:00
|
|
|
}
|
2022-01-13 07:08:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-22 14:23:02 +00:00
|
|
|
ProcessMessage CannedMessageModule::handleReceived(const meshtastic_MeshPacket &mp)
|
|
|
|
{
|
2024-07-11 23:51:26 +00:00
|
|
|
if (mp.decoded.portnum == meshtastic_PortNum_ROUTING_APP && waitingForAck) {
|
2023-08-22 14:23:02 +00:00
|
|
|
// look for a request_id
|
|
|
|
if (mp.decoded.request_id != 0) {
|
2024-07-11 23:51:26 +00:00
|
|
|
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
|
2023-12-11 14:11:10 +00:00
|
|
|
this->runState = CANNED_MESSAGE_RUN_STATE_ACK_NACK_RECEIVED;
|
2024-08-02 00:29:49 +00:00
|
|
|
this->incoming = service->getNodenumFromRequestId(mp.decoded.request_id);
|
2023-08-22 18:29:52 +00:00
|
|
|
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;
|
2024-07-11 23:51:26 +00:00
|
|
|
waitingForAck = false; // No longer want routing packets
|
2023-08-22 14:23:02 +00:00
|
|
|
this->notifyObservers(&e);
|
|
|
|
// run the next time 2 seconds later
|
|
|
|
setIntervalFromNow(2000);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ProcessMessage::CONTINUE;
|
|
|
|
}
|
|
|
|
|
2022-02-27 10:21:02 +00:00
|
|
|
void CannedMessageModule::loadProtoForModule()
|
2022-02-21 05:29:15 +00:00
|
|
|
{
|
2024-04-15 12:22:05 +00:00
|
|
|
if (nodeDB->loadProto(cannedMessagesConfigFile, meshtastic_CannedMessageModuleConfig_size,
|
|
|
|
sizeof(meshtastic_CannedMessageModuleConfig), &meshtastic_CannedMessageModuleConfig_msg,
|
2024-07-26 01:16:21 +00:00
|
|
|
&cannedMessageModuleConfig) != LoadFileResult::LOAD_SUCCESS) {
|
2022-02-27 09:20:23 +00:00
|
|
|
installDefaultCannedMessageModuleConfig();
|
2022-02-21 05:29:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
2022-02-27 08:29:05 +00:00
|
|
|
* @brief Save the module config to file.
|
2022-02-21 05:29:15 +00:00
|
|
|
*
|
|
|
|
* @return true On success.
|
|
|
|
* @return false On error.
|
|
|
|
*/
|
2022-02-27 10:21:02 +00:00
|
|
|
bool CannedMessageModule::saveProtoForModule()
|
2022-02-21 05:29:15 +00:00
|
|
|
{
|
|
|
|
bool okay = true;
|
|
|
|
|
|
|
|
#ifdef FS
|
|
|
|
FS.mkdir("/prefs");
|
|
|
|
#endif
|
|
|
|
|
2024-03-21 14:06:37 +00:00
|
|
|
okay &= nodeDB->saveProto(cannedMessagesConfigFile, meshtastic_CannedMessageModuleConfig_size,
|
|
|
|
&meshtastic_CannedMessageModuleConfig_msg, &cannedMessageModuleConfig);
|
2022-02-21 05:29:15 +00:00
|
|
|
|
|
|
|
return okay;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Fill configuration with default values.
|
|
|
|
*/
|
2022-02-27 09:20:23 +00:00
|
|
|
void CannedMessageModule::installDefaultCannedMessageModuleConfig()
|
2022-02-21 05:29:15 +00:00
|
|
|
{
|
2022-08-16 02:06:55 +00:00
|
|
|
memset(cannedMessageModuleConfig.messages, 0, sizeof(cannedMessageModuleConfig.messages));
|
2022-02-21 05:29:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-02-27 10:21:02 +00:00
|
|
|
* @brief An admin message arrived to AdminModule. We are asked whether we want to handle that.
|
2022-02-21 05:29:15 +00:00
|
|
|
*
|
|
|
|
* @param mp The mesh packet arrived.
|
|
|
|
* @param request The AdminMessage request extracted from the packet.
|
|
|
|
* @param response The prepared response
|
|
|
|
* @return AdminMessageHandleResult HANDLED if message was handled
|
|
|
|
* HANDLED_WITH_RESULT if a result is also prepared.
|
|
|
|
*/
|
2023-01-21 17:39:58 +00:00
|
|
|
AdminMessageHandleResult CannedMessageModule::handleAdminMessageForModule(const meshtastic_MeshPacket &mp,
|
|
|
|
meshtastic_AdminMessage *request,
|
2023-01-21 17:22:19 +00:00
|
|
|
meshtastic_AdminMessage *response)
|
2022-02-21 05:29:15 +00:00
|
|
|
{
|
|
|
|
AdminMessageHandleResult result;
|
|
|
|
|
2022-09-09 10:51:41 +00:00
|
|
|
switch (request->which_payload_variant) {
|
2023-01-21 17:22:19 +00:00
|
|
|
case meshtastic_AdminMessage_get_canned_message_module_messages_request_tag:
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_DEBUG("Client is getting radio canned messages");
|
2022-08-16 02:06:55 +00:00
|
|
|
this->handleGetCannedMessageModuleMessages(mp, response);
|
2022-02-21 05:29:15 +00:00
|
|
|
result = AdminMessageHandleResult::HANDLED_WITH_RESPONSE;
|
|
|
|
break;
|
|
|
|
|
2023-01-21 17:22:19 +00:00
|
|
|
case meshtastic_AdminMessage_set_canned_message_module_messages_tag:
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_DEBUG("Client is setting radio canned messages");
|
2022-08-16 02:06:55 +00:00
|
|
|
this->handleSetCannedMessageModuleMessages(request->set_canned_message_module_messages);
|
2022-02-21 05:29:15 +00:00
|
|
|
result = AdminMessageHandleResult::HANDLED;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
result = AdminMessageHandleResult::NOT_HANDLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2023-01-21 17:39:58 +00:00
|
|
|
void CannedMessageModule::handleGetCannedMessageModuleMessages(const meshtastic_MeshPacket &req,
|
|
|
|
meshtastic_AdminMessage *response)
|
2022-02-21 05:29:15 +00:00
|
|
|
{
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_DEBUG("*** handleGetCannedMessageModuleMessages");
|
2023-01-18 20:51:48 +00:00
|
|
|
if (req.decoded.want_response) {
|
2023-01-21 17:22:19 +00:00
|
|
|
response->which_payload_variant = meshtastic_AdminMessage_get_canned_message_module_messages_response_tag;
|
2023-01-18 20:51:48 +00:00
|
|
|
strncpy(response->get_canned_message_module_messages_response, cannedMessageModuleConfig.messages,
|
|
|
|
sizeof(response->get_canned_message_module_messages_response));
|
2023-01-07 14:24:46 +00:00
|
|
|
} // Don't send anything if not instructed to. Better than asserting.
|
2022-02-21 05:29:15 +00:00
|
|
|
}
|
|
|
|
|
2022-08-16 02:06:55 +00:00
|
|
|
void CannedMessageModule::handleSetCannedMessageModuleMessages(const char *from_msg)
|
2022-02-21 05:29:15 +00:00
|
|
|
{
|
|
|
|
int changed = 0;
|
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
if (*from_msg) {
|
2022-08-16 02:06:55 +00:00
|
|
|
changed |= strcmp(cannedMessageModuleConfig.messages, from_msg);
|
2023-01-16 09:55:40 +00:00
|
|
|
strncpy(cannedMessageModuleConfig.messages, from_msg, sizeof(cannedMessageModuleConfig.messages));
|
2024-10-14 04:11:43 +00:00
|
|
|
LOG_DEBUG("*** from_msg.text:%s", from_msg);
|
2022-02-21 05:29:15 +00:00
|
|
|
}
|
|
|
|
|
2022-05-07 10:31:21 +00:00
|
|
|
if (changed) {
|
2022-02-27 10:21:02 +00:00
|
|
|
this->saveProtoForModule();
|
2022-02-21 05:29:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-20 14:21:32 +00:00
|
|
|
String CannedMessageModule::drawWithCursor(String text, int cursor)
|
|
|
|
{
|
2023-01-18 20:51:48 +00:00
|
|
|
String result = text.substring(0, cursor) + "_" + text.substring(cursor);
|
2022-09-20 14:21:32 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2024-11-04 12:09:23 +00:00
|
|
|
#endif
|