summaryrefslogtreecommitdiffstats
path: root/native
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector0193@gmail.com>2021-08-26 14:53:15 +0700
committerLibravatar GitHub <noreply@github.com>2021-08-26 14:53:15 +0700
commit6821114cae2e41fd2bc69d6fcaee1e8574ac061d (patch)
tree5741859eba63251190eb0a901a72ef4e185349e7 /native
parent2d65621a3b680457e689b93c800e74f726ffc175 (diff)
parent7614127d3641cf3224798c2f0ff07b6ae57d9a53 (diff)
downloadiced-6821114cae2e41fd2bc69d6fcaee1e8574ac061d.tar.gz
iced-6821114cae2e41fd2bc69d6fcaee1e8574ac061d.tar.bz2
iced-6821114cae2e41fd2bc69d6fcaee1e8574ac061d.zip
Merge pull request #670 from twitchyliquid64/text_backend
Refactor textual hit testing into a `renderer::Backend` method
Diffstat (limited to '')
-rw-r--r--native/src/renderer/null.rs14
-rw-r--r--native/src/widget/text.rs19
-rw-r--r--native/src/widget/text_input.rs70
3 files changed, 39 insertions, 64 deletions
diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs
index bb57c163..b1a26c41 100644
--- a/native/src/renderer/null.rs
+++ b/native/src/renderer/null.rs
@@ -2,7 +2,7 @@ use crate::{
button, checkbox, column, container, pane_grid, progress_bar, radio, row,
scrollable, slider, text, text_input, toggler, Color, Element, Font,
HorizontalAlignment, Layout, Padding, Point, Rectangle, Renderer, Size,
- VerticalAlignment,
+ Vector, VerticalAlignment,
};
/// A renderer that does nothing.
@@ -67,6 +67,18 @@ impl text::Renderer for Null {
(0.0, 20.0)
}
+ fn hit_test(
+ &self,
+ _contents: &str,
+ _size: f32,
+ _font: Self::Font,
+ _bounds: Size,
+ _point: Point,
+ _nearest_only: bool,
+ ) -> text::Hit {
+ text::Hit::NearestCharOffset(0, Vector::new(0., 0.))
+ }
+
fn draw(
&mut self,
_defaults: &Self::Defaults,
diff --git a/native/src/widget/text.rs b/native/src/widget/text.rs
index 6cc18e6c..adf6a74f 100644
--- a/native/src/widget/text.rs
+++ b/native/src/widget/text.rs
@@ -4,6 +4,8 @@ use crate::{
Rectangle, Size, VerticalAlignment, Widget,
};
+pub use iced_core::text::Hit;
+
use std::hash::Hash;
/// A paragraph of text.
@@ -179,6 +181,23 @@ pub trait Renderer: crate::Renderer {
bounds: Size,
) -> (f32, f32);
+ /// Tests whether the provided point is within the boundaries of [`Text`]
+ /// laid out with the given parameters, returning information about
+ /// the nearest character.
+ ///
+ /// If `nearest_only` is true, the hit test does not consider whether the
+ /// the point is interior to any glyph bounds, returning only the character
+ /// with the nearest centeroid.
+ fn hit_test(
+ &self,
+ contents: &str,
+ size: f32,
+ font: Self::Font,
+ bounds: Size,
+ point: Point,
+ nearest_only: bool,
+ ) -> Hit;
+
/// Draws a [`Text`] fragment.
///
/// It receives:
diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs
index bb64d5b7..f1a7a1a0 100644
--- a/native/src/widget/text_input.rs
+++ b/native/src/widget/text_input.rs
@@ -707,15 +707,15 @@ pub trait Renderer: text::Renderer + Sized {
let offset = self.offset(text_bounds, font, size, &value, &state);
- find_cursor_position(
- self,
- &value,
+ self.hit_test(
+ &value.to_string(),
+ size.into(),
font,
- size,
- x + offset,
- 0,
- value.len(),
+ Size::INFINITY,
+ Point::new(x + offset, text_bounds.height / 2.0),
+ true,
)
+ .cursor()
}
}
@@ -803,62 +803,6 @@ impl State {
}
}
-// TODO: Reduce allocations
-fn find_cursor_position<Renderer: self::Renderer>(
- renderer: &Renderer,
- value: &Value,
- font: Renderer::Font,
- size: u16,
- target: f32,
- start: usize,
- end: usize,
-) -> usize {
- if start >= end {
- if start == 0 {
- return 0;
- }
-
- let prev = value.until(start - 1);
- let next = value.until(start);
-
- let prev_width = renderer.measure_value(&prev.to_string(), size, font);
- let next_width = renderer.measure_value(&next.to_string(), size, font);
-
- if next_width - target > target - prev_width {
- return start - 1;
- } else {
- return start;
- }
- }
-
- let index = (end - start) / 2;
- let subvalue = value.until(start + index);
-
- let width = renderer.measure_value(&subvalue.to_string(), size, font);
-
- if width > target {
- find_cursor_position(
- renderer,
- value,
- font,
- size,
- target,
- start,
- start + index,
- )
- } else {
- find_cursor_position(
- renderer,
- value,
- font,
- size,
- target,
- start + index + 1,
- end,
- )
- }
-}
-
mod platform {
use crate::keyboard;