diff options
author | crupest <crupest@outlook.com> | 2018-12-12 00:40:57 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2018-12-12 00:40:57 +0800 |
commit | edbdf3d2a166099f5af4dd859258468288919685 (patch) | |
tree | 68c920a32156e13af8bde9d4db3f0a8478b1e499 /src/ui | |
parent | 3540c1718c74e9fa3538ae92a6418eb02d27f1c5 (diff) | |
download | cru-edbdf3d2a166099f5af4dd859258468288919685.tar.gz cru-edbdf3d2a166099f5af4dd859258468288919685.tar.bz2 cru-edbdf3d2a166099f5af4dd859258468288919685.zip |
...
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/d2d_util.hpp | 30 | ||||
-rw-r--r-- | src/ui/render/render_object.cpp | 42 | ||||
-rw-r--r-- | src/ui/render/render_object.hpp | 82 | ||||
-rw-r--r-- | src/ui/ui_base.hpp | 80 |
4 files changed, 158 insertions, 76 deletions
diff --git a/src/ui/d2d_util.hpp b/src/ui/d2d_util.hpp index d4fff620..5f2e10b2 100644 --- a/src/ui/d2d_util.hpp +++ b/src/ui/d2d_util.hpp @@ -19,6 +19,16 @@ namespace cru::ui return D2D1::RectF(rect.left, rect.top, rect.left + rect.width, rect.top + rect.height); } + inline D2D1_ROUNDED_RECT Convert(const RoundedRect& rounded_rect) + { + return D2D1::RoundedRect(Convert(rounded_rect.rect), rounded_rect.radius_x, rounded_rect.radius_y); + } + + inline D2D1_ELLIPSE Convert(const Ellipse& ellipse) + { + return D2D1::Ellipse(Convert(ellipse.center), ellipse.radius_x, ellipse.radius_y); + } + inline Point Convert(const D2D1_POINT_2F& point) { return Point(point.x, point.y); @@ -29,6 +39,16 @@ namespace cru::ui return Rect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); } + inline RoundedRect Convert(const D2D1_ROUNDED_RECT& rounded_rect) + { + return RoundedRect(Convert(rounded_rect.rect), rounded_rect.radiusX, rounded_rect.radiusY); + } + + inline Ellipse Convert(const D2D1_ELLIPSE& ellipse) + { + return Ellipse(Convert(ellipse.point), ellipse.radiusX, ellipse.radiusY); + } + inline bool operator==(const D2D1_POINT_2F& left, const D2D1_POINT_2F& right) { return left.x == right.x && left.y == right.y; @@ -61,4 +81,14 @@ namespace cru::ui { return !(left == right); } + + inline bool operator == (const D2D1_ELLIPSE& left, const D2D1_ELLIPSE& right) + { + return left.point == right.point && left.radiusX == right.radiusX && left.radiusY == right.radiusY; + } + + inline bool operator!=(const D2D1_ELLIPSE& left, const D2D1_ELLIPSE& right) + { + return !(left == right); + } } diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp index 3e2e5265..bfa250d6 100644 --- a/src/ui/render/render_object.cpp +++ b/src/ui/render/render_object.cpp @@ -60,48 +60,18 @@ namespace cru::ui::render InvalidateRenderHost(); } - void RoundedRectangleRenderObject::SetRect(const Rect& rect) + namespace details { - const auto converted_rect = Convert(rect); - if (rounded_rect_.rect == converted_rect) - return; - - rounded_rect_.rect = converted_rect; - InvalidateRenderHost(); - } - - void RoundedRectangleRenderObject::SetRadiusX(const float new_radius_x) - { - if (rounded_rect_.radiusX == new_radius_x) - return; - - rounded_rect_.radiusX = new_radius_x; - InvalidateRenderHost(); - } - - void RoundedRectangleRenderObject::SetRadiusY(const float new_radius_y) - { - if (rounded_rect_.radiusY == new_radius_y) - return; - - rounded_rect_.radiusY = new_radius_y; - InvalidateRenderHost(); - } - - void RoundedRectangleRenderObject::SetRoundedRect(const D2D1_ROUNDED_RECT& new_rounded_rect) - { - if (rounded_rect_ == new_rounded_rect) - return; - - rounded_rect_ = new_rounded_rect; - InvalidateRenderHost(); + template class ShapeRenderObject<Rect>; + template class ShapeRenderObject<RoundedRect>; + template class ShapeRenderObject<Ellipse>; } void RoundedRectangleStrokeRenderObject::Draw(ID2D1RenderTarget* render_target) { const auto brush = GetBrush(); if (brush != nullptr) - render_target->DrawRoundedRectangle(GetRoundedRect(), GetBrush().Get(), GetStrokeWidth()); + render_target->DrawRoundedRectangle(Convert(GetShape()), GetBrush().Get(), GetStrokeWidth()); } void CustomDrawHandlerRenderObject::SetDrawHandler(DrawHandler new_draw_handler) @@ -110,7 +80,7 @@ namespace cru::ui::render return; draw_handler_ = std::move(new_draw_handler); - InvalidateRenderHost; + InvalidateRenderHost(); } void CustomDrawHandlerRenderObject::Draw(ID2D1RenderTarget* render_target) diff --git a/src/ui/render/render_object.hpp b/src/ui/render/render_object.hpp index b6f9f13b..0fbeb8c7 100644 --- a/src/ui/render/render_object.hpp +++ b/src/ui/render/render_object.hpp @@ -119,48 +119,50 @@ namespace cru::ui::render }; - class RoundedRectangleRenderObject : public virtual RenderObject + namespace details { - protected: - RoundedRectangleRenderObject() = default; - public: - RoundedRectangleRenderObject(const RoundedRectangleRenderObject& other) = delete; - RoundedRectangleRenderObject(RoundedRectangleRenderObject&& other) = delete; - RoundedRectangleRenderObject& operator=(const RoundedRectangleRenderObject& other) = delete; - RoundedRectangleRenderObject& operator=(RoundedRectangleRenderObject&& other) = delete; - ~RoundedRectangleRenderObject() override = default; - - Rect GetRect() const - { - return Convert(rounded_rect_.rect); - } - - void SetRect(const Rect& rect); - - float GetRadiusX() const - { - return rounded_rect_.radiusX; - } - - void SetRadiusX(float new_radius_x); - - float GetRadiusY() const - { - return rounded_rect_.radiusY; - } - - void SetRadiusY(float new_radius_y); - - D2D1_ROUNDED_RECT GetRoundedRect() const + template <typename TShapeType> + class ShapeRenderObject : public virtual RenderObject { - return rounded_rect_; - } - - void SetRoundedRect(const D2D1_ROUNDED_RECT& new_rounded_rect); - - private: - D2D1_ROUNDED_RECT rounded_rect_ = D2D1::RoundedRect(D2D1::RectF(), 0.0f, 0.0f); - }; + public: + using ShapeType = TShapeType; + protected: + ShapeRenderObject() = default; + public: + ShapeRenderObject(const ShapeRenderObject& other) = delete; + ShapeRenderObject& operator=(const ShapeRenderObject& other) = delete; + ShapeRenderObject(ShapeRenderObject&& other) = delete; + ShapeRenderObject& operator=(ShapeRenderObject&& other) = delete; + ~ShapeRenderObject() override = default; + + ShapeType GetShape() const + { + return shape_; + } + + void SetShape(const ShapeType& new_shape) + { + if (new_shape == shape_) + return; + + shape_ = new_shape; + InvalidateRenderHost(); + } + + private: + ShapeType shape_; + }; + + + extern template class ShapeRenderObject<Rect>; + extern template class ShapeRenderObject<RoundedRect>; + extern template class ShapeRenderObject<Ellipse>; + } + + + using RectangleRenderObject = details::ShapeRenderObject<Rect>; + using RoundedRectangleRenderObject = details::ShapeRenderObject<RoundedRect>; + using EllipseRenderObject = details::ShapeRenderObject<Ellipse>; class RoundedRectangleStrokeRenderObject final : public StrokeRenderObject, public RoundedRectangleRenderObject diff --git a/src/ui/ui_base.hpp b/src/ui/ui_base.hpp index 5350e4e9..c26bfe0e 100644 --- a/src/ui/ui_base.hpp +++ b/src/ui/ui_base.hpp @@ -32,6 +32,7 @@ namespace cru::ui return !(left == right); } + struct Size { constexpr static Size Zero() @@ -66,6 +67,7 @@ namespace cru::ui return !(left == right); } + struct Thickness { constexpr static Thickness Zero() @@ -120,6 +122,20 @@ namespace cru::ui float bottom; }; + constexpr bool operator == (const Thickness& left, const Thickness& right) + { + return left.left == right.left && + left.top == right.top && + left.right == right.right && + left.bottom == right.bottom; + } + + constexpr bool operator != (const Thickness& left, const Thickness& right) + { + return !(left == right); + } + + struct Rect { constexpr Rect() = default; @@ -133,6 +149,11 @@ namespace cru::ui return Rect(left, top, right - left, bottom - top); } + constexpr static Rect FromCenter(const Point& center, const float width, const float height) + { + return Rect(center.x - width / 2.0f, center.y - height / 2.0f, width, height); + } + constexpr float GetRight() const { return left + width; @@ -163,6 +184,11 @@ namespace cru::ui return Point(left + width, top); } + constexpr Point GetCenter() const + { + return Point(left + width / 2.0f, top + height / 2.0f); + } + constexpr Size GetSize() const { return Size(width, height); @@ -202,6 +228,59 @@ namespace cru::ui } + struct RoundedRect + { + constexpr RoundedRect() = default; + constexpr RoundedRect(const Rect& rect, const float radius_x, const float radius_y) + : rect(rect), radius_x(radius_x), radius_y(radius_y) { } + + Rect rect{}; + float radius_x = 0.0f; + float radius_y = 0.0f; + }; + + constexpr bool operator == (const RoundedRect& left, const RoundedRect& right) + { + return left.rect == right.rect && left.radius_x == right.radius_x && left.radius_y == right.radius_y; + } + + constexpr bool operator != (const RoundedRect& left, const RoundedRect& right) + { + return !(left == right); + } + + struct Ellipse + { + constexpr Ellipse() = default; + constexpr Ellipse(const Point& center, const float radius_x, const float radius_y) + : center(center), radius_x(radius_x), radius_y(radius_y) { } + + constexpr static Ellipse FromRect(const Rect& rect) + { + return Ellipse(rect.GetCenter(), rect.width / 2.0f, rect.height / 2.0f); + } + + constexpr Rect GetBoundRect() const + { + return Rect::FromCenter(center, radius_x * 2.0f, radius_y * 2.0f); + } + + Point center{}; + float radius_x = 0.0f; + float radius_y = 0.0f; + }; + + constexpr bool operator == (const Ellipse& left, const Ellipse& right) + { + return left.center == right.center && left.radius_x == right.radius_x && left.radius_y == right.radius_y; + } + + constexpr bool operator != (const Ellipse& left, const Ellipse& right) + { + return !(left == right); + } + + enum class MouseButton { Left, @@ -209,6 +288,7 @@ namespace cru::ui Middle }; + struct TextRange { constexpr static std::optional<TextRange> FromTwoSides(unsigned first, unsigned second) |