aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/cru/common/event.hpp5
-rw-r--r--include/cru/ui/controls/button.hpp51
-rw-r--r--include/cru/ui/controls/flex_layout.hpp2
-rw-r--r--include/cru/ui/render/border_render_object.hpp4
-rw-r--r--include/cru/ui/render/flex_layout_render_object.hpp22
-rw-r--r--include/cru/ui/render/render_object.hpp11
-rw-r--r--include/cru/ui/render/text_render_object.hpp4
-rw-r--r--include/cru/ui/render/window_render_object.hpp2
-rw-r--r--src/ui/controls/flex_layout.cpp32
-rw-r--r--src/ui/render/border_render_object.cpp35
-rw-r--r--src/ui/render/flex_layout_render_object.cpp7
-rw-r--r--src/ui/render/render_object.cpp11
-rw-r--r--src/ui/render/text_render_object.cpp22
-rw-r--r--src/ui/render/window_render_object.cpp2
14 files changed, 105 insertions, 105 deletions
diff --git a/include/cru/common/event.hpp b/include/cru/common/event.hpp
index 12c0d0cd..33b2e3f6 100644
--- a/include/cru/common/event.hpp
+++ b/include/cru/common/event.hpp
@@ -183,6 +183,7 @@ struct EventRevokerDestroyer {
class EventRevokerGuard {
public:
+ EventRevokerGuard() = default;
explicit EventRevokerGuard(EventRevoker&& revoker)
: revoker_(new EventRevoker(std::move(revoker))) {}
EventRevokerGuard(const EventRevokerGuard& other) = delete;
@@ -200,6 +201,10 @@ class EventRevokerGuard {
void Release() { revoker_.release(); }
+ void Reset(EventRevoker&& revoker) {
+ revoker_.reset(new EventRevoker(std::move(revoker)));
+ }
+
private:
std::unique_ptr<EventRevoker, details::EventRevokerDestroyer> revoker_;
}; // namespace cru
diff --git a/include/cru/ui/controls/button.hpp b/include/cru/ui/controls/button.hpp
index b5cca7dc..0fad0035 100644
--- a/include/cru/ui/controls/button.hpp
+++ b/include/cru/ui/controls/button.hpp
@@ -13,15 +13,25 @@ class BorderRenderObject;
}
namespace cru::ui::controls {
-struct ButtonBorderStyle {
+using render::CornerRadius;
+
+struct ButtonStateStyle {
+ std::shared_ptr<platform::graph::Brush> border_brush;
+ Thickness border_thickness;
+ CornerRadius corner_radius;
+ std::shared_ptr<platform::graph::Brush> foreground_brush;
+ std::shared_ptr<platform::graph::Brush> background_brush;
+};
+
+struct ButtonStyle {
// corresponds to ButtonState::Normal
- render::BorderStyle normal;
+ ButtonStateStyle normal;
// corresponds to ButtonState::Hover
- render::BorderStyle hover;
+ ButtonStateStyle hover;
// corresponds to ButtonState::Press
- render::BorderStyle press;
+ ButtonStateStyle press;
// corresponds to ButtonState::PressCancel
- render::BorderStyle press_cancel;
+ ButtonStateStyle press_cancel;
};
enum class ButtonState {
@@ -32,7 +42,7 @@ enum class ButtonState {
// mouse is pressed in it
Press,
// mouse is pressed outside button
- PressCancel,
+ PressCancel,
};
class Button : public ContentControl {
@@ -58,31 +68,8 @@ class Button : public ContentControl {
render::RenderObject* GetRenderObject() const override;
public:
- render::BorderStyle GetNormalBorderStyle() const {
- return border_style_.normal;
- }
- void SetNormalBorderStyle(render::BorderStyle newStyle) {
- border_style_.normal = std::move(newStyle);
- }
-
- render::BorderStyle GetHoverBorderStyle() const {
- return border_style_.hover;
- }
- void SetHoverBorderStyle(render::BorderStyle newStyle) {
- border_style_.hover = std::move(newStyle);
- }
-
- render::BorderStyle GetPressBorderStyle() const {
- return border_style_.press;
- }
- void SetPressBorderStyle(render::BorderStyle newStyle) {
- border_style_.press = std::move(newStyle);
- }
-
- ButtonBorderStyle GetBorderStyle() const { return border_style_; }
- void SetBorderStyle(ButtonBorderStyle newStyle) {
- border_style_ = std::move(newStyle);
- }
+ const ButtonStyle& GetStyle() const { return style_; }
+ void SetStyle(ButtonStyle style);
ButtonState GetState() const { return state_; }
@@ -115,7 +102,7 @@ class Button : public ContentControl {
MouseButton trigger_button_ = MouseButton::Left;
- ButtonBorderStyle border_style_;
+ ButtonStyle style_;
ClickDetector click_detector_;
};
diff --git a/include/cru/ui/controls/flex_layout.hpp b/include/cru/ui/controls/flex_layout.hpp
index 128a79b0..d8d92d08 100644
--- a/include/cru/ui/controls/flex_layout.hpp
+++ b/include/cru/ui/controls/flex_layout.hpp
@@ -42,7 +42,6 @@ class FlexLayout : public LayoutControl {
void SetContentMainAlign(FlexMainAlignment value) {
if (value == GetContentMainAlign()) return;
render_object_->SetContentMainAlign(value);
- if (const auto window = GetWindow()) window->InvalidateLayout();
}
FlexDirection GetFlexDirection() const {
@@ -52,7 +51,6 @@ class FlexLayout : public LayoutControl {
void SetFlexDirection(FlexDirection direction) {
if (direction == GetFlexDirection()) return;
render_object_->SetFlexDirection(direction);
- if (const auto window = GetWindow()) window->InvalidateLayout();
}
FlexChildLayoutData GetChildLayoutData(Control* control);
diff --git a/include/cru/ui/render/border_render_object.hpp b/include/cru/ui/render/border_render_object.hpp
index 18809f91..e21ce34c 100644
--- a/include/cru/ui/render/border_render_object.hpp
+++ b/include/cru/ui/render/border_render_object.hpp
@@ -106,13 +106,13 @@ class BorderRenderObject : public RenderObject {
RenderObject* HitTest(const Point& point) override;
protected:
- 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;
+ void OnAfterLayout() override;
+
private:
RenderObject* GetChild() const {
return GetChildren().empty() ? nullptr : GetChildren()[0];
diff --git a/include/cru/ui/render/flex_layout_render_object.hpp b/include/cru/ui/render/flex_layout_render_object.hpp
index 68ffc89e..7b71b96e 100644
--- a/include/cru/ui/render/flex_layout_render_object.hpp
+++ b/include/cru/ui/render/flex_layout_render_object.hpp
@@ -15,7 +15,7 @@ namespace internal {
constexpr int align_start = 0;
constexpr int align_end = align_start + 1;
constexpr int align_center = align_end + 1;
-//constexpr int align_stretch = align_center + 1;
+// constexpr int align_stretch = align_center + 1;
} // namespace internal
enum class FlexMainAlignment {
@@ -27,7 +27,7 @@ enum class FlexCrossAlignment {
Start = internal::align_start,
End = internal::align_end,
Center = internal::align_center,
-// Stretch = internal::align_stretch
+ // Stretch = internal::align_stretch
};
struct FlexChildLayoutData {
@@ -50,19 +50,33 @@ class FlexLayoutRenderObject : public RenderObject {
~FlexLayoutRenderObject() override = default;
FlexDirection GetFlexDirection() const { return direction_; }
- void SetFlexDirection(FlexDirection direction) { direction_ = direction; }
+ void SetFlexDirection(FlexDirection direction) {
+ direction_ = direction;
+ InvalidateLayout();
+ }
FlexMainAlignment GetContentMainAlign() const { return content_main_align_; }
void SetContentMainAlign(FlexMainAlignment align) {
content_main_align_ = align;
+ InvalidateLayout();
}
FlexCrossAlignment GetItemCrossAlign() const { return item_cross_align_; }
void SetItemCrossAlign(FlexCrossAlignment align) {
item_cross_align_ = align;
+ InvalidateLayout();
+ }
+
+ FlexChildLayoutData GetChildLayoutData(int position) {
+ assert(position >= 0 && position < child_layout_data_.size());
+ return child_layout_data_[position];
}
- FlexChildLayoutData* GetChildLayoutData(int position);
+ void SetChildLayoutData(int position, const FlexChildLayoutData& data) {
+ assert(position >= 0 && position < child_layout_data_.size());
+ child_layout_data_[position] = data;
+ InvalidateLayout();
+ }
void Draw(platform::graph::Painter* painter) override;
diff --git a/include/cru/ui/render/render_object.hpp b/include/cru/ui/render/render_object.hpp
index 2394bf97..befaa3ec 100644
--- a/include/cru/ui/render/render_object.hpp
+++ b/include/cru/ui/render/render_object.hpp
@@ -59,11 +59,7 @@ class RenderObject : public Object {
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);
- }
+ void SetSize(const Size& size) { size_ = size; }
Thickness GetMargin() const { return margin_; }
void SetMargin(const Thickness& margin) { margin_ = margin; }
@@ -109,13 +105,14 @@ class RenderObject : public Object {
// default is to invalidate both layout and paint
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;
+ virtual void OnAfterLayout();
+ static void NotifyAfterLayoutRecursive(RenderObject* render_object);
+
Rect GetContentRect() const;
private:
diff --git a/include/cru/ui/render/text_render_object.hpp b/include/cru/ui/render/text_render_object.hpp
index 054d9b47..a10e3b74 100644
--- a/include/cru/ui/render/text_render_object.hpp
+++ b/include/cru/ui/render/text_render_object.hpp
@@ -53,11 +53,11 @@ class TextRenderObject : public RenderObject {
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;
+ void OnAfterLayout() override;
+
private:
std::shared_ptr<platform::graph::Brush> brush_;
std::shared_ptr<platform::graph::Font> font_;
diff --git a/include/cru/ui/render/window_render_object.hpp b/include/cru/ui/render/window_render_object.hpp
index 431f7025..2260c293 100644
--- a/include/cru/ui/render/window_render_object.hpp
+++ b/include/cru/ui/render/window_render_object.hpp
@@ -40,6 +40,8 @@ class WindowRenderObject : public RenderObject {
private:
Window* window_;
+ EventRevokerGuard after_layout_event_guard_;
+
std::unique_ptr<IRenderHost> render_host_;
};
} // namespace cru::ui::render
diff --git a/src/ui/controls/flex_layout.cpp b/src/ui/controls/flex_layout.cpp
index a8200a12..cf6d4aad 100644
--- a/src/ui/controls/flex_layout.cpp
+++ b/src/ui/controls/flex_layout.cpp
@@ -14,31 +14,29 @@ render::RenderObject* FlexLayout::GetRenderObject() const {
return render_object_.get();
}
-FlexChildLayoutData FlexLayout::GetChildLayoutData(Control* control) {
- const auto& render_objects = render_object_->GetChildren();
+namespace {
+int FindPosition(render::RenderObject* parent, render::RenderObject* child) {
+ const auto& render_objects = parent->GetChildren();
const auto find_result =
- std::find(render_objects.cbegin(), render_objects.cend(),
- control->GetRenderObject());
+ std::find(render_objects.cbegin(), render_objects.cend(), child);
if (find_result == render_objects.cend()) {
throw std::logic_error("Control is not a child of FlexLayout.");
}
- int position = static_cast<int>(find_result - render_objects.cbegin());
- return *(render_object_->GetChildLayoutData(position));
+ return static_cast<int>(find_result - render_objects.cbegin());
+}
+} // namespace
+
+FlexChildLayoutData FlexLayout::GetChildLayoutData(Control* control) {
+ assert(control);
+ return render_object_->GetChildLayoutData(
+ FindPosition(render_object_.get(), control->GetRenderObject()));
}
void FlexLayout::SetChildLayoutData(Control* control,
const FlexChildLayoutData& data) {
- const auto& render_objects = render_object_->GetChildren();
- const auto find_result =
- std::find(render_objects.cbegin(), render_objects.cend(),
- control->GetRenderObject());
- if (find_result == render_objects.cend()) {
- throw std::logic_error("Control is not a child of FlexLayout.");
- }
- int position = static_cast<int>(find_result - render_objects.cbegin());
- const auto d = render_object_->GetChildLayoutData(position);
- *d = data;
- if (const auto window = GetWindow()) window->InvalidateLayout();
+ assert(control);
+ render_object_->SetChildLayoutData(
+ FindPosition(render_object_.get(), control->GetRenderObject()), data);
}
void FlexLayout::OnAddChild(Control* child, int position) {
diff --git a/src/ui/render/border_render_object.cpp b/src/ui/render/border_render_object.cpp
index 6af76b32..2ca55f4d 100644
--- a/src/ui/render/border_render_object.cpp
+++ b/src/ui/render/border_render_object.cpp
@@ -21,10 +21,10 @@ void BorderRenderObject::Draw(platform::graph::Painter* painter) {
painter->FillGeometry(border_inner_geometry_.get(),
background_brush_.get());
if (is_border_enabled_) {
- if (border_style_.brush == nullptr) {
+ if (border_brush_ == nullptr) {
log::Warn(L"Border is enabled but brush is null");
} else {
- painter->FillGeometry(geometry_.get(), border_style_.brush.get());
+ painter->FillGeometry(geometry_.get(), border_brush_.get());
}
}
if (const auto child = GetChild()) {
@@ -64,11 +64,6 @@ RenderObject* BorderRenderObject::HitTest(const Point& point) {
}
}
-void BorderRenderObject::OnSizeChanged(const Size& old_size,
- const Size& new_size) {
- RecreateGeometry();
-}
-
void BorderRenderObject::OnMeasureCore(const Size& available_size) {
const auto margin = GetMargin();
const auto padding = GetPadding();
@@ -78,9 +73,9 @@ void BorderRenderObject::OnMeasureCore(const Size& available_size) {
if (is_border_enabled_) {
margin_border_padding_size.width +=
- border_style_.thickness.GetHorizontalTotal();
+ border_thickness_.GetHorizontalTotal();
margin_border_padding_size.height +=
- border_style_.thickness.GetVerticalTotal();
+ border_thickness_.GetVerticalTotal();
}
auto coerced_margin_border_padding_size = margin_border_padding_size;
@@ -115,9 +110,9 @@ void BorderRenderObject::OnLayoutCore(const Rect& rect) {
if (is_border_enabled_) {
margin_border_padding_size.width +=
- border_style_.thickness.GetHorizontalTotal();
+ border_thickness_.GetHorizontalTotal();
margin_border_padding_size.height +=
- border_style_.thickness.GetVerticalTotal();
+ border_thickness_.GetVerticalTotal();
}
const auto content_available_size =
@@ -138,9 +133,9 @@ void BorderRenderObject::OnLayoutCore(const Rect& rect) {
}
OnLayoutContent(Rect{
- margin.left + (is_border_enabled_ ? border_style_.thickness.left : 0) +
+ margin.left + (is_border_enabled_ ? border_thickness_.left : 0) +
padding.left,
- margin.top + (is_border_enabled_ ? border_style_.thickness.top : 0) +
+ margin.top + (is_border_enabled_ ? border_thickness_.top : 0) +
padding.top,
coerced_content_available_size.width,
coerced_content_available_size.height});
@@ -163,6 +158,10 @@ void BorderRenderObject::OnLayoutContent(const Rect& content_rect) {
}
}
+void BorderRenderObject::OnAfterLayout() {
+ RecreateGeometry();
+}
+
void BorderRenderObject::RecreateGeometry() {
geometry_.reset();
border_outer_geometry_.reset();
@@ -197,20 +196,20 @@ void BorderRenderObject::RecreateGeometry() {
const auto graph_factory = platform::graph::GraphFactory::GetInstance();
std::unique_ptr<platform::graph::GeometryBuilder> builder{
graph_factory->CreateGeometryBuilder()};
- f(builder.get(), outer_rect, border_style_.corner_radius);
+ f(builder.get(), outer_rect, border_radius_);
border_outer_geometry_.reset(builder->Build());
builder.reset();
- const Rect inner_rect = outer_rect.Shrink(border_style_.thickness);
+ const Rect inner_rect = outer_rect.Shrink(border_thickness_);
builder.reset(graph_factory->CreateGeometryBuilder());
- f(builder.get(), inner_rect, border_style_.corner_radius);
+ f(builder.get(), inner_rect, border_radius_);
border_inner_geometry_.reset(builder->Build());
builder.reset();
builder.reset(graph_factory->CreateGeometryBuilder());
- f(builder.get(), outer_rect, border_style_.corner_radius);
- f(builder.get(), inner_rect, border_style_.corner_radius);
+ f(builder.get(), outer_rect, border_radius_);
+ f(builder.get(), inner_rect, border_radius_);
geometry_.reset(builder->Build());
builder.reset();
}
diff --git a/src/ui/render/flex_layout_render_object.cpp b/src/ui/render/flex_layout_render_object.cpp
index 416f39bd..a16aec69 100644
--- a/src/ui/render/flex_layout_render_object.cpp
+++ b/src/ui/render/flex_layout_render_object.cpp
@@ -11,13 +11,6 @@ FlexLayoutRenderObject::FlexLayoutRenderObject() {
SetChildMode(ChildMode::Multiple);
}
-FlexChildLayoutData* FlexLayoutRenderObject::GetChildLayoutData(int position) {
- assert(position >= 0 &&
- position < child_layout_data_.size()); // Position out of bound.
-
- return &child_layout_data_[position];
-}
-
void FlexLayoutRenderObject::Draw(platform::graph::Painter* painter) {
for (const auto child : GetChildren()) {
auto offset = child->GetOffset();
diff --git a/src/ui/render/render_object.cpp b/src/ui/render/render_object.cpp
index dcd2f0b9..118c68c4 100644
--- a/src/ui/render/render_object.cpp
+++ b/src/ui/render/render_object.cpp
@@ -54,8 +54,6 @@ void RenderObject::OnRemoveChild(RenderObject* removed_child, int position) {
InvalidatePaint();
}
-void RenderObject::OnSizeChanged(const Size& old_size, const Size& new_size) {}
-
void RenderObject::OnMeasureCore(const Size& available_size) {
Size margin_padding_size{
margin_.GetHorizontalTotal() + padding_.GetHorizontalTotal(),
@@ -108,6 +106,8 @@ void RenderObject::OnLayoutCore(const Rect& rect) {
coerced_content_available_size.height});
}
+void RenderObject::OnAfterLayout() {}
+
Rect RenderObject::GetContentRect() const {
Rect rect{Point{}, GetSize()};
rect = rect.Shrink(GetMargin());
@@ -122,4 +122,11 @@ void RenderObject::SetParent(RenderObject* new_parent) {
parent_ = new_parent;
OnParentChanged(old_parent, new_parent);
}
+
+void RenderObject::NotifyAfterLayoutRecursive(RenderObject* render_object) {
+ render_object->OnAfterLayout();
+ for (const auto o : render_object->GetChildren()) {
+ NotifyAfterLayoutRecursive(o);
+ }
+}
} // namespace cru::ui::render
diff --git a/src/ui/render/text_render_object.cpp b/src/ui/render/text_render_object.cpp
index 49d7bcb4..a21dc028 100644
--- a/src/ui/render/text_render_object.cpp
+++ b/src/ui/render/text_render_object.cpp
@@ -1,8 +1,8 @@
#include "cru/ui/render/text_render_object.hpp"
#include "cru/platform/graph/graph_factory.hpp"
-#include "cru/platform/graph/util/painter_util.hpp"
#include "cru/platform/graph/text_layout.hpp"
+#include "cru/platform/graph/util/painter_util.hpp"
#include <algorithm>
#include <cassert>
@@ -34,13 +34,11 @@ void TextRenderObject::SetText(std::wstring new_text) {
text_layout_->SetText(std::move(new_text));
}
-std::shared_ptr<platform::graph::Font> TextRenderObject::GetFont()
- const {
+std::shared_ptr<platform::graph::Font> TextRenderObject::GetFont() const {
return text_layout_->GetFont();
}
-void TextRenderObject::SetFont(
- std::shared_ptr<platform::graph::Font> font) {
+void TextRenderObject::SetFont(std::shared_ptr<platform::graph::Font> font) {
text_layout_->SetFont(std::move(font));
}
@@ -71,13 +69,6 @@ RenderObject* TextRenderObject::HitTest(const Point& point) {
: nullptr;
}
-void TextRenderObject::OnSizeChanged(const Size& old_size,
- const Size& new_size) {
- const auto&& size = GetContentRect().GetSize();
- text_layout_->SetMaxWidth(size.width);
- text_layout_->SetMaxHeight(size.height);
-}
-
Size TextRenderObject::OnMeasureContent(const Size& available_size) {
text_layout_->SetMaxWidth(available_size.width);
text_layout_->SetMaxHeight(available_size.height);
@@ -85,4 +76,11 @@ Size TextRenderObject::OnMeasureContent(const Size& available_size) {
}
void TextRenderObject::OnLayoutContent(const Rect& content_rect) {}
+
+void TextRenderObject::OnAfterLayout() {
+ const auto&& size = GetContentRect().GetSize();
+ text_layout_->SetMaxWidth(size.width);
+ text_layout_->SetMaxHeight(size.height);
+}
+
} // namespace cru::ui::render
diff --git a/src/ui/render/window_render_object.cpp b/src/ui/render/window_render_object.cpp
index e2e96897..64bec1e7 100644
--- a/src/ui/render/window_render_object.cpp
+++ b/src/ui/render/window_render_object.cpp
@@ -56,6 +56,8 @@ WindowRenderObject::WindowRenderObject(Window* window)
: window_(window), render_host_(new WindowRenderHost(this)) {
SetChildMode(ChildMode::Single);
SetRenderHost(render_host_.get());
+ after_layout_event_guard_.Reset(render_host_->AfterLayoutEvent()->AddHandler(
+ [this](auto) { NotifyAfterLayoutRecursive(this); }));
}
void WindowRenderObject::Relayout() {