aboutsummaryrefslogtreecommitdiff
path: root/src/ui/control.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/control.h')
-rw-r--r--src/ui/control.h691
1 files changed, 344 insertions, 347 deletions
diff --git a/src/ui/control.h b/src/ui/control.h
index 9ee657f7..020f959e 100644
--- a/src/ui/control.h
+++ b/src/ui/control.h
@@ -14,435 +14,432 @@
#include "border_property.h"
#include "cursor.h"
-namespace cru
+namespace cru::ui
{
- namespace ui
- {
- class Control;
- class Window;
+ class Control;
+ class Window;
- //the position cache
- struct ControlPositionCache
- {
- //The lefttop relative to the ancestor.
- Point lefttop_position_absolute;
- };
+ //the position cache
+ struct ControlPositionCache
+ {
+ //The lefttop relative to the ancestor.
+ Point lefttop_position_absolute;
+ };
- class Control : public Object
- {
- friend class Window;
- friend class LayoutManager;
+ class Control : public Object
+ {
+ friend class Window;
+ friend class LayoutManager;
- protected:
- struct WindowConstructorTag {}; //Used for constructor for class Window.
+ protected:
+ struct WindowConstructorTag {}; //Used for constructor for class Window.
- explicit Control(bool container = false);
+ explicit Control(bool container = false);
- // Used only for creating Window. It will set window_ as window.
- Control(WindowConstructorTag, Window* window);
+ // Used only for creating Window. It will set window_ as window.
+ Control(WindowConstructorTag, Window* window);
- public:
- Control(const Control& other) = delete;
- Control(Control&& other) = delete;
- Control& operator=(const Control& other) = delete;
- Control& operator=(Control&& other) = delete;
- ~Control() override;
+ public:
+ Control(const Control& other) = delete;
+ Control(Control&& other) = delete;
+ Control& operator=(const Control& other) = delete;
+ Control& operator=(Control&& other) = delete;
+ ~Control() override;
- public:
+ public:
- //*************** region: tree ***************
- virtual StringView GetControlType() const = 0;
+ //*************** region: tree ***************
+ virtual StringView GetControlType() const = 0;
- bool IsContainer() const
- {
- return is_container_;
- }
+ bool IsContainer() const
+ {
+ return is_container_;
+ }
- //Get parent of control, return nullptr if it has no parent.
- Control* GetParent() const
- {
- return parent_;
- }
+ //Get parent of control, return nullptr if it has no parent.
+ Control* GetParent() const
+ {
+ return parent_;
+ }
- //Return a immutable vector of all children.
- const std::vector<Control*>& GetChildren() const;
+ //Return a immutable vector of all children.
+ const std::vector<Control*>& GetChildren() const;
- //Add a child at tail.
- void AddChild(Control* control);
+ //Add a child at tail.
+ void AddChild(Control* control);
- //Add a child before the position.
- void AddChild(Control* control, int position);
+ //Add a child before the position.
+ void AddChild(Control* control, int position);
- //Remove a child.
- void RemoveChild(Control* child);
+ //Remove a child.
+ void RemoveChild(Control* child);
- //Remove a child at specified position.
- void RemoveChild(int position);
+ //Remove a child at specified position.
+ void RemoveChild(int position);
- //Get the ancestor of the control.
- Control* GetAncestor();
+ //Get the ancestor of the control.
+ Control* GetAncestor();
- //Get the window if attached, otherwise, return nullptr.
- Window* GetWindow() const
- {
- return window_;
- }
+ //Get the window if attached, otherwise, return nullptr.
+ Window* GetWindow() const
+ {
+ return window_;
+ }
- //Traverse the tree rooted the control including itself.
- void TraverseDescendants(const std::function<void(Control*)>& predicate);
+ //Traverse the tree rooted the control including itself.
+ void TraverseDescendants(const std::function<void(Control*)>& predicate);
- //*************** region: position and size ***************
- // Position and size part must be isolated from layout part.
- // All the operations in this part must be done independently.
- // And layout part must use api of this part.
+ //*************** region: position and size ***************
+ // Position and size part must be isolated from layout part.
+ // All the operations in this part must be done independently.
+ // And layout part must use api of this part.
- //Get the lefttop relative to its parent.
- virtual Point GetPositionRelative();
+ //Get the lefttop relative to its parent.
+ virtual Point GetPositionRelative();
- //Set the lefttop relative to its parent.
- virtual void SetPositionRelative(const Point& position);
+ //Set the lefttop relative to its parent.
+ virtual void SetPositionRelative(const Point& position);
- //Get the actual size.
- virtual Size GetSize();
+ //Get the actual size.
+ virtual Size GetSize();
- //Set the actual size directly without re-layout.
- virtual void SetSize(const Size& size);
+ //Set the actual size directly without re-layout.
+ virtual void SetSize(const Size& size);
- //Get lefttop relative to ancestor. This is only valid when
- //attached to window. Notice that the value is cached.
- //You can invalidate and recalculate it by calling "InvalidatePositionCache".
- Point GetPositionAbsolute() const;
+ //Get lefttop relative to ancestor. This is only valid when
+ //attached to window. Notice that the value is cached.
+ //You can invalidate and recalculate it by calling "InvalidatePositionCache".
+ Point GetPositionAbsolute() const;
- //Local point to absolute point.
- Point ControlToWindow(const Point& point) const;
+ //Local point to absolute point.
+ Point ControlToWindow(const Point& point) const;
- //Absolute point to local point.
- Point WindowToControl(const Point& point) const;
+ //Absolute point to local point.
+ Point WindowToControl(const Point& point) const;
- virtual bool IsPointInside(const Point& point);
+ virtual bool IsPointInside(const Point& point);
- //*************** region: graphic ***************
+ //*************** region: graphic ***************
- //Draw this control and its child controls.
- void Draw(ID2D1DeviceContext* device_context);
+ //Draw this control and its child controls.
+ void Draw(ID2D1DeviceContext* device_context);
- virtual void Repaint();
+ virtual void Repaint();
- //*************** region: focus ***************
+ //*************** region: focus ***************
- bool RequestFocus();
+ bool RequestFocus();
- bool HasFocus();
+ bool HasFocus();
- bool IsFocusOnPressed() const
- {
- return is_focus_on_pressed_;
- }
+ bool IsFocusOnPressed() const
+ {
+ return is_focus_on_pressed_;
+ }
- void SetFocusOnPressed(const bool value)
- {
- is_focus_on_pressed_ = value;
- }
+ void SetFocusOnPressed(const bool value)
+ {
+ is_focus_on_pressed_ = value;
+ }
- //*************** region: layout ***************
+ //*************** region: layout ***************
- void InvalidateLayout();
+ void InvalidateLayout();
- void Measure(const Size& available_size);
+ void Measure(const Size& available_size);
- void Layout(const Rect& rect);
+ void Layout(const Rect& rect);
- Size GetDesiredSize() const;
+ Size GetDesiredSize() const;
- void SetDesiredSize(const Size& desired_size);
+ void SetDesiredSize(const Size& desired_size);
- BasicLayoutParams* GetLayoutParams()
- {
- return &layout_params_;
- }
+ BasicLayoutParams* GetLayoutParams()
+ {
+ return &layout_params_;
+ }
- Rect GetRect(RectRange range);
+ Rect GetRect(RectRange range);
- Point TransformPoint(const Point& point, RectRange from = RectRange::Margin, RectRange to = RectRange::Content);
+ Point TransformPoint(const Point& point, RectRange from = RectRange::Margin, RectRange to = RectRange::Content);
- //*************** region: border ***************
+ //*************** region: border ***************
- BorderProperty& GetBorderProperty()
- {
- return border_property_;
- }
+ BorderProperty& GetBorderProperty()
+ {
+ return border_property_;
+ }
- void InvalidateBorder();
+ void InvalidateBorder();
- bool IsBordered() const
- {
- return is_bordered_;
- }
+ bool IsBordered() const
+ {
+ return is_bordered_;
+ }
- void SetBordered(bool bordered);
+ void SetBordered(bool bordered);
- //*************** region: additional properties ***************
- template <typename T>
- std::optional<T> GetAdditionalProperty(const String& key)
+ //*************** region: additional properties ***************
+ template <typename T>
+ std::optional<T> GetAdditionalProperty(const String& key)
+ {
+ try
{
- try
- {
- const auto find_result = additional_properties_.find(key);
- if (find_result != additional_properties_.cend())
- return std::any_cast<T>(find_result->second);
- else
- return std::nullopt;
- }
- catch (const std::bad_any_cast&)
- {
- throw std::runtime_error(Format("Key \"{}\" is not of the type {}.", ToUtf8String(key), typeid(T).name()));
- }
+ const auto find_result = additional_properties_.find(key);
+ if (find_result != additional_properties_.cend())
+ return std::any_cast<T>(find_result->second);
+ else
+ return std::nullopt;
}
-
- template <typename T>
- void SetAdditionalProperty(const String& key, const T& value)
+ catch (const std::bad_any_cast&)
{
- additional_properties_[key] = std::make_any<T>(value);
+ throw std::runtime_error(Format("Key \"{}\" is not of the type {}.", ToUtf8String(key), typeid(T).name()));
}
+ }
- template <typename T>
- void SetAdditionalProperty(const String& key, T&& value)
- {
- additional_properties_[key] = std::make_any<T>(std::move(value));
- }
+ template <typename T>
+ void SetAdditionalProperty(const String& key, const T& value)
+ {
+ additional_properties_[key] = std::make_any<T>(value);
+ }
-
- //*************** region: cursor ***************
- // If cursor is set to null, then it uses parent's cursor.
- // Window's cursor can't be null.
+ template <typename T>
+ void SetAdditionalProperty(const String& key, T&& value)
+ {
+ additional_properties_[key] = std::make_any<T>(std::move(value));
+ }
- Cursor::Ptr GetCursor() const
- {
- return cursor_;
- }
+
+ //*************** region: cursor ***************
+ // If cursor is set to null, then it uses parent's cursor.
+ // Window's cursor can't be null.
- void SetCursor(const Cursor::Ptr& cursor);
-
-
- //*************** region: events ***************
- //Raised when mouse enter the control.
- events::MouseEvent mouse_enter_event;
- //Raised when mouse is leave the control.
- events::MouseEvent mouse_leave_event;
- //Raised when mouse is move in the control.
- events::MouseEvent mouse_move_event;
- //Raised when a mouse button is pressed in the control.
- events::MouseButtonEvent mouse_down_event;
- //Raised when a mouse button is released in the control.
- events::MouseButtonEvent 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::MouseButtonEvent mouse_click_event;
-
- events::KeyEvent key_down_event;
- events::KeyEvent key_up_event;
- events::CharEvent char_event;
-
- events::FocusChangeEvent get_focus_event;
- events::FocusChangeEvent lose_focus_event;
-
- events::DrawEvent draw_event;
-
- events::PositionChangedEvent position_changed_event;
- events::SizeChangedEvent size_changed_event;
-
- protected:
- //Invoked when a child is added. Overrides should invoke base.
- virtual void OnAddChild(Control* child);
- //Invoked when a child is removed. Overrides should invoke base.
- virtual void OnRemoveChild(Control* child);
-
- //Invoked when the control is attached to a window. Overrides should invoke base.
- virtual void OnAttachToWindow(Window* window);
- //Invoked when the control is detached to a window. Overrides should invoke base.
- virtual void OnDetachToWindow(Window* window);
-
- private:
- void OnDraw(ID2D1DeviceContext* device_context);
-
- protected:
- virtual void OnDrawContent(ID2D1DeviceContext* device_context);
-
- // For a event, the window event system will first dispatch event to core functions.
- // Therefore for particular controls, you should do essential actions in core functions,
- // and override version should invoke base version. The base core function
- // in "Control" class will call corresponding non-core function and call "Raise" on
- // event objects. So user custom actions should be done by overriding non-core function
- // and calling the base version is optional.
-
- //*************** region: position and size event ***************
- virtual void OnPositionChanged(events::PositionChangedEventArgs& args);
- virtual void OnSizeChanged(events::SizeChangedEventArgs& args);
-
- virtual void OnPositionChangedCore(events::PositionChangedEventArgs& args);
- virtual void OnSizeChangedCore(events::SizeChangedEventArgs& args);
-
- void RaisePositionChangedEvent(events::PositionChangedEventArgs& args);
- void RaiseSizeChangedEvent(events::SizeChangedEventArgs& args);
-
- //*************** region: mouse event ***************
- virtual void OnMouseEnter(events::MouseEventArgs& args);
- virtual void OnMouseLeave(events::MouseEventArgs& args);
- virtual void OnMouseMove(events::MouseEventArgs& args);
- virtual void OnMouseDown(events::MouseButtonEventArgs& args);
- virtual void OnMouseUp(events::MouseButtonEventArgs& args);
- virtual void OnMouseClick(events::MouseButtonEventArgs& args);
-
- virtual void OnMouseEnterCore(events::MouseEventArgs& args);
- virtual void OnMouseLeaveCore(events::MouseEventArgs& args);
- virtual void OnMouseMoveCore(events::MouseEventArgs& args);
- virtual void OnMouseDownCore(events::MouseButtonEventArgs& args);
- virtual void OnMouseUpCore(events::MouseButtonEventArgs& args);
- virtual void OnMouseClickCore(events::MouseButtonEventArgs& args);
-
- void RaiseMouseEnterEvent(events::MouseEventArgs& args);
- void RaiseMouseLeaveEvent(events::MouseEventArgs& args);
- void RaiseMouseMoveEvent(events::MouseEventArgs& args);
- void RaiseMouseDownEvent(events::MouseButtonEventArgs& args);
- void RaiseMouseUpEvent(events::MouseButtonEventArgs& args);
- void RaiseMouseClickEvent(events::MouseButtonEventArgs& args);
-
- virtual void OnMouseClickBegin(MouseButton button);
- virtual void OnMouseClickEnd(MouseButton button);
-
- //*************** region: keyboard event ***************
- virtual void OnKeyDown(events::KeyEventArgs& args);
- virtual void OnKeyUp(events::KeyEventArgs& args);
- virtual void OnChar(events::CharEventArgs& args);
-
- virtual void OnKeyDownCore(events::KeyEventArgs& args);
- virtual void OnKeyUpCore(events::KeyEventArgs& args);
- virtual void OnCharCore(events::CharEventArgs& args);
-
- void RaiseKeyDownEvent(events::KeyEventArgs& args);
- void RaiseKeyUpEvent(events::KeyEventArgs& args);
- void RaiseCharEvent(events::CharEventArgs& args);
-
- //*************** region: focus event ***************
- virtual void OnGetFocus(events::FocusChangeEventArgs& args);
- virtual void OnLoseFocus(events::FocusChangeEventArgs& args);
-
- virtual void OnGetFocusCore(events::FocusChangeEventArgs& args);
- virtual void OnLoseFocusCore(events::FocusChangeEventArgs& args);
-
- void RaiseGetFocusEvent(events::FocusChangeEventArgs& args);
- void RaiseLoseFocusEvent(events::FocusChangeEventArgs& args);
-
- //*************** region: layout ***************
- Size OnMeasureCore(const Size& available_size);
- void OnLayoutCore(const Rect& rect);
-
- virtual Size OnMeasureContent(const Size& available_size);
- virtual void OnLayoutContent(const Rect& rect);
-
- private:
- // Only for layout manager to use.
- // Check if the old position is updated to current position.
- // If not, then a notify of position change and update will
- // be done.
- void CheckAndNotifyPositionChanged();
-
- void ThrowIfNotContainer() const
- {
- if (!is_container_)
- throw std::runtime_error("You can't perform such operation on a non-container control.");
- }
+ Cursor::Ptr GetCursor() const
+ {
+ return cursor_;
+ }
- private:
- bool is_container_;
+ void SetCursor(const Cursor::Ptr& cursor);
+
+
+ //*************** region: events ***************
+ //Raised when mouse enter the control.
+ events::MouseEvent mouse_enter_event;
+ //Raised when mouse is leave the control.
+ events::MouseEvent mouse_leave_event;
+ //Raised when mouse is move in the control.
+ events::MouseEvent mouse_move_event;
+ //Raised when a mouse button is pressed in the control.
+ events::MouseButtonEvent mouse_down_event;
+ //Raised when a mouse button is released in the control.
+ events::MouseButtonEvent 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::MouseButtonEvent mouse_click_event;
+
+ events::KeyEvent key_down_event;
+ events::KeyEvent key_up_event;
+ events::CharEvent char_event;
+
+ events::FocusChangeEvent get_focus_event;
+ events::FocusChangeEvent lose_focus_event;
+
+ events::DrawEvent draw_event;
+
+ events::PositionChangedEvent position_changed_event;
+ events::SizeChangedEvent size_changed_event;
+
+ protected:
+ //Invoked when a child is added. Overrides should invoke base.
+ virtual void OnAddChild(Control* child);
+ //Invoked when a child is removed. Overrides should invoke base.
+ virtual void OnRemoveChild(Control* child);
+
+ //Invoked when the control is attached to a window. Overrides should invoke base.
+ virtual void OnAttachToWindow(Window* window);
+ //Invoked when the control is detached to a window. Overrides should invoke base.
+ virtual void OnDetachToWindow(Window* window);
+
+ private:
+ void OnDraw(ID2D1DeviceContext* device_context);
+
+ protected:
+ virtual void OnDrawContent(ID2D1DeviceContext* device_context);
+
+ // For a event, the window event system will first dispatch event to core functions.
+ // Therefore for particular controls, you should do essential actions in core functions,
+ // and override version should invoke base version. The base core function
+ // in "Control" class will call corresponding non-core function and call "Raise" on
+ // event objects. So user custom actions should be done by overriding non-core function
+ // and calling the base version is optional.
+
+ //*************** region: position and size event ***************
+ virtual void OnPositionChanged(events::PositionChangedEventArgs& args);
+ virtual void OnSizeChanged(events::SizeChangedEventArgs& args);
+
+ virtual void OnPositionChangedCore(events::PositionChangedEventArgs& args);
+ virtual void OnSizeChangedCore(events::SizeChangedEventArgs& args);
+
+ void RaisePositionChangedEvent(events::PositionChangedEventArgs& args);
+ void RaiseSizeChangedEvent(events::SizeChangedEventArgs& args);
+
+ //*************** region: mouse event ***************
+ virtual void OnMouseEnter(events::MouseEventArgs& args);
+ virtual void OnMouseLeave(events::MouseEventArgs& args);
+ virtual void OnMouseMove(events::MouseEventArgs& args);
+ virtual void OnMouseDown(events::MouseButtonEventArgs& args);
+ virtual void OnMouseUp(events::MouseButtonEventArgs& args);
+ virtual void OnMouseClick(events::MouseButtonEventArgs& args);
+
+ virtual void OnMouseEnterCore(events::MouseEventArgs& args);
+ virtual void OnMouseLeaveCore(events::MouseEventArgs& args);
+ virtual void OnMouseMoveCore(events::MouseEventArgs& args);
+ virtual void OnMouseDownCore(events::MouseButtonEventArgs& args);
+ virtual void OnMouseUpCore(events::MouseButtonEventArgs& args);
+ virtual void OnMouseClickCore(events::MouseButtonEventArgs& args);
+
+ void RaiseMouseEnterEvent(events::MouseEventArgs& args);
+ void RaiseMouseLeaveEvent(events::MouseEventArgs& args);
+ void RaiseMouseMoveEvent(events::MouseEventArgs& args);
+ void RaiseMouseDownEvent(events::MouseButtonEventArgs& args);
+ void RaiseMouseUpEvent(events::MouseButtonEventArgs& args);
+ void RaiseMouseClickEvent(events::MouseButtonEventArgs& args);
+
+ virtual void OnMouseClickBegin(MouseButton button);
+ virtual void OnMouseClickEnd(MouseButton button);
+
+ //*************** region: keyboard event ***************
+ virtual void OnKeyDown(events::KeyEventArgs& args);
+ virtual void OnKeyUp(events::KeyEventArgs& args);
+ virtual void OnChar(events::CharEventArgs& args);
+
+ virtual void OnKeyDownCore(events::KeyEventArgs& args);
+ virtual void OnKeyUpCore(events::KeyEventArgs& args);
+ virtual void OnCharCore(events::CharEventArgs& args);
+
+ void RaiseKeyDownEvent(events::KeyEventArgs& args);
+ void RaiseKeyUpEvent(events::KeyEventArgs& args);
+ void RaiseCharEvent(events::CharEventArgs& args);
+
+ //*************** region: focus event ***************
+ virtual void OnGetFocus(events::FocusChangeEventArgs& args);
+ virtual void OnLoseFocus(events::FocusChangeEventArgs& args);
+
+ virtual void OnGetFocusCore(events::FocusChangeEventArgs& args);
+ virtual void OnLoseFocusCore(events::FocusChangeEventArgs& args);
+
+ void RaiseGetFocusEvent(events::FocusChangeEventArgs& args);
+ void RaiseLoseFocusEvent(events::FocusChangeEventArgs& args);
+
+ //*************** region: layout ***************
+ Size OnMeasureCore(const Size& available_size);
+ void OnLayoutCore(const Rect& rect);
+
+ virtual Size OnMeasureContent(const Size& available_size);
+ virtual void OnLayoutContent(const Rect& rect);
+
+ private:
+ // Only for layout manager to use.
+ // Check if the old position is updated to current position.
+ // If not, then a notify of position change and update will
+ // be done.
+ void CheckAndNotifyPositionChanged();
+
+ void ThrowIfNotContainer() const
+ {
+ if (!is_container_)
+ throw std::runtime_error("You can't perform such operation on a non-container control.");
+ }
- protected:
- Window * window_ = nullptr; // protected for Window class to write it as itself in constructor.
+ private:
+ bool is_container_;
- private:
- Control * parent_ = nullptr;
- std::vector<Control*> children_{};
+ protected:
+ Window * window_ = nullptr; // protected for Window class to write it as itself in constructor.
- // When position is changed and notification hasn't been
- // sent, it will be the old position. When position is changed
- // more than once, it will be the oldest position since last
- // notification. If notification has been sent, it will be updated
- // to position_.
- Point old_position_ = Point::Zero();
- Point position_ = Point::Zero();
- Size size_ = Size::Zero();
+ private:
+ Control * parent_ = nullptr;
+ std::vector<Control*> children_{};
- ControlPositionCache position_cache_{};
+ // When position is changed and notification hasn't been
+ // sent, it will be the old position. When position is changed
+ // more than once, it will be the oldest position since last
+ // notification. If notification has been sent, it will be updated
+ // to position_.
+ Point old_position_ = Point::Zero();
+ Point position_ = Point::Zero();
+ Size size_ = Size::Zero();
- bool is_mouse_inside_ = false;
+ ControlPositionCache position_cache_{};
- std::unordered_map<MouseButton, bool> is_mouse_click_valid_map_
- {
- { MouseButton::Left, true },
- { MouseButton::Middle, true },
- { MouseButton::Right, true }
- }; // used for clicking determination
+ bool is_mouse_inside_ = false;
- BasicLayoutParams layout_params_{};
- Size desired_size_ = Size::Zero();
+ std::unordered_map<MouseButton, bool> is_mouse_click_valid_map_
+ {
+ { MouseButton::Left, true },
+ { MouseButton::Middle, true },
+ { MouseButton::Right, true }
+ }; // used for clicking determination
- bool is_bordered_ = false;
- BorderProperty border_property_;
+ BasicLayoutParams layout_params_{};
+ Size desired_size_ = Size::Zero();
- std::unordered_map<String, std::any> additional_properties_{};
+ bool is_bordered_ = false;
+ BorderProperty border_property_;
- bool is_focus_on_pressed_ = true;
+ std::unordered_map<String, std::any> additional_properties_{};
+
+ bool is_focus_on_pressed_ = true;
#ifdef CRU_DEBUG_LAYOUT
- Microsoft::WRL::ComPtr<ID2D1Geometry> margin_geometry_;
- Microsoft::WRL::ComPtr<ID2D1Geometry> padding_geometry_;
+ Microsoft::WRL::ComPtr<ID2D1Geometry> margin_geometry_;
+ Microsoft::WRL::ComPtr<ID2D1Geometry> padding_geometry_;
#endif
- Cursor::Ptr cursor_{};
- };
+ Cursor::Ptr cursor_{};
+ };
- // Find the lowest common ancestor.
- // Return nullptr if "left" and "right" are not in the same tree.
- Control* FindLowestCommonAncestor(Control* left, Control* right);
+ // Find the lowest common ancestor.
+ // Return nullptr if "left" and "right" are not in the same tree.
+ Control* FindLowestCommonAncestor(Control* left, Control* right);
- // Return the ancestor if one control is the ancestor of the other one, otherwise nullptr.
- Control* IsAncestorOrDescendant(Control* left, Control* right);
+ // Return the ancestor if one control is the ancestor of the other one, otherwise nullptr.
+ Control* IsAncestorOrDescendant(Control* left, Control* right);
- template <typename TControl, typename... Args>
- TControl* CreateWithLayout(const LayoutSideParams& width, const LayoutSideParams& height, Args&&... args)
- {
- static_assert(std::is_base_of_v<Control, TControl>, "TControl is not a control class.");
- TControl* control = TControl::Create(std::forward<Args>(args)...);
- control->GetLayoutParams()->width = width;
- control->GetLayoutParams()->height = height;
- return control;
- }
+ template <typename TControl, typename... Args>
+ TControl* CreateWithLayout(const LayoutSideParams& width, const LayoutSideParams& height, Args&&... args)
+ {
+ static_assert(std::is_base_of_v<Control, TControl>, "TControl is not a control class.");
+ TControl* control = TControl::Create(std::forward<Args>(args)...);
+ control->GetLayoutParams()->width = width;
+ control->GetLayoutParams()->height = height;
+ return control;
+ }
- template <typename TControl, typename... Args>
- TControl* CreateWithLayout(const Thickness& padding, const Thickness& margin, Args&&... args)
- {
- static_assert(std::is_base_of_v<Control, TControl>, "TControl is not a control class.");
- TControl* control = TControl::Create(std::forward<Args>(args)...);
- control->GetLayoutParams()->padding = padding;
- control->GetLayoutParams()->margin = margin;
- return control;
- }
-
- template <typename TControl, typename... Args>
- TControl* CreateWithLayout(const LayoutSideParams& width, const LayoutSideParams& height, const Thickness& padding, const Thickness& margin, Args&&... args)
- {
- static_assert(std::is_base_of_v<Control, TControl>, "TControl is not a control class.");
- TControl* control = TControl::Create(std::forward<Args>(args)...);
- control->GetLayoutParams()->width = width;
- control->GetLayoutParams()->height = height;
- control->GetLayoutParams()->padding = padding;
- control->GetLayoutParams()->margin = margin;
- return control;
- }
+ template <typename TControl, typename... Args>
+ TControl* CreateWithLayout(const Thickness& padding, const Thickness& margin, Args&&... args)
+ {
+ static_assert(std::is_base_of_v<Control, TControl>, "TControl is not a control class.");
+ TControl* control = TControl::Create(std::forward<Args>(args)...);
+ control->GetLayoutParams()->padding = padding;
+ control->GetLayoutParams()->margin = margin;
+ return control;
+ }
- using ControlList = std::initializer_list<Control*>;
+ template <typename TControl, typename... Args>
+ TControl* CreateWithLayout(const LayoutSideParams& width, const LayoutSideParams& height, const Thickness& padding, const Thickness& margin, Args&&... args)
+ {
+ static_assert(std::is_base_of_v<Control, TControl>, "TControl is not a control class.");
+ TControl* control = TControl::Create(std::forward<Args>(args)...);
+ control->GetLayoutParams()->width = width;
+ control->GetLayoutParams()->height = height;
+ control->GetLayoutParams()->padding = padding;
+ control->GetLayoutParams()->margin = margin;
+ return control;
}
+
+ using ControlList = std::initializer_list<Control*>;
}