#pragma once #include "pre.hpp" #include "base.hpp" #include "events/ui_event.hpp" #include "ui_base.hpp" namespace cru::ui { class Window; namespace render { class RenderObject; } class Control : public Object { friend class Window; protected: Control() = default; public: Control(const Control& other) = delete; Control(Control&& other) = delete; Control& operator=(const Control& other) = delete; Control& operator=(Control&& other) = delete; ~Control() override = default; public: virtual StringView GetControlType() const = 0; //*************** region: tree *************** public: // Get the window if attached, otherwise, return nullptr. Window* GetWindow() const { return window_; } Control* GetParent() const { return parent_; } virtual const std::vector& GetChildren() const = 0; // Traverse the tree rooted the control including itself. void TraverseDescendants(const std::function& predicate); void _SetParent(Control* parent); void _SetDescendantWindow(Window* window); private: static void _TraverseDescendants( Control* control, const std::function& predicate); public: virtual render::RenderObject* GetRenderObject() const = 0; //*************** region: focus *************** public: bool RequestFocus(); bool HasFocus(); //*************** region: events *************** public: // Raised when mouse enter the control. events::RoutedEvent mouse_enter_event; // Raised when mouse is leave the control. events::RoutedEvent mouse_leave_event; // Raised when mouse is move in the control. events::RoutedEvent mouse_move_event; // Raised when a mouse button is pressed in the control. events::RoutedEvent mouse_down_event; // Raised when a mouse button is released in the control. events::RoutedEvent mouse_up_event; // Raised when a mouse button is pressed in the control and released in the // control with mouse not leaving it between two operations. events::RoutedEvent mouse_click_event; events::RoutedEvent mouse_wheel_event; events::RoutedEvent key_down_event; events::RoutedEvent key_up_event; events::RoutedEvent char_event; events::RoutedEvent get_focus_event; events::RoutedEvent lose_focus_event; //*************** region: tree *************** protected: virtual void OnParentChanged(Control* old_parent, Control* new_parent); virtual void OnAttachToWindow(Window* window); virtual void OnDetachToWindow(Window* window); //*************** region: additional mouse event *************** protected: virtual void OnMouseClickBegin(MouseButton button); virtual void OnMouseClickEnd(MouseButton button); private: Window* window_ = nullptr; Control* parent_ = nullptr; }; } // namespace cru::ui