185 lines
4.0 KiB
C++
185 lines
4.0 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])
|
|
);
|
|
|
|
// 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() {
|
|
|
|
} |