aboutsummaryrefslogtreecommitdiff
path: root/src/ui/render
diff options
context:
space:
mode:
Diffstat (limited to 'src/ui/render')
-rw-r--r--src/ui/render/BorderRenderObject.cpp47
-rw-r--r--src/ui/render/CanvasRenderObject.cpp12
-rw-r--r--src/ui/render/GeometryRenderObject.cpp27
-rw-r--r--src/ui/render/RenderObject.cpp40
-rw-r--r--src/ui/render/ScrollRenderObject.cpp23
-rw-r--r--src/ui/render/TextRenderObject.cpp42
-rw-r--r--src/ui/render/TreeRenderObject.cpp18
7 files changed, 101 insertions, 108 deletions
diff --git a/src/ui/render/BorderRenderObject.cpp b/src/ui/render/BorderRenderObject.cpp
index 080bcc4f..1fc120f1 100644
--- a/src/ui/render/BorderRenderObject.cpp
+++ b/src/ui/render/BorderRenderObject.cpp
@@ -5,7 +5,6 @@
#include "cru/platform/graphics/Geometry.h"
#include "cru/platform/graphics/Painter.h"
#include "cru/platform/gui/UiApplication.h"
-#include "cru/ui/DebugFlags.h"
#include "cru/ui/render/RenderObject.h"
#include <algorithm>
@@ -80,15 +79,24 @@ RenderObject* BorderRenderObject::HitTest(const Point& point) {
}
}
-void BorderRenderObject::Draw(platform::graphics::IPainter* painter) {
- if constexpr (debug_flags::draw) {
- CruLogDebug(
- kLogTag, "BorderRenderObject draw, background: {}, foreground: {}.",
- background_brush_ == nullptr ? "NONE"
- : background_brush_->GetDebugString(),
- foreground_brush_ == nullptr ? "NONE"
- : foreground_brush_->GetDebugString());
+Size BorderRenderObject::OnMeasureContent(
+ const MeasureRequirement& requirement) {
+ if (auto child = GetChild()) {
+ child->Measure(requirement);
+ return child->GetMeasureResultSize();
+ } else {
+ return requirement.suggest.GetSizeOr0();
+ }
+}
+
+void BorderRenderObject::OnLayoutContent(const Rect& content_rect) {
+ if (auto child = GetChild()) {
+ child->Layout(content_rect.GetLeftTop());
}
+}
+
+void BorderRenderObject::OnDraw(RenderObjectDrawContext& context) {
+ auto painter = context.painter;
if (background_brush_ != nullptr)
painter->FillGeometry(border_inner_geometry_.get(),
@@ -103,10 +111,7 @@ void BorderRenderObject::Draw(platform::graphics::IPainter* painter) {
}
if (auto child = GetChild()) {
- painter->PushState();
- painter->ConcatTransform(Matrix::Translation(child->GetOffset()));
- child->Draw(painter);
- painter->PopState();
+ context.DrawChild(child);
}
if (foreground_brush_ != nullptr)
@@ -114,22 +119,6 @@ void BorderRenderObject::Draw(platform::graphics::IPainter* painter) {
foreground_brush_.get());
}
-Size BorderRenderObject::OnMeasureContent(
- const MeasureRequirement& requirement) {
- if (auto child = GetChild()) {
- child->Measure(requirement);
- return child->GetMeasureResultSize();
- } else {
- return requirement.suggest.GetSizeOr0();
- }
-}
-
-void BorderRenderObject::OnLayoutContent(const Rect& content_rect) {
- if (auto child = GetChild()) {
- child->Layout(content_rect.GetLeftTop());
- }
-}
-
void BorderRenderObject::OnResize(const Size& new_size) { RecreateGeometry(); }
Thickness BorderRenderObject::GetTotalSpaceThickness() {
diff --git a/src/ui/render/CanvasRenderObject.cpp b/src/ui/render/CanvasRenderObject.cpp
index 0c5ca3ed..9c516477 100644
--- a/src/ui/render/CanvasRenderObject.cpp
+++ b/src/ui/render/CanvasRenderObject.cpp
@@ -9,12 +9,6 @@ RenderObject* CanvasRenderObject::HitTest(const Point& point) {
return padding_rect.IsPointInside(point) ? this : nullptr;
}
-void CanvasRenderObject::Draw(platform::graphics::IPainter* painter) {
- const auto rect = GetContentRect();
- CanvasPaintEventArgs args{painter, rect.GetSize()};
- PaintEvent_.Raise(args);
-}
-
Size CanvasRenderObject::OnMeasureContent(
const MeasureRequirement& requirement) {
return requirement.Coerce(requirement.suggest.GetSizeOr({100, 100}));
@@ -23,4 +17,10 @@ Size CanvasRenderObject::OnMeasureContent(
void CanvasRenderObject::OnLayoutContent(const Rect& content_rect) {
CRU_UNUSED(content_rect)
}
+
+void CanvasRenderObject::OnDraw(RenderObjectDrawContext& context) {
+ const auto rect = GetContentRect();
+ CanvasPaintEventArgs args{context.painter, rect.GetSize()};
+ PaintEvent_.Raise(args);
+}
} // namespace cru::ui::render
diff --git a/src/ui/render/GeometryRenderObject.cpp b/src/ui/render/GeometryRenderObject.cpp
index 84379b39..1ab0d8ed 100644
--- a/src/ui/render/GeometryRenderObject.cpp
+++ b/src/ui/render/GeometryRenderObject.cpp
@@ -60,9 +60,23 @@ void GeometryRenderObject::SetStrokeWidth(float width) {
InvalidatePaint();
}
-void GeometryRenderObject::Draw(platform::graphics::IPainter* painter) {
+RenderObject* GeometryRenderObject::HitTest(const Point& point) {
+ return GetPaddingRect().IsPointInside(point) ? this : nullptr;
+}
+
+Size GeometryRenderObject::OnMeasureContent(
+ const MeasureRequirement& requirement) {
+ Size result = GetViewPort().GetSize();
+ return requirement.ExpandToSuggestAndCoerce(result);
+}
+
+void GeometryRenderObject::OnLayoutContent(const Rect& content_rect) {}
+
+void GeometryRenderObject::OnDraw(RenderObjectDrawContext& context) {
if (!geometry_) return;
+ auto painter = context.painter;
+
painter->PushState();
auto content_rect = GetContentRect();
@@ -86,15 +100,4 @@ void GeometryRenderObject::Draw(platform::graphics::IPainter* painter) {
painter->PopState();
}
-RenderObject* GeometryRenderObject::HitTest(const Point& point) {
- return GetPaddingRect().IsPointInside(point) ? this : nullptr;
-}
-
-Size GeometryRenderObject::OnMeasureContent(
- const MeasureRequirement& requirement) {
- Size result = GetViewPort().GetSize();
- return requirement.ExpandToSuggestAndCoerce(result);
-}
-
-void GeometryRenderObject::OnLayoutContent(const Rect& content_rect) {}
} // namespace cru::ui::render
diff --git a/src/ui/render/RenderObject.cpp b/src/ui/render/RenderObject.cpp
index f553ea6d..a84bd8c1 100644
--- a/src/ui/render/RenderObject.cpp
+++ b/src/ui/render/RenderObject.cpp
@@ -6,7 +6,17 @@
#include "cru/ui/controls/ControlHost.h"
namespace cru::ui::render {
-const BoxConstraint BoxConstraint::kNotLimit{Size::kMax, Size::kZero};
+void RenderObjectDrawContext::DrawChild(RenderObject* render_object) {
+ auto offset = render_object->GetOffset();
+ paint_invalid_area.left -= offset.x;
+ paint_invalid_area.top -= offset.y;
+ painter->PushState();
+ painter->ConcatTransform(Matrix::Translation(offset));
+ render_object->Draw(*this);
+ painter->PopState();
+ paint_invalid_area.left += offset.x;
+ paint_invalid_area.top += offset.y;
+}
RenderObject::RenderObject(std::string name)
: name_(std::move(name)),
@@ -139,28 +149,35 @@ void RenderObject::OnLayoutCore(const Rect& rect) {
}
Rect RenderObject::GetPaddingRect() {
- const auto size = GetMeasureResultSize();
- Rect rect{Point{}, size};
+ Rect rect{Point{}, size_};
rect = rect.Shrink(GetMargin());
- rect.left = std::min(rect.left, size.width);
- rect.top = std::min(rect.top, size.height);
+ rect.left = std::min(rect.left, size_.width);
+ rect.top = std::min(rect.top, size_.height);
rect.width = std::max(rect.width, 0.0f);
rect.height = std::max(rect.height, 0.0f);
return rect;
}
Rect RenderObject::GetContentRect() {
- const auto size = GetMeasureResultSize();
- Rect rect{Point{}, size};
+ Rect rect{Point{}, size_};
rect = rect.Shrink(GetMargin());
rect = rect.Shrink(GetPadding());
- rect.left = std::min(rect.left, size.width);
- rect.top = std::min(rect.top, size.height);
+ rect.left = std::min(rect.left, size_.width);
+ rect.top = std::min(rect.top, size_.height);
rect.width = std::max(rect.width, 0.0f);
rect.height = std::max(rect.height, 0.0f);
return rect;
}
+Rect RenderObject::GetRenderRect() { return GetContentRect(); }
+
+void RenderObject::Draw(RenderObjectDrawContext& context) {
+ if (!context.paint_invalid_area.IsIntersect(GetRenderRect())) {
+ return;
+ }
+ OnDraw(context);
+}
+
controls::ControlHost* RenderObject::GetControlHost() {
if (control_) {
return control_->GetControlHost();
@@ -176,8 +193,9 @@ void RenderObject::InvalidateLayout() {
}
void RenderObject::InvalidatePaint() {
- if (auto window = GetControlHost()) {
- window->ScheduleRepaint();
+ if (auto host = GetControlHost()) {
+ host->AddPaintInvalidArea(GetRenderRect().WithOffset(GetTotalOffset()));
+ host->ScheduleRepaint();
}
}
diff --git a/src/ui/render/ScrollRenderObject.cpp b/src/ui/render/ScrollRenderObject.cpp
index 4d359a86..1d12c7d0 100644
--- a/src/ui/render/ScrollRenderObject.cpp
+++ b/src/ui/render/ScrollRenderObject.cpp
@@ -82,19 +82,6 @@ RenderObject* ScrollRenderObject::HitTest(const Point& point) {
return rect.IsPointInside(point) ? this : nullptr;
} // namespace cru::ui::render
-void ScrollRenderObject::Draw(platform::graphics::IPainter* painter) {
- if (auto child = GetChild()) {
- painter->PushLayer(this->GetContentRect());
- const auto offset = child->GetOffset();
- painter->PushState();
- painter->ConcatTransform(Matrix::Translation(offset));
- child->Draw(painter);
- painter->PopState();
- painter->PopLayer();
- }
- scroll_bar_delegate_->DrawScrollBar(painter);
-}
-
Point ScrollRenderObject::GetScrollOffset() {
if (auto child = GetChild()) {
return CoerceScroll(scroll_offset_, GetContentRect().GetSize(),
@@ -184,6 +171,16 @@ void ScrollRenderObject::OnLayoutContent(const Rect& content_rect) {
}
}
+void ScrollRenderObject::OnDraw(RenderObjectDrawContext& context) {
+ auto painter = context.painter;
+ if (auto child = GetChild()) {
+ painter->PushLayer(this->GetContentRect());
+ context.DrawChild(child);
+ painter->PopLayer();
+ }
+ scroll_bar_delegate_->DrawScrollBar(painter);
+}
+
void ScrollRenderObject::OnAttachedControlChanged(
controls::Control* old_control, controls::Control* new_control) {
if (new_control) {
diff --git a/src/ui/render/TextRenderObject.cpp b/src/ui/render/TextRenderObject.cpp
index 12d77d0d..032adb0f 100644
--- a/src/ui/render/TextRenderObject.cpp
+++ b/src/ui/render/TextRenderObject.cpp
@@ -1,11 +1,8 @@
#include "cru/ui/render/TextRenderObject.h"
-
-#include "cru/base/log/Logger.h"
#include "cru/platform/graphics/Factory.h"
#include "cru/platform/graphics/Painter.h"
#include "cru/platform/graphics/TextLayout.h"
#include "cru/platform/gui/UiApplication.h"
-#include "cru/ui/DebugFlags.h"
#include "cru/ui/render/RenderObject.h"
#include <limits>
@@ -176,29 +173,6 @@ RenderObject* TextRenderObject::HitTest(const Point& point) {
return padding_rect.IsPointInside(point) ? this : nullptr;
}
-void TextRenderObject::Draw(platform::graphics::IPainter* painter) {
- if constexpr (debug_flags::draw) {
- CruLogDebug(kLogTag,
- "Begin to paint, total_offset: {}, size: {}, text_layout: "
- "{}, brush: {}.",
- this->GetTotalOffset(), this->GetMeasureResultSize(),
- this->text_layout_->GetDebugString(),
- this->brush_->GetDebugString());
- }
-
- if (this->selection_range_.has_value()) {
- const auto&& rects = text_layout_->TextRangeRect(*this->selection_range_);
- for (const auto& rect : rects)
- painter->FillRectangle(rect, this->GetSelectionBrush().get());
- }
-
- painter->DrawText(Point{}, text_layout_.get(), brush_.get());
-
- if (this->draw_caret_ && this->caret_width_ != 0.0f) {
- painter->FillRectangle(GetCaretRectInContent(), this->caret_brush_.get());
- }
-}
-
Size TextRenderObject::OnMeasureContent(const MeasureRequirement& requirement) {
float measure_width = requirement.suggest.width.GetLengthOr(
requirement.max.width.GetLengthOrMaxFloat());
@@ -215,4 +189,20 @@ Size TextRenderObject::OnMeasureContent(const MeasureRequirement& requirement) {
void TextRenderObject::OnLayoutContent(const Rect& content_rect) {
CRU_UNUSED(content_rect)
}
+
+void TextRenderObject::OnDraw(RenderObjectDrawContext& context) {
+ auto painter = context.painter;
+
+ if (this->selection_range_.has_value()) {
+ const auto&& rects = text_layout_->TextRangeRect(*this->selection_range_);
+ for (const auto& rect : rects)
+ painter->FillRectangle(rect, this->GetSelectionBrush().get());
+ }
+
+ painter->DrawText(Point{}, text_layout_.get(), brush_.get());
+
+ if (this->draw_caret_ && this->caret_width_ != 0.0f) {
+ painter->FillRectangle(GetCaretRectInContent(), this->caret_brush_.get());
+ }
+}
} // namespace cru::ui::render
diff --git a/src/ui/render/TreeRenderObject.cpp b/src/ui/render/TreeRenderObject.cpp
index 758108f6..7df3d5b6 100644
--- a/src/ui/render/TreeRenderObject.cpp
+++ b/src/ui/render/TreeRenderObject.cpp
@@ -1,5 +1,4 @@
#include "cru/ui/render/TreeRenderObject.h"
-#include "cru/platform/graphics/Painter.h"
#include "cru/ui/render/MeasureRequirement.h"
#include "cru/ui/render/RenderObject.h"
@@ -78,24 +77,17 @@ RenderObject* TreeRenderObject::HitTest(const Point& point) {
}
void TreeRenderObjectItemDraw(TreeRenderObjectItem* item,
- platform::graphics::IPainter* painter) {
+ RenderObjectDrawContext& context) {
auto render_object = item->GetRenderObject();
if (render_object) {
- painter->PushState();
- painter->ConcatTransform(Matrix::Translation(render_object->GetOffset()));
- render_object->Draw(painter);
- painter->PopState();
+ context.DrawChild(render_object);
}
for (auto child : item->GetChildren()) {
- TreeRenderObjectItemDraw(child, painter);
+ TreeRenderObjectItemDraw(child, context);
}
}
-void TreeRenderObject::Draw(platform::graphics::IPainter* painter) {
- TreeRenderObjectItemDraw(root_item_, painter);
-}
-
static Size MeasureTreeRenderObjectItem(MeasureSize max_size,
TreeRenderObjectItem* item,
float tab_width) {
@@ -162,4 +154,8 @@ static void LayoutTreeRenderObjectItem(Rect rect, TreeRenderObjectItem* item,
void TreeRenderObject::OnLayoutContent(const Rect& content_rect) {
LayoutTreeRenderObjectItem(content_rect, root_item_, tab_width_);
}
+
+void TreeRenderObject::OnDraw(RenderObjectDrawContext& context) {
+ TreeRenderObjectItemDraw(root_item_, context);
+}
} // namespace cru::ui::render