#ifndef YAZE_APP_GUI_ZEML_H #define YAZE_APP_GUI_ZEML_H #include #include #include #include #include #include #include "imgui/imgui.h" namespace yaze { namespace gui { /** * @namespace yaze::gui::zeml * @brief Zelda Editor Markup Language Functions */ namespace zeml { /** * @enum TokenType */ enum class TokenType { Identifier, String, OpenBrace, CloseBrace, Comma, EndOfStream }; /** * @struct Token */ struct Token { TokenType type; std::string value; } typedef Token; /** * @enum WidgetType */ enum class WidgetType { Window, Button, Slider, Text, Table, TableSetupColumn, TableHeadersRow, TableNextColumn, CollapsingHeader, Columns, Checkbox, Selectable, Function, BeginChild, BeginMenuBar, BeginMenu, BeginTabBar, BeginTabItem, MenuItem, Separator, HexInputByte, HexInputWord, Canvas, Definition, }; /** * @struct WidgetAttributes * @brief Attributes for a widget * @details id, title, min, max, value, text, count, size, flags, data * @details id: unique identifier for the widget * @details title: title for the widget * @details text: text for the widget * @details min: minimum value for the widget * @details max: maximum value for the widget * @details value: value for the widget * @details count: number of columns * @details size: size of the widget * @details flags: flags for the widget * @details data: data to be binded using the data_binding map */ struct WidgetAttributes { std::string id; std::string title; // For Window, Button std::string text; // For Text, Button double min; // For Slider double max; // For Slider double value; // For Slidecar float width; // For Columns int count = 0; // For Columns ImVec2 size = ImVec2(0, 0); // For BeginChild bool* selected = nullptr; // For Selectable std::shared_ptr flags = nullptr; // For Various void* data = nullptr; // For Various }; /** * @enum ActionType */ enum class ActionType { Click, Change, Run }; /** * @struct Action */ struct Action { ActionType type; std::function callback; }; /** * @brief Tokenize a zeml string */ std::vector Tokenize(const std::string& input); /** * @struct Node * @brief Node for a zeml tree */ struct Node { WidgetType type; WidgetAttributes attributes; std::vector actions; std::vector children; Node* parent = nullptr; Node* GetNode(const std::string& searchId) { if (attributes.id == searchId) { return this; } for (Node& child : children) { Node* found = child.GetNode(searchId); if (found != nullptr) { return found; } } return nullptr; } }; /** * @brief Bind a callback to a node */ void Bind(Node* node, std::function callback); /** * @brief Bind an action to a node */ void BindAction(Node* node, ActionType type, std::function callback); /** * @brief Bind a selectable node */ void BindSelectable(Node* node, bool* selected, std::function callback); /** * @brief Map a string to a widget type */ WidgetType MapType(const std::string& type); void ParseFlags(const WidgetType& type, const std::string& flags, WidgetAttributes& flags_ptr); /** * @brief ParseNode attributes for a widget */ WidgetAttributes ParseAttributes( const std::vector& tokens, size_t& index, const WidgetType& type, const std::map& data_bindings = {}); /** * @brief Parse a zeml node */ Node ParseNode(const std::vector& tokens, size_t& index, const std::map& data_bindings = {}, const std::map& definitions = {}); /** * @brief Parse a zeml string */ Node Parse(const std::string& yazon_input, const std::map& data_bindings = {}); /** * @brief Render a zeml tree */ void Render(Node& node); /** * @brief Execute actions for a node */ void ExecuteActions(const std::vector& actions, ActionType type); std::string LoadFile(const std::string& filename); } // namespace zeml } // namespace gui } // namespace yaze #endif // YAZE_APP_GUI_ZEML_H