Adding the element pool and the main screen
This commit is contained in:
+40
-12
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user