diff options
author | crupest <crupest@outlook.com> | 2019-04-01 18:08:58 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2019-04-01 18:08:58 +0800 |
commit | de00126c6aeba189a50296df455dd516e21e4176 (patch) | |
tree | 3d89a8a36a3603096d4371230c2d071f91e9e986 | |
parent | 055a3cde0cd19c896f3e498b774078654555c065 (diff) | |
download | cru-de00126c6aeba189a50296df455dd516e21e4176.tar.gz cru-de00126c6aeba189a50296df455dd516e21e4176.tar.bz2 cru-de00126c6aeba189a50296df455dd516e21e4176.zip |
...
18 files changed, 213 insertions, 94 deletions
diff --git a/include/cru/platform/matrix.hpp b/include/cru/platform/matrix.hpp new file mode 100644 index 00000000..e5e5cf42 --- /dev/null +++ b/include/cru/platform/matrix.hpp @@ -0,0 +1,84 @@ +#include "cru/common/pre_config.hpp" + +#include "cru/common/ui_base.hpp" + +#include <cmath> + +namespace cru::platform { +struct Matrix { + float m11; + float m12; + float m21; + float m22; + float m31; + float m32; + + Matrix() {} + + Matrix(float m11, float m12, float m21, float m22, float m31, float m32) { + this->m11 = m11; + this->m12 = m12; + this->m21 = m21; + this->m22 = m22; + this->m31 = m31; + this->m32 = m32; + } + + bool IsIdentity() const { + return m11 == 1.0f && m12 == 0.0f && m21 == 0.0f && m22 == 1.0f && + m31 == 0.0f && m32 == 0.0f; + } + + Matrix& operator*=(const Matrix& matrix) const { + *this = Product(*this, matrix); + return *this; + } + + Matrix operator*(const Matrix& matrix) const { return Product(this, matrix); } + + ui::Point TransformPoint(const ui::Point& point) const { + return ui::Point{point.x * m11 + point.y * m21 + m31, + point.x * m12 + point.y * m22 + m32}; + } + + static Matrix Identity() { + return Matrix{1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f}; + } + + static Matrix Translation(float x, float y) { + return Matrix{1.0f, 0.0f, 0.0f, 1.0f, x, y}; + } + + static Matrix Scale(float sx, float sy) { return Scale(sx, sy, 0.0f, 0.0f); } + + static Matrix Scale(float sx, float sy, float cx, float cy) { + return Matrix{sx, 0.0f, 0.0f, sy, cx - sx * cx, cy - sy * cy}; + } + + static Matrix Rotation(float angle) { + float r = AngleToRadian(angle); + float s = std::sinf(r); + float c = std::cosf(r); + + return Matrix{c, s, -s, c, 0.0f, 0.0f}; + } + + static Matrix Skew(float sx, float sy) { + return Matrix{1.0f, sx, sy, 1.0f, 0.0f, 0.0f}; + } + + static Matrix Product(const Matrix& a, const Matrix& b) { + return Matrix{a.m11 * b.m11 + a.m12 * b.m21, + a.m11 * b.m12 + a.m12 * b.m22, + a.m21 * b.m11 + a.m22 * b.m21, + a.m21 * b.m12 + a.m22 * b.m22, + a.m31 * b.m11 + a.m32 * b.m21 + b.m31, + a.m31 * b.m12 + a.m32 * b.m22 + b.m32}; + } + + private: + static constexpr float PI = 3.1415926535f; + + static float AngleToRadian(float angle) { return angle / 180.f * PI; } +}; +} // namespace cru::platform diff --git a/include/cru/platform/painter.hpp b/include/cru/platform/painter.hpp index 77ca5098..2e979184 100644 --- a/include/cru/platform/painter.hpp +++ b/include/cru/platform/painter.hpp @@ -2,12 +2,15 @@ #include "cru/common/base.hpp" #include "cru/common/ui_base.hpp" +#include "matrix.hpp" namespace cru::platform { struct Brush; struct Geometry; struct Painter : virtual Interface { + virtual Matrix GetTransform() = 0; + virtual void SetTransform(const Matrix& matrix) = 0; virtual void StrokeGeometry(Geometry* geometry, Brush* brush, float width) = 0; virtual void FillGeometry(Geometry* geometry, Brush* brush) = 0; diff --git a/include/cru/platform/painter_util.hpp b/include/cru/platform/painter_util.hpp new file mode 100644 index 00000000..fed0c487 --- /dev/null +++ b/include/cru/platform/painter_util.hpp @@ -0,0 +1,14 @@ +#pragma once +#include "painter.hpp" + +#include <functional> + +namespace cru::platform::util { +inline void WithTransform(Painter* painter, const Matrix& matrix, + const std::function<void(Painter*)>& action) { + const auto old = painter->GetTransform(); + painter->SetTransform(old * matrix); + action(painter); + painter->SetTransform(old); +} +} diff --git a/include/cru/platform/win/d2d_util.hpp b/include/cru/platform/win/d2d_util.hpp index 9ff6556a..51aea4f8 100644 --- a/include/cru/platform/win/d2d_util.hpp +++ b/include/cru/platform/win/d2d_util.hpp @@ -1,9 +1,21 @@ #pragma once #include "win_pre_config.hpp" +#include "../matrix.hpp" #include "cru/common/ui_base.hpp" namespace cru::platform::win::util { +inline D2D1_MATRIX_3X2_F Convert(const Matrix& matrix) { + D2D1_MATRIX_3X2_F m; + m._11 = matrix.m11; + m._12 = matrix.m12; + m._21 = matrix.m21; + m._22 = matrix.m22; + m._31 = matrix.m31; + m._32 = matrix.m32; + return m; +} + inline D2D1_COLOR_F Convert(const ui::Color& color) { return D2D1::ColorF(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f, color.alpha / 255.0f); @@ -28,6 +40,11 @@ inline D2D1_ELLIPSE Convert(const ui::Ellipse& ellipse) { ellipse.radius_y); } +inline Matrix Convert(const D2D1_MATRIX_3X2_F& matrix) { + return Matrix{matrix._11, matrix._12, matrix._21, + matrix._22, matrix._31, matrix._32}; +} + inline ui::Color Convert(const D2D1_COLOR_F& color) { auto floor = [](float n) { return static_cast<std::uint8_t>(n + 0.5f); }; return ui::Color{floor(color.r * 255.0f), floor(color.g * 255.0f), diff --git a/include/cru/platform/win/win_painter.hpp b/include/cru/platform/win/win_painter.hpp index 7b71ccbd..1e449d85 100644 --- a/include/cru/platform/win/win_painter.hpp +++ b/include/cru/platform/win/win_painter.hpp @@ -15,6 +15,8 @@ class WinPainter : public Object, public virtual Painter { WinPainter& operator=(WinPainter&& other) = delete; ~WinPainter() override; + Matrix GetTransform() override; + void SetTransform(const Matrix& matrix) override; void StrokeGeometry(Geometry* geometry, Brush* brush, float width) override; void FillGeometry(Geometry* geometry, Brush* brush) override; void EndDraw() override; diff --git a/src/ui/events/ui_event.hpp b/include/cru/ui/event/ui_event.hpp index 7fe4e6eb..ba8940cb 100644 --- a/src/ui/events/ui_event.hpp +++ b/include/cru/ui/event/ui_event.hpp @@ -1,24 +1,25 @@ #pragma once -#include "pre.hpp" +#include "cru/common/base.hpp" -#include <optional> +#include "cru/common/event.hpp" +#include "cru/common/ui_base.hpp" +#include "cru/platform/basic_types.hpp" -#include "base.hpp" -#include "cru_event.hpp" -#include "ui/ui_base.hpp" -#include "ui/input_util.hpp" +#include <optional> -struct ID2D1RenderTarget; +namespace cru::platform { +struct Painter; +} namespace cru::ui { class Control; } -namespace cru::ui::events { -class UiEventArgs : public BasicEventArgs { +namespace cru::ui::event { +class UiEventArgs : public Object { public: UiEventArgs(Object* sender, Object* original_sender) - : BasicEventArgs(sender), + : sender_(sender), original_sender_(original_sender), handled_(false) {} @@ -31,10 +32,10 @@ class UiEventArgs : public BasicEventArgs { Object* GetOriginalSender() const { return original_sender_; } bool IsHandled() const { return handled_; } - void SetHandled(const bool handled = true) { handled_ = handled; } private: + Object* sender_; Object* original_sender_; bool handled_; }; @@ -70,7 +71,7 @@ class MouseEventArgs : public UiEventArgs { MouseEventArgs& operator=(MouseEventArgs&& other) = default; ~MouseEventArgs() override = default; - Point GetPoint() const { return point_.value_or(Point::Zero()); } + Point GetPoint() const { return point_.value_or(Point{}); } private: std::optional<Point> point_; @@ -79,7 +80,7 @@ class MouseEventArgs : public UiEventArgs { class MouseButtonEventArgs : public MouseEventArgs { public: MouseButtonEventArgs(Object* sender, Object* original_sender, - const Point& point, const MouseButton button) + const Point& point, const platform::MouseButton button) : MouseEventArgs(sender, original_sender, point), button_(button) {} MouseButtonEventArgs(const MouseButtonEventArgs& other) = default; MouseButtonEventArgs(MouseButtonEventArgs&& other) = default; @@ -87,10 +88,10 @@ class MouseButtonEventArgs : public MouseEventArgs { MouseButtonEventArgs& operator=(MouseButtonEventArgs&& other) = default; ~MouseButtonEventArgs() override = default; - MouseButton GetMouseButton() const { return button_; } + platform::MouseButton GetMouseButton() const { return button_; } private: - MouseButton button_; + platform::MouseButton button_; }; class MouseWheelEventArgs : public MouseEventArgs { @@ -110,21 +111,21 @@ class MouseWheelEventArgs : public MouseEventArgs { float delta_; }; -class DrawEventArgs : public UiEventArgs { +class PaintEventArgs : public UiEventArgs { public: - DrawEventArgs(Object* sender, Object* original_sender, - ID2D1RenderTarget* render_target) - : UiEventArgs(sender, original_sender), render_target_(render_target) {} - DrawEventArgs(const DrawEventArgs& other) = default; - DrawEventArgs(DrawEventArgs&& other) = default; - DrawEventArgs& operator=(const DrawEventArgs& other) = default; - DrawEventArgs& operator=(DrawEventArgs&& other) = default; - ~DrawEventArgs() = default; + PaintEventArgs(Object* sender, Object* original_sender, + platform::Painter* painter) + : UiEventArgs(sender, original_sender), painter_(painter) {} + PaintEventArgs(const PaintEventArgs& other) = default; + PaintEventArgs(PaintEventArgs&& other) = default; + PaintEventArgs& operator=(const PaintEventArgs& other) = default; + PaintEventArgs& operator=(PaintEventArgs&& other) = default; + ~PaintEventArgs() = default; - ID2D1RenderTarget* GetRenderTarget() const { return render_target_; } + platform::Painter* GetPainter() const { return painter_; } private: - ID2D1RenderTarget* render_target_; + platform::Painter* painter_; }; class FocusChangeEventArgs : public UiEventArgs { @@ -145,6 +146,7 @@ class FocusChangeEventArgs : public UiEventArgs { bool is_window_; }; +/* class ToggleEventArgs : public UiEventArgs { public: ToggleEventArgs(Object* sender, Object* original_sender, bool new_state) @@ -160,6 +162,7 @@ class ToggleEventArgs : public UiEventArgs { private: bool new_state_; }; +*/ class KeyEventArgs : public UiEventArgs { public: @@ -177,6 +180,7 @@ class KeyEventArgs : public UiEventArgs { int virtual_code_; }; +/* class CharEventArgs : public UiEventArgs { public: CharEventArgs(Object* sender, Object* original_sender, wchar_t c) @@ -192,4 +196,5 @@ class CharEventArgs : public UiEventArgs { private: wchar_t c_; }; +*/ } // namespace cru::ui::events diff --git a/src/ui/render/border_render_object.hpp b/include/cru/ui/render/border_render_object.hpp index 80db648a..a96ccf99 100644 --- a/src/ui/render/border_render_object.hpp +++ b/include/cru/ui/render/border_render_object.hpp @@ -1,13 +1,9 @@ #pragma once -#include "pre.hpp" - -#include <wrl/client.h> // for ComPtr - #include "render_object.hpp" -// forward declarations -struct ID2D1Brush; -struct ID2D1Geometry; +namespace cru::platform { +struct Brush; +} namespace cru::ui::render { struct CornerRadius { @@ -33,7 +29,7 @@ struct CornerRadius { class BorderRenderObject : public RenderObject { public: - explicit BorderRenderObject(ID2D1Brush* brush); + explicit BorderRenderObject(platform::Brush* brush); BorderRenderObject(const BorderRenderObject& other) = delete; BorderRenderObject(BorderRenderObject&& other) = delete; BorderRenderObject& operator=(const BorderRenderObject& other) = delete; diff --git a/src/ui/render/flex_layout_render_object.hpp b/include/cru/ui/render/flex_layout_render_object.hpp index ac4c2c0f..278bf8c2 100644 --- a/src/ui/render/flex_layout_render_object.hpp +++ b/include/cru/ui/render/flex_layout_render_object.hpp @@ -1,10 +1,8 @@ #pragma once -#include "pre.hpp" +#include "render_object.hpp" #include <optional> -#include "render_object.hpp" - namespace cru::ui::render { enum class FlexDirection { Horizontal, @@ -40,7 +38,7 @@ class FlexLayoutRenderObject : public RenderObject { FlexChildLayoutData* GetChildLayoutData(int position); - void Draw(ID2D1RenderTarget* render_target) override; + void Draw(platform::Painter* painter) override; RenderObject* HitTest(const Point& point) override; diff --git a/src/ui/render/render_object.hpp b/include/cru/ui/render/render_object.hpp index 824b88e6..3cd14a6a 100644 --- a/src/ui/render/render_object.hpp +++ b/include/cru/ui/render/render_object.hpp @@ -1,19 +1,20 @@ #pragma once -#include "pre.hpp" +#include "cru/common/base.hpp" -#include <vector> +#include "cru/common/ui_base.hpp" -#include "base.hpp" -#include "ui/ui_base.hpp" +#include <vector> // forward declarations -struct ID2D1RenderTarget; namespace cru::ui { class Control; } -namespace cru::ui::render { +namespace cru::platform { +struct Painter; +} +namespace cru::ui::render { class RenderObject : public Object { protected: RenderObject() = default; @@ -57,7 +58,7 @@ class RenderObject : public Object { void Measure(const Size& available_size); void Layout(const Rect& rect); - virtual void Draw(ID2D1RenderTarget* render_target) = 0; + virtual void Draw(platform::Painter* render_target) = 0; virtual RenderObject* HitTest(const Point& point) = 0; @@ -86,12 +87,12 @@ class RenderObject : public Object { RenderObject* parent_ = nullptr; std::vector<RenderObject*> children_{}; - Point offset_ = Point::Zero(); - Size size_ = Size::Zero(); + Point offset_{}; + Size size_{}; - Thickness margin_ = Thickness::Zero(); - Thickness padding_ = Thickness::Zero(); + Thickness margin_{}; + Thickness padding_{}; - Size preferred_size_ = Size::Zero(); + Size preferred_size_{}; }; } // namespace cru::ui::render diff --git a/src/ui/render/text_render_object.hpp b/include/cru/ui/render/text_render_object.hpp index 7827f994..7827f994 100644 --- a/src/ui/render/text_render_object.hpp +++ b/include/cru/ui/render/text_render_object.hpp diff --git a/src/ui/render/window_render_object.hpp b/include/cru/ui/render/window_render_object.hpp index 63eb8588..63eb8588 100644 --- a/src/ui/render/window_render_object.hpp +++ b/include/cru/ui/render/window_render_object.hpp diff --git a/src/platform_win/string_util.cpp b/src/platform_win/string_util.cpp index 21d82c81..8ae069c0 100644 --- a/src/platform_win/string_util.cpp +++ b/src/platform_win/string_util.cpp @@ -14,7 +14,7 @@ std::string ToUtf8String(const std::wstring_view& string) { static_cast<int>(result.size()), nullptr, nullptr) == 0) throw win::Win32Error(::GetLastError(), - "Failed to convert wide string to UTF-8."); + "Failed to convert wide string to UTF-8."); return result; } -} // namespace cru::util +} // namespace cru::platform::util diff --git a/src/platform_win/win_painter.cpp b/src/platform_win/win_painter.cpp index 29777669..748d5766 100644 --- a/src/platform_win/win_painter.cpp +++ b/src/platform_win/win_painter.cpp @@ -1,5 +1,6 @@ #include "cru/platform/win/win_painter.hpp" +#include "cru/platform/win/d2d_util.hpp" #include "cru/platform/win/exception.hpp" #include "cru/platform/win/graph_manager.hpp" #include "cru/platform/win/win_brush.hpp" @@ -26,6 +27,16 @@ WinPainter::~WinPainter() { } } +Matrix WinPainter::GetTransform() { + D2D1_MATRIX_3X2_F m; + render_target_->GetTransform(&m); + return util::Convert(m); +} + +void WinPainter::SetTransform(const Matrix& matrix) { + render_target_->SetTransform(util::Convert(matrix)); +} + void WinPainter::StrokeGeometry(Geometry* geometry, Brush* brush, float width) { assert(!IsDisposed()); const auto g = dynamic_cast<WinGeometry*>(geometry); diff --git a/src/ui/control.hpp b/src/ui/control.hpp index 2504aa62..b69734d6 100644 --- a/src/ui/control.hpp +++ b/src/ui/control.hpp @@ -1,17 +1,15 @@ #pragma once -#include "pre.hpp" +#include "cru/common/base.hpp" -#include "base.hpp" -#include "events/ui_event.hpp" -#include "ui_base.hpp" +#include "cru/ui/event/ui_event.hpp" + +#include "" + +#include <string_view> namespace cru::ui { class Window; -namespace render { -class RenderObject; -} - class Control : public Object { friend class Window; @@ -26,7 +24,7 @@ class Control : public Object { ~Control() override = default; public: - virtual StringView GetControlType() const = 0; + virtual std::wstring_view GetControlType() const = 0; //*************** region: tree *************** public: diff --git a/src/ui/render/border_render_object.cpp b/src/ui/render/border_render_object.cpp index 72cea756..8b6b8d25 100644 --- a/src/ui/render/border_render_object.cpp +++ b/src/ui/render/border_render_object.cpp @@ -1,7 +1,5 @@ -#include "border_render_object.hpp" +#include "cru/ui/render/border_render_object.hpp" -#include <d2d1_1.h> -#include <wrl/client.h> #include <algorithm> #include "cru_debug.hpp" diff --git a/src/ui/render/flex_layout_render_object.cpp b/src/ui/render/flex_layout_render_object.cpp index e4d327f1..0e2e8ff7 100644 --- a/src/ui/render/flex_layout_render_object.cpp +++ b/src/ui/render/flex_layout_render_object.cpp @@ -1,12 +1,15 @@ -#include "flex_layout_render_object.hpp" +#include "cru/ui/render/flex_layout_render_object.hpp" + +#include "cru/platform/debug.hpp" +#include "cru/platform/painter_util.hpp" #include <algorithm> +#include <cassert> #include <functional> -#include "cru_debug.hpp" -#include "graph/graph_util.hpp" - namespace cru::ui::render { +using namespace platform; + FlexChildLayoutData* FlexLayoutRenderObject::GetChildLayoutData(int position) { assert(position >= 0 && position < child_layout_data_.size()); // Position out of bound. @@ -14,12 +17,11 @@ FlexChildLayoutData* FlexLayoutRenderObject::GetChildLayoutData(int position) { return &child_layout_data_[position]; } -void FlexLayoutRenderObject::Draw(ID2D1RenderTarget* render_target) { +void FlexLayoutRenderObject::Draw(platform::Painter* painter) { for (const auto child : GetChildren()) { auto offset = child->GetOffset(); - graph::WithTransform(render_target, - D2D1::Matrix3x2F::Translation(offset.x, offset.y), - [child](auto rt) { child->Draw(rt); }); + util::WithTransform(painter, Matrix::Translation(offset.x, offset.y), + [child](auto rt) { child->Draw(rt); }); } } @@ -171,7 +173,7 @@ void FlexLayoutRenderObject::OnLayoutContent(const Rect& content_rect) { case Alignment::End: return start_point + total_length - content_length; default: - UnreachableCode(); + return 0; } }; diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp index 5c6af580..111128b2 100644 --- a/src/ui/render/render_object.cpp +++ b/src/ui/render/render_object.cpp @@ -1,8 +1,9 @@ -#include "render_object.hpp" +#include "cru/ui/render/render_object.hpp" -#include <algorithm> +#include "cru/platform/debug.hpp" -#include "cru_debug.hpp" +#include <algorithm> +#include <cassert> namespace cru::ui::render { void RenderObject::AddChild(RenderObject* render_object, const int position) { @@ -34,7 +35,7 @@ void RenderObject::Measure(const Size& available_size) { void RenderObject::Layout(const Rect& rect) { SetOffset(rect.GetLeftTop()); SetSize(rect.GetSize()); - OnLayoutCore(Rect{Point::Zero(), rect.GetSize()}); + OnLayoutCore(Rect{Point{}, rect.GetSize()}); } void RenderObject::OnParentChanged(RenderObject* old_parent, @@ -53,13 +54,13 @@ void RenderObject::OnMeasureCore(const Size& available_size) { auto coerced_margin_padding_size = margin_padding_size; if (coerced_margin_padding_size.width > available_size.width) { - debug::DebugMessage( + platform::debug::DebugMessage( L"Measure: horizontal length of padding and margin is bigger than " L"available length."); coerced_margin_padding_size.width = available_size.width; } if (coerced_margin_padding_size.height > available_size.height) { - debug::DebugMessage( + platform::debug::DebugMessage( L"Measure: vertical length of padding and margin is bigger than " L"available length."); coerced_margin_padding_size.height = available_size.height; @@ -81,13 +82,13 @@ void RenderObject::OnLayoutCore(const Rect& rect) { auto coerced_content_available_size = content_available_size; if (coerced_content_available_size.width < 0) { - debug::DebugMessage( + platform::debug::DebugMessage( L"Layout: horizontal length of padding and margin is bigger than " L"available length."); coerced_content_available_size.width = 0; } if (coerced_content_available_size.height < 0) { - debug::DebugMessage( + platform::debug::DebugMessage( L"Layout: vertical length of padding and margin is bigger than " L"available length."); coerced_content_available_size.height = 0; @@ -99,7 +100,7 @@ void RenderObject::OnLayoutCore(const Rect& rect) { } Rect RenderObject::GetContentRect() const { - Rect rect{Point::Zero(), GetSize()}; + Rect rect{Point{}, GetSize()}; rect = rect.Shrink(GetMargin()); rect = rect.Shrink(GetPadding()); rect.width = std::max(rect.width, 0.0f); diff --git a/src/ui/window.hpp b/src/ui/window.hpp index 1e480454..f38743dc 100644 --- a/src/ui/window.hpp +++ b/src/ui/window.hpp @@ -1,29 +1,18 @@ #pragma once -#include "pre.hpp" +#include "cru/common/pre_config.hpp" -#include <Windows.h> #include <map> #include <memory> #include "content_control.hpp" #include "events/ui_event.hpp" -#include "events/window_event.hpp" #include "window_class.hpp" -namespace cru::graph { -class WindowRenderTarget; -} - -namespace cru::ui::render { -class WindowRenderObject; -} namespace cru::ui { class Window final : public ContentControl { - friend class WindowManager; - public: static constexpr auto control_type = L"Window"; |