Improve text_input::cursor
API
This commit is contained in:
parent
763f64b653
commit
6b89dd7db9
@ -34,7 +34,7 @@
|
|||||||
//! [`window::Renderer`]: window/trait.Renderer.html
|
//! [`window::Renderer`]: window/trait.Renderer.html
|
||||||
//! [`UserInterface`]: struct.UserInterface.html
|
//! [`UserInterface`]: struct.UserInterface.html
|
||||||
//! [renderer]: renderer/index.html
|
//! [renderer]: renderer/index.html
|
||||||
#![deny(missing_docs)]
|
//#![deny(missing_docs)]
|
||||||
#![deny(missing_debug_implementations)]
|
#![deny(missing_debug_implementations)]
|
||||||
#![deny(unused_results)]
|
#![deny(unused_results)]
|
||||||
#![forbid(unsafe_code)]
|
#![forbid(unsafe_code)]
|
||||||
|
@ -4,17 +4,18 @@
|
|||||||
//!
|
//!
|
||||||
//! [`TextInput`]: struct.TextInput.html
|
//! [`TextInput`]: struct.TextInput.html
|
||||||
//! [`State`]: struct.State.html
|
//! [`State`]: struct.State.html
|
||||||
mod cursor;
|
pub mod cursor;
|
||||||
|
|
||||||
|
pub use cursor::Cursor;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
input::{
|
input::{
|
||||||
keyboard,
|
keyboard,
|
||||||
mouse::{self, click},
|
mouse::{self, click},
|
||||||
ButtonState,
|
ButtonState,
|
||||||
},
|
},
|
||||||
layout,
|
layout, Clipboard, Element, Event, Font, Hasher, Layout, Length, Point,
|
||||||
widget::text_input::cursor::Cursor,
|
Rectangle, Size, Widget,
|
||||||
Clipboard, Element, Event, Font, Hasher, Layout, Length, Point, Rectangle,
|
|
||||||
Size, Widget,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::u32;
|
use std::u32;
|
||||||
@ -261,7 +262,8 @@ 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();
|
let end = self.state.cursor.end(&self.value);
|
||||||
|
|
||||||
self.state.cursor.select_range(
|
self.state.cursor.select_range(
|
||||||
self.value.previous_start_of_word(end),
|
self.value.previous_start_of_word(end),
|
||||||
self.value.next_end_of_word(end),
|
self.value.next_end_of_word(end),
|
||||||
@ -307,7 +309,7 @@ where
|
|||||||
self.font,
|
self.font,
|
||||||
);
|
);
|
||||||
|
|
||||||
let pos = find_cursor_position(
|
let position = find_cursor_position(
|
||||||
renderer,
|
renderer,
|
||||||
target + offset,
|
target + offset,
|
||||||
&value,
|
&value,
|
||||||
@ -317,9 +319,10 @@ where
|
|||||||
self.font,
|
self.font,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.state
|
self.state.cursor.select_range(
|
||||||
.cursor
|
self.state.cursor.start(&value),
|
||||||
.select_range(self.state.cursor.start(), pos);
|
position,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -328,15 +331,15 @@ where
|
|||||||
&& self.state.is_pasting.is_none()
|
&& self.state.is_pasting.is_none()
|
||||||
&& !c.is_control() =>
|
&& !c.is_control() =>
|
||||||
{
|
{
|
||||||
match self.state.cursor.selection_position() {
|
match self.state.cursor.selection() {
|
||||||
Some((left, right)) => {
|
Some((left, right)) => {
|
||||||
self.value.remove_many(left, right);
|
self.value.remove_many(left, right);
|
||||||
self.state.cursor.move_left();
|
self.state.cursor.move_left(&self.value);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
self.value
|
|
||||||
.insert(self.state.cursor.end().min(self.value.len()), c);
|
self.value.insert(self.state.cursor.end(&self.value), c);
|
||||||
self.state.cursor.move_right(&self.value);
|
self.state.cursor.move_right(&self.value);
|
||||||
|
|
||||||
let message = (self.on_change)(self.value.to_string());
|
let message = (self.on_change)(self.value.to_string());
|
||||||
@ -353,19 +356,18 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
keyboard::KeyCode::Backspace => {
|
keyboard::KeyCode::Backspace => {
|
||||||
match self.state.cursor.selection_position() {
|
match self.state.cursor.selection() {
|
||||||
Some((start, end)) => {
|
Some((start, end)) => {
|
||||||
self.value.remove_many(start, end);
|
self.value.remove_many(start, end);
|
||||||
self.state.cursor.move_left();
|
self.state.cursor.move_left(&self.value);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if self.state.cursor.start().min(self.value.len())
|
if self.state.cursor.start(&self.value) > 0 {
|
||||||
> 0
|
self.state.cursor.move_left(&self.value);
|
||||||
{
|
|
||||||
self.state.cursor.move_left();
|
let _ = self.value.remove(
|
||||||
let _ = self
|
self.state.cursor.start(&self.value),
|
||||||
.value
|
);
|
||||||
.remove(self.state.cursor.start());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -373,15 +375,16 @@ where
|
|||||||
messages.push(message);
|
messages.push(message);
|
||||||
}
|
}
|
||||||
keyboard::KeyCode::Delete => {
|
keyboard::KeyCode::Delete => {
|
||||||
match self.state.cursor.selection_position() {
|
match self.state.cursor.selection() {
|
||||||
Some((start, end)) => {
|
Some((start, end)) => {
|
||||||
self.value.remove_many(start, end);
|
self.value.remove_many(start, end);
|
||||||
self.state.cursor.move_left();
|
self.state.cursor.move_left(&self.value);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
if self.state.cursor.end() < self.value.len() {
|
let end = self.state.cursor.end(&self.value);
|
||||||
let _ =
|
|
||||||
self.value.remove(self.state.cursor.end());
|
if end > 0 {
|
||||||
|
let _ = self.value.remove(end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -398,9 +401,9 @@ where
|
|||||||
self.state.cursor.move_left_by_words(&self.value);
|
self.state.cursor.move_left_by_words(&self.value);
|
||||||
}
|
}
|
||||||
} else if modifiers.shift {
|
} else if modifiers.shift {
|
||||||
self.state.cursor.select_left()
|
self.state.cursor.select_left(&self.value)
|
||||||
} else {
|
} else {
|
||||||
self.state.cursor.move_left();
|
self.state.cursor.move_left(&self.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
keyboard::KeyCode::Right => {
|
keyboard::KeyCode::Right => {
|
||||||
@ -422,9 +425,10 @@ where
|
|||||||
}
|
}
|
||||||
keyboard::KeyCode::Home => {
|
keyboard::KeyCode::Home => {
|
||||||
if modifiers.shift {
|
if modifiers.shift {
|
||||||
self.state
|
self.state.cursor.select_range(
|
||||||
.cursor
|
self.state.cursor.start(&self.value),
|
||||||
.select_range(self.state.cursor.start(), 0);
|
0,
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
self.state.cursor.move_to(0);
|
self.state.cursor.move_to(0);
|
||||||
}
|
}
|
||||||
@ -432,7 +436,7 @@ where
|
|||||||
keyboard::KeyCode::End => {
|
keyboard::KeyCode::End => {
|
||||||
if modifiers.shift {
|
if modifiers.shift {
|
||||||
self.state.cursor.select_range(
|
self.state.cursor.select_range(
|
||||||
self.state.cursor.start(),
|
self.state.cursor.start(&self.value),
|
||||||
self.value.len(),
|
self.value.len(),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@ -456,16 +460,16 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match self.state.cursor.selection_position() {
|
match self.state.cursor.selection() {
|
||||||
Some((left, right)) => {
|
Some((left, right)) => {
|
||||||
self.value.remove_many(left, right);
|
self.value.remove_many(left, right);
|
||||||
self.state.cursor.move_left();
|
self.state.cursor.move_left(&self.value);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.value.insert_many(
|
self.value.insert_many(
|
||||||
self.state.cursor.end().min(self.value.len()),
|
self.state.cursor.end(&self.value),
|
||||||
content.clone(),
|
content.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
//! Track the cursor of a text input.
|
||||||
use crate::widget::text_input::Value;
|
use crate::widget::text_input::Value;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
enum State {
|
pub enum State {
|
||||||
Index(usize),
|
Index(usize),
|
||||||
Selection { start: usize, end: usize },
|
Selection { start: usize, end: usize },
|
||||||
}
|
}
|
||||||
@ -20,7 +21,6 @@ impl Default for Cursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Cursor {
|
impl Cursor {
|
||||||
/* index move methods */
|
|
||||||
pub fn move_to(&mut self, position: usize) {
|
pub fn move_to(&mut self, position: usize) {
|
||||||
self.state = State::Index(position);
|
self.state = State::Index(position);
|
||||||
}
|
}
|
||||||
@ -30,42 +30,40 @@ impl Cursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_right_by_words(&mut self, value: &Value) {
|
pub fn move_right_by_words(&mut self, value: &Value) {
|
||||||
self.move_to(value.next_end_of_word(self.right()))
|
self.move_to(value.next_end_of_word(self.right(value)))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_right_by_amount(&mut self, value: &Value, amount: usize) {
|
pub fn move_right_by_amount(&mut self, value: &Value, amount: usize) {
|
||||||
match self.state {
|
match self.state(value) {
|
||||||
State::Index(index) => {
|
State::Index(index) => {
|
||||||
self.move_to(index.saturating_add(amount).min(value.len()))
|
self.move_to(index.saturating_add(amount).min(value.len()))
|
||||||
}
|
}
|
||||||
State::Selection { .. } => self.move_to(self.right()),
|
State::Selection { start, end } => self.move_to(end.max(start)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_left(&mut self) {
|
pub fn move_left(&mut self, value: &Value) {
|
||||||
match self.state {
|
match self.state(value) {
|
||||||
State::Index(index) if index > 0 => self.move_to(index - 1),
|
State::Index(index) if index > 0 => self.move_to(index - 1),
|
||||||
State::Selection { .. } => self.move_to(self.left()),
|
State::Selection { start, end } => self.move_to(start.min(end)),
|
||||||
_ => self.move_to(0),
|
_ => self.move_to(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_left_by_words(&mut self, value: &Value) {
|
pub fn move_left_by_words(&mut self, value: &Value) {
|
||||||
self.move_to(value.previous_start_of_word(self.right()));
|
self.move_to(value.previous_start_of_word(self.left(value)));
|
||||||
}
|
}
|
||||||
/* end of index move methods */
|
|
||||||
|
|
||||||
/* expand/shrink selection */
|
|
||||||
pub fn select_range(&mut self, start: usize, end: usize) {
|
pub fn select_range(&mut self, start: usize, end: usize) {
|
||||||
if start != end {
|
if start == end {
|
||||||
self.state = State::Selection { start, end };
|
|
||||||
} else {
|
|
||||||
self.state = State::Index(start);
|
self.state = State::Index(start);
|
||||||
|
} else {
|
||||||
|
self.state = State::Selection { start, end };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_left(&mut self) {
|
pub fn select_left(&mut self, value: &Value) {
|
||||||
match self.state {
|
match self.state(value) {
|
||||||
State::Index(index) if index > 0 => {
|
State::Index(index) if index > 0 => {
|
||||||
self.select_range(index, index - 1)
|
self.select_range(index, index - 1)
|
||||||
}
|
}
|
||||||
@ -77,7 +75,7 @@ impl Cursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_right(&mut self, value: &Value) {
|
pub fn select_right(&mut self, value: &Value) {
|
||||||
match self.state {
|
match self.state(value) {
|
||||||
State::Index(index) if index < value.len() => {
|
State::Index(index) if index < value.len() => {
|
||||||
self.select_range(index, index + 1)
|
self.select_range(index, index + 1)
|
||||||
}
|
}
|
||||||
@ -89,7 +87,7 @@ impl Cursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_left_by_words(&mut self, value: &Value) {
|
pub fn select_left_by_words(&mut self, value: &Value) {
|
||||||
match self.state {
|
match self.state(value) {
|
||||||
State::Index(index) => {
|
State::Index(index) => {
|
||||||
self.select_range(index, value.previous_start_of_word(index))
|
self.select_range(index, value.previous_start_of_word(index))
|
||||||
}
|
}
|
||||||
@ -100,7 +98,7 @@ impl Cursor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn select_right_by_words(&mut self, value: &Value) {
|
pub fn select_right_by_words(&mut self, value: &Value) {
|
||||||
match self.state {
|
match self.state(value) {
|
||||||
State::Index(index) => {
|
State::Index(index) => {
|
||||||
self.select_range(index, value.next_end_of_word(index))
|
self.select_range(index, value.next_end_of_word(index))
|
||||||
}
|
}
|
||||||
@ -113,51 +111,56 @@ impl Cursor {
|
|||||||
pub fn select_all(&mut self, value: &Value) {
|
pub fn select_all(&mut self, value: &Value) {
|
||||||
self.select_range(0, value.len());
|
self.select_range(0, value.len());
|
||||||
}
|
}
|
||||||
/* end of selection section */
|
|
||||||
|
|
||||||
/* helpers */
|
pub fn state(&self, value: &Value) -> State {
|
||||||
// get start position of selection (can be left OR right boundary of selection) or index
|
|
||||||
pub(crate) fn start(&self) -> usize {
|
|
||||||
match self.state {
|
match self.state {
|
||||||
|
State::Index(index) => State::Index(index.min(value.len())),
|
||||||
|
State::Selection { start, end } => {
|
||||||
|
let start = start.min(value.len());
|
||||||
|
let end = end.min(value.len());
|
||||||
|
|
||||||
|
if start == end {
|
||||||
|
State::Index(start)
|
||||||
|
} else {
|
||||||
|
State::Selection { start, end }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn start(&self, value: &Value) -> usize {
|
||||||
|
let start = match self.state {
|
||||||
State::Index(index) => index,
|
State::Index(index) => index,
|
||||||
State::Selection { start, .. } => start,
|
State::Selection { start, .. } => start,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
start.min(value.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
// get end position of selection (can be left OR right boundary of selection) or index
|
pub fn end(&self, value: &Value) -> usize {
|
||||||
pub fn end(&self) -> usize {
|
let end = match self.state {
|
||||||
match self.state {
|
|
||||||
State::Index(index) => index,
|
State::Index(index) => index,
|
||||||
State::Selection { end, .. } => end,
|
State::Selection { end, .. } => end,
|
||||||
}
|
};
|
||||||
|
|
||||||
|
end.min(value.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
// get left boundary of selection or index
|
fn left(&self, value: &Value) -> usize {
|
||||||
pub fn left(&self) -> usize {
|
match self.state(value) {
|
||||||
match self.state {
|
|
||||||
State::Index(index) => index,
|
State::Index(index) => index,
|
||||||
State::Selection { start, end } => start.min(end),
|
State::Selection { start, end } => start.min(end),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get right boundary of selection or index
|
fn right(&self, value: &Value) -> usize {
|
||||||
pub fn right(&self) -> usize {
|
match self.state(value) {
|
||||||
match self.state {
|
|
||||||
State::Index(index) => index,
|
State::Index(index) => index,
|
||||||
State::Selection { start, end } => start.max(end),
|
State::Selection { start, end } => start.max(end),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cursor_position(&self, value: &Value) -> usize {
|
pub fn selection(&self) -> Option<(usize, usize)> {
|
||||||
match self.state {
|
|
||||||
State::Index(index) => index.min(value.len()),
|
|
||||||
State::Selection { end, .. } => end.min(value.len()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns Option of left and right border of selection
|
|
||||||
// a second method that returns start and end may be useful (see below)
|
|
||||||
pub fn selection_position(&self) -> Option<(usize, usize)> {
|
|
||||||
match self.state {
|
match self.state {
|
||||||
State::Selection { start, end } => {
|
State::Selection { start, end } => {
|
||||||
Some((start.min(end), start.max(end)))
|
Some((start.min(end), start.max(end)))
|
||||||
@ -165,11 +168,4 @@ impl Cursor {
|
|||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pub fn selection_position(&self) -> Option<(usize, usize)> {
|
|
||||||
match self.state {
|
|
||||||
State::Selection { start, end } => Some((start, end)),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
use crate::{text_input::StyleSheet, Primitive, Renderer};
|
use crate::{text_input::StyleSheet, Primitive, Renderer};
|
||||||
|
|
||||||
use iced_native::{
|
use iced_native::{
|
||||||
text_input, Background, Color, Font, HorizontalAlignment, MouseCursor,
|
text_input::{self, cursor},
|
||||||
Point, Rectangle, Size, Vector, VerticalAlignment,
|
Background, Color, Font, HorizontalAlignment, MouseCursor, Point,
|
||||||
|
Rectangle, Size, Vector, VerticalAlignment,
|
||||||
};
|
};
|
||||||
use std::f32;
|
use std::f32;
|
||||||
|
|
||||||
@ -41,12 +42,19 @@ impl text_input::Renderer for Renderer {
|
|||||||
font: Font,
|
font: Font,
|
||||||
) -> f32 {
|
) -> f32 {
|
||||||
if state.is_focused() {
|
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(
|
let (_, offset) = measure_cursor_and_scroll_offset(
|
||||||
self,
|
self,
|
||||||
text_bounds,
|
text_bounds,
|
||||||
value,
|
value,
|
||||||
size,
|
size,
|
||||||
state.cursor().cursor_position(value),
|
focus_position,
|
||||||
font,
|
font,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -111,70 +119,91 @@ impl text_input::Renderer for Renderer {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let (contents_primitive, offset) = if state.is_focused() {
|
let (contents_primitive, offset) = if state.is_focused() {
|
||||||
let (text_value_width, offset) = measure_cursor_and_scroll_offset(
|
let cursor = state.cursor();
|
||||||
self,
|
|
||||||
text_bounds,
|
|
||||||
value,
|
|
||||||
size,
|
|
||||||
state.cursor().cursor_position(value),
|
|
||||||
font,
|
|
||||||
);
|
|
||||||
|
|
||||||
let selection = match state.cursor().selection_position() {
|
let (cursor_primitive, offset) = match cursor.state(value) {
|
||||||
None => Primitive::None,
|
cursor::State::Index(position) => {
|
||||||
Some(_) => {
|
let (text_value_width, offset) =
|
||||||
let (cursor_left_offset, _) =
|
|
||||||
measure_cursor_and_scroll_offset(
|
measure_cursor_and_scroll_offset(
|
||||||
self,
|
self,
|
||||||
text_bounds,
|
text_bounds,
|
||||||
value,
|
value,
|
||||||
size,
|
size,
|
||||||
state.cursor().left(),
|
position,
|
||||||
font,
|
font,
|
||||||
);
|
);
|
||||||
let (cursor_right_offset, _) =
|
|
||||||
measure_cursor_and_scroll_offset(
|
(
|
||||||
self,
|
Primitive::Quad {
|
||||||
text_bounds,
|
bounds: Rectangle {
|
||||||
value,
|
x: text_bounds.x + text_value_width,
|
||||||
size,
|
y: text_bounds.y,
|
||||||
state.cursor().right(),
|
width: 1.0,
|
||||||
font,
|
height: text_bounds.height,
|
||||||
);
|
},
|
||||||
let width = cursor_right_offset - cursor_left_offset;
|
background: Background::Color(
|
||||||
Primitive::Quad {
|
style_sheet.value_color(),
|
||||||
bounds: Rectangle {
|
),
|
||||||
x: text_bounds.x + cursor_left_offset,
|
border_radius: 0,
|
||||||
y: text_bounds.y,
|
border_width: 0,
|
||||||
width,
|
border_color: Color::TRANSPARENT,
|
||||||
height: text_bounds.height,
|
|
||||||
},
|
},
|
||||||
background: Background::Color(
|
offset,
|
||||||
style_sheet.selection_color(),
|
)
|
||||||
),
|
|
||||||
border_radius: 0,
|
|
||||||
border_width: 0,
|
|
||||||
border_color: Color::TRANSPARENT,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
cursor::State::Selection { start, end } => {
|
||||||
|
let left = start.min(end);
|
||||||
|
let right = end.max(start);
|
||||||
|
|
||||||
let cursor = Primitive::Quad {
|
let (left_position, left_offset) =
|
||||||
bounds: Rectangle {
|
measure_cursor_and_scroll_offset(
|
||||||
x: text_bounds.x + text_value_width,
|
self,
|
||||||
y: text_bounds.y,
|
text_bounds,
|
||||||
width: 1.0,
|
value,
|
||||||
height: text_bounds.height,
|
size,
|
||||||
},
|
left,
|
||||||
background: Background::Color(style_sheet.value_color()),
|
font,
|
||||||
border_radius: 0,
|
);
|
||||||
border_width: 0,
|
|
||||||
border_color: Color::TRANSPARENT,
|
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 {
|
Primitive::Group {
|
||||||
primitives: vec![selection, text_value, cursor],
|
primitives: vec![cursor_primitive, text_value],
|
||||||
},
|
},
|
||||||
Vector::new(offset as u32, 0),
|
Vector::new(offset as u32, 0),
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user