#pragma once #include "cru/common/base.hpp" #include "base.hpp" #include "cru/platform/native/basic_types.hpp" #include "event/ui_event.hpp" #include #include namespace cru::ui { class Window; namespace render { class RenderObject; } // namespace render 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 std::wstring_view 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. event::RoutedEvent* MouseEnterEvent() { return &mouse_enter_event_; } // Raised when mouse is leave the control. event::RoutedEvent* MouseLeaveEvent() { return &mouse_leave_event_; } // Raised when mouse is move in the control. event::RoutedEvent* MouseMoveEvent() { return &mouse_move_event_; } // Raised when a mouse button is pressed in the control. event::RoutedEvent* MouseDownEvent() { return &mouse_down_event_; } // Raised when a mouse button is released in the control. event::RoutedEvent* MouseUpEvent() { return &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. event::RoutedEvent* MouseClickEvent() { return &mouse_click_event_; } event::RoutedEvent* MouseWheelEvent() { return &mouse_wheel_event_; } event::RoutedEvent* KeyDownEvent() { return &key_down_event_; } event::RoutedEvent* KeyUpEvent() { return &key_up_event_; } // event::RoutedEvent* CharEvent() { // return &char_event_; // } event::RoutedEvent* GainFocusEvent() { return &gain_focus_event_; } event::RoutedEvent* LoseFocusEvent() { return &lose_focus_event_; } private: event::RoutedEvent mouse_enter_event_; event::RoutedEvent mouse_leave_event_; event::RoutedEvent mouse_move_event_; event::RoutedEvent mouse_down_event_; event::RoutedEvent mouse_up_event_; event::RoutedEvent mouse_click_event_; event::RoutedEvent mouse_wheel_event_; event::RoutedEvent key_down_event_; event::RoutedEvent key_up_event_; // event::RoutedEvent char_event_; event::RoutedEvent gain_focus_event_; event::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(platform::native::MouseButton button); virtual void OnMouseClickEnd(platform::native::MouseButton button); private: Window* window_ = nullptr; Control* parent_ = nullptr; }; } // namespace cru::ui