Well, Dynamic memory it is. Only for the layout configuration at least

This commit is contained in:
2025-11-13 22:45:50 +00:00
parent 962926333f
commit 3ba1ff5b59
11 changed files with 167 additions and 85 deletions
+2
View File
@@ -1,6 +1,8 @@
#include "UIBar.h"
#include "UIComponent.h"
#include "UIDrawing.h"
UIBar::UIBar() {};
UIBar::UIBar(Arduino_GFX *d, UIDimensions dims, UIDecorations decor,
char *title)
: UIElement(d, dims, decor, title) {}
+1
View File
@@ -9,6 +9,7 @@ struct UIBar : UIElement {
uint32_t value = 0; // current tach value
uint8_t range = 0; // define the tach range, ie: 8 for 8000rpm
UIBar();
UIBar(Arduino_GFX *d, UIDimensions dims, UIDecorations decor, char *title);
void Update(char *val);
+4 -55
View File
@@ -1,4 +1,6 @@
#include "UIComponent.h"
#include "values.h"
#include "windowPool.h"
// #include "u8g2.h"
#include "Arduino.h"
#include "HardwareSerial.h"
@@ -130,7 +132,7 @@ void UIElement::replaceString(char *oldVal, char *newVal) {
}
}
bool UIElement::AddChild() {
bool UIElement::AddChild(ComponentType t) {
if (childrenCount >= MAX_CHILDREN) {
Serial2.println("Failed to add child: childrenCount exceeds MAX_CHILDREN");
Serial2.print( childrenCount);
@@ -139,7 +141,7 @@ bool UIElement::AddChild() {
return false;
}
int16_t newElem = WindowPool::Allocate();
int16_t newElem = WindowPool::Allocate(t);
if (newElem < 0) {
Serial2.println("Failed to allocate new component");
return false;
@@ -160,56 +162,3 @@ std::uint8_t UIElement::ChildrenCount() {
return this->childrenCount;
}
namespace WindowPool {
UIElement pool[MAX_WINDOWS];
bool inUse[MAX_WINDOWS] = {false};
static inline int16_t getNextIndex() {
for (int k = 0; k < MAX_WINDOWS; k++) {
if (!inUse[k]) {
return k;
}
}
return -1;
}
int16_t Allocate() {
int16_t nextIndex = getNextIndex();
if (nextIndex < 0) {
Serial2.println("Failed to allocate comp: poolIndex exceeds MAX_WINDOWS");
Serial2.print( nextIndex);
Serial2.print( " >= ");
Serial2.println( MAX_WINDOWS);
return -1;
}
// Mark it as in use
inUse[nextIndex] = true;
return nextIndex;
}
void Deallocate(int16_t id) {
pool[id].SetTitle((char*)"");
pool[id].SetUIDimensions(UIDimensions(0, 0, 0, 0));
pool[id].SetUIDecorations(UIDecorations());
inUse[id] = false;
}
UIElement* GetHandle(int16_t id) {
return &pool[id];
}
void PrintInUse() {
for (int k = 0; k < MAX_WINDOWS; k++) {
if (inUse[k]) {
Serial2.print(k);
Serial2.print(" : ");
Serial2.println(inUse[k]);
}
}
}
}
+4 -26
View File
@@ -1,21 +1,13 @@
#ifndef __UI_COMPONENT
#define __UI_COMPONENT
#ifndef __UI_COMPONENT__
#define __UI_COMPONENT__
#include "Arduino_GFX.h"
#include "values.h"
#include "UIDecorations.h"
#include "UIDimensions.h"
#include <cstdint>
#include <stdint.h>
#define MAX_WINDOWS 512
#define MAX_CHILDREN 32
#define MAX_TITLE_LEN 32
enum ComponentType {
STRING,
TABLE,
};
class UIElement {
private:
uint8_t childrenCount = 0;
@@ -38,7 +30,7 @@ public:
int16_t children[MAX_CHILDREN];
// Children Handling
bool AddChild();
bool AddChild(ComponentType t);
UIElement* GetChild(int16_t childID);
uint8_t ChildrenCount();
@@ -71,18 +63,4 @@ public:
void replaceString(char *oldVal, char *newVal);
};
namespace WindowPool {
extern UIElement pool[MAX_WINDOWS];
extern bool inUse[MAX_WINDOWS];
int16_t Allocate();
// I will finish this later on, still have to figure out how to properly
// destroy the UIComponent
void Deallocate();
UIElement* GetHandle(int16_t index);
// Debugging
void PrintInUse();
};
#endif
+2 -1
View File
@@ -1,4 +1,5 @@
#include "UIScreen.h"
#include "windowPool.h"
#include "UIComponent.h"
#include "UIDecorations.h"
#include "UIDimensions.h"
@@ -10,7 +11,7 @@ Curses::Screen::Screen(Arduino_GFX *d, UIDimensions dims,
void Curses::Screen::Setup(const char* title) {
// This should always return the first available component
this->mainWindowID = WindowPool::Allocate();
this->mainWindowID = WindowPool::Allocate(BASE);
if (this->mainWindowID != 0) {
// Something wrong happened
Serial2.print("Unexpected ID for main window: ");
+3 -3
View File
@@ -1,11 +1,11 @@
#ifndef __UI_STRING
#define __UI_STRING
#ifndef __UI_STRING__
#define __UI_STRING__
#include "UIComponent.h"
// Representation of single line strings
struct UIString : UIElement {
static const size_t bufferSize = 64;
static const std::size_t bufferSize = 64;
char value[bufferSize];
UIString();
+1
View File
@@ -6,6 +6,7 @@
#define DEBUG
UITable::UITable() {};
UITable::UITable(Arduino_GFX *gfx, UIDimensions dims, UIDecorations decor,
int nRows, int nCols, int *colWidths, char *title)
: UIElement(gfx, dims, decor, title) {
+1
View File
@@ -18,6 +18,7 @@ struct UITable : UIElement {
int *colWidths;
UIString **tableData;
UITable();
UITable(Arduino_GFX *gfx, UIDimensions dims, UIDecorations decor, int nR,
int nC, int *cWidth, char *t);
+15
View File
@@ -0,0 +1,15 @@
#ifndef __VALUES__
#define __VALUES__
#define MAX_WINDOWS 512
#define MAX_CHILDREN 32
#define MAX_TITLE_LEN 32
enum ComponentType {
BASE,
BAR,
STRING,
TABLE,
};
#endif
+98
View File
@@ -0,0 +1,98 @@
#include "windowPool.h"
#include "UIComponent.h"
#include "UIBar.h"
#include "UIString.h"
#include "UITable.h"
#include "values.h"
namespace WindowPool {
WindowEntry pool[MAX_WINDOWS];
bool inUse[MAX_WINDOWS] = {false};
static inline int16_t getNextIndex() {
for (int k = 0; k < MAX_WINDOWS; k++) {
if (!inUse[k]) {
return k;
}
}
return -1;
}
int16_t Allocate(ComponentType t) {
int16_t nextIndex = getNextIndex();
if (nextIndex < 0) {
Serial2.println("Failed to allocate comp: poolIndex exceeds MAX_WINDOWS");
Serial2.print( nextIndex);
Serial2.print( " >= ");
Serial2.println( MAX_WINDOWS);
return -1;
}
pool[nextIndex].type = t;
switch(pool[nextIndex].type) {
case BAR:
pool[nextIndex].bar = new UIBar();
break;
case STRING:
pool[nextIndex].str = new UIString();
break;
case TABLE:
pool[nextIndex].table = new UITable();
break;
case BASE:
pool[nextIndex].base = new UIElement();
break;
}
// Mark it as in use
inUse[nextIndex] = true;
return nextIndex;
}
void Deallocate(int16_t id) {
switch(pool[id].type) {
case BAR:
break;
case STRING:
break;
case TABLE:
break;
case BASE:
break;
}
inUse[id] = false;
}
UIElement* GetHandle(int16_t id) {
switch(pool[id].type) {
case BAR:
return pool[id].bar;
break;
case STRING:
return pool[id].str;
break;
case TABLE:
return pool[id].table;
break;
case BASE:
return pool[id].base;
break;
}
return nullptr;
}
void PrintInUse() {
for (int k = 0; k < MAX_WINDOWS; k++) {
if (inUse[k]) {
Serial2.print(k);
Serial2.print(" : ");
Serial2.println(inUse[k]);
}
}
}
}
+36
View File
@@ -0,0 +1,36 @@
#ifndef __WINDOW_POOL__
#define __WINDOW_POOL__
#include <stdint.h>
#include "values.h"
struct UIElement;
struct UIString;
struct UIBar;
struct UITable;
namespace WindowPool {
struct WindowEntry {
ComponentType type;
union {
UIElement* base;
UIString* str;
UIBar* bar;
UITable* table;
};
};
extern WindowEntry pool[MAX_WINDOWS];
extern bool inUse[MAX_WINDOWS];
int16_t Allocate(ComponentType t);
// I will finish this later on, still have to figure out how to properly
// destroy the UIComponent
void Deallocate();
UIElement* GetHandle(int16_t index);
// Debugging
void PrintInUse();
};
#endif