Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add select flag for motion and click actions #265

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions examples/editor-test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ fn main() {
// Test delete of EGC
{
let cursor = editor.cursor();
editor.action(Action::Motion(Motion::Previous));
editor.action(Action::Motion {
motion: Motion::Previous,
select: false,
});
editor.action(Action::Delete);
for c in grapheme.chars() {
editor.action(Action::Insert(c));
Expand All @@ -140,7 +143,10 @@ fn main() {
{
let cursor = editor.cursor();
editor.action(Action::Enter);
editor.action(Action::Motion(Motion::Previous));
editor.action(Action::Motion {
motion: Motion::Previous,
select: false,
});
editor.action(Action::Delete);
assert_eq!(cursor, editor.cursor());
}
Expand Down
51 changes: 36 additions & 15 deletions examples/editor/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ fn main() {
}

let mut ctrl_pressed = false;
let mut shift_pressed = false;
let mut mouse_x = 0.0;
let mut mouse_y = 0.0;
let mut mouse_left = ElementState::Released;
Expand Down Expand Up @@ -174,7 +175,8 @@ fn main() {
surface_buffer.present().unwrap();
}
WindowEvent::ModifiersChanged(modifiers) => {
ctrl_pressed = modifiers.state().control_key()
ctrl_pressed = modifiers.state().control_key();
shift_pressed = modifiers.state().shift_key();
}
WindowEvent::KeyboardInput { event, .. } => {
let KeyEvent {
Expand All @@ -184,28 +186,46 @@ fn main() {
if state.is_pressed() {
match logical_key {
Key::Named(NamedKey::ArrowLeft) => {
editor.action(Action::Motion(Motion::Left))
editor.action(Action::Motion {
motion: Motion::Left,
select: shift_pressed,
})
}
Key::Named(NamedKey::ArrowRight) => {
editor.action(Action::Motion(Motion::Right))
editor.action(Action::Motion {
motion: Motion::Right,
select: shift_pressed,
})
}
Key::Named(NamedKey::ArrowUp) => {
editor.action(Action::Motion(Motion::Up))
editor.action(Action::Motion {
motion: Motion::Up,
select: shift_pressed,
})
}
Key::Named(NamedKey::ArrowDown) => {
editor.action(Action::Motion(Motion::Down))
}
Key::Named(NamedKey::Home) => {
editor.action(Action::Motion(Motion::Home))
}
Key::Named(NamedKey::End) => {
editor.action(Action::Motion(Motion::End))
}
Key::Named(NamedKey::PageUp) => {
editor.action(Action::Motion(Motion::PageUp))
editor.action(Action::Motion {
motion: Motion::Down,
select: shift_pressed,
})
}
Key::Named(NamedKey::Home) => editor.action(Action::Motion {
motion: Motion::Home,
select: shift_pressed,
}),
Key::Named(NamedKey::End) => editor.action(Action::Motion {
motion: Motion::End,
select: shift_pressed,
}),
Key::Named(NamedKey::PageUp) => editor.action(Action::Motion {
motion: Motion::PageUp,
select: shift_pressed,
}),
Key::Named(NamedKey::PageDown) => {
editor.action(Action::Motion(Motion::PageDown))
editor.action(Action::Motion {
motion: Motion::PageDown,
select: shift_pressed,
})
}
Key::Named(NamedKey::Escape) => editor.action(Action::Escape),
Key::Named(NamedKey::Enter) => editor.action(Action::Enter),
Expand Down Expand Up @@ -316,6 +336,7 @@ fn main() {
editor.action(Action::Click {
x: mouse_x as i32,
y: mouse_y as i32,
select: shift_pressed,
});
window.request_redraw();
}
Expand Down
51 changes: 36 additions & 15 deletions examples/rich-text/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ fn main() {
editor.with_buffer_mut(|buffer| set_buffer_text(buffer));

let mut ctrl_pressed = false;
let mut shift_pressed = false;
let mut mouse_x = 0.0;
let mut mouse_y = 0.0;
let mut mouse_left = ElementState::Released;
Expand Down Expand Up @@ -217,7 +218,8 @@ fn main() {
surface_buffer.present().unwrap();
}
WindowEvent::ModifiersChanged(modifiers) => {
ctrl_pressed = modifiers.state().control_key()
ctrl_pressed = modifiers.state().control_key();
shift_pressed = modifiers.state().shift_key();
}
WindowEvent::KeyboardInput { event, .. } => {
let KeyEvent {
Expand All @@ -227,28 +229,46 @@ fn main() {
if state.is_pressed() {
match logical_key {
Key::Named(NamedKey::ArrowLeft) => {
editor.action(Action::Motion(Motion::Left))
editor.action(Action::Motion {
motion: Motion::Left,
select: shift_pressed,
})
}
Key::Named(NamedKey::ArrowRight) => {
editor.action(Action::Motion(Motion::Right))
editor.action(Action::Motion {
motion: Motion::Right,
select: shift_pressed,
})
}
Key::Named(NamedKey::ArrowUp) => {
editor.action(Action::Motion(Motion::Up))
editor.action(Action::Motion {
motion: Motion::Up,
select: shift_pressed,
})
}
Key::Named(NamedKey::ArrowDown) => {
editor.action(Action::Motion(Motion::Down))
}
Key::Named(NamedKey::Home) => {
editor.action(Action::Motion(Motion::Home))
}
Key::Named(NamedKey::End) => {
editor.action(Action::Motion(Motion::End))
}
Key::Named(NamedKey::PageUp) => {
editor.action(Action::Motion(Motion::PageUp))
editor.action(Action::Motion {
motion: Motion::Down,
select: shift_pressed,
})
}
Key::Named(NamedKey::Home) => editor.action(Action::Motion {
motion: Motion::Home,
select: shift_pressed,
}),
Key::Named(NamedKey::End) => editor.action(Action::Motion {
motion: Motion::End,
select: shift_pressed,
}),
Key::Named(NamedKey::PageUp) => editor.action(Action::Motion {
motion: Motion::PageUp,
select: shift_pressed,
}),
Key::Named(NamedKey::PageDown) => {
editor.action(Action::Motion(Motion::PageDown))
editor.action(Action::Motion {
motion: Motion::PageDown,
select: shift_pressed,
})
}
Key::Named(NamedKey::Escape) => editor.action(Action::Escape),
Key::Named(NamedKey::Enter) => editor.action(Action::Enter),
Expand Down Expand Up @@ -313,6 +333,7 @@ fn main() {
editor.action(Action::Click {
x: mouse_x /*- line_x*/ as i32,
y: mouse_y as i32,
select: shift_pressed,
});
window.request_redraw();
}
Expand Down
52 changes: 48 additions & 4 deletions src/edit/editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use unicode_segmentation::UnicodeSegmentation;
use crate::Color;
use crate::{
Action, Attrs, AttrsList, BorrowedWithFontSystem, BufferLine, BufferRef, Change, ChangeItem,
Cursor, Edit, FontSystem, LayoutRun, Selection, Shaping,
Cursor, Edit, FontSystem, LayoutRun, Motion, Selection, Shaping,
};

/// A wrapper of [`Buffer`] for easy editing
Expand Down Expand Up @@ -565,8 +565,46 @@ impl<'buffer> Edit<'buffer> for Editor<'buffer> {
let old_cursor = self.cursor;

match action {
Action::Motion(motion) => {
Action::Motion { motion, select } => {
let cursor = self.cursor;
if select {
if self.selection == Selection::None {
self.selection = Selection::Normal(self.cursor);
}
} else if let Some((start, end)) = self.selection_bounds() {
if start.line != end.line || start.index != end.index {
let new_cursor = match motion {
// These actions have special behavior when there is an active selection.
Motion::Previous => Some(start),
Motion::Next => Some(end),
Motion::Left => self
.with_buffer_mut(|buffer| {
buffer
.line_shape(font_system, cursor.line)
.map(|shape| shape.rtl)
})
.map(|rtl| if rtl { end } else { start }),
Motion::Right => self
.with_buffer_mut(|buffer| {
buffer
.line_shape(font_system, cursor.line)
.map(|shape| shape.rtl)
})
.map(|rtl| if rtl { start } else { end }),
_ => None,
};
if let Some(new_cursor) = new_cursor {
self.cursor = new_cursor;
self.cursor_x_opt = None;
self.cursor_moved = true;
self.selection = Selection::None;
self.set_redraw(true);
return;
}
}
self.selection = Selection::None;
}

let cursor_x_opt = self.cursor_x_opt;
if let Some((new_cursor, new_cursor_x_opt)) = self.with_buffer_mut(|buffer| {
buffer.cursor_motion(font_system, cursor, cursor_x_opt, motion)
Expand Down Expand Up @@ -807,8 +845,14 @@ impl<'buffer> Edit<'buffer> for Editor<'buffer> {
self.with_buffer_mut(|buffer| buffer.set_redraw(true));
}
}
Action::Click { x, y } => {
self.set_selection(Selection::None);
Action::Click { x, y, select } => {
if select {
if self.selection == Selection::None {
self.selection = Selection::Normal(self.cursor);
}
} else {
self.selection = Selection::None;
}

if let Some(new_cursor) = self.with_buffer(|buffer| buffer.hit(x as f32, y as f32))
{
Expand Down
6 changes: 5 additions & 1 deletion src/edit/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ mod vi;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Action {
/// Move the cursor with some motion
Motion(Motion),
Motion {
motion: Motion,
select: bool,
},
/// Escape, clears selection
Escape,
/// Insert character at cursor
Expand All @@ -42,6 +45,7 @@ pub enum Action {
Click {
x: i32,
y: i32,
select: bool,
},
/// Mouse double click at specified position
DoubleClick {
Expand Down
Loading
Loading