aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/cru/platform/GraphicsBase.h70
-rw-r--r--include/cru/ui/controls/ControlHost.h7
-rw-r--r--include/cru/ui/render/BorderRenderObject.h2
-rw-r--r--include/cru/ui/render/CanvasRenderObject.h3
-rw-r--r--include/cru/ui/render/GeometryRenderObject.h2
-rw-r--r--include/cru/ui/render/LayoutRenderObject.h20
-rw-r--r--include/cru/ui/render/RenderObject.h42
-rw-r--r--include/cru/ui/render/ScrollRenderObject.h3
-rw-r--r--include/cru/ui/render/TextRenderObject.h3
-rw-r--r--include/cru/ui/render/TreeRenderObject.h3
10 files changed, 81 insertions, 74 deletions
diff --git a/include/cru/platform/GraphicsBase.h b/include/cru/platform/GraphicsBase.h
index 81c44cb6..14c5d926 100644
--- a/include/cru/platform/GraphicsBase.h
+++ b/include/cru/platform/GraphicsBase.h
@@ -152,37 +152,38 @@ struct Rect final {
constexpr static Rect FromVertices(const float left, const float top,
const float right, const float bottom) {
- return Rect(left, top, right - left, bottom - top);
+ return {left, top, right - left, bottom - top};
}
constexpr static Rect FromVertices(const Point& lefttop,
const Point& rightbottom) {
- return Rect(lefttop.x, lefttop.y, rightbottom.x - lefttop.x,
- rightbottom.y - lefttop.y);
+ return {lefttop.x, lefttop.y, rightbottom.x - lefttop.x,
+ rightbottom.y - lefttop.y};
}
constexpr static Rect FromCenter(const Point& center, const float width,
const float height) {
- return Rect(center.x - width / 2.0f, center.y - height / 2.0f, width,
- height);
+ return {center.x - width / 2.0f, center.y - height / 2.0f, width, height};
}
+ constexpr bool HasNoSize() const { return width == 0.f || height == 0.f; }
+
constexpr float GetRight() const { return left + width; }
constexpr float GetBottom() const { return top + height; }
- constexpr Point GetLeftTop() const { return Point(left, top); }
+ constexpr Point GetLeftTop() const { return {left, top}; }
constexpr Point GetRightBottom() const {
- return Point(left + width, top + height);
+ return {left + width, top + height};
}
- constexpr Point GetLeftBottom() const { return Point(left, top + height); }
+ constexpr Point GetLeftBottom() const { return {left, top + height}; }
- constexpr Point GetRightTop() const { return Point(left + width, top); }
+ constexpr Point GetRightTop() const { return {left + width, top}; }
constexpr Point GetCenter() const {
- return Point(left + width / 2.0f, top + height / 2.0f);
+ return {left + width / 2.0f, top + height / 2.0f};
}
constexpr void SetSize(const Size& size) {
@@ -192,28 +193,21 @@ struct Rect final {
constexpr Size GetSize() const { return Size(width, height); }
+ constexpr Rect WithOffset(const Point& offset) const {
+ return {left + offset.x, top + offset.y, width, height};
+ }
+
constexpr Rect Expand(const Thickness& thickness) const {
- return Rect(left - thickness.left, top - thickness.top,
- width + thickness.GetHorizontalTotal(),
- height + thickness.GetVerticalTotal());
+ return {left - thickness.left, top - thickness.top,
+ width + thickness.GetHorizontalTotal(),
+ height + thickness.GetVerticalTotal()};
}
constexpr Rect Shrink(const Thickness& thickness,
bool normalize = false) const {
- Rect result(left + thickness.left, top + thickness.top,
- width - thickness.GetHorizontalTotal(),
- height - thickness.GetVerticalTotal());
-
- if (normalize) {
- if (result.width < 0) {
- result.width = 0;
- }
- if (result.height < 0) {
- result.height = 0;
- }
- }
-
- return result;
+ return {left + thickness.left, top + thickness.top,
+ width - thickness.GetHorizontalTotal(),
+ height - thickness.GetVerticalTotal()};
}
constexpr Rect Scale(float scale) const {
@@ -238,6 +232,28 @@ struct Rect final {
return result;
}
+ constexpr bool IsIntersect(const Rect& other) const {
+ if (HasNoSize() || other.HasNoSize()) {
+ return false;
+ }
+
+ if (left >= other.GetRight() || GetRight() <= other.left) {
+ return false;
+ }
+
+ if (top >= other.GetBottom() || GetBottom() <= other.top) {
+ return false;
+ }
+
+ return true;
+ }
+
+ constexpr Rect Union(const Rect& other) const {
+ return FromVertices(std::min(left, other.left), std::min(top, other.top),
+ std::max(GetRight(), other.GetRight()),
+ std::max(GetBottom(), other.GetBottom()));
+ }
+
std::string ToString() const {
return std::format("Rect(left: {}, top: {}, width: {}, height: {})", left,
top, width, height);
diff --git a/include/cru/ui/controls/ControlHost.h b/include/cru/ui/controls/ControlHost.h
index 5d0b7947..e6eb472d 100644
--- a/include/cru/ui/controls/ControlHost.h
+++ b/include/cru/ui/controls/ControlHost.h
@@ -23,6 +23,9 @@ class CRU_UI_API ControlHost : public Object {
void ScheduleRepaint();
void ScheduleRelayout();
+ Rect GetPaintInvalidArea();
+ void AddPaintInvalidArea(const Rect& area);
+
void Repaint();
void Relayout();
void RelayoutWithSize(const Size& available_size = Size::Infinite(),
@@ -56,7 +59,7 @@ class CRU_UI_API ControlHost : public Object {
std::unique_ptr<platform::gui::INativeWindow> CreateNativeWindow();
void OnNativeDestroy(std::nullptr_t);
- void OnNativePaint(std::nullptr_t);
+ void OnNativePaint1(const cru::platform::gui::NativePaintEventArgs& args);
void OnNativeResize(const Size& size);
void OnNativeFocus(cru::platform::gui::FocusChangeType focus);
void OnNativeMouseEnterLeave(cru::platform::gui::MouseEnterLeaveType enter);
@@ -190,6 +193,8 @@ class CRU_UI_API ControlHost : public Object {
bool layout_prefer_to_fill_window_;
+ Rect paint_invalid_area_;
+
platform::gui::TimerAutoCanceler relayout_schedule_canceler_;
};
} // namespace cru::ui::controls
diff --git a/include/cru/ui/render/BorderRenderObject.h b/include/cru/ui/render/BorderRenderObject.h
index 73fc85c1..c011cda0 100644
--- a/include/cru/ui/render/BorderRenderObject.h
+++ b/include/cru/ui/render/BorderRenderObject.h
@@ -43,7 +43,6 @@ class CRU_UI_API BorderRenderObject : public SingleChildRenderObject {
void ApplyBorderStyle(const style::ApplyBorderStyleInfo& style);
RenderObject* HitTest(const Point& point) override;
- void Draw(platform::graphics::IPainter* painter) override;
Thickness GetTotalSpaceThickness() override;
Thickness GetInnerSpaceThickness() override;
@@ -53,6 +52,7 @@ class CRU_UI_API BorderRenderObject : public SingleChildRenderObject {
protected:
Size OnMeasureContent(const MeasureRequirement& requirement) override;
void OnLayoutContent(const Rect& content_rect) override;
+ void OnDraw(RenderObjectDrawContext& context) override;
void OnResize(const Size& new_size) override;
diff --git a/include/cru/ui/render/CanvasRenderObject.h b/include/cru/ui/render/CanvasRenderObject.h
index 2e44fcc2..b2da3207 100644
--- a/include/cru/ui/render/CanvasRenderObject.h
+++ b/include/cru/ui/render/CanvasRenderObject.h
@@ -33,12 +33,11 @@ class CRU_UI_API CanvasRenderObject : public RenderObject {
public:
RenderObject* HitTest(const Point& point) override;
- void Draw(platform::graphics::IPainter* painter) override;
-
CRU_DEFINE_EVENT(Paint, const CanvasPaintEventArgs&)
protected:
Size OnMeasureContent(const MeasureRequirement& requirement) override;
void OnLayoutContent(const Rect& content_rect) override;
+ void OnDraw(RenderObjectDrawContext& context) override;
};
} // namespace cru::ui::render
diff --git a/include/cru/ui/render/GeometryRenderObject.h b/include/cru/ui/render/GeometryRenderObject.h
index 1994daf3..455af6b8 100644
--- a/include/cru/ui/render/GeometryRenderObject.h
+++ b/include/cru/ui/render/GeometryRenderObject.h
@@ -15,7 +15,6 @@ class GeometryRenderObject : public RenderObject {
GeometryRenderObject();
public:
- void Draw(platform::graphics::IPainter* painter) override;
RenderObject* HitTest(const Point& point) override;
std::shared_ptr<platform::graphics::IGeometry> GetGeometry();
@@ -37,6 +36,7 @@ class GeometryRenderObject : public RenderObject {
protected:
Size OnMeasureContent(const MeasureRequirement& requirement) override;
void OnLayoutContent(const Rect& content_rect) override;
+ void OnDraw(RenderObjectDrawContext& context) override;
private:
std::shared_ptr<platform::graphics::IGeometry> geometry_ = nullptr;
diff --git a/include/cru/ui/render/LayoutRenderObject.h b/include/cru/ui/render/LayoutRenderObject.h
index 5cb70680..99dd8057 100644
--- a/include/cru/ui/render/LayoutRenderObject.h
+++ b/include/cru/ui/render/LayoutRenderObject.h
@@ -1,8 +1,6 @@
#pragma once
#include "RenderObject.h"
-#include "cru/platform/graphics/Painter.h"
-
namespace cru::ui::render {
template <typename TChildLayoutData>
class LayoutRenderObject : public RenderObject {
@@ -81,16 +79,6 @@ class LayoutRenderObject : public RenderObject {
InvalidateLayout();
}
- void Draw(platform::graphics::IPainter* painter) override {
- for (const auto& child : children_) {
- painter->PushState();
- painter->ConcatTransform(
- Matrix::Translation(child.render_object->GetOffset()));
- child.render_object->Draw(painter);
- painter->PopState();
- }
- }
-
RenderObject* HitTest(const Point& point) override {
const auto child_count = GetChildCount();
for (auto i = child_count - 1; i >= 0; --i) {
@@ -104,6 +92,14 @@ class LayoutRenderObject : public RenderObject {
return GetPaddingRect().IsPointInside(point) ? this : nullptr;
}
+ protected:
+ void OnDraw(RenderObjectDrawContext& context) override {
+ auto painter = context.painter;
+ for (const auto& child : children_) {
+ context.DrawChild(child.render_object);
+ }
+ }
+
private:
std::vector<ChildData> children_;
};
diff --git a/include/cru/ui/render/RenderObject.h b/include/cru/ui/render/RenderObject.h
index e696aefe..85cb7990 100644
--- a/include/cru/ui/render/RenderObject.h
+++ b/include/cru/ui/render/RenderObject.h
@@ -1,33 +1,24 @@
#pragma once
#include "../Base.h"
-
#include "MeasureRequirement.h"
#include <cru/base/Event.h>
#include <cru/platform/graphics/Painter.h>
+
#include <string>
namespace cru::ui::render {
-struct BoxConstraint {
- static const BoxConstraint kNotLimit;
-
- Size max;
- Size min;
+class RenderObject;
- constexpr bool Validate() const {
- return max.width >= min.width && max.height >= min.height &&
- min.width >= 0 && min.height >= 0;
- }
-
- constexpr bool Satisfy(const Size& size) const {
- return size.width <= max.width && size.height <= max.height &&
- size.width >= min.width && size.height >= min.height;
- }
+struct CRU_UI_API RenderObjectDrawContext {
+ /**
+ * Coordinates are related to the render object to be painted. So parent
+ * render object should adjust this before passing to children.
+ */
+ Rect paint_invalid_area;
+ platform::graphics::IPainter* painter;
- constexpr Size Coerce(const Size& size) const {
- return Size{std::min(std::max(size.width, min.width), max.width),
- std::min(std::max(size.height, min.height), max.height)};
- }
+ void DrawChild(RenderObject* render_object);
};
/**
@@ -37,11 +28,11 @@ struct BoxConstraint {
* To write a custom RenderObject, override following methods:
*
* public:
- * void Draw(platform::graphics::IPainter* painter) override;
* RenderObject* HitTest(const Point& point) override;
* protected:
* Size OnMeasureContent(const MeasureRequirement& requirement) override;
* void OnLayoutContent(const Rect& content_rect) override;
+ * void OnDraw(RenderObjectDrawContext& context) override;
*/
class CRU_UI_API RenderObject : public Object {
private:
@@ -124,10 +115,12 @@ class CRU_UI_API RenderObject : public Object {
virtual Rect GetPaddingRect();
virtual Rect GetContentRect();
- virtual void Draw(platform::graphics::IPainter* painter) = 0;
+ virtual Rect GetRenderRect();
- // Param point must be relative the lefttop of render object including margin.
- // Add offset before pass point to children.
+ void Draw(RenderObjectDrawContext& context);
+
+ // Param point must be relative the lefttop of render object including
+ // margin. Add offset before pass point to children.
virtual RenderObject* HitTest(const Point& point) = 0;
public:
@@ -160,13 +153,14 @@ class CRU_UI_API RenderObject : public Object {
// Override this function to measure content and children(Call Measure on
// them). Do not consider margin or padding in this method because they are
// already considered in OnMeasureCore. Returned size must obey requirement.
- // Caller should guarantee preferred_size is corerced into required range.
virtual Size OnMeasureContent(const MeasureRequirement& requirement) = 0;
// Layout all content and children(Call Layout on them).
// Lefttop of content_rect should be added when calculated children's offset.
virtual void OnLayoutContent(const Rect& content_rect) = 0;
+ virtual void OnDraw(RenderObjectDrawContext& context) = 0;
+
virtual void OnAttachedControlChanged(controls::Control* old_control,
controls::Control* new_control) {}
diff --git a/include/cru/ui/render/ScrollRenderObject.h b/include/cru/ui/render/ScrollRenderObject.h
index ae11f361..ed67331d 100644
--- a/include/cru/ui/render/ScrollRenderObject.h
+++ b/include/cru/ui/render/ScrollRenderObject.h
@@ -62,8 +62,6 @@ class CRU_UI_API ScrollRenderObject : public SingleChildRenderObject {
bool VerticalCanScrollUp();
bool VerticalCanScrollDown();
- void Draw(platform::graphics::IPainter* painter) override;
-
protected:
// Logic:
// If available size is bigger than child's preferred size, then child's
@@ -71,6 +69,7 @@ class CRU_UI_API ScrollRenderObject : public SingleChildRenderObject {
// If not, all available size is taken while forming a scroll area.
Size OnMeasureContent(const MeasureRequirement& requirement) override;
void OnLayoutContent(const Rect& content_rect) override;
+ void OnDraw(RenderObjectDrawContext& context) override;
void OnAttachedControlChanged(controls::Control* old_control,
controls::Control* new_control) override;
diff --git a/include/cru/ui/render/TextRenderObject.h b/include/cru/ui/render/TextRenderObject.h
index 0d17853b..eefb3264 100644
--- a/include/cru/ui/render/TextRenderObject.h
+++ b/include/cru/ui/render/TextRenderObject.h
@@ -88,12 +88,11 @@ class CRU_UI_API TextRenderObject : public RenderObject {
RenderObject* HitTest(const Point& point) override;
- void Draw(platform::graphics::IPainter* painter) override;
-
protected:
// See remarks of this class.
Size OnMeasureContent(const MeasureRequirement& requirement) override;
void OnLayoutContent(const Rect& content_rect) override;
+ void OnDraw(RenderObjectDrawContext& context) override;
private:
std::shared_ptr<platform::graphics::IBrush> brush_;
diff --git a/include/cru/ui/render/TreeRenderObject.h b/include/cru/ui/render/TreeRenderObject.h
index 599e0f65..425eee23 100644
--- a/include/cru/ui/render/TreeRenderObject.h
+++ b/include/cru/ui/render/TreeRenderObject.h
@@ -62,11 +62,10 @@ class CRU_UI_API TreeRenderObject : public RenderObject {
RenderObject* HitTest(const Point& point) override;
- void Draw(platform::graphics::IPainter* painter) override;
-
protected:
Size OnMeasureContent(const MeasureRequirement& requirement) override;
void OnLayoutContent(const Rect& content_rect) override;
+ void OnDraw(RenderObjectDrawContext& context) override;
private:
float tab_width_ = 12.f;