From 74bb9cd27242b9320f99ff4d2b50c3051576cc14 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 8 Feb 2022 16:53:51 +0800 Subject: ... --- include/cru/ui/render/TextRenderObject.h | 121 +++++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 include/cru/ui/render/TextRenderObject.h (limited to 'include/cru/ui/render/TextRenderObject.h') diff --git a/include/cru/ui/render/TextRenderObject.h b/include/cru/ui/render/TextRenderObject.h new file mode 100644 index 00000000..3b5f581a --- /dev/null +++ b/include/cru/ui/render/TextRenderObject.h @@ -0,0 +1,121 @@ +#pragma once +#include "RenderObject.h" + +#include + +namespace cru::ui::render { +// Layout logic: +// 1. If preferred width is set then it is taken to do a text measure. If not +// set, then max width is taken to do that. +// 2. If the actual width of text after measure exceeds the required width, +// coerced value is returned and an error is reported. If preferred width is set +// and actual width is smaller than that, then preferred width is used. If +// preferred width is not set, then the same thing is applied to min width. +// 3. If actual height of text is bigger than max height, an error is reported +// and coerced value is returned. Or height is lifted up to be at least +// preferred size if set or min height. +// +// If the result layout box is bigger than actual text box, then text is center +// aligned. +class CRU_UI_API TextRenderObject : public RenderObject { + CRU_DEFINE_CLASS_LOG_TAG(u"cru::ui::render::TextRenderObject") + + public: + constexpr static float default_caret_width = 2; + + public: + TextRenderObject(std::shared_ptr brush, + std::shared_ptr font, + std::shared_ptr selection_brush, + std::shared_ptr caret_brush); + TextRenderObject(const TextRenderObject& other) = delete; + TextRenderObject(TextRenderObject&& other) = delete; + TextRenderObject& operator=(const TextRenderObject& other) = delete; + TextRenderObject& operator=(TextRenderObject&& other) = delete; + ~TextRenderObject() override; + + String GetText() const; + void SetText(String new_text); + + void SetBrush(std::shared_ptr new_brush); + + std::shared_ptr GetFont() const; + void SetFont(std::shared_ptr font); + + bool IsEditMode(); + void SetEditMode(bool enable); + + Index GetLineCount(); + Index GetLineIndexFromCharIndex(Index char_index); + float GetLineHeight(Index line_index); + std::vector TextRangeRect(const TextRange& text_range); + Rect TextSinglePoint(gsl::index position, bool trailing); + platform::graphics::TextHitTestResult TextHitTest(const Point& point); + + std::optional GetSelectionRange() const { + return selection_range_; + } + void SetSelectionRange(std::optional new_range); + + std::shared_ptr GetSelectionBrush() const { + return selection_brush_; + } + void SetSelectionBrush(std::shared_ptr new_brush); + + bool IsDrawCaret() const { return draw_caret_; } + void SetDrawCaret(bool draw_caret); + void ToggleDrawCaret() { SetDrawCaret(!IsDrawCaret()); } + + // Caret position can be any value. When it is negative, 0 is used. When it + // exceeds the size of the string, the size of the string is used. + gsl::index GetCaretPosition() const { return caret_position_; } + void SetCaretPosition(gsl::index position); + + // Lefttop relative to content lefttop. + Rect GetCaretRectInContent(); + // Lefttop relative to render object lefttop. + Rect GetCaretRect(); + + std::shared_ptr GetCaretBrush() const { + return caret_brush_; + } + void GetCaretBrush(std::shared_ptr 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; + + std::u16string_view GetName() const override { return u"TextRenderObject"; } + + protected: + void OnDrawContent(platform::graphics::IPainter* painter) override; + + // See remarks of this class. + Size OnMeasureContent(const MeasureRequirement& requirement, + const MeasureSize& preferred_size) override; + void OnLayoutContent(const Rect& content_rect) override; + + void OnAfterLayout() override; + + private: + std::shared_ptr brush_; + std::shared_ptr font_; + std::unique_ptr text_layout_; + + std::optional selection_range_ = std::nullopt; + std::shared_ptr selection_brush_; + + bool draw_caret_ = false; + gsl::index caret_position_ = 0; + std::shared_ptr caret_brush_; + float caret_width_ = default_caret_width; + + bool is_measure_including_trailing_space_ = false; +}; +} // namespace cru::ui::render -- cgit v1.2.3