aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-07-08 17:14:42 +0800
committercrupest <crupest@outlook.com>2020-07-08 17:14:42 +0800
commit83736f1208a613d2457147c2df3f493228bab3cb (patch)
tree5bd44c7d1676c040f4cd61b9862a418d5b8ba29c
parent3a49e87637e2493f3e5854bbcb8ab804bae5a46e (diff)
downloadcru-83736f1208a613d2457147c2df3f493228bab3cb.tar.gz
cru-83736f1208a613d2457147c2df3f493228bab3cb.tar.bz2
cru-83736f1208a613d2457147c2df3f493228bab3cb.zip
...
-rw-r--r--include/cru/ui/render/ScrollRenderObject.hpp2
-rw-r--r--include/cru/ui/render/TextRenderObject.hpp5
-rw-r--r--src/ui/controls/TextControlService.hpp4
-rw-r--r--src/ui/render/ScrollRenderObject.cpp4
-rw-r--r--src/ui/render/TextRenderObject.cpp54
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());