From 896f98476e276b105a72b1c7126fc3cf2fdc67cf Mon Sep 17 00:00:00 2001 From: Corentin Date: Thu, 22 Jul 2021 17:47:03 +0900 Subject: [PATCH] Implement GlStack, GlFlex is now child of GlStack --- ROADMAP.md | 2 - include/uui/opengl/application.hpp | 3 + include/uui/opengl/component.hpp | 2 + include/uui/opengl/container.hpp | 3 +- include/uui/opengl/flex.hpp | 14 +---- include/uui/opengl/label.hpp | 2 + include/uui/opengl/stack.hpp | 39 ++++++++++++ src/test/example_gl.cpp | 20 ++++++- src/uui/opengl/component.cpp | 2 +- src/uui/opengl/flex.cpp | 37 +----------- src/uui/opengl/stack.cpp | 96 ++++++++++++++++++++++++++++++ src/uui/opengl/window.cpp | 14 ++++- 12 files changed, 179 insertions(+), 55 deletions(-) create mode 100644 include/uui/opengl/stack.hpp create mode 100644 src/uui/opengl/stack.cpp diff --git a/ROADMAP.md b/ROADMAP.md index e4b4f52..9c5580d 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,3 @@ -* stack component - * button * layout (constraint) diff --git a/include/uui/opengl/application.hpp b/include/uui/opengl/application.hpp index 2488997..2146237 100644 --- a/include/uui/opengl/application.hpp +++ b/include/uui/opengl/application.hpp @@ -39,12 +39,14 @@ private: class GlComponent; class GlFlex; class GlLabel; +class GlStack; class GlWindow: public GlContainer, public std::enable_shared_from_this { friend class GlApplication; friend class GlComponent; friend class GlFlex; friend class GlLabel; + friend class GlStack; public: std::string title; @@ -57,6 +59,7 @@ public: std::shared_ptr create_label( const position_t x, const position_t y, const std::string& text, const std::tuple& text_color); std::shared_ptr create_flex(const position_t x, const position_t y, const Direction direction); + std::shared_ptr create_stack(const position_t x, const position_t y, const Direction direction); protected: GlApplication* app; diff --git a/include/uui/opengl/component.hpp b/include/uui/opengl/component.hpp index d6b3b2d..ab9a554 100644 --- a/include/uui/opengl/component.hpp +++ b/include/uui/opengl/component.hpp @@ -11,10 +11,12 @@ namespace uui { class GlFlex; +class GlStack; class GlComponent: public std::enable_shared_from_this { friend class GlWindow; friend class GlFlex; + friend class GlStack; public: ~GlComponent(); diff --git a/include/uui/opengl/container.hpp b/include/uui/opengl/container.hpp index 0455201..f690fb1 100644 --- a/include/uui/opengl/container.hpp +++ b/include/uui/opengl/container.hpp @@ -33,7 +33,8 @@ public: enum Type { WINDOW, - FLEX + FLEX, + STACK }; std::vector> components; Type type; diff --git a/include/uui/opengl/flex.hpp b/include/uui/opengl/flex.hpp index 1bd209b..8448c7a 100644 --- a/include/uui/opengl/flex.hpp +++ b/include/uui/opengl/flex.hpp @@ -7,22 +7,15 @@ #include "uui/opengl/component.hpp" #include "uui/opengl/container.hpp" #include "uui/opengl/label.hpp" +#include "uui/opengl/stack.hpp" namespace uui { -class GlFlex: public GlComponent, public GlContainer +class GlFlex: public GlStack { 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; - GlFlex( 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); @@ -30,9 +23,6 @@ protected: GlFlex(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; }; diff --git a/include/uui/opengl/label.hpp b/include/uui/opengl/label.hpp index 3257da5..be3eee1 100644 --- a/include/uui/opengl/label.hpp +++ b/include/uui/opengl/label.hpp @@ -9,10 +9,12 @@ namespace uui { class GlFlex; +class GlStack; class GlLabel: public GlComponent { friend class GlWindow; friend class GlFlex; + friend class GlStack; size_t font_index; diff --git a/include/uui/opengl/stack.hpp b/include/uui/opengl/stack.hpp new file mode 100644 index 0000000..6a52e38 --- /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; + + virtual std::tuple get_child_position(const std::size_t child_index) const; +}; + +} // namespace uui diff --git a/src/test/example_gl.cpp b/src/test/example_gl.cpp index 6204a78..8315822 100644 --- a/src/test/example_gl.cpp +++ b/src/test/example_gl.cpp @@ -31,14 +31,30 @@ int main() 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_flex(200, 0.6f, uui::Direction::HORIZONTAL); + auto flex = window->create_flex(200, 0.6f, uui::Direction::HORIZONTAL); + comp = flex->create_component(100, 50); + comp->set_background_color(0.2f, 0.75f, 0.25f); + flex->create_label("test", {0.8f, 0.2f, 0.2f, 1.0f}); + comp = flex->create_component(100, 20); + comp->set_background_color(0.2f, 0.25f, 0.75f); + + flex = window->create_flex(50, 400, uui::Direction::VERTICAL); + comp = flex->create_component(50, 100); + comp->set_background_color(0.2f, 0.75f, 0.25f); + flex->create_label("test", {0.8f, 0.2f, 0.2f, 1.0f}); + comp = flex->create_component(100, 20); + comp->set_background_color(0.2f, 0.25f, 0.75f); + + window = app.create_window(800, 600, "OpenGl 2"); + + 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_flex(50, 400, uui::Direction::VERTICAL); + 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}); diff --git a/src/uui/opengl/component.cpp b/src/uui/opengl/component.cpp index 843a45c..f4e031e 100644 --- a/src/uui/opengl/component.cpp +++ b/src/uui/opengl/component.cpp @@ -148,7 +148,7 @@ void uui::GlComponent::render() void uui::GlComponent::on_resize() { - bool is_in_stack = parent->type == GlContainer::Type::FLEX; + bool is_in_stack = parent->type == GlContainer::Type::FLEX || parent->type == GlContainer::Type::STACK; if(!coord_all_relative || is_in_stack) { if(is_in_stack) diff --git a/src/uui/opengl/flex.cpp b/src/uui/opengl/flex.cpp index 73f819a..5cd73db 100644 --- a/src/uui/opengl/flex.cpp +++ b/src/uui/opengl/flex.cpp @@ -7,8 +7,7 @@ uui::GlFlex::GlFlex( 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) + GlStack(window, window_index, parent, parent_index, x, y, direction) { if constexpr(uui::GlApplication::debug_mode) std::cout << "Creating a GlStack" << std::endl; @@ -17,40 +16,6 @@ uui::GlFlex::GlFlex( coord_all_relative = false; } -std::shared_ptr uui::GlFlex::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::GlFlex::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::GlFlex::get_child_position(const std::size_t child_index) const { const int initial_x = diff --git a/src/uui/opengl/stack.cpp b/src/uui/opengl/stack.cpp new file mode 100644 index 0000000..1b2c9f1 --- /dev/null +++ b/src/uui/opengl/stack.cpp @@ -0,0 +1,96 @@ +#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; + + std::cout << "Stack:" << direction << 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 +{ + int x = + position_x.index() == 0 ? std::get<0>(position_x) : static_cast(std::get<1>(position_x) * static_cast(window->width)); + int 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 {x, y}; + if(child_index >= components.size()) + throw std::runtime_error("GlStack error: child_index greater than children count"); + + if(direction == Direction::HORIZONTAL) + { + for(std::size_t index = 0; index < child_index; index += 1) + if(components[index] != nullptr) + { + auto& component = components[index]; + if(component->size_width.index() == 1) + x += static_cast(std::get<1>(component->size_width) * static_cast(window->width)); + else + x += std::get<0>(component->size_width); + } + } + else + { + for(std::size_t index = 0; index < child_index; index += 1) + { + if(components[index] != nullptr) + { + auto& component = components[index]; + if(component->size_height.index() == 1) + y += static_cast(std::get<1>(component->size_height) * static_cast(window->height)); + else + y += std::get<0>(component->size_height); + } + } + } + + return {x, y}; +} diff --git a/src/uui/opengl/window.cpp b/src/uui/opengl/window.cpp index 3f866c6..5063be7 100644 --- a/src/uui/opengl/window.cpp +++ b/src/uui/opengl/window.cpp @@ -275,12 +275,24 @@ std::shared_ptr uui::GlWindow::create_label( } std::shared_ptr uui::GlWindow::create_flex(const position_t x, const position_t y, const Direction direction) +{ + if(!initialized) + throw std::runtime_error("GlWindow error : cannot create flex while not initialized"); + + glfwMakeContextCurrent(glfw_window); + std::shared_ptr flex(new uui::GlFlex(shared_from_this(), components.size(), x, y, direction)); + push_child(flex); + flex->init(); + return flex; +} + +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::GlFlex(shared_from_this(), components.size(), x, y, direction)); + std::shared_ptr stack(new uui::GlStack(shared_from_this(), components.size(), x, y, direction)); push_child(stack); stack->init(); return stack;