diff options
author | 杨宇千 <crupest@outlook.com> | 2019-09-17 16:05:17 +0800 |
---|---|---|
committer | 杨宇千 <crupest@outlook.com> | 2019-09-17 16:05:17 +0800 |
commit | e8dd10eec26d26c3fb30f2712ccf58ac72edc8a2 (patch) | |
tree | 75293a2bb477fb1872087fab8bfd2c89b6d2051f | |
parent | 465d89b4207cce929dc8e0b6ac93c3533ba19408 (diff) | |
download | cru-e8dd10eec26d26c3fb30f2712ccf58ac72edc8a2.tar.gz cru-e8dd10eec26d26c3fb30f2712ccf58ac72edc8a2.tar.bz2 cru-e8dd10eec26d26c3fb30f2712ccf58ac72edc8a2.zip |
...
-rw-r--r-- | include/cru/common/event.hpp | 5 | ||||
-rw-r--r-- | include/cru/ui/controls/button.hpp | 51 | ||||
-rw-r--r-- | include/cru/ui/controls/flex_layout.hpp | 2 | ||||
-rw-r--r-- | include/cru/ui/render/border_render_object.hpp | 4 | ||||
-rw-r--r-- | include/cru/ui/render/flex_layout_render_object.hpp | 22 | ||||
-rw-r--r-- | include/cru/ui/render/render_object.hpp | 11 | ||||
-rw-r--r-- | include/cru/ui/render/text_render_object.hpp | 4 | ||||
-rw-r--r-- | include/cru/ui/render/window_render_object.hpp | 2 | ||||
-rw-r--r-- | src/ui/controls/flex_layout.cpp | 32 | ||||
-rw-r--r-- | src/ui/render/border_render_object.cpp | 35 | ||||
-rw-r--r-- | src/ui/render/flex_layout_render_object.cpp | 7 | ||||
-rw-r--r-- | src/ui/render/render_object.cpp | 11 | ||||
-rw-r--r-- | src/ui/render/text_render_object.cpp | 22 | ||||
-rw-r--r-- | src/ui/render/window_render_object.cpp | 2 |
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() { |