aboutsummaryrefslogtreecommitdiff
path: root/include/cru/ui/render
diff options
context:
space:
mode:
Diffstat (limited to 'include/cru/ui/render')
-rw-r--r--include/cru/ui/render/Base.hpp1
-rw-r--r--include/cru/ui/render/BorderRenderObject.hpp30
-rw-r--r--include/cru/ui/render/CanvasRenderObject.hpp2
-rw-r--r--include/cru/ui/render/FlexLayoutRenderObject.hpp4
-rw-r--r--include/cru/ui/render/LayoutRenderObject.hpp2
-rw-r--r--include/cru/ui/render/MeasureRequirement.hpp28
-rw-r--r--include/cru/ui/render/RenderObject.hpp61
-rw-r--r--include/cru/ui/render/ScrollBar.hpp218
-rw-r--r--include/cru/ui/render/ScrollRenderObject.hpp27
-rw-r--r--include/cru/ui/render/TextRenderObject.hpp47
-rw-r--r--include/cru/ui/render/WindowRenderObject.hpp29
11 files changed, 359 insertions, 90 deletions
diff --git a/include/cru/ui/render/Base.hpp b/include/cru/ui/render/Base.hpp
index 801d58bd..ac67349e 100644
--- a/include/cru/ui/render/Base.hpp
+++ b/include/cru/ui/render/Base.hpp
@@ -9,5 +9,4 @@ class FlexLayoutRenderObject;
class ScrollRenderObject;
class StackLayoutRenderObject;
class TextRenderObject;
-class WindowRenderObject;
} // namespace cru::ui::render
diff --git a/include/cru/ui/render/BorderRenderObject.hpp b/include/cru/ui/render/BorderRenderObject.hpp
index 587f051a..3d4f4dad 100644
--- a/include/cru/ui/render/BorderRenderObject.hpp
+++ b/include/cru/ui/render/BorderRenderObject.hpp
@@ -1,5 +1,7 @@
#pragma once
+#include "../style/ApplyBorderStyleInfo.hpp"
#include "RenderObject.hpp"
+#include "cru/ui/Base.hpp"
namespace cru::ui::render {
class BorderRenderObject : public RenderObject {
@@ -16,11 +18,11 @@ class BorderRenderObject : public RenderObject {
bool IsBorderEnabled() const { return is_border_enabled_; }
void SetBorderEnabled(bool enabled) { is_border_enabled_ = enabled; }
- std::shared_ptr<platform::graph::IBrush> GetBorderBrush() {
+ std::shared_ptr<platform::graphics::IBrush> GetBorderBrush() {
return border_brush_;
}
- void SetBorderBrush(std::shared_ptr<platform::graph::IBrush> brush) {
+ void SetBorderBrush(std::shared_ptr<platform::graphics::IBrush> brush) {
if (brush == border_brush_) return;
border_brush_ = std::move(brush);
InvalidatePaint();
@@ -42,32 +44,32 @@ class BorderRenderObject : public RenderObject {
RecreateGeometry();
}
- std::shared_ptr<platform::graph::IBrush> GetForegroundBrush() {
+ std::shared_ptr<platform::graphics::IBrush> GetForegroundBrush() {
return foreground_brush_;
}
- void SetForegroundBrush(std::shared_ptr<platform::graph::IBrush> brush) {
+ void SetForegroundBrush(std::shared_ptr<platform::graphics::IBrush> brush) {
if (brush == foreground_brush_) return;
foreground_brush_ = std::move(brush);
InvalidatePaint();
}
- std::shared_ptr<platform::graph::IBrush> GetBackgroundBrush() {
+ std::shared_ptr<platform::graphics::IBrush> GetBackgroundBrush() {
return background_brush_;
}
- void SetBackgroundBrush(std::shared_ptr<platform::graph::IBrush> brush) {
+ void SetBackgroundBrush(std::shared_ptr<platform::graphics::IBrush> brush) {
if (brush == background_brush_) return;
background_brush_ = std::move(brush);
InvalidatePaint();
}
- void SetBorderStyle(const BorderStyle& style);
+ void ApplyBorderStyle(const style::ApplyBorderStyleInfo& style);
RenderObject* HitTest(const Point& point) override;
protected:
- void OnDrawCore(platform::graph::IPainter* painter) override;
+ void OnDrawCore(platform::graphics::IPainter* painter) override;
Size OnMeasureCore(const MeasureRequirement& requirement,
const MeasureSize& preferred_size) override;
@@ -87,19 +89,19 @@ class BorderRenderObject : public RenderObject {
private:
bool is_border_enabled_ = false;
- std::shared_ptr<platform::graph::IBrush> border_brush_;
+ std::shared_ptr<platform::graphics::IBrush> border_brush_;
Thickness border_thickness_;
CornerRadius border_radius_;
- std::shared_ptr<platform::graph::IBrush> foreground_brush_;
- std::shared_ptr<platform::graph::IBrush> background_brush_;
+ std::shared_ptr<platform::graphics::IBrush> foreground_brush_;
+ std::shared_ptr<platform::graphics::IBrush> background_brush_;
// The ring. Used for painting.
- std::unique_ptr<platform::graph::IGeometry> geometry_;
+ std::unique_ptr<platform::graphics::IGeometry> geometry_;
// Area including inner area of the border. Used for painting foreground and
// background.
- std::unique_ptr<platform::graph::IGeometry> border_inner_geometry_;
+ std::unique_ptr<platform::graphics::IGeometry> border_inner_geometry_;
// Area including border ring and inner area. Used for hit test.
- std::unique_ptr<platform::graph::IGeometry> border_outer_geometry_;
+ std::unique_ptr<platform::graphics::IGeometry> border_outer_geometry_;
};
} // namespace cru::ui::render
diff --git a/include/cru/ui/render/CanvasRenderObject.hpp b/include/cru/ui/render/CanvasRenderObject.hpp
index 3216f08c..58fee59c 100644
--- a/include/cru/ui/render/CanvasRenderObject.hpp
+++ b/include/cru/ui/render/CanvasRenderObject.hpp
@@ -22,7 +22,7 @@ class CanvasRenderObject : public RenderObject {
IEvent<CanvasPaintEventArgs>* PaintEvent() { return &paint_event_; }
protected:
- void OnDrawContent(platform::graph::IPainter* painter) override;
+ void OnDrawContent(platform::graphics::IPainter* painter) override;
Size OnMeasureContent(const MeasureRequirement& requirement,
const MeasureSize& preferred_size) override;
diff --git a/include/cru/ui/render/FlexLayoutRenderObject.hpp b/include/cru/ui/render/FlexLayoutRenderObject.hpp
index ee29d1e4..a8154487 100644
--- a/include/cru/ui/render/FlexLayoutRenderObject.hpp
+++ b/include/cru/ui/render/FlexLayoutRenderObject.hpp
@@ -1,6 +1,8 @@
#pragma once
#include "LayoutRenderObject.hpp"
+#include <string_view>
+
namespace cru::ui::render {
// Measure Logic (v0.1):
// Cross axis measure logic is the same as stack layout.
@@ -85,6 +87,8 @@ class FlexLayoutRenderObject : public LayoutRenderObject<FlexChildLayoutData> {
FlexLayoutRenderObject& operator=(FlexLayoutRenderObject&& other) = delete;
~FlexLayoutRenderObject() override = default;
+ std::u16string_view GetName() const override;
+
FlexDirection GetFlexDirection() const { return direction_; }
void SetFlexDirection(FlexDirection direction) {
direction_ = direction;
diff --git a/include/cru/ui/render/LayoutRenderObject.hpp b/include/cru/ui/render/LayoutRenderObject.hpp
index b46ba0d0..732031a1 100644
--- a/include/cru/ui/render/LayoutRenderObject.hpp
+++ b/include/cru/ui/render/LayoutRenderObject.hpp
@@ -1,7 +1,7 @@
#pragma once
#include "RenderObject.hpp"
-#include "cru/platform/graph/util/Painter.hpp"
+#include "cru/platform/graphics/util/Painter.hpp"
namespace cru::ui::render {
template <typename TChildLayoutData>
diff --git a/include/cru/ui/render/MeasureRequirement.hpp b/include/cru/ui/render/MeasureRequirement.hpp
index 2be159f8..6a0c6952 100644
--- a/include/cru/ui/render/MeasureRequirement.hpp
+++ b/include/cru/ui/render/MeasureRequirement.hpp
@@ -1,8 +1,12 @@
#pragma once
#include "Base.hpp"
+#include "cru/common/Format.hpp"
+
+#include <fmt/core.h>
#include <algorithm>
#include <limits>
+#include <string>
namespace cru::ui::render {
constexpr Size Min(const Size& left, const Size& right) {
@@ -112,6 +116,11 @@ class MeasureLength final {
}
}
+ std::u16string ToDebugString() const {
+ return IsSpecified() ? ToUtf16String(GetLengthOrUndefined())
+ : u"UNSPECIFIED";
+ }
+
private:
// -1 for not specify
float length_;
@@ -160,6 +169,11 @@ struct MeasureSize {
};
}
+ std::u16string ToDebugString() const {
+ return fmt::format(u"({}, {})", width.ToDebugString(),
+ height.ToDebugString());
+ }
+
constexpr static MeasureSize NotSpecified() {
return MeasureSize{MeasureLength::NotSpecified(),
MeasureLength::NotSpecified()};
@@ -187,10 +201,11 @@ struct MeasureRequirement {
: max(max), min(min) {}
constexpr bool Satisfy(const Size& size) const {
- return max.width.GetLengthOrMax() >= size.width &&
- max.height.GetLengthOrMax() >= size.height &&
- min.width.GetLengthOr0() <= size.width &&
- min.height.GetLengthOr0() <= size.height;
+ auto normalized = Normalize();
+ return normalized.max.width.GetLengthOrMax() >= size.width &&
+ normalized.max.height.GetLengthOrMax() >= size.height &&
+ normalized.min.width.GetLengthOr0() <= size.width &&
+ normalized.min.height.GetLengthOr0() <= size.height;
}
constexpr MeasureRequirement Normalize() const {
@@ -225,6 +240,11 @@ struct MeasureRequirement {
return result;
}
+ std::u16string ToDebugString() const {
+ return fmt::format(u"{{min: {}, max: {}}}", min.ToDebugString(),
+ max.ToDebugString());
+ }
+
constexpr static MeasureRequirement Merge(const MeasureRequirement& left,
const MeasureRequirement& right) {
return MeasureRequirement{MeasureSize::Min(left.max, right.max),
diff --git a/include/cru/ui/render/RenderObject.hpp b/include/cru/ui/render/RenderObject.hpp
index f820f029..8bcd4c62 100644
--- a/include/cru/ui/render/RenderObject.hpp
+++ b/include/cru/ui/render/RenderObject.hpp
@@ -2,10 +2,15 @@
#include "Base.hpp"
#include "MeasureRequirement.hpp"
+#include "cru/common/Base.hpp"
#include "cru/common/Event.hpp"
+#include "cru/ui/Base.hpp"
-namespace cru::ui::render {
+#include <cstddef>
+#include <string>
+#include <string_view>
+namespace cru::ui::render {
// Render object will not destroy its children when destroyed. Control must
// manage lifecycle of its render objects. Since control will destroy its
// children when destroyed, render objects will be destroyed along with it.
@@ -29,13 +34,13 @@ namespace cru::ui::render {
//
// To write a custom RenderObject, override following methods:
// public:
-// void Draw(platform::graph::IPainter* painter) override;
+// 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;
class RenderObject : public Object {
- friend WindowRenderObject;
+ friend host::WindowHost;
CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::render::RenderObject")
@@ -58,10 +63,10 @@ class RenderObject : public Object {
RenderObject& operator=(RenderObject&& other) = delete;
~RenderObject() override = default;
- Control* GetAttachedControl() const { return control_; }
- void SetAttachedControl(Control* new_control) { control_ = new_control; }
+ controls::Control* GetAttachedControl() const { return control_; }
+ void SetAttachedControl(controls::Control* new_control);
- UiHost* GetUiHost() const { return ui_host_; }
+ host::WindowHost* GetWindowHost() const { return window_host_; }
RenderObject* GetParent() const { return parent_; }
@@ -70,6 +75,9 @@ class RenderObject : public Object {
void AddChild(RenderObject* render_object, Index position);
void RemoveChild(Index position);
+ RenderObject* GetFirstChild() const;
+ void TraverseDescendants(const std::function<void(RenderObject*)>& action);
+
// Offset from parent's lefttop to lefttop of this render object. Margin is
// accounted for.
Point GetOffset() const { return offset_; }
@@ -123,16 +131,30 @@ class RenderObject : public Object {
// This will set offset of this render object and call OnLayoutCore.
void Layout(const Point& offset);
- void Draw(platform::graph::IPainter* painter);
+ virtual Rect GetPaddingRect() const;
+ virtual Rect GetContentRect() const;
+
+ void Draw(platform::graphics::IPainter* painter);
// 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;
+ IEvent<host::WindowHost*>* AttachToHostEvent() {
+ return &attach_to_host_event_;
+ }
+ IEvent<std::nullptr_t>* DetachFromHostEvent() {
+ return &detach_from_host_event_;
+ }
+
public:
void InvalidateLayout();
void InvalidatePaint();
+ public:
+ virtual std::u16string_view GetName() const;
+ std::u16string GetDebugPathInTree() const;
+
protected:
void SetChildMode(ChildMode mode) { child_mode_ = mode; }
@@ -148,15 +170,15 @@ class RenderObject : public Object {
virtual void OnRemoveChild(RenderObject* removed_child, Index position);
// Draw all children with offset.
- void DefaultDrawChildren(platform::graph::IPainter* painter);
+ void DefaultDrawChildren(platform::graphics::IPainter* painter);
// Draw all children with translation of content rect lefttop.
- void DefaultDrawContent(platform::graph::IPainter* painter);
+ void DefaultDrawContent(platform::graphics::IPainter* painter);
// Call DefaultDrawContent. Then call DefaultDrawChildren.
- virtual void OnDrawCore(platform::graph::IPainter* painter);
+ virtual void OnDrawCore(platform::graphics::IPainter* painter);
- virtual void OnDrawContent(platform::graph::IPainter* painter);
+ virtual void OnDrawContent(platform::graphics::IPainter* painter);
// Size measure including margin and padding. Please reduce margin and padding
// or other custom things and pass the result content measure requirement and
@@ -182,20 +204,20 @@ class RenderObject : public Object {
// Lefttop of content_rect should be added when calculated children's offset.
virtual void OnLayoutContent(const Rect& content_rect) = 0;
- virtual void OnAfterLayout();
- static void NotifyAfterLayoutRecursive(RenderObject* render_object);
+ virtual void OnAttachedControlChanged(controls::Control* control) {
+ CRU_UNUSED(control)
+ }
- virtual Rect GetPaddingRect() const;
- virtual Rect GetContentRect() const;
+ virtual void OnAfterLayout();
private:
void SetParent(RenderObject* new_parent);
- void SetRenderHostRecursive(UiHost* host);
+ void SetWindowHostRecursive(host::WindowHost* host);
private:
- Control* control_ = nullptr;
- UiHost* ui_host_ = nullptr;
+ controls::Control* control_ = nullptr;
+ host::WindowHost* window_host_ = nullptr;
RenderObject* parent_ = nullptr;
std::vector<RenderObject*> children_{};
@@ -210,5 +232,8 @@ class RenderObject : public Object {
Thickness margin_{};
Thickness padding_{};
+
+ Event<host::WindowHost*> attach_to_host_event_;
+ Event<std::nullptr_t> detach_from_host_event_;
};
} // namespace cru::ui::render
diff --git a/include/cru/ui/render/ScrollBar.hpp b/include/cru/ui/render/ScrollBar.hpp
new file mode 100644
index 00000000..3293e9d0
--- /dev/null
+++ b/include/cru/ui/render/ScrollBar.hpp
@@ -0,0 +1,218 @@
+#pragma once
+#include "Base.hpp"
+#include "cru/common/Base.hpp"
+#include "cru/common/Event.hpp"
+#include "cru/platform/graphics/Base.hpp"
+#include "cru/platform/graphics/Geometry.hpp"
+#include "cru/platform/graphics/Painter.hpp"
+#include "cru/platform/gui/Cursor.hpp"
+#include "cru/platform/gui/UiApplication.hpp"
+#include "cru/ui/Base.hpp"
+#include "cru/ui/controls/Control.hpp"
+
+#include <gsl/pointers>
+#include <memory>
+#include <optional>
+
+namespace cru::ui::render {
+class ScrollRenderObject;
+
+enum class ScrollKind { Absolute, Relative, Page, Line };
+
+struct Scroll {
+ Direction direction;
+ ScrollKind kind;
+ // For absolute, the new scroll position. Otherwise, offset.
+ float value;
+};
+
+enum class ScrollBarAreaKind {
+ UpArrow, // Line up
+ DownArrow, // Line down
+ UpSlot, // Page up
+ DownSlot, // Page down
+ Thumb
+};
+
+class ScrollBar : public Object {
+ public:
+ ScrollBar(gsl::not_null<ScrollRenderObject*> render_object,
+ Direction direction);
+
+ CRU_DELETE_COPY(ScrollBar)
+ CRU_DELETE_MOVE(ScrollBar)
+
+ ~ScrollBar() override;
+
+ public:
+ Direction GetDirection() const { return direction_; }
+
+ bool IsEnabled() const { return is_enabled_; }
+ void SetEnabled(bool value);
+
+ bool IsExpanded() const { return is_expanded_; }
+ void SetExpanded(bool value);
+
+ void Draw(platform::graphics::IPainter* painter);
+
+ IEvent<Scroll>* ScrollAttemptEvent() { return &scroll_attempt_event_; }
+
+ void InstallHandlers(controls::Control* control);
+ void UninstallHandlers() { InstallHandlers(nullptr); }
+
+ gsl::not_null<std::shared_ptr<platform::graphics::IBrush>>
+ GetCollapsedThumbBrush() const;
+ gsl::not_null<std::shared_ptr<platform::graphics::IBrush>>
+ GetExpandedThumbBrush() const;
+ gsl::not_null<std::shared_ptr<platform::graphics::IBrush>>
+ GetExpandedSlotBrush() const;
+ gsl::not_null<std::shared_ptr<platform::graphics::IBrush>>
+ GetExpandedArrowBrush() const;
+ gsl::not_null<std::shared_ptr<platform::graphics::IBrush>>
+ GetExpandedArrowBackgroundBrush() const;
+
+ protected:
+ void OnDraw(platform::graphics::IPainter* painter, bool expand);
+
+ virtual void DrawUpArrow(platform::graphics::IPainter* painter,
+ const Rect& area) = 0;
+ virtual void DrawDownArrow(platform::graphics::IPainter* painter,
+ const Rect& area) = 0;
+
+ std::optional<ScrollBarAreaKind> ExpandedHitTest(const Point& point);
+
+ virtual bool IsShowBar() = 0;
+
+ virtual std::optional<Rect> GetExpandedAreaRect(
+ ScrollBarAreaKind area_kind) = 0;
+ virtual std::optional<Rect> GetCollapsedTriggerExpandAreaRect() = 0;
+ virtual std::optional<Rect> GetCollapsedThumbRect() = 0;
+
+ virtual float CalculateNewScrollPosition(const Rect& thumb_original_rect,
+ const Point& mouse_offset) = 0;
+
+ private:
+ void SetCursor();
+ void RestoreCursor();
+
+ void BeginAutoCollapseTimer();
+ void StopAutoCollapseTimer();
+
+ void OnMouseLeave();
+
+ protected:
+ gsl::not_null<ScrollRenderObject*> render_object_;
+
+ std::unique_ptr<platform::graphics::IGeometry> arrow_geometry_;
+
+ private:
+ Direction direction_;
+
+ bool is_enabled_ = true;
+
+ bool is_expanded_ = false;
+
+ std::shared_ptr<platform::graphics::IBrush> collapsed_thumb_brush_;
+ std::shared_ptr<platform::graphics::IBrush> expanded_thumb_brush_;
+ std::shared_ptr<platform::graphics::IBrush> expanded_slot_brush_;
+ std::shared_ptr<platform::graphics::IBrush> expanded_arrow_brush_;
+ std::shared_ptr<platform::graphics::IBrush> expanded_arrow_background_brush_;
+
+ Rect move_thumb_thumb_original_rect_;
+ std::optional<Point> move_thumb_start_;
+
+ EventRevokerListGuard event_guard_;
+
+ Event<Scroll> scroll_attempt_event_;
+
+ std::optional<std::shared_ptr<platform::gui::ICursor>> old_cursor_;
+
+ platform::gui::TimerAutoCanceler auto_collapse_timer_canceler_;
+};
+
+class HorizontalScrollBar : public ScrollBar {
+ public:
+ explicit HorizontalScrollBar(
+ gsl::not_null<ScrollRenderObject*> render_object);
+
+ CRU_DELETE_COPY(HorizontalScrollBar)
+ CRU_DELETE_MOVE(HorizontalScrollBar)
+
+ ~HorizontalScrollBar() override = default;
+
+ protected:
+ void DrawUpArrow(platform::graphics::IPainter* painter,
+ const Rect& area) override;
+ void DrawDownArrow(platform::graphics::IPainter* painter,
+ const Rect& area) override;
+
+ bool IsShowBar() override;
+
+ std::optional<Rect> GetExpandedAreaRect(ScrollBarAreaKind area_kind) override;
+ std::optional<Rect> GetCollapsedTriggerExpandAreaRect() override;
+ std::optional<Rect> GetCollapsedThumbRect() override;
+
+ float CalculateNewScrollPosition(const Rect& thumb_original_rect,
+ const Point& mouse_offset) override;
+};
+
+class VerticalScrollBar : public ScrollBar {
+ public:
+ explicit VerticalScrollBar(gsl::not_null<ScrollRenderObject*> render_object);
+
+ CRU_DELETE_COPY(VerticalScrollBar)
+ CRU_DELETE_MOVE(VerticalScrollBar)
+
+ ~VerticalScrollBar() override = default;
+
+ protected:
+ void DrawUpArrow(platform::graphics::IPainter* painter,
+ const Rect& area) override;
+ void DrawDownArrow(platform::graphics::IPainter* painter,
+ const Rect& area) override;
+
+ bool IsShowBar() override;
+
+ std::optional<Rect> GetExpandedAreaRect(ScrollBarAreaKind area_kind) override;
+ std::optional<Rect> GetCollapsedTriggerExpandAreaRect() override;
+ std::optional<Rect> GetCollapsedThumbRect() override;
+
+ float CalculateNewScrollPosition(const Rect& thumb_original_rect,
+ const Point& mouse_offset) override;
+};
+
+// A delegate to draw scrollbar and register related events.
+class ScrollBarDelegate : public Object {
+ public:
+ explicit ScrollBarDelegate(gsl::not_null<ScrollRenderObject*> render_object);
+
+ CRU_DELETE_COPY(ScrollBarDelegate)
+ CRU_DELETE_MOVE(ScrollBarDelegate)
+
+ ~ScrollBarDelegate() override = default;
+
+ public:
+ bool IsHorizontalBarEnabled() const { return horizontal_bar_.IsEnabled(); }
+ void SetHorizontalBarEnabled(bool value) {
+ horizontal_bar_.SetEnabled(value);
+ }
+
+ bool IsVerticalBarEnabled() const { return horizontal_bar_.IsEnabled(); }
+ void SetVerticalBarEnabled(bool value) { horizontal_bar_.SetEnabled(value); }
+
+ IEvent<Scroll>* ScrollAttemptEvent() { return &scroll_attempt_event_; }
+
+ void DrawScrollBar(platform::graphics::IPainter* painter);
+
+ void InstallHandlers(controls::Control* control);
+ void UninstallHandlers() { InstallHandlers(nullptr); }
+
+ private:
+ gsl::not_null<ScrollRenderObject*> render_object_;
+
+ HorizontalScrollBar horizontal_bar_;
+ VerticalScrollBar vertical_bar_;
+
+ Event<Scroll> scroll_attempt_event_;
+};
+} // namespace cru::ui::render
diff --git a/include/cru/ui/render/ScrollRenderObject.hpp b/include/cru/ui/render/ScrollRenderObject.hpp
index 9b0cbf9a..aed25f8e 100644
--- a/include/cru/ui/render/ScrollRenderObject.hpp
+++ b/include/cru/ui/render/ScrollRenderObject.hpp
@@ -1,8 +1,11 @@
#pragma once
#include "RenderObject.hpp"
-#include "cru/platform/graph/util/Painter.hpp"
+#include "cru/platform/graphics/util/Painter.hpp"
+#include "cru/ui/Base.hpp"
+#include "cru/ui/render/ScrollBar.hpp"
+#include <memory>
#include <optional>
namespace cru::ui::render {
@@ -16,7 +19,7 @@ namespace cru::ui::render {
// Or layout by scroll state.
class ScrollRenderObject : public RenderObject {
public:
- ScrollRenderObject() : RenderObject(ChildMode::Single) {}
+ ScrollRenderObject();
CRU_DELETE_COPY(ScrollRenderObject)
CRU_DELETE_MOVE(ScrollRenderObject)
@@ -27,8 +30,22 @@ class ScrollRenderObject : public RenderObject {
// Return the coerced scroll offset.
Point GetScrollOffset();
+ float GetScrollOffset(Direction direction) {
+ return direction == Direction::Horizontal ? GetScrollOffset().x
+ : GetScrollOffset().y;
+ }
void SetScrollOffset(const Point& offset);
void SetScrollOffset(std::optional<float> x, std::optional<float> y);
+ void SetScrollOffset(Direction direction, std::optional<float> value) {
+ if (direction == Direction::Horizontal) {
+ SetScrollOffset(value, std::nullopt);
+ } else {
+ SetScrollOffset(std::nullopt, value);
+ }
+ }
+
+ void Scroll(const Scroll& scroll);
+
Point GetRawScrollOffset() const { return scroll_offset_; }
// Return the viewable area rect.
@@ -44,7 +61,7 @@ class ScrollRenderObject : public RenderObject {
void ScrollToContain(const Rect& rect, const Thickness& margin = Thickness{});
protected:
- void OnDrawCore(platform::graph::IPainter* painter) override;
+ void OnDrawCore(platform::graphics::IPainter* painter) override;
// Logic:
// If available size is bigger than child's preferred size, then child's
@@ -54,7 +71,11 @@ class ScrollRenderObject : public RenderObject {
const MeasureSize& preferred_size) override;
void OnLayoutContent(const Rect& content_rect) override;
+ void OnAttachedControlChanged(controls::Control* control) override;
+
private:
Point scroll_offset_;
+
+ std::unique_ptr<ScrollBarDelegate> scroll_bar_delegate_;
};
} // namespace cru::ui::render
diff --git a/include/cru/ui/render/TextRenderObject.hpp b/include/cru/ui/render/TextRenderObject.hpp
index 3be42bbb..bdec18d1 100644
--- a/include/cru/ui/render/TextRenderObject.hpp
+++ b/include/cru/ui/render/TextRenderObject.hpp
@@ -24,10 +24,10 @@ class TextRenderObject : public RenderObject {
constexpr static float default_caret_width = 2;
public:
- TextRenderObject(std::shared_ptr<platform::graph::IBrush> brush,
- std::shared_ptr<platform::graph::IFont> font,
- std::shared_ptr<platform::graph::IBrush> selection_brush,
- std::shared_ptr<platform::graph::IBrush> caret_brush);
+ TextRenderObject(std::shared_ptr<platform::graphics::IBrush> brush,
+ std::shared_ptr<platform::graphics::IFont> font,
+ std::shared_ptr<platform::graphics::IBrush> selection_brush,
+ std::shared_ptr<platform::graphics::IBrush> caret_brush);
TextRenderObject(const TextRenderObject& other) = delete;
TextRenderObject(TextRenderObject&& other) = delete;
TextRenderObject& operator=(const TextRenderObject& other) = delete;
@@ -38,25 +38,27 @@ class TextRenderObject : public RenderObject {
std::u16string_view GetTextView() const;
void SetText(std::u16string new_text);
- std::shared_ptr<platform::graph::IBrush> GetBrush() const { return brush_; }
- void SetBrush(std::shared_ptr<platform::graph::IBrush> new_brush);
+ std::shared_ptr<platform::graphics::IBrush> GetBrush() const {
+ return brush_;
+ }
+ void SetBrush(std::shared_ptr<platform::graphics::IBrush> new_brush);
- std::shared_ptr<platform::graph::IFont> GetFont() const;
- void SetFont(std::shared_ptr<platform::graph::IFont> font);
+ std::shared_ptr<platform::graphics::IFont> GetFont() const;
+ void SetFont(std::shared_ptr<platform::graphics::IFont> font);
std::vector<Rect> TextRangeRect(const TextRange& text_range);
Point TextSinglePoint(gsl::index position, bool trailing);
- platform::graph::TextHitTestResult TextHitTest(const Point& point);
+ platform::graphics::TextHitTestResult TextHitTest(const Point& point);
std::optional<TextRange> GetSelectionRange() const {
return selection_range_;
}
void SetSelectionRange(std::optional<TextRange> new_range);
- std::shared_ptr<platform::graph::IBrush> GetSelectionBrush() const {
+ std::shared_ptr<platform::graphics::IBrush> GetSelectionBrush() const {
return selection_brush_;
}
- void SetSelectionBrush(std::shared_ptr<platform::graph::IBrush> new_brush);
+ void SetSelectionBrush(std::shared_ptr<platform::graphics::IBrush> new_brush);
bool IsDrawCaret() const { return draw_caret_; }
void SetDrawCaret(bool draw_caret);
@@ -72,18 +74,23 @@ class TextRenderObject : public RenderObject {
// Lefttop relative to render object lefttop.
Rect GetCaretRect();
- std::shared_ptr<platform::graph::IBrush> GetCaretBrush() const {
+ std::shared_ptr<platform::graphics::IBrush> GetCaretBrush() const {
return caret_brush_;
}
- void GetCaretBrush(std::shared_ptr<platform::graph::IBrush> brush);
+ void GetCaretBrush(std::shared_ptr<platform::graphics::IBrush> brush);
float GetCaretWidth() const { return caret_width_; }
void SetCaretWidth(float width);
+ bool IsMeasureIncludingTrailingSpace() const {
+ return is_measure_including_trailing_space_;
+ }
+ void SetMeasureIncludingTrailingSpace(bool including);
+
RenderObject* HitTest(const Point& point) override;
protected:
- void OnDrawContent(platform::graph::IPainter* painter) override;
+ void OnDrawContent(platform::graphics::IPainter* painter) override;
// See remarks of this class.
Size OnMeasureContent(const MeasureRequirement& requirement,
@@ -93,16 +100,18 @@ class TextRenderObject : public RenderObject {
void OnAfterLayout() override;
private:
- std::shared_ptr<platform::graph::IBrush> brush_;
- std::shared_ptr<platform::graph::IFont> font_;
- std::unique_ptr<platform::graph::ITextLayout> text_layout_;
+ std::shared_ptr<platform::graphics::IBrush> brush_;
+ std::shared_ptr<platform::graphics::IFont> font_;
+ std::unique_ptr<platform::graphics::ITextLayout> text_layout_;
std::optional<TextRange> selection_range_ = std::nullopt;
- std::shared_ptr<platform::graph::IBrush> selection_brush_;
+ std::shared_ptr<platform::graphics::IBrush> selection_brush_;
bool draw_caret_ = false;
gsl::index caret_position_ = 0;
- std::shared_ptr<platform::graph::IBrush> caret_brush_;
+ std::shared_ptr<platform::graphics::IBrush> caret_brush_;
float caret_width_ = default_caret_width;
+
+ bool is_measure_including_trailing_space_ = false;
};
} // namespace cru::ui::render
diff --git a/include/cru/ui/render/WindowRenderObject.hpp b/include/cru/ui/render/WindowRenderObject.hpp
deleted file mode 100644
index 4c254f42..00000000
--- a/include/cru/ui/render/WindowRenderObject.hpp
+++ /dev/null
@@ -1,29 +0,0 @@
-#pragma once
-#include "RenderObject.hpp"
-
-namespace cru::ui::render {
-class WindowRenderObject : public RenderObject {
- public:
- WindowRenderObject(UiHost* host);
- WindowRenderObject(const WindowRenderObject& other) = delete;
- WindowRenderObject(WindowRenderObject&& other) = delete;
- WindowRenderObject& operator=(const WindowRenderObject& other) = delete;
- WindowRenderObject& operator=(WindowRenderObject&& other) = delete;
- ~WindowRenderObject() override = default;
-
- RenderObject* HitTest(const Point& point) override;
-
- protected:
- Size OnMeasureContent(const MeasureRequirement& requirement,
- const MeasureSize& preferred_size) override;
- void OnLayoutContent(const Rect& content_rect) override;
-
- private:
- RenderObject* GetChild() const {
- return GetChildren().empty() ? nullptr : GetChildren()[0];
- }
-
- private:
- EventRevokerGuard after_layout_event_guard_;
-};
-} // namespace cru::ui::render