From de00126c6aeba189a50296df455dd516e21e4176 Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 1 Apr 2019 18:08:58 +0800 Subject: ... --- include/cru/platform/matrix.hpp | 84 +++++++++ include/cru/platform/painter.hpp | 3 + include/cru/platform/painter_util.hpp | 14 ++ include/cru/platform/win/d2d_util.hpp | 17 ++ include/cru/platform/win/win_painter.hpp | 2 + include/cru/ui/event/ui_event.hpp | 200 +++++++++++++++++++++ include/cru/ui/render/border_render_object.hpp | 88 +++++++++ .../cru/ui/render/flex_layout_render_object.hpp | 57 ++++++ include/cru/ui/render/render_object.hpp | 98 ++++++++++ include/cru/ui/render/text_render_object.hpp | 69 +++++++ include/cru/ui/render/window_render_object.hpp | 40 +++++ src/platform_win/string_util.cpp | 4 +- src/platform_win/win_painter.cpp | 11 ++ src/ui/control.hpp | 16 +- src/ui/events/ui_event.hpp | 195 -------------------- src/ui/render/border_render_object.cpp | 4 +- src/ui/render/border_render_object.hpp | 92 ---------- src/ui/render/flex_layout_render_object.cpp | 20 ++- src/ui/render/flex_layout_render_object.hpp | 59 ------ src/ui/render/render_object.cpp | 19 +- src/ui/render/render_object.hpp | 97 ---------- src/ui/render/text_render_object.hpp | 69 ------- src/ui/render/window_render_object.hpp | 40 ----- src/ui/window.hpp | 13 +- 24 files changed, 715 insertions(+), 596 deletions(-) create mode 100644 include/cru/platform/matrix.hpp create mode 100644 include/cru/platform/painter_util.hpp create mode 100644 include/cru/ui/event/ui_event.hpp create mode 100644 include/cru/ui/render/border_render_object.hpp create mode 100644 include/cru/ui/render/flex_layout_render_object.hpp create mode 100644 include/cru/ui/render/render_object.hpp create mode 100644 include/cru/ui/render/text_render_object.hpp create mode 100644 include/cru/ui/render/window_render_object.hpp delete mode 100644 src/ui/events/ui_event.hpp delete mode 100644 src/ui/render/border_render_object.hpp delete mode 100644 src/ui/render/flex_layout_render_object.hpp delete mode 100644 src/ui/render/render_object.hpp delete mode 100644 src/ui/render/text_render_object.hpp delete mode 100644 src/ui/render/window_render_object.hpp 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 + +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 + +namespace cru::platform::util { +inline void WithTransform(Painter* painter, const Matrix& matrix, + const std::function& 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(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/include/cru/ui/event/ui_event.hpp b/include/cru/ui/event/ui_event.hpp new file mode 100644 index 00000000..ba8940cb --- /dev/null +++ b/include/cru/ui/event/ui_event.hpp @@ -0,0 +1,200 @@ +#pragma once +#include "cru/common/base.hpp" + +#include "cru/common/event.hpp" +#include "cru/common/ui_base.hpp" +#include "cru/platform/basic_types.hpp" + +#include + +namespace cru::platform { +struct Painter; +} + +namespace cru::ui { +class Control; +} + +namespace cru::ui::event { +class UiEventArgs : public Object { + public: + UiEventArgs(Object* sender, Object* original_sender) + : sender_(sender), + original_sender_(original_sender), + handled_(false) {} + + UiEventArgs(const UiEventArgs& other) = default; + UiEventArgs(UiEventArgs&& other) = default; + UiEventArgs& operator=(const UiEventArgs& other) = default; + UiEventArgs& operator=(UiEventArgs&& other) = default; + ~UiEventArgs() override = default; + + 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_; +}; + +template +class RoutedEvent { + public: + static_assert(std::is_base_of_v, + "TEventArgs must be subclass of UiEventArgs."); + + using EventArgs = TEventArgs; + + RoutedEvent() = default; + RoutedEvent(const RoutedEvent& other) = delete; + RoutedEvent(RoutedEvent&& other) = delete; + RoutedEvent& operator=(const RoutedEvent& other) = delete; + RoutedEvent& operator=(RoutedEvent&& other) = delete; + ~RoutedEvent() = default; + + Event direct; + Event bubble; + Event tunnel; +}; + +class MouseEventArgs : public UiEventArgs { + public: + MouseEventArgs(Object* sender, Object* original_sender, + const std::optional& point = std::nullopt) + : UiEventArgs(sender, original_sender), point_(point) {} + MouseEventArgs(const MouseEventArgs& other) = default; + MouseEventArgs(MouseEventArgs&& other) = default; + MouseEventArgs& operator=(const MouseEventArgs& other) = default; + MouseEventArgs& operator=(MouseEventArgs&& other) = default; + ~MouseEventArgs() override = default; + + Point GetPoint() const { return point_.value_or(Point{}); } + + private: + std::optional point_; +}; + +class MouseButtonEventArgs : public MouseEventArgs { + public: + MouseButtonEventArgs(Object* sender, Object* original_sender, + const Point& point, const platform::MouseButton button) + : MouseEventArgs(sender, original_sender, point), button_(button) {} + MouseButtonEventArgs(const MouseButtonEventArgs& other) = default; + MouseButtonEventArgs(MouseButtonEventArgs&& other) = default; + MouseButtonEventArgs& operator=(const MouseButtonEventArgs& other) = default; + MouseButtonEventArgs& operator=(MouseButtonEventArgs&& other) = default; + ~MouseButtonEventArgs() override = default; + + platform::MouseButton GetMouseButton() const { return button_; } + + private: + platform::MouseButton button_; +}; + +class MouseWheelEventArgs : public MouseEventArgs { + public: + MouseWheelEventArgs(Object* sender, Object* original_sender, + const Point& point, const float delta) + : MouseEventArgs(sender, original_sender, point), delta_(delta) {} + MouseWheelEventArgs(const MouseWheelEventArgs& other) = default; + MouseWheelEventArgs(MouseWheelEventArgs&& other) = default; + MouseWheelEventArgs& operator=(const MouseWheelEventArgs& other) = default; + MouseWheelEventArgs& operator=(MouseWheelEventArgs&& other) = default; + ~MouseWheelEventArgs() override = default; + + float GetDelta() const { return delta_; } + + private: + float delta_; +}; + +class PaintEventArgs : public UiEventArgs { + public: + 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; + + platform::Painter* GetPainter() const { return painter_; } + + private: + platform::Painter* painter_; +}; + +class FocusChangeEventArgs : public UiEventArgs { + public: + FocusChangeEventArgs(Object* sender, Object* original_sender, + const bool is_window = false) + : UiEventArgs(sender, original_sender), is_window_(is_window) {} + FocusChangeEventArgs(const FocusChangeEventArgs& other) = default; + FocusChangeEventArgs(FocusChangeEventArgs&& other) = default; + FocusChangeEventArgs& operator=(const FocusChangeEventArgs& other) = default; + FocusChangeEventArgs& operator=(FocusChangeEventArgs&& other) = default; + ~FocusChangeEventArgs() override = default; + + // Return whether the focus change is caused by the window-wide focus change. + bool IsWindow() const { return is_window_; } + + private: + bool is_window_; +}; + +/* +class ToggleEventArgs : public UiEventArgs { + public: + ToggleEventArgs(Object* sender, Object* original_sender, bool new_state) + : UiEventArgs(sender, original_sender), new_state_(new_state) {} + ToggleEventArgs(const ToggleEventArgs& other) = default; + ToggleEventArgs(ToggleEventArgs&& other) = default; + ToggleEventArgs& operator=(const ToggleEventArgs& other) = default; + ToggleEventArgs& operator=(ToggleEventArgs&& other) = default; + ~ToggleEventArgs() override = default; + + bool GetNewState() const { return new_state_; } + + private: + bool new_state_; +}; +*/ + +class KeyEventArgs : public UiEventArgs { + public: + KeyEventArgs(Object* sender, Object* original_sender, int virtual_code) + : UiEventArgs(sender, original_sender), virtual_code_(virtual_code) {} + KeyEventArgs(const KeyEventArgs& other) = default; + KeyEventArgs(KeyEventArgs&& other) = default; + KeyEventArgs& operator=(const KeyEventArgs& other) = default; + KeyEventArgs& operator=(KeyEventArgs&& other) = default; + ~KeyEventArgs() override = default; + + int GetVirtualCode() const { return virtual_code_; } + + private: + int virtual_code_; +}; + +/* +class CharEventArgs : public UiEventArgs { + public: + CharEventArgs(Object* sender, Object* original_sender, wchar_t c) + : UiEventArgs(sender, original_sender), c_(c) {} + CharEventArgs(const CharEventArgs& other) = default; + CharEventArgs(CharEventArgs&& other) = default; + CharEventArgs& operator=(const CharEventArgs& other) = default; + CharEventArgs& operator=(CharEventArgs&& other) = default; + ~CharEventArgs() override = default; + + wchar_t GetChar() const { return c_; } + + private: + wchar_t c_; +}; +*/ +} // namespace cru::ui::events diff --git a/include/cru/ui/render/border_render_object.hpp b/include/cru/ui/render/border_render_object.hpp new file mode 100644 index 00000000..a96ccf99 --- /dev/null +++ b/include/cru/ui/render/border_render_object.hpp @@ -0,0 +1,88 @@ +#pragma once +#include "render_object.hpp" + +namespace cru::platform { +struct Brush; +} + +namespace cru::ui::render { +struct CornerRadius { + constexpr CornerRadius() + : left_top(), right_top(), left_bottom(), right_bottom() {} + constexpr CornerRadius(const Point& value) + : left_top(value), + right_top(value), + left_bottom(value), + right_bottom(value) {} + constexpr CornerRadius(Point left_top, Point right_top, Point left_bottom, + Point right_bottom) + : left_top(left_top), + right_top(right_top), + left_bottom(left_bottom), + right_bottom(right_bottom) {} + + Point left_top; + Point right_top; + Point left_bottom; + Point right_bottom; +}; + +class BorderRenderObject : public RenderObject { + public: + explicit BorderRenderObject(platform::Brush* brush); + BorderRenderObject(const BorderRenderObject& other) = delete; + BorderRenderObject(BorderRenderObject&& other) = delete; + BorderRenderObject& operator=(const BorderRenderObject& other) = delete; + BorderRenderObject& operator=(BorderRenderObject&& other) = delete; + ~BorderRenderObject() override; + + bool IsEnabled() const { return is_enabled_; } + void SetEnabled(bool enabled) { is_enabled_ = enabled; } + + ID2D1Brush* GetBrush() const { return border_brush_; } + void SetBrush(ID2D1Brush* new_brush); + + Thickness GetBorderWidth() const { return border_thickness_; } + void SetBorderWidth(const Thickness& thickness) { + border_thickness_ = thickness; + } + + CornerRadius GetCornerRadius() const { return corner_radius_; } + void SetCornerRadius(const CornerRadius& new_corner_radius) { + corner_radius_ = new_corner_radius; + } + + void Refresh() { RecreateGeometry(); } + + void Draw(ID2D1RenderTarget* render_target) override; + + RenderObject* HitTest(const Point& point) override; + + protected: + void OnAddChild(RenderObject* new_child, int position) override; + + void OnSizeChanged(const Size& old_size, const Size& new_size) override; + + void OnMeasureCore(const Size& available_size) override; + void OnLayoutCore(const Rect& rect) override; + Size OnMeasureContent(const Size& available_size) override; + void OnLayoutContent(const Rect& content_rect) override; + + private: + RenderObject* GetChild() const { + return GetChildren().empty() ? nullptr : GetChildren()[0]; + } + + void RecreateGeometry(); + + private: + bool is_enabled_ = false; + + ID2D1Brush* border_brush_ = nullptr; + Thickness border_thickness_ = Thickness::Zero(); + CornerRadius corner_radius_{}; + + ID2D1Geometry* geometry_ = nullptr; + ID2D1Geometry* border_outer_geometry_ = nullptr; +}; +} // namespace cru::ui::render diff --git a/include/cru/ui/render/flex_layout_render_object.hpp b/include/cru/ui/render/flex_layout_render_object.hpp new file mode 100644 index 00000000..278bf8c2 --- /dev/null +++ b/include/cru/ui/render/flex_layout_render_object.hpp @@ -0,0 +1,57 @@ +#pragma once +#include "render_object.hpp" + +#include + +namespace cru::ui::render { +enum class FlexDirection { + Horizontal, + HorizontalReverse, + Vertical, + VertivalReverse +}; + +enum class Alignment { Start, End, Center }; + +struct FlexChildLayoutData { + std::optional flex_basis; // nullopt stands for content + float flex_grow = 0; + float flex_shrink = 0; + Alignment alignment = Alignment::Center; +}; + +class FlexLayoutRenderObject : public RenderObject { + public: + FlexLayoutRenderObject() = default; + FlexLayoutRenderObject(const FlexLayoutRenderObject& other) = delete; + FlexLayoutRenderObject& operator=(const FlexLayoutRenderObject& other) = + delete; + FlexLayoutRenderObject(FlexLayoutRenderObject&& other) = delete; + FlexLayoutRenderObject& operator=(FlexLayoutRenderObject&& other) = delete; + ~FlexLayoutRenderObject() override = default; + + FlexDirection GetFlexDirection() const { return direction_; } + void SetFlexDirection(FlexDirection direction) { direction_ = direction; } + + Alignment GetContentMainAlign() const { return content_main_align_; } + void SetContentMainAlign(Alignment align) { content_main_align_ = align; } + + FlexChildLayoutData* GetChildLayoutData(int position); + + void Draw(platform::Painter* painter) override; + + RenderObject* HitTest(const Point& point) override; + + protected: + void OnAddChild(RenderObject* new_child, int position) override; + void OnRemoveChild(RenderObject* removed_child, int position) override; + + Size OnMeasureContent(const Size& available_size) override; + void OnLayoutContent(const Rect& content_rect) override; + + private: + FlexDirection direction_ = FlexDirection::Horizontal; + Alignment content_main_align_ = Alignment::Start; + std::vector child_layout_data_{}; +}; +} // namespace cru::ui::render diff --git a/include/cru/ui/render/render_object.hpp b/include/cru/ui/render/render_object.hpp new file mode 100644 index 00000000..3cd14a6a --- /dev/null +++ b/include/cru/ui/render/render_object.hpp @@ -0,0 +1,98 @@ +#pragma once +#include "cru/common/base.hpp" + +#include "cru/common/ui_base.hpp" + +#include + +// forward declarations +namespace cru::ui { +class Control; +} + +namespace cru::platform { +struct Painter; +} + +namespace cru::ui::render { +class RenderObject : public Object { + protected: + RenderObject() = default; + + public: + RenderObject(const RenderObject& other) = delete; + RenderObject(RenderObject&& other) = delete; + RenderObject& operator=(const RenderObject& other) = delete; + RenderObject& operator=(RenderObject&& other) = delete; + ~RenderObject() override = default; + + Control* GetAttachedControl() const { return control_; } + void SetAttachedControl(Control* new_control) { control_ = new_control; } + + RenderObject* GetParent() const { return parent_; } + + const std::vector& GetChildren() const { return children_; } + void AddChild(RenderObject* render_object, int position); + void RemoveChild(int position); + + Point GetOffset() const { return offset_; } + void SetOffset(const Point& offset) { offset_ = offset; } + Size GetSize() const { return size_; } + void SetSize(const Size& size) { + const auto old_size = size_; + size_ = size; + OnSizeChanged(old_size, size); + } + + Thickness GetMargin() const { return margin_; } + void SetMargin(const Thickness& margin) { margin_ = margin; } + + Thickness GetPadding() const { return padding_; } + void SetPadding(const Thickness& padding) { padding_ = padding; } + + Size GetPreferredSize() const { return preferred_size_; } + void SetPreferredSize(const Size& preferred_size) { + preferred_size_ = preferred_size; + } + + void Measure(const Size& available_size); + void Layout(const Rect& rect); + + virtual void Draw(platform::Painter* render_target) = 0; + + virtual RenderObject* HitTest(const Point& point) = 0; + + protected: + virtual void OnParentChanged(RenderObject* old_parent, + RenderObject* new_parent); + + virtual void OnAddChild(RenderObject* new_child, int position); + virtual void OnRemoveChild(RenderObject* removed_child, int position); + + virtual void OnSizeChanged(const Size& old_size, const Size& new_size); + + virtual void OnMeasureCore(const Size& available_size); + virtual void OnLayoutCore(const Rect& rect); + virtual Size OnMeasureContent(const Size& available_size) = 0; + virtual void OnLayoutContent(const Rect& content_rect) = 0; + + Rect GetContentRect() const; + + private: + void SetParent(RenderObject* new_parent); + + private: + Control* control_ = nullptr; + + RenderObject* parent_ = nullptr; + std::vector children_{}; + + Point offset_{}; + Size size_{}; + + Thickness margin_{}; + Thickness padding_{}; + + Size preferred_size_{}; +}; +} // namespace cru::ui::render diff --git a/include/cru/ui/render/text_render_object.hpp b/include/cru/ui/render/text_render_object.hpp new file mode 100644 index 00000000..7827f994 --- /dev/null +++ b/include/cru/ui/render/text_render_object.hpp @@ -0,0 +1,69 @@ +#pragma once +#include "pre.hpp" + +#include "render_object.hpp" + +// forward declarations +struct ID2D1Brush; +struct IDWriteTextFormat; +struct IDWriteTextLayout; + +namespace cru::ui::render { +class TextRenderObject : public RenderObject { + public: + TextRenderObject(ID2D1Brush* brush, IDWriteTextFormat* format, + ID2D1Brush* selection_brush); + TextRenderObject(const TextRenderObject& other) = delete; + TextRenderObject(TextRenderObject&& other) = delete; + TextRenderObject& operator=(const TextRenderObject& other) = delete; + TextRenderObject& operator=(TextRenderObject&& other) = delete; + ~TextRenderObject() override; + + String GetText() const { return text_; } + void SetText(String new_text) { + text_ = std::move(new_text); + RecreateTextLayout(); + } + + ID2D1Brush* GetBrush() const { return brush_; } + void SetBrush(ID2D1Brush* new_brush); + + IDWriteTextFormat* GetTextFormat() const { return text_format_; } + void SetTextFormat(IDWriteTextFormat* new_text_format); + + std::optional GetSelectionRange() const { + return selection_range_; + } + void SetSelectionRange(std::optional new_range) { + selection_range_ = std::move(new_range); + } + + ID2D1Brush* GetSelectionBrush() const { return selection_brush_; } + void SetSelectionBrush(ID2D1Brush* new_brush); + + void Refresh() { RecreateTextLayout(); } + + void Draw(ID2D1RenderTarget* render_target) override; + + RenderObject* HitTest(const Point& point) override; + + protected: + void OnSizeChanged(const Size& old_size, const Size& new_size) override; + + Size OnMeasureContent(const Size& available_size) override; + void OnLayoutContent(const Rect& content_rect) override; + + private: + void RecreateTextLayout(); + + private: + String text_; + + ID2D1Brush* brush_ = nullptr; + IDWriteTextFormat* text_format_ = nullptr; + IDWriteTextLayout* text_layout_ = nullptr; + + std::optional selection_range_ = std::nullopt; + ID2D1Brush* selection_brush_ = nullptr; +}; +} // namespace cru::ui::render diff --git a/include/cru/ui/render/window_render_object.hpp b/include/cru/ui/render/window_render_object.hpp new file mode 100644 index 00000000..63eb8588 --- /dev/null +++ b/include/cru/ui/render/window_render_object.hpp @@ -0,0 +1,40 @@ +#pragma once +#include "pre.hpp" + +#include "render_object.hpp" + +namespace cru::ui { +class Window; +} + +namespace cru::ui::render { +class WindowRenderObject : public RenderObject { + public: + WindowRenderObject(Window* window) : window_(window) {} + WindowRenderObject(const WindowRenderObject& other) = delete; + WindowRenderObject(WindowRenderObject&& other) = delete; + WindowRenderObject& operator=(const WindowRenderObject& other) = delete; + WindowRenderObject& operator=(WindowRenderObject&& other) = delete; + ~WindowRenderObject() override = default; + + void MeasureAndLayout(); + + void Draw(ID2D1RenderTarget* render_target) override; + + RenderObject* HitTest(const Point& point) override; + + protected: + void OnAddChild(RenderObject* new_child, int position) override; + + Size OnMeasureContent(const Size& available_size) override; + void OnLayoutContent(const Rect& content_rect) override; + + private: + RenderObject* GetChild() const { + return GetChildren().empty() ? nullptr : GetChildren()[0]; + } + + private: + Window* window_; +}; +} // namespace cru::ui::render 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(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(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 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/events/ui_event.hpp b/src/ui/events/ui_event.hpp deleted file mode 100644 index 7fe4e6eb..00000000 --- a/src/ui/events/ui_event.hpp +++ /dev/null @@ -1,195 +0,0 @@ -#pragma once -#include "pre.hpp" - -#include - -#include "base.hpp" -#include "cru_event.hpp" -#include "ui/ui_base.hpp" -#include "ui/input_util.hpp" - -struct ID2D1RenderTarget; - -namespace cru::ui { -class Control; -} - -namespace cru::ui::events { -class UiEventArgs : public BasicEventArgs { - public: - UiEventArgs(Object* sender, Object* original_sender) - : BasicEventArgs(sender), - original_sender_(original_sender), - handled_(false) {} - - UiEventArgs(const UiEventArgs& other) = default; - UiEventArgs(UiEventArgs&& other) = default; - UiEventArgs& operator=(const UiEventArgs& other) = default; - UiEventArgs& operator=(UiEventArgs&& other) = default; - ~UiEventArgs() override = default; - - Object* GetOriginalSender() const { return original_sender_; } - - bool IsHandled() const { return handled_; } - - void SetHandled(const bool handled = true) { handled_ = handled; } - - private: - Object* original_sender_; - bool handled_; -}; - -template -class RoutedEvent { - public: - static_assert(std::is_base_of_v, - "TEventArgs must be subclass of UiEventArgs."); - - using EventArgs = TEventArgs; - - RoutedEvent() = default; - RoutedEvent(const RoutedEvent& other) = delete; - RoutedEvent(RoutedEvent&& other) = delete; - RoutedEvent& operator=(const RoutedEvent& other) = delete; - RoutedEvent& operator=(RoutedEvent&& other) = delete; - ~RoutedEvent() = default; - - Event direct; - Event bubble; - Event tunnel; -}; - -class MouseEventArgs : public UiEventArgs { - public: - MouseEventArgs(Object* sender, Object* original_sender, - const std::optional& point = std::nullopt) - : UiEventArgs(sender, original_sender), point_(point) {} - MouseEventArgs(const MouseEventArgs& other) = default; - MouseEventArgs(MouseEventArgs&& other) = default; - MouseEventArgs& operator=(const MouseEventArgs& other) = default; - MouseEventArgs& operator=(MouseEventArgs&& other) = default; - ~MouseEventArgs() override = default; - - Point GetPoint() const { return point_.value_or(Point::Zero()); } - - private: - std::optional point_; -}; - -class MouseButtonEventArgs : public MouseEventArgs { - public: - MouseButtonEventArgs(Object* sender, Object* original_sender, - const Point& point, const MouseButton button) - : MouseEventArgs(sender, original_sender, point), button_(button) {} - MouseButtonEventArgs(const MouseButtonEventArgs& other) = default; - MouseButtonEventArgs(MouseButtonEventArgs&& other) = default; - MouseButtonEventArgs& operator=(const MouseButtonEventArgs& other) = default; - MouseButtonEventArgs& operator=(MouseButtonEventArgs&& other) = default; - ~MouseButtonEventArgs() override = default; - - MouseButton GetMouseButton() const { return button_; } - - private: - MouseButton button_; -}; - -class MouseWheelEventArgs : public MouseEventArgs { - public: - MouseWheelEventArgs(Object* sender, Object* original_sender, - const Point& point, const float delta) - : MouseEventArgs(sender, original_sender, point), delta_(delta) {} - MouseWheelEventArgs(const MouseWheelEventArgs& other) = default; - MouseWheelEventArgs(MouseWheelEventArgs&& other) = default; - MouseWheelEventArgs& operator=(const MouseWheelEventArgs& other) = default; - MouseWheelEventArgs& operator=(MouseWheelEventArgs&& other) = default; - ~MouseWheelEventArgs() override = default; - - float GetDelta() const { return delta_; } - - private: - float delta_; -}; - -class DrawEventArgs : 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; - - ID2D1RenderTarget* GetRenderTarget() const { return render_target_; } - - private: - ID2D1RenderTarget* render_target_; -}; - -class FocusChangeEventArgs : public UiEventArgs { - public: - FocusChangeEventArgs(Object* sender, Object* original_sender, - const bool is_window = false) - : UiEventArgs(sender, original_sender), is_window_(is_window) {} - FocusChangeEventArgs(const FocusChangeEventArgs& other) = default; - FocusChangeEventArgs(FocusChangeEventArgs&& other) = default; - FocusChangeEventArgs& operator=(const FocusChangeEventArgs& other) = default; - FocusChangeEventArgs& operator=(FocusChangeEventArgs&& other) = default; - ~FocusChangeEventArgs() override = default; - - // Return whether the focus change is caused by the window-wide focus change. - bool IsWindow() const { return is_window_; } - - private: - bool is_window_; -}; - -class ToggleEventArgs : public UiEventArgs { - public: - ToggleEventArgs(Object* sender, Object* original_sender, bool new_state) - : UiEventArgs(sender, original_sender), new_state_(new_state) {} - ToggleEventArgs(const ToggleEventArgs& other) = default; - ToggleEventArgs(ToggleEventArgs&& other) = default; - ToggleEventArgs& operator=(const ToggleEventArgs& other) = default; - ToggleEventArgs& operator=(ToggleEventArgs&& other) = default; - ~ToggleEventArgs() override = default; - - bool GetNewState() const { return new_state_; } - - private: - bool new_state_; -}; - -class KeyEventArgs : public UiEventArgs { - public: - KeyEventArgs(Object* sender, Object* original_sender, int virtual_code) - : UiEventArgs(sender, original_sender), virtual_code_(virtual_code) {} - KeyEventArgs(const KeyEventArgs& other) = default; - KeyEventArgs(KeyEventArgs&& other) = default; - KeyEventArgs& operator=(const KeyEventArgs& other) = default; - KeyEventArgs& operator=(KeyEventArgs&& other) = default; - ~KeyEventArgs() override = default; - - int GetVirtualCode() const { return virtual_code_; } - - private: - int virtual_code_; -}; - -class CharEventArgs : public UiEventArgs { - public: - CharEventArgs(Object* sender, Object* original_sender, wchar_t c) - : UiEventArgs(sender, original_sender), c_(c) {} - CharEventArgs(const CharEventArgs& other) = default; - CharEventArgs(CharEventArgs&& other) = default; - CharEventArgs& operator=(const CharEventArgs& other) = default; - CharEventArgs& operator=(CharEventArgs&& other) = default; - ~CharEventArgs() override = default; - - wchar_t GetChar() const { return c_; } - - private: - wchar_t c_; -}; -} // namespace cru::ui::events 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 -#include #include #include "cru_debug.hpp" diff --git a/src/ui/render/border_render_object.hpp b/src/ui/render/border_render_object.hpp deleted file mode 100644 index 80db648a..00000000 --- a/src/ui/render/border_render_object.hpp +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once -#include "pre.hpp" - -#include // for ComPtr - -#include "render_object.hpp" - -// forward declarations -struct ID2D1Brush; -struct ID2D1Geometry; - -namespace cru::ui::render { -struct CornerRadius { - constexpr CornerRadius() - : left_top(), right_top(), left_bottom(), right_bottom() {} - constexpr CornerRadius(const Point& value) - : left_top(value), - right_top(value), - left_bottom(value), - right_bottom(value) {} - constexpr CornerRadius(Point left_top, Point right_top, Point left_bottom, - Point right_bottom) - : left_top(left_top), - right_top(right_top), - left_bottom(left_bottom), - right_bottom(right_bottom) {} - - Point left_top; - Point right_top; - Point left_bottom; - Point right_bottom; -}; - -class BorderRenderObject : public RenderObject { - public: - explicit BorderRenderObject(ID2D1Brush* brush); - BorderRenderObject(const BorderRenderObject& other) = delete; - BorderRenderObject(BorderRenderObject&& other) = delete; - BorderRenderObject& operator=(const BorderRenderObject& other) = delete; - BorderRenderObject& operator=(BorderRenderObject&& other) = delete; - ~BorderRenderObject() override; - - bool IsEnabled() const { return is_enabled_; } - void SetEnabled(bool enabled) { is_enabled_ = enabled; } - - ID2D1Brush* GetBrush() const { return border_brush_; } - void SetBrush(ID2D1Brush* new_brush); - - Thickness GetBorderWidth() const { return border_thickness_; } - void SetBorderWidth(const Thickness& thickness) { - border_thickness_ = thickness; - } - - CornerRadius GetCornerRadius() const { return corner_radius_; } - void SetCornerRadius(const CornerRadius& new_corner_radius) { - corner_radius_ = new_corner_radius; - } - - void Refresh() { RecreateGeometry(); } - - void Draw(ID2D1RenderTarget* render_target) override; - - RenderObject* HitTest(const Point& point) override; - - protected: - void OnAddChild(RenderObject* new_child, int position) override; - - void OnSizeChanged(const Size& old_size, const Size& new_size) override; - - void OnMeasureCore(const Size& available_size) override; - void OnLayoutCore(const Rect& rect) override; - Size OnMeasureContent(const Size& available_size) override; - void OnLayoutContent(const Rect& content_rect) override; - - private: - RenderObject* GetChild() const { - return GetChildren().empty() ? nullptr : GetChildren()[0]; - } - - void RecreateGeometry(); - - private: - bool is_enabled_ = false; - - ID2D1Brush* border_brush_ = nullptr; - Thickness border_thickness_ = Thickness::Zero(); - CornerRadius corner_radius_{}; - - ID2D1Geometry* geometry_ = nullptr; - ID2D1Geometry* border_outer_geometry_ = nullptr; -}; -} // namespace cru::ui::render 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 +#include #include -#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/flex_layout_render_object.hpp b/src/ui/render/flex_layout_render_object.hpp deleted file mode 100644 index ac4c2c0f..00000000 --- a/src/ui/render/flex_layout_render_object.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once -#include "pre.hpp" - -#include - -#include "render_object.hpp" - -namespace cru::ui::render { -enum class FlexDirection { - Horizontal, - HorizontalReverse, - Vertical, - VertivalReverse -}; - -enum class Alignment { Start, End, Center }; - -struct FlexChildLayoutData { - std::optional flex_basis; // nullopt stands for content - float flex_grow = 0; - float flex_shrink = 0; - Alignment alignment = Alignment::Center; -}; - -class FlexLayoutRenderObject : public RenderObject { - public: - FlexLayoutRenderObject() = default; - FlexLayoutRenderObject(const FlexLayoutRenderObject& other) = delete; - FlexLayoutRenderObject& operator=(const FlexLayoutRenderObject& other) = - delete; - FlexLayoutRenderObject(FlexLayoutRenderObject&& other) = delete; - FlexLayoutRenderObject& operator=(FlexLayoutRenderObject&& other) = delete; - ~FlexLayoutRenderObject() override = default; - - FlexDirection GetFlexDirection() const { return direction_; } - void SetFlexDirection(FlexDirection direction) { direction_ = direction; } - - Alignment GetContentMainAlign() const { return content_main_align_; } - void SetContentMainAlign(Alignment align) { content_main_align_ = align; } - - FlexChildLayoutData* GetChildLayoutData(int position); - - void Draw(ID2D1RenderTarget* render_target) override; - - RenderObject* HitTest(const Point& point) override; - - protected: - void OnAddChild(RenderObject* new_child, int position) override; - void OnRemoveChild(RenderObject* removed_child, int position) override; - - Size OnMeasureContent(const Size& available_size) override; - void OnLayoutContent(const Rect& content_rect) override; - - private: - FlexDirection direction_ = FlexDirection::Horizontal; - Alignment content_main_align_ = Alignment::Start; - std::vector child_layout_data_{}; -}; -} // namespace cru::ui::render 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 +#include "cru/platform/debug.hpp" -#include "cru_debug.hpp" +#include +#include 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/render/render_object.hpp b/src/ui/render/render_object.hpp deleted file mode 100644 index 824b88e6..00000000 --- a/src/ui/render/render_object.hpp +++ /dev/null @@ -1,97 +0,0 @@ -#pragma once -#include "pre.hpp" - -#include - -#include "base.hpp" -#include "ui/ui_base.hpp" - -// forward declarations -struct ID2D1RenderTarget; -namespace cru::ui { -class Control; -} - -namespace cru::ui::render { - -class RenderObject : public Object { - protected: - RenderObject() = default; - - public: - RenderObject(const RenderObject& other) = delete; - RenderObject(RenderObject&& other) = delete; - RenderObject& operator=(const RenderObject& other) = delete; - RenderObject& operator=(RenderObject&& other) = delete; - ~RenderObject() override = default; - - Control* GetAttachedControl() const { return control_; } - void SetAttachedControl(Control* new_control) { control_ = new_control; } - - RenderObject* GetParent() const { return parent_; } - - const std::vector& GetChildren() const { return children_; } - void AddChild(RenderObject* render_object, int position); - void RemoveChild(int position); - - Point GetOffset() const { return offset_; } - void SetOffset(const Point& offset) { offset_ = offset; } - Size GetSize() const { return size_; } - void SetSize(const Size& size) { - const auto old_size = size_; - size_ = size; - OnSizeChanged(old_size, size); - } - - Thickness GetMargin() const { return margin_; } - void SetMargin(const Thickness& margin) { margin_ = margin; } - - Thickness GetPadding() const { return padding_; } - void SetPadding(const Thickness& padding) { padding_ = padding; } - - Size GetPreferredSize() const { return preferred_size_; } - void SetPreferredSize(const Size& preferred_size) { - preferred_size_ = preferred_size; - } - - void Measure(const Size& available_size); - void Layout(const Rect& rect); - - virtual void Draw(ID2D1RenderTarget* render_target) = 0; - - virtual RenderObject* HitTest(const Point& point) = 0; - - protected: - virtual void OnParentChanged(RenderObject* old_parent, - RenderObject* new_parent); - - virtual void OnAddChild(RenderObject* new_child, int position); - virtual void OnRemoveChild(RenderObject* removed_child, int position); - - virtual void OnSizeChanged(const Size& old_size, const Size& new_size); - - virtual void OnMeasureCore(const Size& available_size); - virtual void OnLayoutCore(const Rect& rect); - virtual Size OnMeasureContent(const Size& available_size) = 0; - virtual void OnLayoutContent(const Rect& content_rect) = 0; - - Rect GetContentRect() const; - - private: - void SetParent(RenderObject* new_parent); - - private: - Control* control_ = nullptr; - - RenderObject* parent_ = nullptr; - std::vector children_{}; - - Point offset_ = Point::Zero(); - Size size_ = Size::Zero(); - - Thickness margin_ = Thickness::Zero(); - Thickness padding_ = Thickness::Zero(); - - Size preferred_size_ = Size::Zero(); -}; -} // namespace cru::ui::render diff --git a/src/ui/render/text_render_object.hpp b/src/ui/render/text_render_object.hpp deleted file mode 100644 index 7827f994..00000000 --- a/src/ui/render/text_render_object.hpp +++ /dev/null @@ -1,69 +0,0 @@ -#pragma once -#include "pre.hpp" - -#include "render_object.hpp" - -// forward declarations -struct ID2D1Brush; -struct IDWriteTextFormat; -struct IDWriteTextLayout; - -namespace cru::ui::render { -class TextRenderObject : public RenderObject { - public: - TextRenderObject(ID2D1Brush* brush, IDWriteTextFormat* format, - ID2D1Brush* selection_brush); - TextRenderObject(const TextRenderObject& other) = delete; - TextRenderObject(TextRenderObject&& other) = delete; - TextRenderObject& operator=(const TextRenderObject& other) = delete; - TextRenderObject& operator=(TextRenderObject&& other) = delete; - ~TextRenderObject() override; - - String GetText() const { return text_; } - void SetText(String new_text) { - text_ = std::move(new_text); - RecreateTextLayout(); - } - - ID2D1Brush* GetBrush() const { return brush_; } - void SetBrush(ID2D1Brush* new_brush); - - IDWriteTextFormat* GetTextFormat() const { return text_format_; } - void SetTextFormat(IDWriteTextFormat* new_text_format); - - std::optional GetSelectionRange() const { - return selection_range_; - } - void SetSelectionRange(std::optional new_range) { - selection_range_ = std::move(new_range); - } - - ID2D1Brush* GetSelectionBrush() const { return selection_brush_; } - void SetSelectionBrush(ID2D1Brush* new_brush); - - void Refresh() { RecreateTextLayout(); } - - void Draw(ID2D1RenderTarget* render_target) override; - - RenderObject* HitTest(const Point& point) override; - - protected: - void OnSizeChanged(const Size& old_size, const Size& new_size) override; - - Size OnMeasureContent(const Size& available_size) override; - void OnLayoutContent(const Rect& content_rect) override; - - private: - void RecreateTextLayout(); - - private: - String text_; - - ID2D1Brush* brush_ = nullptr; - IDWriteTextFormat* text_format_ = nullptr; - IDWriteTextLayout* text_layout_ = nullptr; - - std::optional selection_range_ = std::nullopt; - ID2D1Brush* selection_brush_ = nullptr; -}; -} // namespace cru::ui::render diff --git a/src/ui/render/window_render_object.hpp b/src/ui/render/window_render_object.hpp deleted file mode 100644 index 63eb8588..00000000 --- a/src/ui/render/window_render_object.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include "pre.hpp" - -#include "render_object.hpp" - -namespace cru::ui { -class Window; -} - -namespace cru::ui::render { -class WindowRenderObject : public RenderObject { - public: - WindowRenderObject(Window* window) : window_(window) {} - WindowRenderObject(const WindowRenderObject& other) = delete; - WindowRenderObject(WindowRenderObject&& other) = delete; - WindowRenderObject& operator=(const WindowRenderObject& other) = delete; - WindowRenderObject& operator=(WindowRenderObject&& other) = delete; - ~WindowRenderObject() override = default; - - void MeasureAndLayout(); - - void Draw(ID2D1RenderTarget* render_target) override; - - RenderObject* HitTest(const Point& point) override; - - protected: - void OnAddChild(RenderObject* new_child, int position) override; - - Size OnMeasureContent(const Size& available_size) override; - void OnLayoutContent(const Rect& content_rect) override; - - private: - RenderObject* GetChild() const { - return GetChildren().empty() ? nullptr : GetChildren()[0]; - } - - private: - Window* window_; -}; -} // namespace cru::ui::render 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 #include #include #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"; -- cgit v1.2.3