Compare commits
10 commits
b530f65f38
...
2a2044c632
| Author | SHA1 | Date | |
|---|---|---|---|
|
2a2044c632 |
|||
|
|
3ad40381e5 | ||
|
|
6427c7aeb7 | ||
|
|
73934d0e34 | ||
|
|
9ec93964ba | ||
|
|
af734cda73 | ||
|
|
d15b25dba6 | ||
|
|
896f98476e | ||
|
|
e7753f244c | ||
|
|
2ba59d8e37 |
46 changed files with 1344 additions and 408 deletions
4
.ccls
4
.ccls
|
|
@ -1,6 +1,8 @@
|
|||
clang++
|
||||
clangd
|
||||
-std=c++17
|
||||
-DDEBUG
|
||||
-Wall
|
||||
-Wconversion
|
||||
-Iinclude
|
||||
-I/usr/include/freetype2
|
||||
-I/usr/include/libpng16
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
BasedOnStyle: Microsoft
|
||||
AccessModifierOffset: -3
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveAssignments: None
|
||||
AlignConsecutiveBitFields: None
|
||||
|
|
@ -21,7 +21,7 @@ AllowShortLoopsOnASingleLine: true
|
|||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: No
|
||||
AttributeMacros: ['__ununsed']
|
||||
AttributeMacros: ['__unused']
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BitFieldColonSpacing: Both
|
||||
|
|
@ -50,12 +50,13 @@ BreakBeforeTernaryOperators: true
|
|||
BreakConstructorInitializers: AfterColon
|
||||
BreakInheritanceList: AfterColon
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 140
|
||||
ColumnLimit: 120
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
Cpp11BracedListStyle: true
|
||||
DeriveLineEnding: true
|
||||
DerivePointerAlignment: false
|
||||
EmptyLineAfterAccessModifier: Never
|
||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||
FixNamespaceComments: true
|
||||
IncludeBlocks: Regroup
|
||||
|
|
@ -78,13 +79,14 @@ IncludeCategories:
|
|||
- Regex: '^"'
|
||||
Priority: 4
|
||||
SortPriority: 4
|
||||
IndentAccessModifiers: false
|
||||
IndentCaseBlocks: true
|
||||
IndentCaseLabels: true
|
||||
IndentExternBlock: NoIndent
|
||||
IndentGotoLabels: false
|
||||
IndentPPDirectives: BeforeHash
|
||||
IndentRequires: true
|
||||
IndentWidth: 3
|
||||
IndentWidth: 4
|
||||
IndentWrappedFunctionNames: false
|
||||
InsertTrailingCommas: None
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
|
|
@ -116,6 +118,6 @@ SpacesInContainerLiterals: false
|
|||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: c++17
|
||||
TabWidth: 3
|
||||
TabWidth: 4
|
||||
UseCRLF: false
|
||||
UseTab: Always
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,5 +1,6 @@
|
|||
.#.*
|
||||
*.kdev4
|
||||
*.ttf
|
||||
|
||||
.ccls-cache
|
||||
.kdev4
|
||||
|
|
|
|||
3
README.md
Normal file
3
README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
# UUI
|
||||
|
||||
Simple and efficient C++ GUI toolkit
|
||||
21
ROADMAP.md
Normal file
21
ROADMAP.md
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
* button
|
||||
|
||||
* scroll
|
||||
|
||||
* Text wrap
|
||||
|
||||
* Style
|
||||
|
||||
* Text Edition
|
||||
|
||||
* projected vertex/raw vertex mode (projection on GPU)
|
||||
|
||||
* negative absolute position (from right/bottom)
|
||||
|
||||
* 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)
|
||||
|
|
@ -3,17 +3,39 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "window.hpp"
|
||||
#include "uui/types.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class Window;
|
||||
class Application
|
||||
{
|
||||
public:
|
||||
#ifdef DEBUG
|
||||
constexpr static bool debug_mode = true;
|
||||
#else
|
||||
constexpr static bool debug_mode = false;
|
||||
#endif
|
||||
enum Implementaion
|
||||
{
|
||||
OPENGL
|
||||
};
|
||||
|
||||
virtual void run() = 0;
|
||||
// virtual std::weak_ptr<Window> add_window(int width, int height, const std::string& title) = 0;
|
||||
virtual void create_window(int width, int height, const std::string& title, InitFunction<Window> init) = 0;
|
||||
virtual std::shared_ptr<Window> get_window(std::size_t index [[maybe_unused]]) const = 0;
|
||||
virtual ~Application() {};
|
||||
|
||||
protected:
|
||||
static bool application_created;
|
||||
static std::shared_ptr<Application> current_application;
|
||||
|
||||
bool initialized;
|
||||
|
||||
virtual void init() = 0;
|
||||
virtual void deinit() = 0;
|
||||
|
||||
friend std::shared_ptr<Application> create_application(Application::Implementaion implementation);
|
||||
};
|
||||
|
||||
std::shared_ptr<Application> create_application(Application::Implementaion implementation);
|
||||
} // namespace uui
|
||||
|
|
|
|||
|
|
@ -1,31 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <variant>
|
||||
#include <memory>
|
||||
|
||||
#include "uui/types.hpp"
|
||||
#include "uui/window.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class Container;
|
||||
class Component
|
||||
{
|
||||
public:
|
||||
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):
|
||||
position_x(x),
|
||||
position_y(y), size_width(width), size_height(height)
|
||||
{
|
||||
background_color = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
}
|
||||
virtual void set_background_color(float r, float g, float b, float a = 1.0f) = 0;
|
||||
|
||||
virtual void render() = 0;
|
||||
ComponentType type() { return _type; }
|
||||
uui::position_t x() { return _position_x; }
|
||||
uui::position_t y() { return _position_y; }
|
||||
uui::size_t width() { return _width; }
|
||||
uui::size_t height() { return _height; }
|
||||
|
||||
protected:
|
||||
std::variant<int, float> position_x;
|
||||
std::variant<int, float> position_y;
|
||||
std::variant<int, float> size_width;
|
||||
std::variant<int, float> size_height;
|
||||
ComponentType _type = ComponentType::UNASSIGNED;
|
||||
|
||||
std::array<float, 4> background_color;
|
||||
std::shared_ptr<Window> _window;
|
||||
std::size_t _window_index;
|
||||
std::shared_ptr<Container> _parent;
|
||||
std::size_t _parent_index;
|
||||
|
||||
uui::position_t _position_x;
|
||||
uui::position_t _position_y;
|
||||
uui::size_t _width;
|
||||
uui::size_t _height;
|
||||
|
||||
bool _coord_all_relative;
|
||||
|
||||
std::array<float, 4> _background_color;
|
||||
|
||||
bool _initialized = false;
|
||||
|
||||
virtual void render() = 0;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "graphic_context.hpp"
|
||||
|
||||
namespace Config
|
||||
{
|
||||
constexpr unsigned int FONT_TEXTURE_UNIT = GL_TEXTURE0;
|
||||
}
|
||||
12
include/uui/container.hpp
Normal file
12
include/uui/container.hpp
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "uui/component.hpp"
|
||||
#include "uui/container_interface.hpp"
|
||||
#include "uui/types.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class Container: virtual public Component, virtual public ContainerInterface
|
||||
{};
|
||||
|
||||
} // namespace uui
|
||||
22
include/uui/container_interface.hpp
Normal file
22
include/uui/container_interface.hpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
#include "uui/types.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class Component;
|
||||
class ContainerInterface
|
||||
{
|
||||
public:
|
||||
virtual std::tuple<int, int> get_child_position(const std::size_t child_index [[maybe_unused]]) const = 0;
|
||||
|
||||
protected:
|
||||
virtual std::size_t push_child(std::shared_ptr<Component> child) = 0;
|
||||
virtual std::shared_ptr<Component> get_child(std::size_t index) const = 0;
|
||||
virtual void remove_child(std::size_t index) = 0;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
16
include/uui/flex.hpp
Normal file
16
include/uui/flex.hpp
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "uui/stack.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class Flex: virtual public Stack
|
||||
{
|
||||
protected:
|
||||
virtual std::tuple<int, int> get_child_position(const std::size_t child_index) const = 0;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
56
include/uui/font_manager.hpp
Normal file
56
include/uui/font_manager.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class Window;
|
||||
class FontManager
|
||||
{
|
||||
friend class Window;
|
||||
|
||||
public:
|
||||
struct character_info
|
||||
{
|
||||
float advance_x; // advance.x
|
||||
float advance_y; // advance.y
|
||||
|
||||
float bitmap_width; // bitmap.width;
|
||||
float bitmap_height; // bitmap.rows;
|
||||
|
||||
float bitmap_left; // bitmap_left;
|
||||
float bitmap_top; // bitmap_top;
|
||||
|
||||
float texture_x; // x offset of glyph in texture coordinates
|
||||
float texture_y; // y offset of glyph in texture coordinates
|
||||
};
|
||||
|
||||
struct Font
|
||||
{
|
||||
character_info char_infos[256];
|
||||
unsigned int atlas_texture;
|
||||
unsigned int atlas_width;
|
||||
unsigned int atlas_height;
|
||||
};
|
||||
|
||||
std::vector<Font> fonts;
|
||||
|
||||
virtual void render_text(
|
||||
const std::string& text, Font& font, float x, float y, float scale_x, float scale_y,
|
||||
const std::tuple<float, float, float, float>& text_color) = 0;
|
||||
virtual std::tuple<int, int> get_text_size(const std::string& text, Font& font, float scale_x, float scale_y) = 0;
|
||||
|
||||
protected:
|
||||
static constexpr int ATLAS_MAX_WIDTH = 1024;
|
||||
|
||||
bool initialized;
|
||||
|
||||
FT_Library ft;
|
||||
virtual const Font& init_font(const std::string& font_path, unsigned int font_size) = 0;
|
||||
};
|
||||
} // namespace uui
|
||||
22
include/uui/label.hpp
Normal file
22
include/uui/label.hpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "uui/component.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class Label: virtual public Component
|
||||
{
|
||||
protected:
|
||||
std::size_t font_index;
|
||||
|
||||
std::string text;
|
||||
std::tuple<float, float, float, float> text_color;
|
||||
|
||||
int text_width;
|
||||
int text_height;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
|
|
@ -2,89 +2,32 @@
|
|||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "graphic_context.hpp"
|
||||
#include "uui/opengl/font_manager.hpp"
|
||||
#include "uui/application.hpp"
|
||||
#include "uui/types.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class GlWindow;
|
||||
class GlApplication
|
||||
class GlApplication final: virtual public Application
|
||||
{
|
||||
friend class GlWindow;
|
||||
|
||||
public:
|
||||
#ifdef DEBUG
|
||||
constexpr static bool debug_mode = true;
|
||||
#else
|
||||
constexpr static bool debug_mode = false;
|
||||
#endif
|
||||
std::vector<std::shared_ptr<GlWindow>> windows;
|
||||
|
||||
GlApplication();
|
||||
~GlApplication();
|
||||
virtual ~GlApplication() final;
|
||||
|
||||
void run();
|
||||
std::shared_ptr<GlWindow> create_window(int width, int height, const std::string& title);
|
||||
std::shared_ptr<GlWindow> get_window(size_t index) const;
|
||||
|
||||
private:
|
||||
static GlApplication* application_pointer;
|
||||
};
|
||||
|
||||
class GlLabel;
|
||||
class GlComponent;
|
||||
class GlWindow
|
||||
{
|
||||
friend class GlApplication;
|
||||
friend class GlComponent;
|
||||
friend class GlLabel;
|
||||
|
||||
public:
|
||||
std::string title;
|
||||
std::vector<std::shared_ptr<GlComponent>> components;
|
||||
|
||||
GlWindow(const GlWindow&) = delete;
|
||||
GlWindow(GlWindow&&) = delete;
|
||||
~GlWindow();
|
||||
|
||||
std::shared_ptr<GlComponent> 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);
|
||||
std::shared_ptr<GlLabel> 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);
|
||||
void run() final;
|
||||
void create_window(int width, int height, const std::string& title, InitFunction<Window> init) final;
|
||||
std::shared_ptr<Window> get_window(std::size_t index) const final;
|
||||
|
||||
protected:
|
||||
GlApplication* app;
|
||||
|
||||
GlFontManager font_manager;
|
||||
|
||||
int width;
|
||||
int height;
|
||||
bool render_needed;
|
||||
bool resize_needed;
|
||||
|
||||
bool iconified;
|
||||
|
||||
size_t index;
|
||||
bool initialized;
|
||||
|
||||
GLFWwindow* glfw_window;
|
||||
|
||||
GLuint gl_program;
|
||||
|
||||
GlWindow(GlApplication* app, size_t index, int width, int height, const std::string& title);
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
void render();
|
||||
|
||||
static void glfw_resize_callback(GLFWwindow* window, int width, int height);
|
||||
static void glfw_iconify_callback(GLFWwindow* window, int iconified);
|
||||
static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
void init() final;
|
||||
void deinit() final;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
|
|
|
|||
27
include/uui/opengl/button.hpp
Normal file
27
include/uui/opengl/button.hpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "uui/opengl/component.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class GlButton: public GlComponent
|
||||
{
|
||||
friend class GlWindow;
|
||||
|
||||
protected:
|
||||
GlButton(
|
||||
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 Direction direction);
|
||||
GlButton(
|
||||
std::shared_ptr<GlWindow> window, std::size_t window_index, const position_t x, const position_t y,
|
||||
const Direction direction): GlButton(window, window_index, window, window_index, x, y, direction)
|
||||
{}
|
||||
|
||||
virtual std::tuple<int, int> get_child_position(const std::size_t child_index) const;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
|
|
@ -2,49 +2,50 @@
|
|||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
|
||||
#include "graphic_context.hpp"
|
||||
#include "window.hpp"
|
||||
#include "uui/component.hpp"
|
||||
#include "uui/opengl/graphic_context.hpp"
|
||||
#include "uui/opengl/window.hpp"
|
||||
#include "uui/types.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class GlComponent
|
||||
class GlContainer;
|
||||
class GlFlex;
|
||||
class GlStack;
|
||||
class GlComponent: public std::enable_shared_from_this<GlComponent>, virtual public Component
|
||||
{
|
||||
friend class GlContainer;
|
||||
friend class GlWindow;
|
||||
friend class GlFlex;
|
||||
friend class GlStack;
|
||||
|
||||
public:
|
||||
GlComponent(const GlComponent&) = delete;
|
||||
GlComponent(GlComponent&&) = delete;
|
||||
~GlComponent();
|
||||
virtual ~GlComponent();
|
||||
|
||||
void set_background_color(float r, float g, float b, float a = 1.0f);
|
||||
void set_background_color(float r, float g, float b, float a = 1.0f) final;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<GlWindow> window;
|
||||
|
||||
std::variant<int, float> position_x;
|
||||
std::variant<int, float> position_y;
|
||||
std::variant<int, float> size_width;
|
||||
std::variant<int, float> size_height;
|
||||
bool coord_all_relative;
|
||||
|
||||
std::array<float, 4> background_color;
|
||||
|
||||
bool initialized;
|
||||
|
||||
std::shared_ptr<GlWindow> gl_window;
|
||||
GLuint gl_vbo;
|
||||
GLuint gl_vao;
|
||||
GLuint gl_ebo;
|
||||
|
||||
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 ComponentParams& params);
|
||||
GlComponent(std::shared_ptr<GlWindow> window, std::size_t window_index, const ComponentParams& params):
|
||||
GlComponent(window, window_index, nullptr, 0, params)
|
||||
{}
|
||||
GlComponent(const GlComponent&) = delete;
|
||||
GlComponent(GlComponent&&) = default;
|
||||
std::shared_ptr<GlComponent> getptr() { return shared_from_this(); }
|
||||
|
||||
virtual void render();
|
||||
|
||||
virtual void init();
|
||||
virtual void set_vbo_data();
|
||||
virtual void deinit();
|
||||
virtual void render();
|
||||
virtual void on_resize();
|
||||
};
|
||||
|
||||
|
|
|
|||
18
include/uui/opengl/container.hpp
Normal file
18
include/uui/opengl/container.hpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "uui/container.hpp"
|
||||
#include "uui/opengl/component.hpp"
|
||||
#include "uui/opengl/container_interface.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class GlContainer: virtual public Container, virtual public GlContainerInterface
|
||||
{};
|
||||
|
||||
} // namespace uui
|
||||
28
include/uui/opengl/container_interface.hpp
Normal file
28
include/uui/opengl/container_interface.hpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
|
||||
#include "uui/component.hpp"
|
||||
#include "uui/container_interface.hpp"
|
||||
#include "uui/types.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class GlComponent;
|
||||
class GlContainerInterface: virtual public ContainerInterface
|
||||
{
|
||||
public:
|
||||
virtual std::tuple<int, int> get_child_position(const std::size_t child_index [[maybe_unused]]) const override;
|
||||
|
||||
protected:
|
||||
virtual std::size_t push_child(std::shared_ptr<Component> child) final;
|
||||
std::size_t push_child(std::shared_ptr<GlComponent> child);
|
||||
virtual std::shared_ptr<Component> get_child(std::size_t index) const final;
|
||||
virtual void remove_child(std::size_t index) final;
|
||||
|
||||
virtual ~GlContainerInterface();
|
||||
|
||||
std::vector<std::shared_ptr<GlComponent>> components;
|
||||
};
|
||||
} // namespace uui
|
||||
29
include/uui/opengl/flex.hpp
Normal file
29
include/uui/opengl/flex.hpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "uui/flex.hpp"
|
||||
#include "uui/opengl/container.hpp"
|
||||
#include "uui/opengl/stack.hpp"
|
||||
#include "uui/opengl/window.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class GlFlex: virtual public GlStack, virtual public Flex
|
||||
{
|
||||
friend class GlWindow;
|
||||
|
||||
protected:
|
||||
GlFlex(
|
||||
std::shared_ptr<GlWindow> window, std::size_t window_index, std::shared_ptr<GlContainer> parent,
|
||||
std::size_t parent_index, const StackParams& params);
|
||||
GlFlex(std::shared_ptr<GlWindow> window, std::size_t window_index, const StackParams& params):
|
||||
GlFlex(window, window_index, nullptr, 0, params)
|
||||
{}
|
||||
|
||||
std::tuple<int, int> get_child_position(const std::size_t child_index) const override;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
|
|
@ -5,64 +5,32 @@
|
|||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "graphic_context.hpp"
|
||||
#include "uui/font_manager.hpp"
|
||||
#include "uui/opengl/graphic_context.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class GlWindow;
|
||||
class GlFontManager
|
||||
class GlFontManager final: public FontManager
|
||||
{
|
||||
friend class GlWindow;
|
||||
|
||||
public:
|
||||
struct character_info
|
||||
{
|
||||
float advance_x; // advance.x
|
||||
float advance_y; // advance.y
|
||||
|
||||
float bitmap_width; // bitmap.width;
|
||||
float bitmap_height; // bitmap.rows;
|
||||
|
||||
float bitmap_left; // bitmap_left;
|
||||
float bitmap_top; // bitmap_top;
|
||||
|
||||
float texture_x; // x offset of glyph in texture coordinates
|
||||
float texture_y; // y offset of glyph in texture coordinates
|
||||
};
|
||||
|
||||
struct Font
|
||||
{
|
||||
character_info char_infos[256];
|
||||
GLuint atlas_texture;
|
||||
unsigned int atlas_width;
|
||||
unsigned int atlas_height;
|
||||
};
|
||||
|
||||
std::vector<Font> fonts;
|
||||
|
||||
GlFontManager();
|
||||
~GlFontManager();
|
||||
|
||||
void render_text(
|
||||
const std::string& text, Font& font, float x, float y, float scale_x, float scale_y,
|
||||
const std::tuple<float, float, float, float>& text_color);
|
||||
std::tuple<int, int> get_text_size(const std::string& text, Font& font, float scale_x, float scale_y);
|
||||
const std::tuple<float, float, float, float>& text_color) final;
|
||||
std::tuple<int, int> get_text_size(const std::string& text, Font& font, float scale_x, float scale_y) final;
|
||||
|
||||
private:
|
||||
static constexpr int ATLAS_MAX_WIDTH = 1024;
|
||||
|
||||
bool initialized;
|
||||
|
||||
FT_Library ft;
|
||||
|
||||
GLuint gl_program;
|
||||
GLuint gl_vao;
|
||||
GLuint gl_vbo;
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
const Font& init_font(const std::string& font_path, size_t font_size);
|
||||
const Font& init_font(const std::string& font_path, unsigned int font_size);
|
||||
};
|
||||
} // namespace uui
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
// clang-format off
|
||||
#define GLAD_GL_IMPLEMENTATION
|
||||
#include "glad/glad.h"
|
||||
#define GLFW_INCLUDE_VULKAN
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#define GLM_FORCE_RADIANS
|
||||
|
|
@ -11,3 +12,8 @@
|
|||
#include <glm/gtc/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
// clang-format off
|
||||
|
||||
namespace GlConfig
|
||||
{
|
||||
constexpr unsigned int FONT_TEXTURE_UNIT = GL_TEXTURE0;
|
||||
}
|
||||
|
|
@ -3,18 +3,20 @@
|
|||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "uui/label.hpp"
|
||||
#include "uui/opengl/component.hpp"
|
||||
#include "uui/opengl/container.hpp"
|
||||
#include "uui/opengl/window.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class GlLabel: public GlComponent
|
||||
class GlFlex;
|
||||
class GlStack;
|
||||
class GlLabel final: virtual public GlComponent, virtual public Label
|
||||
{
|
||||
friend class GlWindow;
|
||||
|
||||
size_t font_index;
|
||||
|
||||
float get_width() const;
|
||||
float get_height() const;
|
||||
friend class GlFlex;
|
||||
friend class GlStack;
|
||||
|
||||
protected:
|
||||
std::string text;
|
||||
|
|
@ -24,10 +26,13 @@ protected:
|
|||
int text_height;
|
||||
|
||||
GlLabel(
|
||||
std::shared_ptr<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);
|
||||
std::shared_ptr<GlWindow> window, std::size_t window_index, std::shared_ptr<GlContainer> parent,
|
||||
std::size_t parent_index, const LabelParams& params);
|
||||
GlLabel(std::shared_ptr<GlWindow> window, std::size_t window_index, const LabelParams& params):
|
||||
GlLabel(window, window_index, nullptr, 0, params)
|
||||
{}
|
||||
|
||||
void render();
|
||||
void render() final;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
|
|
|
|||
32
include/uui/opengl/stack.hpp
Normal file
32
include/uui/opengl/stack.hpp
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "uui/opengl/component.hpp"
|
||||
#include "uui/opengl/container.hpp"
|
||||
#include "uui/stack.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class GlStack: virtual public GlComponent, virtual public GlContainer, virtual public Stack
|
||||
{
|
||||
friend class GlWindow;
|
||||
|
||||
public:
|
||||
void create_component(const StackComponentParams& params, InitFunction<Component> init) override;
|
||||
void create_label(const StackLabelParams& params, InitFunction<Label> init) override;
|
||||
|
||||
protected:
|
||||
GlStack(
|
||||
std::shared_ptr<GlWindow> window, std::size_t window_index, std::shared_ptr<GlContainer> parent,
|
||||
std::size_t parent_index, const StackParams& params);
|
||||
GlStack(std::shared_ptr<GlWindow> window, std::size_t window_index, const StackParams& params):
|
||||
GlStack(window, window_index, nullptr, 0, params)
|
||||
{}
|
||||
|
||||
std::tuple<int, int> get_child_position(const std::size_t child_index) const override;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
|
|
@ -1,3 +1,56 @@
|
|||
#pragma once
|
||||
|
||||
#include "uui/opengl/application.hpp"
|
||||
#include "uui/opengl/container_interface.hpp"
|
||||
#include "uui/opengl/font_manager.hpp"
|
||||
#include "uui/types.hpp"
|
||||
#include "uui/window.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class GlComponent;
|
||||
class GlContainer;
|
||||
class GlFlex;
|
||||
class GlLabel;
|
||||
class GlStack;
|
||||
class GlWindow:
|
||||
public std::enable_shared_from_this<GlWindow>,
|
||||
virtual public Window,
|
||||
virtual public GlContainerInterface
|
||||
{
|
||||
friend class GlApplication;
|
||||
friend class GlComponent;
|
||||
friend class GlFlex;
|
||||
friend class GlLabel;
|
||||
friend class GlStack;
|
||||
|
||||
public:
|
||||
GlWindow(const GlWindow&) = delete;
|
||||
GlWindow(GlWindow&&) = delete;
|
||||
~GlWindow();
|
||||
|
||||
void create_component(const ComponentParams& params, InitFunction<Component> init) final;
|
||||
void create_label(const LabelParams& params, InitFunction<Label> init) final;
|
||||
void create_flex(const StackParams& params, InitFunction<Flex> init) final;
|
||||
void create_stack(const StackParams& params, InitFunction<Stack> init) final;
|
||||
|
||||
protected:
|
||||
void render() final;
|
||||
|
||||
std::shared_ptr<GlFontManager> gl_font_manager;
|
||||
|
||||
GLFWwindow* glfw_window;
|
||||
GLuint gl_program;
|
||||
|
||||
GlWindow(std::shared_ptr<Application> app, int width, int height, const std::string& title);
|
||||
std::shared_ptr<GlWindow> getptr() { return shared_from_this(); }
|
||||
|
||||
void init();
|
||||
void deinit();
|
||||
|
||||
static void glfw_resize_callback(GLFWwindow* window, int width, int height);
|
||||
static void glfw_iconify_callback(GLFWwindow* window, int iconified);
|
||||
static void glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods);
|
||||
// static void glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int mods);
|
||||
};
|
||||
} // namespace uui
|
||||
|
|
|
|||
25
include/uui/stack.hpp
Normal file
25
include/uui/stack.hpp
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "uui/component.hpp"
|
||||
#include "uui/label.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class Stack: virtual public Component
|
||||
{
|
||||
public:
|
||||
virtual void create_component(const StackComponentParams& params, InitFunction<Component> init) = 0;
|
||||
virtual void create_label(const StackLabelParams& params, InitFunction<Label> init) = 0;
|
||||
|
||||
protected:
|
||||
Direction direction;
|
||||
int content_width;
|
||||
int content_height;
|
||||
|
||||
virtual std::tuple<int, int> get_child_position(const std::size_t child_index) const = 0;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
46
include/uui/style.hpp
Normal file
46
include/uui/style.hpp
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
struct Style
|
||||
{
|
||||
enum Position
|
||||
{
|
||||
RELATIVE,
|
||||
ABSOLUTE
|
||||
};
|
||||
enum Alignment
|
||||
{
|
||||
START,
|
||||
CENTER,
|
||||
END
|
||||
};
|
||||
struct AbsolutePostion
|
||||
{
|
||||
std::optional<position_t> left;
|
||||
std::optional<position_t> right;
|
||||
std::optional<position_t> top;
|
||||
std::optional<position_t> bottom;
|
||||
};
|
||||
|
||||
// Layout
|
||||
Position position;
|
||||
Alignment horizontal_alignment;
|
||||
Alignment vertical_alignment;
|
||||
std::optional<uui::size_t> width;
|
||||
std::optional<uui::size_t> height;
|
||||
std::optional<uui::size_t> margin;
|
||||
std::optional<uui::size_t> padding;
|
||||
// For absolute positioning
|
||||
std::unique_ptr<AbsolutePostion> absolute_position;
|
||||
|
||||
// Color
|
||||
std::optional<std::tuple<float, float, float, float>> background_color;
|
||||
};
|
||||
} // namespace uui
|
||||
67
include/uui/types.hpp
Normal file
67
include/uui/types.hpp
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <tuple>
|
||||
#include <variant>
|
||||
|
||||
namespace uui
|
||||
{
|
||||
namespace Config
|
||||
{
|
||||
constexpr int MOUSE_GRID_WIDTH = 20;
|
||||
constexpr int MOUSE_GRID_HEIGHT = 20;
|
||||
}; // namespace Config
|
||||
|
||||
template<typename T> using InitFunction = const std::function<void(T&)>&;
|
||||
typedef std::variant<int, float> position_t;
|
||||
typedef std::variant<int, float> size_t;
|
||||
typedef std::tuple<float, float, float, float> color_t;
|
||||
|
||||
enum class ComponentType
|
||||
{
|
||||
UNASSIGNED,
|
||||
COMPONENT,
|
||||
LABEL,
|
||||
FLEX,
|
||||
STACK,
|
||||
WINDOW
|
||||
};
|
||||
|
||||
enum class Direction
|
||||
{
|
||||
HORIZONTAL,
|
||||
VERTICAL
|
||||
};
|
||||
|
||||
struct ComponentParams
|
||||
{
|
||||
uui::position_t x;
|
||||
uui::position_t y;
|
||||
uui::size_t width;
|
||||
uui::size_t height;
|
||||
};
|
||||
struct LabelParams
|
||||
{
|
||||
uui::position_t x;
|
||||
uui::position_t y;
|
||||
const std::string& text;
|
||||
const uui::color_t& text_color;
|
||||
};
|
||||
struct StackParams
|
||||
{
|
||||
const uui::position_t x;
|
||||
const uui::position_t y;
|
||||
const uui::Direction direction;
|
||||
};
|
||||
struct StackComponentParams
|
||||
{
|
||||
uui::size_t width;
|
||||
uui::size_t height;
|
||||
};
|
||||
struct StackLabelParams
|
||||
{
|
||||
const std::string& text;
|
||||
const uui::color_t& text_color;
|
||||
};
|
||||
|
||||
} // namespace uui
|
||||
9
include/uui/uui.hpp
Normal file
9
include/uui/uui.hpp
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "uui/application.hpp"
|
||||
#include "uui/component.hpp"
|
||||
#include "uui/flex.hpp"
|
||||
#include "uui/label.hpp"
|
||||
#include "uui/stack.hpp"
|
||||
#include "uui/types.hpp"
|
||||
#include "uui/window.hpp"
|
||||
|
|
@ -1,24 +1,52 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "graphic_context.hpp"
|
||||
#include "uui/component.hpp"
|
||||
#include "uui/application.hpp"
|
||||
#include "uui/container_interface.hpp"
|
||||
#include "uui/font_manager.hpp"
|
||||
#include "uui/types.hpp"
|
||||
|
||||
namespace uui
|
||||
{
|
||||
class Window
|
||||
class Component;
|
||||
class Label;
|
||||
class Flex;
|
||||
class Stack;
|
||||
class Window: virtual public ContainerInterface
|
||||
{
|
||||
public:
|
||||
std::string title;
|
||||
friend class Component;
|
||||
|
||||
virtual void add_component(const Component& box) = 0;
|
||||
public:
|
||||
std::shared_ptr<FontManager> font_manager;
|
||||
|
||||
virtual void create_component(const ComponentParams& params, InitFunction<Component> init) = 0;
|
||||
virtual void create_label(const LabelParams& params, InitFunction<Label> init) = 0;
|
||||
virtual void create_flex(const StackParams& params, InitFunction<Flex> init) = 0;
|
||||
virtual void create_stack(const StackParams& params, InitFunction<Stack> init) = 0;
|
||||
|
||||
const std::string& title() { return _title; }
|
||||
int width() { return _width; };
|
||||
int height() { return _height; };
|
||||
|
||||
protected:
|
||||
GLFWwindow* glfw_window;
|
||||
ComponentType _type = ComponentType::UNASSIGNED;
|
||||
|
||||
virtual void draw() = 0;
|
||||
std::shared_ptr<Application> _app;
|
||||
bool _initialized;
|
||||
|
||||
std::string _title;
|
||||
int _width;
|
||||
int _height;
|
||||
bool _render_needed;
|
||||
bool _resize_needed;
|
||||
bool _iconified;
|
||||
|
||||
std::array<std::array<std::vector<std::shared_ptr<Component>>, Config::MOUSE_GRID_HEIGHT>, Config::MOUSE_GRID_WIDTH>
|
||||
_grid_click;
|
||||
|
||||
virtual void render() = 0;
|
||||
};
|
||||
} // namespace uui
|
||||
|
|
|
|||
44
make.py
44
make.py
|
|
@ -1,50 +1,38 @@
|
|||
#! python3
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
|
||||
from umake import get_hash, make
|
||||
|
||||
|
||||
class Config:
|
||||
CC = 'g++'
|
||||
APPS = ['test/example_gl', 'test/benchmark_text']
|
||||
IGNORE_APPS = []
|
||||
JOB_COUNT = int(os.cpu_count() * 0.8)
|
||||
|
||||
BIN_DIR = Path('bin')
|
||||
INCLUDE_DIR = Path('include')
|
||||
OBJECT_DIR = Path('obj')
|
||||
SOURCE_DIR = Path('src')
|
||||
|
||||
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`'
|
||||
LINK_FLAGS = '-lpthread -ldl `pkg-config --libs glfw3 vulkan gl x11 freetype2`'
|
||||
|
||||
PRE_COMPILE_FUNCTION = None
|
||||
|
||||
CPP_SOURCES = [filepath for filepath in SOURCE_DIR.rglob('*.cpp') if not filepath.name.startswith('.')]
|
||||
from umake.umake import get_hash, make, Config
|
||||
|
||||
|
||||
def main():
|
||||
config = Config()
|
||||
|
||||
def pre_compile():
|
||||
# Copying OpenGL shaders
|
||||
src_opengl_shader_path = Config.SOURCE_DIR / 'uui' / 'opengl' / 'shaders'
|
||||
src_opengl_shader_path = config.source_dir / 'uui' / 'opengl' / 'shaders'
|
||||
for shader_path in (
|
||||
list(src_opengl_shader_path.rglob('*.vert'))
|
||||
+ list(src_opengl_shader_path.rglob('*.frag'))):
|
||||
out_path = Config.BIN_DIR / shader_path.relative_to(Config.SOURCE_DIR)
|
||||
out_path = config.bin_dir / shader_path.relative_to(config.source_dir)
|
||||
if out_path.exists() and get_hash(shader_path) == get_hash(out_path):
|
||||
continue
|
||||
if not out_path.parent.exists():
|
||||
out_path.parent.mkdir(parents=True)
|
||||
shutil.copy(shader_path, out_path)
|
||||
|
||||
Config.PRE_COMPILE_FUNCTION = pre_compile
|
||||
make(Config)
|
||||
|
||||
config.apps = [str(p.relative_to(Path('src')))[:-4] for p in (config.source_dir / 'test').rglob('*.cpp')]
|
||||
config.watch = True
|
||||
|
||||
config.common_flags = '-std=c++20 -fno-semantic-interposition'
|
||||
config.common_debug_flags = '-g -Og -DDEBUG'
|
||||
config.common_release_flags = '-O2 -flto=auto'
|
||||
config.compile_flags = f'-Wall -Wextra -Wpedantic -Wconversion -I{config.include_dir} `pkg-config --cflags glfw3 gl x11 freetype2`'
|
||||
config.link_flags = '-lpthread -ldl `pkg-config --libs glfw3 gl freetype2`'
|
||||
config.pre_compile_function = pre_compile
|
||||
make(config)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
5
makefile
5
makefile
|
|
@ -1,7 +1,7 @@
|
|||
MAKE_PATH="."
|
||||
UMAKE_PATH="umake"
|
||||
|
||||
.PHONY: all clean
|
||||
.PHONY: all watch debug debug_watch clean lint
|
||||
|
||||
all:
|
||||
@PYTHONPATH=$(UMAKE_PATH) python $(MAKE_PATH)/make.py
|
||||
|
|
@ -11,3 +11,6 @@ debug:
|
|||
|
||||
clean:
|
||||
@PYTHONPATH=$(UMAKE_PATH) python $(MAKE_PATH)/make.py --clean
|
||||
|
||||
lint:
|
||||
@clang-format --dry-run --Werror include/uui/*.hpp include/uui/**/*.hpp src/uui/*.cpp src/uui/**/*.cpp src/test/*.cpp
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
# UUI : micro UI Toolkit
|
||||
|
||||
|
||||
* C++ + Vulkan/OpenGL
|
||||
|
||||
* Python binding
|
||||
|
|
@ -9,6 +8,10 @@
|
|||
|
||||
* Let custom rendering
|
||||
|
||||
* Canvas for easy drawing
|
||||
|
||||
* Style/Config watch option : real-time update on file change
|
||||
|
||||
|
||||
## Technical
|
||||
|
||||
|
|
@ -27,4 +30,4 @@
|
|||
|
||||
## Layout / Style
|
||||
|
||||
* Constraint based? padding/margin?
|
||||
* CSS subset
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "uui/opengl/application.hpp"
|
||||
#include "uui/opengl/component.hpp"
|
||||
#include "uui/opengl/label.hpp"
|
||||
#include "uui/uui.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -10,12 +8,12 @@ int main()
|
|||
{
|
||||
try
|
||||
{
|
||||
uui::GlApplication app;
|
||||
// uui::GlApplication app2; // exception : application already created
|
||||
auto window = app.create_window(800, 600, "OpenGl!");
|
||||
auto app = uui::create_application(uui::Application::OPENGL);
|
||||
app->create_window(800, 600, "OpenGl!", [](uui::Window& 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});
|
||||
app.run();
|
||||
window.create_label({4 * i, 4 * i, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f}}, nullptr);
|
||||
});
|
||||
app->run();
|
||||
}
|
||||
catch(const std::exception& error)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "uui/opengl/application.hpp"
|
||||
#include "uui/opengl/component.hpp"
|
||||
#include "uui/opengl/label.hpp"
|
||||
#include "uui/uui.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
@ -12,36 +10,94 @@ int main()
|
|||
{
|
||||
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);
|
||||
auto app = uui::create_application(uui::Application::OPENGL);
|
||||
// auto app2 = uui::create_application(uui::Application::OPENGL); // exception : application already created
|
||||
app->create_window(800, 600, "OpenGl!", [](uui::Window& window) {
|
||||
window.create_component({.x = 0, .y = 100, .width = 0.5f, .height = 50}, [](uui::Component& component) {
|
||||
component.set_background_color(0.8f, 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();
|
||||
// }
|
||||
window.create_component(
|
||||
{.x = 0.25f, .y = 50, .width = 0.4f, .height = 150},
|
||||
[](uui::Component& component) { component.set_background_color(0.3f, 0.8f, 0.4f, 0.5f); });
|
||||
|
||||
window.create_label(
|
||||
{.x = 50, .y = 50, .text = "Hello World!", .text_color = {0.5f, 1.0f, 0.5f, 1.0f}},
|
||||
[](uui::Label& label) { label.set_background_color(0.1f, 0.2f, 0.5f, 0.8f); });
|
||||
|
||||
window.create_label({0.5f, 0.5f, "Hello World!", {1.0f, 1.0f, 1.0f, 0.5f}}, [](uui::Label& label) {
|
||||
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}}, {});
|
||||
|
||||
window.create_flex({200, 0.6f, uui::Direction::HORIZONTAL}, [](uui::Flex& flex) {
|
||||
flex.create_component({.width = 100, .height = 50}, [](uui::Component& component) {
|
||||
component.set_background_color(0.2f, 0.75f, 0.25f);
|
||||
});
|
||||
flex.create_label({.text = "test", .text_color = {0.8f, 0.2f, 0.2f, 1.0f}}, {});
|
||||
flex.create_component({100, 20}, [](uui::Component& component) {
|
||||
component.set_background_color(0.2f, 0.25f, 0.75f);
|
||||
});
|
||||
});
|
||||
|
||||
window.create_flex({50, 400, uui::Direction::VERTICAL}, [](uui::Flex& flex) {
|
||||
flex.create_component({50, 100}, [](uui::Component& component) {
|
||||
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::Component& component) {
|
||||
component.set_background_color(0.2f, 0.25f, 0.75f);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
app->create_window(800, 600, "OpenGl 2", [](uui::Window& window) {
|
||||
window.create_stack(
|
||||
{.x = 200, .y = 0.6f, .direction = uui::Direction::HORIZONTAL}, [](uui::Stack& stack) {
|
||||
stack.create_component({.width = 100, .height = 50}, [](uui::Component& component) {
|
||||
component.set_background_color(0.2f, 0.75f, 0.25f);
|
||||
});
|
||||
stack.create_label({.text = "test", .text_color = {0.8f, 0.2f, 0.2f, 1.0f}}, {});
|
||||
stack.create_component({.width = 100, .height = 20}, [](uui::Component& component) {
|
||||
component.set_background_color(0.2f, 0.25f, 0.75f);
|
||||
});
|
||||
});
|
||||
|
||||
window.create_stack({.x = 50, .y = 400, .direction = uui::Direction::VERTICAL}, [](uui::Stack& stack) {
|
||||
stack.create_component({.width = 100, .height = 50}, [](uui::Component& component) {
|
||||
component.set_background_color(0.2f, 0.75f, 0.25f);
|
||||
});
|
||||
stack.create_label({.text = "test", .text_color = {0.8f, 0.2f, 0.2f, 1.0f}}, {});
|
||||
stack.create_component({.width = 100, .height = 20}, [](uui::Component& component) {
|
||||
component.set_background_color(0.2f, 0.25f, 0.75f);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
app->run();
|
||||
}
|
||||
cout << "\nStarting example 2" << endl;
|
||||
{
|
||||
auto app = uui::create_application(uui::Application::OPENGL);
|
||||
app->create_window(800, 600, "OpenGl!", [](uui::Window& window) {
|
||||
window.create_component({0.25f, 0.25f, 0.5f, 0.5f}, [](uui::Component& component) {
|
||||
component.set_background_color(0.8f, 0.1f, 0.5f);
|
||||
});
|
||||
window.create_component({0.75f, 0.75f, 0.25f, 0.25f}, [](uui::Component& component) {
|
||||
component.set_background_color(0.2f, 0.1f, 0.5f);
|
||||
});
|
||||
});
|
||||
|
||||
app->create_window(600, 600, "OpenGL 2!", [](uui::Window& window) {
|
||||
window.create_component({0, 0.5f, 100, 0.5f}, [](uui::Component& component) {
|
||||
component.set_background_color(0.2f, 0.5f, 0.3f);
|
||||
});
|
||||
window.create_label({50, 50, "Hello World!", {0.5f, 1.0f, 0.5f, 1.0f}}, [](uui::Label& label) {
|
||||
label.set_background_color(0.1f, 0.2f, 0.5f);
|
||||
});
|
||||
});
|
||||
app->run();
|
||||
}
|
||||
}
|
||||
catch(const std::exception& error)
|
||||
{
|
||||
|
|
|
|||
15
src/test/sample.cpp
Normal file
15
src/test/sample.cpp
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
#include "uui/uui.hpp"
|
||||
|
||||
int main()
|
||||
{
|
||||
auto app = uui::create_application(uui::Application::OPENGL);
|
||||
app->create_window(800, 600, "UUI sample", [](uui::Window& window) {
|
||||
window.create_component({.x = 0, .y = 0, .width = 200, .height = 100}, [](uui::Component& component) {
|
||||
component.set_background_color(1.0f, 0.f, 0.f, 0.5f);
|
||||
});
|
||||
window.create_label(
|
||||
{.x = 0.5f, .y = 0.5f, .text = "Hello world!", .text_color = {0.8f, 0.8f, 0.8f, 1.0f}}, nullptr);
|
||||
});
|
||||
app->run();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,3 +1,20 @@
|
|||
#include "uui/application.hpp"
|
||||
|
||||
bool uui::Application::application_created = false;
|
||||
#include <stdexcept>
|
||||
|
||||
#include "uui/opengl/application.hpp"
|
||||
|
||||
std::shared_ptr<uui::Application> uui::Application::current_application;
|
||||
|
||||
std::shared_ptr<uui::Application> uui::create_application(uui::Application::Implementaion implementation)
|
||||
{
|
||||
switch(implementation)
|
||||
{
|
||||
case uui::Application::Implementaion::OPENGL:
|
||||
if(uui::Application::current_application != nullptr)
|
||||
throw std::runtime_error("Application error: the application already created");
|
||||
std::shared_ptr<uui::Application> new_application(new uui::GlApplication());
|
||||
uui::Application::current_application = new_application;
|
||||
return new_application;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,17 +3,35 @@
|
|||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
uui::GlApplication* uui::GlApplication::application_pointer = nullptr;
|
||||
#include "uui/opengl/window.hpp"
|
||||
|
||||
uui::GlApplication::GlApplication()
|
||||
{
|
||||
if(application_pointer != nullptr)
|
||||
throw std::runtime_error("GlApplication error: the application already created");
|
||||
if constexpr(debug_mode)
|
||||
std::cout << "Creating the GlApplication in debug mode" << std::endl;
|
||||
else
|
||||
std::cout << "Creating the GlApplication in release mode" << std::endl;
|
||||
initialized = false;
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
uui::GlApplication::~GlApplication()
|
||||
{
|
||||
if constexpr(debug_mode)
|
||||
std::cout << "Destroying the GlApplication" << std::endl;
|
||||
if(initialized)
|
||||
deinit();
|
||||
}
|
||||
|
||||
void uui::GlApplication::init()
|
||||
{
|
||||
if constexpr(debug_mode)
|
||||
std::cout << "Initialize the GlApplication" << std::endl;
|
||||
|
||||
// Init GLFW
|
||||
// Avoiding libdecor would be better
|
||||
// glfwInitHint(GLFW_WAYLAND_LIBDECOR, GLFW_WAYLAND_DISABLE_LIBDECOR);
|
||||
glfwInit();
|
||||
// Set all the required options for GLFW
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
|
||||
|
|
@ -23,22 +41,24 @@ uui::GlApplication::GlApplication()
|
|||
if constexpr(uui::GlApplication::debug_mode)
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true);
|
||||
|
||||
application_pointer = this;
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
uui::GlApplication::~GlApplication()
|
||||
void uui::GlApplication::deinit()
|
||||
{
|
||||
if constexpr(debug_mode)
|
||||
std::cout << "Destroying the GlApplication" << std::endl;
|
||||
std::cout << "Deinit the GlApplication" << std::endl;
|
||||
windows.clear();
|
||||
glfwTerminate();
|
||||
application_pointer = nullptr;
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
void uui::GlApplication::run()
|
||||
{
|
||||
if constexpr(debug_mode)
|
||||
std::cout << "Starting the GlApplication" << std::endl;
|
||||
if(!initialized)
|
||||
init();
|
||||
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
auto end_time = start_time;
|
||||
|
|
@ -51,7 +71,7 @@ void uui::GlApplication::run()
|
|||
if constexpr(debug_mode)
|
||||
{
|
||||
end_time = std::chrono::high_resolution_clock::now();
|
||||
render_duration = std::chrono::duration_cast<std::chrono::milliseconds>(end_time - start_time).count();
|
||||
render_duration = std::chrono::duration<float, std::milli>(end_time - start_time).count();
|
||||
// std::cout << "Frame " << frame_count << ", duration: " << render_duration << std::endl;
|
||||
if(frame_count > 0.0f && render_duration > 500.0f)
|
||||
{
|
||||
|
|
@ -75,6 +95,8 @@ void uui::GlApplication::run()
|
|||
glfwMakeContextCurrent((*(windows.end() - 2))->glfw_window);
|
||||
glfwSwapInterval(1);
|
||||
}
|
||||
if constexpr(debug_mode)
|
||||
std::cout << "\nGlApplication closing GlWindow : " << window->title() << std::endl;
|
||||
window->deinit();
|
||||
windows.erase(it);
|
||||
it -= 1;
|
||||
|
|
@ -85,7 +107,7 @@ void uui::GlApplication::run()
|
|||
window->render();
|
||||
else
|
||||
{
|
||||
if(window->render_needed && !window->iconified)
|
||||
if(window->_render_needed && !window->_iconified)
|
||||
window->render();
|
||||
}
|
||||
}
|
||||
|
|
@ -95,11 +117,12 @@ void uui::GlApplication::run()
|
|||
}
|
||||
if constexpr(debug_mode)
|
||||
std::cout << "Ending the GlApplication" << std::endl;
|
||||
current_application = nullptr;
|
||||
}
|
||||
|
||||
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<Window> init)
|
||||
{
|
||||
std::shared_ptr<uui::GlWindow> window(new uui::GlWindow(this, windows.size(), width, height, title));
|
||||
auto window = std::shared_ptr<uui::GlWindow>(new uui::GlWindow(current_application, width, height, title));
|
||||
window->init();
|
||||
windows.push_back(window);
|
||||
glfwSwapInterval(1);
|
||||
|
|
@ -108,10 +131,12 @@ std::shared_ptr<uui::GlWindow> uui::GlApplication::create_window(int width, int
|
|||
glfwMakeContextCurrent((*(windows.end() - 2))->glfw_window);
|
||||
glfwSwapInterval(0);
|
||||
}
|
||||
return window;
|
||||
|
||||
if(window != nullptr && init != nullptr)
|
||||
init(*window);
|
||||
}
|
||||
|
||||
std::shared_ptr<uui::GlWindow> uui::GlApplication::get_window(size_t index) const
|
||||
std::shared_ptr<uui::Window> uui::GlApplication::get_window(std::size_t index) const
|
||||
{
|
||||
if(index > windows.size())
|
||||
throw std::runtime_error("Application doesn't have window at given index");
|
||||
|
|
|
|||
|
|
@ -3,46 +3,62 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "uui/opengl/application.hpp"
|
||||
#include "uui/opengl/container.hpp"
|
||||
#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):
|
||||
window(window),
|
||||
position_x(x), position_y(y), size_width(width), size_height(height), initialized(false)
|
||||
std::shared_ptr<uui::GlWindow> window, std::size_t window_index, std::shared_ptr<uui::GlContainer> parent,
|
||||
std::size_t parent_index, const ComponentParams& params)
|
||||
{
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Creating a GlBox" << std::endl;
|
||||
if constexpr(uui::Application::debug_mode)
|
||||
std::cout << "Creating a GlComponent " << parent_index << std::endl;
|
||||
|
||||
coord_all_relative = true;
|
||||
auto parse_coords = [&](std::variant<int, float>& value) {
|
||||
_type = ComponentType::COMPONENT;
|
||||
|
||||
gl_window = window;
|
||||
this->_window = std::static_pointer_cast<uui::Window>(window);
|
||||
this->_window_index = window_index;
|
||||
this->_parent = std::static_pointer_cast<uui::Container>(parent);
|
||||
this->_parent_index = parent_index;
|
||||
|
||||
_initialized = false;
|
||||
|
||||
_position_x = params.x;
|
||||
_position_y = params.y;
|
||||
_width = params.width;
|
||||
_height = params.height;
|
||||
|
||||
_coord_all_relative = true;
|
||||
auto parse_coords = [&](position_t& value) {
|
||||
if(value.index() == 0)
|
||||
{
|
||||
if(std::get<0>(value) == 0)
|
||||
value = 0.0f;
|
||||
else
|
||||
coord_all_relative = false;
|
||||
_coord_all_relative = false;
|
||||
}
|
||||
};
|
||||
parse_coords(position_x);
|
||||
parse_coords(position_y);
|
||||
parse_coords(size_width);
|
||||
parse_coords(size_height);
|
||||
parse_coords(_position_x);
|
||||
parse_coords(_position_y);
|
||||
parse_coords(_width);
|
||||
parse_coords(_height);
|
||||
|
||||
background_color = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
_background_color = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
}
|
||||
|
||||
uui::GlComponent::~GlComponent()
|
||||
{
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Closing a GlBox" << std::endl;
|
||||
if(initialized)
|
||||
std::cout << "Destructor GlComponent " << _parent_index << 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*/)
|
||||
{
|
||||
background_color = {r, g, b, a};
|
||||
_background_color = {r, g, b, a};
|
||||
glBindVertexArray(gl_vao);
|
||||
set_vbo_data();
|
||||
glBindVertexArray(0); // Optional : for safety
|
||||
|
|
@ -50,8 +66,8 @@ void uui::GlComponent::set_background_color(float r, float g, float b, float a /
|
|||
|
||||
void uui::GlComponent::init()
|
||||
{
|
||||
if(initialized)
|
||||
throw std::runtime_error("GlBox error : calling init while already initialized");
|
||||
if(_initialized)
|
||||
throw std::runtime_error("GlComponent error : calling init while already initialized");
|
||||
|
||||
glGenVertexArrays(1, &gl_vao);
|
||||
glGenBuffers(1, &gl_vbo);
|
||||
|
|
@ -78,31 +94,33 @@ void uui::GlComponent::init()
|
|||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
glBindVertexArray(0);
|
||||
|
||||
initialized = true;
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void uui::GlComponent::set_vbo_data()
|
||||
{
|
||||
float vert_x =
|
||||
position_x.index() == 1 ? std::get<1>(position_x) : static_cast<float>(std::get<0>(position_x)) / static_cast<float>(window->width);
|
||||
float vert_y =
|
||||
position_y.index() == 1 ? std::get<1>(position_y) : static_cast<float>(std::get<0>(position_y)) / static_cast<float>(window->height);
|
||||
float vert_w =
|
||||
size_width.index() == 1 ? std::get<1>(size_width) : static_cast<float>(std::get<0>(size_width)) / static_cast<float>(window->width);
|
||||
float vert_h = size_height.index() == 1 ? std::get<1>(size_height)
|
||||
: static_cast<float>(std::get<0>(size_height)) / static_cast<float>(window->height);
|
||||
float vert_x = _position_x.index() == 1
|
||||
? std::get<1>(_position_x)
|
||||
: static_cast<float>(std::get<0>(_position_x)) / static_cast<float>(_window->width());
|
||||
float vert_y = _position_y.index() == 1
|
||||
? std::get<1>(_position_y)
|
||||
: static_cast<float>(std::get<0>(_position_y)) / static_cast<float>(_window->height());
|
||||
float vert_w = _width.index() == 1 ? std::get<1>(_width)
|
||||
: static_cast<float>(std::get<0>(_width)) / static_cast<float>(_window->width());
|
||||
float vert_h = _height.index() == 1
|
||||
? std::get<1>(_height)
|
||||
: static_cast<float>(std::get<0>(_height)) / static_cast<float>(_window->height());
|
||||
float x_min = (2.0f * vert_x) - 1.0f;
|
||||
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
|
||||
x_max, y_max, background_color[0] , background_color[1], background_color[2], background_color[3], // bottom right
|
||||
x_min, y_max, background_color[0] , background_color[1], background_color[2], background_color[3], // bottom left
|
||||
x_min, y_min, background_color[0] , background_color[1], background_color[2], background_color[3] // top left
|
||||
float vertices[] =
|
||||
{
|
||||
x_max, y_min, _background_color[0], _background_color[1], _background_color[2], _background_color[3], // top right
|
||||
x_max, y_max, _background_color[0], _background_color[1], _background_color[2], _background_color[3], // bottom right
|
||||
x_min, y_max, _background_color[0], _background_color[1], _background_color[2], _background_color[3], // bottom left
|
||||
x_min, y_min, _background_color[0], _background_color[1], _background_color[2], _background_color[3] // top left
|
||||
};
|
||||
// clang-format on
|
||||
glBindBuffer(GL_ARRAY_BUFFER, gl_vbo);
|
||||
|
|
@ -130,13 +148,19 @@ void uui::GlComponent::set_vbo_data()
|
|||
|
||||
void uui::GlComponent::deinit()
|
||||
{
|
||||
if(!initialized)
|
||||
throw std::runtime_error("GlBox error : calling deinit while not initialized");
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Deinit GlComponent " << _parent_index << std::endl;
|
||||
|
||||
if(!_initialized)
|
||||
throw std::runtime_error("GlComponent error : calling deinit while not initialized");
|
||||
|
||||
glDeleteVertexArrays(1, &gl_vao);
|
||||
glDeleteBuffers(1, &gl_vbo);
|
||||
glDeleteBuffers(1, &gl_ebo);
|
||||
initialized = false;
|
||||
|
||||
_window = nullptr;
|
||||
_parent = nullptr;
|
||||
_initialized = false;
|
||||
}
|
||||
|
||||
void uui::GlComponent::render()
|
||||
|
|
@ -147,8 +171,12 @@ void uui::GlComponent::render()
|
|||
|
||||
void uui::GlComponent::on_resize()
|
||||
{
|
||||
if(!coord_all_relative)
|
||||
bool is_in_stack =
|
||||
_parent != nullptr && (_parent->type() == ComponentType::FLEX || _parent->type() == ComponentType::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
|
||||
|
|
|
|||
38
src/uui/opengl/container_interface.cpp
Normal file
38
src/uui/opengl/container_interface.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include "uui/opengl/container_interface.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "uui/opengl/component.hpp"
|
||||
|
||||
std::size_t uui::GlContainerInterface::push_child(std::shared_ptr<uui::Component> child [[maybe_unused]])
|
||||
{
|
||||
throw std::runtime_error("GlContainerInterface error : should only push GlComponent child, not Component");
|
||||
}
|
||||
|
||||
std::size_t uui::GlContainerInterface::push_child(std::shared_ptr<uui::GlComponent> child)
|
||||
{
|
||||
components.push_back(child);
|
||||
return components.size() - 1;
|
||||
}
|
||||
|
||||
std::shared_ptr<uui::Component> uui::GlContainerInterface::get_child(std::size_t index) const
|
||||
{
|
||||
return components.at(index);
|
||||
}
|
||||
|
||||
void uui::GlContainerInterface::remove_child(std::size_t index)
|
||||
{
|
||||
components.at(index) = nullptr;
|
||||
};
|
||||
|
||||
std::tuple<int, int> uui::GlContainerInterface::get_child_position(const std::size_t child_index [[maybe_unused]]) const
|
||||
{
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
uui::GlContainerInterface::~GlContainerInterface()
|
||||
{
|
||||
if constexpr(uui::Application::debug_mode)
|
||||
std::cout << "Destroying GlContainerInterface" << std::endl;
|
||||
components.clear();
|
||||
}
|
||||
124
src/uui/opengl/flex.cpp
Normal file
124
src/uui/opengl/flex.cpp
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
#include "uui/opengl/flex.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "uui/opengl/gl_utils.hpp"
|
||||
|
||||
uui::GlFlex::GlFlex(
|
||||
std::shared_ptr<uui::GlWindow> window, std::size_t window_index, std::shared_ptr<uui::GlContainer> parent,
|
||||
std::size_t parent_index, const StackParams& params):
|
||||
GlComponent(window, window_index, parent, parent_index, {params.x, params.y, 0.0f, 0.0f}),
|
||||
GlStack(window, window_index, parent, parent_index, params)
|
||||
{
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Creating a GlFlex " << parent_index << std::endl;
|
||||
|
||||
_type = ComponentType::FLEX;
|
||||
|
||||
_coord_all_relative = false;
|
||||
}
|
||||
|
||||
std::tuple<int, int> uui::GlFlex::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->width().index() == 1)
|
||||
width = static_cast<int>(std::get<1>(component->width()) * static_cast<float>(_window->width()));
|
||||
else
|
||||
width = std::get<0>(component->width());
|
||||
if(component->height().index() == 1)
|
||||
height = static_cast<int>(std::get<1>(component->height()) * static_cast<float>(_window->height()));
|
||||
else
|
||||
height = std::get<0>(component->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};
|
||||
}
|
||||
|
|
@ -6,12 +6,15 @@
|
|||
#include <algorithm>
|
||||
#include <iostream>
|
||||
|
||||
#include "uui/config.hpp"
|
||||
#include "uui/opengl/application.hpp"
|
||||
#include "uui/opengl/gl_utils.hpp"
|
||||
#include "uui/shader.hpp"
|
||||
#include "uui/types.hpp"
|
||||
|
||||
uui::GlFontManager::GlFontManager(): initialized(false) {}
|
||||
uui::GlFontManager::GlFontManager()
|
||||
{
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
uui::GlFontManager::~GlFontManager()
|
||||
{
|
||||
|
|
@ -25,7 +28,7 @@ void uui::GlFontManager::init()
|
|||
throw std::runtime_error("GlFontManager error : calling init while initialized");
|
||||
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Init glFontManager" << std::endl;
|
||||
std::cout << "Init GlFontManager" << std::endl;
|
||||
|
||||
if(FT_Init_FreeType(&ft))
|
||||
throw std::runtime_error("ERROR::FREETYPE: Could not init FreeType Library");
|
||||
|
|
@ -117,6 +120,9 @@ void uui::GlFontManager::deinit()
|
|||
if(!initialized)
|
||||
throw std::runtime_error("GlFontManager error : calling deinit while not initialized");
|
||||
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Deinit GlFontManager" << std::endl;
|
||||
|
||||
for(const auto& font: fonts) glDeleteTextures(1, &font.atlas_texture);
|
||||
glDeleteBuffers(1, &gl_vbo);
|
||||
glDeleteBuffers(1, &gl_vao);
|
||||
|
|
@ -125,7 +131,7 @@ void uui::GlFontManager::deinit()
|
|||
initialized = false;
|
||||
}
|
||||
|
||||
const uui::GlFontManager::Font& uui::GlFontManager::init_font(const std::string& font_path, size_t font_size)
|
||||
const uui::GlFontManager::Font& uui::GlFontManager::init_font(const std::string& font_path, unsigned int font_size)
|
||||
{
|
||||
fonts.emplace_back();
|
||||
auto& font = fonts.back();
|
||||
|
|
@ -167,7 +173,7 @@ const uui::GlFontManager::Font& uui::GlFontManager::init_font(const std::string&
|
|||
glLinkProgram(gl_program);
|
||||
|
||||
// Create a texture that will be used to hold all ASCII glyphs
|
||||
glActiveTexture(Config::FONT_TEXTURE_UNIT);
|
||||
glActiveTexture(GlConfig::FONT_TEXTURE_UNIT);
|
||||
glGenTextures(1, &font.atlas_texture);
|
||||
glBindTexture(GL_TEXTURE_2D, font.atlas_texture);
|
||||
|
||||
|
|
@ -206,7 +212,8 @@ const uui::GlFontManager::Font& uui::GlFontManager::init_font(const std::string&
|
|||
}
|
||||
|
||||
glTexSubImage2D(
|
||||
GL_TEXTURE_2D, 0, offset_x, offset_y, glyph->bitmap.width, glyph->bitmap.rows, GL_RED, GL_UNSIGNED_BYTE, glyph->bitmap.buffer);
|
||||
GL_TEXTURE_2D, 0, offset_x, offset_y, glyph->bitmap.width, glyph->bitmap.rows, GL_RED, GL_UNSIGNED_BYTE,
|
||||
glyph->bitmap.buffer);
|
||||
font.char_infos[i].advance_x = glyph->advance.x >> 6;
|
||||
font.char_infos[i].advance_y = glyph->advance.y >> 6;
|
||||
|
||||
|
|
@ -234,7 +241,7 @@ std::tuple<int, int> uui::GlFontManager::get_text_size(
|
|||
float height = 0.0f;
|
||||
for(auto current_char: text)
|
||||
{
|
||||
const auto& char_info = font.char_infos[static_cast<size_t>(current_char)];
|
||||
const auto& char_info = font.char_infos[static_cast<std::size_t>(current_char)];
|
||||
width += char_info.advance_x * scale_x;
|
||||
// height = std::max(height, char_info.bitmap_top + char_info.bitmap_height * scale_y);
|
||||
height = std::max(height, roundf(char_info.bitmap_height * scale_y));
|
||||
|
|
@ -250,7 +257,7 @@ void uui::GlFontManager::render_text(
|
|||
glGetIntegerv(GL_CURRENT_PROGRAM, (GLint*)(&gl_prev_program));
|
||||
glUseProgram(gl_program);
|
||||
|
||||
glActiveTexture(Config::FONT_TEXTURE_UNIT);
|
||||
glActiveTexture(GlConfig::FONT_TEXTURE_UNIT);
|
||||
auto [color_r, color_g, color_b, color_a] = text_color;
|
||||
glUniform4f(glGetUniformLocation(gl_program, "textColor"), color_r, color_g, color_b, color_a);
|
||||
glBindVertexArray(gl_vao);
|
||||
|
|
@ -268,7 +275,7 @@ void uui::GlFontManager::render_text(
|
|||
float out_base_y = y;
|
||||
for(auto current_char: text)
|
||||
{
|
||||
const auto& char_info = font.char_infos[static_cast<size_t>(current_char)];
|
||||
const auto& char_info = font.char_infos[static_cast<std::size_t>(current_char)];
|
||||
// Calculate the vertex and texture coordinates
|
||||
float char_x = out_base_x + char_info.bitmap_left * scale_x;
|
||||
float char_y = out_base_y - char_info.bitmap_top * scale_y;
|
||||
|
|
@ -284,7 +291,8 @@ void uui::GlFontManager::render_text(
|
|||
continue;
|
||||
|
||||
// clang-format off
|
||||
float current_vertex[24] = {
|
||||
float current_vertex[24] =
|
||||
{
|
||||
char_x, char_y, char_info.texture_x, char_info.texture_y, // top_left
|
||||
char_x + w, char_y, char_info.texture_x + char_info.bitmap_width / font.atlas_width, char_info.texture_y, // top-right
|
||||
char_x, char_y + h, char_info.texture_x, char_info.texture_y + char_info.bitmap_height / font.atlas_height, // bottom-right
|
||||
|
|
|
|||
|
|
@ -2,34 +2,39 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include "uui/opengl/font_manager.hpp"
|
||||
#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),
|
||||
text(text), text_color(text_color)
|
||||
std::shared_ptr<uui::GlWindow> window, std::size_t window_index, std::shared_ptr<uui::GlContainer> parent,
|
||||
std::size_t parent_index, const LabelParams& params):
|
||||
GlComponent(window, window_index, parent, parent_index, {params.x, params.y, 0.0f, 0.0f}), text(params.text),
|
||||
text_color(params.text_color)
|
||||
{
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Creating a GlLabel" << std::endl;
|
||||
if constexpr(uui::Application::debug_mode)
|
||||
std::cout << "Creating GlLabel " << parent_index << std::endl;
|
||||
|
||||
_type = ComponentType::LABEL;
|
||||
|
||||
font_index = 0;
|
||||
std::tie(text_width, text_height) = window->font_manager.get_text_size(text, window->font_manager.fonts[font_index], 1.0f, 1.0f);
|
||||
size_width = text_width;
|
||||
size_height = text_height;
|
||||
coord_all_relative = false;
|
||||
std::tie(text_width, text_height) =
|
||||
window->font_manager->get_text_size(text, window->font_manager->fonts[font_index], 1.0f, 1.0f);
|
||||
_width = text_width;
|
||||
_height = text_height;
|
||||
_coord_all_relative = false;
|
||||
}
|
||||
|
||||
void uui::GlLabel::render()
|
||||
{
|
||||
float text_x =
|
||||
position_x.index() == 1 ? std::get<1>(position_x) * static_cast<float>(window->width) : static_cast<float>(std::get<0>(position_x));
|
||||
float text_y =
|
||||
position_y.index() == 1 ? std::get<1>(position_y) * static_cast<float>(window->height) : static_cast<float>(std::get<0>(position_y));
|
||||
float text_x = _position_x.index() == 1 ? std::get<1>(_position_x) * static_cast<float>(_window->width())
|
||||
: static_cast<float>(std::get<0>(_position_x));
|
||||
float text_y = _position_y.index() == 1 ? std::get<1>(_position_y) * static_cast<float>(_window->height())
|
||||
: static_cast<float>(std::get<0>(_position_y));
|
||||
text_y += static_cast<float>(text_height) - 1;
|
||||
|
||||
glBindVertexArray(gl_vao);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)0);
|
||||
window->font_manager.render_text(text.c_str(), window->font_manager.fonts.front(), text_x, text_y, 1.0f, 1.0f, text_color);
|
||||
_window->font_manager->render_text(
|
||||
text.c_str(), _window->font_manager->fonts.front(), text_x, text_y, 1.0f, 1.0f, text_color);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
|
|
|||
101
src/uui/opengl/stack.cpp
Normal file
101
src/uui/opengl/stack.cpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
#include "uui/opengl/stack.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "uui/opengl/gl_utils.hpp"
|
||||
#include "uui/opengl/label.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 StackParams& params):
|
||||
GlComponent(window, window_index, parent, parent_index, {params.x, params.y, 0.0f, 0.0f})
|
||||
{
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Creating GlStack " << parent_index << std::endl;
|
||||
|
||||
_type = ComponentType::STACK;
|
||||
|
||||
direction = params.direction;
|
||||
|
||||
_coord_all_relative = false;
|
||||
}
|
||||
|
||||
void uui::GlStack::create_component(const StackComponentParams& params, uui::InitFunction<uui::Component> init)
|
||||
{
|
||||
if(!_initialized)
|
||||
throw std::runtime_error("GlWindow error : cannot create component while not initialized");
|
||||
|
||||
glfwMakeContextCurrent(gl_window->glfw_window);
|
||||
std::shared_ptr<uui::GlComponent> component(new uui::GlComponent(
|
||||
gl_window, gl_window->components.size(), std::dynamic_pointer_cast<uui::GlContainer>(shared_from_this()),
|
||||
components.size(), {0, 0, params.width, params.height}));
|
||||
push_child(component);
|
||||
component->init();
|
||||
std::tie(component->_position_x, component->_position_y) = get_child_position(components.size() - 1);
|
||||
gl_window->components.push_back(component);
|
||||
|
||||
if(component != nullptr)
|
||||
init(*component);
|
||||
}
|
||||
|
||||
void uui::GlStack::create_label(const StackLabelParams& params, uui::InitFunction<uui::Label> init)
|
||||
{
|
||||
if(!_initialized)
|
||||
throw std::runtime_error("GlWindow error : cannot create component while not initialized");
|
||||
|
||||
glfwMakeContextCurrent(gl_window->glfw_window);
|
||||
std::shared_ptr<uui::GlLabel> label(new uui::GlLabel(
|
||||
gl_window, gl_window->components.size(), std::dynamic_pointer_cast<uui::GlContainer>(shared_from_this()),
|
||||
components.size(), {0, 0, params.text, params.text_color}));
|
||||
push_child(std::static_pointer_cast<uui::GlComponent>(label));
|
||||
label->init();
|
||||
std::tie(label->_position_x, label->_position_y) = get_child_position(components.size() - 1);
|
||||
gl_window->components.push_back(label);
|
||||
|
||||
if(label != nullptr && init != nullptr)
|
||||
init(*label);
|
||||
}
|
||||
|
||||
std::tuple<int, int> 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<int>(std::get<1>(_position_x) * static_cast<float>(_window->width()));
|
||||
int 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 {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->width().index() == 1)
|
||||
x += static_cast<int>(std::get<1>(component->width()) * static_cast<float>(_window->width()));
|
||||
else
|
||||
x += std::get<0>(component->width());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(std::size_t index = 0; index < child_index; index += 1)
|
||||
{
|
||||
if(components[index] != nullptr)
|
||||
{
|
||||
auto& component = components[index];
|
||||
if(component->height().index() == 1)
|
||||
y += static_cast<int>(std::get<1>(component->height()) * static_cast<float>(_window->height()));
|
||||
else
|
||||
y += std::get<0>(component->height());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {x, y};
|
||||
}
|
||||
|
|
@ -3,12 +3,15 @@
|
|||
#include <iostream>
|
||||
|
||||
#include "uui/opengl/component.hpp"
|
||||
#include "uui/opengl/flex.hpp"
|
||||
#include "uui/opengl/gl_utils.hpp"
|
||||
#include "uui/opengl/label.hpp"
|
||||
#include "uui/opengl/stack.hpp"
|
||||
#include "uui/shader.hpp"
|
||||
|
||||
static void APIENTRY
|
||||
glDebugOutput(GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length, const char* message, const void* userParam)
|
||||
static void APIENTRY glDebugOutput(
|
||||
GLenum source, GLenum type, unsigned int id, GLenum severity, GLsizei length [[maybe_unused]], const char* message,
|
||||
const void* userParam [[maybe_unused]])
|
||||
{
|
||||
// ignore non-significant error/warning codes
|
||||
if(id == 131169 || id == 131185 || id == 131218 || id == 131204)
|
||||
|
|
@ -57,55 +60,77 @@ void uui::GlWindow::glfw_resize_callback(GLFWwindow* window, int width, int heig
|
|||
glfwMakeContextCurrent(window);
|
||||
auto gl_window = reinterpret_cast<uui::GlWindow*>(glfwGetWindowUserPointer(window));
|
||||
glViewport(0, 0, width, height);
|
||||
gl_window->width = width;
|
||||
gl_window->height = height;
|
||||
gl_window->render_needed = true;
|
||||
gl_window->resize_needed = true;
|
||||
gl_window->_width = width;
|
||||
gl_window->_height = height;
|
||||
gl_window->_render_needed = true;
|
||||
gl_window->_resize_needed = true;
|
||||
|
||||
glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(width), static_cast<float>(height), 0.0f);
|
||||
glfwMakeContextCurrent(window);
|
||||
glUseProgram(gl_window->font_manager.gl_program);
|
||||
glUniformMatrix4fv(glGetUniformLocation(gl_window->font_manager.gl_program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||
glUseProgram(gl_window->gl_font_manager->gl_program);
|
||||
glUniformMatrix4fv(
|
||||
glGetUniformLocation(gl_window->gl_font_manager->gl_program, "projection"), 1, GL_FALSE,
|
||||
glm::value_ptr(projection));
|
||||
}
|
||||
|
||||
void uui::GlWindow::glfw_iconify_callback(GLFWwindow* window, int iconified)
|
||||
{
|
||||
auto gl_window = reinterpret_cast<uui::GlWindow*>(glfwGetWindowUserPointer(window));
|
||||
gl_window->iconified = iconified;
|
||||
gl_window->_iconified = iconified;
|
||||
}
|
||||
|
||||
void uui::GlWindow::glfw_key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
|
||||
void uui::GlWindow::glfw_key_callback(
|
||||
GLFWwindow* window, int key, int scancode [[maybe_unused]], int action, int mods [[maybe_unused]])
|
||||
{
|
||||
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
|
||||
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)
|
||||
// void uui::GlWindow::glfw_mouse_button_callback(GLFWwindow* window, int button, int action, int mods)
|
||||
// {
|
||||
// if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
|
||||
// {}
|
||||
// }
|
||||
|
||||
uui::GlWindow::GlWindow(std::shared_ptr<uui::Application> app, int width, int height, const std::string& title)
|
||||
{
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Creating a GlWindow" << std::endl;
|
||||
this->title = title;
|
||||
_type = ComponentType::WINDOW;
|
||||
|
||||
_app = app;
|
||||
_initialized = false;
|
||||
|
||||
_title = title;
|
||||
_width = width;
|
||||
_height = height;
|
||||
_render_needed = true;
|
||||
_resize_needed = false;
|
||||
_iconified = false;
|
||||
|
||||
if constexpr(uui::Application::debug_mode)
|
||||
std::cout << "Creating GlWindow : " << title << std::endl;
|
||||
}
|
||||
|
||||
uui::GlWindow::~GlWindow()
|
||||
{
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Closing a GlWindow" << std::endl;
|
||||
if(initialized)
|
||||
if constexpr(uui::Application::debug_mode)
|
||||
std::cout << "Destructor GlWindow : " << _title << std::endl;
|
||||
if(_initialized)
|
||||
{
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Destructor-deinit a GlWindow" << std::endl;
|
||||
if constexpr(uui::Application::debug_mode)
|
||||
std::cout << "Destructor-deinit GlWindow : " << _title << std::endl;
|
||||
deinit();
|
||||
}
|
||||
}
|
||||
|
||||
void uui::GlWindow::init()
|
||||
{
|
||||
if(initialized)
|
||||
if(_initialized)
|
||||
throw std::runtime_error("GlWindow error : calling init while already initialized");
|
||||
|
||||
glfw_window = glfwCreateWindow(width, height, title.c_str(), NULL, NULL);
|
||||
gl_font_manager = std::make_shared<uui::GlFontManager>();
|
||||
font_manager = std::static_pointer_cast<uui::FontManager>(gl_font_manager);
|
||||
|
||||
glfw_window = glfwCreateWindow(_width, _height, _title.c_str(), NULL, NULL);
|
||||
if(glfw_window == NULL)
|
||||
throw std::runtime_error("GLWindow : failed to create GLFW window");
|
||||
glfwMakeContextCurrent(glfw_window);
|
||||
|
|
@ -201,31 +226,35 @@ void uui::GlWindow::init()
|
|||
glDeleteShader(vertex_shader);
|
||||
glDeleteShader(fragment_shader);
|
||||
|
||||
font_manager.init();
|
||||
glUseProgram(font_manager.gl_program);
|
||||
glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(width), static_cast<float>(height), 0.0f);
|
||||
glUniformMatrix4fv(glGetUniformLocation(font_manager.gl_program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||
gl_font_manager->init();
|
||||
glUseProgram(gl_font_manager->gl_program);
|
||||
glm::mat4 projection = glm::ortho(0.0f, static_cast<float>(_width), static_cast<float>(_height), 0.0f);
|
||||
glUniformMatrix4fv(
|
||||
glGetUniformLocation(gl_font_manager->gl_program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));
|
||||
glUseProgram(gl_program);
|
||||
|
||||
initialized = true;
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
void uui::GlWindow::deinit()
|
||||
{
|
||||
if(!initialized)
|
||||
if(!_initialized)
|
||||
throw std::runtime_error("GlWindow error : calling deinit while not initialized");
|
||||
|
||||
if constexpr(uui::GlApplication::debug_mode)
|
||||
std::cout << "Deinit a GlWindow" << std::endl;
|
||||
std::cout << "Deinit GlWindow : " << _title << std::endl;
|
||||
|
||||
glfwMakeContextCurrent(glfw_window);
|
||||
glDeleteProgram(gl_program);
|
||||
for(auto& component: components) component->deinit();
|
||||
for(auto& gl_component: components) gl_component->deinit();
|
||||
components.clear();
|
||||
font_manager.deinit();
|
||||
gl_font_manager->deinit();
|
||||
glfwDestroyWindow(glfw_window);
|
||||
|
||||
initialized = false;
|
||||
_app = nullptr;
|
||||
font_manager = nullptr;
|
||||
gl_font_manager = nullptr;
|
||||
_initialized = false;
|
||||
}
|
||||
|
||||
void uui::GlWindow::render()
|
||||
|
|
@ -235,41 +264,69 @@ void uui::GlWindow::render()
|
|||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glUseProgram(gl_program);
|
||||
if(resize_needed)
|
||||
if(_resize_needed)
|
||||
{
|
||||
for(auto& component: components) component->on_resize();
|
||||
resize_needed = false;
|
||||
_resize_needed = false;
|
||||
}
|
||||
for(auto& component: components) component->render();
|
||||
glfwSwapBuffers(glfw_window);
|
||||
|
||||
render_needed = false;
|
||||
_render_needed = false;
|
||||
}
|
||||
|
||||
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)
|
||||
void uui::GlWindow::create_component(const uui::ComponentParams& params, uui::InitFunction<Component> init)
|
||||
{
|
||||
if(!initialized)
|
||||
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(), params));
|
||||
push_child(component);
|
||||
component->init();
|
||||
components.push_back(component);
|
||||
return component;
|
||||
|
||||
if(component != nullptr && init != nullptr)
|
||||
init(*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)
|
||||
void uui::GlWindow::create_label(const LabelParams& params, uui::InitFunction<Label> init)
|
||||
{
|
||||
if(!initialized)
|
||||
throw std::runtime_error("GlWindow error : cannot create component while not initialized");
|
||||
if(!_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(), params));
|
||||
push_child(std::static_pointer_cast<uui::GlComponent>(label));
|
||||
label->init();
|
||||
components.push_back(label);
|
||||
return label;
|
||||
|
||||
if(label != nullptr && init != nullptr)
|
||||
init(*label);
|
||||
}
|
||||
|
||||
void uui::GlWindow::create_flex(const StackParams& params, uui::InitFunction<Flex> init)
|
||||
{
|
||||
if(!_initialized)
|
||||
throw std::runtime_error("GlWindow error : cannot create flex while not initialized");
|
||||
|
||||
glfwMakeContextCurrent(glfw_window);
|
||||
std::shared_ptr<uui::GlFlex> flex(new uui::GlFlex(shared_from_this(), components.size(), params));
|
||||
push_child(std::static_pointer_cast<uui::GlComponent>(flex));
|
||||
flex->init();
|
||||
|
||||
if(flex != nullptr && init != nullptr)
|
||||
init(*flex);
|
||||
}
|
||||
|
||||
void uui::GlWindow::create_stack(const StackParams& params, uui::InitFunction<Stack> init)
|
||||
{
|
||||
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(), params));
|
||||
push_child(std::static_pointer_cast<uui::GlComponent>(stack));
|
||||
stack->init();
|
||||
|
||||
if(stack != nullptr && init != nullptr)
|
||||
init(*stack);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#include "uui/shader.hpp"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include <ios>
|
||||
|
||||
std::vector<char> uui::readFile(const std::string& filename)
|
||||
{
|
||||
|
|
@ -10,10 +10,10 @@ std::vector<char> uui::readFile(const std::string& filename)
|
|||
if(!file.is_open())
|
||||
throw std::runtime_error("failed to open file!");
|
||||
|
||||
size_t fileSize = (size_t)file.tellg();
|
||||
std::size_t fileSize = static_cast<std::size_t>(file.tellg());
|
||||
std::vector<char> buffer(fileSize);
|
||||
file.seekg(0);
|
||||
file.read(buffer.data(), fileSize);
|
||||
file.read(buffer.data(), static_cast<std::streamsize>(fileSize));
|
||||
file.close();
|
||||
|
||||
return buffer;
|
||||
|
|
|
|||
2
umake
2
umake
|
|
@ -1 +1 @@
|
|||
Subproject commit f5965cc91e7eb27d1def78113301e7ec28fad54a
|
||||
Subproject commit 933dea2b9e9da0b03489ea9dca3cd597fdd2d09e
|
||||
Loading…
Add table
Add a link
Reference in a new issue