Enlarge Indicator native setup screen

This commit is contained in:
mikecarper committed 2026-08-31 16:10:03 -07:00
1 parent 164a6e8227
commit 4bbdf4b071
6 files changed
+163 -5

No files matched your search

+95 -3
View File
@@ -1182,6 +1182,88 @@ void halt() {
&& companion_setup_display->height() >= 128;
}
static bool hasNativeIndicatorSetupTypography() {
#if defined(INDICATOR_TRANSPORT_RENDER_PROFILE)
return mesh::ui::usesNativeIndicatorTypography(
companion_setup_display->width(),
companion_setup_display->height(),
companion_setup_display->renderWidth(),
companion_setup_display->renderHeight());
#else
return false;
#endif
}
static int drawNativeIndicatorSetupValue(int y, const char* value) {
companion_setup_display->setTextSize(2);
// The setup AP has a stable prefix. Split on its semantic boundary so
// the two large centered rows read cleanly instead of wrapping midway
// through "Setup".
if (value != nullptr
&& strncmp(value, "MeshCore-Setup-", 15) == 0) {
companion_setup_display->drawTextCentered(
companion_setup_display->width() / 2, y, "MeshCore-");
companion_setup_display->drawTextCentered(
companion_setup_display->width() / 2, y + 21, value + 9);
return 2;
}
const int max_width = companion_setup_display->width() - 12;
int line_height = 21;
// A configured SSID can contain 32 bytes. Keep ordinary names at the
// large size, but let the longest legal value use two complete size-1
// rows instead of silently losing its tail.
if (value != nullptr
&& companion_setup_display->getTextWidth(value) > max_width * 2) {
companion_setup_display->setTextSize(1);
line_height = 11;
}
return mesh::ui::drawTextWrapped(
*companion_setup_display, 6, y,
max_width, line_height, 2,
value != nullptr && value[0] != 0 ? value : "(not set)");
}
static void drawNativeIndicatorSetupAddress(int y, const char* address) {
const char* value = address != nullptr && address[0] != 0
? address : "(not set)";
companion_setup_display->setTextSize(2);
if (companion_setup_display->getTextWidth(value)
> companion_setup_display->width()) {
companion_setup_display->setTextSize(1);
}
companion_setup_display->drawTextCentered(
companion_setup_display->width() / 2, y, value);
}
static void renderNativeIndicatorSetupDisplay(const char* title,
const char* wifi_name,
const char* address,
bool connecting) {
companion_setup_display->setTextSize(3);
companion_setup_display->drawTextCentered(
companion_setup_display->width() / 2, 2, title);
companion_setup_display->setTextSize(2);
companion_setup_display->drawTextCentered(
companion_setup_display->width() / 2, 34,
connecting ? "CONNECTING" : "JOIN WIFI");
drawNativeIndicatorSetupValue(56, wifi_name);
if (connecting) {
companion_setup_display->setTextSize(2);
companion_setup_display->drawTextCentered(
companion_setup_display->width() / 2, 126, "WAIT...");
return;
}
companion_setup_display->setTextSize(2);
companion_setup_display->drawTextCentered(
companion_setup_display->width() / 2, 101, "BROWSE");
// The scheme is implicit here so the address itself can remain nearly
// panel-wide at size 2. Long DHCP addresses fall back to size 1.
drawNativeIndicatorSetupAddress(124, address);
}
static int drawCompanionSetupValue(int y, int max_lines,
const char* value) {
static constexpr int margin = 6;
@@ -1225,6 +1307,7 @@ void halt() {
companion_setup_display->turnOn();
companion_setup_display->startFrame();
companion_setup_display->setCompactText(false);
companion_setup_display->setTextSize(1);
companion_setup_display->setColor(UIColor::primary_txt);
@@ -1232,7 +1315,10 @@ void halt() {
char setup_ip[16] = {0};
if (WebConfigServer::getSetupInfo(setup_ssid, sizeof(setup_ssid),
setup_ip, sizeof(setup_ip))) {
if (hasLargeCompanionSetupDisplay()) {
if (hasNativeIndicatorSetupTypography()) {
renderNativeIndicatorSetupDisplay(
"SETUP", setup_ssid, setup_ip, false);
} else if (hasLargeCompanionSetupDisplay()) {
renderLargeCompanionSetupDisplay(
"WebUI setup", "Join open WiFi:", setup_ssid, setup_ip, false);
} else {
@@ -1249,7 +1335,10 @@ void halt() {
}
} else if (WiFi.status() == WL_CONNECTED) {
const String ip = WiFi.localIP().toString();
if (hasLargeCompanionSetupDisplay()) {
if (hasNativeIndicatorSetupTypography()) {
renderNativeIndicatorSetupDisplay(
"READY", configured_wifi_ssid, ip.c_str(), false);
} else if (hasLargeCompanionSetupDisplay()) {
renderLargeCompanionSetupDisplay(
"WebUI ready", "Join WiFi:", configured_wifi_ssid, ip.c_str(),
false);
@@ -1266,7 +1355,10 @@ void halt() {
companion_setup_display->width() / 2, 51, ip.c_str());
}
} else {
if (hasLargeCompanionSetupDisplay()) {
if (hasNativeIndicatorSetupTypography()) {
renderNativeIndicatorSetupDisplay(
"WIFI", configured_wifi_ssid, nullptr, true);
} else if (hasLargeCompanionSetupDisplay()) {
renderLargeCompanionSetupDisplay(
"WiFi connecting", "WiFi name:", configured_wifi_ssid, nullptr,
true);
+3 -2
View File
@@ -1,6 +1,7 @@
#pragma once
#include <helpers/ui/DisplayDriver.h>
#include <helpers/ui/IndicatorRenderProfile.h>
namespace mesh {
namespace ui {
@@ -37,8 +38,8 @@ struct CompactCompanionPairingLayout {
// unrelated displays that happen to have a tall viewport.
inline bool usesExpandedCompanionHomeTypography(
int width, int height, int render_width, int render_height) {
return width == 160 && height == 160
&& render_width == 480 && render_height == 480;
return usesNativeIndicatorTypography(
width, height, render_width, render_height);
}
// The common Companion OLED/TFT viewport is 128x64. Its normal instruction
+10
View File
@@ -11,6 +11,16 @@ struct IndicatorRenderProfile {
uint16_t canvas_size;
};
// Full-size Indicator builds retain the established 160x160 logical
// coordinate system even when the backing canvas is the panel's native
// 480x480. Screens with enough room to reflow can use this distinction to
// choose substantially larger text without changing the 320px BLE fallback.
inline bool usesNativeIndicatorTypography(
int width, int height, int render_width, int render_height) {
return width == 160 && height == 160
&& render_width == 480 && render_height == 480;
}
// ESP-NOW and BLE are the Indicator's tightest internal-RAM combination.
// Every other exclusive Full-Companion combination can use a native 480px
// internal canvas while preserving the established 160px UI coordinates.
+26
View File
@@ -164,6 +164,32 @@ class IndicatorDisplayProfileTest(unittest.TestCase):
self.assertLessEqual(pairing_label_y + 29, pairing_value_y)
self.assertLessEqual(pairing_value_y + 29, 160)
# Native setup mode intentionally uses most of the panel: a size-3
# title and size-2 action/value rows replace the legacy size-1 page.
for text, requested_size in (
("SETUP", 3),
("READY", 3),
("WIFI", 3),
("CONNECTING", 2),
("JOIN WIFI", 2),
("BROWSE", 2),
("192.168.4.1", 2),
):
width, _height = dimensions(text, requested_size, 3, 1.2)
self.assertLessEqual(width, 160)
title_height = dimensions("SETUP", 3, 3, 1.2)[1]
row_height = dimensions("JOIN WIFI", 2, 3, 1.2)[1]
self.assertLessEqual(2 + title_height, 34)
self.assertLessEqual(34 + row_height, 56)
self.assertLessEqual(56 + row_height, 77)
self.assertLessEqual(77 + row_height, 101)
self.assertLessEqual(101 + row_height, 124)
self.assertLessEqual(124 + row_height, 160)
long_ssid = dimensions("ABCDEFGHIJKLMNOPQRSTUVWXYZ123456", 1, 3, 1.2)
self.assertLessEqual(long_ssid[0], 2 * 148)
if __name__ == "__main__":
unittest.main()
+24
View File
@@ -36,6 +36,9 @@ int main() {
if (mesh::ui::selectIndicatorTextScale(480, false) != 1.2f) return 5;
if (mesh::ui::selectIndicatorTextScale(480, true) != 1.0f) return 6;
if (mesh::ui::selectIndicatorTextScale(320, false) != 1.0f) return 7;
if (!mesh::ui::usesNativeIndicatorTypography(160, 160, 480, 480)) return 8;
if (mesh::ui::usesNativeIndicatorTypography(160, 160, 320, 320)) return 9;
if (mesh::ui::usesNativeIndicatorTypography(128, 128, 480, 480)) return 10;
return 0;
}
'''
@@ -120,6 +123,27 @@ int main() {
self.assertIn("static_cast<uint16_t>(renderWidth()), _compactText", display)
self.assertIn("* profile_scale;", display)
def test_native_setup_page_uses_large_reflow(self):
main = MAIN.read_text(encoding="utf-8")
start = main.index("static bool hasNativeIndicatorSetupTypography()")
end = main.index("static bool saveCompanionWiFi", start)
setup = main[start:end]
self.assertIn("usesNativeIndicatorTypography", setup)
self.assertIn("renderNativeIndicatorSetupDisplay", setup)
self.assertIn('setTextSize(3);', setup)
self.assertIn('connecting ? "CONNECTING" : "JOIN WIFI"', setup)
self.assertIn('drawNativeIndicatorSetupValue(56, wifi_name);', setup)
self.assertIn('strncmp(value, "MeshCore-Setup-", 15) == 0', setup)
self.assertIn('y, "MeshCore-"', setup)
self.assertIn('y + 21, value + 9', setup)
self.assertIn('getTextWidth(value) > max_width * 2', setup)
self.assertIn('line_height = 11;', setup)
self.assertIn('101, "BROWSE"', setup)
self.assertIn('drawNativeIndicatorSetupAddress(124, address);', setup)
self.assertIn('"SETUP", setup_ssid, setup_ip, false', setup)
self.assertIn('"READY", configured_wifi_ssid, ip.c_str(), false', setup)
self.assertIn('"WIFI", configured_wifi_ssid, nullptr, true', setup)
def test_lora_fresh_install_uses_compiled_cascade_defaults(self):
profile = PROFILE.read_text(encoding="utf-8")
lora = profile[profile.index("[SenseCapIndicator-LoRa]") :]
@@ -144,6 +144,11 @@ uses separate full-width size-4 `INBOX` and count rows plus a large lower
action or BLE-status block. Long IP addresses retain a smaller bounded row
instead of clipping.
The native-480 WiFi setup/status screen is reflowed separately: its title is
size 3, its join/browse instructions and setup SSID are size 2, and the IP
address remains size 2 whenever it fits. The legacy 320 and other display
layouts keep their existing compact setup page.
LoRa remains the primary radio in both LoRa modes. On the ESP-NOW layout,
selecting BLE leaves the primary ESP-NOW WiFi radio and its fixed channel
running; it disables only infrastructure WiFi. Rendering follows the memory