Dawn/src/dawn/scene/components/ui/UIComponent.cpp
2023-04-30 15:31:22 -07:00

133 lines
3.1 KiB
C++

// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "UIComponent.hpp"
#include "UIGrid.hpp"
using namespace Dawn;
UIComponent::UIComponent(SceneItem *item) :
SceneItemComponent(item),
alignment(glm::vec4(0, 0, 128, 128)),
alignX(UI_COMPONENT_ALIGN_START),
alignY(UI_COMPONENT_ALIGN_START),
alignmentNeedsUpdating(true)
{
}
UIComponentDimensional * UIComponent::getParentDimensional() {
auto parent = this->transform->getParent();
if(parent == nullptr) return nullptr;
auto dimensional = parent->item->getComponent<UIComponentDimensional>();
assertNotNull(dimensional);
return dimensional;
}
void UIComponent::updateAlignment() {
if(!this->alignmentNeedsUpdating) return;
auto align = (glm::vec4)this->alignment;
auto dimensional = this->getParentDimensional();
auto translate = this->transform->getLocalPosition();
float_t parentWidth, parentHeight, parentX, parentY;
auto dimensionalAsGrid = dynamic_cast<UIGrid*>(dimensional);
if(dimensionalAsGrid != nullptr) {
std::cout << "TEST" << std::endl;
} else {
parentWidth = dimensional->getWidth();
parentHeight = dimensional->getHeight();
parentX = 0;
parentY = 0;
}
UIComponent::calculateDimensions(
this->alignX,
&translate.x,
&this->width,
parentWidth,
this->getContentWidth(),
glm::vec2(align[0], align[2])
);
UIComponent::calculateDimensions(
this->alignY,
&translate.y,
&this->height,
parentHeight,
this->getContentHeight(),
glm::vec2(align[1], align[3])
);
translate.x += parentX;
translate.y += parentY;
this->transform->setLocalPosition(translate);
this->alignmentNeedsUpdating = false;
this->eventAlignmentUpdated.invoke();
}
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 = mathMax<float_t>(innerSize, alignment[1]);
*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;
}
}
float_t UIComponent::getWidth() {
return this->width;
}
float_t UIComponent::getHeight() {
return this->height;
}
void UIComponent::onStart() {
useEffect([&]{
this->alignmentNeedsUpdating = true;
}, { &alignment, &alignX, &alignY });
useEffect([&]{
this->updateAlignment();
auto child = this->item->findChildren<UIComponent>();
auto itChild = child.begin();
while(itChild != child.end()) {
(*itChild)->alignmentNeedsUpdating = true;
++itChild;
}
}, alignmentNeedsUpdating)();
}