aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2019-03-23 00:15:18 +0800
committercrupest <crupest@outlook.com>2019-03-23 00:15:18 +0800
commit39d2c8b3d957e75c3a2a1c738c1628e3eb5c0173 (patch)
tree72fff34573ffc7e788051bd7911032283340588d /src
parent63a5d619ac81ba3f48e95c890d96fa7d9047bb26 (diff)
downloadcru-39d2c8b3d957e75c3a2a1c738c1628e3eb5c0173.tar.gz
cru-39d2c8b3d957e75c3a2a1c738c1628e3eb5c0173.tar.bz2
cru-39d2c8b3d957e75c3a2a1c738c1628e3eb5c0173.zip
...
Diffstat (limited to 'src')
-rw-r--r--src/ui/render/border_render_object.cpp96
-rw-r--r--src/ui/render/border_render_object.hpp71
-rw-r--r--src/ui/render/flex_layout_render_object.hpp10
-rw-r--r--src/ui/render/render_object.cpp30
-rw-r--r--src/ui/render/render_object.hpp9
-rw-r--r--src/ui/render/text_render_object.hpp7
6 files changed, 198 insertions, 25 deletions
diff --git a/src/ui/render/border_render_object.cpp b/src/ui/render/border_render_object.cpp
new file mode 100644
index 00000000..c98d6c29
--- /dev/null
+++ b/src/ui/render/border_render_object.cpp
@@ -0,0 +1,96 @@
+#include "border_render_object.hpp"
+
+#include "cru_debug.hpp"
+
+namespace cru::ui::render {
+BorderRenderObject::BorderRenderObject(Microsoft::WRL::ComPtr<ID2D1Brush> brush)
+ : border_brush_(std::move(brush)) {}
+
+void BorderRenderObject::OnMeasureCore(const Size& available_size) {
+ const auto margin = GetMargin();
+ const auto padding = GetPadding();
+ Size margin_border_padding_size{
+ margin.GetHorizontalTotal() + padding.GetHorizontalTotal(),
+ margin.GetVerticalTotal() + padding.GetVerticalTotal()};
+
+ if (is_enabled_) {
+ margin_border_padding_size.width += border_width_.GetHorizontalTotal();
+ margin_border_padding_size.height += border_width_.GetVerticalTotal();
+ }
+
+ auto coerced_margin_border_padding_size = margin_border_padding_size;
+ if (coerced_margin_border_padding_size.width > available_size.width) {
+ debug::DebugMessage(
+ L"Measure: horizontal length of padding, border and margin is bigger "
+ L"than available length.");
+ coerced_margin_border_padding_size.width = available_size.width;
+ }
+ if (coerced_margin_border_padding_size.height > available_size.height) {
+ debug::DebugMessage(
+ L"Measure: vertical length of padding, border and margin is bigger "
+ L"than available length.");
+ coerced_margin_border_padding_size.height = available_size.height;
+ }
+
+ const auto coerced_content_available_size =
+ available_size - coerced_margin_border_padding_size;
+
+ const auto actual_content_size =
+ OnMeasureContent(coerced_content_available_size);
+
+ SetPreferredSize(coerced_margin_border_padding_size + actual_content_size);
+}
+
+void BorderRenderObject::OnLayoutCore(const Rect& rect) {
+ const auto margin = GetMargin();
+ const auto padding = GetPadding();
+ Size margin_border_padding_size{
+ margin.GetHorizontalTotal() + padding.GetHorizontalTotal(),
+ margin.GetVerticalTotal() + padding.GetVerticalTotal()};
+
+ if (is_enabled_) {
+ margin_border_padding_size.width += border_width_.GetHorizontalTotal();
+ margin_border_padding_size.height += border_width_.GetVerticalTotal();
+ }
+
+ const auto content_available_size =
+ rect.GetSize() - margin_border_padding_size;
+ auto coerced_content_available_size = content_available_size;
+
+ if (coerced_content_available_size.width < 0) {
+ debug::DebugMessage(
+ L"Layout: horizontal length of padding, border and margin is bigger "
+ L"than available length.");
+ coerced_content_available_size.width = 0;
+ }
+ if (coerced_content_available_size.height < 0) {
+ debug::DebugMessage(
+ L"Layout: vertical length of padding, border and margin is bigger than "
+ L"available length.");
+ coerced_content_available_size.height = 0;
+ }
+
+ OnLayoutContent(
+ Rect{margin.left + (is_enabled_ ? border_width_.left : 0) + padding.left,
+ margin.top + (is_enabled_ ? border_width_.top : 0) + padding.top,
+ coerced_content_available_size.width,
+ coerced_content_available_size.height});
+}
+
+Size BorderRenderObject::OnMeasureContent(const Size& available_size) {
+ const auto child = GetChild();
+ if (child) {
+ child->Measure(available_size);
+ return child->GetPreferredSize();
+ } else {
+ return Size::Zero();
+ }
+}
+
+void BorderRenderObject::OnLayoutContent(const Rect& content_rect) {
+ const auto child = GetChild();
+ if (child) {
+ child->Layout(content_rect);
+ }
+}
+} // namespace cru::ui::render
diff --git a/src/ui/render/border_render_object.hpp b/src/ui/render/border_render_object.hpp
new file mode 100644
index 00000000..d7a595af
--- /dev/null
+++ b/src/ui/render/border_render_object.hpp
@@ -0,0 +1,71 @@
+#pragma once
+#include "pre.hpp"
+
+#include <wrl/client.h> // for ComPtr
+
+#include "render_object.hpp"
+
+// forward declarations
+struct ID2D1Brush;
+struct ID2D1Geometry;
+
+struct CornerRadius {
+ float left_top;
+ float right_top;
+ float left_bottom;
+ float right_bottom;
+};
+
+namespace cru::ui::render {
+class BorderRenderObject : public RenderObject {
+ public:
+ explicit BorderRenderObject(Microsoft::WRL::ComPtr<ID2D1Brush> brush);
+ BorderRenderObject(const BorderRenderObject& other) = delete;
+ BorderRenderObject(BorderRenderObject&& other) = delete;
+ BorderRenderObject& operator=(const BorderRenderObject& other) = delete;
+ BorderRenderObject& operator=(BorderRenderObject&& other) = delete;
+ ~BorderRenderObject() override = default;
+
+ bool IsEnabled() const { return is_enabled_; }
+ void SetEnabled(bool enabled) { is_enabled_ = enabled; }
+
+ Microsoft::WRL::ComPtr<ID2D1Brush> GetBrush() const { return border_brush_; }
+ void SetBrush(const Microsoft::WRL::ComPtr<ID2D1Brush> new_brush) {
+ border_brush_ = std::move(new_brush);
+ }
+
+ Thickness GetBorderWidth() const { return border_width_; }
+ void SetBorderWidth(const Thickness& thickness) { border_width_ = thickness; }
+
+ CornerRadius GetCornerRadius() const { return corner_radius_; }
+ void SetCornerRadius(const CornerRadius& new_corner_radius) {
+ corner_radius_ = new_corner_radius;
+ }
+
+ void RecreateGeometry(); // TODO
+
+ void Draw(ID2D1RenderTarget* render_target) override; // TODO
+
+ RenderObject* HitTest(const Point& point) override; // TODO
+
+ protected:
+ 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];
+ }
+
+ private:
+ bool is_enabled_;
+
+ Microsoft::WRL::ComPtr<ID2D1Brush> border_brush_;
+ Thickness border_width_;
+ CornerRadius corner_radius_;
+
+ Microsoft::WRL::ComPtr<ID2D1Geometry> geometry_;
+};
+} // namespace cru::ui::render
diff --git a/src/ui/render/flex_layout_render_object.hpp b/src/ui/render/flex_layout_render_object.hpp
index b12362e8..ac4c2c0f 100644
--- a/src/ui/render/flex_layout_render_object.hpp
+++ b/src/ui/render/flex_layout_render_object.hpp
@@ -16,7 +16,7 @@ enum class FlexDirection {
enum class Alignment { Start, End, Center };
struct FlexChildLayoutData {
- std::optional<float> flex_basis;
+ std::optional<float> flex_basis; // nullopt stands for content
float flex_grow = 0;
float flex_shrink = 0;
Alignment alignment = Alignment::Center;
@@ -35,12 +35,8 @@ class FlexLayoutRenderObject : public RenderObject {
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;
- }
+ Alignment GetContentMainAlign() const { return content_main_align_; }
+ void SetContentMainAlign(Alignment align) { content_main_align_ = align; }
FlexChildLayoutData* GetChildLayoutData(int position);
diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp
index 6380c2fe..f56baa8f 100644
--- a/src/ui/render/render_object.cpp
+++ b/src/ui/render/render_object.cpp
@@ -1,5 +1,8 @@
#include "render_object.hpp"
+#include <d2d1.h>
+#include <dwrite.h>
+
#include "cru_debug.hpp"
namespace cru::ui::render {
@@ -44,36 +47,31 @@ void RenderObject::OnRemoveChild(RenderObject* removed_child, int position) {}
void RenderObject::OnSizeChanged(const Size& old_size, const Size& new_size) {}
-void RenderObject::SetParent(RenderObject* new_parent) {
- const auto old_parent = parent_;
- parent_ = new_parent;
- OnParentChanged(old_parent, new_parent);
-}
-
void RenderObject::OnMeasureCore(const Size& available_size) {
Size margin_padding_size{
margin_.GetHorizontalTotal() + padding_.GetHorizontalTotal(),
margin_.GetVerticalTotal() + padding_.GetVerticalTotal()};
- const auto content_available_size = available_size - margin_padding_size;
- auto coerced_content_available_size = content_available_size;
- if (coerced_content_available_size.width < 0) {
+ auto coerced_margin_padding_size = margin_padding_size;
+ if (coerced_margin_padding_size.width > available_size.width) {
debug::DebugMessage(
L"Measure: horizontal length of padding and margin is bigger than "
L"available length.");
- coerced_content_available_size.width = 0;
+ coerced_margin_padding_size.width = available_size.width;
}
- if (coerced_content_available_size.height < 0) {
+ if (coerced_margin_padding_size.height > available_size.height) {
debug::DebugMessage(
L"Measure: vertical length of padding and margin is bigger than "
L"available length.");
- coerced_content_available_size.height = 0;
+ coerced_margin_padding_size.height = available_size.height;
}
+ const auto coerced_content_available_size =
+ available_size - coerced_margin_padding_size;
const auto actual_content_size =
OnMeasureContent(coerced_content_available_size);
- SetPreferredSize(margin_padding_size + actual_content_size);
+ SetPreferredSize(coerced_margin_padding_size + actual_content_size);
}
void RenderObject::OnLayoutCore(const Rect& rect) {
@@ -100,4 +98,10 @@ void RenderObject::OnLayoutCore(const Rect& rect) {
coerced_content_available_size.width,
coerced_content_available_size.height});
}
+
+void RenderObject::SetParent(RenderObject* new_parent) {
+ const auto old_parent = parent_;
+ parent_ = new_parent;
+ OnParentChanged(old_parent, new_parent);
+}
} // namespace cru::ui::render
diff --git a/src/ui/render/render_object.hpp b/src/ui/render/render_object.hpp
index a9950198..51b0c3ae 100644
--- a/src/ui/render/render_object.hpp
+++ b/src/ui/render/render_object.hpp
@@ -3,11 +3,13 @@
#include <optional>
#include <vector>
-#include "system_headers.hpp"
#include "base.hpp"
#include "ui/ui_base.hpp"
+// forward declarations
+struct ID2D1RenderTarget;
+
namespace cru::ui {
class Control;
}
@@ -70,15 +72,14 @@ class RenderObject : public Object {
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;
private:
void SetParent(RenderObject* new_parent);
- void OnMeasureCore(const Size& available_size);
- void OnLayoutCore(const Rect& rect);
-
private:
Control* control_ = nullptr;
diff --git a/src/ui/render/text_render_object.hpp b/src/ui/render/text_render_object.hpp
index 4361b9c0..ac874b75 100644
--- a/src/ui/render/text_render_object.hpp
+++ b/src/ui/render/text_render_object.hpp
@@ -1,10 +1,15 @@
#pragma once
#include "pre.hpp"
-#include "system_headers.hpp"
+#include <wrl/client.h> // for ComPtr
#include "render_object.hpp"
+// forward declarations
+struct ID2D1Brush;
+struct IDWriteTextFormat;
+struct IDWriteTextLayout;
+
namespace cru::ui::render {
class TextRenderObject : public RenderObject {
public: