Restore the V4 WiFi setup QR with a one-pixel border
This commit is contained in:
1 parent
626ead5433
commit
7ff11a2d64
6 files changed
+94
-17
No files matched your search
@@ -5,9 +5,15 @@
|
||||
#include <qrcode.h>
|
||||
|
||||
bool DisplayDriver::drawQrCode(const char* text, int x, int y, int size) {
|
||||
return drawQrCodeWithBorder(text, x, y, size, -1);
|
||||
}
|
||||
|
||||
bool DisplayDriver::drawQrCodeWithBorder(const char* text, int x, int y,
|
||||
int size, int border_pixels) {
|
||||
if (text == nullptr || text[0] == 0 || x < 0 || y < 0 || size <= 0
|
||||
|| size > width() || size > height()
|
||||
|| x > width() - size || y > height() - size) {
|
||||
|| x > width() - size || y > height() - size
|
||||
|| border_pixels < -1 || border_pixels > (size - 1) / 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -28,13 +34,17 @@ bool DisplayDriver::drawQrCode(const char* text, int x, int y, int size) {
|
||||
if (!initialized) return false;
|
||||
|
||||
static constexpr int quiet_zone = 4;
|
||||
const int module_size = size / (qr.size + quiet_zone * 2);
|
||||
const int module_size = border_pixels < 0
|
||||
? size / (qr.size + quiet_zone * 2)
|
||||
: (size - border_pixels * 2) / qr.size;
|
||||
if (module_size <= 0) return false;
|
||||
const int used_size = module_size * (qr.size + quiet_zone * 2);
|
||||
const int border = border_pixels < 0
|
||||
? quiet_zone * module_size : border_pixels;
|
||||
const int used_size = module_size * qr.size + border * 2;
|
||||
const int left = x + (size - used_size) / 2;
|
||||
const int top = y + (size - used_size) / 2;
|
||||
const int matrix_left = left + quiet_zone * module_size;
|
||||
const int matrix_top = top + quiet_zone * module_size;
|
||||
const int matrix_left = left + border;
|
||||
const int matrix_top = top + border;
|
||||
|
||||
// Dark-theme OLED/TFT drivers use a dark window and light popup text;
|
||||
// e-paper reverses that convention. Always emit the conventional dark
|
||||
@@ -42,7 +52,10 @@ bool DisplayDriver::drawQrCode(const char* text, int x, int y, int size) {
|
||||
const ColorVal light = isEink() ? UIColor::window_bkg : UIColor::popup_txt;
|
||||
const ColorVal dark = isEink() ? UIColor::primary_txt : UIColor::window_bkg;
|
||||
setColor(light);
|
||||
fillRect(x, y, size, size);
|
||||
// An explicit border is exact, even if a larger QR version leaves unused
|
||||
// space in the requested square. Do not add that space to the white border.
|
||||
if (border_pixels < 0) fillRect(x, y, size, size);
|
||||
else fillRect(left, top, used_size, used_size);
|
||||
setColor(dark);
|
||||
for (uint8_t row = 0; row < qr.size; ++row) {
|
||||
for (uint8_t column = 0; column < qr.size; ++column) {
|
||||
|
||||
@@ -74,6 +74,10 @@ public:
|
||||
// fallback layout in place.
|
||||
#if defined(ESP32_PLATFORM) && defined(MESHCORE_HAS_REAL_DISPLAY)
|
||||
virtual bool drawQrCode(const char* text, int x, int y, int size);
|
||||
// Explicit pixel border for compact setup screens; -1 keeps the normal
|
||||
// four-module quiet zone. The matrix always uses whole pixels.
|
||||
virtual bool drawQrCodeWithBorder(const char* text, int x, int y, int size,
|
||||
int border_pixels);
|
||||
#else
|
||||
virtual bool drawQrCode(const char* text, int x, int y, int size) {
|
||||
(void)text;
|
||||
@@ -82,6 +86,15 @@ public:
|
||||
(void)size;
|
||||
return false;
|
||||
}
|
||||
virtual bool drawQrCodeWithBorder(const char* text, int x, int y, int size,
|
||||
int border_pixels) {
|
||||
(void)text;
|
||||
(void)x;
|
||||
(void)y;
|
||||
(void)size;
|
||||
(void)border_pixels;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
virtual uint16_t getTextWidth(const char* str) = 0;
|
||||
virtual bool getTouch(int* x, int* y) {
|
||||
|
||||
@@ -13,7 +13,8 @@ namespace ui {
|
||||
// panels so a normal setup IP has the full 66-pixel text row beside it.
|
||||
// Returns false when the payload or panel geometry cannot be represented.
|
||||
inline bool drawWiFiSetupQr(DisplayDriver& display, const char* ssid,
|
||||
const char* address) {
|
||||
const char* address, bool compact_border = false,
|
||||
const char* action = nullptr) {
|
||||
char payload[256];
|
||||
const char* password = nullptr;
|
||||
#ifdef WEBCONFIG_AP_PASSWORD
|
||||
@@ -27,18 +28,24 @@ inline bool drawWiFiSetupQr(DisplayDriver& display, const char* ssid,
|
||||
int qr_size = display.height() < display.width() / 2
|
||||
? display.height() : display.width() / 2;
|
||||
static constexpr int compact_qr_size = (21 + 4 * 2) * 2;
|
||||
if (display.height() == 64 && qr_size >= compact_qr_size) {
|
||||
if (compact_border && qr_size >= 44) {
|
||||
// Version 1: 21 modules at 2 pixels, plus an exact one-pixel border.
|
||||
qr_size = 44;
|
||||
} else if (display.height() == 64 && qr_size >= compact_qr_size) {
|
||||
qr_size = compact_qr_size;
|
||||
}
|
||||
if (!display.drawQrCode(payload, 0, 0, qr_size)) return false;
|
||||
const bool rendered = compact_border
|
||||
? display.drawQrCodeWithBorder(payload, 0, 0, qr_size, 1)
|
||||
: display.drawQrCode(payload, 0, 0, qr_size);
|
||||
if (!rendered) return false;
|
||||
|
||||
const int text_x = qr_size + 4;
|
||||
display.setTextSize(1);
|
||||
display.setColor(UIColor::primary_txt);
|
||||
display.setCursor(text_x, 2);
|
||||
display.print("SCAN TO");
|
||||
display.print(action ? "SCAN JOIN" : "SCAN TO");
|
||||
display.setCursor(text_x, 12);
|
||||
display.print("JOIN:");
|
||||
display.print(action ? action : "JOIN:");
|
||||
display.drawTextEllipsized(
|
||||
text_x, 22, display.width() - text_x, ssid);
|
||||
display.setCursor(text_x, 37);
|
||||
|
||||
Reference in new issue
Block a user