From 2ba59d8e37f0d4e82ba8a7491a340745c3601c2f Mon Sep 17 00:00:00 2001 From: Corentin Date: Sun, 18 Jul 2021 01:19:44 +0900 Subject: [PATCH] Stack component implemented (more flex than stack) --- .ccls | 2 + ROADMAP.md | 21 ++++ include/uui/component.hpp | 17 ++-- include/uui/config.hpp | 12 +++ include/uui/opengl/application.hpp | 28 +++--- include/uui/opengl/component.hpp | 32 ++++-- include/uui/opengl/container.hpp | 44 ++++++++ include/uui/opengl/label.hpp | 12 ++- include/uui/opengl/stack.hpp | 39 ++++++++ make.py | 2 +- manifest.md | 1 - src/test/example_gl.cpp | 95 +++++++++++------- src/uui/opengl/application.cpp | 2 +- src/uui/opengl/component.cpp | 20 ++-- src/uui/opengl/label.cpp | 6 +- src/uui/opengl/stack.cpp | 155 +++++++++++++++++++++++++++++ src/uui/opengl/window.cpp | 34 +++++-- 17 files changed, 424 insertions(+), 98 deletions(-) create mode 100644 ROADMAP.md create mode 100644 include/uui/opengl/container.hpp create mode 100644 include/uui/opengl/stack.hpp create mode 100644 src/uui/opengl/stack.cpp diff --git a/.ccls b/.ccls index 68cd814..04436f7 100644 --- a/.ccls +++ b/.ccls @@ -1,6 +1,8 @@ clang++ -std=c++17 -DDEBUG +-Wall +-Wconversion -Iinclude -I/usr/include/freetype2 -I/usr/include/libpng16 diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..d126f8c --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,21 @@ +* stack component + +* negative absolution position (from right/bottom) + +* flex component + +* layout (constraint) + +* scroll + +* button + +* projected vertex/raw vertex mode (projection on GPU) + +* VAO/VBO in windows (batched) + +* pool/wait mode mechanism + +* better font rendering : signed distance + +* Rich text component : parsing html? making list of struct of texts (with style information for the rendering) diff --git a/include/uui/component.hpp b/include/uui/component.hpp index 7e41fc9..1313eba 100644 --- a/include/uui/component.hpp +++ b/include/uui/component.hpp @@ -3,16 +3,15 @@ #include #include +#include "uui/config.hpp" + namespace uui { class Component { public: - Component( - const std::variant x, const std::variant y, const std::variant width, - const std::variant height): - position_x(x), - position_y(y), size_width(width), size_height(height) + Component(const position_t x, const position_t y, const position_t width, const position_t height): + position_x(x), position_y(y), size_width(width), size_height(height) { background_color = {0.0f, 0.0f, 0.0f, 0.0f}; } @@ -20,10 +19,10 @@ public: virtual void render() = 0; protected: - std::variant position_x; - std::variant position_y; - std::variant size_width; - std::variant size_height; + position_t position_x; + position_t position_y; + position_t size_width; + position_t size_height; std::array background_color; }; diff --git a/include/uui/config.hpp b/include/uui/config.hpp index 1afb3a0..03c4f94 100644 --- a/include/uui/config.hpp +++ b/include/uui/config.hpp @@ -1,8 +1,20 @@ #pragma once +#include + #include "graphic_context.hpp" namespace Config { constexpr unsigned int FONT_TEXTURE_UNIT = GL_TEXTURE0; } + +namespace uui +{ +typedef std::variant position_t; +enum Direction +{ + HORIZONTAL, + VERTICAL +}; +} // namespace uui diff --git a/include/uui/opengl/application.hpp b/include/uui/opengl/application.hpp index df15fe4..ed7ab60 100644 --- a/include/uui/opengl/application.hpp +++ b/include/uui/opengl/application.hpp @@ -6,6 +6,8 @@ #include #include "graphic_context.hpp" +#include "uui/config.hpp" +#include "uui/opengl/container.hpp" #include "uui/opengl/font_manager.hpp" namespace uui @@ -34,49 +36,45 @@ private: static GlApplication* application_pointer; }; -class GlLabel; class GlComponent; -class GlWindow +class GlStack; +class GlLabel; +class GlWindow: public GlContainer, public std::enable_shared_from_this { friend class GlApplication; friend class GlComponent; + friend class GlStack; friend class GlLabel; public: std::string title; - std::vector> components; GlWindow(const GlWindow&) = delete; GlWindow(GlWindow&&) = delete; ~GlWindow(); - std::shared_ptr create_component( - const std::variant x, const std::variant y, const std::variant width, - const std::variant height); + std::shared_ptr create_component(const position_t x, const position_t y, const position_t width, const position_t height); std::shared_ptr create_label( - const std::variant x, const std::variant y, const std::string& text, - const std::tuple& text_color); + const position_t x, const position_t y, const std::string& text, const std::tuple& text_color); + std::shared_ptr create_stack(const position_t x, const position_t y, const Direction direction); protected: GlApplication* app; - - GlFontManager font_manager; + bool initialized; int width; int height; bool render_needed; bool resize_needed; - bool iconified; - size_t index; - bool initialized; + GlFontManager font_manager; GLFWwindow* glfw_window; - GLuint gl_program; - GlWindow(GlApplication* app, size_t index, int width, int height, const std::string& title); + GlWindow(GlApplication* app, int width, int height, const std::string& title); + std::shared_ptr getptr() { return shared_from_this(); } void init(); void deinit(); diff --git a/include/uui/opengl/component.hpp b/include/uui/opengl/component.hpp index b2c57bc..efcb31a 100644 --- a/include/uui/opengl/component.hpp +++ b/include/uui/opengl/component.hpp @@ -2,31 +2,35 @@ #include #include -#include #include "graphic_context.hpp" +#include "uui/config.hpp" +#include "uui/opengl/container.hpp" #include "window.hpp" namespace uui { -class GlComponent +class GlStack; +class GlComponent: public std::enable_shared_from_this { friend class GlWindow; + friend class GlStack; public: - GlComponent(const GlComponent&) = delete; - GlComponent(GlComponent&&) = delete; ~GlComponent(); void set_background_color(float r, float g, float b, float a = 1.0f); protected: std::shared_ptr window; + size_t window_index; + std::shared_ptr parent; + size_t parent_index; - std::variant position_x; - std::variant position_y; - std::variant size_width; - std::variant size_height; + position_t position_x; + position_t position_y; + position_t size_width; + position_t size_height; bool coord_all_relative; std::array background_color; @@ -38,8 +42,16 @@ protected: GLuint gl_ebo; GlComponent( - std::shared_ptr window, const std::variant x, const std::variant y, - const std::variant width, const std::variant height); + std::shared_ptr window, std::size_t window_index, std::shared_ptr parent, std::size_t parent_index, + const position_t x, const position_t y, const position_t width, const position_t height); + GlComponent( + std::shared_ptr window, std::size_t window_index, const position_t x, const position_t y, const position_t width, + const position_t height): + GlComponent(window, window_index, window, window_index, x, y, width, height) + {} + GlComponent(const GlComponent&) = delete; + GlComponent(GlComponent&&) = default; + std::shared_ptr getptr() { return shared_from_this(); } virtual void init(); virtual void set_vbo_data(); diff --git a/include/uui/opengl/container.hpp b/include/uui/opengl/container.hpp new file mode 100644 index 0000000..7c10116 --- /dev/null +++ b/include/uui/opengl/container.hpp @@ -0,0 +1,44 @@ +#pragma once + +#include + +#include +#include + +namespace uui +{ +class GlComponent; +class GlStack; +class GlContainer +{ + friend class GlComponent; + friend class GlStack; + +protected: + GlContainer() = default; + GlContainer(const GlContainer&) = default; + GlContainer(GlContainer&&) = default; + + virtual std::size_t push_child(std::shared_ptr child) + { + components.push_back(child); + return components.size() - 1; + } + virtual std::shared_ptr get_child(std::size_t index) const { return components.at(index); } + virtual void remove_child(std::size_t index) { components.at(index) = nullptr; }; + + virtual std::tuple get_child_position(const std::size_t child_index) const { return {0, 0}; } + +public: + enum Type + { + WINDOW, + STACK + }; + std::vector> components; + Type type; + + ~GlContainer() { components.clear(); } +}; + +} // namespace uui diff --git a/include/uui/opengl/label.hpp b/include/uui/opengl/label.hpp index fcb1d24..c24c5ba 100644 --- a/include/uui/opengl/label.hpp +++ b/include/uui/opengl/label.hpp @@ -4,12 +4,15 @@ #include #include "uui/opengl/component.hpp" +#include "uui/opengl/container.hpp" namespace uui { +class GlStack; class GlLabel: public GlComponent { friend class GlWindow; + friend class GlStack; size_t font_index; @@ -24,8 +27,13 @@ protected: int text_height; GlLabel( - std::shared_ptr window, const std::variant x, const std::variant y, const std::string& text, - const std::tuple& text_color); + std::shared_ptr window, std::size_t window_index, std::shared_ptr parent, std::size_t parent_index, + const position_t x, const position_t y, const std::string& text, const std::tuple& text_color); + GlLabel( + std::shared_ptr window, std::size_t window_index, const position_t x, const position_t y, const std::string& text, + const std::tuple& text_color): + GlLabel(window, window_index, window, window_index, x, y, text, text_color) + {} void render(); }; diff --git a/include/uui/opengl/stack.hpp b/include/uui/opengl/stack.hpp new file mode 100644 index 0000000..e89fba1 --- /dev/null +++ b/include/uui/opengl/stack.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include + +#include "uui/opengl/component.hpp" +#include "uui/opengl/container.hpp" +#include "uui/opengl/label.hpp" + +namespace uui +{ +class GlStack: public GlComponent, public GlContainer +{ + friend class GlWindow; + +public: + std::shared_ptr create_component(const position_t width, const position_t height); + std::shared_ptr create_label(const std::string& text, const std::tuple& text_color); + +protected: + Direction direction; + int content_width; + int content_height; + + GlStack( + std::shared_ptr window, std::size_t window_index, std::shared_ptr parent, std::size_t parent_index, + const position_t x, const position_t y, const Direction direction); + GlStack(std::shared_ptr window, std::size_t window_index, const position_t x, const position_t y, const Direction direction): + GlStack(window, window_index, window, window_index, x, y, direction) + {} + + float get_width() const; + float get_height() const; + + std::tuple get_child_position(const std::size_t child_index) const override; +}; + +} // namespace uui diff --git a/make.py b/make.py index 7799daf..86b943e 100644 --- a/make.py +++ b/make.py @@ -21,7 +21,7 @@ class Config: COMMON_FLAGS = '-std=c++17 -fno-semantic-interposition' COMMON_DEBUG_FLAGS = '-g -DDEBUG' COMMON_RELEASE_FLAGS = '-O2 -flto' - COMPILE_FLAGS = f'-Wall -I{INCLUDE_DIR} `pkg-config --cflags glfw3 vulkan gl x11 freetype2`' + COMPILE_FLAGS = f'-Wall -Wconversion -I{INCLUDE_DIR} `pkg-config --cflags glfw3 vulkan gl x11 freetype2`' LINK_FLAGS = '-lpthread -ldl `pkg-config --libs glfw3 vulkan gl x11 freetype2`' PRE_COMPILE_FUNCTION = None diff --git a/manifest.md b/manifest.md index b7f40bd..1c88ca7 100644 --- a/manifest.md +++ b/manifest.md @@ -1,6 +1,5 @@ # UUI : micro UI Toolkit - * C++ + Vulkan/OpenGL * Python binding diff --git a/src/test/example_gl.cpp b/src/test/example_gl.cpp index f1eeb8b..3d3975f 100644 --- a/src/test/example_gl.cpp +++ b/src/test/example_gl.cpp @@ -1,53 +1,74 @@ #include +#include "uui/config.hpp" #include "uui/opengl/application.hpp" #include "uui/opengl/component.hpp" #include "uui/opengl/label.hpp" +#include "uui/opengl/stack.hpp" using namespace std; int main() { - try + // try + // { + cout << "Starting example 1" << endl; { - cout << "Starting example 1" << endl; - { - uui::GlApplication app; - // uui::GlApplication app2; // exception : application already created - auto window = app.create_window(800, 600, "OpenGl!"); - auto comp = window->create_component(0, 100, 0.5f, 50); - comp->set_background_color(0.8f, 0.1f, 0.5f); - comp = window->create_component(0.25f, 50, 0.4f, 150); - comp->set_background_color(0.3f, 0.8f, 0.4f, 0.5f); - auto label = window->create_label(50, 50, "Hello World!", {0.5f, 1.0f, 0.5f, 1.0f}); - label->set_background_color(0.1f, 0.2f, 0.5f, 0.8f); - label = window->create_label(0.5f, 0.5f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f}); - label->set_background_color(0.5f, 0.5f, 0.1f); - label = window->create_label(0.75f, 0.75f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.1f}); - app.run(); - } - // cout << "\nStarting example 2" << endl; - // { - // uui::GlApplication app; - // auto window_1 = app.create_window(800, 600, "OpenGl!"); - // auto comp = window_1->create_component(0.25f, 0.25f, 0.5f, 0.5f); - // comp->set_background_color(0.8f, 0.1f, 0.5f); - // comp = window_1->create_component(0.75f, 0.75f, 0.25f, 0.25f); - // comp->set_background_color(0.2f, 0.1f, 0.5f); + uui::GlApplication app; + // uui::GlApplication app2; // exception : application already created + auto window = app.create_window(800, 600, "OpenGl!"); - // auto window_2 = app.create_window(600, 600, "OpenGL 2!"); - // comp = window_2->create_component(0, 0.5f, 100, 0.5f); - // comp->set_background_color(0.2f, 0.5f, 0.3f); - // auto label = window_2->create_label(50, 50, "Hello World!", {0.5f, 1.0f, 0.5f, 1.0f}); - // label->set_background_color(0.1f, 0.2f, 0.5f); - // app.run(); - // } - } - catch(const std::exception& error) - { - std::cerr << error.what() << std::endl; - return EXIT_FAILURE; + auto comp = window->create_component(0, 100, 0.5f, 50); + comp->set_background_color(0.8f, 0.1f, 0.5f); + + comp = window->create_component(0.25f, 50, 0.4f, 150); + comp->set_background_color(0.3f, 0.8f, 0.4f, 0.5f); + + auto label = window->create_label(50, 50, "Hello World!", {0.5f, 1.0f, 0.5f, 1.0f}); + label->set_background_color(0.1f, 0.2f, 0.5f, 0.8f); + + label = window->create_label(0.5f, 0.5f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f}); + label->set_background_color(0.5f, 0.5f, 0.1f); + label = window->create_label(0.75f, 0.75f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.1f}); + + auto stack = window->create_stack(200, 0.6f, uui::Direction::HORIZONTAL); + comp = stack->create_component(100, 50); + comp->set_background_color(0.2f, 0.75f, 0.25f); + stack->create_label("test", {0.8f, 0.2f, 0.2f, 1.0f}); + comp = stack->create_component(100, 20); + comp->set_background_color(0.2f, 0.25f, 0.75f); + + stack = window->create_stack(50, 400, uui::Direction::VERTICAL); + comp = stack->create_component(50, 100); + comp->set_background_color(0.2f, 0.75f, 0.25f); + stack->create_label("test", {0.8f, 0.2f, 0.2f, 1.0f}); + comp = stack->create_component(100, 20); + comp->set_background_color(0.2f, 0.25f, 0.75f); + + app.run(); } + // cout << "\nStarting example 2" << endl; + // { + // uui::GlApplication app; + // auto window_1 = app.create_window(800, 600, "OpenGl!"); + // auto comp = window_1->create_component(0.25f, 0.25f, 0.5f, 0.5f); + // comp->set_background_color(0.8f, 0.1f, 0.5f); + // comp = window_1->create_component(0.75f, 0.75f, 0.25f, 0.25f); + // comp->set_background_color(0.2f, 0.1f, 0.5f); + + // auto window_2 = app.create_window(600, 600, "OpenGL 2!"); + // comp = window_2->create_component(0, 0.5f, 100, 0.5f); + // comp->set_background_color(0.2f, 0.5f, 0.3f); + // auto label = window_2->create_label(50, 50, "Hello World!", {0.5f, 1.0f, 0.5f, 1.0f}); + // label->set_background_color(0.1f, 0.2f, 0.5f); + // app.run(); + // } + // } + // catch(const std::exception& error) + // { + // std::cerr << error.what() << std::endl; + // return EXIT_FAILURE; + // } cout << "Example done" << endl; return 0; diff --git a/src/uui/opengl/application.cpp b/src/uui/opengl/application.cpp index 79ed9c6..ee36f85 100644 --- a/src/uui/opengl/application.cpp +++ b/src/uui/opengl/application.cpp @@ -99,7 +99,7 @@ void uui::GlApplication::run() std::shared_ptr uui::GlApplication::create_window(int width, int height, const std::string& title) { - std::shared_ptr window(new uui::GlWindow(this, windows.size(), width, height, title)); + std::shared_ptr window(new uui::GlWindow(this, width, height, title)); window->init(); windows.push_back(window); glfwSwapInterval(1); diff --git a/src/uui/opengl/component.cpp b/src/uui/opengl/component.cpp index 1a43e76..3429f33 100644 --- a/src/uui/opengl/component.cpp +++ b/src/uui/opengl/component.cpp @@ -6,16 +6,17 @@ #include "uui/opengl/gl_utils.hpp" uui::GlComponent::GlComponent( - std::shared_ptr window, const std::variant x, const std::variant y, - const std::variant width, const std::variant height): + std::shared_ptr window, std::size_t window_index, std::shared_ptr parent, std::size_t parent_index, + const position_t x, const position_t y, const position_t width, const position_t height): window(window), - position_x(x), position_y(y), size_width(width), size_height(height), initialized(false) + window_index(window_index), parent(parent), parent_index(parent_index), position_x(x), position_y(y), size_width(width), + size_height(height), initialized(false) { if constexpr(uui::GlApplication::debug_mode) std::cout << "Creating a GlBox" << std::endl; coord_all_relative = true; - auto parse_coords = [&](std::variant& value) { + auto parse_coords = [&](position_t& value) { if(value.index() == 0) { if(std::get<0>(value) == 0) @@ -35,9 +36,11 @@ uui::GlComponent::GlComponent( uui::GlComponent::~GlComponent() { if constexpr(uui::GlApplication::debug_mode) - std::cout << "Closing a GlBox" << std::endl; + std::cout << "Closing a GlComponent" << std::endl; if(initialized) deinit(); + // if(parent != window) + // parent->remove_child(0); // TODO } void uui::GlComponent::set_background_color(float r, float g, float b, float a /*=0.0f*/) @@ -95,8 +98,6 @@ void uui::GlComponent::set_vbo_data() float x_max = x_min + (2.0f * vert_w); float y_min = (-2.0f * vert_y) + 1.0f; float y_max = y_min - (2.0f * vert_h); - std::cout << "Sending vbo data with color: " << background_color[0] << ", " << background_color[1] << ", " << background_color[2] << ", " - << background_color[3] << std::endl; // clang-format off float vertices[] = { x_max, y_min, background_color[0] , background_color[1], background_color[2], background_color[3], // top right @@ -147,8 +148,11 @@ void uui::GlComponent::render() void uui::GlComponent::on_resize() { - if(!coord_all_relative) + bool is_in_stack = parent->type == GlContainer::Type::STACK; + if(!coord_all_relative || is_in_stack) { + if(is_in_stack) + std::tie(position_x, position_y) = parent->get_child_position(parent_index); glBindVertexArray(gl_vao); set_vbo_data(); glBindVertexArray(0); // Optional : for safety diff --git a/src/uui/opengl/label.cpp b/src/uui/opengl/label.cpp index 5ba7478..7e39604 100644 --- a/src/uui/opengl/label.cpp +++ b/src/uui/opengl/label.cpp @@ -5,9 +5,9 @@ #include "uui/opengl/gl_utils.hpp" uui::GlLabel::GlLabel( - std::shared_ptr window, const std::variant x, const std::variant y, const std::string& text, - const std::tuple& text_color): - GlComponent(window, x, y, 0.0f, 0.0f), + std::shared_ptr window, std::size_t window_index, std::shared_ptr parent, std::size_t parent_index, + const position_t x, const position_t y, const std::string& text, const std::tuple& text_color): + GlComponent(window, window_index, parent, parent_index, x, y, 0.0f, 0.0f), text(text), text_color(text_color) { if constexpr(uui::GlApplication::debug_mode) diff --git a/src/uui/opengl/stack.cpp b/src/uui/opengl/stack.cpp new file mode 100644 index 0000000..25037db --- /dev/null +++ b/src/uui/opengl/stack.cpp @@ -0,0 +1,155 @@ +#include "uui/opengl/stack.hpp" + +#include + +#include "uui/opengl/gl_utils.hpp" + +uui::GlStack::GlStack( + std::shared_ptr window, std::size_t window_index, std::shared_ptr parent, std::size_t parent_index, + const position_t x, const position_t y, const Direction direction): + GlComponent(window, window_index, parent, parent_index, x, y, 0.0f, 0.0f), + direction(direction) +{ + if constexpr(uui::GlApplication::debug_mode) + std::cout << "Creating a GlStack" << std::endl; + + type = Type::STACK; + coord_all_relative = false; +} + +std::shared_ptr uui::GlStack::create_component(const position_t width, const position_t height) +{ + if(!initialized) + throw std::runtime_error("GlWindow error : cannot create component while not initialized"); + + glfwMakeContextCurrent(window->glfw_window); + std::shared_ptr component(new uui::GlComponent( + window, window->components.size(), std::dynamic_pointer_cast(shared_from_this()), components.size(), 0, 0, width, + height)); + push_child(component); + component->init(); + std::tie(component->position_x, component->position_y) = get_child_position(components.size() - 1); + window->components.push_back(component); + + return component; +} + +std::shared_ptr uui::GlStack::create_label(const std::string& text, const std::tuple& text_color) +{ + if(!initialized) + throw std::runtime_error("GlWindow error : cannot create component while not initialized"); + + glfwMakeContextCurrent(window->glfw_window); + std::shared_ptr label(new uui::GlLabel( + window, window->components.size(), std::dynamic_pointer_cast(shared_from_this()), components.size(), 0, 0, text, + text_color)); + push_child(label); + label->init(); + std::tie(label->position_x, label->position_y) = get_child_position(components.size() - 1); + window->components.push_back(label); + + return label; +} + +std::tuple uui::GlStack::get_child_position(const std::size_t child_index) const +{ + const int initial_x = + position_x.index() == 0 ? std::get<0>(position_x) : static_cast(std::get<1>(position_x) * static_cast(window->width)); + const int initial_y = + position_y.index() == 0 ? std::get<0>(position_y) : static_cast(std::get<1>(position_y) * static_cast(window->height)); + + if(child_index == 0) + return {initial_x, initial_y}; + if(child_index >= components.size()) + throw std::runtime_error("GlStack error: child_index greater than children count"); + + auto get_child_size = [&](std::size_t index) -> std::tuple { + int width = 0; + int height = 0; + if(components[index] != nullptr) + { + auto& component = components[index]; + if(component->size_width.index() == 1) + width = static_cast(std::get<1>(component->size_width) * static_cast(window->width)); + else + width = std::get<0>(component->size_width); + if(component->size_height.index() == 1) + height = static_cast(std::get<1>(component->size_height) * static_cast(window->height)); + else + height = std::get<0>(component->size_height); + } + return {width, height}; + }; + int x = initial_x; + int y = initial_y; + if(direction == Direction::HORIZONTAL) + { + int child_width; + int child_height; + int max_height = 0; + + std::tie(child_width, child_height) = get_child_size(0); + if(child_height > max_height) + max_height = child_height; + x += child_width; + for(std::size_t index = 1; index < child_index; index += 1) + { + std::tie(child_width, child_height) = get_child_size(index); + if(child_height > max_height) + max_height = child_height; + if(x != initial_x && x + child_width > window->width) + { + x = initial_x + child_width; + y += max_height; + max_height = child_height; + } + else + x += child_width; + } + if(components[child_index] != nullptr) + { + std::tie(child_width, child_height) = get_child_size(child_index); + if(x != initial_x && x + child_width > window->width) + { + x = initial_x; + y += max_height; + } + } + } + else + { + int child_width; + int child_height; + int max_width = 0; + + std::tie(child_width, child_height) = get_child_size(0); + if(child_width > max_width) + max_width = child_width; + y += child_height; + for(std::size_t index = 1; index < child_index; index += 1) + { + std::tie(child_width, child_height) = get_child_size(index); + if(child_width > max_width) + max_width = child_width; + if(y != initial_y && y + child_height > window->height) + { + y = initial_y + child_height; + x += max_width; + max_width = child_width; + } + else + y += child_height; + } + if(components[child_index] != nullptr) + { + std::tie(child_width, child_height) = get_child_size(child_index); + if(y != initial_y && y + child_height > window->height) + { + y = initial_y; + x += max_width; + } + } + } + + return {x, y}; +} diff --git a/src/uui/opengl/window.cpp b/src/uui/opengl/window.cpp index d728d77..bb92f92 100644 --- a/src/uui/opengl/window.cpp +++ b/src/uui/opengl/window.cpp @@ -5,6 +5,7 @@ #include "uui/opengl/component.hpp" #include "uui/opengl/gl_utils.hpp" #include "uui/opengl/label.hpp" +#include "uui/opengl/stack.hpp" #include "uui/shader.hpp" static void APIENTRY @@ -80,12 +81,13 @@ void uui::GlWindow::glfw_key_callback(GLFWwindow* window, int key, int scancode, glfwSetWindowShouldClose(window, true); } -uui::GlWindow::GlWindow(uui::GlApplication* app, size_t index, int width, int height, const std::string& title): - app(app), width(width), height(height), render_needed(true), resize_needed(false), iconified(false), index(index), initialized(false) +uui::GlWindow::GlWindow(uui::GlApplication* app, int width, int height, const std::string& title): + app(app), initialized(false), width(width), height(height), render_needed(true), resize_needed(false), iconified(false) { if constexpr(uui::GlApplication::debug_mode) std::cout << "Creating a GlWindow" << std::endl; this->title = title; + type = Type::WINDOW; } uui::GlWindow::~GlWindow() @@ -247,29 +249,39 @@ void uui::GlWindow::render() } std::shared_ptr uui::GlWindow::create_component( - const std::variant x, const std::variant y, const std::variant width, - const std::variant height) + const position_t x, const position_t y, const position_t width, const position_t height) { if(!initialized) throw std::runtime_error("GlWindow error : cannot create component while not initialized"); glfwMakeContextCurrent(glfw_window); - std::shared_ptr component(new uui::GlComponent(app->get_window(index), x, y, width, height)); + std::shared_ptr component(new uui::GlComponent(shared_from_this(), components.size(), x, y, width, height)); + push_child(component); component->init(); - components.push_back(component); return component; } std::shared_ptr uui::GlWindow::create_label( - const std::variant x, const std::variant y, const std::string& text, - const std::tuple& text_color) + const position_t x, const position_t y, const std::string& text, const std::tuple& text_color) { if(!initialized) - throw std::runtime_error("GlWindow error : cannot create component while not initialized"); + throw std::runtime_error("GlWindow error : cannot create label while not initialized"); glfwMakeContextCurrent(glfw_window); - std::shared_ptr label(new uui::GlLabel(app->get_window(index), x, y, text, text_color)); + std::shared_ptr label(new uui::GlLabel(shared_from_this(), components.size(), x, y, text, text_color)); + push_child(label); label->init(); - components.push_back(label); return label; } + +std::shared_ptr uui::GlWindow::create_stack(const position_t x, const position_t y, const Direction direction) +{ + if(!initialized) + throw std::runtime_error("GlWindow error : cannot create stack while not initialized"); + + glfwMakeContextCurrent(glfw_window); + std::shared_ptr stack(new uui::GlStack(shared_from_this(), components.size(), x, y, direction)); + push_child(stack); + stack->init(); + return stack; +}