diff --git a/.ccls b/.ccls index 68cd814..a91784d 100644 --- a/.ccls +++ b/.ccls @@ -1,6 +1,8 @@ -clang++ +clangd -std=c++17 -DDEBUG +-Wall +-Wconversion -Iinclude -I/usr/include/freetype2 -I/usr/include/libpng16 diff --git a/.clang-format b/.clang-format index f54912e..3efd2bd 100644 --- a/.clang-format +++ b/.clang-format @@ -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 \ No newline at end of file +UseTab: Always diff --git a/.gitignore b/.gitignore index f6d5daf..68174dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .#.* *.kdev4 +*.ttf .ccls-cache .kdev4 diff --git a/README.md b/README.md new file mode 100644 index 0000000..f3cd877 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# UUI + +Simple and efficient C++ GUI toolkit diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..b85818b --- /dev/null +++ b/ROADMAP.md @@ -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) diff --git a/include/uui/application.hpp b/include/uui/application.hpp index 151ca36..7d813a0 100644 --- a/include/uui/application.hpp +++ b/include/uui/application.hpp @@ -3,17 +3,39 @@ #include #include -#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 add_window(int width, int height, const std::string& title) = 0; + virtual void create_window(int width, int height, const std::string& title, InitFunction init) = 0; + virtual std::shared_ptr get_window(std::size_t index [[maybe_unused]]) const = 0; + virtual ~Application() {}; protected: - static bool application_created; + static std::shared_ptr current_application; + + bool initialized; + + virtual void init() = 0; + virtual void deinit() = 0; + + friend std::shared_ptr create_application(Application::Implementaion implementation); }; + +std::shared_ptr create_application(Application::Implementaion implementation); } // namespace uui diff --git a/include/uui/component.hpp b/include/uui/component.hpp index 7e41fc9..ef91c34 100644 --- a/include/uui/component.hpp +++ b/include/uui/component.hpp @@ -1,31 +1,45 @@ #pragma once #include -#include +#include + +#include "uui/types.hpp" +#include "uui/window.hpp" namespace uui { +class Container; class Component { public: - Component( - const std::variant x, const std::variant y, const std::variant width, - const std::variant height): - position_x(x), - position_y(y), size_width(width), size_height(height) - { - 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 position_x; - std::variant position_y; - std::variant size_width; - std::variant size_height; + ComponentType _type = ComponentType::UNASSIGNED; - std::array background_color; + std::shared_ptr _window; + std::size_t _window_index; + std::shared_ptr _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 _background_color; + + bool _initialized = false; + + virtual void render() = 0; }; } // namespace uui diff --git a/include/uui/config.hpp b/include/uui/config.hpp deleted file mode 100644 index 1afb3a0..0000000 --- a/include/uui/config.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "graphic_context.hpp" - -namespace Config -{ -constexpr unsigned int FONT_TEXTURE_UNIT = GL_TEXTURE0; -} diff --git a/include/uui/container.hpp b/include/uui/container.hpp new file mode 100644 index 0000000..782ff97 --- /dev/null +++ b/include/uui/container.hpp @@ -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 diff --git a/include/uui/container_interface.hpp b/include/uui/container_interface.hpp new file mode 100644 index 0000000..e43f496 --- /dev/null +++ b/include/uui/container_interface.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#include "uui/types.hpp" + +namespace uui +{ +class Component; +class ContainerInterface +{ +public: + virtual std::tuple get_child_position(const std::size_t child_index [[maybe_unused]]) const = 0; + +protected: + virtual std::size_t push_child(std::shared_ptr child) = 0; + virtual std::shared_ptr get_child(std::size_t index) const = 0; + virtual void remove_child(std::size_t index) = 0; +}; + +} // namespace uui diff --git a/include/uui/flex.hpp b/include/uui/flex.hpp new file mode 100644 index 0000000..1adf974 --- /dev/null +++ b/include/uui/flex.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +#include "uui/stack.hpp" + +namespace uui +{ +class Flex: virtual public Stack +{ +protected: + virtual std::tuple get_child_position(const std::size_t child_index) const = 0; +}; + +} // namespace uui diff --git a/include/uui/font_manager.hpp b/include/uui/font_manager.hpp new file mode 100644 index 0000000..52da172 --- /dev/null +++ b/include/uui/font_manager.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include +#include +#include + +#include +#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 fonts; + + virtual void render_text( + const std::string& text, Font& font, float x, float y, float scale_x, float scale_y, + const std::tuple& text_color) = 0; + virtual std::tuple 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 diff --git a/include/uui/label.hpp b/include/uui/label.hpp new file mode 100644 index 0000000..2de7c22 --- /dev/null +++ b/include/uui/label.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include +#include + +#include "uui/component.hpp" + +namespace uui +{ +class Label: virtual public Component +{ +protected: + std::size_t font_index; + + std::string text; + std::tuple text_color; + + int text_width; + int text_height; +}; + +} // namespace uui diff --git a/include/uui/opengl/application.hpp b/include/uui/opengl/application.hpp index df15fe4..4d2d4e6 100644 --- a/include/uui/opengl/application.hpp +++ b/include/uui/opengl/application.hpp @@ -2,89 +2,32 @@ #include #include -#include #include #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> windows; GlApplication(); - ~GlApplication(); + virtual ~GlApplication() final; - void run(); - std::shared_ptr create_window(int width, int height, const std::string& title); - std::shared_ptr 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> components; - - GlWindow(const GlWindow&) = delete; - GlWindow(GlWindow&&) = delete; - ~GlWindow(); - - std::shared_ptr create_component( - const std::variant x, const std::variant y, const std::variant width, - const std::variant height); - std::shared_ptr create_label( - const std::variant x, const std::variant y, const std::string& text, - const std::tuple& text_color); + void run() final; + void create_window(int width, int height, const std::string& title, InitFunction init) final; + std::shared_ptr 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 diff --git a/include/uui/opengl/button.hpp b/include/uui/opengl/button.hpp new file mode 100644 index 0000000..0df1ff2 --- /dev/null +++ b/include/uui/opengl/button.hpp @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include + +#include "uui/opengl/component.hpp" + +namespace uui +{ +class GlButton: public GlComponent +{ + friend class GlWindow; + +protected: + GlButton( + std::shared_ptr window, std::size_t window_index, std::shared_ptr parent, + std::size_t parent_index, const position_t x, const position_t y, const Direction direction); + GlButton( + std::shared_ptr 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 get_child_position(const std::size_t child_index) const; +}; + +} // namespace uui diff --git a/include/uui/opengl/component.hpp b/include/uui/opengl/component.hpp index b2c57bc..6ecaa99 100644 --- a/include/uui/opengl/component.hpp +++ b/include/uui/opengl/component.hpp @@ -2,49 +2,50 @@ #include #include -#include -#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, 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 window; - - std::variant position_x; - std::variant position_y; - std::variant size_width; - std::variant size_height; - bool coord_all_relative; - - std::array background_color; - - bool initialized; - + std::shared_ptr gl_window; GLuint gl_vbo; GLuint gl_vao; GLuint gl_ebo; GlComponent( - std::shared_ptr window, const std::variant x, const std::variant y, - const std::variant width, const std::variant height); + std::shared_ptr window, std::size_t window_index, std::shared_ptr parent, + std::size_t parent_index, const ComponentParams& params); + GlComponent(std::shared_ptr 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 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(); }; diff --git a/include/uui/opengl/container.hpp b/include/uui/opengl/container.hpp new file mode 100644 index 0000000..8deaf6d --- /dev/null +++ b/include/uui/opengl/container.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +#include +#include +#include + +#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 diff --git a/include/uui/opengl/container_interface.hpp b/include/uui/opengl/container_interface.hpp new file mode 100644 index 0000000..e068ffa --- /dev/null +++ b/include/uui/opengl/container_interface.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include +#include + +#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 get_child_position(const std::size_t child_index [[maybe_unused]]) const override; + +protected: + virtual std::size_t push_child(std::shared_ptr child) final; + std::size_t push_child(std::shared_ptr child); + virtual std::shared_ptr get_child(std::size_t index) const final; + virtual void remove_child(std::size_t index) final; + + virtual ~GlContainerInterface(); + + std::vector> components; +}; +} // namespace uui diff --git a/include/uui/opengl/flex.hpp b/include/uui/opengl/flex.hpp new file mode 100644 index 0000000..975d30c --- /dev/null +++ b/include/uui/opengl/flex.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include +#include +#include + +#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 window, std::size_t window_index, std::shared_ptr parent, + std::size_t parent_index, const StackParams& params); + GlFlex(std::shared_ptr window, std::size_t window_index, const StackParams& params): + GlFlex(window, window_index, nullptr, 0, params) + {} + + std::tuple get_child_position(const std::size_t child_index) const override; +}; + +} // namespace uui diff --git a/include/uui/opengl/font_manager.hpp b/include/uui/opengl/font_manager.hpp index 07184a5..e797f1b 100644 --- a/include/uui/opengl/font_manager.hpp +++ b/include/uui/opengl/font_manager.hpp @@ -5,64 +5,32 @@ #include #include -#include -#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 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& text_color); - std::tuple get_text_size(const std::string& text, Font& font, float scale_x, float scale_y); + const std::string& text, Font& font, float x, float y, float scale_x, float scale_y, + const std::tuple& text_color) final; + std::tuple 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 diff --git a/include/graphic_context.hpp b/include/uui/opengl/graphic_context.hpp similarity index 65% rename from include/graphic_context.hpp rename to include/uui/opengl/graphic_context.hpp index 800a70d..037f696 100644 --- a/include/graphic_context.hpp +++ b/include/uui/opengl/graphic_context.hpp @@ -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 #define GLM_FORCE_RADIANS @@ -11,3 +12,8 @@ #include #include // clang-format off + +namespace GlConfig +{ + constexpr unsigned int FONT_TEXTURE_UNIT = GL_TEXTURE0; +} diff --git a/include/uui/opengl/label.hpp b/include/uui/opengl/label.hpp index fcb1d24..266b615 100644 --- a/include/uui/opengl/label.hpp +++ b/include/uui/opengl/label.hpp @@ -3,18 +3,20 @@ #include #include +#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 window, const std::variant x, const std::variant y, const std::string& text, - const std::tuple& text_color); + std::shared_ptr window, std::size_t window_index, std::shared_ptr parent, + std::size_t parent_index, const LabelParams& params); + GlLabel(std::shared_ptr window, std::size_t window_index, const LabelParams& params): + GlLabel(window, window_index, nullptr, 0, params) + {} - void render(); + void render() final; }; } // namespace uui diff --git a/include/uui/opengl/stack.hpp b/include/uui/opengl/stack.hpp new file mode 100644 index 0000000..52310c4 --- /dev/null +++ b/include/uui/opengl/stack.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include + +#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 init) override; + void create_label(const StackLabelParams& params, InitFunction