From 1ca1866d017427c7d1488047cf436b9d4d03f269 Mon Sep 17 00:00:00 2001 From: Alex <15167344+frostmorn@users.noreply.github.com> Date: Sat, 3 Oct 2026 00:55:30 +0000 Subject: [PATCH 1/3] Add helpers for ToolBar in App --- src/apps/fmanager/fmanager.cpp | 53 ++++++++++++++-------------- src/apps/fmanager/fmanager.h | 18 ++++------ src/apps/partmanager/partmanager.cpp | 16 +++------ src/apps/partmanager/partmanager.h | 14 ++------ src/keira/app.cpp | 27 ++++++++++++++ src/keira/app.h | 27 ++++++++++++-- 6 files changed, 93 insertions(+), 62 deletions(-) diff --git a/src/apps/fmanager/fmanager.cpp b/src/apps/fmanager/fmanager.cpp index e4f7b076..0bebed67 100644 --- a/src/apps/fmanager/fmanager.cpp +++ b/src/apps/fmanager/fmanager.cpp @@ -317,8 +317,10 @@ FMEntry FileManagerApp::pathToEntry(const String& path) { newEntry.type = FT_JS_SCRIPT; newEntry.icon = FT_JS_SCRIPT_ICON; newEntry.color = FT_JS_SCRIPT_COLOR; - } else if (lowerCasedPath.endsWith(".mod") || lowerCasedPath.endsWith(".wav") || lowerCasedPath.endsWith(".mp3") || - lowerCasedPath.endsWith(".aac") || lowerCasedPath.endsWith(".flac")) { + } else if ( + lowerCasedPath.endsWith(".mod") || lowerCasedPath.endsWith(".wav") || lowerCasedPath.endsWith(".mp3") || + lowerCasedPath.endsWith(".aac") || lowerCasedPath.endsWith(".flac") + ) { newEntry.type = FT_SOUND; newEntry.icon = FT_SOUND_ICON; newEntry.color = FT_SOUND_COLOR; @@ -330,8 +332,10 @@ FMEntry FileManagerApp::pathToEntry(const String& path) { newEntry.type = FT_SO; newEntry.icon = FT_SO_ICON; newEntry.color = FT_SO_COLOR; - } else if (lowerCasedPath.endsWith(".png") || lowerCasedPath.endsWith(".jpg") || lowerCasedPath.endsWith(".jpeg") || - lowerCasedPath.endsWith(".gif") || lowerCasedPath.endsWith(".bmp")) { + } else if ( + lowerCasedPath.endsWith(".png") || lowerCasedPath.endsWith(".jpg") || lowerCasedPath.endsWith(".jpeg") || + lowerCasedPath.endsWith(".gif") || lowerCasedPath.endsWith(".bmp") + ) { newEntry.type = FT_IMAGE; newEntry.icon = FT_IMAGE_ICON; newEntry.color = FT_IMAGE_COLOR; @@ -1328,7 +1332,8 @@ void FileManagerApp::run() { } void FileManagerApp::queueDraw() { - drawStatusBar(); + // TODO: ToolBar part unified, so we can probably avoid overriding queueDraw at all + drawToolBar(); App::queueDraw(); } void FileManagerApp::spaceUsageUpdate() { @@ -1344,43 +1349,37 @@ void FileManagerApp::spaceUsageUpdate() { } } } -void FileManagerApp::drawStatusBar() { - spaceUsageUpdate(); - canvas->fillRect( - 0, canvas->height() - STATUS_BAR_HEIGHT, canvas->width(), STATUS_BAR_HEIGHT, STATUS_BAR_FILL_COLOR - ); - // Uncomment those to get an idea where is x, and where is y - // Draw xy - //canvas->drawLine(0, 0, 50, 0, lilka::colors::Red); - //canvas->drawLine(0, 0, 0, 50, lilka::colors::Blue); - // canvas->printf("Height %d, width %d", canvas->height(), canvas->width()); +void FileManagerApp::drawToolBar() { + sToolBar = ""; - canvas->setCursor(STATUS_BAR_SAFE_DISTANCE, canvas->height() - 20 / 2); // FONT_Y / 2 - canvas->setFont(FONT_8x13); + uint16_t toolBarColor = lilka::colors::White; + uint16_t toolBarBgColor = lilka::colors::Black; - canvas->setTextBound( - STATUS_BAR_SAFE_DISTANCE, canvas->height() - STATUS_BAR_HEIGHT, STATUS_BAR_WIDTH, STATUS_BAR_HEIGHT - ); // Show errno if set if (errno != 0) { errnoTime = millis(); errnoStr = String(errno) + ":" + strerror(errno); errno = 0; } + if ((millis() - errnoTime) <= FM_ERRNO_TIME) { - canvas->setTextColor(lilka::colors::Red); - canvas->printf("%s", errnoStr.c_str()); + toolBarColor = lilka::colors::Red; + sToolBar = errnoStr.c_str(); return; } // Other significant data to show if (mode == FM_MODE_SELECT) { - canvas->setTextColor(lilka::colors::White); - canvas->printf(K_S_FMANAGER_SELECTED_FILES_FMT, selectedDirEntries.size()); + sToolBar = StringFormat(K_S_FMANAGER_SELECTED_FILES_FMT, selectedDirEntries.size()); } else if (mode == FM_MODE_VIEW) { - canvas->setTextColor(lilka::colors::White); auto fileListMenuIndex = fileListMenu.getCursor(); auto dirLength = currentDirEntries.size(); - if (fileListMenuIndex != dirLength) - canvas->printf("(%s) [ %d / %d ] ", spaceUsageStr.c_str(), fileListMenuIndex + 1, dirLength); + if (fileListMenuIndex != dirLength) { + spaceUsageUpdate(); + sToolBar = StringFormat("(%s) [ %d / %d ] ", spaceUsageStr.c_str(), fileListMenuIndex + 1, dirLength); + } } + + // Configure tool bar + setToolBarColor(toolBarColor, toolBarBgColor); + setToolBar(sToolBar); } diff --git a/src/apps/fmanager/fmanager.h b/src/apps/fmanager/fmanager.h index 53048fed..6696887a 100644 --- a/src/apps/fmanager/fmanager.h +++ b/src/apps/fmanager/fmanager.h @@ -70,14 +70,9 @@ #define FM_MKDIR_MODE 0777 #define FM_DEFAULT_NEW_FOLDER_NAME "New Folder" -// STATUS BAR SETTINGS: ///////////////////////////////////////////////////// -#define STATUS_BAR_HEIGHT 30 -#define STATUS_BAR_SAFE_DISTANCE 38 -#define STATUS_BAR_WIDTH canvas->width() - STATUS_BAR_SAFE_DISTANCE * 2 -#define STATUS_BAR_TEXT_COLOR lilka::colors::White -#define STATUS_BAR_FILL_COLOR lilka::colors::Black -#define FM_ERRNO_TIME 5000 // time to show last error -#define FM_FREE_SPACE_UPDATE 5000 +// TOOL BAR SETTINGS: /////////////////////////////////////////////////////// +#define FM_ERRNO_TIME 5000 // time to show last error +#define FM_FREE_SPACE_UPDATE 5000 ////////////////////////////////////////////////////////////////////////////// #define ENTRY_NOT_FOUND_INDEX UINT16_MAX @@ -111,7 +106,7 @@ // very bad test // /sd/1 => /sd/1122/1 -// no need with status bar +// no need with tool bar #define MAKE_SANDWICH(X) \ if (0) ksystem.apps.startToast(X) @@ -258,7 +253,7 @@ class FileManagerApp : public App { int lastSpaceUsageTime = 0; // Manual draw - void drawStatusBar(); + void drawToolBar(); void spaceUsageUpdate(); // updates freeSpaceStr for current filesystem(by dir) // Menu: @@ -326,8 +321,9 @@ class FileManagerApp : public App { std::vector> currentDirEntries; std::vector> selectedDirEntries; - // Status bar stuff + // Tool bar stuff int errnoTime = 0; String errnoStr = ""; String spaceUsageStr = ""; + String sToolBar = ""; }; diff --git a/src/apps/partmanager/partmanager.cpp b/src/apps/partmanager/partmanager.cpp index 54888706..c8f5870b 100644 --- a/src/apps/partmanager/partmanager.cpp +++ b/src/apps/partmanager/partmanager.cpp @@ -571,19 +571,13 @@ void PartManagerApp::run() { // Drawing StatusBar //? Toolbar, right? ///////////////////////////////////////////////////////////////////////////// void PartManagerApp::queueDraw() { - canvas->fillRect( - 0, canvas->height() - STATUS_BAR_HEIGHT, canvas->width(), STATUS_BAR_HEIGHT, STATUS_BAR_FILL_COLOR - ); - - canvas->setCursor(STATUS_BAR_SAFE_DISTANCE, canvas->height() - 20 / 2); // FONT_Y / 2 - canvas->setFont(FONT_8x13); - - canvas->setTextBound( - STATUS_BAR_SAFE_DISTANCE, canvas->height() - STATUS_BAR_HEIGHT, STATUS_BAR_WIDTH, STATUS_BAR_HEIGHT - ); + sToolBar = ""; if (selectedParts.size() > 0) { - canvas->printf(K_S_PART_MGR_SELECTED_ENTRIES_FMT, selectedParts.size()); + sToolBar = StringFormat(K_S_PART_MGR_SELECTED_ENTRIES_FMT, selectedParts.size()); } + + setToolBar(sToolBar); + App::queueDraw(); } ///////////////////////////////////////////////////////////////////////////// diff --git a/src/apps/partmanager/partmanager.h b/src/apps/partmanager/partmanager.h index 82545980..5ebcdf82 100644 --- a/src/apps/partmanager/partmanager.h +++ b/src/apps/partmanager/partmanager.h @@ -24,17 +24,6 @@ #define PART_MGR_SELECTED_PART_ICON &selectedfile_img ///////////////////////////////////////////////////////////////////////////// -///////////////////////////////////////////////////////////////////////////// -// TODO: Requires unification as additional feature of App -// StatusBar(ToolBar): -///////////////////////////////////////////////////////////////////////////// -#define STATUS_BAR_HEIGHT 30 -#define STATUS_BAR_SAFE_DISTANCE 38 -#define STATUS_BAR_WIDTH canvas->width() - STATUS_BAR_SAFE_DISTANCE * 2 -#define STATUS_BAR_TEXT_COLOR lilka::colors::White -#define STATUS_BAR_FILL_COLOR lilka::colors::Black -///////////////////////////////////////////////////////////////////////////// - ///////////////////////////////////////////////////////////////////////////// // Debug ///////////////////////////////////////////////////////////////////////////// @@ -106,4 +95,7 @@ class PartManagerApp : public App { size_t lastProgress = 0; // cursor of partListMenu as well as index in lilka::partitions std::vector selectedParts; + + // ToolBar + String sToolBar = ""; }; diff --git a/src/keira/app.cpp b/src/keira/app.cpp index ccedffc6..a2c283ab 100644 --- a/src/keira/app.cpp +++ b/src/keira/app.cpp @@ -121,6 +121,18 @@ String App::input(const String& title, const String& value, bool masked) { return inputDialog.getValue(); } /////////////////////////////////////////////////////////////////////////////// +//======================================================================== +// App UI Misc: +//======================================================================== +// Set toolbar contents +void App::setToolBar(const String& toolbar) { + this->toolBarLabel = toolbar; +} +void App::setToolBarColor(uint16_t color, uint16_t bgcolor) { + this->toolBarColor = color; + this->toolBarBgColor = bgcolor; +} +////////////////////////////////////////////////////////////////////////// //============================================================================= // App Canvas management //============================================================================= @@ -211,6 +223,21 @@ void App::deinitCanvas() { } //----------------------------------------------------------------------------- void App::queueDraw() { + // Draw toolbar on top of canvas + if (toolBarLabel != "") { + canvas->fillRect(0, canvas->height() - TOOL_BAR_HEIGHT, canvas->width(), TOOL_BAR_HEIGHT, this->toolBarBgColor); + + canvas->setCursor(TOOL_BAR_SAFE_DISTANCE, canvas->height() - 20 / 2); // FONT_Y / 2 + canvas->setFont(FONT_8x13); + canvas->setTextColor(this->toolBarColor); + + canvas->setTextBound( + TOOL_BAR_SAFE_DISTANCE, canvas->height() - TOOL_BAR_HEIGHT, TOOL_BAR_WIDTH, TOOL_BAR_HEIGHT + ); + + canvas->printf(this->toolBarLabel.c_str()); + } + KMTX_LOCK(canvasMutex); // Detect if frame was skipped. Need to readjust priorities in this case diff --git a/src/keira/app.h b/src/keira/app.h index 43b402e2..2b8cca1e 100644 --- a/src/keira/app.h +++ b/src/keira/app.h @@ -14,6 +14,11 @@ #define APP_CAST(X) reinterpret_cast(X) #define APP_PCAST(X) reinterpret_cast(X) +// Toolbar +#define TOOL_BAR_HEIGHT 30 +#define TOOL_BAR_SAFE_DISTANCE 38 +#define TOOL_BAR_WIDTH canvas->width() - TOOL_BAR_SAFE_DISTANCE * 2 + //============================================================================ // App Flags //============================================================================ @@ -54,6 +59,8 @@ class App : public KeiraThread { //======================================================================== void setFlags(AppFlags_t flags); AppFlags_t getFlags(); + ////////////////////////////////////////////////////////////////////////// + //======================================================================== // App UI Dialogs: //======================================================================== @@ -68,14 +75,23 @@ class App : public KeiraThread { bool errnocheck(); // Simple lilka::InputDialog String input(const String& title, const String& value = "", bool masked = false); + ////////////////////////////////////////////////////////////////////////// + //======================================================================== + // App UI Misc: + //======================================================================== + // Set toolbar contents + void setToolBar(const String& toolbar); + // Set toolbar colors + void setToolBarColor(uint16_t color = lilka::colors::White, uint16_t bgcolor = lilka::colors::Black); ////////////////////////////////////////////////////////////////////////// + //======================================================================== // App Canvas management //======================================================================== - // Retrieves current redraw status. true indicates redraw needed + // Retrieves current redraw status. true indicates redraw needed bool getRedraw(); - // Set redraw status + // Set redraw status void setRedraw(bool redraw); // Initializes canvas, recreates canvas on flag changes void initCanvas(); @@ -88,6 +104,13 @@ class App : public KeiraThread { // TODO: lastFrame, FPS meter private: SemaphoreHandle_t canvasMutex = xSemaphoreCreateMutex(); + bool redraw = false; + AppFlags_t flags = AppFlags::APP_FLAG_NONE; + + // Toolbar: + String toolBarLabel; + uint16_t toolBarColor = lilka::colors::White; + uint16_t toolBarBgColor = lilka::colors::Black; }; From c4466f20c0b76c64aad080095ba06137e2007807 Mon Sep 17 00:00:00 2001 From: Alex <15167344+frostmorn@users.noreply.github.com> Date: Sat, 3 Oct 2026 04:49:54 +0300 Subject: [PATCH 2/3] clang-format/fix errno message display in fmanager toolbar --- src/apps/fmanager/fmanager.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/apps/fmanager/fmanager.cpp b/src/apps/fmanager/fmanager.cpp index 0bebed67..1f6b46ad 100644 --- a/src/apps/fmanager/fmanager.cpp +++ b/src/apps/fmanager/fmanager.cpp @@ -317,10 +317,8 @@ FMEntry FileManagerApp::pathToEntry(const String& path) { newEntry.type = FT_JS_SCRIPT; newEntry.icon = FT_JS_SCRIPT_ICON; newEntry.color = FT_JS_SCRIPT_COLOR; - } else if ( - lowerCasedPath.endsWith(".mod") || lowerCasedPath.endsWith(".wav") || lowerCasedPath.endsWith(".mp3") || - lowerCasedPath.endsWith(".aac") || lowerCasedPath.endsWith(".flac") - ) { + } else if (lowerCasedPath.endsWith(".mod") || lowerCasedPath.endsWith(".wav") || lowerCasedPath.endsWith(".mp3") || + lowerCasedPath.endsWith(".aac") || lowerCasedPath.endsWith(".flac")) { newEntry.type = FT_SOUND; newEntry.icon = FT_SOUND_ICON; newEntry.color = FT_SOUND_COLOR; @@ -332,10 +330,8 @@ FMEntry FileManagerApp::pathToEntry(const String& path) { newEntry.type = FT_SO; newEntry.icon = FT_SO_ICON; newEntry.color = FT_SO_COLOR; - } else if ( - lowerCasedPath.endsWith(".png") || lowerCasedPath.endsWith(".jpg") || lowerCasedPath.endsWith(".jpeg") || - lowerCasedPath.endsWith(".gif") || lowerCasedPath.endsWith(".bmp") - ) { + } else if (lowerCasedPath.endsWith(".png") || lowerCasedPath.endsWith(".jpg") || lowerCasedPath.endsWith(".jpeg") || + lowerCasedPath.endsWith(".gif") || lowerCasedPath.endsWith(".bmp")) { newEntry.type = FT_IMAGE; newEntry.icon = FT_IMAGE_ICON; newEntry.color = FT_IMAGE_COLOR; @@ -1365,12 +1361,14 @@ void FileManagerApp::drawToolBar() { if ((millis() - errnoTime) <= FM_ERRNO_TIME) { toolBarColor = lilka::colors::Red; sToolBar = errnoStr.c_str(); - return; } + // Other significant data to show - if (mode == FM_MODE_SELECT) { + if (sTooBar == "" && mode == FM_MODE_SELECT) { sToolBar = StringFormat(K_S_FMANAGER_SELECTED_FILES_FMT, selectedDirEntries.size()); - } else if (mode == FM_MODE_VIEW) { + } + + if (sTooBar == "" && mode == FM_MODE_VIEW) { auto fileListMenuIndex = fileListMenu.getCursor(); auto dirLength = currentDirEntries.size(); if (fileListMenuIndex != dirLength) { From ea4b58eb2ef744361b1bdde3782a1048231f4ffc Mon Sep 17 00:00:00 2001 From: Alex <15167344+frostmorn@users.noreply.github.com> Date: Sat, 3 Oct 2026 04:54:17 +0300 Subject: [PATCH 3/3] typo fix --- src/apps/fmanager/fmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/fmanager/fmanager.cpp b/src/apps/fmanager/fmanager.cpp index 1f6b46ad..ecb62d98 100644 --- a/src/apps/fmanager/fmanager.cpp +++ b/src/apps/fmanager/fmanager.cpp @@ -1364,11 +1364,11 @@ void FileManagerApp::drawToolBar() { } // Other significant data to show - if (sTooBar == "" && mode == FM_MODE_SELECT) { + if (sToolBar == "" && mode == FM_MODE_SELECT) { sToolBar = StringFormat(K_S_FMANAGER_SELECTED_FILES_FMT, selectedDirEntries.size()); } - if (sTooBar == "" && mode == FM_MODE_VIEW) { + if (sToolBar == "" && mode == FM_MODE_VIEW) { auto fileListMenuIndex = fileListMenu.getCursor(); auto dirLength = currentDirEntries.size(); if (fileListMenuIndex != dirLength) {