diff options
-rw-r--r-- | .vscode/settings.json | 14 | ||||
-rw-r--r-- | api.cpp | 31 | ||||
-rw-r--r-- | api.hpp | 7 | ||||
-rw-r--r-- | apps/home_menu.cpp | 1 | ||||
-rw-r--r-- | oled/ss_oled.c | 29 |
5 files changed, 66 insertions, 16 deletions
diff --git a/.vscode/settings.json b/.vscode/settings.json index 4cbb933..e63b566 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,5 +19,17 @@ "cmake.buildBeforeRun": true, // This may need to be arm-none-eabi-gdb depending on your system "cortex-debug.gdbPath": "gdb-multiarch", - "C_Cpp.errorSquiggles": "Disabled" + "C_Cpp.errorSquiggles": "Disabled", + "files.associations": { + "cctype": "cpp", + "cmath": "cpp", + "cstdarg": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "type_traits": "cpp", + "limits": "cpp", + "*.tcc": "cpp", + "typeinfo": "cpp" + } }
\ No newline at end of file @@ -3,8 +3,6 @@ extern "C" { #include "hardware/rtc.h" } -#include "pico/util/datetime.h" -#include "oled/ss_oled.h" #include "api.hpp" #include "init.hpp" @@ -54,6 +52,35 @@ int Api::display_write_pixel(int x, int y, unsigned char ucColor, int bRender) { return oledSetPixel(&m_oled, x, y, ucColor, bRender); } +bool Api::gui_popup_text(std::string title, std::string body){ +#define CHARS_PER_LINE 13 + oledRectangle(&m_oled, 9,7, 119,63, 0, 1); // Background + oledRectangle(&m_oled, 9,7, 119,63, 1, 0); // Popup border + oledRectangle(&m_oled, 9,7, 119,16, 1, 1); // Title background + oledDumpBuffer(&m_oled, m_ucBuffer); // Display rectangle + + // Truncate longer strings to avoid wasting time in for loop and drawing on OLED + if (title.size() > 13) + title.resize(13); + if (body.size() > 78) + body.resize(78); + + // Make body fit by adding '\n' at a regular interval + int since_nl = 0; // Characters since newline + for(std::string::size_type i = 0; i < body.size(); ++i) { + if (body[i] == '\n') + since_nl = 0; + else if (since_nl++ == CHARS_PER_LINE) { + body.insert(i, 1, '\n'); + since_nl = 0; // Probably unneeded + } + } + // See https://stackoverflow.com/questions/1986966/does-s0-point-to-contiguous-characters-in-a-stdstring + oledWriteString(&m_oled, 0, 15,1, &title[0], FONT_8x8, 1, 1); // Draw title + oledWriteString(&m_oled, 0, 13,2, &body[0], FONT_8x8, 0, 1); // Draw body + while(1) {;} // TODO: change, this is temporary, only for this commit! +} + bool Api::datetime_get(datetime_t *t) { return rtc_get_datetime(t); } @@ -1,6 +1,7 @@ #ifndef __API_H__ #define __API_H__ +#include <iostream> #include "pico/util/datetime.h" #include "oled/ss_oled.h" @@ -19,6 +20,12 @@ class Api { void display_draw_ellipse(int iCenterX, int iCenterY, int32_t iRadiusX, int32_t iRadiusY, uint8_t ucColor, uint8_t bFilled); void display_write_buffer(uint8_t *pBuffer); int display_write_pixel(int x, int y, unsigned char ucColor, int bRender); + // Display a popup over the current view. + // This is a blocking function and should be used only in the app's render method. + // \param title Popup's title, length should not exceed 13 characters. + // \param body String containing the popup's body. The zone has a size of 13×6 characters, so body should not be longer than 78 characters. Newline allows going to the next line and the text is automatically wrapped. + // \note Strings longer than 13 and 78 respectively will be truncated. + bool gui_popup_text(std::string title, std::string body); bool datetime_get(datetime_t *t); }; diff --git a/apps/home_menu.cpp b/apps/home_menu.cpp index a3a0691..996b713 100644 --- a/apps/home_menu.cpp +++ b/apps/home_menu.cpp @@ -40,6 +40,7 @@ namespace app_home_menu { show_title(app_api); app_api->display_write_string(0,0,2, pressed_button, FONT_6x8, 0, 1); app_api->display_write_string(0,5,3, APPS_NAME[*selected_app], FONT_12x16, 0, 1); + app_api->gui_popup_text("Title is a string", "Body text, and new line. And this is a pretty long string.\nIterating is very fun!"); return 0; } diff --git a/oled/ss_oled.c b/oled/ss_oled.c index 3cd9132..3375bde 100644 --- a/oled/ss_oled.c +++ b/oled/ss_oled.c @@ -1486,20 +1486,23 @@ unsigned char c, *s, ucTemp[40]; if (iScroll < 8) // only display visible characters { c = (unsigned char)szMsg[i]; - iFontOff = (int)(c-32) * 7; - // we can't directly use the pointer to FLASH memory, so copy to a local buffer - ucTemp[0] = 0; - memcpy(&ucTemp[1], &ucFont[iFontOff], 7); - if (bInvert) InvertBytes(ucTemp, 8); - // oledCachedWrite(ucTemp, 8); - iLen = 8 - iFontSkip; - if (pOLED->iCursorX + iLen > pOLED->oled_x) // clip right edge - iLen = pOLED->oled_x - pOLED->iCursorX; - oledWriteDataBlock(pOLED, &ucTemp[iFontSkip], iLen, bRender); // write character pattern - pOLED->iCursorX += iLen; - if (pOLED->iCursorX >= pOLED->oled_x-7 && pOLED->oled_wrap) // word wrap enabled? + if (c != '\n') { // Do not draw the new line char + iFontOff = (int)(c-32) * 7; + // we can't directly use the pointer to FLASH memory, so copy to a local buffer + ucTemp[0] = 0; + memcpy(&ucTemp[1], &ucFont[iFontOff], 7); + if (bInvert) InvertBytes(ucTemp, 8); + // oledCachedWrite(ucTemp, 8); + iLen = 8 - iFontSkip; + if (pOLED->iCursorX + iLen > pOLED->oled_x) // clip right edge + iLen = pOLED->oled_x - pOLED->iCursorX; + oledWriteDataBlock(pOLED, &ucTemp[iFontSkip], iLen, bRender); // write character pattern + pOLED->iCursorX += iLen; + } + + if ((pOLED->iCursorX >= pOLED->oled_x-7 && pOLED->oled_wrap) || c == '\n') // word wrap enabled? or new line char { - pOLED->iCursorX = 0; // start at the beginning of the next line + pOLED->iCursorX = x; // start at the beginning of the next line pOLED->iCursorY++; oledSetPosition(pOLED, pOLED->iCursorX, pOLED->iCursorY, bRender); } |