aboutsummaryrefslogtreecommitdiff
path: root/src/ui
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2018-12-12 00:40:57 +0800
committercrupest <crupest@outlook.com>2018-12-12 00:40:57 +0800
commitedbdf3d2a166099f5af4dd859258468288919685 (patch)
tree68c920a32156e13af8bde9d4db3f0a8478b1e499 /src/ui
parent3540c1718c74e9fa3538ae92a6418eb02d27f1c5 (diff)
downloadcru-edbdf3d2a166099f5af4dd859258468288919685.tar.gz
cru-edbdf3d2a166099f5af4dd859258468288919685.tar.bz2
cru-edbdf3d2a166099f5af4dd859258468288919685.zip
...
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/d2d_util.hpp30
-rw-r--r--src/ui/render/render_object.cpp42
-rw-r--r--src/ui/render/render_object.hpp82
-rw-r--r--src/ui/ui_base.hpp80
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)