#pragma once #include "Renderer.h" #include "TextureManager.h" #include "Environment.h" #include "external/nlohmann/json.hpp" #include #include #include #include namespace ZL { using json = nlohmann::json; struct UiRect { float x = 0; float y = 0; float w = 0; float h = 0; bool contains(float px, float py) const { return px >= x && px <= x + w && py >= y && py <= y + h; } }; enum class ButtonState { Normal, Hover, Pressed }; struct UiButton { std::string name; UiRect rect; std::shared_ptr texNormal; std::shared_ptr texHover; std::shared_ptr texPressed; ButtonState state = ButtonState::Normal; VertexRenderStruct mesh; std::function onClick; void buildMesh(); void draw(Renderer& renderer) const; }; struct UiNode { std::string type; UiRect rect; std::string name; std::vector> children; std::shared_ptr button; std::string orientation = "vertical"; float spacing = 0.0f; }; class UiManager { public: UiManager() = default; void loadFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile = ""); void draw(Renderer& renderer); void onMouseMove(int x, int y); void onMouseDown(int x, int y); void onMouseUp(int x, int y); std::shared_ptr findButton(const std::string& name); bool setButtonCallback(const std::string& name, std::function cb); bool pushMenuFromFile(const std::string& path, Renderer& renderer, const std::string& zipFile = ""); bool popMenu(); void clearMenuStack(); private: std::shared_ptr parseNode(const json& j, Renderer& renderer, const std::string& zipFile); void layoutNode(const std::shared_ptr& node); void collectButtons(const std::shared_ptr& node); std::shared_ptr root; std::vector> buttons; std::shared_ptr pressedButton; struct MenuState { std::shared_ptr root; std::vector> buttons; std::shared_ptr pressedButton; std::string path; }; std::vector menuStack; }; } // namespace ZL