Add dedicated WiFi password screen with full keyboard (CAPS, SHIFT, symbols)

This commit is contained in:
Chad 2026-03-31 14:47:15 -05:00
parent c78f07b4b5
commit 93dfd86cc2

View file

@ -168,13 +168,14 @@ enum ScreenState {
SCREEN_DASHBOARD, SCREEN_DASHBOARD,
SCREEN_CUSTOMIZE_STOCKS, SCREEN_CUSTOMIZE_STOCKS,
SCREEN_CUSTOMIZE_INDICES, SCREEN_CUSTOMIZE_INDICES,
SCREEN_WIFI_CONFIG SCREEN_WIFI_CONFIG,
SCREEN_WIFI_PASSWORD
}; };
ScreenState currentScreen = SCREEN_DASHBOARD; ScreenState currentScreen = SCREEN_DASHBOARD;
int selectedStockSlot = -1; int selectedStockSlot = -1;
int selectedIndexSlot = -1; int selectedIndexSlot = -1;
char keyboardBuffer[MAX_TICKER_LEN + 1] = ""; char keyboardBuffer[64] = "";
int keyboardPos = 0; int keyboardPos = 0;
int indexScrollOffset = 0; int indexScrollOffset = 0;
bool needsRefresh = false; bool needsRefresh = false;
@ -186,7 +187,9 @@ int wifiScrollOffset = 0;
bool wifiScanDone = false; bool wifiScanDone = false;
String selectedSSID = ""; String selectedSSID = "";
String wifiPassword = ""; String wifiPassword = "";
bool enteringPassword = false; bool keyboardShift = false;
bool keyboardCaps = false;
bool keyboardSymbols = false;
String formatPriceUS(double price, int decimals = 2, bool includeDollar = true) { String formatPriceUS(double price, int decimals = 2, bool includeDollar = true) {
if (price <= 0) return "..."; if (price <= 0) return "...";
@ -687,29 +690,16 @@ void drawWifiConfigScreen() {
lcd.drawString("v", 400, listY + visibleItems * (itemHeight + 4) + 17); lcd.drawString("v", 400, listY + visibleItems * (itemHeight + 4) + 17);
} }
if (selectedSSID.length() > 0) {
lcd.setTextColor(TFT_WHITE, TFT_BLACK); lcd.setTextColor(TFT_WHITE, TFT_BLACK);
lcd.setFont(&fonts::DejaVu18); lcd.setFont(&fonts::DejaVu18);
lcd.setTextDatum(textdatum_t::middle_left); lcd.setTextDatum(textdatum_t::middle_left);
lcd.drawString("Password:", 50, 285); lcd.drawString("Password:", 50, 285);
lcd.fillSmoothRoundRect(50, 305, 700, 40, 6, enteringPassword ? TFT_ORANGE : TFT_DARKGRAY); lcd.fillSmoothRoundRect(50, 305, 700, 40, 6, TFT_ORANGE);
lcd.setTextColor(enteringPassword ? TFT_WHITE : TFT_GRAY, enteringPassword ? TFT_ORANGE : TFT_DARKGRAY); lcd.setTextColor(TFT_WHITE, TFT_ORANGE);
lcd.setTextDatum(textdatum_t::middle_left); lcd.setTextDatum(textdatum_t::middle_left);
String pwdDisplay = wifiPassword;
if (enteringPassword && keyboardPos > 0) {
pwdDisplay = String(keyboardBuffer);
}
if (pwdDisplay.length() == 0) {
lcd.drawString("(tap to enter password)", 70, 325); lcd.drawString("(tap to enter password)", 70, 325);
} else {
String masked = "";
for (int i = 0; i < pwdDisplay.length(); i++) masked += "*";
lcd.drawString(masked, 70, 325);
}
if (enteringPassword) {
drawKeyboard(360);
} }
lcd.fillSmoothRoundRect(50, SCREEN_HEIGHT - 50, 150, 40, 8, TFT_GRAY); lcd.fillSmoothRoundRect(50, SCREEN_HEIGHT - 50, 150, 40, 8, TFT_GRAY);
@ -717,12 +707,6 @@ void drawWifiConfigScreen() {
lcd.setFont(&fonts::DejaVu18); lcd.setFont(&fonts::DejaVu18);
lcd.setTextDatum(textdatum_t::middle_center); lcd.setTextDatum(textdatum_t::middle_center);
lcd.drawString("BACK", 125, SCREEN_HEIGHT - 30); lcd.drawString("BACK", 125, SCREEN_HEIGHT - 30);
bool canSave = selectedSSID.length() > 0 && (wifiPassword.length() > 0 || (!enteringPassword && keyboardPos > 0));
uint16_t saveColor = canSave ? TFT_GREEN : TFT_GRAY;
lcd.fillSmoothRoundRect(SCREEN_WIDTH - 200, SCREEN_HEIGHT - 50, 150, 40, 8, saveColor);
lcd.setTextColor(TFT_WHITE, saveColor);
lcd.drawString("CONNECT", SCREEN_WIDTH - 125, SCREEN_HEIGHT - 30);
} }
void drawDashboard() { void drawDashboard() {
@ -801,6 +785,125 @@ void drawDashboard() {
lcd.drawString("CUSTOMIZE", SCREEN_WIDTH - 90, SCREEN_HEIGHT - 20); lcd.drawString("CUSTOMIZE", SCREEN_WIDTH - 90, SCREEN_HEIGHT - 20);
} }
void drawFullKeyboard(int y, bool showSpecials) {
const char* letterRows[] = {
"QWERTYUIOP",
"ASDFGHJKL",
"ZXCVBNM"
};
const char* symbolRows[] = {
"1234567890",
"-=_+[]{}\\",
"!@#$%^&*()"
};
const int keySize = 36;
const int keyGap = 3;
if (!showSpecials) {
for (int r = 0; r < 3; r++) {
int rowLen = strlen(letterRows[r]);
int rowWidth = rowLen * (keySize + keyGap) - keyGap;
int startX = (SCREEN_WIDTH - rowWidth) / 2;
int keyY = y + r * (keySize + keyGap);
for (int k = 0; k < rowLen; k++) {
int keyX = startX + k * (keySize + keyGap);
lcd.fillSmoothRoundRect(keyX, keyY, keySize, keySize, 4, TFT_DARKGRAY);
lcd.setTextColor(TFT_WHITE, TFT_DARKGRAY);
lcd.setFont(&fonts::DejaVu12);
lcd.setTextDatum(textdatum_t::middle_center);
char c = letterRows[r][k];
if (!(keyboardCaps || keyboardShift)) {
c = tolower(letterRows[r][k]);
}
lcd.drawChar(c, keyX + keySize/2, keyY + keySize/2);
}
}
} else {
for (int r = 0; r < 3; r++) {
int rowLen = strlen(symbolRows[r]);
int rowWidth = rowLen * (keySize + keyGap) - keyGap;
int startX = (SCREEN_WIDTH - rowWidth) / 2;
int keyY = y + r * (keySize + keyGap);
for (int k = 0; k < rowLen; k++) {
int keyX = startX + k * (keySize + keyGap);
lcd.fillSmoothRoundRect(keyX, keyY, keySize, keySize, 4, TFT_DARKGRAY);
lcd.setTextColor(TFT_WHITE, TFT_DARKGRAY);
lcd.setFont(&fonts::DejaVu12);
lcd.setTextDatum(textdatum_t::middle_center);
lcd.drawChar(symbolRows[r][k], keyX + keySize/2, keyY + keySize/2);
}
}
}
int btnY = y + 3 * (keySize + keyGap) + 4;
int capsX = 50;
lcd.fillSmoothRoundRect(capsX, btnY, 80, 36, 6, keyboardCaps ? TFT_ORANGE : TFT_GRAY);
lcd.setTextColor(TFT_WHITE, keyboardCaps ? TFT_ORANGE : TFT_GRAY);
lcd.setFont(&fonts::DejaVu12);
lcd.setTextDatum(textdatum_t::middle_center);
lcd.drawString("CAPS", capsX + 40, btnY + 18);
int shiftX = 140;
lcd.fillSmoothRoundRect(shiftX, btnY, 80, 36, 6, keyboardShift ? TFT_ORANGE : TFT_GRAY);
lcd.setTextColor(TFT_WHITE, keyboardShift ? TFT_ORANGE : TFT_GRAY);
lcd.drawString("SHIFT", shiftX + 40, btnY + 18);
int symX = 230;
lcd.fillSmoothRoundRect(symX, btnY, 80, 36, 6, keyboardSymbols ? TFT_ORANGE : TFT_GRAY);
lcd.setTextColor(TFT_WHITE, keyboardSymbols ? TFT_ORANGE : TFT_GRAY);
lcd.drawString("123", symX + 40, btnY + 18);
int delX = SCREEN_WIDTH / 2 - 40;
lcd.fillSmoothRoundRect(delX, btnY, 80, 36, 6, TFT_ORANGE);
lcd.setTextColor(TFT_WHITE, TFT_ORANGE);
lcd.drawString("DEL", delX + 40, btnY + 18);
int enterX = SCREEN_WIDTH / 2 + 50;
lcd.fillSmoothRoundRect(enterX, btnY, 100, 36, 6, TFT_GREEN);
lcd.setTextColor(TFT_WHITE, TFT_GREEN);
lcd.drawString("SAVE", enterX + 50, btnY + 18);
}
void drawWifiPasswordScreen() {
lcd.fillScreen(TFT_BLACK);
lcd.fillSmoothRoundRect(0, 0, SCREEN_WIDTH, 50, 8, TFT_ORANGE);
lcd.setTextColor(TFT_WHITE, TFT_ORANGE);
lcd.setFont(&fonts::DejaVu24);
lcd.setTextDatum(textdatum_t::middle_center);
lcd.drawString("ENTER PASSWORD", SCREEN_WIDTH / 2, 25);
lcd.setTextColor(TFT_GRAY, TFT_BLACK);
lcd.setFont(&fonts::DejaVu12);
lcd.setTextDatum(textdatum_t::middle_left);
lcd.drawString("Network: " + selectedSSID, 50, 70);
lcd.fillSmoothRoundRect(50, 100, SCREEN_WIDTH - 100, 50, 8, TFT_DARKGRAY);
lcd.setTextColor(TFT_WHITE, TFT_DARKGRAY);
lcd.setFont(&fonts::DejaVu18);
lcd.setTextDatum(textdatum_t::middle_left);
String displayPwd = "";
for (int i = 0; i < keyboardPos; i++) displayPwd += "*";
if (keyboardPos == 0) {
lcd.setTextColor(TFT_GRAY, TFT_DARKGRAY);
displayPwd = "_";
}
lcd.drawString(displayPwd, 70, 125);
drawFullKeyboard(170, keyboardSymbols);
lcd.fillSmoothRoundRect(50, SCREEN_HEIGHT - 50, 150, 40, 8, TFT_GRAY);
lcd.setTextColor(TFT_WHITE, TFT_GRAY);
lcd.setFont(&fonts::DejaVu18);
lcd.setTextDatum(textdatum_t::middle_center);
lcd.drawString("CANCEL", 125, SCREEN_HEIGHT - 30);
}
bool handleKeyboardTouch(int32_t x, int32_t y, int keyboardY) { bool handleKeyboardTouch(int32_t x, int32_t y, int keyboardY) {
const char* rows[] = { const char* rows[] = {
"QWERTYUIOP", "QWERTYUIOP",
@ -911,19 +1014,6 @@ bool handleWifiConfigTouch(int32_t x, int32_t y) {
return true; return true;
} }
if (x >= SCREEN_WIDTH - 200 && x < SCREEN_WIDTH - 50 && y >= SCREEN_HEIGHT - 50 && y < SCREEN_HEIGHT - 10) {
String pwdToSave = enteringPassword ? String(keyboardBuffer) : wifiPassword;
if (selectedSSID.length() > 0 && pwdToSave.length() > 0) {
preferences.begin("wifi", false);
preferences.putString("ssid", selectedSSID);
preferences.putString("password", pwdToSave);
preferences.end();
currentScreen = SCREEN_DASHBOARD;
needsRefresh = true;
}
return true;
}
int listY = 85; int listY = 85;
int itemHeight = 36; int itemHeight = 36;
int visibleItems = 5; int visibleItems = 5;
@ -949,34 +1039,47 @@ bool handleWifiConfigTouch(int32_t x, int32_t y) {
int iy = listY + i * (itemHeight + 4); int iy = listY + i * (itemHeight + 4);
if (x >= 50 && x < 750 && y >= iy && y < iy + itemHeight) { if (x >= 50 && x < 750 && y >= iy && y < iy + itemHeight) {
selectedSSID = scannedSSIDs[idx]; selectedSSID = scannedSSIDs[idx];
enteringPassword = false;
keyboardPos = 0;
keyboardBuffer[0] = '\0';
return true; return true;
} }
} }
if (x >= 50 && x < 750 && y >= 305 && y < 345) { if (x >= 50 && x < 750 && y >= 305 && y < 345 && selectedSSID.length() > 0) {
enteringPassword = true; currentScreen = SCREEN_WIFI_PASSWORD;
keyboardPos = 0; keyboardPos = 0;
keyboardBuffer[0] = '\0'; keyboardBuffer[0] = '\0';
keyboardCaps = false;
keyboardShift = false;
keyboardSymbols = false;
return true; return true;
} }
if (enteringPassword) { return false;
int keyboardY = 360; }
const char* rows[] = {
bool handleWifiPasswordTouch(int32_t x, int32_t y) {
if (x >= 50 && x < 200 && y >= SCREEN_HEIGHT - 50 && y < SCREEN_HEIGHT - 10) {
currentScreen = SCREEN_WIFI_CONFIG;
return true;
}
const char* letterRows[] = {
"QWERTYUIOP", "QWERTYUIOP",
"ASDFGHJKL", "ASDFGHJKL",
"ZXCVBNM", "ZXCVBNM"
"1234567890" };
const char* symbolRows[] = {
"1234567890",
"-=_+[]{}\\",
"!@#$%^&*()"
}; };
const int numRows = 4;
const int keySize = 32;
const int keyGap = 2;
for (int r = 0; r < numRows; r++) { const int keySize = 36;
int rowLen = strlen(rows[r]); const int keyGap = 3;
int keyboardY = 170;
if (!keyboardSymbols) {
for (int r = 0; r < 3; r++) {
int rowLen = strlen(letterRows[r]);
int rowWidth = rowLen * (keySize + keyGap) - keyGap; int rowWidth = rowLen * (keySize + keyGap) - keyGap;
int startX = (SCREEN_WIDTH - rowWidth) / 2; int startX = (SCREEN_WIDTH - rowWidth) / 2;
int keyY = keyboardY + r * (keySize + keyGap); int keyY = keyboardY + r * (keySize + keyGap);
@ -985,19 +1088,56 @@ bool handleWifiConfigTouch(int32_t x, int32_t y) {
int keyX = startX + k * (keySize + keyGap); int keyX = startX + k * (keySize + keyGap);
if (x >= keyX && x < keyX + keySize && y >= keyY && y < keyY + keySize) { if (x >= keyX && x < keyX + keySize && y >= keyY && y < keyY + keySize) {
if (keyboardPos < 63) { if (keyboardPos < 63) {
keyboardBuffer[keyboardPos++] = rows[r][k]; char c = letterRows[r][k];
if (!(keyboardCaps || keyboardShift)) {
c = tolower(c);
}
keyboardBuffer[keyboardPos++] = c;
keyboardBuffer[keyboardPos] = '\0';
if (keyboardShift) keyboardShift = false;
}
return true;
}
}
}
} else {
for (int r = 0; r < 3; r++) {
int rowLen = strlen(symbolRows[r]);
int rowWidth = rowLen * (keySize + keyGap) - keyGap;
int startX = (SCREEN_WIDTH - rowWidth) / 2;
int keyY = keyboardY + r * (keySize + keyGap);
for (int k = 0; k < rowLen; k++) {
int keyX = startX + k * (keySize + keyGap);
if (x >= keyX && x < keyX + keySize && y >= keyY && y < keyY + keySize) {
if (keyboardPos < 63) {
keyboardBuffer[keyboardPos++] = symbolRows[r][k];
keyboardBuffer[keyboardPos] = '\0'; keyboardBuffer[keyboardPos] = '\0';
} }
return true; return true;
} }
} }
} }
}
int btnY = keyboardY + numRows * (keySize + keyGap) + 4; int btnY = keyboardY + 3 * (keySize + keyGap) + 4;
int delX = SCREEN_WIDTH / 2 - 125;
int enterX = SCREEN_WIDTH / 2 + 5;
if (x >= delX && x < delX + 120 && y >= btnY && y < btnY + 32) { if (x >= 50 && x < 130 && y >= btnY && y < btnY + 36) {
keyboardCaps = !keyboardCaps;
return true;
}
if (x >= 140 && x < 220 && y >= btnY && y < btnY + 36) {
keyboardShift = !keyboardShift;
return true;
}
if (x >= 230 && x < 310 && y >= btnY && y < btnY + 36) {
keyboardSymbols = !keyboardSymbols;
return true;
}
if (x >= SCREEN_WIDTH / 2 - 40 && x < SCREEN_WIDTH / 2 + 40 && y >= btnY && y < btnY + 36) {
if (keyboardPos > 0) { if (keyboardPos > 0) {
keyboardPos--; keyboardPos--;
keyboardBuffer[keyboardPos] = '\0'; keyboardBuffer[keyboardPos] = '\0';
@ -1005,14 +1145,18 @@ bool handleWifiConfigTouch(int32_t x, int32_t y) {
return true; return true;
} }
if (x >= enterX && x < enterX + 120 && y >= btnY && y < btnY + 32) { if (x >= SCREEN_WIDTH / 2 + 50 && x < SCREEN_WIDTH / 2 + 150 && y >= btnY && y < btnY + 36) {
wifiPassword = String(keyboardBuffer); wifiPassword = String(keyboardBuffer);
enteringPassword = false; preferences.begin("wifi", false);
preferences.putString("ssid", selectedSSID);
preferences.putString("password", wifiPassword);
preferences.end();
currentScreen = SCREEN_DASHBOARD;
needsRefresh = true;
return true; return true;
} }
}
return false; return false;
} }
bool handleIndexCustomizeTouch(int32_t x, int32_t y) { bool handleIndexCustomizeTouch(int32_t x, int32_t y) {
@ -1127,9 +1271,11 @@ bool handleDashboardTouch(int32_t x, int32_t y) {
wifiScanDone = false; wifiScanDone = false;
wifiPassword = ""; wifiPassword = "";
selectedSSID = ""; selectedSSID = "";
enteringPassword = false;
keyboardPos = 0; keyboardPos = 0;
keyboardBuffer[0] = '\0'; keyboardBuffer[0] = '\0';
keyboardCaps = false;
keyboardShift = false;
keyboardSymbols = false;
scanWifiNetworks(); scanWifiNetworks();
return true; return true;
} }
@ -1238,6 +1384,9 @@ void loop() {
case SCREEN_WIFI_CONFIG: case SCREEN_WIFI_CONFIG:
handleWifiConfigTouch(x, y); handleWifiConfigTouch(x, y);
break; break;
case SCREEN_WIFI_PASSWORD:
handleWifiPasswordTouch(x, y);
break;
} }
if (!needsRefresh) { if (!needsRefresh) {
@ -1256,6 +1405,9 @@ void loop() {
case SCREEN_WIFI_CONFIG: case SCREEN_WIFI_CONFIG:
drawWifiConfigScreen(); drawWifiConfigScreen();
break; break;
case SCREEN_WIFI_PASSWORD:
drawWifiPasswordScreen();
break;
} }
} }