aboutsummaryrefslogtreecommitdiff
path: root/src/ui/control.hpp
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2019-03-19 16:21:54 +0800
committercrupest <crupest@outlook.com>2019-03-19 16:21:54 +0800
commit5dc738a57930271194bd86673eb86f149096a7b2 (patch)
tree71174aba0d1c0918cc7d7a1be0b86ec0d5c20401 /src/ui/control.hpp
parent06edefebe8dfb138404397fb2c46732da6cd733a (diff)
downloadcru-5dc738a57930271194bd86673eb86f149096a7b2.tar.gz
cru-5dc738a57930271194bd86673eb86f149096a7b2.tar.bz2
cru-5dc738a57930271194bd86673eb86f149096a7b2.zip
...
Diffstat (limited to 'src/ui/control.hpp')
-rw-r--r--src/ui/control.hpp301
1 files changed, 44 insertions, 257 deletions
diff --git a/src/ui/control.hpp b/src/ui/control.hpp
index 6abcc365..8e69fb07 100644
--- a/src/ui/control.hpp
+++ b/src/ui/control.hpp
@@ -12,49 +12,21 @@
#include "ui_base.hpp"
#include "layout_base.hpp"
#include "events/ui_event.hpp"
-#include "border_property.hpp"
#include "cursor.hpp"
#include "any_map.hpp"
+#include "input_util.hpp"
namespace cru::ui
{
class Window;
- struct AdditionalMeasureInfo
- {
- bool horizontal_stretchable = true;
- bool vertical_stretchable = true;
- };
-
- struct AdditionalLayoutInfo
- {
- Point total_offset = Point::Zero();
- };
-
- //the position cache
- struct ControlPositionCache
- {
- //The lefttop relative to the ancestor.
- Point lefttop_position_absolute = Point::Zero();
- };
-
-
class Control : public Object
{
friend class Window;
protected:
- struct GeometryInfo
- {
- Microsoft::WRL::ComPtr<ID2D1Geometry> border_geometry = nullptr;
- Microsoft::WRL::ComPtr<ID2D1Geometry> padding_content_geometry = nullptr;
- Microsoft::WRL::ComPtr<ID2D1Geometry> content_geometry = nullptr;
- };
-
-
- protected:
- Control();
+ Control() = default;
public:
Control(const Control& other) = delete;
Control(Control&& other) = delete;
@@ -63,53 +35,35 @@ namespace cru::ui
~Control() override = default;
public:
-
- //*************** region: tree ***************
virtual StringView GetControlType() const = 0;
- virtual const std::vector<Control*>& GetInternalChildren() const = 0;
-
- Control* GetParent() const
- {
- return parent_ == nullptr ? internal_parent_ : parent_;
- }
-
- Control* GetInternalParent() const
- {
- return internal_parent_;
- }
+ //*************** region: tree ***************
+ public:
//Get the window if attached, otherwise, return nullptr.
Window* GetWindow() const
{
return window_;
}
- void SetParent(Control* parent);
+ Control* GetParent() const
+ {
+ return parent_;
+ }
- void SetInternalParent(Control* internal_parent);
+ void SetParent(Control* parent);
void SetDescendantWindow(Window* window);
-
//Traverse the tree rooted the control including itself.
void TraverseDescendants(const std::function<void(Control*)>& predicate);
- //*************** region: position and size ***************
-
- //Get the lefttop relative to its parent.
- virtual Point GetOffset();
-
- //Get the actual size.
- virtual Size GetSize();
-
- // If offset changes, call RefreshDescendantPositionCache.
- virtual void SetRect(const Rect& rect);
+ private:
+ static void TraverseDescendantsInternal(Control* control, const std::function<void(Control*)>& predicate);
- //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;
+ //*************** region: position ***************
+ public:
+ virtual Point GetPositionInWindow() const = 0;
//Local point to absolute point.
Point ControlToWindow(const Point& point) const;
@@ -117,122 +71,19 @@ namespace cru::ui
//Absolute point to local point.
Point WindowToControl(const Point& point) const;
- void RefreshDescendantPositionCache();
-
- private:
- static void RefreshControlPositionCacheInternal(Control* control, const Point& parent_lefttop_absolute);
-
- public:
-
- // Default implement in Control is test point in border geometry's
- // fill and stroke with width of border.
- virtual bool IsPointInside(const Point& point);
-
- // Get the top control among all descendants (including self) in local coordinate.
- virtual Control* HitTest(const Point& point);
-
- //*************** region: graphic ***************
-
- bool IsClipContent() const
- {
- return clip_content_;
- }
-
- void SetClipContent(bool clip);
-
- //Draw this control and its child controls.
- void Draw(ID2D1DeviceContext* device_context);
-
- virtual void InvalidateDraw();
-
- Microsoft::WRL::ComPtr<ID2D1Brush> GetForegroundBrush() const
- {
- return foreground_brush_;
- }
-
- void SetForegroundBrush(Microsoft::WRL::ComPtr<ID2D1Brush> foreground_brush)
- {
- foreground_brush_ = std::move(foreground_brush);
- InvalidateDraw();
- }
-
- Microsoft::WRL::ComPtr<ID2D1Brush> GetBackgroundBrush() const
- {
- return background_brush_;
- }
-
- void SetBackgroundBrush(Microsoft::WRL::ComPtr<ID2D1Brush> background_brush)
- {
- background_brush_ = std::move(background_brush);
- InvalidateDraw();
- }
//*************** region: focus ***************
-
+ public:
bool RequestFocus();
bool HasFocus();
- bool IsFocusOnPressed() const
- {
- return is_focus_on_pressed_;
- }
-
- void SetFocusOnPressed(const bool value)
- {
- is_focus_on_pressed_ = value;
- }
-
- //*************** region: layout ***************
-
- void InvalidateLayout();
-
- void Measure(const Size& available_size, const AdditionalMeasureInfo& additional_info);
-
- void Layout(const Rect& rect, const AdditionalLayoutInfo& additional_info);
-
- Size GetDesiredSize() const;
-
- void SetDesiredSize(const Size& desired_size);
-
- BasicLayoutParams* GetLayoutParams()
- {
- return &layout_params_;
- }
-
- Rect GetRect(RectRange range);
-
- Point TransformPoint(const Point& point, RectRange from = RectRange::Margin, RectRange to = RectRange::Content);
-
- //*************** region: border ***************
-
- BorderProperty& GetBorderProperty()
- {
- return border_property_;
- }
-
- void UpdateBorder();
-
- bool IsBordered() const
- {
- return is_bordered_;
- }
-
- void SetBordered(bool bordered);
-
-
- //*************** region: additional properties ***************
- AnyMap* GetAdditionalPropertyMap()
- {
- return &additional_property_map_;
- }
-
//*************** region: cursor ***************
// If cursor is set to null, then it uses parent's cursor.
// Window's cursor can't be null.
-
+ public:
Cursor::Ptr GetCursor() const
{
return cursor_;
@@ -241,7 +92,16 @@ namespace cru::ui
void SetCursor(const Cursor::Ptr& cursor);
+ //*************** region: additional properties ***************
+ public:
+ AnyMap* GetAdditionalPropertyMap()
+ {
+ return &additional_property_map_;
+ }
+
+
//*************** region: events ***************
+ public:
//Raised when mouse enter the control.
events::RoutedEvent<events::MouseEventArgs> mouse_enter_event;
//Raised when mouse is leave the control.
@@ -264,95 +124,29 @@ namespace cru::ui
events::RoutedEvent<events::FocusChangeEventArgs> get_focus_event;
events::RoutedEvent<events::FocusChangeEventArgs> lose_focus_event;
- Event<events::DrawEventArgs> draw_content_event;
- Event<events::DrawEventArgs> draw_background_event;
- Event<events::DrawEventArgs> draw_foreground_event;
-
- //*************** region: tree event ***************
+ //*************** region: tree ***************
protected:
- virtual void OnParentChanged(Control* old_parent, Control* new_parent);
-
- virtual void OnInternalParentChanged(Control* old_internal_parent, Control* new_internal_parent);
+ virtual const std::vector<Control*>& GetInternalChildren() const = 0;
- //Invoked when the control is attached to a window. Overrides should invoke base.
+ virtual void OnParentChanged(Control* old_parent, Control* new_parent);
virtual void OnAttachToWindow(Window* window);
- //Invoked when the control is detached to a window. Overrides should invoke base.
virtual void OnDetachToWindow(Window* window);
- //*************** region: graphic event ***************
- private:
- void OnDrawDecoration(ID2D1DeviceContext* device_context);
- void OnDrawCore(ID2D1DeviceContext* device_context);
-
-
- //*************** region: position and size event ***************
- protected:
- virtual void OnRectChange(const Rect& old_rect, const Rect& new_rect);
-
- void RegenerateGeometryInfo();
-
- const GeometryInfo& GetGeometryInfo() const
- {
- return geometry_info_;
- }
-
-
- //*************** region: mouse event ***************
+ //*************** region: additional mouse event ***************
protected:
virtual void OnMouseClickBegin(MouseButton button);
virtual void OnMouseClickEnd(MouseButton button);
- //*************** region: layout ***************
- private:
- Size OnMeasureCore(const Size& available_size, const AdditionalMeasureInfo& additional_info);
- void OnLayoutCore(const Rect& rect, const AdditionalLayoutInfo& additional_info);
-
- protected:
- virtual Size OnMeasureContent(const Size& available_size, const AdditionalMeasureInfo& additional_info) = 0;
- virtual void OnLayoutContent(const Rect& rect, const AdditionalLayoutInfo& additional_info) = 0;
-
private:
Window * window_ = nullptr;
- Control* parent_ = nullptr; // when parent and internal parent are the same, parent_ is nullptr.
- Control * internal_parent_ = nullptr;
-
- Rect rect_{};
-
- 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
-
- BasicLayoutParams layout_params_{};
- Size desired_size_ = Size::Zero();
-
- bool is_bordered_ = false;
- BorderProperty border_property_;
-
- GeometryInfo geometry_info_{};
-
- bool clip_content_ = false;
+ Control* parent_ = nullptr;
- Microsoft::WRL::ComPtr<ID2D1Brush> foreground_brush_ = nullptr;
- Microsoft::WRL::ComPtr<ID2D1Brush> background_brush_ = nullptr;
+ Cursor::Ptr cursor_{};
AnyMap additional_property_map_{};
-
- bool is_focus_on_pressed_ = true;
-
-#ifdef CRU_DEBUG_LAYOUT
- Microsoft::WRL::ComPtr<ID2D1Geometry> margin_geometry_;
- Microsoft::WRL::ComPtr<ID2D1Geometry> padding_geometry_;
-#endif
-
- Cursor::Ptr cursor_{};
};
@@ -372,31 +166,24 @@ namespace cru::ui
NoChildControl& operator=(NoChildControl&& other) = delete;
~NoChildControl() override = default;
+ protected:
const std::vector<Control*>& GetInternalChildren() const override final
{
return empty_control_vector;
}
-
- protected:
- void OnLayoutContent(const Rect& rect, const AdditionalLayoutInfo& additional_info) override;
};
- class SingleChildControl : public Control
+ class ContentControl : public Control
{
protected:
- SingleChildControl();
+ ContentControl();
public:
- SingleChildControl(const SingleChildControl& other) = delete;
- SingleChildControl(SingleChildControl&& other) = delete;
- SingleChildControl& operator=(const SingleChildControl& other) = delete;
- SingleChildControl& operator=(SingleChildControl&& other) = delete;
- ~SingleChildControl() override;
-
- const std::vector<Control*>& GetInternalChildren() const override final
- {
- return child_vector_;
- }
+ ContentControl(const ContentControl& other) = delete;
+ ContentControl(ContentControl&& other) = delete;
+ ContentControl& operator=(const ContentControl& other) = delete;
+ ContentControl& operator=(ContentControl&& other) = delete;
+ ~ContentControl() override;
Control* GetChild() const
{
@@ -406,12 +193,14 @@ namespace cru::ui
void SetChild(Control* child);
protected:
+ const std::vector<Control*>& GetInternalChildren() const override final
+ {
+ return child_vector_;
+ }
+
// Override should call base.
virtual void OnChildChanged(Control* old_child, Control* new_child);
- Size OnMeasureContent(const Size& available_size, const AdditionalMeasureInfo& additional_info) override;
- void OnLayoutContent(const Rect& rect, const AdditionalLayoutInfo& additional_info) override;
-
private:
std::vector<Control*> child_vector_;
Control*& child_;
@@ -452,9 +241,7 @@ namespace cru::ui
void RemoveChild(int position);
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);
private: