mirror of
https://github.com/meshtastic/firmware.git
synced 2025-07-31 19:05:44 +00:00
BaseUI Updates (#7358)
Some checks failed
CI / setup (check) (push) Has been cancelled
CI / setup (esp32) (push) Has been cancelled
CI / setup (esp32c3) (push) Has been cancelled
CI / setup (esp32c6) (push) Has been cancelled
CI / setup (esp32s3) (push) Has been cancelled
CI / setup (nrf52840) (push) Has been cancelled
CI / setup (rp2040) (push) Has been cancelled
CI / setup (stm32) (push) Has been cancelled
CI / build-debian-src (push) Has been cancelled
CI / package-pio-deps-native-tft (push) Has been cancelled
CI / test-native (push) Has been cancelled
CI / docker-deb-amd64 (push) Has been cancelled
CI / docker-deb-amd64-tft (push) Has been cancelled
CI / docker-alp-amd64 (push) Has been cancelled
CI / docker-alp-amd64-tft (push) Has been cancelled
CI / docker-deb-arm64 (push) Has been cancelled
CI / docker-deb-armv7 (push) Has been cancelled
CI / check (push) Has been cancelled
CI / build-esp32 (push) Has been cancelled
CI / build-esp32-s3 (push) Has been cancelled
CI / build-esp32-c3 (push) Has been cancelled
CI / build-esp32-c6 (push) Has been cancelled
CI / build-nrf52 (push) Has been cancelled
CI / build-rpi2040 (push) Has been cancelled
CI / build-stm32 (push) Has been cancelled
CI / gather-artifacts (esp32) (push) Has been cancelled
CI / gather-artifacts (esp32c3) (push) Has been cancelled
CI / gather-artifacts (esp32c6) (push) Has been cancelled
CI / gather-artifacts (esp32s3) (push) Has been cancelled
CI / gather-artifacts (nrf52840) (push) Has been cancelled
CI / gather-artifacts (rp2040) (push) Has been cancelled
CI / gather-artifacts (stm32) (push) Has been cancelled
CI / release-artifacts (push) Has been cancelled
CI / release-firmware (esp32) (push) Has been cancelled
CI / release-firmware (esp32c3) (push) Has been cancelled
CI / release-firmware (esp32c6) (push) Has been cancelled
CI / release-firmware (esp32s3) (push) Has been cancelled
CI / release-firmware (nrf52840) (push) Has been cancelled
CI / release-firmware (rp2040) (push) Has been cancelled
CI / release-firmware (stm32) (push) Has been cancelled
CI / publish-firmware (push) Has been cancelled
Nightly / Trunk Check and Upload (push) Has been cancelled
Nightly / Trunk Upgrade (PR) (push) Has been cancelled
Some checks failed
CI / setup (check) (push) Has been cancelled
CI / setup (esp32) (push) Has been cancelled
CI / setup (esp32c3) (push) Has been cancelled
CI / setup (esp32c6) (push) Has been cancelled
CI / setup (esp32s3) (push) Has been cancelled
CI / setup (nrf52840) (push) Has been cancelled
CI / setup (rp2040) (push) Has been cancelled
CI / setup (stm32) (push) Has been cancelled
CI / build-debian-src (push) Has been cancelled
CI / package-pio-deps-native-tft (push) Has been cancelled
CI / test-native (push) Has been cancelled
CI / docker-deb-amd64 (push) Has been cancelled
CI / docker-deb-amd64-tft (push) Has been cancelled
CI / docker-alp-amd64 (push) Has been cancelled
CI / docker-alp-amd64-tft (push) Has been cancelled
CI / docker-deb-arm64 (push) Has been cancelled
CI / docker-deb-armv7 (push) Has been cancelled
CI / check (push) Has been cancelled
CI / build-esp32 (push) Has been cancelled
CI / build-esp32-s3 (push) Has been cancelled
CI / build-esp32-c3 (push) Has been cancelled
CI / build-esp32-c6 (push) Has been cancelled
CI / build-nrf52 (push) Has been cancelled
CI / build-rpi2040 (push) Has been cancelled
CI / build-stm32 (push) Has been cancelled
CI / gather-artifacts (esp32) (push) Has been cancelled
CI / gather-artifacts (esp32c3) (push) Has been cancelled
CI / gather-artifacts (esp32c6) (push) Has been cancelled
CI / gather-artifacts (esp32s3) (push) Has been cancelled
CI / gather-artifacts (nrf52840) (push) Has been cancelled
CI / gather-artifacts (rp2040) (push) Has been cancelled
CI / gather-artifacts (stm32) (push) Has been cancelled
CI / release-artifacts (push) Has been cancelled
CI / release-firmware (esp32) (push) Has been cancelled
CI / release-firmware (esp32c3) (push) Has been cancelled
CI / release-firmware (esp32c6) (push) Has been cancelled
CI / release-firmware (esp32s3) (push) Has been cancelled
CI / release-firmware (nrf52840) (push) Has been cancelled
CI / release-firmware (rp2040) (push) Has been cancelled
CI / release-firmware (stm32) (push) Has been cancelled
CI / publish-firmware (push) Has been cancelled
Nightly / Trunk Check and Upload (push) Has been cancelled
Nightly / Trunk Upgrade (PR) (push) Has been cancelled
* Calculate the length of the right string and use it * Improve readability of Version Number * Prevent negative message IDs and proactively favorite DM'd nodes * Patch up Remove Favorite functionality * Fix warnings for TFT_MESH_* and hasSupportBrightness * Fix warning around casting variables * Correct Favorite Node Behavior to rebuild favorite nodes when updated. * Resolve bool kb_found issue not working for second discovery keyboards --------- Co-authored-by: Jonathan Bennett <jbennett@incomsystems.biz>
This commit is contained in:
parent
55fc4fcd90
commit
71b6508ad3
@ -864,6 +864,8 @@ void Screen::setFrames(FrameFocus focus)
|
|||||||
uint8_t previousFrameCount = framesetInfo.frameCount;
|
uint8_t previousFrameCount = framesetInfo.frameCount;
|
||||||
FramesetInfo fsi; // Location of specific frames, for applying focus parameter
|
FramesetInfo fsi; // Location of specific frames, for applying focus parameter
|
||||||
|
|
||||||
|
graphics::UIRenderer::rebuildFavoritedNodes();
|
||||||
|
|
||||||
LOG_DEBUG("Show standard frames");
|
LOG_DEBUG("Show standard frames");
|
||||||
showingNormalScreen = true;
|
showingNormalScreen = true;
|
||||||
|
|
||||||
|
@ -483,7 +483,7 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ****************************
|
// ****************************
|
||||||
// * Memory Screen *
|
// * System Screen *
|
||||||
// ****************************
|
// ****************************
|
||||||
void drawMemoryUsage(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
void drawMemoryUsage(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
@ -593,7 +593,19 @@ void drawMemoryUsage(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
|
|||||||
}
|
}
|
||||||
line += 1;
|
line += 1;
|
||||||
char appversionstr[35];
|
char appversionstr[35];
|
||||||
snprintf(appversionstr, sizeof(appversionstr), "Ver.: %s", optstr(APP_VERSION));
|
snprintf(appversionstr, sizeof(appversionstr), "Ver: %s", optstr(APP_VERSION));
|
||||||
|
char appversionstr_formatted[40];
|
||||||
|
char *lastDot = strrchr(appversionstr, '.');
|
||||||
|
if (lastDot) {
|
||||||
|
size_t prefixLen = lastDot - appversionstr;
|
||||||
|
strncpy(appversionstr_formatted, appversionstr, prefixLen);
|
||||||
|
appversionstr_formatted[prefixLen] = '\0';
|
||||||
|
strncat(appversionstr_formatted, " (", sizeof(appversionstr_formatted) - strlen(appversionstr_formatted) - 1);
|
||||||
|
strncat(appversionstr_formatted, lastDot + 1, sizeof(appversionstr_formatted) - strlen(appversionstr_formatted) - 1);
|
||||||
|
strncat(appversionstr_formatted, ")", sizeof(appversionstr_formatted) - strlen(appversionstr_formatted) - 1);
|
||||||
|
strncpy(appversionstr, appversionstr_formatted, sizeof(appversionstr) - 1);
|
||||||
|
appversionstr[sizeof(appversionstr) - 1] = '\0';
|
||||||
|
}
|
||||||
int textWidth = display->getStringWidth(appversionstr);
|
int textWidth = display->getStringWidth(appversionstr);
|
||||||
int nameX = (SCREEN_WIDTH - textWidth) / 2;
|
int nameX = (SCREEN_WIDTH - textWidth) / 2;
|
||||||
display->drawString(nameX, getTextPositions(display)[line], appversionstr);
|
display->drawString(nameX, getTextPositions(display)[line], appversionstr);
|
||||||
|
@ -375,12 +375,6 @@ void menuHandler::textMessageBaseMenu()
|
|||||||
|
|
||||||
void menuHandler::systemBaseMenu()
|
void menuHandler::systemBaseMenu()
|
||||||
{
|
{
|
||||||
// Check if brightness is supported
|
|
||||||
bool hasSupportBrightness = false;
|
|
||||||
#if defined(ST7789_CS) || defined(USE_OLED) || defined(USE_SSD1306) || defined(USE_SH1106) || defined(USE_SH1107) || HAS_TFT
|
|
||||||
hasSupportBrightness = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum optionsNumbers { Back, Notifications, ScreenOptions, PowerMenu, Test, enumEnd };
|
enum optionsNumbers { Back, Notifications, ScreenOptions, PowerMenu, Test, enumEnd };
|
||||||
static const char *optionsArray[enumEnd] = {"Back"};
|
static const char *optionsArray[enumEnd] = {"Back"};
|
||||||
static int optionsEnumArray[enumEnd] = {Back};
|
static int optionsEnumArray[enumEnd] = {Back};
|
||||||
@ -450,11 +444,11 @@ void menuHandler::favoriteBaseMenu()
|
|||||||
bannerOptions.optionsEnumPtr = optionsEnumArray;
|
bannerOptions.optionsEnumPtr = optionsEnumArray;
|
||||||
bannerOptions.optionsCount = options;
|
bannerOptions.optionsCount = options;
|
||||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||||
if (selected == 1) {
|
if (selected == Preset) {
|
||||||
cannedMessageModule->LaunchWithDestination(graphics::UIRenderer::currentFavoriteNodeNum);
|
cannedMessageModule->LaunchWithDestination(graphics::UIRenderer::currentFavoriteNodeNum);
|
||||||
} else if (selected == 2 && kb_found) {
|
} else if (selected == Freetext) {
|
||||||
cannedMessageModule->LaunchFreetextWithDestination(graphics::UIRenderer::currentFavoriteNodeNum);
|
cannedMessageModule->LaunchFreetextWithDestination(graphics::UIRenderer::currentFavoriteNodeNum);
|
||||||
} else if ((!kb_found && selected == 2) || (selected == 3 && kb_found)) {
|
} else if (selected == Remove) {
|
||||||
menuHandler::menuQueue = menuHandler::remove_favorite;
|
menuHandler::menuQueue = menuHandler::remove_favorite;
|
||||||
screen->runNow();
|
screen->runNow();
|
||||||
}
|
}
|
||||||
@ -707,6 +701,7 @@ void menuHandler::TFTColorPickerMenu(OLEDDisplay *display)
|
|||||||
bannerOptions.optionsArrayPtr = optionsArray;
|
bannerOptions.optionsArrayPtr = optionsArray;
|
||||||
bannerOptions.optionsCount = 10;
|
bannerOptions.optionsCount = 10;
|
||||||
bannerOptions.bannerCallback = [display](int selected) -> void {
|
bannerOptions.bannerCallback = [display](int selected) -> void {
|
||||||
|
#if defined(HELTEC_MESH_NODE_T114) || defined(HELTEC_VISION_MASTER_T190) || defined(T_DECK) || HAS_TFT
|
||||||
uint8_t TFT_MESH_r = 0;
|
uint8_t TFT_MESH_r = 0;
|
||||||
uint8_t TFT_MESH_g = 0;
|
uint8_t TFT_MESH_g = 0;
|
||||||
uint8_t TFT_MESH_b = 0;
|
uint8_t TFT_MESH_b = 0;
|
||||||
@ -758,7 +753,6 @@ void menuHandler::TFTColorPickerMenu(OLEDDisplay *display)
|
|||||||
screen->runNow();
|
screen->runNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HELTEC_MESH_NODE_T114) || defined(HELTEC_VISION_MASTER_T190) || defined(T_DECK) || HAS_TFT
|
|
||||||
if (selected != 0) {
|
if (selected != 0) {
|
||||||
display->setColor(BLACK);
|
display->setColor(BLACK);
|
||||||
display->fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
display->fillRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
@ -856,8 +850,9 @@ void menuHandler::removeFavoriteMenu()
|
|||||||
bannerOptions.optionsCount = 2;
|
bannerOptions.optionsCount = 2;
|
||||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||||
if (selected == 1) {
|
if (selected == 1) {
|
||||||
|
LOG_INFO("Removing %x as favorite node", graphics::UIRenderer::currentFavoriteNodeNum);
|
||||||
nodeDB->set_favorite(false, graphics::UIRenderer::currentFavoriteNodeNum);
|
nodeDB->set_favorite(false, graphics::UIRenderer::currentFavoriteNodeNum);
|
||||||
screen->setFrames(graphics::Screen::FOCUS_PRESERVE);
|
screen->setFrames(graphics::Screen::FOCUS_DEFAULT);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
screen->showOverlayBanner(bannerOptions);
|
screen->showOverlayBanner(bannerOptions);
|
||||||
|
@ -156,7 +156,7 @@ void NotificationRenderer::drawNumberPicker(OLEDDisplay *display, OLEDDisplayUiS
|
|||||||
resetBanner();
|
resetBanner();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (curSelected == numDigits) {
|
if (curSelected == static_cast<int8_t>(numDigits)) {
|
||||||
alertBannerCallback(currentNumber);
|
alertBannerCallback(currentNumber);
|
||||||
resetBanner();
|
resetBanner();
|
||||||
return;
|
return;
|
||||||
|
@ -24,6 +24,23 @@ extern graphics::Screen *screen;
|
|||||||
namespace graphics
|
namespace graphics
|
||||||
{
|
{
|
||||||
NodeNum UIRenderer::currentFavoriteNodeNum = 0;
|
NodeNum UIRenderer::currentFavoriteNodeNum = 0;
|
||||||
|
std::vector<meshtastic_NodeInfoLite *> graphics::UIRenderer::favoritedNodes;
|
||||||
|
|
||||||
|
void graphics::UIRenderer::rebuildFavoritedNodes()
|
||||||
|
{
|
||||||
|
favoritedNodes.clear();
|
||||||
|
size_t total = nodeDB->getNumMeshNodes();
|
||||||
|
for (size_t i = 0; i < total; i++) {
|
||||||
|
meshtastic_NodeInfoLite *n = nodeDB->getMeshNodeByIndex(i);
|
||||||
|
if (!n || n->num == nodeDB->getNodeNum())
|
||||||
|
continue;
|
||||||
|
if (n->is_favorite)
|
||||||
|
favoritedNodes.push_back(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::sort(favoritedNodes.begin(), favoritedNodes.end(),
|
||||||
|
[](const meshtastic_NodeInfoLite *a, const meshtastic_NodeInfoLite *b) { return a->num < b->num; });
|
||||||
|
}
|
||||||
|
|
||||||
#if !MESHTASTIC_EXCLUDE_GPS
|
#if !MESHTASTIC_EXCLUDE_GPS
|
||||||
// GeoCoord object for coordinate conversions
|
// GeoCoord object for coordinate conversions
|
||||||
@ -201,27 +218,7 @@ void UIRenderer::drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const mes
|
|||||||
// **********************
|
// **********************
|
||||||
void UIRenderer::drawNodeInfo(OLEDDisplay *display, const OLEDDisplayUiState *state, int16_t x, int16_t y)
|
void UIRenderer::drawNodeInfo(OLEDDisplay *display, const OLEDDisplayUiState *state, int16_t x, int16_t y)
|
||||||
{
|
{
|
||||||
// --- Cache favorite nodes for the current frame only, to save computation ---
|
|
||||||
static std::vector<meshtastic_NodeInfoLite *> favoritedNodes;
|
|
||||||
static int prevFrame = -1;
|
|
||||||
|
|
||||||
// --- Only rebuild favorites list if we're on a new frame ---
|
|
||||||
if (state->currentFrame != prevFrame) {
|
|
||||||
prevFrame = state->currentFrame;
|
|
||||||
favoritedNodes.clear();
|
|
||||||
size_t total = nodeDB->getNumMeshNodes();
|
|
||||||
for (size_t i = 0; i < total; i++) {
|
|
||||||
meshtastic_NodeInfoLite *n = nodeDB->getMeshNodeByIndex(i);
|
|
||||||
// Skip nulls and ourself
|
|
||||||
if (!n || n->num == nodeDB->getNodeNum())
|
|
||||||
continue;
|
|
||||||
if (n->is_favorite)
|
|
||||||
favoritedNodes.push_back(n);
|
|
||||||
}
|
|
||||||
// Keep a stable, consistent display order
|
|
||||||
std::sort(favoritedNodes.begin(), favoritedNodes.end(),
|
|
||||||
[](const meshtastic_NodeInfoLite *a, const meshtastic_NodeInfoLite *b) { return a->num < b->num; });
|
|
||||||
}
|
|
||||||
if (favoritedNodes.empty())
|
if (favoritedNodes.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -657,7 +654,7 @@ void UIRenderer::drawDeviceFocused(OLEDDisplay *display, OLEDDisplayUiState *sta
|
|||||||
|
|
||||||
char combinedName[50];
|
char combinedName[50];
|
||||||
snprintf(combinedName, sizeof(combinedName), "%s (%s)", longNameStr.empty() ? "" : longNameStr.c_str(), shortnameble);
|
snprintf(combinedName, sizeof(combinedName), "%s (%s)", longNameStr.empty() ? "" : longNameStr.c_str(), shortnameble);
|
||||||
if (SCREEN_WIDTH - (display->getStringWidth(longName) + display->getStringWidth(shortnameble)) > 10) {
|
if (SCREEN_WIDTH - (display->getStringWidth(combinedName)) > 10) {
|
||||||
size_t len = strlen(combinedName);
|
size_t len = strlen(combinedName);
|
||||||
if (len >= 3 && strcmp(combinedName + len - 3, " ()") == 0) {
|
if (len >= 3 && strcmp(combinedName + len - 3, " ()") == 0) {
|
||||||
combinedName[len - 3] = '\0'; // Remove the last three characters
|
combinedName[len - 3] = '\0'; // Remove the last three characters
|
||||||
@ -668,7 +665,7 @@ void UIRenderer::drawDeviceFocused(OLEDDisplay *display, OLEDDisplayUiState *sta
|
|||||||
nameX, ((rows == 4) ? getTextPositions(display)[line++] : getTextPositions(display)[line++]) + yOffset, combinedName);
|
nameX, ((rows == 4) ? getTextPositions(display)[line++] : getTextPositions(display)[line++]) + yOffset, combinedName);
|
||||||
} else {
|
} else {
|
||||||
// === LongName Centered ===
|
// === LongName Centered ===
|
||||||
textWidth = display->getStringWidth(longName);
|
textWidth = display->getStringWidth(longNameStr.c_str());
|
||||||
nameX = (SCREEN_WIDTH - textWidth) / 2;
|
nameX = (SCREEN_WIDTH - textWidth) / 2;
|
||||||
display->drawString(nameX, getTextPositions(display)[line++], longNameStr.c_str());
|
display->drawString(nameX, getTextPositions(display)[line++], longNameStr.c_str());
|
||||||
|
|
||||||
|
@ -61,6 +61,8 @@ class UIRenderer
|
|||||||
static void drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
static void drawCompassAndLocationScreen(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
static NodeNum currentFavoriteNodeNum;
|
static NodeNum currentFavoriteNodeNum;
|
||||||
|
static std::vector<meshtastic_NodeInfoLite *> favoritedNodes;
|
||||||
|
static void rebuildFavoritedNodes();
|
||||||
|
|
||||||
// OEM screens
|
// OEM screens
|
||||||
#ifdef USERPREFS_OEM_TEXT
|
#ifdef USERPREFS_OEM_TEXT
|
||||||
|
@ -67,4 +67,5 @@ void CardKbI2cImpl::init()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
inputBroker->registerSource(this);
|
inputBroker->registerSource(this);
|
||||||
|
kb_found = true;
|
||||||
}
|
}
|
@ -850,7 +850,13 @@ void CannedMessageModule::sendText(NodeNum dest, ChannelIndex channel, const cha
|
|||||||
this->waitingForAck = true;
|
this->waitingForAck = true;
|
||||||
|
|
||||||
// Log outgoing message
|
// Log outgoing message
|
||||||
LOG_INFO("Send message id=%d, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
|
LOG_INFO("Send message id=%u, dest=%x, msg=%.*s", p->id, p->to, p->decoded.payload.size, p->decoded.payload.bytes);
|
||||||
|
|
||||||
|
if (p->to != 0xffffffff) {
|
||||||
|
LOG_INFO("Proactively adding %x as favorite node", p->to);
|
||||||
|
nodeDB->set_favorite(true, p->to);
|
||||||
|
screen->setFrames(graphics::Screen::FOCUS_PRESERVE);
|
||||||
|
}
|
||||||
|
|
||||||
// Send to mesh and phone (even if no phone connected, to track ACKs)
|
// Send to mesh and phone (even if no phone connected, to track ACKs)
|
||||||
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
service->sendToMesh(p, RX_SRC_LOCAL, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user