Implement Renderer::find_cursor_position
This commit is contained in:
parent
b30ddf90d2
commit
30f02345a8
@ -114,10 +114,10 @@ impl text_input::Renderer for Null {
|
||||
fn offset(
|
||||
&self,
|
||||
_text_bounds: Rectangle,
|
||||
_font: Font,
|
||||
_size: u16,
|
||||
_value: &text_input::Value,
|
||||
_state: &text_input::State,
|
||||
_font: Font,
|
||||
) -> f32 {
|
||||
0.0
|
||||
}
|
||||
@ -127,8 +127,8 @@ impl text_input::Renderer for Null {
|
||||
_bounds: Rectangle,
|
||||
_text_bounds: Rectangle,
|
||||
_cursor_position: Point,
|
||||
_size: u16,
|
||||
_font: Font,
|
||||
_size: u16,
|
||||
_placeholder: &str,
|
||||
_value: &text_input::Value,
|
||||
_state: &text_input::State,
|
||||
|
@ -236,29 +236,16 @@ where
|
||||
self.value.clone()
|
||||
};
|
||||
|
||||
let size = self
|
||||
.size
|
||||
.unwrap_or(renderer.default_size());
|
||||
|
||||
let offset = renderer.offset(
|
||||
let position = renderer.find_cursor_position(
|
||||
text_layout.bounds(),
|
||||
size,
|
||||
self.font,
|
||||
self.size,
|
||||
&value,
|
||||
&self.state,
|
||||
self.font,
|
||||
target,
|
||||
);
|
||||
|
||||
self.state.cursor.move_to(
|
||||
find_cursor_position(
|
||||
renderer,
|
||||
target + offset,
|
||||
&value,
|
||||
size,
|
||||
0,
|
||||
self.value.len(),
|
||||
self.font,
|
||||
),
|
||||
);
|
||||
self.state.cursor.move_to(position);
|
||||
} else {
|
||||
self.state.cursor.move_to(0);
|
||||
}
|
||||
@ -267,11 +254,18 @@ where
|
||||
if self.is_secure {
|
||||
self.state.cursor.select_all(&self.value);
|
||||
} else {
|
||||
let end = self.state.cursor.end(&self.value);
|
||||
let position = renderer.find_cursor_position(
|
||||
text_layout.bounds(),
|
||||
self.font,
|
||||
self.size,
|
||||
&self.value,
|
||||
&self.state,
|
||||
target,
|
||||
);
|
||||
|
||||
self.state.cursor.select_range(
|
||||
self.value.previous_start_of_word(end),
|
||||
self.value.next_end_of_word(end),
|
||||
self.value.previous_start_of_word(position),
|
||||
self.value.next_end_of_word(position),
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -304,24 +298,13 @@ where
|
||||
self.value.clone()
|
||||
};
|
||||
|
||||
let size = self.size.unwrap_or(renderer.default_size());
|
||||
|
||||
let offset = renderer.offset(
|
||||
let position = renderer.find_cursor_position(
|
||||
text_layout.bounds(),
|
||||
size,
|
||||
self.font,
|
||||
self.size,
|
||||
&value,
|
||||
&self.state,
|
||||
self.font,
|
||||
);
|
||||
|
||||
let position = find_cursor_position(
|
||||
renderer,
|
||||
target + offset,
|
||||
&value,
|
||||
size,
|
||||
0,
|
||||
self.value.len(),
|
||||
self.font,
|
||||
target,
|
||||
);
|
||||
|
||||
self.state.cursor.select_range(
|
||||
@ -493,8 +476,8 @@ where
|
||||
bounds,
|
||||
text_bounds,
|
||||
cursor_position,
|
||||
self.size.unwrap_or(renderer.default_size()),
|
||||
self.font,
|
||||
self.size.unwrap_or(renderer.default_size()),
|
||||
&self.placeholder,
|
||||
&self.value.secure(),
|
||||
&self.state,
|
||||
@ -505,8 +488,8 @@ where
|
||||
bounds,
|
||||
text_bounds,
|
||||
cursor_position,
|
||||
self.size.unwrap_or(renderer.default_size()),
|
||||
self.font,
|
||||
self.size.unwrap_or(renderer.default_size()),
|
||||
&self.placeholder,
|
||||
&self.value,
|
||||
&self.state,
|
||||
@ -559,10 +542,10 @@ pub trait Renderer: crate::Renderer + Sized {
|
||||
fn offset(
|
||||
&self,
|
||||
text_bounds: Rectangle,
|
||||
font: Font,
|
||||
size: u16,
|
||||
value: &Value,
|
||||
state: &State,
|
||||
font: Font,
|
||||
) -> f32;
|
||||
|
||||
/// Draws a [`TextInput`].
|
||||
@ -583,13 +566,41 @@ pub trait Renderer: crate::Renderer + Sized {
|
||||
bounds: Rectangle,
|
||||
text_bounds: Rectangle,
|
||||
cursor_position: Point,
|
||||
size: u16,
|
||||
font: Font,
|
||||
size: u16,
|
||||
placeholder: &str,
|
||||
value: &Value,
|
||||
state: &State,
|
||||
style: &Self::Style,
|
||||
) -> Self::Output;
|
||||
|
||||
/// Computes the position of the text cursor at the given X coordinate of
|
||||
/// a [`TextInput`].
|
||||
///
|
||||
/// [`TextInput`]: struct.TextInput.html
|
||||
fn find_cursor_position(
|
||||
&self,
|
||||
text_bounds: Rectangle,
|
||||
font: Font,
|
||||
size: Option<u16>,
|
||||
value: &Value,
|
||||
state: &State,
|
||||
x: f32,
|
||||
) -> usize {
|
||||
let size = size.unwrap_or(self.default_size());
|
||||
|
||||
let offset = self.offset(text_bounds, font, size, &value, &state);
|
||||
|
||||
find_cursor_position(
|
||||
self,
|
||||
&value,
|
||||
font,
|
||||
size,
|
||||
x + offset,
|
||||
0,
|
||||
value.len(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Message, Renderer> From<TextInput<'a, Message, Renderer>>
|
||||
@ -658,12 +669,12 @@ impl State {
|
||||
// TODO: Reduce allocations
|
||||
fn find_cursor_position<Renderer: self::Renderer>(
|
||||
renderer: &Renderer,
|
||||
target: f32,
|
||||
value: &Value,
|
||||
font: Font,
|
||||
size: u16,
|
||||
target: f32,
|
||||
start: usize,
|
||||
end: usize,
|
||||
font: Font,
|
||||
) -> usize {
|
||||
if start >= end {
|
||||
if start == 0 {
|
||||
@ -691,22 +702,22 @@ fn find_cursor_position<Renderer: self::Renderer>(
|
||||
if width > target {
|
||||
find_cursor_position(
|
||||
renderer,
|
||||
target,
|
||||
value,
|
||||
font,
|
||||
size,
|
||||
target,
|
||||
start,
|
||||
start + index,
|
||||
font,
|
||||
)
|
||||
} else {
|
||||
find_cursor_position(
|
||||
renderer,
|
||||
target,
|
||||
value,
|
||||
font,
|
||||
size,
|
||||
target,
|
||||
start + index + 1,
|
||||
end,
|
||||
font,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -36,10 +36,10 @@ impl text_input::Renderer for Renderer {
|
||||
fn offset(
|
||||
&self,
|
||||
text_bounds: Rectangle,
|
||||
font: Font,
|
||||
size: u16,
|
||||
value: &text_input::Value,
|
||||
state: &text_input::State,
|
||||
font: Font,
|
||||
) -> f32 {
|
||||
if state.is_focused() {
|
||||
let cursor = state.cursor();
|
||||
@ -69,8 +69,8 @@ impl text_input::Renderer for Renderer {
|
||||
bounds: Rectangle,
|
||||
text_bounds: Rectangle,
|
||||
cursor_position: Point,
|
||||
size: u16,
|
||||
font: Font,
|
||||
size: u16,
|
||||
placeholder: &str,
|
||||
value: &text_input::Value,
|
||||
state: &text_input::State,
|
||||
|
Loading…
Reference in New Issue
Block a user