moved cursor into own file
moved click tracking as a new State struct to input::mouse made cursor field of text_input state private brought back cursor type(Index, Selection) representation with a state enum cleaned out some stuff (but not enough/all) TODO: Documentation (sigh) TODO: Editor struct TODO: some (hopefully) small improvements here and there
This commit is contained in:
parent
190dcef155
commit
c6c8cabdaf
@ -2,5 +2,69 @@
|
||||
mod button;
|
||||
mod event;
|
||||
|
||||
use crate::Point;
|
||||
pub use button::Button;
|
||||
pub use event::{Event, ScrollDelta};
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
/// enum to track the type of the last click
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Interaction {
|
||||
/// Last Click was a single click
|
||||
Click(Point),
|
||||
/// Last Click was a double click
|
||||
DoubleClick(Point),
|
||||
/// Last Click was a triple click
|
||||
TripleClick(Point),
|
||||
}
|
||||
|
||||
/// Compiler bully
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct State {
|
||||
last_click: Option<Interaction>,
|
||||
last_click_timestamp: Option<SystemTime>,
|
||||
}
|
||||
|
||||
impl Default for State {
|
||||
fn default() -> Self {
|
||||
State {
|
||||
last_click: None,
|
||||
last_click_timestamp: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
/// processes left click to check for double/triple clicks
|
||||
/// return amount of repetitive mouse clicks
|
||||
/// (1 -> double click, 2 -> triple click)
|
||||
pub fn update(&mut self, position: Point) -> Interaction {
|
||||
self.last_click_timestamp = Some(SystemTime::now());
|
||||
self.last_click = match self.last_click {
|
||||
None => Some(Interaction::Click(position)),
|
||||
Some(x) => match x {
|
||||
Interaction::Click(p) if self.process_click(p, position) => {
|
||||
Some(Interaction::DoubleClick(position))
|
||||
}
|
||||
Interaction::DoubleClick(p)
|
||||
if self.process_click(p, position) =>
|
||||
{
|
||||
Some(Interaction::TripleClick(position))
|
||||
}
|
||||
_ => Some(Interaction::Click(position)),
|
||||
},
|
||||
};
|
||||
self.last_click.unwrap_or(Interaction::Click(position))
|
||||
}
|
||||
|
||||
fn process_click(&self, old_position: Point, new_position: Point) -> bool {
|
||||
old_position == new_position
|
||||
&& SystemTime::now()
|
||||
.duration_since(
|
||||
self.last_click_timestamp.unwrap_or(SystemTime::UNIX_EPOCH),
|
||||
)
|
||||
.unwrap_or(Duration::from_secs(1))
|
||||
.as_millis()
|
||||
<= 500
|
||||
}
|
||||
}
|
||||
|
@ -4,10 +4,13 @@
|
||||
//!
|
||||
//! [`TextInput`]: struct.TextInput.html
|
||||
//! [`State`]: struct.State.html
|
||||
mod cursor;
|
||||
use crate::{
|
||||
input::{keyboard, mouse, ButtonState},
|
||||
layout, Clipboard, Element, Event, Font, Hasher, Layout, Length, Point,
|
||||
Rectangle, Size, Widget,
|
||||
input::{keyboard, mouse, mouse::Interaction, ButtonState},
|
||||
layout,
|
||||
widget::text_input::cursor::Cursor,
|
||||
Clipboard, Element, Event, Font, Hasher, Layout, Length, Point, Rectangle,
|
||||
Size, Widget,
|
||||
};
|
||||
|
||||
use std::u32;
|
||||
@ -209,16 +212,20 @@ where
|
||||
let text_layout = layout.children().next().unwrap();
|
||||
let target = cursor_position.x - text_layout.bounds().x;
|
||||
|
||||
match self.state.cursor.process_click(cursor_position) {
|
||||
1 => self.state.cursor.select_range(
|
||||
self.value.previous_start_of_word(
|
||||
self.state.cursor.end(),
|
||||
),
|
||||
self.value
|
||||
.next_end_of_word(self.state.cursor.end()),
|
||||
),
|
||||
2 => self.state.cursor.select_all(self.value.len()),
|
||||
_ => {
|
||||
match self.state.mouse.update(cursor_position) {
|
||||
Interaction::DoubleClick(_) => {
|
||||
self.state.cursor.select_range(
|
||||
self.value.previous_start_of_word(
|
||||
self.state.cursor.end(),
|
||||
),
|
||||
self.value
|
||||
.next_end_of_word(self.state.cursor.end()),
|
||||
)
|
||||
}
|
||||
Interaction::TripleClick(_) => {
|
||||
self.state.cursor.select_all(&self.value)
|
||||
}
|
||||
Interaction::Click(_) => {
|
||||
if target > 0.0 {
|
||||
let value = if self.is_secure {
|
||||
self.value.secure()
|
||||
@ -308,17 +315,14 @@ where
|
||||
&& self.state.is_pasting.is_none()
|
||||
&& !c.is_control() =>
|
||||
{
|
||||
if !self.state.cursor.is_selection() {
|
||||
self.value.insert(self.state.cursor.end(), c);
|
||||
} else {
|
||||
self.value.remove_many(
|
||||
self.state.cursor.left(),
|
||||
self.state.cursor.right(),
|
||||
);
|
||||
self.state.cursor.move_left();
|
||||
self.value.insert(self.state.cursor.end(), c);
|
||||
match self.state.cursor.selection_position() {
|
||||
Some((left, right)) => {
|
||||
self.value.remove_many(left, right);
|
||||
self.state.cursor.move_left();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
self.value.insert(self.state.cursor.end(), c);
|
||||
self.state.cursor.move_right(&self.value);
|
||||
|
||||
let message = (self.on_change)(self.value.to_string());
|
||||
@ -335,42 +339,38 @@ where
|
||||
}
|
||||
}
|
||||
keyboard::KeyCode::Backspace => {
|
||||
if !self.state.cursor.is_selection() {
|
||||
if self.state.cursor.start() > 0 {
|
||||
match self.state.cursor.selection_position() {
|
||||
Some((start, end)) => {
|
||||
self.value.remove_many(start, end);
|
||||
self.state.cursor.move_left();
|
||||
let _ =
|
||||
self.value.remove(self.state.cursor.end() - 1);
|
||||
let message =
|
||||
(self.on_change)(self.value.to_string());
|
||||
messages.push(message);
|
||||
}
|
||||
} else {
|
||||
self.value.remove_many(
|
||||
self.state.cursor.left(),
|
||||
self.state.cursor.right(),
|
||||
);
|
||||
self.state.cursor.move_left();
|
||||
let message = (self.on_change)(self.value.to_string());
|
||||
messages.push(message);
|
||||
None => {
|
||||
if self.state.cursor.start() > 0 {
|
||||
self.state.cursor.move_left();
|
||||
let _ = self
|
||||
.value
|
||||
.remove(self.state.cursor.start() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
let message = (self.on_change)(self.value.to_string());
|
||||
messages.push(message);
|
||||
}
|
||||
keyboard::KeyCode::Delete => {
|
||||
if !self.state.cursor.is_selection() {
|
||||
if self.state.cursor.end() < self.value.len() {
|
||||
let _ = self.value.remove(self.state.cursor.end());
|
||||
let message =
|
||||
(self.on_change)(self.value.to_string());
|
||||
messages.push(message);
|
||||
match self.state.cursor.selection_position() {
|
||||
Some((start, end)) => {
|
||||
self.value.remove_many(start, end);
|
||||
self.state.cursor.move_left();
|
||||
}
|
||||
None => {
|
||||
if self.state.cursor.end() < self.value.len() {
|
||||
let _ =
|
||||
self.value.remove(self.state.cursor.end());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.value.remove_many(
|
||||
self.state.cursor.left(),
|
||||
self.state.cursor.right(),
|
||||
);
|
||||
self.state.cursor.move_left();
|
||||
let message = (self.on_change)(self.value.to_string());
|
||||
messages.push(message);
|
||||
}
|
||||
let message = (self.on_change)(self.value.to_string());
|
||||
messages.push(message);
|
||||
}
|
||||
keyboard::KeyCode::Left => {
|
||||
if platform::is_jump_modifier_pressed(modifiers)
|
||||
@ -413,12 +413,12 @@ where
|
||||
}
|
||||
};
|
||||
|
||||
if self.state.cursor.is_selection() {
|
||||
self.value.remove_many(
|
||||
self.state.cursor.left(),
|
||||
self.state.cursor.right(),
|
||||
);
|
||||
self.state.cursor.move_left();
|
||||
match self.state.cursor.selection_position() {
|
||||
Some((left, right)) => {
|
||||
self.value.remove_many(left, right);
|
||||
self.state.cursor.move_left();
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
||||
self.value.insert_many(
|
||||
@ -442,7 +442,7 @@ where
|
||||
}
|
||||
keyboard::KeyCode::A => {
|
||||
if platform::is_copy_paste_modifier_pressed(modifiers) {
|
||||
self.state.cursor.select_range(0, self.value.len());
|
||||
self.state.cursor.select_all(&self.value);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@ -596,8 +596,8 @@ pub struct State {
|
||||
is_focused: bool,
|
||||
is_pressed: bool,
|
||||
is_pasting: Option<Value>,
|
||||
/// TODO: Compiler wants documentation here
|
||||
pub cursor: cursor::Cursor,
|
||||
cursor: Cursor,
|
||||
mouse: crate::input::mouse::State,
|
||||
// TODO: Add stateful horizontal scrolling offset
|
||||
}
|
||||
|
||||
@ -617,7 +617,8 @@ impl State {
|
||||
is_focused: true,
|
||||
is_pressed: false,
|
||||
is_pasting: None,
|
||||
cursor: cursor::Cursor::default(),
|
||||
cursor: Cursor::default(),
|
||||
mouse: crate::input::mouse::State::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -627,6 +628,11 @@ impl State {
|
||||
pub fn is_focused(&self) -> bool {
|
||||
self.is_focused
|
||||
}
|
||||
|
||||
/// getter for cursor
|
||||
pub fn cursor(&self) -> Cursor {
|
||||
self.cursor
|
||||
}
|
||||
}
|
||||
|
||||
/// The value of a [`TextInput`].
|
||||
@ -841,182 +847,3 @@ mod platform {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod cursor {
|
||||
use crate::widget::text_input::Value;
|
||||
use iced_core::Point;
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
/// Even the compiler bullies me for not writing documentation
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Cursor {
|
||||
start: usize,
|
||||
end: usize,
|
||||
click_count: usize,
|
||||
last_click_position: Option<crate::Point>,
|
||||
last_click_timestamp: Option<SystemTime>,
|
||||
}
|
||||
|
||||
impl Default for Cursor {
|
||||
fn default() -> Self {
|
||||
Cursor {
|
||||
start: 0,
|
||||
end: 0,
|
||||
click_count: 0,
|
||||
last_click_position: None,
|
||||
last_click_timestamp: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Cursor {
|
||||
/* Move section */
|
||||
pub fn move_to(&mut self, position: usize) {
|
||||
self.start = position;
|
||||
self.end = position;
|
||||
}
|
||||
|
||||
pub fn move_right(&mut self, value: &Value) {
|
||||
if self.is_selection() {
|
||||
let dest = self.right();
|
||||
self.start = dest;
|
||||
self.end = dest;
|
||||
} else if self.end < value.len() {
|
||||
self.start += 1;
|
||||
self.end += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_left(&mut self) {
|
||||
if self.is_selection() {
|
||||
let dest = self.left();
|
||||
self.start = dest;
|
||||
self.end = dest;
|
||||
} else if self.left() > 0 {
|
||||
self.start -= 1;
|
||||
self.end -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_right_by_amount(&mut self, value: &Value, amount: usize) {
|
||||
self.start = self.start.saturating_add(amount).min(value.len());
|
||||
self.end = self.end.saturating_add(amount).min(value.len());
|
||||
}
|
||||
|
||||
pub fn move_left_by_words(&mut self, value: &Value) {
|
||||
let (left, _) = self.cursor_position(value);
|
||||
|
||||
self.move_to(value.previous_start_of_word(left));
|
||||
}
|
||||
|
||||
pub fn move_right_by_words(&mut self, value: &Value) {
|
||||
let (_, right) = self.cursor_position(value);
|
||||
|
||||
self.move_to(value.next_end_of_word(right));
|
||||
}
|
||||
/* Move section end */
|
||||
|
||||
/* Selection section */
|
||||
pub fn select_range(&mut self, start: usize, end: usize) {
|
||||
self.start = start;
|
||||
self.end = end;
|
||||
}
|
||||
|
||||
pub fn select_left(&mut self) {
|
||||
if self.end > 0 {
|
||||
self.end -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_right(&mut self, value: &Value) {
|
||||
if self.end < value.len() {
|
||||
self.end += 1;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_left_by_words(&mut self, value: &Value) {
|
||||
self.end = value.previous_start_of_word(self.start);
|
||||
}
|
||||
|
||||
pub fn select_right_by_words(&mut self, value: &Value) {
|
||||
self.end = value.next_end_of_word(self.start);
|
||||
}
|
||||
|
||||
pub fn select_all(&mut self, len: usize) {
|
||||
self.start = 0;
|
||||
self.end = len;
|
||||
}
|
||||
/* Selection section end */
|
||||
|
||||
/* Double/Triple click section */
|
||||
// returns the amount of clicks on the same position in specific timeframe
|
||||
// (1=double click, 2=triple click)
|
||||
pub fn process_click(&mut self, position: Point) -> usize {
|
||||
if position
|
||||
== self.last_click_position.unwrap_or(Point { x: 0.0, y: 0.0 })
|
||||
&& self.click_count < 2
|
||||
&& SystemTime::now()
|
||||
.duration_since(
|
||||
self.last_click_timestamp
|
||||
.unwrap_or(SystemTime::UNIX_EPOCH),
|
||||
)
|
||||
.unwrap_or(Duration::from_secs(1))
|
||||
.as_millis()
|
||||
<= 500
|
||||
{
|
||||
self.click_count += 1;
|
||||
} else {
|
||||
self.click_count = 0;
|
||||
}
|
||||
self.last_click_position = Option::from(position);
|
||||
self.last_click_timestamp = Option::from(SystemTime::now());
|
||||
self.click_count
|
||||
}
|
||||
/* Double/Triple click section end */
|
||||
|
||||
/* "get info about cursor/selection" section */
|
||||
pub fn is_selection(&self) -> bool {
|
||||
self.start != self.end
|
||||
}
|
||||
|
||||
// get start position of selection (can be left OR right boundary of selection)
|
||||
pub(crate) fn start(&self) -> usize {
|
||||
self.start
|
||||
}
|
||||
|
||||
// get end position of selection (can be left OR right boundary of selection)
|
||||
pub fn end(&self) -> usize {
|
||||
self.end
|
||||
}
|
||||
|
||||
// get left boundary of selection
|
||||
pub fn left(&self) -> usize {
|
||||
self.start.min(self.end)
|
||||
}
|
||||
|
||||
// get right boundary of selection
|
||||
pub fn right(&self) -> usize {
|
||||
self.start.max(self.end)
|
||||
}
|
||||
|
||||
pub fn cursor_position(&self, value: &Value) -> (usize, usize) {
|
||||
(self.start.min(value.len()), self.end.min(value.len()))
|
||||
}
|
||||
|
||||
pub fn cursor_position_left(&self, value: &Value) -> usize {
|
||||
let (a, b) = self.cursor_position(value);
|
||||
a.min(b)
|
||||
}
|
||||
|
||||
pub fn cursor_position_right(&self, value: &Value) -> usize {
|
||||
let (a, b) = self.cursor_position(value);
|
||||
a.max(b)
|
||||
}
|
||||
|
||||
pub fn draw_position(&self, value: &Value) -> usize {
|
||||
let (_, end) = self.cursor_position(value);
|
||||
end
|
||||
}
|
||||
/* "get info about cursor/selection" section end */
|
||||
}
|
||||
}
|
||||
|
176
native/src/widget/text_input/cursor.rs
Normal file
176
native/src/widget/text_input/cursor.rs
Normal file
@ -0,0 +1,176 @@
|
||||
use crate::widget::text_input::Value;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
enum State {
|
||||
Index(usize),
|
||||
Selection { start: usize, end: usize },
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct Cursor {
|
||||
state: State,
|
||||
}
|
||||
|
||||
impl Default for Cursor {
|
||||
fn default() -> Self {
|
||||
Cursor {
|
||||
state: State::Index(0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Cursor {
|
||||
/* index move methods */
|
||||
pub fn move_to(&mut self, position: usize) {
|
||||
self.state = State::Index(position);
|
||||
}
|
||||
|
||||
pub fn move_right(&mut self, value: &Value) {
|
||||
self.move_right_by_amount(value, 1)
|
||||
}
|
||||
|
||||
pub fn move_right_by_words(&mut self, value: &Value) {
|
||||
self.move_to(value.next_end_of_word(self.right()))
|
||||
}
|
||||
|
||||
pub fn move_right_by_amount(&mut self, value: &Value, amount: usize) {
|
||||
match self.state {
|
||||
State::Index(index) => {
|
||||
self.move_to(index.saturating_add(amount).min(value.len()))
|
||||
}
|
||||
State::Selection { .. } => self.move_to(self.right()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_left(&mut self) {
|
||||
match self.state {
|
||||
State::Index(index) if index > 0 => self.move_to(index - 1),
|
||||
State::Selection { .. } => self.move_to(self.left()),
|
||||
_ => self.move_to(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn move_left_by_words(&mut self, value: &Value) {
|
||||
self.move_to(value.previous_start_of_word(self.right()));
|
||||
}
|
||||
/* end of index move methods */
|
||||
|
||||
/* expand/shrink selection */
|
||||
// TODO: (whole section): Return State::Cursor if start == end after operation
|
||||
pub fn select_range(&mut self, start: usize, end: usize) {
|
||||
self.state = State::Selection { start, end };
|
||||
}
|
||||
|
||||
pub fn select_left(&mut self) {
|
||||
match self.state {
|
||||
State::Index(index) if index > 0 => {
|
||||
self.select_range(index, index - 1)
|
||||
}
|
||||
State::Selection { start, end } if end > 0 => {
|
||||
self.select_range(start, end - 1)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_right(&mut self, value: &Value) {
|
||||
match self.state {
|
||||
State::Index(index) if index < value.len() => {
|
||||
self.select_range(index, index + 1)
|
||||
}
|
||||
State::Selection { start, end } if end < value.len() => {
|
||||
self.select_range(start, end + 1)
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_left_by_words(&mut self, value: &Value) {
|
||||
match self.state {
|
||||
State::Index(index) => {
|
||||
self.select_range(index, value.previous_start_of_word(index))
|
||||
}
|
||||
State::Selection { start, end } => {
|
||||
self.select_range(start, value.previous_start_of_word(end))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_right_by_words(&mut self, value: &Value) {
|
||||
match self.state {
|
||||
State::Index(index) => {
|
||||
self.select_range(index, value.next_end_of_word(index))
|
||||
}
|
||||
State::Selection { start, end } => {
|
||||
self.select_range(start, value.next_end_of_word(end))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn select_all(&mut self, value: &Value) {
|
||||
self.select_range(0, value.len());
|
||||
}
|
||||
/* end of selection section */
|
||||
|
||||
/* helpers */
|
||||
// get start position of selection (can be left OR right boundary of selection) or index
|
||||
pub(crate) fn start(&self) -> usize {
|
||||
match self.state {
|
||||
State::Index(index) => index,
|
||||
State::Selection { start, .. } => start,
|
||||
}
|
||||
}
|
||||
|
||||
// get end position of selection (can be left OR right boundary of selection) or index
|
||||
pub fn end(&self) -> usize {
|
||||
match self.state {
|
||||
State::Index(index) => index,
|
||||
State::Selection { end, .. } => end,
|
||||
}
|
||||
}
|
||||
|
||||
// get left boundary of selection or index
|
||||
pub fn left(&self) -> usize {
|
||||
match self.state {
|
||||
State::Index(index) => index,
|
||||
State::Selection { start, end } => start.min(end),
|
||||
}
|
||||
}
|
||||
|
||||
// get right boundary of selection or index
|
||||
pub fn right(&self) -> usize {
|
||||
match self.state {
|
||||
State::Index(index) => index,
|
||||
State::Selection { start, end } => start.max(end),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn draw_position(&self, value: &Value) -> usize {
|
||||
self.cursor_position(value)
|
||||
}
|
||||
|
||||
pub fn cursor_position(&self, value: &Value) -> 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 return start and end may be useful (see below)
|
||||
pub fn selection_position(&self) -> Option<(usize, usize)> {
|
||||
match self.state {
|
||||
State::Selection { start, end } => {
|
||||
Some((start.min(end), start.max(end)))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/* pub fn selection_position(&self) -> Option<(usize, usize)> {
|
||||
match self.state {
|
||||
State::Selection { start, end } => Some((start, end)),
|
||||
_ => None,
|
||||
}
|
||||
} */
|
||||
}
|
@ -46,7 +46,7 @@ impl text_input::Renderer for Renderer {
|
||||
text_bounds,
|
||||
value,
|
||||
size,
|
||||
state.cursor.draw_position(value),
|
||||
state.cursor().cursor_position(value),
|
||||
font,
|
||||
);
|
||||
|
||||
@ -116,20 +116,20 @@ impl text_input::Renderer for Renderer {
|
||||
text_bounds,
|
||||
value,
|
||||
size,
|
||||
state.cursor.draw_position(value),
|
||||
state.cursor().cursor_position(value),
|
||||
font,
|
||||
);
|
||||
|
||||
/*let selection = match cursor {
|
||||
text_input::Cursor::Index(_) => Primitive::None,
|
||||
text_input::Cursor::Selection { .. } => {
|
||||
let selection = match state.cursor().selection_position() {
|
||||
None => Primitive::None,
|
||||
Some(_) => {
|
||||
let (cursor_left_offset, _) =
|
||||
measure_cursor_and_scroll_offset(
|
||||
self,
|
||||
text_bounds,
|
||||
value,
|
||||
size,
|
||||
state.cursor.left(),
|
||||
state.cursor().left(),
|
||||
font,
|
||||
);
|
||||
let (cursor_right_offset, _) =
|
||||
@ -138,7 +138,7 @@ impl text_input::Renderer for Renderer {
|
||||
text_bounds,
|
||||
value,
|
||||
size,
|
||||
state.cursor.right(),
|
||||
state.cursor().right(),
|
||||
font,
|
||||
);
|
||||
let width = cursor_right_offset - cursor_left_offset;
|
||||
@ -157,42 +157,6 @@ impl text_input::Renderer for Renderer {
|
||||
border_color: Color::TRANSPARENT,
|
||||
}
|
||||
}
|
||||
};*/
|
||||
|
||||
let selection = if !state.cursor.is_selection() {
|
||||
Primitive::None
|
||||
} else {
|
||||
let (cursor_left_offset, _) = measure_cursor_and_scroll_offset(
|
||||
self,
|
||||
text_bounds,
|
||||
value,
|
||||
size,
|
||||
state.cursor.left(),
|
||||
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,
|
||||
},
|
||||
background: Background::Color(
|
||||
style_sheet.selection_color(),
|
||||
),
|
||||
border_radius: 0,
|
||||
border_width: 0,
|
||||
border_color: Color::TRANSPARENT,
|
||||
}
|
||||
};
|
||||
|
||||
let cursor = Primitive::Quad {
|
||||
|
Loading…
x
Reference in New Issue
Block a user