#pragma once #include "ui/control.h" namespace cru::ui::controls { class BorderProperty : public PropertyChangedNotifyObject { public: using Ptr = std::shared_ptr; static Ptr Create() { return std::make_shared(); } constexpr static auto brush_property_name = L"Brush"; constexpr static auto width_property_name = L"Width"; constexpr static auto stroke_style_property_name = L"StrokeStyle"; constexpr static auto radius_x_property_name = L"RadiusX"; constexpr static auto radius_y_property_name = L"RadiusY"; BorderProperty() = default; BorderProperty(const BorderProperty& other) = delete; BorderProperty(BorderProperty&& other) = delete; BorderProperty& operator=(const BorderProperty& other) = delete; BorderProperty& operator=(BorderProperty&& other) = delete; ~BorderProperty() override = default; Microsoft::WRL::ComPtr GetBrush() const { return brush_; } float GetWidth() const { return width_; } Microsoft::WRL::ComPtr GetStrokeStyle() const { return stroke_style_; } float GetRadiusX() const { return radius_x_; } float GetRadiusY() const { return radius_y_; } void SetBrush(Microsoft::WRL::ComPtr brush); void SetWidth(float width); void SetStrokeStyle(Microsoft::WRL::ComPtr stroke_style); void SetRadiusX(float radius_x); void SetRadiusY(float radius_y); private: Microsoft::WRL::ComPtr brush_ = nullptr; float width_ = 1.0f; Microsoft::WRL::ComPtr stroke_style_ = nullptr; float radius_x_ = 0.0f; float radius_y_ = 0.0f; }; // BorderDelegate is a delegate for border painting and layout. // It must bind a control and not change the binding. // But multiple BorderDelegate may share a common BorderProperty. class BorderDelegate : public Object { public: explicit BorderDelegate(Control* control); BorderDelegate(Control* control, std::shared_ptr border_property); BorderDelegate(const BorderDelegate& other) = delete; BorderDelegate(BorderDelegate&& other) = delete; BorderDelegate& operator=(const BorderDelegate& other) = delete; BorderDelegate& operator=(BorderDelegate&& other) = delete; ~BorderDelegate() override; std::shared_ptr GetBorderProperty() const { return border_property_; } void SetBorderProperty(std::shared_ptr border_property); void Draw(ID2D1DeviceContext* device_context, const Size& size) const; Size GetBorderSize() const; Rect CoerceLayoutRect(const Rect& rect) const; private: Control* control_; std::shared_ptr border_property_; FunctionPtr border_property_changed_listener_; }; }