Compare commits
1 Commits
140be50baa
...
fc89826794
| Author | SHA1 | Date | |
|---|---|---|---|
| fc89826794 |
@@ -169,12 +169,20 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
.cursor_motion(self.font_system, cursor, None, motion)
|
.cursor_motion(self.font_system, cursor, None, motion)
|
||||||
{
|
{
|
||||||
self.text.selection = TextSelection::Pos(cursor);
|
self.text.selection = TextSelection::Pos(cursor);
|
||||||
|
} else if let TextSelection::Span { start, end } = self.text.selection {
|
||||||
|
let (start, end) = sort_cursors(start, end);
|
||||||
|
let sel = &mut self.text.selection;
|
||||||
|
match motion {
|
||||||
|
Motion::Left | Motion::LeftWord => *sel = TextSelection::Pos(start),
|
||||||
|
Motion::Right | Motion::RightWord => *sel = TextSelection::Pos(end),
|
||||||
|
_ => (),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replace(&mut self, len: usize, text: &str) {
|
pub fn replace(&mut self, len: usize, text: &str) {
|
||||||
for _ in 0..len {
|
for _ in 0..len {
|
||||||
self.delete();
|
self.delete(false);
|
||||||
}
|
}
|
||||||
self.insert_inner(text, false);
|
self.insert_inner(text, false);
|
||||||
}
|
}
|
||||||
@@ -193,6 +201,16 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
|
|
||||||
pub fn clear_span(&mut self) -> bool {
|
pub fn clear_span(&mut self) -> bool {
|
||||||
if let TextSelection::Span { start, end } = self.text.selection {
|
if let TextSelection::Span { start, end } = self.text.selection {
|
||||||
|
self.delete_between(start, end);
|
||||||
|
let (start, _) = sort_cursors(start, end);
|
||||||
|
self.text.selection = TextSelection::Pos(start);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete_between(&mut self, start: Cursor, end: Cursor) {
|
||||||
let lines = &mut self.text.view.buf.lines;
|
let lines = &mut self.text.view.buf.lines;
|
||||||
let (start, end) = sort_cursors(start, end);
|
let (start, end) = sort_cursors(start, end);
|
||||||
if start.line == end.line {
|
if start.line == end.line {
|
||||||
@@ -212,11 +230,6 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
if !range.is_empty() {
|
if !range.is_empty() {
|
||||||
lines.splice(range, None);
|
lines.splice(range, None);
|
||||||
}
|
}
|
||||||
self.text.selection = TextSelection::Pos(start);
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn insert_inner(&mut self, text: &str, mov: bool) {
|
fn insert_inner(&mut self, text: &str, mov: bool) {
|
||||||
@@ -246,20 +259,30 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn backspace(&mut self) {
|
pub fn backspace(&mut self, word: bool) {
|
||||||
if !self.clear_span()
|
if !self.clear_span()
|
||||||
&& let TextSelection::Pos(cursor) = &mut self.text.selection
|
&& let TextSelection::Pos(cursor) = &mut self.text.selection
|
||||||
&& (cursor.index != 0 || cursor.line != 0)
|
&& (cursor.index != 0 || cursor.line != 0)
|
||||||
{
|
{
|
||||||
self.motion(Motion::Left);
|
self.motion(if word { Motion::LeftWord } else { Motion::Left });
|
||||||
self.delete();
|
self.delete(word);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&mut self) {
|
pub fn delete(&mut self, word: bool) {
|
||||||
if !self.clear_span()
|
if !self.clear_span()
|
||||||
&& let TextSelection::Pos(cursor) = &mut self.text.selection
|
&& let TextSelection::Pos(cursor) = &mut self.text.selection
|
||||||
{
|
{
|
||||||
|
if word {
|
||||||
|
let start = *cursor;
|
||||||
|
if let Some((end, _)) =
|
||||||
|
self.text
|
||||||
|
.buf
|
||||||
|
.cursor_motion(self.font_system, start, None, Motion::RightWord)
|
||||||
|
{
|
||||||
|
self.delete_between(start, end);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
let lines = &mut self.text.view.buf.lines;
|
let lines = &mut self.text.view.buf.lines;
|
||||||
let line = &mut lines[cursor.line];
|
let line = &mut lines[cursor.line];
|
||||||
if cursor.index == line.text().len() {
|
if cursor.index == line.text().len() {
|
||||||
@@ -278,6 +301,7 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn select(&mut self, pos: Vec2, size: Vec2, drag: bool) {
|
pub fn select(&mut self, pos: Vec2, size: Vec2, drag: bool) {
|
||||||
let pos = pos - self.text.region().top_left().to_abs(size);
|
let pos = pos - self.text.region().top_left().to_abs(size);
|
||||||
@@ -316,8 +340,8 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
pub fn apply_event(&mut self, event: &KeyEvent, modifiers: &Modifiers) -> TextInputResult {
|
pub fn apply_event(&mut self, event: &KeyEvent, modifiers: &Modifiers) -> TextInputResult {
|
||||||
match &event.logical_key {
|
match &event.logical_key {
|
||||||
Key::Named(named) => match named {
|
Key::Named(named) => match named {
|
||||||
NamedKey::Backspace => self.backspace(),
|
NamedKey::Backspace => self.backspace(modifiers.control),
|
||||||
NamedKey::Delete => self.delete(),
|
NamedKey::Delete => self.delete(modifiers.control),
|
||||||
NamedKey::Space => self.insert(" "),
|
NamedKey::Space => self.insert(" "),
|
||||||
NamedKey::Enter => {
|
NamedKey::Enter => {
|
||||||
if modifiers.shift {
|
if modifiers.shift {
|
||||||
@@ -326,8 +350,20 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
return TextInputResult::Submit;
|
return TextInputResult::Submit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NamedKey::ArrowRight => self.motion(Motion::Right),
|
NamedKey::ArrowRight => {
|
||||||
NamedKey::ArrowLeft => self.motion(Motion::Left),
|
if modifiers.control {
|
||||||
|
self.motion(Motion::RightWord)
|
||||||
|
} else {
|
||||||
|
self.motion(Motion::Right)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NamedKey::ArrowLeft => {
|
||||||
|
if modifiers.control {
|
||||||
|
self.motion(Motion::LeftWord)
|
||||||
|
} else {
|
||||||
|
self.motion(Motion::Left)
|
||||||
|
}
|
||||||
|
}
|
||||||
NamedKey::ArrowUp => self.motion(Motion::Up),
|
NamedKey::ArrowUp => self.motion(Motion::Up),
|
||||||
NamedKey::ArrowDown => self.motion(Motion::Down),
|
NamedKey::ArrowDown => self.motion(Motion::Down),
|
||||||
NamedKey::Escape => {
|
NamedKey::Escape => {
|
||||||
@@ -345,12 +381,25 @@ impl<'a> TextEditCtx<'a> {
|
|||||||
let content = self.text.select_content(start, end);
|
let content = self.text.select_content(start, end);
|
||||||
return TextInputResult::Copy(content);
|
return TextInputResult::Copy(content);
|
||||||
}
|
}
|
||||||
return TextInputResult::Used;
|
|
||||||
}
|
}
|
||||||
_ => (),
|
"a" => {
|
||||||
|
if !self.text.buf.lines[0].text().is_empty()
|
||||||
|
|| self.text.buf.lines.len() > 1
|
||||||
|
{
|
||||||
|
let lines = &self.text.buf.lines;
|
||||||
|
let last_line = lines.len() - 1;
|
||||||
|
let last_idx = lines[last_line].text().len();
|
||||||
|
self.text.selection = TextSelection::Span {
|
||||||
|
start: Cursor::new(0, 0),
|
||||||
|
end: Cursor::new(last_line, last_idx),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.insert(text)
|
_ => self.insert(text),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.insert(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_ => return TextInputResult::Unused,
|
_ => return TextInputResult::Unused,
|
||||||
}
|
}
|
||||||
@@ -380,7 +429,7 @@ pub enum TextInputResult {
|
|||||||
Paste,
|
Paste,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Debug, Default)]
|
||||||
pub enum TextSelection {
|
pub enum TextSelection {
|
||||||
#[default]
|
#[default]
|
||||||
None,
|
None,
|
||||||
|
|||||||
Reference in New Issue
Block a user