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