Remove old battery icon and option, use drawCommonHeader throughout, re-add battery to Clock frames

This commit is contained in:
Jason P 2025-06-24 10:46:25 -05:00
parent a3ed75c5c9
commit 34f3800e2b
9 changed files with 36 additions and 96 deletions

View File

@ -53,7 +53,7 @@ void drawRoundedHighlight(OLEDDisplay *display, int16_t x, int16_t y, int16_t w,
// ************************* // *************************
// * Common Header Drawing * // * Common Header Drawing *
// ************************* // *************************
void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *titleStr) void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *titleStr, bool battery_only)
{ {
constexpr int HEADER_OFFSET_Y = 1; constexpr int HEADER_OFFSET_Y = 1;
y += HEADER_OFFSET_Y; y += HEADER_OFFSET_Y;
@ -69,6 +69,7 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti
const int screenW = display->getWidth(); const int screenW = display->getWidth();
const int screenH = display->getHeight(); const int screenH = display->getHeight();
if (!battery_only) {
// === Inverted Header Background === // === Inverted Header Background ===
if (isInverted) { if (isInverted) {
display->setColor(BLACK); display->setColor(BLACK);
@ -93,6 +94,7 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti
if (config.display.heading_bold) { if (config.display.heading_bold) {
display->drawString((SCREEN_WIDTH / 2) + 1, y, titleStr); display->drawString((SCREEN_WIDTH / 2) + 1, y, titleStr);
} }
}
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
// === Battery State === // === Battery State ===
@ -163,7 +165,7 @@ void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *ti
int timeStrWidth = display->getStringWidth("12:34"); // Default alignment int timeStrWidth = display->getStringWidth("12:34"); // Default alignment
int timeX = screenW - xOffset - timeStrWidth + 4; int timeX = screenW - xOffset - timeStrWidth + 4;
if (rtc_sec > 0) { if (rtc_sec > 0 && !battery_only) {
// === Build Time String === // === Build Time String ===
long hms = (rtc_sec % SEC_PER_DAY + SEC_PER_DAY) % SEC_PER_DAY; long hms = (rtc_sec % SEC_PER_DAY + SEC_PER_DAY) % SEC_PER_DAY;
int hour = hms / SEC_PER_HOUR; int hour = hms / SEC_PER_HOUR;

View File

@ -48,7 +48,7 @@ void determineResolution(int16_t screenheight, int16_t screenwidth);
void drawRoundedHighlight(OLEDDisplay *display, int16_t x, int16_t y, int16_t w, int16_t h, int16_t r); void drawRoundedHighlight(OLEDDisplay *display, int16_t x, int16_t y, int16_t w, int16_t h, int16_t r);
// Shared battery/time/mail header // Shared battery/time/mail header
void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *titleStr = ""); void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *titleStr = "", bool battery_only = false);
const int *getTextPositions(OLEDDisplay *display); const int *getTextPositions(OLEDDisplay *display);

View File

@ -188,6 +188,10 @@ void drawDigitalClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int1
display->clear(); display->clear();
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
int line = 1; int line = 1;
// === Set Title, Blank for Clock
const char *titleStr = "";
// === Header ===
graphics::drawCommonHeader(display, x, y, titleStr, true);
#ifdef T_WATCH_S3 #ifdef T_WATCH_S3
if (nimbleBluetooth && nimbleBluetooth->isConnected()) { if (nimbleBluetooth && nimbleBluetooth->isConnected()) {
@ -300,18 +304,12 @@ void drawBluetoothConnectedIcon(OLEDDisplay *display, int16_t x, int16_t y)
void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) void drawAnalogClockFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y)
{ {
display->setTextAlignment(TEXT_ALIGN_LEFT); display->setTextAlignment(TEXT_ALIGN_LEFT);
// === Set Title, Blank for Clock
const char *titleStr = "";
// === Header ===
graphics::drawCommonHeader(display, x, y, titleStr, true);
#ifdef T_WATCH_S3 #ifdef T_WATCH_S3
graphics::UIRenderer::drawBattery(display, x, y + 7, imgBattery, powerStatus);
if (powerStatus->getHasBattery()) {
char batteryPercent[8];
snprintf(batteryPercent, sizeof(batteryPercent), "%d%%", powerStatus->getBatteryChargePercent());
display->setFont(FONT_SMALL);
display->drawString(x + 20, y + 2, batteryPercent);
}
if (nimbleBluetooth && nimbleBluetooth->isConnected()) { if (nimbleBluetooth && nimbleBluetooth->isConnected()) {
drawBluetoothConnectedIcon(display, display->getWidth() - 18, y + 2); drawBluetoothConnectedIcon(display, display->getWidth() - 18, y + 2);
} }

View File

@ -67,21 +67,6 @@ void drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16
char channelStr[20]; char channelStr[20];
snprintf(channelStr, sizeof(channelStr), "#%s", channels.getName(channels.getPrimaryIndex())); snprintf(channelStr, sizeof(channelStr), "#%s", channels.getName(channels.getPrimaryIndex()));
// Display power status
if (powerStatus->getHasBattery()) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
UIRenderer::drawBattery(display, x, y + 2, imgBattery, powerStatus);
} else {
UIRenderer::drawBattery(display, x + 1, y + 3, imgBattery, powerStatus);
}
} else if (powerStatus->knowsUSB()) {
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
display->drawFastImage(x, y + 2, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
} else {
display->drawFastImage(x + 1, y + 3, 16, 8, powerStatus->getHasUSB() ? imgUSB : imgPower);
}
}
// Display nodes status // Display nodes status
if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) { if (config.display.displaymode == meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT) {
UIRenderer::drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus); UIRenderer::drawNodes(display, x + (SCREEN_WIDTH * 0.25), y + 2, nodeStatus);

View File

@ -189,46 +189,6 @@ void UIRenderer::drawGpsCoordinates(OLEDDisplay *display, int16_t x, int16_t y,
} }
} }
void UIRenderer::drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *imgBuffer,
const meshtastic::PowerStatus *powerStatus)
{
static const uint8_t powerBar[3] = {0x81, 0xBD, 0xBD};
static const uint8_t lightning[8] = {0xA1, 0xA1, 0xA5, 0xAD, 0xB5, 0xA5, 0x85, 0x85};
// Clear the bar area inside the battery image
for (int i = 1; i < 14; i++) {
imgBuffer[i] = 0x81;
}
// Fill with lightning or power bars
if (powerStatus->getIsCharging()) {
memcpy(imgBuffer + 3, lightning, 8);
} else {
for (int i = 0; i < 4; i++) {
if (powerStatus->getBatteryChargePercent() >= 25 * i)
memcpy(imgBuffer + 1 + (i * 3), powerBar, 3);
}
}
// Slightly more conservative scaling based on screen width
int scale = 1;
if (SCREEN_WIDTH >= 200)
scale = 2;
if (SCREEN_WIDTH >= 300)
scale = 2; // Do NOT go higher than 2
// Draw scaled battery image (16 columns × 8 rows)
for (int col = 0; col < 16; col++) {
uint8_t colBits = imgBuffer[col];
for (int row = 0; row < 8; row++) {
if (colBits & (1 << row)) {
display->fillRect(x + col * scale, y + row * scale, scale, scale);
}
}
}
}
// Draw nodes status // Draw nodes status
void UIRenderer::drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const meshtastic::NodeStatus *nodeStatus, int node_offset, void UIRenderer::drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const meshtastic::NodeStatus *nodeStatus, int node_offset,
bool show_total, String additional_words) bool show_total, String additional_words)

View File

@ -32,8 +32,6 @@ class UIRenderer
{ {
public: public:
// Common UI elements // Common UI elements
static void drawBattery(OLEDDisplay *display, int16_t x, int16_t y, uint8_t *imgBuffer,
const meshtastic::PowerStatus *powerStatus);
static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const meshtastic::NodeStatus *nodeStatus, static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const meshtastic::NodeStatus *nodeStatus,
int node_offset = 0, bool show_total = true, String additional_words = ""); int node_offset = 0, bool show_total = true, String additional_words = "");

View File

@ -23,9 +23,6 @@ const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03
0xf3, 0x3f, 0x33, 0x30, 0x33, 0x33, 0x33, 0x33, 0x03, 0x33, 0xff, 0x33, 0xf3, 0x3f, 0x33, 0x30, 0x33, 0x33, 0x33, 0x33, 0x03, 0x33, 0xff, 0x33,
0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f}; 0xfe, 0x31, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0xf0, 0x3f, 0xe0, 0x1f};
// This image definition is here instead of images.h because it's modified dynamically by the drawBattery function
static uint8_t imgBattery[16] = {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xE7, 0x3C};
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \ #if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || ARCH_PORTDUINO) && \ defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || ARCH_PORTDUINO) && \
!defined(DISPLAY_FORCE_SMALL_FONTS) !defined(DISPLAY_FORCE_SMALL_FONTS)

View File

@ -30,7 +30,7 @@
namespace graphics namespace graphics
{ {
extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *titleStr); extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *titleStr, bool battery_only);
} }
#if __has_include(<Adafruit_AHTX0.h>) #if __has_include(<Adafruit_AHTX0.h>)
#include "Sensor/AHT10.h" #include "Sensor/AHT10.h"

View File

@ -24,7 +24,7 @@
namespace graphics namespace graphics
{ {
extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *titleStr); extern void drawCommonHeader(OLEDDisplay *display, int16_t x, int16_t y, const char *titleStr, bool battery_only);
} }
int32_t PowerTelemetryModule::runOnce() int32_t PowerTelemetryModule::runOnce()