Adding some ammenities so that we can have better layout support
This commit is contained in:
+41
-2
@@ -8,6 +8,9 @@
|
||||
|
||||
#define DEBUG 1
|
||||
|
||||
UIElement::UIElement()
|
||||
: display(nullptr), dims(UIDimensions(0, 0, 0, 0)), decor(nullptr), title(nullptr) {}
|
||||
|
||||
UIElement::UIElement(Arduino_GFX *d, UIDimensions dims, UIDecorations *decor,
|
||||
char *title)
|
||||
: display(d), dims(dims), decor(decor), title(title) {}
|
||||
@@ -82,7 +85,7 @@ void UIElement::replaceString(char *oldVal, char *newVal) {
|
||||
if (oldValLen > newValLen) {
|
||||
// If the old value is longer than the new value, we have to delete the
|
||||
// extra of the old value, which is whatever starts at the new value len
|
||||
for (size_t start = newValLen; start < oldValLen; start++) {
|
||||
for (std::size_t start = newValLen; start < oldValLen; start++) {
|
||||
this->display->setCursor(x0 + start * (CHR_WIDTH(this->decor->textSize)),
|
||||
y0);
|
||||
this->display->setTextColor(this->decor->bgColor);
|
||||
@@ -90,7 +93,7 @@ void UIElement::replaceString(char *oldVal, char *newVal) {
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t k = 0; k < newValLen; k++) {
|
||||
for (std::size_t k = 0; k < newValLen; k++) {
|
||||
if (k <= oldValLen) {
|
||||
if (oldVal[k] != newVal[k]) {
|
||||
this->display->setCursor(x0 + k * (CHR_WIDTH(this->decor->textSize)),
|
||||
@@ -106,3 +109,39 @@ void UIElement::replaceString(char *oldVal, char *newVal) {
|
||||
this->display->print(newVal[k]);
|
||||
}
|
||||
}
|
||||
|
||||
UIElement* UIElement::AddChild() {
|
||||
if (childrenCount >= MAX_CHILDREN) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UIElement* newElem = WindowPool::Allocate();
|
||||
if (!newElem) {
|
||||
return newElem;
|
||||
}
|
||||
|
||||
this->children[this->curChildIndex] = newElem;
|
||||
this->childrenCount++;
|
||||
this->curChildIndex++;
|
||||
|
||||
return newElem;
|
||||
}
|
||||
|
||||
std::uint8_t UIElement::ChildrenCount() {
|
||||
return this->childrenCount;
|
||||
}
|
||||
|
||||
namespace WindowPool {
|
||||
UIElement pool[MAX_WINDOWS];
|
||||
uint16_t poolIndex = 0;
|
||||
|
||||
UIElement* Allocate() {
|
||||
if (poolIndex >= MAX_WINDOWS) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return &pool[poolIndex];
|
||||
poolIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+25
-7
@@ -3,21 +3,24 @@
|
||||
|
||||
#include "Arduino_GFX.h"
|
||||
#include "UIDecorations.h"
|
||||
#include "UIDimensions.h"
|
||||
#include <cstdint>
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_WINDOWS 512
|
||||
#define MAX_CHILDREN 32
|
||||
|
||||
enum ComponentType {
|
||||
STRING,
|
||||
TABLE,
|
||||
};
|
||||
|
||||
struct UIDimensions {
|
||||
uint16_t x = 0, y = 0;
|
||||
uint16_t width = 0, height = 0;
|
||||
class UIElement {
|
||||
private:
|
||||
uint8_t childrenCount = 0;
|
||||
int8_t curChildIndex = -1; // Start at -1, have no children
|
||||
|
||||
UIDimensions(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||||
};
|
||||
|
||||
struct UIElement {
|
||||
public:
|
||||
Arduino_GFX *display;
|
||||
UIDimensions dims;
|
||||
UIDecorations *decor;
|
||||
@@ -26,9 +29,17 @@ struct UIElement {
|
||||
uint16_t refreshRate = 0;
|
||||
ComponentType type;
|
||||
|
||||
UIElement();
|
||||
UIElement(Arduino_GFX *d, UIDimensions dims, UIDecorations *decor,
|
||||
char *Title);
|
||||
|
||||
// Children
|
||||
UIElement* children[MAX_CHILDREN];
|
||||
|
||||
// Children Handling
|
||||
UIElement* AddChild();
|
||||
uint8_t ChildrenCount();
|
||||
|
||||
// Getters
|
||||
int16_t getContentAreaX0();
|
||||
int16_t getContentAreaY0();
|
||||
@@ -52,4 +63,11 @@ struct UIElement {
|
||||
void replaceString(char *oldVal, char *newVal);
|
||||
};
|
||||
|
||||
namespace WindowPool {
|
||||
extern UIElement pool[MAX_WINDOWS];
|
||||
extern uint16_t poolIndex;
|
||||
|
||||
UIElement* Allocate();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
#include "UIDecorations.h"
|
||||
|
||||
namespace Curses {
|
||||
};
|
||||
|
||||
UIDecorations::UIDecorations() {}
|
||||
UIDecorations::UIDecorations(uint16_t bg, uint16_t fg, uint16_t title,
|
||||
uint16_t border, uint8_t titleSize,
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef __UI_DIMENSIONS__
|
||||
#define __UI_DIMENSIONS__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct UIDimensions {
|
||||
uint16_t x = 0, y = 0;
|
||||
uint16_t width = 0, height = 0;
|
||||
|
||||
UIDimensions(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -50,6 +50,7 @@ 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++) {
|
||||
@@ -59,15 +60,18 @@ 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();
|
||||
@@ -77,6 +81,7 @@ void UIElement::drawBox() {
|
||||
h, GREEN);
|
||||
#endif
|
||||
|
||||
Serial2.println("Debug4");
|
||||
// content area
|
||||
x = this->getContentAreaX0();
|
||||
y = this->getContentAreaY0();
|
||||
@@ -88,17 +93,21 @@ 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
|
||||
this->display->drawRect(this->dims.x, this->dims.y, this->dims.width,
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "UIScreen.h"
|
||||
#include "UIDecorations.h"
|
||||
#include "UIDimensions.h"
|
||||
|
||||
Curses::Screen::Screen(Arduino_GFX *d, UIDimensions dims, UIDecorations decor)
|
||||
: display(d), dims(dims), decor(decor) {};
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef __UI_SCREEN__
|
||||
#define __UI_SCREEN__
|
||||
|
||||
#include "UIComponent.h"
|
||||
#include "UIDecorations.h"
|
||||
#include "UIDimensions.h"
|
||||
|
||||
namespace Curses {
|
||||
// Entrypoint for our UI. We will have a single screen and this screen can
|
||||
// have some windows and whatnot
|
||||
class Screen {
|
||||
public:
|
||||
UIDimensions dims;
|
||||
UIDecorations decor;
|
||||
Arduino_GFX *display;
|
||||
Screen(Arduino_GFX *d, UIDimensions dims, UIDecorations decor);
|
||||
};
|
||||
}; // namespace Curses
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user