Add init function for cleaner usage

This commit is contained in:
Corentin 2022-10-01 08:06:38 +09:00
commit af734cda73
12 changed files with 156 additions and 91 deletions

3
README.md Normal file
View file

@ -0,0 +1,3 @@
# UUI
Simple and efficient C++ GUI toolkit

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <functional>
#include <memory> #include <memory>
#include <string> #include <string>
#include <variant> #include <variant>
@ -12,6 +13,7 @@
namespace uui namespace uui
{ {
template<typename T> using InitFunction = const std::function<void(T&)>&;
class GlWindow; class GlWindow;
class GlApplication class GlApplication
{ {
@ -29,7 +31,7 @@ public:
~GlApplication(); ~GlApplication();
void run(); void run();
std::shared_ptr<GlWindow> create_window(int width, int height, const std::string& title); void create_window(int width, int height, const std::string& title, InitFunction<GlWindow> init);
std::shared_ptr<GlWindow> get_window(std::size_t index) const; std::shared_ptr<GlWindow> get_window(std::size_t index) const;
private: private:
@ -55,13 +57,14 @@ public:
GlWindow(GlWindow&&) = delete; GlWindow(GlWindow&&) = delete;
~GlWindow(); ~GlWindow();
std::shared_ptr<GlComponent> create_component( void create_component(
const position_t x, const position_t y, const position_t width, const position_t height); const position_t x, const position_t y, const position_t width, const position_t height,
std::shared_ptr<GlLabel> create_label( InitFunction<GlComponent> init);
void create_label(
const position_t x, const position_t y, const std::string& text, const position_t x, const position_t y, const std::string& text,
const std::tuple<float, float, float, float>& text_color); const std::tuple<float, float, float, float>& text_color, InitFunction<GlLabel> init);
std::shared_ptr<GlFlex> create_flex(const position_t x, const position_t y, const Direction direction); void create_flex(const position_t x, const position_t y, const Direction direction, InitFunction<GlFlex> init);
std::shared_ptr<GlStack> create_stack(const position_t x, const position_t y, const Direction direction); void create_stack(const position_t x, const position_t y, const Direction direction, InitFunction<GlStack> init);
protected: protected:
GlApplication* app; GlApplication* app;

View file

@ -31,6 +31,11 @@ protected:
virtual std::tuple<int, int> get_child_position(const std::size_t child_index) const { return {0, 0}; } virtual std::tuple<int, int> get_child_position(const std::size_t child_index) const { return {0, 0}; }
public: public:
#ifdef DEBUG
constexpr static bool debug_mode = true;
#else
constexpr static bool debug_mode = false;
#endif
enum Type enum Type
{ {
WINDOW, WINDOW,
@ -42,7 +47,8 @@ public:
virtual ~GlContainer() virtual ~GlContainer()
{ {
std::cout << "Destroying Container" << std::endl; if constexpr(debug_mode)
std::cout << "Destroying Container" << std::endl;
components.clear(); components.clear();
} }
}; };

View file

@ -15,9 +15,9 @@ class GlStack: public GlComponent, public GlContainer
friend class GlWindow; friend class GlWindow;
public: public:
std::shared_ptr<GlComponent> create_component(const position_t width, const position_t height); void create_component(const position_t width, const position_t height, InitFunction<GlComponent> init);
std::shared_ptr<GlLabel> create_label( void create_label(
const std::string& text, const std::tuple<float, float, float, float>& text_color); const std::string& text, const std::tuple<float, float, float, float>& text_color, InitFunction<GlLabel> init);
protected: protected:
Direction direction; Direction direction;

View file

@ -0,0 +1,6 @@
#pragma once
#include "uui/opengl/application.hpp"
#include "uui/opengl/component.hpp"
#include "uui/opengl/flex.hpp"
#include "uui/opengl/label.hpp"

View file

@ -9,7 +9,7 @@ from umake import get_hash, make
class Config: class Config:
CC = 'g++' CC = 'g++'
APPS = ['test/example_gl', 'test/benchmark_text'] APPS = ['test/example_gl', 'test/benchmark_text', 'test/sample']
IGNORE_APPS = [] IGNORE_APPS = []
JOB_COUNT = int(os.cpu_count() * 0.8) JOB_COUNT = int(os.cpu_count() * 0.8)
@ -19,9 +19,9 @@ class Config:
SOURCE_DIR = Path('src') SOURCE_DIR = Path('src')
COMMON_FLAGS = '-std=c++17 -fno-semantic-interposition' COMMON_FLAGS = '-std=c++17 -fno-semantic-interposition'
COMMON_DEBUG_FLAGS = '-g -DDEBUG' COMMON_DEBUG_FLAGS = '-g -Og -DDEBUG'
COMMON_RELEASE_FLAGS = '-O2 -flto' COMMON_RELEASE_FLAGS = '-O2 -flto'
COMPILE_FLAGS = f'-Wall -Wconversion -I{INCLUDE_DIR} `pkg-config --cflags glfw3 vulkan gl x11 freetype2`' COMPILE_FLAGS = f'-Wall -Wextra -Wpedantic -Wconversion -I{INCLUDE_DIR} `pkg-config --cflags glfw3 vulkan gl x11 freetype2`'
LINK_FLAGS = '-lpthread -ldl `pkg-config --libs glfw3 vulkan gl x11 freetype2`' LINK_FLAGS = '-lpthread -ldl `pkg-config --libs glfw3 vulkan gl x11 freetype2`'
PRE_COMPILE_FUNCTION = None PRE_COMPILE_FUNCTION = None

View file

@ -1,8 +1,6 @@
#include <iostream> #include <iostream>
#include "uui/opengl/application.hpp" #include "uui/opengl/uui.hpp"
#include "uui/opengl/component.hpp"
#include "uui/opengl/label.hpp"
using namespace std; using namespace std;
@ -12,8 +10,9 @@ int main()
{ {
uui::GlApplication app; uui::GlApplication app;
// uui::GlApplication app2; // exception : application already created // uui::GlApplication app2; // exception : application already created
auto window = app.create_window(800, 600, "OpenGl!"); app.create_window(800, 600, "OpenGl!", [](uui::GlWindow& window) {
for(int i = 0; i < 100; i += 1) window->create_label(4 * i, 4 * i, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f}); for(int i = 0; i < 100; i += 1) window.create_label(4 * i, 4 * i, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f}, {});
});
app.run(); app.run();
} }
catch(const std::exception& error) catch(const std::exception& error)

View file

@ -1,10 +1,6 @@
#include <iostream> #include <iostream>
#include "uui/config.hpp" #include "uui/opengl/uui.hpp"
#include "uui/opengl/application.hpp"
#include "uui/opengl/component.hpp"
#include "uui/opengl/flex.hpp"
#include "uui/opengl/label.hpp"
using namespace std; using namespace std;
@ -16,67 +12,89 @@ int main()
{ {
uui::GlApplication app; uui::GlApplication app;
// uui::GlApplication app2; // exception : application already created // uui::GlApplication app2; // exception : application already created
auto window = app.create_window(800, 600, "OpenGl!"); app.create_window(800, 600, "OpenGl!", [](uui::GlWindow& window) {
window.create_component(0, 100, 0.5f, 50, [](uui::GlComponent& component) {
component.set_background_color(0.8f, 0.1f, 0.5f);
});
auto comp = window->create_component(0, 100, 0.5f, 50); window.create_component(0.25f, 50, 0.4f, 150, [](uui::GlComponent& component) {
comp->set_background_color(0.8f, 0.1f, 0.5f); component.set_background_color(0.3f, 0.8f, 0.4f, 0.5f);
});
comp = window->create_component(0.25f, 50, 0.4f, 150); window.create_label(50, 50, "Hello World!", {0.5f, 1.0f, 0.5f, 1.0f}, [](uui::GlLabel& label) {
comp->set_background_color(0.3f, 0.8f, 0.4f, 0.5f); label.set_background_color(0.1f, 0.2f, 0.5f, 0.8f);
});
auto label = window->create_label(50, 50, "Hello World!", {0.5f, 1.0f, 0.5f, 1.0f}); window.create_label(0.5f, 0.5f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f}, [](uui::GlLabel& label) {
label->set_background_color(0.1f, 0.2f, 0.5f, 0.8f); label.set_background_color(0.5f, 0.5f, 0.1f);
});
window.create_label(0.75f, 0.75f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.1f}, {});
label = window->create_label(0.5f, 0.5f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f}); window.create_flex(200, 0.6f, uui::Direction::HORIZONTAL, [](uui::GlFlex& flex) {
label->set_background_color(0.5f, 0.5f, 0.1f); flex.create_component(100, 50, [](uui::GlComponent& component) {
label = window->create_label(0.75f, 0.75f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.1f}); component.set_background_color(0.2f, 0.75f, 0.25f);
});
flex.create_label("test", {0.8f, 0.2f, 0.2f, 1.0f}, {});
flex.create_component(100, 20, [](uui::GlComponent& component) {
component.set_background_color(0.2f, 0.25f, 0.75f);
});
});
auto flex = window->create_flex(200, 0.6f, uui::Direction::HORIZONTAL); window.create_flex(50, 400, uui::Direction::VERTICAL, [](uui::GlFlex& flex) {
comp = flex->create_component(100, 50); flex.create_component(50, 100, [](uui::GlComponent& component) {
comp->set_background_color(0.2f, 0.75f, 0.25f); component.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); flex.create_label("test", {0.8f, 0.2f, 0.2f, 1.0f}, {});
comp->set_background_color(0.2f, 0.25f, 0.75f); flex.create_component(100, 20, [](uui::GlComponent& component) {
component.set_background_color(0.2f, 0.25f, 0.75f);
});
});
});
flex = window->create_flex(50, 400, uui::Direction::VERTICAL); app.create_window(800, 600, "OpenGl 2", [](uui::GlWindow& window) {
comp = flex->create_component(50, 100); window.create_stack(200, 0.6f, uui::Direction::HORIZONTAL, [](uui::GlStack& stack) {
comp->set_background_color(0.2f, 0.75f, 0.25f); stack.create_component(100, 50, [](uui::GlComponent& component) {
flex->create_label("test", {0.8f, 0.2f, 0.2f, 1.0f}); component.set_background_color(0.2f, 0.75f, 0.25f);
comp = flex->create_component(100, 20); });
comp->set_background_color(0.2f, 0.25f, 0.75f); stack.create_label("test", {0.8f, 0.2f, 0.2f, 1.0f}, {});
stack.create_component(100, 20, [](uui::GlComponent& component) {
component.set_background_color(0.2f, 0.25f, 0.75f);
});
});
window = app.create_window(800, 600, "OpenGl 2"); window.create_stack(50, 400, uui::Direction::VERTICAL, [](uui::GlStack& stack) {
stack.create_component(100, 50, [](uui::GlComponent& component) {
auto stack = window->create_stack(200, 0.6f, uui::Direction::HORIZONTAL); component.set_background_color(0.2f, 0.75f, 0.25f);
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}, {});
stack->create_label("test", {0.8f, 0.2f, 0.2f, 1.0f}); stack.create_component(100, 20, [](uui::GlComponent& component) {
comp = stack->create_component(100, 20); component.set_background_color(0.2f, 0.25f, 0.75f);
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(); app.run();
} }
cout << "\nStarting example 2" << endl; cout << "\nStarting example 2" << endl;
{ {
uui::GlApplication app; uui::GlApplication app;
auto window_1 = app.create_window(800, 600, "OpenGl!"); app.create_window(800, 600, "OpenGl!", [](uui::GlWindow& window) {
auto comp = window_1->create_component(0.25f, 0.25f, 0.5f, 0.5f); window.create_component(0.25f, 0.25f, 0.5f, 0.5f, [](uui::GlComponent& component) {
comp->set_background_color(0.8f, 0.1f, 0.5f); component.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); window.create_component(0.75f, 0.75f, 0.25f, 0.25f, [](uui::GlComponent& component) {
component.set_background_color(0.2f, 0.1f, 0.5f);
});
});
auto window_2 = app.create_window(600, 600, "OpenGL 2!"); app.create_window(600, 600, "OpenGL 2!", [](uui::GlWindow& window) {
comp = window_2->create_component(0, 0.5f, 100, 0.5f); window.create_component(0, 0.5f, 100, 0.5f, [](uui::GlComponent& component) {
comp->set_background_color(0.2f, 0.5f, 0.3f); component.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); window.create_label(50, 50, "Hello World!", {0.5f, 1.0f, 0.5f, 1.0f}, [](uui::GlLabel& label) {
label.set_background_color(0.1f, 0.2f, 0.5f);
});
});
app.run(); app.run();
} }
} }

14
src/test/sample.cpp Normal file
View file

@ -0,0 +1,14 @@
#include "uui/opengl/uui.hpp"
int main()
{
uui::GlApplication app;
app.create_window(800, 600, "UUI sample", [](uui::GlWindow& window) {
window.create_component(
0, 0, 200, 100, [](uui::GlComponent& component) { component.set_background_color(1.0f, 0.f, 0.f, 0.5f); });
window.create_label(0.5f, 0.5f, "Hello world!", {0.8f, 0.8f, 0.8f, 1.0f}, nullptr);
});
app.run();
return 0;
}

View file

@ -97,7 +97,8 @@ void uui::GlApplication::run()
std::cout << "Ending the GlApplication" << std::endl; std::cout << "Ending the GlApplication" << std::endl;
} }
std::shared_ptr<uui::GlWindow> uui::GlApplication::create_window(int width, int height, const std::string& title) void uui::GlApplication::create_window(
int width, int height, const std::string& title, uui::InitFunction<GlWindow> init)
{ {
std::shared_ptr<uui::GlWindow> window(new uui::GlWindow(this, width, height, title)); std::shared_ptr<uui::GlWindow> window(new uui::GlWindow(this, width, height, title));
window->init(); window->init();
@ -108,7 +109,9 @@ std::shared_ptr<uui::GlWindow> uui::GlApplication::create_window(int width, int
glfwMakeContextCurrent((*(windows.end() - 2))->glfw_window); glfwMakeContextCurrent((*(windows.end() - 2))->glfw_window);
glfwSwapInterval(0); glfwSwapInterval(0);
} }
return window;
if(window != nullptr && init != nullptr)
init(*window);
} }
std::shared_ptr<uui::GlWindow> uui::GlApplication::get_window(std::size_t index) const std::shared_ptr<uui::GlWindow> uui::GlApplication::get_window(std::size_t index) const

View file

@ -17,7 +17,8 @@ uui::GlStack::GlStack(
coord_all_relative = false; coord_all_relative = false;
} }
std::shared_ptr<uui::GlComponent> uui::GlStack::create_component(const position_t width, const position_t height) void uui::GlStack::create_component(
const uui::position_t width, const uui::position_t height, uui::InitFunction<uui::GlComponent> init)
{ {
if(!initialized) if(!initialized)
throw std::runtime_error("GlWindow error : cannot create component while not initialized"); throw std::runtime_error("GlWindow error : cannot create component while not initialized");
@ -31,11 +32,13 @@ std::shared_ptr<uui::GlComponent> uui::GlStack::create_component(const position_
std::tie(component->position_x, component->position_y) = get_child_position(components.size() - 1); std::tie(component->position_x, component->position_y) = get_child_position(components.size() - 1);
window->components.push_back(component); window->components.push_back(component);
return component; if(component != nullptr)
init(*component);
} }
std::shared_ptr<uui::GlLabel> uui::GlStack::create_label( void uui::GlStack::create_label(
const std::string& text, const std::tuple<float, float, float, float>& text_color) const std::string& text, const std::tuple<float, float, float, float>& text_color,
uui::InitFunction<uui::GlLabel> init)
{ {
if(!initialized) if(!initialized)
throw std::runtime_error("GlWindow error : cannot create component while not initialized"); throw std::runtime_error("GlWindow error : cannot create component while not initialized");
@ -49,7 +52,8 @@ std::shared_ptr<uui::GlLabel> uui::GlStack::create_label(
std::tie(label->position_x, label->position_y) = get_child_position(components.size() - 1); std::tie(label->position_x, label->position_y) = get_child_position(components.size() - 1);
window->components.push_back(label); window->components.push_back(label);
return label; if(label != nullptr && init != nullptr)
init(*label);
} }
std::tuple<int, int> uui::GlStack::get_child_position(const std::size_t child_index) const std::tuple<int, int> uui::GlStack::get_child_position(const std::size_t child_index) const

View file

@ -253,8 +253,9 @@ void uui::GlWindow::render()
render_needed = false; render_needed = false;
} }
std::shared_ptr<uui::GlComponent> uui::GlWindow::create_component( void uui::GlWindow::create_component(
const position_t x, const position_t y, const position_t width, const position_t height) const uui::position_t x, const uui::position_t y, const uui::position_t width, const uui::position_t height,
uui::InitFunction<GlComponent> init)
{ {
if(!initialized) if(!initialized)
throw std::runtime_error("GlWindow error : cannot create component while not initialized"); throw std::runtime_error("GlWindow error : cannot create component while not initialized");
@ -264,12 +265,14 @@ std::shared_ptr<uui::GlComponent> uui::GlWindow::create_component(
new uui::GlComponent(shared_from_this(), components.size(), x, y, width, height)); new uui::GlComponent(shared_from_this(), components.size(), x, y, width, height));
push_child(component); push_child(component);
component->init(); component->init();
return component;
if(component != nullptr && init != nullptr)
init(*component);
} }
std::shared_ptr<uui::GlLabel> uui::GlWindow::create_label( void uui::GlWindow::create_label(
const position_t x, const position_t y, const std::string& text, const uui::position_t x, const uui::position_t y, const std::string& text,
const std::tuple<float, float, float, float>& text_color) const std::tuple<float, float, float, float>& text_color, uui::InitFunction<GlLabel> init)
{ {
if(!initialized) if(!initialized)
throw std::runtime_error("GlWindow error : cannot create label while not initialized"); throw std::runtime_error("GlWindow error : cannot create label while not initialized");
@ -279,11 +282,13 @@ std::shared_ptr<uui::GlLabel> uui::GlWindow::create_label(
new uui::GlLabel(shared_from_this(), components.size(), x, y, text, text_color)); new uui::GlLabel(shared_from_this(), components.size(), x, y, text, text_color));
push_child(label); push_child(label);
label->init(); label->init();
return label;
if(label != nullptr && init != nullptr)
init(*label);
} }
std::shared_ptr<uui::GlFlex> uui::GlWindow::create_flex( void uui::GlWindow::create_flex(
const position_t x, const position_t y, const Direction direction) const uui::position_t x, const uui::position_t y, const uui::Direction direction, uui::InitFunction<GlFlex> init)
{ {
if(!initialized) if(!initialized)
throw std::runtime_error("GlWindow error : cannot create flex while not initialized"); throw std::runtime_error("GlWindow error : cannot create flex while not initialized");
@ -292,11 +297,13 @@ std::shared_ptr<uui::GlFlex> uui::GlWindow::create_flex(
std::shared_ptr<uui::GlFlex> flex(new uui::GlFlex(shared_from_this(), components.size(), x, y, direction)); std::shared_ptr<uui::GlFlex> flex(new uui::GlFlex(shared_from_this(), components.size(), x, y, direction));
push_child(flex); push_child(flex);
flex->init(); flex->init();
return flex;
if(flex != nullptr && init != nullptr)
init(*flex);
} }
std::shared_ptr<uui::GlStack> uui::GlWindow::create_stack( void uui::GlWindow::create_stack(
const position_t x, const position_t y, const Direction direction) const uui::position_t x, const uui::position_t y, const uui::Direction direction, uui::InitFunction<GlStack> init)
{ {
if(!initialized) if(!initialized)
throw std::runtime_error("GlWindow error : cannot create stack while not initialized"); throw std::runtime_error("GlWindow error : cannot create stack while not initialized");
@ -305,5 +312,7 @@ std::shared_ptr<uui::GlStack> uui::GlWindow::create_stack(
std::shared_ptr<uui::GlStack> stack(new uui::GlStack(shared_from_this(), components.size(), x, y, direction)); std::shared_ptr<uui::GlStack> stack(new uui::GlStack(shared_from_this(), components.size(), x, y, direction));
push_child(stack); push_child(stack);
stack->init(); stack->init();
return stack;
if(stack != nullptr && init != nullptr)
init(*stack);
} }