VN Textbox can now be any size

This commit is contained in:
2022-11-06 11:45:10 -08:00
parent db90bd1476
commit 6f4ab49caa
23 changed files with 1493 additions and 1317 deletions

View File

@ -1,130 +1,134 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIBorder.hpp"
using namespace Dawn;
UIBorder::UIBorder(UICanvas &canvas) : UIComponent(canvas) {
this->mesh.createBuffers(QUAD_VERTICE_COUNT * 9, QUAD_INDICE_COUNT * 9);
this->texture = new Texture();
this->texture->setSize(3, 3);
struct Color pixels[9] = {
COLOR_WHITE, COLOR_RED, COLOR_BLUE,
COLOR_GREEN, COLOR_MAGENTA, COLOR_BLACK,
COLOR_CORNFLOWER_BLUE, COLOR_WHITE, COLOR_MAGENTA
};
this->texture->buffer(pixels);
this->updatePositions();
}
void UIBorder::updatePositions() {
UIComponent::updatePositions();
glm::vec2 oneThird = this->uv1 / 3.0f;
glm::vec2 overallDimensions = glm::vec2(this->getWidth(), this->getHeight());
glm::vec2 innerDimensions = overallDimensions - (this->edgeDimensions * 2.0f);
// Top Left.
QuadMesh::bufferQuadMesh(&this->mesh,
glm::vec2(0, 0),
this->uv0,
edgeDimensions,
this->uv0 + oneThird,
0, 0
);
// Top Center
QuadMesh::bufferQuadMesh(&this->mesh,
glm::vec2(edgeDimensions.x, 0),
this->uv0 + glm::vec2(oneThird.x, 0),
glm::vec2(edgeDimensions.x + innerDimensions.x, edgeDimensions.y),
this->uv0 + glm::vec2(oneThird.x * 2.0f, oneThird.y),
QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT
);
// Top Right
QuadMesh::bufferQuadMesh(&this->mesh,
glm::vec2(edgeDimensions.x + innerDimensions.x, 0),
this->uv0 + glm::vec2(oneThird.x * 2.0f, 0),
glm::vec2(overallDimensions.x, edgeDimensions.y),
glm::vec2(this->uv1.x, this->uv0.y + oneThird.y),
QUAD_VERTICE_COUNT * 2, QUAD_INDICE_COUNT * 2
);
// Middle Left
QuadMesh::bufferQuadMesh(&this->mesh,
glm::vec2(0, edgeDimensions.y),
this->uv0 + glm::vec2(0, oneThird.y),
glm::vec2(edgeDimensions.x, edgeDimensions.y + innerDimensions.y),
this->uv0 + glm::vec2(oneThird.x, oneThird.y * 2.0f),
QUAD_VERTICE_COUNT * 3, QUAD_INDICE_COUNT * 3
);
// Center
QuadMesh::bufferQuadMesh(&this->mesh,
edgeDimensions,
this->uv0 + oneThird,
edgeDimensions + innerDimensions,
this->uv0 + (oneThird * 2.0f),
QUAD_VERTICE_COUNT * 4, QUAD_INDICE_COUNT * 4
);
// Middle Right
QuadMesh::bufferQuadMesh(&this->mesh,
edgeDimensions + glm::vec2(innerDimensions.x, 0),
this->uv0 + glm::vec2(oneThird.x * 2.0f, oneThird.y),
edgeDimensions + innerDimensions + glm::vec2(edgeDimensions.x, 0),
this->uv1 - glm::vec2(0.0f, oneThird.y),
QUAD_VERTICE_COUNT * 5, QUAD_INDICE_COUNT * 5
);
// Bottom Left
QuadMesh::bufferQuadMesh(&this->mesh,
glm::vec2(0.0f, edgeDimensions.y + innerDimensions.y),
this->uv0 + glm::vec2(0.0f, uv1.y - oneThird.y),
glm::vec2(edgeDimensions.x, overallDimensions.y),
this->uv1 - glm::vec2(oneThird.x * 2.0f, 0.0f),
QUAD_VERTICE_COUNT * 6, QUAD_INDICE_COUNT * 6
);
// Bottom Center
QuadMesh::bufferQuadMesh(&this->mesh,
edgeDimensions + glm::vec2(0.0f, innerDimensions.y),
this->uv1 - oneThird,
overallDimensions - glm::vec2(edgeDimensions.x, 0.0f),
this->uv1 - glm::vec2(oneThird.x, 0.0f),
QUAD_VERTICE_COUNT * 7, QUAD_INDICE_COUNT * 7
);
// Bottom Right
QuadMesh::bufferQuadMesh(&this->mesh,
overallDimensions - edgeDimensions,
this->uv1 - oneThird,
overallDimensions,
this->uv1,
QUAD_VERTICE_COUNT * 8, QUAD_INDICE_COUNT * 8
);
}
void UIBorder::drawSelf(UIShader &shader, glm::mat4 transform) {
if(this->texture == nullptr) return;
shader.setUIColor(COLOR_WHITE);
shader.setUIModel(transform);
shader.setUITexture(this->texture);
this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
}
void UIBorder::setBorderSize(glm::vec2 borderSize) {
this->edgeDimensions = borderSize;
this->updatePositions();
}
glm::vec2 UIBorder::getBorderSize() {
return this->edgeDimensions;
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIBorder.hpp"
using namespace Dawn;
UIBorder::UIBorder(UICanvas &canvas) : UIComponent(canvas) {
this->mesh.createBuffers(QUAD_VERTICE_COUNT * 9, QUAD_INDICE_COUNT * 9);
this->texture = new Texture();
this->texture->setSize(3, 3);
struct Color pixels[9] = {
COLOR_WHITE, COLOR_RED, COLOR_BLUE,
COLOR_GREEN, COLOR_MAGENTA, COLOR_BLACK,
COLOR_CORNFLOWER_BLUE, COLOR_WHITE, COLOR_MAGENTA
};
this->texture->buffer(pixels);
this->updatePositions();
}
void UIBorder::updatePositions() {
UIComponent::updatePositions();
glm::vec2 oneThird = this->uv1 / 3.0f;
glm::vec2 overallDimensions = glm::vec2(this->getWidth(), this->getHeight());
glm::vec2 innerDimensions = overallDimensions - (this->edgeDimensions * 2.0f);
// Top Left.
QuadMesh::bufferQuadMesh(&this->mesh,
glm::vec2(0, 0),
this->uv0,
edgeDimensions,
this->uv0 + oneThird,
0, 0
);
// Top Center
QuadMesh::bufferQuadMesh(&this->mesh,
glm::vec2(edgeDimensions.x, 0),
this->uv0 + glm::vec2(oneThird.x, 0),
glm::vec2(edgeDimensions.x + innerDimensions.x, edgeDimensions.y),
this->uv0 + glm::vec2(oneThird.x * 2.0f, oneThird.y),
QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT
);
// Top Right
QuadMesh::bufferQuadMesh(&this->mesh,
glm::vec2(edgeDimensions.x + innerDimensions.x, 0),
this->uv0 + glm::vec2(oneThird.x * 2.0f, 0),
glm::vec2(overallDimensions.x, edgeDimensions.y),
glm::vec2(this->uv1.x, this->uv0.y + oneThird.y),
QUAD_VERTICE_COUNT * 2, QUAD_INDICE_COUNT * 2
);
// Middle Left
QuadMesh::bufferQuadMesh(&this->mesh,
glm::vec2(0, edgeDimensions.y),
this->uv0 + glm::vec2(0, oneThird.y),
glm::vec2(edgeDimensions.x, edgeDimensions.y + innerDimensions.y),
this->uv0 + glm::vec2(oneThird.x, oneThird.y * 2.0f),
QUAD_VERTICE_COUNT * 3, QUAD_INDICE_COUNT * 3
);
// Center
QuadMesh::bufferQuadMesh(&this->mesh,
edgeDimensions,
this->uv0 + oneThird,
edgeDimensions + innerDimensions,
this->uv0 + (oneThird * 2.0f),
QUAD_VERTICE_COUNT * 4, QUAD_INDICE_COUNT * 4
);
// Middle Right
QuadMesh::bufferQuadMesh(&this->mesh,
edgeDimensions + glm::vec2(innerDimensions.x, 0),
this->uv0 + glm::vec2(oneThird.x * 2.0f, oneThird.y),
edgeDimensions + innerDimensions + glm::vec2(edgeDimensions.x, 0),
this->uv1 - glm::vec2(0.0f, oneThird.y),
QUAD_VERTICE_COUNT * 5, QUAD_INDICE_COUNT * 5
);
// Bottom Left
QuadMesh::bufferQuadMesh(&this->mesh,
glm::vec2(0.0f, edgeDimensions.y + innerDimensions.y),
this->uv0 + glm::vec2(0.0f, uv1.y - oneThird.y),
glm::vec2(edgeDimensions.x, overallDimensions.y),
this->uv1 - glm::vec2(oneThird.x * 2.0f, 0.0f),
QUAD_VERTICE_COUNT * 6, QUAD_INDICE_COUNT * 6
);
// Bottom Center
QuadMesh::bufferQuadMesh(&this->mesh,
edgeDimensions + glm::vec2(0.0f, innerDimensions.y),
this->uv1 - oneThird,
overallDimensions - glm::vec2(edgeDimensions.x, 0.0f),
this->uv1 - glm::vec2(oneThird.x, 0.0f),
QUAD_VERTICE_COUNT * 7, QUAD_INDICE_COUNT * 7
);
// Bottom Right
QuadMesh::bufferQuadMesh(&this->mesh,
overallDimensions - edgeDimensions,
this->uv1 - oneThird,
overallDimensions,
this->uv1,
QUAD_VERTICE_COUNT * 8, QUAD_INDICE_COUNT * 8
);
}
void UIBorder::drawSelf(UIShader &shader, glm::mat4 transform) {
if(this->texture == nullptr) return;
shader.setUIColor(COLOR_WHITE);
shader.setUIModel(transform);
shader.setUITexture(this->texture);
this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
}
void UIBorder::setBorderSize(glm::vec2 borderSize) {
this->edgeDimensions = borderSize;
this->updatePositions();
}
glm::vec2 UIBorder::getInnerSize() {
return glm::vec2(this->getWidth(), this->getHeight()) - this->edgeDimensions;
}
glm::vec2 UIBorder::getBorderSize() {
return this->edgeDimensions;
}

View File

@ -1,30 +1,48 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "UIComponent.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "display/Texture.hpp"
namespace Dawn {
class UIBorder : public UIComponent {
private:
Mesh mesh;
glm::vec2 edgeDimensions = glm::vec2(8.0f, 8.0f);
glm::vec2 uv0 = glm::vec2(0.0f, 0.0f);
glm::vec2 uv1 = glm::vec2(1.0f, 1.0f);
void updatePositions() override;
public:
Texture *texture;
UIBorder(UICanvas &canvas);
void drawSelf(UIShader &shader, glm::mat4 selfTransform) override;
void setBorderSize(glm::vec2 borderSize);
glm::vec2 getBorderSize();
};
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "UIComponent.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "display/Texture.hpp"
namespace Dawn {
class UIBorder : public UIComponent {
private:
Mesh mesh;
glm::vec2 edgeDimensions = glm::vec2(8.0f, 8.0f);
glm::vec2 uv0 = glm::vec2(0.0f, 0.0f);
glm::vec2 uv1 = glm::vec2(1.0f, 1.0f);
void updatePositions() override;
void drawSelf(UIShader &shader, glm::mat4 selfTransform) override;
public:
Texture *texture;
UIBorder(UICanvas &canvas);
/**
* Changes the dimensions of the border.
*
* @param borderSize Size of the border.
*/
void setBorderSize(glm::vec2 borderSize);
/**
* Returns the size of the border.
*
* @return Border size of this UI border.
*/
glm::vec2 getBorderSize();
/**
* Returns the size of the area within the border.
*
* @return The inner content area size.
*/
glm::vec2 getInnerSize();
};
}

View File

@ -1,153 +1,158 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIComponent.hpp"
using namespace Dawn;
UIComponent::UIComponent(UICanvas &canvas) :
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];
}
// 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];
}
// Update children
auto it = this->children.begin();
while(it != this->children.end()) {
(*it)->updatePositions();
++it;
}
}
float_t UIComponent::getWidth() {
return this->width;
}
float_t UIComponent::getHeight() {
return this->height;
}
float_t UIComponent::getRelativeX() {
return this->relativeX;
}
float_t UIComponent::getRelativeY() {
return this->relativeY;
}
void UIComponent::setTransform(
UIComponentAlign xAlign,
UIComponentAlign yAlign,
glm::vec4 alignment,
float_t z
) {
this->alignX = xAlign;
this->alignY = yAlign;
this->alignment = alignment;
this->z = z;
this->updatePositions();
}
void UIComponent::draw(UIShader &uiShader, glm::mat4 parentTransform) {
// Calculate self transform matrix
glm::mat4 selfTransform = parentTransform * glm::translate(
glm::mat4(1.0f), glm::vec3(this->relativeX, this->relativeY, this->z)
);
// Draw Self
this->drawSelf(uiShader, selfTransform);
// Render children
auto it = this->children.begin();
while(it != this->children.end()) {
(*it)->draw(uiShader, selfTransform);
++it;
}
}
void UIComponent::addChild(UIComponent *child) {
if(child->parent == this) return;
if(child->parent != nullptr) child->parent->removeChild(child);
this->children.push_back(child);
child->parent = this;
}
void UIComponent::removeChild(UIComponent *child) {
if(child->parent != this) throw "Invalid child";
auto it = this->children.begin();
while(it != this->children.end()) {
if(*it == child) {
this->children.erase(it);
break;
}
++it;
}
}
UIComponent::~UIComponent() {
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIComponent.hpp"
using namespace Dawn;
UIComponent::UIComponent(UICanvas &canvas) :
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];
}
// 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];
}
// Update children
auto it = this->children.begin();
while(it != this->children.end()) {
(*it)->updatePositions();
++it;
}
// Fire event
eventAlignmentUpdated.invoke(
this->width, this->height, this->relativeX, this->relativeY
);
}
float_t UIComponent::getWidth() {
return this->width;
}
float_t UIComponent::getHeight() {
return this->height;
}
float_t UIComponent::getRelativeX() {
return this->relativeX;
}
float_t UIComponent::getRelativeY() {
return this->relativeY;
}
void UIComponent::setTransform(
UIComponentAlign xAlign,
UIComponentAlign yAlign,
glm::vec4 alignment,
float_t z
) {
this->alignX = xAlign;
this->alignY = yAlign;
this->alignment = alignment;
this->z = z;
this->updatePositions();
}
void UIComponent::draw(UIShader &uiShader, glm::mat4 parentTransform) {
// Calculate self transform matrix
glm::mat4 selfTransform = parentTransform * glm::translate(
glm::mat4(1.0f), glm::vec3(this->relativeX, this->relativeY, this->z)
);
// Draw Self
this->drawSelf(uiShader, selfTransform);
// Render children
auto it = this->children.begin();
while(it != this->children.end()) {
(*it)->draw(uiShader, selfTransform);
++it;
}
}
void UIComponent::addChild(UIComponent *child) {
if(child->parent == this) return;
if(child->parent != nullptr) child->parent->removeChild(child);
this->children.push_back(child);
child->parent = this;
}
void UIComponent::removeChild(UIComponent *child) {
if(child->parent != this) throw "Invalid child";
auto it = this->children.begin();
while(it != this->children.end()) {
if(*it == child) {
this->children.erase(it);
break;
}
++it;
}
}
UIComponent::~UIComponent() {
}

View File

@ -1,82 +1,128 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/components/ui/UICanvas.hpp"
#include "scene/Scene.hpp"
#include "display/Color.hpp"
#include "display/shader/UIShader.hpp"
namespace Dawn {
enum UIComponentAlign {
UI_COMPONENT_ALIGN_START,
UI_COMPONENT_ALIGN_MIDDLE,
UI_COMPONENT_ALIGN_END,
UI_COMPONENT_ALIGN_STRETCH
};
class UIComponent {
protected:
// Calculated (and cached) values
float_t width = 1;
float_t height = 1;
float_t relativeX = 0;
float_t relativeY = 0;
// Setting values
UIComponentAlign alignX = UI_COMPONENT_ALIGN_START;
UIComponentAlign alignY = UI_COMPONENT_ALIGN_START;
glm::vec4 alignment = glm::vec4(0, 0, 32, 32);
float_t z = 0;
std::vector<UIComponent*> children;
UIComponent *parent = nullptr;
// I currently don't support rotation or scale. Not because I can't but
// because it's basically un-necessary. Unity does support rotation but
// it doesn't affect how the alignment side of things work (similar to how
// CSS would handle things) When I need to support these I will add the
// code but right now it's not necessary
/**
* Updates the cached/stored values based on the setting internal values.
* You should watchdog this if you intend to do something when values are
* updated, e.g. if you need to resize a quad, or something.
*/
virtual void updatePositions();
public:
UICanvas &canvas;
UIComponent(UICanvas &canvas);
/**
* Returns the calculated width, based on the internal alignment values.
*
* @return Width of the component.
*/
float_t getWidth();
float_t getHeight();
float_t getRelativeX();
float_t getRelativeY();
void setTransform(
UIComponentAlign xAlign,
UIComponentAlign yAlign,
glm::vec4 alignment,
float_t z
);
// virtual void update() = 0;
void draw(UIShader &uiShader, glm::mat4 parentTransform);
virtual void drawSelf(UIShader &uiShader, glm::mat4 selfTransform) = 0;
void addChild(UIComponent *child);
void removeChild(UIComponent *child);
virtual ~UIComponent();
friend class UICanvas;
};
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/components/ui/UICanvas.hpp"
#include "scene/Scene.hpp"
#include "display/Color.hpp"
#include "display/shader/UIShader.hpp"
namespace Dawn {
enum UIComponentAlign {
UI_COMPONENT_ALIGN_START,
UI_COMPONENT_ALIGN_MIDDLE,
UI_COMPONENT_ALIGN_END,
UI_COMPONENT_ALIGN_STRETCH
};
class UIComponent {
protected:
// Calculated (and cached) values
float_t width = 1;
float_t height = 1;
float_t relativeX = 0;
float_t relativeY = 0;
// Setting values
UIComponentAlign alignX = UI_COMPONENT_ALIGN_START;
UIComponentAlign alignY = UI_COMPONENT_ALIGN_START;
glm::vec4 alignment = glm::vec4(0, 0, 32, 32);
float_t z = 0;
std::vector<UIComponent*> children;
UIComponent *parent = nullptr;
// Events
Event<float_t, float_t, float_t, float_t> eventAlignmentUpdated;
// I currently don't support rotation or scale. Not because I can't but
// because it's basically un-necessary. Unity does support rotation but
// it doesn't affect how the alignment side of things work (similar to how
// CSS would handle things) When I need to support these I will add the
// code but right now it's not necessary
/**
* Updates the cached/stored values based on the setting internal values.
* You should watchdog this if you intend to do something when values are
* updated, e.g. if you need to resize a quad, or something.
*/
virtual void updatePositions();
/**
* Intended to be overwritten by subclass. Called by the draw method to
* ask this child to draw.
*
* @param uiShader UI Shader for the child to use.
* @param selfTransform Self alignment transform.
*/
virtual void drawSelf(UIShader &uiShader, glm::mat4 selfTransform) = 0;
public:
UICanvas &canvas;
UIComponent(UICanvas &canvas);
/**
* Returns the calculated width, based on the internal alignment values.
*
* @return Width of the component.
*/
float_t getWidth();
/**
* Returns the calculated height, based on the internal alignment values.
*
* @return Height of the component.
*/
float_t getHeight();
/**
* Returns the X position, relative to this components' parent.
*
* @return Relative X position.
*/
float_t getRelativeX();
/**
* Returns the Y position, relative to this components' parent.
*
* @return Relative Y position.
*/
float_t getRelativeY();
/**
* Updates the transformation for this component.
*
* @param xAlign X axis alignment method.
* @param yAlign Y axis alignment method.
* @param alignment Alignment parameters, changes depending on the align.
* @param z Z position (relative to screen).
*/
virtual void setTransform(
UIComponentAlign xAlign,
UIComponentAlign yAlign,
glm::vec4 alignment,
float_t z
);
void draw(UIShader &uiShader, glm::mat4 parentTransform);
/**
* Adds a child to this UI Component.
*
* @param child Child UI Component to add.
*/
void addChild(UIComponent *child);
/**
* Removes a child from this UI Component.
*
* @param child Child to remove.
*/
void removeChild(UIComponent *child);
virtual ~UIComponent();
friend class UICanvas;
};
}

View File

@ -1,63 +1,73 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UILabel.hpp"
using namespace Dawn;
UILabel::UILabel(UICanvas &canvas) : UIComponent(canvas) {
}
void UILabel::updatePositions() {
UIComponent::updatePositions();
this->updateMesh();
}
void UILabel::updateMesh() {
if(!this->needsRebuffering) return;
if(this->font == nullptr) return;
if(this->text.size() == 0) return;
this->font->buffer(
this->text,
this->fontSize,
this->getWidth(),
this->mesh,
&this->measure
);
this->needsRebuffering = false;
}
std::string UILabel::getText() {
return this->text;
}
void UILabel::setFont(Font *font) {
this->font = font;
this->needsRebuffering = true;
}
void UILabel::setText(std::string text) {
this->text = text;
this->needsRebuffering = true;
}
void UILabel::setFontSize(float_t fontSize) {
this->fontSize = fontSize;
this->needsRebuffering = true;
}
void UILabel::drawSelf(UIShader &shader, glm::mat4 selfTransform) {
if(this->font == nullptr || this->text.size() == 0) return;
this->updateMesh();
shader.setUIColor(this->textColor);
shader.setUIModel(selfTransform);
shader.setUITexture(&this->font->getTexture());
this->font->draw(this->mesh, this->startQuad, this->quadCount);
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UILabel.hpp"
using namespace Dawn;
UILabel::UILabel(UICanvas &canvas) : UIComponent(canvas) {
}
void UILabel::updatePositions() {
UIComponent::updatePositions();
this->updateMesh();
}
void UILabel::updateMesh() {
if(!this->needsRebuffering) return;
if(this->font == nullptr) return;
if(this->text.size() == 0) return;
this->font->buffer(
this->text,
this->fontSize,
this->getWidth(),
this->mesh,
&this->measure
);
this->needsRebuffering = false;
}
std::string UILabel::getText() {
return this->text;
}
void UILabel::setFont(Font *font) {
this->font = font;
this->needsRebuffering = true;
}
void UILabel::setText(std::string text) {
this->text = text;
this->needsRebuffering = true;
}
void UILabel::setFontSize(float_t fontSize) {
this->fontSize = fontSize;
this->needsRebuffering = true;
}
void UILabel::drawSelf(UIShader &shader, glm::mat4 selfTransform) {
if(this->font == nullptr || this->text.size() == 0) return;
this->updateMesh();
shader.setUIColor(this->textColor);
shader.setUIModel(selfTransform);
shader.setUITexture(&this->font->getTexture());
this->font->draw(this->mesh, this->startQuad, this->quadCount);
}
void UILabel::setTransform(
UIComponentAlign xAlign,
UIComponentAlign yAlign,
glm::vec4 alignment,
float_t z
) {
this->needsRebuffering = true;
UIComponent::setTransform(xAlign, yAlign, alignment, z);
}

View File

@ -1,67 +1,73 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "UIComponent.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "display/font/Font.hpp"
namespace Dawn {
class UILabel : public UIComponent {
private:
Mesh mesh;
bool_t needsRebuffering = true;
Font *font = nullptr;
std::string text = "";
float_t fontSize = 10.0f;
void updatePositions() override;
public:
struct FontMeasure measure;
int32_t startQuad = 0;
int32_t quadCount = -1;
/** The colour of this label */
struct Color textColor = COLOR_MAGENTA;
UILabel(UICanvas &canvas);
void drawSelf(UIShader &shader, glm::mat4 selfTransform) override;
/**
* Internal method to force the font mesh to be recreated.
*/
void updateMesh();
/**
* Returns the current text that the label has.
*
* @return The current label string.
*/
std::string getText();
/**
* Set the font to use for the label.
*
* @param font Font to use.
*/
void setFont(Font *font);
/**
* Sets the text for the label to use.
*
* @param text Text for the label to use.
*/
void setText(std::string text);
/**
* Sets / Updates the font size for the label.
*
* @param fontSize Font size to use.
*/
void setFontSize(float_t fontSize);
};
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "UIComponent.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "display/font/Font.hpp"
namespace Dawn {
class UILabel : public UIComponent {
private:
Mesh mesh;
bool_t needsRebuffering = true;
Font *font = nullptr;
std::string text = "";
float_t fontSize = 10.0f;
void updatePositions() override;
public:
struct FontMeasure measure;
int32_t startQuad = 0;
int32_t quadCount = -1;
/** The colour of this label */
struct Color textColor = COLOR_MAGENTA;
UILabel(UICanvas &canvas);
void drawSelf(UIShader &shader, glm::mat4 selfTransform) override;
void setTransform(
UIComponentAlign xAlign,
UIComponentAlign yAlign,
glm::vec4 alignment,
float_t z
) override;
/**
* Internal method to force the font mesh to be recreated.
*/
void updateMesh();
/**
* Returns the current text that the label has.
*
* @return The current label string.
*/
std::string getText();
/**
* Set the font to use for the label.
*
* @param font Font to use.
*/
void setFont(Font *font);
/**
* Sets the text for the label to use.
*
* @param text Text for the label to use.
*/
void setText(std::string text);
/**
* Sets / Updates the font size for the label.
*
* @param fontSize Font size to use.
*/
void setFontSize(float_t fontSize);
};
}

View File

@ -1,28 +1,28 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "UIComponent.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "display/Texture.hpp"
namespace Dawn {
class UISprite : public UIComponent {
protected:
void updatePositions() override;
public:
Mesh mesh;
Texture *texture;
/**
* UI Sprite Constructor, use the UIElement / UIComponent create instead.
*
* @param canvas Canvas that this sprite belongs to.
*/
UISprite(UICanvas &canvas);
void drawSelf(UIShader &uiShader, glm::mat4 selfTransform) override;
};
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "UIComponent.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "display/Texture.hpp"
namespace Dawn {
class UISprite : public UIComponent {
protected:
void updatePositions() override;
void drawSelf(UIShader &uiShader, glm::mat4 selfTransform) override;
public:
Mesh mesh;
Texture *texture;
/**
* UI Sprite Constructor, use the UIElement / UIComponent create instead.
*
* @param canvas Canvas that this sprite belongs to.
*/
UISprite(UICanvas &canvas);
};
}