#pragma once #include "event.h" enum class kAttribute : uint16_t { id = const_hash("id"), Width = const_hash("width"), MinWidth = const_hash("min-width"), MaxWidth = const_hash("max-width"), Height = const_hash("height"), MinHeight = const_hash("min-height"), MaxHeight = const_hash("max-height"), Divisions = const_hash("divisions"), InnerRadius = const_hash("inner-radius"), OuterRadius = const_hash("outer-radius"), Grow = const_hash("grow"), Shrink = const_hash("shrink"), FlexDir = const_hash("dir"), FlexWrap = const_hash("wrap"), Padding = const_hash("pad"), Margin = const_hash("margin"), Color = const_hash("color"), Thickness = const_hash("thickness"), BorderColor = const_hash("border-color"), Type = const_hash("type"), Text = const_hash("text"), FontFace = const_hash("font-face"), FontSize = const_hash("font-size"), Justify = const_hash("justify"), Align = const_hash("align"), Path = const_hash("path"), Region = const_hash("region"), Position = const_hash("position"), Positioning = const_hash("positioning"), FloodEvents = const_hash("flood-events"), Icon = const_hash("icon"), Selected = const_hash("selected"), Template = const_hash("template"), Value = const_hash("value"), Range = const_hash("range"), }; enum class kWidget : uint16_t { Node = const_hash("node"), Border = const_hash("border"), Shape = const_hash("shape"), Text = const_hash("text"), TextInput = const_hash("text-input"), Image = const_hash("image"), ImageTexture = const_hash("image-texture"), Icon = const_hash("icon"), Button = const_hash("button"), ButtonCustom = const_hash("button-custom"), SliderH = const_hash("slider-h"), SliderV = const_hash("slider-v"), SliderHue = const_hash("slider-hue"), PopupMenu = const_hash("popup-menu"), Viewport = const_hash("viewport"), Ref = const_hash("ref"), CheckBox = const_hash("checkbox"), Layer = const_hash("layer"), PanelLayer = const_hash("panel-layer"), PanelBrush = const_hash("panel-brush"), PanelColor = const_hash("panel-color"), PanelStroke = const_hash("panel-stroke"), ColorQuad = const_hash("color-quad"), StrokePreview = const_hash("stroke-preview"), Canvas = const_hash("canvas"), Scroll = const_hash("scroll"), }; class Node { friend class LayoutManager; public: Node* parent{ nullptr }; YGNodeRef y_node{ nullptr }; class LayoutManager* m_manager; uint16_t m_nodeID; std::string m_nodeID_s; std::vector> m_children; Node* current_mouse_capture = nullptr; Node* current_key_capture = nullptr; bool m_mouse_captured = false; bool m_key_captured = false; glm::mat4 m_proj; glm::mat4 m_mvp; bool m_mouse_inside = false; bool m_flood_events = false; bool m_capture_children = true; // wether to capture children events when xx_capture() is used bool m_destroyed = false; bool m_mouse_ignore = true; float m_zoom = 1.f; glm::vec2 m_scale{ 1.f }; glm::vec2 m_pos; glm::vec2 m_pos_origin; // original layout position without offset glm::vec2 m_pos_offset; // artificial position offset for scrolling glm::vec2 m_pos_offset_childred; // artificial position offset for scrolling glm::vec2 m_size; glm::vec4 m_clip; glm::vec4 m_clip_uncut; std::string m_name; bool m_display = true; Node(const Node&) = delete; Node& operator=(const Node&) = delete; Node&& operator=(Node&& o); Node(Node&& o); Node(); ~Node(); void SetWidth(float value); void SetWidthP(float value); void SetHeight(float value); void SetHeightP(float value); void SetSize(glm::vec2 value); void SetSize(float w, float h); void SetPadding(float t, float r, float b, float l); glm::vec4 GetPadding() const; void SetPosition(float l, float t, float r, float b); void SetPosition(float l, float t); void SetPosition(const glm::vec2 pos); void SetFlexGrow(float value); void SetFlexShrink(float value); void SetFlexDir(YGFlexDirection value); void SetFlexWrap(YGWrap value); void SetJustify(YGJustify value); void SetAlign(YGAlign value); void SetPositioning(YGPositionType value); void SetAspectRatio(float ar); glm::vec2 GetPosition(); float GetWidth(); float GetHeight(); glm::vec2 GetSize(); glm::vec4 rect_intersection(glm::vec4 a, glm::vec4 b) const; glm::vec4 rect_union(glm::vec4 a, glm::vec4 b) const; virtual void restore_context();; virtual void clear_context(); void update(float width, float height, float zoom); void update(); void update_internal(const glm::vec2& origin, const glm::mat4& proj); virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr); void load_internal(const tinyxml2::XMLElement* x_node); virtual void draw(); Node* clone(); virtual Node* clone_instantiate() const; virtual void clone_copy(Node* dest) const; virtual void clone_children(Node* dest) const; virtual void clone_finalize(Node* dest) const;; void watch(std::function observer); void destroy(); Node* root(); template T* find(const char* ids) { uint16_t id = const_hash(ids); if (id == m_nodeID) return static_cast(this); for (auto& c : m_children) if (auto found = c->find(ids)) return static_cast(found); return nullptr; } virtual kEventResult on_event(Event* e); virtual kEventResult handle_event(Event* e); virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size);; virtual void create(); virtual void init(); virtual void loaded(); const Node* init_template(const char* id); void add_child(Node* n); void add_child(Node* n, int index); void add_child(std::shared_ptr n); void add_child(std::shared_ptr n, int index); void remove_child(Node* n); void remove_all_children(); void move_child(Node* n, int index); void move_child_offset(Node* n, int offset); int get_child_index(Node* n); Node* get_child_at(int index); glm::vec4 get_children_rect() const; void mouse_capture(); void mouse_release(); void key_capture(); void key_release(); };