Improve text_input::cursor API

This commit is contained in:
Héctor Ramón Jiménez 2020-03-24 20:23:31 +01:00
parent 763f64b653
commit 6b89dd7db9
4 changed files with 170 additions and 141 deletions

View file

@ -1,8 +1,9 @@
use crate::{text_input::StyleSheet, Primitive, Renderer};
use iced_native::{
text_input, Background, Color, Font, HorizontalAlignment, MouseCursor,
Point, Rectangle, Size, Vector, VerticalAlignment,
text_input::{self, cursor},
Background, Color, Font, HorizontalAlignment, MouseCursor, Point,
Rectangle, Size, Vector, VerticalAlignment,
};
use std::f32;
@ -41,12 +42,19 @@ impl text_input::Renderer for Renderer {
font: Font,
) -> f32 {
if state.is_focused() {
let cursor = state.cursor();
let focus_position = match cursor.state(value) {
cursor::State::Index(i) => i,
cursor::State::Selection { end, .. } => end,
};
let (_, offset) = measure_cursor_and_scroll_offset(
self,
text_bounds,
value,
size,
state.cursor().cursor_position(value),
focus_position,
font,
);
@ -111,70 +119,91 @@ impl text_input::Renderer for Renderer {
};
let (contents_primitive, offset) = if state.is_focused() {
let (text_value_width, offset) = measure_cursor_and_scroll_offset(
self,
text_bounds,
value,
size,
state.cursor().cursor_position(value),
font,
);
let cursor = state.cursor();
let selection = match state.cursor().selection_position() {
None => Primitive::None,
Some(_) => {
let (cursor_left_offset, _) =
let (cursor_primitive, offset) = match cursor.state(value) {
cursor::State::Index(position) => {
let (text_value_width, offset) =
measure_cursor_and_scroll_offset(
self,
text_bounds,
value,
size,
state.cursor().left(),
position,
font,
);
let (cursor_right_offset, _) =
measure_cursor_and_scroll_offset(
self,
text_bounds,
value,
size,
state.cursor().right(),
font,
);
let width = cursor_right_offset - cursor_left_offset;
Primitive::Quad {
bounds: Rectangle {
x: text_bounds.x + cursor_left_offset,
y: text_bounds.y,
width,
height: text_bounds.height,
(
Primitive::Quad {
bounds: Rectangle {
x: text_bounds.x + text_value_width,
y: text_bounds.y,
width: 1.0,
height: text_bounds.height,
},
background: Background::Color(
style_sheet.value_color(),
),
border_radius: 0,
border_width: 0,
border_color: Color::TRANSPARENT,
},
background: Background::Color(
style_sheet.selection_color(),
),
border_radius: 0,
border_width: 0,
border_color: Color::TRANSPARENT,
}
offset,
)
}
};
cursor::State::Selection { start, end } => {
let left = start.min(end);
let right = end.max(start);
let cursor = Primitive::Quad {
bounds: Rectangle {
x: text_bounds.x + text_value_width,
y: text_bounds.y,
width: 1.0,
height: text_bounds.height,
},
background: Background::Color(style_sheet.value_color()),
border_radius: 0,
border_width: 0,
border_color: Color::TRANSPARENT,
let (left_position, left_offset) =
measure_cursor_and_scroll_offset(
self,
text_bounds,
value,
size,
left,
font,
);
let (right_position, right_offset) =
measure_cursor_and_scroll_offset(
self,
text_bounds,
value,
size,
right,
font,
);
let width = right_position - left_position;
(
Primitive::Quad {
bounds: Rectangle {
x: text_bounds.x + left_position,
y: text_bounds.y,
width,
height: text_bounds.height,
},
background: Background::Color(
style_sheet.selection_color(),
),
border_radius: 0,
border_width: 0,
border_color: Color::TRANSPARENT,
},
if end == right {
right_offset
} else {
left_offset
},
)
}
};
(
Primitive::Group {
primitives: vec![selection, text_value, cursor],
primitives: vec![cursor_primitive, text_value],
},
Vector::new(offset as u32, 0),
)