diff options
-rw-r--r-- | core/src/text.rs | 6 | ||||
-rw-r--r-- | glow/src/backend.rs | 2 | ||||
-rw-r--r-- | glow/src/text.rs | 18 | ||||
-rw-r--r-- | graphics/src/backend.rs | 2 | ||||
-rw-r--r-- | graphics/src/widget/text.rs | 2 | ||||
-rw-r--r-- | native/src/renderer/null.rs | 6 | ||||
-rw-r--r-- | native/src/widget/text.rs | 2 | ||||
-rw-r--r-- | native/src/widget/text_input.rs | 53 | ||||
-rw-r--r-- | wgpu/src/backend.rs | 2 | ||||
-rw-r--r-- | wgpu/src/text.rs | 18 |
10 files changed, 59 insertions, 52 deletions
diff --git a/core/src/text.rs b/core/src/text.rs index ded22eef..e5d0092e 100644 --- a/core/src/text.rs +++ b/core/src/text.rs @@ -14,14 +14,14 @@ pub enum Hit { impl Hit { /// Computes the cursor position corresponding to this [`HitTestResult`] . - pub fn cursor(&self) -> usize { + pub fn cursor(self) -> usize { match self { - Self::CharOffset(i) => *i, + Self::CharOffset(i) => i, Self::NearestCharOffset(i, delta) => { if delta.x > f32::EPSILON { i + 1 } else { - *i + i } } } diff --git a/glow/src/backend.rs b/glow/src/backend.rs index 37c0ac9d..526965cb 100644 --- a/glow/src/backend.rs +++ b/glow/src/backend.rs @@ -221,7 +221,7 @@ impl backend::Text for Backend { bounds: Size, point: iced_native::Point, nearest_only: bool, - ) -> text::Hit { + ) -> Option<text::Hit> { self.text_pipeline.hit_test( contents, size, diff --git a/glow/src/text.rs b/glow/src/text.rs index d6915d92..4ebd7087 100644 --- a/glow/src/text.rs +++ b/glow/src/text.rs @@ -121,7 +121,7 @@ impl Pipeline { bounds: iced_native::Size, point: iced_native::Point, nearest_only: bool, - ) -> Hit { + ) -> Option<Hit> { use glow_glyph::GlyphCruncher; let glow_glyph::FontId(font_id) = self.find_font(font); @@ -182,23 +182,25 @@ impl Pipeline { if !nearest_only { for (idx, bounds) in bounds.clone() { if bounds.contains(point) { - return Hit::CharOffset(char_index(idx)); + return Some(Hit::CharOffset(char_index(idx))); } } } let (idx, nearest) = bounds.fold( - (0usize, iced_native::Point::ORIGIN), - |acc: (usize, iced_native::Point), (idx, bounds)| { - if bounds.center().distance(point) < acc.1.distance(point) { - (idx, bounds.center()) + (None, iced_native::Point::ORIGIN), + |best, (idx, bounds)| { + let center = bounds.center(); + + if center.distance(point) < best.1.distance(point) { + (Some(idx), center) } else { - acc + best } }, ); - Hit::NearestCharOffset(char_index(idx), (point - nearest).into()) + idx.map(|idx| Hit::NearestCharOffset(char_index(idx), point - nearest)) } pub fn trim_measurement_cache(&mut self) { diff --git a/graphics/src/backend.rs b/graphics/src/backend.rs index 656949c5..7e0af2cc 100644 --- a/graphics/src/backend.rs +++ b/graphics/src/backend.rs @@ -60,7 +60,7 @@ pub trait Text { bounds: Size, point: Point, nearest_only: bool, - ) -> text::Hit; + ) -> Option<text::Hit>; } /// A graphics backend that supports image rendering. diff --git a/graphics/src/widget/text.rs b/graphics/src/widget/text.rs index c235f254..645c8414 100644 --- a/graphics/src/widget/text.rs +++ b/graphics/src/widget/text.rs @@ -43,7 +43,7 @@ where bounds: Size, point: Point, nearest_only: bool, - ) -> text::Hit { + ) -> Option<text::Hit> { self.backend().hit_test( content, size, diff --git a/native/src/renderer/null.rs b/native/src/renderer/null.rs index b1a26c41..2c47ddf2 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, - Vector, VerticalAlignment, + VerticalAlignment, }; /// A renderer that does nothing. @@ -75,8 +75,8 @@ impl text::Renderer for Null { _bounds: Size, _point: Point, _nearest_only: bool, - ) -> text::Hit { - text::Hit::NearestCharOffset(0, Vector::new(0., 0.)) + ) -> Option<text::Hit> { + None } fn draw( diff --git a/native/src/widget/text.rs b/native/src/widget/text.rs index adf6a74f..d8bc0a00 100644 --- a/native/src/widget/text.rs +++ b/native/src/widget/text.rs @@ -196,7 +196,7 @@ pub trait Renderer: crate::Renderer { bounds: Size, point: Point, nearest_only: bool, - ) -> Hit; + ) -> Option<Hit>; /// Draws a [`Text`] fragment. /// diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index f1a7a1a0..84d171be 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -268,41 +268,42 @@ where match click.kind() { click::Kind::Single => { - if target > 0.0 { + let position = if target > 0.0 { let value = if self.is_secure { self.value.secure() } else { self.value.clone() }; - let position = renderer.find_cursor_position( + renderer.find_cursor_position( text_layout.bounds(), self.font, self.size, &value, &self.state, target, - ); - - self.state.cursor.move_to(position); + ) } else { - self.state.cursor.move_to(0); - } + None + }; + self.state.cursor.move_to(position.unwrap_or(0)); self.state.is_dragging = true; } click::Kind::Double => { if self.is_secure { self.state.cursor.select_all(&self.value); } else { - let position = renderer.find_cursor_position( - text_layout.bounds(), - self.font, - self.size, - &self.value, - &self.state, - target, - ); + let position = renderer + .find_cursor_position( + text_layout.bounds(), + self.font, + self.size, + &self.value, + &self.state, + target, + ) + .unwrap_or(0); self.state.cursor.select_range( self.value.previous_start_of_word(position), @@ -341,14 +342,16 @@ where self.value.clone() }; - let position = renderer.find_cursor_position( - text_layout.bounds(), - self.font, - self.size, - &value, - &self.state, - target, - ); + let position = renderer + .find_cursor_position( + text_layout.bounds(), + self.font, + self.size, + &value, + &self.state, + target, + ) + .unwrap_or(0); self.state.cursor.select_range( self.state.cursor.start(&value), @@ -702,7 +705,7 @@ pub trait Renderer: text::Renderer + Sized { value: &Value, state: &State, x: f32, - ) -> usize { + ) -> Option<usize> { let size = size.unwrap_or(self.default_size()); let offset = self.offset(text_bounds, font, size, &value, &state); @@ -715,7 +718,7 @@ pub trait Renderer: text::Renderer + Sized { Point::new(x + offset, text_bounds.height / 2.0), true, ) - .cursor() + .map(text::Hit::cursor) } } diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index b31bf92c..51429e84 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -284,7 +284,7 @@ impl backend::Text for Backend { bounds: Size, point: iced_native::Point, nearest_only: bool, - ) -> text::Hit { + ) -> Option<text::Hit> { self.text_pipeline.hit_test( contents, size, diff --git a/wgpu/src/text.rs b/wgpu/src/text.rs index ee49ee4b..34fd5b58 100644 --- a/wgpu/src/text.rs +++ b/wgpu/src/text.rs @@ -129,7 +129,7 @@ impl Pipeline { bounds: iced_native::Size, point: iced_native::Point, nearest_only: bool, - ) -> Hit { + ) -> Option<Hit> { use wgpu_glyph::GlyphCruncher; let wgpu_glyph::FontId(font_id) = self.find_font(font); @@ -190,23 +190,25 @@ impl Pipeline { if !nearest_only { for (idx, bounds) in bounds.clone() { if bounds.contains(point) { - return Hit::CharOffset(char_index(idx)); + return Some(Hit::CharOffset(char_index(idx))); } } } let (idx, nearest) = bounds.fold( - (0usize, iced_native::Point::ORIGIN), - |acc: (usize, iced_native::Point), (idx, bounds)| { - if bounds.center().distance(point) < acc.1.distance(point) { - (idx, bounds.center()) + (None, iced_native::Point::ORIGIN), + |best, (idx, bounds)| { + let center = bounds.center(); + + if center.distance(point) < best.1.distance(point) { + (Some(idx), center) } else { - acc + best } }, ); - Hit::NearestCharOffset(char_index(idx), (point - nearest).into()) + idx.map(|idx| Hit::NearestCharOffset(char_index(idx), point - nearest)) } pub fn trim_measurement_cache(&mut self) { |