aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2018-12-10 23:29:54 +0800
committercrupest <crupest@outlook.com>2018-12-10 23:29:54 +0800
commit769a4db24b64a2baf20960858ae24461328e5b7a (patch)
treeffdd7e84d820dae71fe2af801d5f8d57e93072b1
parent4219992207b524e23a426e753589001b6f7a24d0 (diff)
downloadcru-769a4db24b64a2baf20960858ae24461328e5b7a.tar.gz
cru-769a4db24b64a2baf20960858ae24461328e5b7a.tar.bz2
cru-769a4db24b64a2baf20960858ae24461328e5b7a.zip
...
-rw-r--r--CruUI.vcxproj5
-rw-r--r--CruUI.vcxproj.filters9
-rw-r--r--snippets/vc++snippets.snippet55
-rw-r--r--src/ui/control.cpp2
-rw-r--r--src/ui/controls/list_item.cpp2
-rw-r--r--src/ui/controls/scroll_control.cpp2
-rw-r--r--src/ui/controls/toggle_button.cpp2
-rw-r--r--src/ui/convert_util.hpp21
-rw-r--r--src/ui/d2d_util.hpp64
-rw-r--r--src/ui/render/render_object.cpp99
-rw-r--r--src/ui/render/render_object.hpp164
-rw-r--r--src/ui/ui_base.hpp14
12 files changed, 398 insertions, 41 deletions
diff --git a/CruUI.vcxproj b/CruUI.vcxproj
index 429e6377..23e51e34 100644
--- a/CruUI.vcxproj
+++ b/CruUI.vcxproj
@@ -172,7 +172,7 @@
<ClInclude Include="src\ui\controls\text_box.hpp" />
<ClCompile Include="src\ui\controls\text_control.cpp" />
<ClInclude Include="src\ui\controls\toggle_button.hpp" />
- <ClInclude Include="src\ui\convert_util.hpp" />
+ <ClInclude Include="src\ui\d2d_util.hpp" />
<ClInclude Include="src\ui\cursor.hpp" />
<ClInclude Include="src\ui\events\ui_event.hpp" />
<ClInclude Include="src\ui\layout_base.hpp" />
@@ -181,6 +181,9 @@
<ClInclude Include="src\ui\ui_base.hpp" />
<ClInclude Include="src\ui\window.hpp" />
</ItemGroup>
+ <ItemGroup>
+ <Xml Include="snippets\vc++snippets.snippet" />
+ </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
diff --git a/CruUI.vcxproj.filters b/CruUI.vcxproj.filters
index 547a58c2..13976a7d 100644
--- a/CruUI.vcxproj.filters
+++ b/CruUI.vcxproj.filters
@@ -176,9 +176,6 @@
<ClInclude Include="src\ui\controls\list_item.hpp">
<Filter>Header Files</Filter>
</ClInclude>
- <ClInclude Include="src\ui\convert_util.hpp">
- <Filter>Header Files</Filter>
- </ClInclude>
<ClInclude Include="src\ui\controls\popup_menu.hpp">
<Filter>Header Files</Filter>
</ClInclude>
@@ -197,6 +194,9 @@
<ClInclude Include="src\ui\render\render_object.hpp">
<Filter>Header Files</Filter>
</ClInclude>
+ <ClInclude Include="src\ui\d2d_util.hpp">
+ <Filter>Header Files</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\application.cpp">
@@ -254,4 +254,7 @@
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
+ <ItemGroup>
+ <Xml Include="snippets\vc++snippets.snippet" />
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/snippets/vc++snippets.snippet b/snippets/vc++snippets.snippet
new file mode 100644
index 00000000..1a5f7666
--- /dev/null
+++ b/snippets/vc++snippets.snippet
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
+ <CodeSnippet Format="1.0.0">
+ <Header>
+ <Title>Deleted Copy Constructor/Assignment</Title>
+ <Author>crupest</Author>
+ <Description>Declare a deleted copy constructor and a deleted copy assignment operator for a class.</Description>
+ <Shortcut>dcopy</Shortcut>
+ <SnippetTypes>
+ <SnippetType>Expansion</SnippetType>
+ </SnippetTypes>
+ </Header>
+ <Snippet>
+ <Declarations>
+ <Literal>
+ <ID>classname</ID>
+ <Default>class_name</Default>
+ <ToolTip>The name of the class.</ToolTip>
+ </Literal>
+ </Declarations>
+ <Code Language="CPP" Kind="method decl">
+ <![CDATA[
+ $classname$(const $classname$& other) = delete;
+ $classname$& operator=(const $classname$& other) = delete;
+ ]]>
+ </Code>
+ </Snippet>
+ </CodeSnippet>
+ <CodeSnippet Format="1.0.0">
+ <Header>
+ <Title>Deleted Move Constructor/Assignment</Title>
+ <Author>crupest</Author>
+ <Description>Declare a deleted move constructor and a deleted move assignment operator for a class.</Description>
+ <Shortcut>dmove</Shortcut>
+ <SnippetTypes>
+ <SnippetType>Expansion</SnippetType>
+ </SnippetTypes>
+ </Header>
+ <Snippet>
+ <Declarations>
+ <Literal>
+ <ID>classname</ID>
+ <Default>class_name</Default>
+ <ToolTip>The name of the class.</ToolTip>
+ </Literal>
+ </Declarations>
+ <Code Language="CPP" Kind="method decl">
+ <![CDATA[
+ $classname$($classname$&& other) = delete;
+ $classname$& operator=($classname$&& other) = delete;
+ ]]>
+ </Code>
+ </Snippet>
+ </CodeSnippet>
+</CodeSnippets> \ No newline at end of file
diff --git a/src/ui/control.cpp b/src/ui/control.cpp
index 3987e818..9388c719 100644
--- a/src/ui/control.cpp
+++ b/src/ui/control.cpp
@@ -8,7 +8,7 @@
#include "graph/graph.hpp"
#include "exception.hpp"
#include "cru_debug.hpp"
-#include "convert_util.hpp"
+#include "d2d_util.hpp"
#include "math_util.hpp"
#ifdef CRU_DEBUG_LAYOUT
diff --git a/src/ui/controls/list_item.cpp b/src/ui/controls/list_item.cpp
index e0ca28a9..6dd37fe9 100644
--- a/src/ui/controls/list_item.cpp
+++ b/src/ui/controls/list_item.cpp
@@ -1,7 +1,7 @@
#include "list_item.hpp"
#include "ui/ui_manager.hpp"
-#include "ui/convert_util.hpp"
+#include "ui/d2d_util.hpp"
namespace cru::ui::controls
{
diff --git a/src/ui/controls/scroll_control.cpp b/src/ui/controls/scroll_control.cpp
index 622b4e4c..a202e355 100644
--- a/src/ui/controls/scroll_control.cpp
+++ b/src/ui/controls/scroll_control.cpp
@@ -3,7 +3,7 @@
#include <limits>
#include "cru_debug.hpp"
-#include "ui/convert_util.hpp"
+#include "ui/d2d_util.hpp"
#include "exception.hpp"
#include "math_util.hpp"
#include "ui/ui_manager.hpp"
diff --git a/src/ui/controls/toggle_button.cpp b/src/ui/controls/toggle_button.cpp
index 6eb0bc40..db72d7bb 100644
--- a/src/ui/controls/toggle_button.cpp
+++ b/src/ui/controls/toggle_button.cpp
@@ -3,7 +3,7 @@
#include "graph/graph.hpp"
#include "ui/animations/animation.hpp"
#include "ui/ui_manager.hpp"
-#include "ui/convert_util.hpp"
+#include "ui/d2d_util.hpp"
namespace cru::ui::controls
{
diff --git a/src/ui/convert_util.hpp b/src/ui/convert_util.hpp
deleted file mode 100644
index 5408f2e4..00000000
--- a/src/ui/convert_util.hpp
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-// ReSharper disable once CppUnusedIncludeDirective
-#include "pre.hpp"
-
-#include "system_headers.hpp"
-
-#include "ui_base.hpp"
-
-namespace cru::ui
-{
- inline D2D1_POINT_2F Convert(const Point& point)
- {
- return D2D1::Point2F(point.x, point.y);
- }
-
- inline D2D1_RECT_F Convert(const Rect& rect)
- {
- return D2D1::RectF(rect.left, rect.top, rect.left + rect.width, rect.top + rect.height);
- }
-}
diff --git a/src/ui/d2d_util.hpp b/src/ui/d2d_util.hpp
new file mode 100644
index 00000000..d4fff620
--- /dev/null
+++ b/src/ui/d2d_util.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+// ReSharper disable once CppUnusedIncludeDirective
+#include "pre.hpp"
+
+#include "system_headers.hpp"
+
+#include "ui_base.hpp"
+
+namespace cru::ui
+{
+ inline D2D1_POINT_2F Convert(const Point& point)
+ {
+ return D2D1::Point2F(point.x, point.y);
+ }
+
+ inline D2D1_RECT_F Convert(const Rect& rect)
+ {
+ return D2D1::RectF(rect.left, rect.top, rect.left + rect.width, rect.top + rect.height);
+ }
+
+ inline Point Convert(const D2D1_POINT_2F& point)
+ {
+ return Point(point.x, point.y);
+ }
+
+ inline Rect Convert(const D2D1_RECT_F& rect)
+ {
+ return Rect(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
+ }
+
+ inline bool operator==(const D2D1_POINT_2F& left, const D2D1_POINT_2F& right)
+ {
+ return left.x == right.x && left.y == right.y;
+ }
+
+ inline bool operator!=(const D2D1_POINT_2F& left, const D2D1_POINT_2F& right)
+ {
+ return !(left == right);
+ }
+
+ inline bool operator==(const D2D1_RECT_F& left, const D2D1_RECT_F& right)
+ {
+ return left.left == right.left &&
+ left.top == right.top &&
+ left.right == right.right &&
+ left.bottom == right.bottom;
+ }
+
+ inline bool operator!=(const D2D1_RECT_F& left, const D2D1_RECT_F& right)
+ {
+ return !(left == right);
+ }
+
+ inline bool operator==(const D2D1_ROUNDED_RECT& left, const D2D1_ROUNDED_RECT& right)
+ {
+ return left.rect == right.rect && left.radiusX == right.radiusX && left.radiusY == right.radiusY;
+ }
+
+ inline bool operator!=(const D2D1_ROUNDED_RECT& left, const D2D1_ROUNDED_RECT& right)
+ {
+ return !(left == right);
+ }
+}
diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp
index 7b430f06..78445bf1 100644
--- a/src/ui/render/render_object.cpp
+++ b/src/ui/render/render_object.cpp
@@ -87,6 +87,9 @@ namespace cru::ui::render
render_target->SetTransform(matrix);
}
+ const MatrixRenderObject::MatrixApplier MatrixRenderObject::append_applier(ApplyAppendMatrix);
+ const MatrixRenderObject::MatrixApplier MatrixRenderObject::set_applier(ApplySetMatrix);
+
MatrixRenderObject::MatrixRenderObject(const D2D1_MATRIX_3X2_F& matrix, MatrixApplier applier)
: matrix_(matrix), applier_(std::move(applier))
{
@@ -128,6 +131,98 @@ namespace cru::ui::render
SetMatrix(D2D1::Matrix3x2F::Translation(offset_x_, offset_y_));
}
- const MatrixRenderObject::MatrixApplier MatrixRenderObject::append_applier(ApplyAppendMatrix);
- const MatrixRenderObject::MatrixApplier MatrixRenderObject::set_applier(ApplySetMatrix);
+ void StrokeRenderObject::SetStrokeWidth(const float new_stroke_width)
+ {
+ if (stroke_width_ == new_stroke_width)
+ return;
+
+ stroke_width_ = new_stroke_width;
+ InvalidateRenderHost();
+ }
+
+ void StrokeRenderObject::SetBrush(Microsoft::WRL::ComPtr<ID2D1Brush> new_brush)
+ {
+ if (brush_ == new_brush)
+ return;
+
+ brush_ = std::move(new_brush);
+ InvalidateRenderHost();
+ }
+
+ void StrokeRenderObject::SetStrokeStyle(Microsoft::WRL::ComPtr<ID2D1StrokeStyle> new_stroke_style)
+ {
+ if (stroke_style_ == new_stroke_style)
+ return;
+
+ stroke_style_ = std::move(new_stroke_style);
+ InvalidateRenderHost();
+ }
+
+ void FillRenderObject::SetBrush(Microsoft::WRL::ComPtr<ID2D1Brush> new_brush)
+ {
+ if (brush_ == new_brush)
+ return;
+
+ brush_ = std::move(new_brush);
+ InvalidateRenderHost();
+ }
+
+ void RoundedRectangleRenderObject::SetRect(const Rect& rect)
+ {
+ 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();
+ }
+
+ void RoundedRectangleStrokeRenderObject::Draw(ID2D1RenderTarget* render_target)
+ {
+ const auto brush = GetBrush();
+ if (brush != nullptr)
+ render_target->DrawRoundedRectangle(GetRoundedRect(), GetBrush().Get(), GetStrokeWidth());
+ }
+
+ void CustomDrawHandlerRenderObject::SetDrawHandler(DrawHandler new_draw_handler)
+ {
+ if (draw_handler_ == nullptr && new_draw_handler == nullptr)
+ return;
+
+ draw_handler_ = std::move(new_draw_handler);
+ InvalidateRenderHost;
+ }
+
+ void CustomDrawHandlerRenderObject::Draw(ID2D1RenderTarget * render_target)
+ {
+ if (draw_handler_ != nullptr)
+ draw_handler_(render_target);
+ }
}
diff --git a/src/ui/render/render_object.hpp b/src/ui/render/render_object.hpp
index 675a1759..6603728d 100644
--- a/src/ui/render/render_object.hpp
+++ b/src/ui/render/render_object.hpp
@@ -7,6 +7,7 @@
#include "base.hpp"
#include "ui/ui_base.hpp"
+#include "ui/d2d_util.hpp"
namespace cru::ui::render
{
@@ -193,11 +194,154 @@ namespace cru::ui::render
float offset_y_;
};
- class BorderRenderObject; //TODO!
- class FillGeometryRenderObject; //TODO!
+ class StrokeRenderObject : public virtual RenderObject
+ {
+ protected:
+ StrokeRenderObject() = default;
+ public:
+ StrokeRenderObject(const StrokeRenderObject& other) = delete;
+ StrokeRenderObject(StrokeRenderObject&& other) = delete;
+ StrokeRenderObject& operator=(const StrokeRenderObject& other) = delete;
+ StrokeRenderObject& operator=(StrokeRenderObject&& other) = delete;
+ ~StrokeRenderObject() override = default;
+
+ float GetStrokeWidth() const
+ {
+ return stroke_width_;
+ }
+
+ void SetStrokeWidth(float new_stroke_width);
+
+ Microsoft::WRL::ComPtr<ID2D1Brush> GetBrush() const
+ {
+ return brush_;
+ }
+
+ void SetBrush(Microsoft::WRL::ComPtr<ID2D1Brush> new_brush);
+
+ Microsoft::WRL::ComPtr<ID2D1StrokeStyle> GetStrokeStyle() const
+ {
+ return stroke_style_;
+ }
+
+ void SetStrokeStyle(Microsoft::WRL::ComPtr<ID2D1StrokeStyle> new_stroke_style);
+
+ private:
+ float stroke_width_ = 1.0f;
+ Microsoft::WRL::ComPtr<ID2D1Brush> brush_ = nullptr;
+ Microsoft::WRL::ComPtr<ID2D1StrokeStyle> stroke_style_ = nullptr;
+ };
+
+
+ class FillRenderObject : public virtual RenderObject
+ {
+ protected:
+ FillRenderObject() = default;
+ public:
+ FillRenderObject(const FillRenderObject& other) = delete;
+ FillRenderObject(FillRenderObject&& other) = delete;
+ FillRenderObject& operator=(const FillRenderObject& other) = delete;
+ FillRenderObject& operator=(FillRenderObject&& other) = delete;
+ ~FillRenderObject() override = default;
+
+ Microsoft::WRL::ComPtr<ID2D1Brush> GetBrush() const
+ {
+ return brush_;
+ }
+
+ void SetBrush(Microsoft::WRL::ComPtr<ID2D1Brush> new_brush);
+
+ private:
+ Microsoft::WRL::ComPtr<ID2D1Brush> brush_ = nullptr;
+ };
+
+
+ class RoundedRectangleRenderObject : public virtual RenderObject
+ {
+ 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
+ {
+ 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);
+ };
+
+
+ class RoundedRectangleStrokeRenderObject final : public StrokeRenderObject, public RoundedRectangleRenderObject
+ {
+ public:
+ RoundedRectangleStrokeRenderObject() = default;
+ RoundedRectangleStrokeRenderObject(const RoundedRectangleStrokeRenderObject& other) = delete;
+ RoundedRectangleStrokeRenderObject(RoundedRectangleStrokeRenderObject&& other) = delete;
+ RoundedRectangleStrokeRenderObject& operator=(const RoundedRectangleStrokeRenderObject& other) = delete;
+ RoundedRectangleStrokeRenderObject& operator=(RoundedRectangleStrokeRenderObject&& other) = delete;
+ ~RoundedRectangleStrokeRenderObject() override = default;
+
+ protected:
+ void Draw(ID2D1RenderTarget* render_target) override;
+ };
+
+
+ class CustomDrawHandlerRenderObject : public RenderObject
+ {
+ public:
+ using DrawHandler = std::function<void(ID2D1RenderTarget*)>;
+
+ CustomDrawHandlerRenderObject() = default;
+ CustomDrawHandlerRenderObject(const CustomDrawHandlerRenderObject& other) = delete;
+ CustomDrawHandlerRenderObject& operator=(const CustomDrawHandlerRenderObject& other) = delete;
+ CustomDrawHandlerRenderObject(CustomDrawHandlerRenderObject&& other) = delete;
+ CustomDrawHandlerRenderObject& operator=(CustomDrawHandlerRenderObject&& other) = delete;
+ ~CustomDrawHandlerRenderObject() override = default;
+
+ DrawHandler GetDrawHandler() const
+ {
+ return draw_handler_;
+ }
+
+ void SetDrawHandler(DrawHandler new_draw_handler);
+
+ protected:
+ void Draw(ID2D1RenderTarget* render_target) override;
+
+ private:
+ DrawHandler draw_handler_{};
+ };
- class CustomDrawHandlerRenderObject; //TODO!
class ContainerRenderObject; //TODO!
@@ -215,7 +359,7 @@ namespace cru::ui::render
// |
// ContainerRO
// / |
- // BorderRO OffsetRO (padding offset)
+ // StrokeRO (border) OffsetRO (padding offset)
// / | \
// / | \
// / | \
@@ -224,7 +368,7 @@ namespace cru::ui::render
// / | \
// ContainerRO (background) | ContainerRO (foreground, symmetrical to background)
// / \ | / \
- // GeometryFillRO CustomDrawHandlerRO | GeometryFillRO CustomDrawHandlerRO
+ // FillRO CustomDrawHandlerRO | FillRO CustomDrawHandlerRO
// |
// OffsetRO (content offset)
// |
@@ -247,13 +391,13 @@ namespace cru::ui::render
~ControlRenderObject() override = default;
- D2D1_MATRIX_3X2_F GetControlTransform() const;
- Microsoft::WRL::ComPtr<ID2D1Geometry> GetControlClip() const;
+ MatrixRenderObject* GetControlTransformRenderObject() const;
+ ClipRenderObject* GetControlClipRenderObject() const;
- Point GetBorderOffset() const;
- BorderRenderObject* GetBorderRenderObject() const;
+ OffsetRenderObject* GetBorderOffsetRenderObject() const;
+ RoundedRectangleStrokeRenderObject* GetBorderRenderObject() const;
- Point GetPaddingOffset() const;
+ OffsetRenderObject* GetPaddingOffsetRenderObject() const;
Microsoft::WRL::ComPtr<ID2D1Geometry> GetPaddingGeometry() const;
Point GetContentOffset() const;
diff --git a/src/ui/ui_base.hpp b/src/ui/ui_base.hpp
index b898b2ed..5350e4e9 100644
--- a/src/ui/ui_base.hpp
+++ b/src/ui/ui_base.hpp
@@ -188,6 +188,20 @@ namespace cru::ui
float height = 0.0f;
};
+ constexpr bool operator==(const Rect& left, const Rect& right)
+ {
+ return left.left == right.left &&
+ left.top == right.top &&
+ left.width == right.width &&
+ left.height == right.height;
+ }
+
+ constexpr bool operator!=(const Rect& left, const Rect& right)
+ {
+ return !(left == right);
+ }
+
+
enum class MouseButton
{
Left,