Dawn/archive/ui/UIComponent.cpp
2023-03-05 12:58:59 -08:00

190 lines
4.3 KiB
C++

// 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])
);
// 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();
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() {
}