#pragma once #include "delegates.hpp" #include #include #include #include #include #include class DrawContext; class Assets; class Camera; class Batch2D; struct CursorState; class Engine; class Input; class Window; namespace devtools { class Editor; } /* Some info about padding and margin. Padding is element inner space, margin is outer glm::vec4 usage: x - left y - top z - right w - bottom Outer element +======================================================================+ | . . . . | | .padding.y . . . | | padding.x . . . . padding.z | |- - - - - - + - - - - - + - - - - - - - - - -+- - - - - + - - - - - - | | . . . . | | . .margin.y . . | | .margin.x . . margin.z. | |- - - - - - + - - - - - +====================+- - - - - + - - - - - - | | . | Inner element | . | |- - - - - - + - - - - - +====================+- - - - - + - - - - - - | | . . . . | | . .margin.w . . | | . . . . | |- - - - - - + - - - - - + - - - - - - - - - -+- - - - - + - - - - - - | | . . . . | | .padding.w . . . | | . . . . | +======================================================================+ */ namespace gui { class UINode; class Container; class Menu; using PageLoaderFunc = std::function(const std::string&)>; /// @brief The main UI controller class GUI { Engine& engine; Input& input; std::unique_ptr batch2D; std::shared_ptr container; std::shared_ptr hover; std::shared_ptr pressed; std::shared_ptr focus; std::shared_ptr tooltip; std::unordered_map> storage; std::unique_ptr uicamera; std::shared_ptr menu; std::queue postRunnables; PageLoaderFunc pagesLoader; float tooltipTimer = 0.0f; float doubleClickTimer = 0.0f; float doubleClickDelay = 0.5f; bool doubleClicked = false; bool debug = false; void actMouse(float delta, const CursorState& cursor); void actFocused(); void updateTooltip(float delta); void resetTooltip(); public: GUI(Engine& engine); ~GUI(); void setPageLoader(PageLoaderFunc pageLoader); PageLoaderFunc getPagesLoader(); /// @brief Get the main menu (Menu) node std::shared_ptr getMenu(); /// @brief Get current focused node /// @return focused node or nullptr std::shared_ptr getFocused() const; /// @brief Check if all user input is caught by some element like TextBox bool isFocusCaught() const; /// @brief Main input handling and logic update method /// @param delta delta time /// @param viewport window size void act(float delta, const glm::uvec2& viewport); /// @brief Draw all visible elements on main container /// @param pctx parent graphics context /// @param assets active assets storage void draw(const DrawContext& pctx, const Assets& assets); void postAct(); /// @brief Add element to the main container /// @param node UI element void add(std::shared_ptr node); /// @brief Remove node from the main container void remove(UINode* node) noexcept; void remove(const std::shared_ptr& node) noexcept { return remove(node.get()); } /// @brief Store node in the GUI nodes dictionary /// (does not add node to the main container) /// @param name node key /// @param node target node void store(const std::string& name, std::shared_ptr node); /// @brief Get node from the GUI nodes dictionary /// @param name node key /// @return stored node or nullptr std::shared_ptr get(const std::string& name) noexcept; /// @brief Remove node from the GUI nodes dictionary /// @param name node key void remove(const std::string& name) noexcept; /// @brief Set node as focused /// @param node new focused node or nullptr to remove focus void setFocus(std::shared_ptr node); /// @brief Get the main container /// @deprecated std::shared_ptr getContainer() const; void onAssetsLoad(Assets* assets); void postRunnable(const runnable& callback); void setDoubleClickDelay(float delay); float getDoubleClickDelay() const; void toggleDebug(); const Input& getInput() const; Input& getInput(); Window& getWindow(); devtools::Editor& getEditor(); }; }