Stack component implemented (more flex than stack)

This commit is contained in:
Corentin 2021-07-18 01:19:44 +09:00
commit 2ba59d8e37
17 changed files with 426 additions and 100 deletions

View file

@ -1,53 +1,74 @@
#include <iostream>
#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;

View file

@ -99,7 +99,7 @@ void uui::GlApplication::run()
std::shared_ptr<uui::GlWindow> uui::GlApplication::create_window(int width, int height, const std::string& title)
{
std::shared_ptr<uui::GlWindow> window(new uui::GlWindow(this, windows.size(), width, height, title));
std::shared_ptr<uui::GlWindow> window(new uui::GlWindow(this, width, height, title));
window->init();
windows.push_back(window);
glfwSwapInterval(1);

View file

@ -6,16 +6,17 @@
#include "uui/opengl/gl_utils.hpp"
uui::GlComponent::GlComponent(
std::shared_ptr<GlWindow> window, const std::variant<int, float> x, const std::variant<int, float> y,
const std::variant<int, float> width, const std::variant<int, float> height):
std::shared_ptr<GlWindow> window, std::size_t window_index, std::shared_ptr<GlContainer> 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<int, float>& 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

View file

@ -5,9 +5,9 @@
#include "uui/opengl/gl_utils.hpp"
uui::GlLabel::GlLabel(
std::shared_ptr<uui::GlWindow> window, const std::variant<int, float> x, const std::variant<int, float> y, const std::string& text,
const std::tuple<float, float, float, float>& text_color):
GlComponent(window, x, y, 0.0f, 0.0f),
std::shared_ptr<uui::GlWindow> window, std::size_t window_index, std::shared_ptr<uui::GlContainer> parent, std::size_t parent_index,
const position_t x, const position_t y, const std::string& text, const std::tuple<float, float, float, float>& 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)

155
src/uui/opengl/stack.cpp Normal file
View file

@ -0,0 +1,155 @@
#include "uui/opengl/stack.hpp"
#include <iostream>
#include "uui/opengl/gl_utils.hpp"
uui::GlStack::GlStack(
std::shared_ptr<uui::GlWindow> window, std::size_t window_index, std::shared_ptr<uui::GlContainer> 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::GlComponent> 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<uui::GlComponent> component(new uui::GlComponent(
window, window->components.size(), std::dynamic_pointer_cast<uui::GlContainer>(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::GlLabel> uui::GlStack::create_label(const std::string& text, const std::tuple<float, float, float, float>& text_color)
{
if(!initialized)
throw std::runtime_error("GlWindow error : cannot create component while not initialized");
glfwMakeContextCurrent(window->glfw_window);
std::shared_ptr<uui::GlLabel> label(new uui::GlLabel(
window, window->components.size(), std::dynamic_pointer_cast<uui::GlContainer>(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<int, int> 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<int>(std::get<1>(position_x) * static_cast<float>(window->width));
const int initial_y =
position_y.index() == 0 ? std::get<0>(position_y) : static_cast<int>(std::get<1>(position_y) * static_cast<float>(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, int> {
int width = 0;
int height = 0;
if(components[index] != nullptr)
{
auto& component = components[index];
if(component->size_width.index() == 1)
width = static_cast<int>(std::get<1>(component->size_width) * static_cast<float>(window->width));
else
width = std::get<0>(component->size_width);
if(component->size_height.index() == 1)
height = static_cast<int>(std::get<1>(component->size_height) * static_cast<float>(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};
}

View file

@ -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::GlComponent> uui::GlWindow::create_component(
const std::variant<int, float> x, const std::variant<int, float> y, const std::variant<int, float> width,
const std::variant<int, float> 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<uui::GlComponent> component(new uui::GlComponent(app->get_window(index), x, y, width, height));
std::shared_ptr<uui::GlComponent> 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::GlLabel> uui::GlWindow::create_label(
const std::variant<int, float> x, const std::variant<int, float> y, const std::string& text,
const std::tuple<float, float, float, float>& text_color)
const position_t x, const position_t y, const std::string& text, const std::tuple<float, float, float, float>& 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<uui::GlLabel> label(new uui::GlLabel(app->get_window(index), x, y, text, text_color));
std::shared_ptr<uui::GlLabel> 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::GlStack> 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<uui::GlStack> stack(new uui::GlStack(shared_from_this(), components.size(), x, y, direction));
push_child(stack);
stack->init();
return stack;
}