Added UI Grid

This commit is contained in:
2023-01-24 21:06:51 -08:00
parent 4d6cffbcfe
commit 5c45ca8998
8 changed files with 255 additions and 119 deletions

View File

@ -29,8 +29,4 @@ scene.22.1,"King Fight"
scene.23.1,"Post King Fight, angry he leaves, town rallies around you"
scene.24.1,"Go to one of the kingsmen who's working with the big bad, he's worried that the townspeople know more than they let on."
unknown3,"Something here has to bring the big bad to town."
test.1,"Test 1
Test 2
Test 3
Test 4
"
test.1,"Test"
1 undefined UNDEFINED
29 scene.23.1 Post King Fight, angry he leaves, town rallies around you
30 scene.24.1 Go to one of the kingsmen who's working with the big bad, he's worried that the townspeople know more than they let on.
31 unknown3 Something here has to bring the big bad to town.
32 test.1 Test 1 Test 2 Test 3 Test 4 Test

View File

@ -11,5 +11,5 @@ target_sources(${DAWN_TARGET_NAME}
UILabel.cpp
UISprite.cpp
UIEmpty.cpp
# UIGrid.cpp
UIGrid.cpp
)

View File

@ -7,78 +7,81 @@
using namespace Dawn;
void UIComponent::calculateDimensions(
enum UIComponentAlign align,
float_t *position,
float_t *size,
float_t outerSize,
float_t innerSize,
glm::vec2 alignment
) {
assertNotNull(position);
assertNotNull(size);
switch(align) {
case UI_COMPONENT_ALIGN_STRETCH:
*position = alignment[0];
*size = outerSize + (alignment[0] + alignment[1]);
break;
case UI_COMPONENT_ALIGN_START:
*position = alignment[0];
*size = alignment[1];
break;
case UI_COMPONENT_ALIGN_MIDDLE:
*size = innerSize;
*position = (outerSize / 2.0f) - (innerSize / 2.0f) + alignment[0];
break;
case UI_COMPONENT_ALIGN_END:
*size = alignment[0];
*position = outerSize - innerSize - alignment[1];
break;
default:
assertUnreachable();
break;
}
}
UIComponent::UIComponent(UICanvas *canvas) {
assertNotNull(canvas);
this->canvas = canvas;
}
void UIComponent::updatePositions() {
// X Alignment
if(this->alignX == UI_COMPONENT_ALIGN_STRETCH) {
if(this->parent == nullptr) {
this->width = this->canvas->getWidth();
} else {
this->width = this->parent->getWidth();
}
this->relativeX = this->alignment[0];
this->width -= (this->alignment[0] + this->alignment[2]);
} else if(this->alignX == UI_COMPONENT_ALIGN_START) {
this->relativeX = this->alignment[0];
this->width = this->alignment[2];
} else if(this->alignX == UI_COMPONENT_ALIGN_END) {
this->width = this->alignment[0];
if(this->parent == nullptr) {
this->relativeX = this->canvas->getWidth();
} else {
this->relativeX = this->parent->getWidth();
}
this->relativeX -= this->width;
this->relativeX -= this->alignment[2];
} else if(this->alignX == UI_COMPONENT_ALIGN_MIDDLE) {
this->width = this->alignment[2];
if(this->parent == nullptr) {
this->relativeX = this->canvas->getWidth();
} else {
this->relativeX = this->parent->getWidth();
}
this->relativeX = (this->relativeX / 2.0f) - (this->width / 2.0f) + this->alignment[0];
float_t outerWidth, outerHeight;
if(this->parent == nullptr) {
outerWidth = this->canvas->getWidth();
outerHeight = this->canvas->getHeight();
} else {
outerWidth = this->parent->getWidth();
outerHeight = this->parent->getHeight();
}
// Y Alignment
if(this->alignY == UI_COMPONENT_ALIGN_STRETCH) {
if(this->parent == nullptr) {
this->height = this->canvas->getHeight();
} else {
this->height = this->parent->getHeight();
}
this->relativeY = this->alignment[1];
this->height -= (this->alignment[1] + this->alignment[3]);
} else if(this->alignY == UI_COMPONENT_ALIGN_START) {
this->relativeY = this->alignment[1];
this->height = this->alignment[3];
} else if(this->alignY == UI_COMPONENT_ALIGN_END) {
this->height = this->alignment[1];
if(this->parent == nullptr) {
this->relativeY = this->canvas->getHeight();
} else {
this->relativeY = this->parent->getHeight();
}
this->relativeY -= this->height;
this->relativeY -= this->alignment[3];
} else if(this->alignY == UI_COMPONENT_ALIGN_MIDDLE) {
this->height = this->alignment[3];
if(this->parent == nullptr) {
this->relativeY = this->canvas->getHeight();
} else {
this->relativeY = this->parent->getHeight();
}
this->relativeY = (this->relativeY / 2.0f) - (this->height / 2.0f) + this->alignment[1];
}
UIComponent::calculateDimensions(
this->alignX,
&this->relativeX,
&this->width,
outerWidth,
this->getContentWidth(),
glm::vec2(this->alignment[0], this->alignment[2])
);
UIComponent::calculateDimensions(
this->alignY,
&this->relativeY,
&this->height,
outerHeight,
this->getContentHeight(),
glm::vec2(this->alignment[1], this->alignment[3])
);
this->relativeX = mathRound<float_t>(this->relativeX);
this->relativeY = mathRound<float_t>(this->relativeY);
this->width = mathRound<float_t>(this->width);
this->height = mathRound<float_t>(this->height);
// this->relativeX = mathRound<float_t>(this->relativeX);
// this->relativeY = mathRound<float_t>(this->relativeY);
// this->width = mathRound<float_t>(this->width);
// this->height = mathRound<float_t>(this->height);
// Update children
auto it = this->children.begin();

View File

@ -18,6 +18,8 @@ namespace Dawn {
UI_COMPONENT_ALIGN_END,
UI_COMPONENT_ALIGN_STRETCH
};
class UIGrid;
class UIComponent {
protected:
@ -67,6 +69,25 @@ namespace Dawn {
) = 0;
public:
/**
* Method used to calculate alignment dimensions.
*
* @param align Alignment value enumator.
* @param position Output position floating point.
* @param size Output size floating point.
* @param outerSize Outer size (of the parent).
* @param innerSize Inner size (of this element's content).
* @param alignment Alignment settings.
*/
static void calculateDimensions(
enum UIComponentAlign align,
float_t *position,
float_t *size,
float_t outerSize,
float_t innerSize,
glm::vec2 alignment
);
UICanvas *canvas;
UIComponent(UICanvas *canvas);
@ -165,16 +186,18 @@ namespace Dawn {
*
* @param child Child UI Component to add.
*/
void addChild(UIComponent *child);
virtual void addChild(UIComponent *child);
/**
* Removes a child from this UI Component.
*
* @param child Child to remove.
*/
void removeChild(UIComponent *child);
virtual void removeChild(UIComponent *child);
virtual ~UIComponent();
friend class UICanvas;
friend class UIGrid;
};
}

View File

@ -8,28 +8,101 @@
using namespace Dawn;
UIGrid::UIGrid(UICanvas *canvas) : UIComponent(canvas) {
}
void UIGrid::setSize(int32_t rows, int32_t columns) {
this->gridArea.clear();
this->rows = rows;
this->columns = columns;
void UIGrid::updatePositions() {
UIComponent::updatePositions();
int32_t i, l;
l = rows * columns;
for(i = 0; i < l; i++) {
struct GridArea area;
area.uiComponent = nullptr;
this->gridArea.push_back(area);
this->sizeCol = (
this->width - (this->gutterX * (this->columns - 1))
) / this->columns;
this->sizeRow = (
this->height - (this->gutterY * (this->rows - 1))
) / this->rows;
auto it = this->gridChildren.begin();
while(it != this->gridChildren.end()) {
this->alignChild(it->first, it->second);
++it;
}
}
void UIGrid::setItem(int32_t x, int32_t y, UIComponent *comp) {
auto item = &this->gridArea[(y * this->rows) + x];
//Too lazy to support re setting. Need to mod setSize too
assertNull(item->uiComponent);
item->uiComponent = comp;
std::vector<struct ShaderPassItem> UIGrid::getSelfPassItems(
glm::mat4 projection,
glm::mat4 view,
glm::mat4 transform
) {
return std::vector<struct ShaderPassItem>();
}
void UIGrid::alignChild(UIComponent *child, struct UIGridPosition pos) {
float_t gridX = (this->sizeCol * pos.x) + (this->gutterX * pos.x);
float_t gridY = (this->sizeRow * pos.y) + (this->gutterY * pos.y);
// Hack for when content width is undefined.
child->width = this->sizeCol;
child->height = this->sizeRow;
// Alignment
float_t x, y, sizeX, sizeY;
UIComponent::calculateDimensions(
UI_COMPONENT_ALIGN_MIDDLE,
&x,
&sizeX,
this->sizeCol,
child->getContentWidth(),
glm::vec2(0, 0)
);
UIComponent::calculateDimensions(
UI_COMPONENT_ALIGN_MIDDLE,
&y,
&sizeY,
this->sizeRow,
child->getContentHeight(),
glm::vec2(0, 0)
);
child->setTransform(
UI_COMPONENT_ALIGN_START, UI_COMPONENT_ALIGN_START,
glm::vec4(gridX + x, gridY + y, sizeX, sizeY),
0.0f
);
}
void UIGrid::setGridSize(
int32_t columns, int32_t rows,
float_t gutterX, float_t gutterY
) {
this->rows = rows;
this->columns = columns;
this->gutterX = gutterX;
this->gutterY = gutterY;
this->gridChildren.clear();
this->updatePositions();
}
void UIGrid::addToGrid(UIComponent *ui, int32_t x, int32_t y) {
assertTrue(x >= 0 && x < this->columns);
assertTrue(y >= 0 && y < this->rows);
this->addChild(ui);
struct UIGridPosition pos;
pos.x = x;
pos.y = y;
this->gridChildren[ui] = pos;
this->alignChild(ui, pos);
}
int32_t UIGrid::getRows() {
return this->rows;
}
int32_t UIGrid::getColumns() {
return this->columns;
}
void UIGrid::removeChild(UIComponent *component) {
UIComponent::removeChild(component);
assertUnreachable();
}

View File

@ -5,37 +5,70 @@
#pragma once
#include "UIComponent.hpp"
#include "util/mathutils.hpp"
namespace Dawn {
enum GridAlign {
ALIGN_GROW,
ALIGN_CONTENT,
ALIGN_FIXED
struct UIGridPosition {
int32_t x;
int32_t y;
UIComponentAlign alignX;
UIComponentAlign alignY;
};
struct GridArea {
enum GridAlignment xAlign;
enum GridAlignment yAlign;
float_t width, height;
float_t x, y;
UIComponent *uiComponent;
};
class UIGrid : public UIComponent {
protected:
void alignChildren();
public:
glm::vec2 cellPadding;
glm::vec2 cellMargin;
private:
int32_t rows = 1;
int32_t columns = 1;
std::vector<struct GridArea> gridArea;
float_t gutterX = 0;
float_t gutterY = 0;
float_t sizeRow, sizeCol;
std::map<UIComponent*, struct UIGridPosition> gridChildren;
/**
* Internal method to update the alignment of a child.
*
* @param child Child UI component.
* @param pos Positional information of the child UI item..
*/
void alignChild(UIComponent *child, struct UIGridPosition pos);
protected:
void updatePositions() override;
std::vector<struct ShaderPassItem> getSelfPassItems(
glm::mat4 projection,
glm::mat4 view,
glm::mat4 transform
) override;
public:
UIGrid(UICanvas *canvas);
void setSize(int32_t rows, int32_t columns);
/**
* Sets the dimensions of the grid.
*
* @param columns Count of columns in the grid.
* @param rows Count of rows in the grid.
* @param gutterX Gutter spacing between the cells of the grid.
* @param gutterY Gutter spacing between the cells of the grid.
*/
void setGridSize(
int32_t columns, int32_t rows,
float_t gutterX, float_t gutterY
);
void setItem(int32_t row, int32_t col, UIComponent *comp);
/**
* Adds a UI component to the grid.
*
* @param component Component to add to the grid.
* @param column Column Position.
* @param row Row Position.
*/
void addToGrid(UIComponent *component, int32_t column, int32_t row);
int32_t getRows();
int32_t getColumns();
void removeChild(UIComponent *component) override;
};
}

View File

@ -32,7 +32,7 @@ void TestUIScene::stage() {
this->canvas = UICanvas::create(this);
// auto text = man->get<TextureAsset>("texture_test");
// auto border = this->canvas->addElement<UIBorder>();
// auto border = this->canvas->addElement<UIBorder>();
// border->texture = &text->texture;
// border->setBorderSize(glm::vec2(4, 4));
// border->setTransform(
@ -42,13 +42,19 @@ void TestUIScene::stage() {
// );
auto assetFont = man->get<TrueTypeAsset>("truetype_alice");
auto label = this->canvas->addElement<UILabel>();
label->setFont(&assetFont->font);
label->setText("test.1");
label->setFontSize(24);
label->setTransform(
UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH,
glm::vec4(0, 0, 0, 0),
0.0f
);
auto grid = this->canvas->addElement<UIGrid>();
grid->setTransform(UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH, glm::vec4(0, 0, 0, 0), 0);
grid->setGridSize(4, 4, 8, 8);
for(int32_t x = 0; x < grid->getColumns(); x++) {
for(int32_t y = 0; y < grid->getRows(); y++) {
auto label = this->canvas->addElement<UILabel>();
label->setFont(&assetFont->font);
label->setText("test.1");
label->setFontSize(24);
grid->addToGrid(label, x, y);
}
}
}

View File

@ -9,6 +9,8 @@
#include "scene/components/ui/UICanvas.hpp"
#include "ui/UILabel.hpp"
#include "ui/UIBorder.hpp"
#include "ui/UIGrid.hpp"
#include "ui/UISprite.hpp"
#include "prefabs/SimpleSpinningCubePrefab.hpp"
namespace Dawn {