aboutsummaryrefslogtreecommitdiff
path: root/include/cru/ui/render/TextRenderObject.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/cru/ui/render/TextRenderObject.h')
-rw-r--r--include/cru/ui/render/TextRenderObject.h121
1 files changed, 121 insertions, 0 deletions
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 <string>
+
+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<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;
+ TextRenderObject& operator=(TextRenderObject&& other) = delete;
+ ~TextRenderObject() override;
+
+ String GetText() const;
+ void SetText(String new_text);
+
+ void SetBrush(std::shared_ptr<platform::graphics::IBrush> new_brush);
+
+ std::shared_ptr<platform::graphics::IFont> GetFont() const;
+ void SetFont(std::shared_ptr<platform::graphics::IFont> font);
+
+ bool IsEditMode();
+ void SetEditMode(bool enable);
+
+ Index GetLineCount();
+ Index GetLineIndexFromCharIndex(Index char_index);
+ float GetLineHeight(Index line_index);
+ std::vector<Rect> TextRangeRect(const TextRange& text_range);
+ Rect TextSinglePoint(gsl::index position, bool trailing);
+ 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::graphics::IBrush> GetSelectionBrush() const {
+ return selection_brush_;
+ }
+ void SetSelectionBrush(std::shared_ptr<platform::graphics::IBrush> 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<platform::graphics::IBrush> GetCaretBrush() const {
+ return caret_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;
+
+ 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<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::graphics::IBrush> selection_brush_;
+
+ bool draw_caret_ = false;
+ gsl::index caret_position_ = 0;
+ 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