Adding the element pool and the main screen

This commit is contained in:
2025-11-11 22:31:38 +00:00
parent 2240517cc2
commit c9666792df
5 changed files with 63 additions and 26 deletions
+40 -12
View File
@@ -4,16 +4,20 @@
#include "HardwareSerial.h"
#include "UIDrawing.h"
// #include <U8g2lib.h>
#include <cstdarg>
#include <cstdint>
#include <cstring>
#define DEBUG 1
UIElement::UIElement()
: display(nullptr), dims(UIDimensions(0, 0, 0, 0)), decor(nullptr), title(nullptr) {}
: display(nullptr), dims(UIDimensions(0, 0, 0, 0)), decor(nullptr) {}
UIElement::UIElement(Arduino_GFX *d, UIDimensions dims, UIDecorations *decor,
char *title)
: display(d), dims(dims), decor(decor), title(title) {}
: display(d), dims(dims), decor(decor) {
strncpy(this->title, title, MAX_TITLE_LEN);
}
UIDimensions::UIDimensions(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
: x(x), y(y), width(w), height(h) {}
@@ -70,6 +74,13 @@ uint16_t UIElement::getTitleAreaWidth() {
return w;
}
void UIElement::SetTitle(char* format, ...) {
va_list args;
va_start(args, format);
vsnprintf(this->title, MAX_TITLE_LEN, format, args);
va_end(args);
}
void UIElement::replaceString(char *oldVal, char *newVal) {
size_t newValLen = strlen(newVal);
size_t oldValLen = strlen(oldVal);
@@ -110,21 +121,30 @@ void UIElement::replaceString(char *oldVal, char *newVal) {
}
}
UIElement* UIElement::AddChild() {
bool UIElement::AddChild() {
if (childrenCount >= MAX_CHILDREN) {
return nullptr;
Serial2.println("Failed to add child: childrenCount exceeds MAX_CHILDREN");
Serial2.print( childrenCount);
Serial2.print( " >= ");
Serial2.print( MAX_CHILDREN);
return false;
}
UIElement* newElem = WindowPool::Allocate();
if (!newElem) {
return newElem;
int16_t newElem = WindowPool::Allocate();
if (newElem < 0) {
Serial2.println("Failed to allocate new component");
return false;
}
this->children[this->curChildIndex] = newElem;
this->childrenCount++;
this->curChildIndex++;
return newElem;
return true;
}
UIElement* UIElement::GetChild(int16_t childID) {
return WindowPool::GetHandle(childID);
}
std::uint8_t UIElement::ChildrenCount() {
@@ -133,15 +153,23 @@ std::uint8_t UIElement::ChildrenCount() {
namespace WindowPool {
UIElement pool[MAX_WINDOWS];
uint16_t poolIndex = 0;
int16_t poolIndex = 0;
UIElement* Allocate() {
int16_t Allocate() {
if (poolIndex >= MAX_WINDOWS) {
return nullptr;
Serial2.println("Failed to allocate comp: poolIndex exceeds MAX_WINDOWS");
Serial2.print( poolIndex);
Serial2.print( " >= ");
Serial2.print( MAX_WINDOWS);
return -1;
}
return &pool[poolIndex];
return poolIndex;
poolIndex++;
}
UIElement* GetHandle(int16_t id) {
return &pool[poolIndex];
}
}
+11 -5
View File
@@ -9,6 +9,7 @@
#define MAX_WINDOWS 512
#define MAX_CHILDREN 32
#define MAX_TITLE_LEN 32
enum ComponentType {
STRING,
@@ -24,7 +25,7 @@ public:
Arduino_GFX *display;
UIDimensions dims;
UIDecorations *decor;
char *title;
char title[MAX_TITLE_LEN];
uint64_t lastUpdate = 0;
uint16_t refreshRate = 0;
ComponentType type;
@@ -34,10 +35,11 @@ public:
char *Title);
// Children
UIElement* children[MAX_CHILDREN];
int16_t children[MAX_CHILDREN];
// Children Handling
UIElement* AddChild();
bool AddChild();
UIElement* GetChild(int16_t childID);
uint8_t ChildrenCount();
// Getters
@@ -50,6 +52,9 @@ public:
uint16_t getTitleAreaHeight();
uint16_t getTitleAreaWidth();
// Setters
void SetTitle(char* format, ...);
// Positioning
void horizontalCenter(UIElement *reference);
void verticalCenter(UIElement *reference);
@@ -65,9 +70,10 @@ public:
namespace WindowPool {
extern UIElement pool[MAX_WINDOWS];
extern uint16_t poolIndex;
extern int16_t poolIndex;
UIElement* Allocate();
int16_t Allocate();
UIElement* GetHandle(int16_t index);
};
#endif
-8
View File
@@ -50,7 +50,6 @@ void UIElement::placeLeft(UIElement *ref) {
}
void UIElement::drawBox() {
Serial2.println("Drawing box!");
// This is the border rectangle
if (this->decor->hasBorder) {
for (int k = 0; k < DEFAULT_BORDER_THICKNESS; k++) {
@@ -60,18 +59,15 @@ void UIElement::drawBox() {
}
}
Serial2.println("Debug1");
// For debugging purpouses
// title area
int16_t x = 0, y = 0;
uint16_t w = 0, h = 0;
Serial2.println("Debug2");
// U8G2 u8g2; // No display pin setup needed since we're only using font data
// u8g2.setFont(u8g2_font_9x18_tf);
// int ascent = u8g2.getAscent();
Serial2.println("Debug3");
h = this->getTitleAreaHeight();
uint16_t titleAreaWidth = this->getTitleAreaWidth();
int16_t titleTopLeftX = this->getTitleAreaX0();
@@ -81,7 +77,6 @@ void UIElement::drawBox() {
h, GREEN);
#endif
Serial2.println("Debug4");
// content area
x = this->getContentAreaX0();
y = this->getContentAreaY0();
@@ -93,20 +88,17 @@ void UIElement::drawBox() {
this->display->drawRect(x, y, w, h, BLUE);
#endif
Serial2.println("Debug5");
if (this->decor->hasBorder) {
// Remove the border line behind the title
this->display->fillRect(titleTopLeftX - DEFAULT_MARGIN, this->dims.y,
titleAreaWidth + DEFAULT_MARGIN,
DEFAULT_BORDER_THICKNESS, MAIN_BG_COLOR);
Serial2.println("Debug6");
// Render the title
this->display->setCursor(titleTopLeftX, this->dims.y);
this->display->print(this->title);
}
Serial2.println("Debug7");
#ifdef DEBUG
// Element bounds
+10 -1
View File
@@ -1,6 +1,15 @@
#include "UIScreen.h"
#include "UIComponent.h"
#include "UIDecorations.h"
#include "UIDimensions.h"
Curses::Screen::Screen(Arduino_GFX *d, UIDimensions dims, UIDecorations decor)
: display(d), dims(dims), decor(decor) {};
: display(d), dims(dims), decor(decor) {
// This should always return the first available component
this->mainWindowID = WindowPool::Allocate();
if (this->mainWindowID != 0) {
// Something wrong happened
Serial2.print("Unexpected ID for main window: ");
Serial2.println(this->mainWindowID);
}
};
+2
View File
@@ -13,6 +13,8 @@ public:
UIDimensions dims;
UIDecorations decor;
Arduino_GFX *display;
int16_t mainWindowID;
Screen(Arduino_GFX *d, UIDimensions dims, UIDecorations decor);
};
}; // namespace Curses