diff options
author | crupest <crupest@outlook.com> | 2020-07-08 17:14:42 +0800 |
---|---|---|
committer | crupest <crupest@outlook.com> | 2020-07-08 17:14:42 +0800 |
commit | 83736f1208a613d2457147c2df3f493228bab3cb (patch) | |
tree | 5bd44c7d1676c040f4cd61b9862a418d5b8ba29c | |
parent | 3a49e87637e2493f3e5854bbcb8ab804bae5a46e (diff) | |
download | cru-83736f1208a613d2457147c2df3f493228bab3cb.tar.gz cru-83736f1208a613d2457147c2df3f493228bab3cb.tar.bz2 cru-83736f1208a613d2457147c2df3f493228bab3cb.zip |
...
-rw-r--r-- | include/cru/ui/render/ScrollRenderObject.hpp | 2 | ||||
-rw-r--r-- | include/cru/ui/render/TextRenderObject.hpp | 5 | ||||
-rw-r--r-- | src/ui/controls/TextControlService.hpp | 4 | ||||
-rw-r--r-- | src/ui/render/ScrollRenderObject.cpp | 4 | ||||
-rw-r--r-- | src/ui/render/TextRenderObject.cpp | 54 |
5 files changed, 47 insertions, 22 deletions
diff --git a/include/cru/ui/render/ScrollRenderObject.hpp b/include/cru/ui/render/ScrollRenderObject.hpp index 20b7278c..45fa3993 100644 --- a/include/cru/ui/render/ScrollRenderObject.hpp +++ b/include/cru/ui/render/ScrollRenderObject.hpp @@ -29,7 +29,7 @@ class ScrollRenderObject : public RenderObject { Point GetRawScrollOffset() const { return scroll_offset_; } // Rect lefttop relative to content rect. - void ScrollToContain(const Rect& rect); + void ScrollToContain(const Rect& rect, const Thickness& margin = Thickness{}); protected: void OnDrawCore(platform::graph::IPainter* painter) override; diff --git a/include/cru/ui/render/TextRenderObject.hpp b/include/cru/ui/render/TextRenderObject.hpp index 32d96797..0b276415 100644 --- a/include/cru/ui/render/TextRenderObject.hpp +++ b/include/cru/ui/render/TextRenderObject.hpp @@ -66,6 +66,11 @@ class TextRenderObject : public RenderObject { 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::graph::IBrush> GetCaretBrush() const { return caret_brush_; } diff --git a/src/ui/controls/TextControlService.hpp b/src/ui/controls/TextControlService.hpp index 93a48c44..1108a3b2 100644 --- a/src/ui/controls/TextControlService.hpp +++ b/src/ui/controls/TextControlService.hpp @@ -7,6 +7,7 @@ #include "cru/ui/Control.hpp" #include "cru/ui/UiEvent.hpp" #include "cru/ui/render/CanvasRenderObject.hpp" +#include "cru/ui/render/ScrollRenderObject.hpp" #include "cru/ui/render/TextRenderObject.hpp" namespace cru::ui::controls { @@ -140,7 +141,8 @@ class TextControlService : public Object { log::TagDebug(log_tag, u"Text selection updated, range: {}, {}.", old_start, new_end); if (const auto scroll_render_object = this->GetScrollRenderObject()) { - // TODO: Implement this. + const auto caret_rect = text_render_object->GetCaretRect(); + scroll_render_object->ScrollToContain(caret_rect, Thickness{5.f}); } } diff --git a/src/ui/render/ScrollRenderObject.cpp b/src/ui/render/ScrollRenderObject.cpp index d3996b98..533a269a 100644 --- a/src/ui/render/ScrollRenderObject.cpp +++ b/src/ui/render/ScrollRenderObject.cpp @@ -67,9 +67,11 @@ void ScrollRenderObject::SetScrollOffset(const Point& offset) { InvalidateLayout(); } -void ScrollToContain(const Rect& rect) { +void ScrollRenderObject::ScrollToContain(const Rect& rect, + const Thickness& margin) { // TODO: Implement this. CRU_UNUSED(rect); + CRU_UNUSED(margin); throw std::runtime_error("Not implemented."); } diff --git a/src/ui/render/TextRenderObject.cpp b/src/ui/render/TextRenderObject.cpp index 8a4a4ba1..cd248cea 100644 --- a/src/ui/render/TextRenderObject.cpp +++ b/src/ui/render/TextRenderObject.cpp @@ -118,6 +118,37 @@ void TextRenderObject::SetCaretWidth(const float width) { } } +Rect TextRenderObject::GetCaretRectInContent() { + auto caret_pos = this->caret_position_; + gsl::index text_size = this->GetText().size(); + if (caret_pos < 0) { + caret_pos = 0; + } else if (caret_pos > text_size) { + caret_pos = text_size; + } + + const auto caret_top_center = + this->text_layout_->TextSinglePoint(caret_pos, false); + + const auto font_height = this->font_->GetFontSize(); + const auto caret_width = this->caret_width_; + + auto rect = Rect{caret_top_center.x - caret_width / 2.0f, caret_top_center.y, + caret_width, font_height}; + + return rect; +} + +Rect TextRenderObject::GetCaretRect() { + auto rect = GetCaretRectInContent(); + const auto content_rect = GetContentRect(); + + rect.left += content_rect.left; + rect.top += content_rect.top; + + return rect; +} + RenderObject* TextRenderObject::HitTest(const Point& point) { const auto padding_rect = GetPaddingRect(); return padding_rect.IsPointInside(point) ? this : nullptr; @@ -134,23 +165,7 @@ void TextRenderObject::OnDrawContent(platform::graph::IPainter* painter) { painter->DrawText(Point{}, text_layout_.get(), brush_.get()); if (this->draw_caret_ && this->caret_width_ != 0.0f) { - auto caret_pos = this->caret_position_; - gsl::index text_size = this->GetText().size(); - if (caret_pos < 0) { - caret_pos = 0; - } else if (caret_pos > text_size) { - caret_pos = text_size; - } - - const auto caret_top_center = - this->text_layout_->TextSinglePoint(caret_pos, false); - - const auto font_height = this->font_->GetFontSize(); - const auto caret_width = this->caret_width_; - - painter->FillRectangle(Rect{caret_top_center.x - caret_width / 2.0f, - caret_top_center.y, caret_width, font_height}, - this->caret_brush_.get()); + painter->FillRectangle(GetCaretRectInContent(), this->caret_brush_.get()); } } @@ -170,8 +185,9 @@ Size TextRenderObject::OnMeasureContent(const MeasureRequirement& requirement, if (requirement.max.width.IsSpecified() && text_size.width > requirement.max.width.GetLengthOrUndefined()) { - log::TagWarn(log_tag, - u"(Measure) Text actual width exceeds the required max width."); + log::TagWarn( + log_tag, + u"(Measure) Text actual width exceeds the required max width."); result.width = requirement.max.width.GetLengthOrUndefined(); } else { result.width = std::max(result.width, preferred_size.width.GetLengthOr0()); |