ADD: Allow for absolute pixel values

This commit is contained in:
sebastian 2026-02-12 10:37:29 +01:00
parent 47d18092ac
commit f56aed436d
11 changed files with 92 additions and 83 deletions

View File

@ -124,8 +124,8 @@ add_executable(Dicewars_Siedler src/main.cpp
src/engine/core/gui/uiComponent/UiComponent.cpp src/engine/core/gui/uiComponent/UiComponent.cpp
src/engine/core/gui/uiComponent/UiComponent.h src/engine/core/gui/uiComponent/UiComponent.h
src/engine/core/gui/uiComponent/Dimensions.h src/engine/core/gui/uiComponent/Dimensions.h
src/engine/core/gui/uiComponent/UiPositioner.cpp src/engine/core/gui/uiComponent/layout/UiPositioner.cpp
src/engine/core/gui/uiComponent/UiPositioner.h src/engine/core/gui/uiComponent/layout/UiPositioner.h
src/engine/core/gui/uiMain/UiContainer.cpp src/engine/core/gui/uiMain/UiContainer.cpp
src/engine/core/gui/uiMain/UiContainer.h src/engine/core/gui/uiMain/UiContainer.h
src/engine/core/gui/uiComponent/UiImage.cpp src/engine/core/gui/uiComponent/UiImage.cpp
@ -142,6 +142,7 @@ add_executable(Dicewars_Siedler src/main.cpp
src/engine/renderer/TextRenderer.h src/engine/renderer/TextRenderer.h
src/engine/renderer/model/TextQuadModel.cpp src/engine/renderer/model/TextQuadModel.cpp
src/engine/renderer/model/TextQuadModel.h src/engine/renderer/model/TextQuadModel.h
src/engine/core/gui/uiComponent/layout/LayoutStyle.h
) )
target_include_directories(Dicewars_Siedler PRIVATE target_include_directories(Dicewars_Siedler PRIVATE

View File

@ -7,14 +7,15 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "UiPositioner.h" #include "layout/UiPositioner.h"
#include "UiRenderBundle.h" #include "UiRenderBundle.h"
#include "../../../renderer/model/GUITexture.h" #include "../../../renderer/model/GUITexture.h"
class UiComponent { class UiComponent {
public: public:
UiComponent() : uiPositioner(*this) {}; UiComponent() :uiPositioner(*this) {};
UiComponent(const LayoutStyle& layout) : uiPositioner(*this, layout) {};
virtual ~UiComponent() = default; virtual ~UiComponent() = default;
void addChild(std::unique_ptr<UiComponent> child); void addChild(std::unique_ptr<UiComponent> child);
void setVisible(bool visible); void setVisible(bool visible);

View File

@ -9,9 +9,8 @@
class UiImage : public UiComponent { class UiImage : public UiComponent {
public: public:
UiImage(GLuint textureID, const glm::vec2& relativePos, const glm::vec2& relativeSize) : textureID(textureID) { UiImage(GLuint textureID, const LayoutStyle& style) : textureID(textureID), UiComponent(style) {
uiPositioner.setRelativePos(relativePos);
uiPositioner.setRelativeSize(relativeSize);
}; };
protected: protected:

View File

@ -1,28 +0,0 @@
//
// Created by sebastian on 10.02.26.
//
#include "UiPositioner.h"
#include "UiComponent.h"
void UiPositioner::compute(const Dimensions &parent) {
screenSpace.x = parent.x + relativePos.x * parent.width;
screenSpace.y = parent.y + relativePos.y * parent.height;
screenSpace.width = relativeSize.x * parent.width;
screenSpace.height = relativeSize.y * parent.height;
}
void UiPositioner::setRelativePos(const glm::vec2 &pos) {
relativePos = pos;
if (uiComponent.parent) {
compute(uiComponent.parent->uiPositioner.screenSpace);
}
}
void UiPositioner::setRelativeSize(const glm::vec2 &size) {
relativeSize = size;
if (uiComponent.parent) {
compute(uiComponent.parent->uiPositioner.screenSpace);
}
}

View File

@ -1,34 +0,0 @@
//
// Created by sebastian on 10.02.26.
//
#ifndef DICEWARS_SIEDLER_UIPOSITIONER_H
#define DICEWARS_SIEDLER_UIPOSITIONER_H
#include "Dimensions.h"
#include <glm/vec2.hpp>
class UiComponent; // forward declaration
class UiPositioner {
public:
Dimensions screenSpace = Dimensions();
explicit UiPositioner(UiComponent& uiComponent)
: uiComponent(uiComponent),
relativePos(0.0f, 0.0f),
relativeSize(1.0f, 1.0f)
{}
void compute(const Dimensions& parentDimensions);
void setRelativePos(const glm::vec2& pos);
void setRelativeSize(const glm::vec2& size);
private:
UiComponent& uiComponent;
glm::vec2 relativePos; // [0..1] relative to parent
glm::vec2 relativeSize; // [0..1] relative to parent
};
#endif //DICEWARS_SIEDLER_UIPOSITIONER_H

View File

@ -8,13 +8,15 @@
#include "../text/Font.h" #include "../text/Font.h"
UiText::UiText(Font &font, std::string text, const glm::vec2 &relativePos, glm::vec3 color): font(font), text(std::move(text)), color(color) { UiText::UiText(Font &font, std::string text, LayoutStyle& style, glm::vec3 color): font(font), text(std::move(text)), color(color), UiComponent(style) {
uiPositioner.setRelativePos(relativePos);
} }
UiText::UiText(Font &font, std::string text, const glm::vec2 &relativePos) : font(font), text(std::move(text)) { UiText::UiText(Font &font, std::string text, LayoutStyle& style) : font(font), text(std::move(text)), UiComponent(style), color(glm::vec3(0.f)) {
uiPositioner.setRelativePos(relativePos); }
color = glm::vec3(0.f);
void UiText::setText(const std::string &text) {
this->text = text;
} }
void UiText::onCollectRenderData(UiRenderBundle& ui_render_bundle) { void UiText::onCollectRenderData(UiRenderBundle& ui_render_bundle) {

View File

@ -13,8 +13,8 @@ class Font;
class UiText : public UiComponent { class UiText : public UiComponent {
public: public:
UiText(Font& font, std::string text, const glm::vec2& relativePos, glm::vec3 size); UiText(Font& font, std::string text, LayoutStyle& style, glm::vec3 size);
UiText(Font& font, std::string text, const glm::vec2& relativePos); UiText(Font& font, std::string text, LayoutStyle& style);
void setText(const std::string& text); void setText(const std::string& text);
[[nodiscard]] const Font& getFont() const { return font; } [[nodiscard]] const Font& getFont() const { return font; }

View File

@ -45,10 +45,12 @@ struct LayoutStyle {
SizeValue width = {1.0f, SizeUnit::Percent}; SizeValue width = {1.0f, SizeUnit::Percent};
SizeValue height = {1.0f, SizeUnit::Percent}; SizeValue height = {1.0f, SizeUnit::Percent};
Margin margin; Margin margin = {
FlexDirection flexDirection = FlexDirection::Column; .left = {0.0f, SizeUnit::Percent},
JustifyContent justifyContent = JustifyContent::Start; .right = {0.0f, SizeUnit::Percent},
AlignItems alignItems = AlignItems::Start; .top = {0.0f, SizeUnit::Percent},
.bottom = {0.0f, SizeUnit::Percent}
};
float flexGrow = 0.0f; float flexGrow = 0.0f;
}; };

View File

@ -0,0 +1,31 @@
//
// Created by sebastian on 10.02.26.
//
#include "UiPositioner.h"
#include "../UiComponent.h"
#include "../../../Application.h"
void UiPositioner::compute(const Dimensions &parent) {
const auto screenWidth = static_cast<float>(Application::getInstance().getWindow().GetWidth());
const auto screenHeight = static_cast<float>(Application::getInstance().getWindow().GetHeight());
screenSpace.x = parent.x + resolve(style.margin.left, parent.width, screenWidth);
screenSpace.y = parent.y + resolve(style.margin.top, parent.height, screenHeight);
screenSpace.width = resolve(style.width, parent.width, screenWidth);
screenSpace.height = resolve(style.height, parent.height, screenHeight);
}
float UiPositioner::resolve(const SizeValue &size, float parentSize, float axisLength) {
switch (size.unit) {
case SizeUnit::Percent:
return size.value * parentSize;
case SizeUnit::Pixels:
return size.value / axisLength; // has to be normalized!
default:
return 0.0f;
}
}

View File

@ -0,0 +1,30 @@
//
// Created by sebastian on 10.02.26.
//
#ifndef DICEWARS_SIEDLER_UIPOSITIONER_H
#define DICEWARS_SIEDLER_UIPOSITIONER_H
#include "../Dimensions.h"
#include <glm/vec2.hpp>
#include "LayoutStyle.h"
class UiComponent; // forward declaration
class UiPositioner {
public:
Dimensions screenSpace = Dimensions();
explicit UiPositioner(UiComponent& uiComponent): uiComponent(uiComponent), style() {}
UiPositioner(UiComponent& uiComponent, const LayoutStyle& style): uiComponent(uiComponent), style(style) {}
void compute(const Dimensions& parentDimensions);
private:
UiComponent& uiComponent;
LayoutStyle style;
float resolve(const SizeValue &size, float parentSize, float axisLength);
};
#endif //DICEWARS_SIEDLER_UIPOSITIONER_H

View File

@ -22,19 +22,24 @@ void UILayer::onAttach() {
rootContainer = std::make_unique<UiContainer>(); rootContainer = std::make_unique<UiContainer>();
auto imageStyle = LayoutStyle();
imageStyle.width = SizeValue(0.5f, SizeUnit::Percent);
imageStyle.height = SizeValue(0.5f, SizeUnit::Percent);
imageStyle.margin.left = {50.f, SizeUnit::Pixels};
imageStyle.margin.top = {0.f, SizeUnit::Percent};
auto image = std::make_unique<UiImage>( auto image = std::make_unique<UiImage>(
Loader::instance().loadTextureFromFile("assets/textures/texture.png").getTextureID(), Loader::instance().loadTextureFromFile("assets/textures/texture.png").getTextureID(),
glm::vec2(0.5f, 0.5f), glm::vec2(0.5f) imageStyle
); );
rootContainer->addChild(std::move(image)); rootContainer->addChild(std::move(image));
Font myFont("/usr/share/fonts/TTF/DejaVuSans.ttf", 48); Font myFont("/usr/share/fonts/TTF/DejaVuSans.ttf", 48);
font = std::make_unique<Font>(myFont); font = std::make_unique<Font>(myFont);
auto text = std::make_unique<UiText>(*font, "Hello World!", glm::vec2(0.5f, 0.5f), glm::vec3(1,1,1)); //auto text = std::make_unique<UiText>(*font, "Hello World!", glm::vec2(0.5f, 0.5f), glm::vec3(1,1,1));
rootContainer->addChild(std::move(text)); //rootContainer->addChild(std::move(text));
} }
void UILayer::onUpdate() { void UILayer::onUpdate() {