Updated some docs

This commit is contained in:
2023-03-05 23:49:58 -08:00
parent 98eb09f288
commit c36eb4134a
8 changed files with 53 additions and 7 deletions

View File

@ -0,0 +1,185 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIComponent.hpp"
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() {
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();
}
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])
);
// Update children
auto it = this->children.begin();
while(it != this->children.end()) {
(*it)->updatePositions();
++it;
}
// Fire event
eventAlignmentUpdated.invoke(this);
}
float_t UIComponent::getWidth() {
return this->width;
}
float_t UIComponent::getHeight() {
return this->height;
}
float_t UIComponent::getContentWidth() {
return this->width;
}
float_t UIComponent::getContentHeight() {
return this->height;
}
float_t UIComponent::getRelativeX() {
return this->relativeX;
}
float_t UIComponent::getRelativeY() {
return this->relativeY;
}
DawnGame * UIComponent::getGame() {
return this->canvas->getGame();
}
Scene * UIComponent::getScene() {
return this->canvas->getScene();
}
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();
}
std::vector<struct ShaderPassItem> UIComponent::getPassItems(
glm::mat4 projection,
glm::mat4 view,
glm::mat4 parent
) {
// Calculate self transform matrix
glm::mat4 selfTransform = parent * glm::translate(
glm::mat4(1.0f),
glm::vec3(this->relativeX, this->relativeY, this->z)
);
// Draw Self
auto items = this->getSelfPassItems(projection, view, selfTransform);
// Render children
auto it = this->children.begin();
while(it != this->children.end()) {
vectorAppend(&items, (*it)->getPassItems(projection, view, selfTransform));
++it;
}
return items;
}
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;
this->updatePositions();
}
void UIComponent::removeChild(UIComponent *child) {
assertTrue(child->parent == this);
auto it = this->children.begin();
while(it != this->children.end()) {
if(*it == child) {
this->children.erase(it);
break;
}
++it;
}
child->parent = nullptr;
}
UIComponent::~UIComponent() {
}

View File

@ -0,0 +1,203 @@
// 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 "display/Color.hpp"
#include "util/array.hpp"
#include "util/mathutils.hpp"
#include "display/shader/Shader.hpp"
#include "state/State.hpp"
namespace Dawn {
enum UIComponentAlign {
UI_COMPONENT_ALIGN_START,
UI_COMPONENT_ALIGN_MIDDLE,
UI_COMPONENT_ALIGN_END,
UI_COMPONENT_ALIGN_STRETCH
};
class UIGrid;
class UIComponent : public StateOwner {
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<UIComponent*> 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 projection Projection matrix of the camera.
* @param view View matrix of the camera.
* @param parent Matrix of the parent of this UI item.
* @return The list of shader pass items.
*/
virtual std::vector<struct ShaderPassItem> getSelfPassItems(
glm::mat4 projection,
glm::mat4 view,
glm::mat4 transform
) = 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);
/**
* Returns the calculated width, based on the internal alignment values.
*
* @return Width of the component.
*/
virtual float_t getWidth();
/**
* Returns the calculated height, based on the internal alignment values.
*
* @return Height of the component.
*/
virtual float_t getHeight();
/**
* Returns the internal width of the content within this element, e.g.
* the content width.
*
* @return Content width.
*/
virtual float_t getContentWidth();
/**
* Returns the internal height of the content within this element, e.g.
* the content height.
*
* @return Content height.
*/
virtual float_t getContentHeight();
/**
* 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();
/**
* Gets the game that this UI component belongs to.
*
* @return Game instance.
*/
DawnGame * getGame();
/**
* Gets the scene that thsi UI Component belongs to.
*
* @return Scene instance.
*/
Scene * getScene();
/**
* 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
);
/**
* Returns the list of renderable shader pass items for this UI element.
* This is basically how you get your UI item to draw, this is called by
* the RenderPipeline.
*
* @param projection Projection matrix of the camera.
* @param view View matrix of the camera.
* @param parent Matrix of the parent of this UI item.
* @return The list of shader pass items, including children.
*/
std::vector<struct ShaderPassItem> getPassItems(
glm::mat4 projection,
glm::mat4 view,
glm::mat4 parent
);
/**
* Adds a child to this UI Component.
*
* @param child Child UI Component to add.
*/
virtual void addChild(UIComponent *child);
/**
* Removes a child from this UI Component.
*
* @param child Child to remove.
*/
virtual void removeChild(UIComponent *child);
virtual ~UIComponent();
friend class UICanvas;
friend class UIGrid;
};
}

View File

@ -0,0 +1,110 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UILabel.hpp"
#include "game/DawnGame.hpp"
using namespace Dawn;
UILabel::UILabel(UICanvas *canvas) : UIComponent(canvas) {
evtLangUpdated = useEvent([&]{
this->needsRebuffering = true;
if(key.size() > 0 && this->getGame()->localeManager.getString(key).size() > 0) {
this->hasText = true;
}
}, getGame()->localeManager.eventLanguageUpdated);
}
void UILabel::updatePositions() {
UIComponent::updatePositions();
this->updateMesh();
}
void UILabel::updateMesh() {
if(!this->needsRebuffering || !this->hasText) return;
if(this->font == nullptr || !this->font->isReady()) return;
float_t width = this->width;
if(width == 0) width = -1;
std::string text = this->getGame()->localeManager.getString(key);
this->font->buffer(
text,
this->fontSize,
width,
&this->mesh,
&this->measure
);
this->needsRebuffering = false;
}
void UILabel::setFont(Font *font) {
this->font = font;
this->needsRebuffering = true;
}
void UILabel::setText(std::string key) {
this->key = key;
this->hasText = false;
if(key.size() > 0 && this->getGame()->localeManager.getString(key).size()>0){
this->hasText = true;
}
this->needsRebuffering = true;
}
void UILabel::setFontSize(float_t fontSize) {
this->fontSize = fontSize;
this->needsRebuffering = true;
}
float_t UILabel::getFontSize() {
return this->fontSize;
}
float_t UILabel::getContentWidth() {
this->updateMesh();
return this->measure.getWidth();
}
float_t UILabel::getContentHeight() {
this->updateMesh();
return this->measure.getHeight();
}
std::vector<struct ShaderPassItem> UILabel::getSelfPassItems(
glm::mat4 projection,
glm::mat4 view,
glm::mat4 transform
) {
std::vector<struct ShaderPassItem> items;
if(this->font == nullptr) return items;
// this has to go eventually
this->updateMesh();
auto item = this->getGame()->renderManager.uiShaderProgram.getUIPassItem(
projection,
view,
transform,
this->font->getTexture(),
this->textColor,
&this->mesh,
this->z
);
item.start = this->startQuad * QUAD_INDICE_COUNT;
item.count = this->quadCount == -1 ? -1 : this->quadCount * QUAD_INDICE_COUNT;
items.push_back(item);
return items;
}
void UILabel::setTransform(
UIComponentAlign xAlign,
UIComponentAlign yAlign,
glm::vec4 alignment,
float_t z
) {
this->needsRebuffering = true;
UIComponent::setTransform(xAlign, yAlign, alignment, z);
}

View File

@ -0,0 +1,81 @@
// 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 key = "";
float_t fontSize = 10.0f;
bool_t hasText = false;
std::function<void()> evtLangUpdated;
void updatePositions() override;
std::vector<struct ShaderPassItem> getSelfPassItems(
glm::mat4 projection,
glm::mat4 view,
glm::mat4 transform
) 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);
virtual float_t getContentWidth() override;
virtual float_t getContentHeight() 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();
/**
* 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 key Localzied string key for the label to use.
*/
void setText(std::string key);
/**
* Sets / Updates the font size for the label.
*
* @param fontSize Font size to use.
*/
void setFontSize(float_t fontSize);
/**
* Get the labels' current font size.
*
* @return Font size of the label.
*/
float_t getFontSize();
};
}