From 62fb6d520984af4dd2a34068f68cdc1fe52e3926 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 28 Jun 2023 23:14:09 +1000 Subject: [PATCH] Starting to implement Elements --- source/Core/Drivers/OLED.cpp | 41 +++++++++++++++++++ source/Core/Drivers/OLED.hpp | 4 +- source/UI/UI_Elements.cpp | 78 ++++++++++++++++++++++-------------- source/UI/UI_Elements.h | 3 +- 4 files changed, 94 insertions(+), 32 deletions(-) diff --git a/source/Core/Drivers/OLED.cpp b/source/Core/Drivers/OLED.cpp index 71603b84..83fa065e 100644 --- a/source/Core/Drivers/OLED.cpp +++ b/source/Core/Drivers/OLED.cpp @@ -169,6 +169,7 @@ void OLED::drawChar(const uint16_t charCode, const FontStyle fontStyle) { case FontStyle::SMALL: case FontStyle::LARGE: default: + // TODO handle 4 lines if (charCode == '\x01' && cursor_y == 0) { // 0x01 is used as new line char setCursor(0, 8); return; @@ -431,6 +432,46 @@ void OLED::setInverseDisplay(bool inverse) { OLED_Setup_Array[21].val = normalInverseCmd; I2C_CLASS::I2C_RegisterWrite(DEVICEADDR_OLED, 0x80, normalInverseCmd); } +void OLED::printBounded(const char *str, const uint8_t x, const uint8_t y, const uint8_t w, const uint8_t h) { + setCursor(x, y); + const uint8_t *next = reinterpret_cast(str); + FontStyle fontStyle = FontStyle::SMALL; + if (next[0] == 0x01) { + fontStyle = FontStyle::LARGE; + next++; + } + // Now we walk and print + while (next[0]) { + uint16_t index; + if (next[0] <= 0xF0) { + index = next[0]; + next++; + } else { + if (!next[1]) { + return; + } + index = (next[0] - 0xF0) * 0xFF - 15 + next[1]; + next += 2; + } + if (index > 0x01) { + // Not a newline or terminator + // Need to make sure we clip + if (cursor_x >= (x + w)) { + // About to write out of bounds, wrap + if (fontStyle == FontStyle::SMALL) { + cursor_y += 8; + } else { + cursor_y += 16; + } + } + if (cursor_y >= y + h) { + // Clipping off bottom, yeet + return; + } + } + drawChar(index, fontStyle); + } +} // print a string to the current cursor location, len chars MAX void OLED::print(const char *const str, FontStyle fontStyle, uint8_t len) { diff --git a/source/Core/Drivers/OLED.hpp b/source/Core/Drivers/OLED.hpp index eb71b86a..102afe56 100644 --- a/source/Core/Drivers/OLED.hpp +++ b/source/Core/Drivers/OLED.hpp @@ -106,7 +106,9 @@ public: static void setBrightness(uint8_t contrast); static void setInverseDisplay(bool inverted); static int16_t getCursorX() { return cursor_x; } - static void print(const char *string, FontStyle fontStyle, uint8_t length = 255); // Draw a string to the current location, with selected font; optionally - with MAX length only + static void printBounded(const char *str, const uint8_t x, const uint8_t y, const uint8_t w, const uint8_t h); + static void print(const char *string, FontStyle fontStyle, + uint8_t length = 255); // Draw a string to the current location, with selected font; optionally - with MAX length only static void printWholeScreen(const char *string); // Set the cursor location by pixels static void setCursor(int16_t x, int16_t y) { diff --git a/source/UI/UI_Elements.cpp b/source/UI/UI_Elements.cpp index 56d7a017..d6799027 100644 --- a/source/UI/UI_Elements.cpp +++ b/source/UI/UI_Elements.cpp @@ -1,53 +1,73 @@ #include "UI_Elements.h" +#include "OLED.hpp" +void render_Text(const ElementSettings_t *settings, screen_arg_t *args); +void render_Number(const ElementSettings_t *settings, screen_arg_t *args); +void render_Image(const ElementSettings_t *settings, screen_arg_t *args); +void render_PowerSource(const ElementSettings_t *settings, screen_arg_t *args); +void render_Temperature(const ElementSettings_t *settings, screen_arg_t *args); +void render_InputVoltage(const ElementSettings_t *settings, screen_arg_t *args); +void render_ScrollBar(const ElementSettings_t *settings, screen_arg_t *args); +void render_CheckBox(const ElementSettings_t *settings, screen_arg_t *args); +void render_TextScroller(const ElementSettings_t *settings, screen_arg_t *args); -void render_Text(screen_arg_t *args); -void render_Number(screen_arg_t *args); -void render_Image(screen_arg_t *args); -void render_PowerSource(screen_arg_t *args); -void render_Temperature(screen_arg_t *args); -void render_InputVoltage(screen_arg_t *args); -void render_ScrollBar(screen_arg_t *args); -void render_CheckBox(screen_arg_t *args); -void render_TextScroller(screen_arg_t *args); - -void ui_render_element(ElementTypes_t element, screen_arg_t *args) { +void ui_render_element(const ElementTypes_t element, const ElementSettings_t *settings, screen_arg_t *args) { switch (element) { case ElementTypes_t::Text: - render_Text(args); + render_Text(settings, args); break; case ElementTypes_t::Number: - render_Number(args); + render_Number(settings, args); break; case ElementTypes_t::Image: - render_Image(args); + render_Image(settings, args); break; case ElementTypes_t::PowerSource: - render_PowerSource(args); + render_PowerSource(settings, args); break; case ElementTypes_t::Temperature: - render_Temperature(args); + render_Temperature(settings, args); break; case ElementTypes_t::InputVoltage: - render_InputVoltage(args); + render_InputVoltage(settings, args); break; case ElementTypes_t::ScrollBar: - render_ScrollBar(args); + render_ScrollBar(settings, args); break; case ElementTypes_t::CheckBox: - render_CheckBox(args); + render_CheckBox(settings, args); break; case ElementTypes_t::TextScroller: - render_TextScroller(args); + render_TextScroller(settings, args); break; } } -void render_Text(screen_arg_t *args) {} -void render_Number(screen_arg_t *args) {} -void render_Image(screen_arg_t *args) {} -void render_PowerSource(screen_arg_t *args) {} -void render_Temperature(screen_arg_t *args) {} -void render_InputVoltage(screen_arg_t *args) {} -void render_ScrollBar(screen_arg_t *args) {} -void render_CheckBox(screen_arg_t *args) {} -void render_TextScroller(screen_arg_t *args) {} \ No newline at end of file +void render_Text(const ElementSettings_t *settings, screen_arg_t *args) { + // Draw text clipped into bounds + // Args shall be a pointer to an encoded string + OLED::printBounded((const char *)args->ptr, settings->position.x, settings->position.y, settings->size.w, settings->size.h); +} +void render_Number(const ElementSettings_t *settings, screen_arg_t *args) { + // +} +void render_Image(const ElementSettings_t *settings, screen_arg_t *args) { + // +} +void render_PowerSource(const ElementSettings_t *settings, screen_arg_t *args) { + // +} +void render_Temperature(const ElementSettings_t *settings, screen_arg_t *args) { + // +} +void render_InputVoltage(const ElementSettings_t *settings, screen_arg_t *args) { + // +} +void render_ScrollBar(const ElementSettings_t *settings, screen_arg_t *args) { + // +} +void render_CheckBox(const ElementSettings_t *settings, screen_arg_t *args) { + // +} +void render_TextScroller(const ElementSettings_t *settings, screen_arg_t *args) { + // +} diff --git a/source/UI/UI_Elements.h b/source/UI/UI_Elements.h index 14b654d5..123dd008 100644 --- a/source/UI/UI_Elements.h +++ b/source/UI/UI_Elements.h @@ -22,7 +22,6 @@ typedef struct { uint8_t h; } size; - } ElementSettings_t; -void ui_render_element(ElementTypes_t element, screen_arg_t *args); \ No newline at end of file +void ui_render_element(const ElementTypes_t element,const ElementSettings_t * settings, screen_arg_t *args); \ No newline at end of file