// 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(); 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(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(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(); auto itChild = child.begin(); while(itChild != child.end()) { (*itChild)->alignmentNeedsUpdating = true; ++itChild; } }, alignmentNeedsUpdating)(); }