mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-22 08:17:40 +03:00
implemented selection with up and down arrows, closes #776
This commit is contained in:
parent
f67c4324d4
commit
2b0a320734
@ -1,6 +1,6 @@
|
||||
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
|
||||
use crate::tea::model::{Model};
|
||||
use crate::tea::update::{move_caret_left, move_caret_right};
|
||||
use crate::tea::update::{move_caret_left, move_caret_right, move_caret_down, move_caret_up};
|
||||
|
||||
pub fn handle_keydown(
|
||||
elem_state: ElementState,
|
||||
@ -21,7 +21,9 @@ pub fn handle_keydown(
|
||||
model.selection_opt = new_selection_opt;
|
||||
},
|
||||
Up => {
|
||||
todo!("arrow up");
|
||||
let (new_caret_pos, new_selection_opt) = move_caret_up(model.caret_pos, model.selection_opt, modifiers.shift(), &model.lines);
|
||||
model.caret_pos = new_caret_pos;
|
||||
model.selection_opt = new_selection_opt;
|
||||
},
|
||||
Right => {
|
||||
let (new_caret_pos, new_selection_opt) = move_caret_right(model.caret_pos, model.selection_opt, modifiers.shift(), &model.lines);
|
||||
@ -29,7 +31,9 @@ pub fn handle_keydown(
|
||||
model.selection_opt = new_selection_opt;
|
||||
},
|
||||
Down => {
|
||||
todo!("arrow down");
|
||||
let (new_caret_pos, new_selection_opt) = move_caret_down(model.caret_pos, model.selection_opt, modifiers.shift(), &model.lines);
|
||||
model.caret_pos = new_caret_pos;
|
||||
model.selection_opt = new_selection_opt;
|
||||
},
|
||||
Copy => {
|
||||
todo!("copy");
|
||||
|
@ -1,3 +1,6 @@
|
||||
|
||||
use std::cmp::{Ordering};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Model {
|
||||
pub lines: Vec<String>,
|
||||
@ -25,6 +28,26 @@ pub struct Position {
|
||||
pub column: usize
|
||||
}
|
||||
|
||||
impl Ord for Position {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
(self.line, self.column).cmp(&(other.line, other.column))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for Position {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq for Position {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
(self.line, self.column) == (other.line, other.column)
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Position { }
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct RawSelection {
|
||||
pub start_pos: Position,
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
use crate::tea::model::{Position, RawSelection};
|
||||
use crate::text::{is_newline};
|
||||
use std::cmp::{min, max};
|
||||
|
||||
pub fn move_caret_left(old_caret_pos: Position, old_selection_opt: Option<RawSelection>, shift_pressed: bool, lines: &[String]) -> (Position, Option<RawSelection>) {
|
||||
let old_line_nr = old_caret_pos.line;
|
||||
@ -19,6 +20,11 @@ pub fn move_caret_left(old_caret_pos: Position, old_selection_opt: Option<RawSel
|
||||
(old_line_nr, old_col_nr - 1)
|
||||
};
|
||||
|
||||
let new_caret_pos = Position {
|
||||
line: line_nr,
|
||||
column: col_nr
|
||||
};
|
||||
|
||||
let new_selection_opt =
|
||||
if shift_pressed {
|
||||
if let Some(old_selection) = old_selection_opt {
|
||||
@ -62,10 +68,7 @@ pub fn move_caret_left(old_caret_pos: Position, old_selection_opt: Option<RawSel
|
||||
|
||||
|
||||
(
|
||||
Position {
|
||||
line: line_nr,
|
||||
column: col_nr
|
||||
},
|
||||
new_caret_pos,
|
||||
new_selection_opt
|
||||
)
|
||||
}
|
||||
@ -95,6 +98,11 @@ pub fn move_caret_right(old_caret_pos: Position, old_selection_opt: Option<RawSe
|
||||
(0, 0) // this should never happen, should this method return Result?
|
||||
};
|
||||
|
||||
let new_caret_pos = Position {
|
||||
line: line_nr,
|
||||
column: col_nr
|
||||
};
|
||||
|
||||
let new_selection_opt =
|
||||
if shift_pressed {
|
||||
if let Some(old_selection) = old_selection_opt {
|
||||
@ -137,10 +145,136 @@ pub fn move_caret_right(old_caret_pos: Position, old_selection_opt: Option<RawSe
|
||||
};
|
||||
|
||||
(
|
||||
Position {
|
||||
new_caret_pos,
|
||||
new_selection_opt
|
||||
)
|
||||
}
|
||||
|
||||
pub fn move_caret_up(old_caret_pos: Position, old_selection_opt: Option<RawSelection>, shift_pressed: bool, lines: &[String]) -> (Position, Option<RawSelection>) {
|
||||
let old_line_nr = old_caret_pos.line;
|
||||
let old_col_nr = old_caret_pos.column;
|
||||
|
||||
let (line_nr, col_nr) =
|
||||
if old_line_nr == 0 {
|
||||
(old_line_nr, old_col_nr)
|
||||
} else if let Some(prev_line) = lines.get(old_line_nr - 1) {
|
||||
if prev_line.len() < old_col_nr {
|
||||
(old_line_nr - 1, prev_line.len() - 1)
|
||||
} else {
|
||||
(old_line_nr - 1, old_col_nr)
|
||||
}
|
||||
} else {
|
||||
(0, 0) // this should never happen, should this method return Result?
|
||||
};
|
||||
|
||||
let new_caret_pos = Position {
|
||||
line: line_nr,
|
||||
column: col_nr
|
||||
},
|
||||
};
|
||||
|
||||
let new_selection_opt =
|
||||
if shift_pressed {
|
||||
if let Some(old_selection) = old_selection_opt {
|
||||
Some(
|
||||
RawSelection {
|
||||
start_pos:
|
||||
new_caret_pos
|
||||
,
|
||||
end_pos:
|
||||
old_selection.end_pos
|
||||
,
|
||||
}
|
||||
)
|
||||
} else if !(old_line_nr == line_nr && old_col_nr == col_nr){
|
||||
Some(
|
||||
RawSelection {
|
||||
start_pos:
|
||||
min(old_caret_pos, new_caret_pos)
|
||||
,
|
||||
end_pos:
|
||||
max(old_caret_pos, new_caret_pos)
|
||||
,
|
||||
}
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(
|
||||
new_caret_pos,
|
||||
new_selection_opt
|
||||
)
|
||||
}
|
||||
|
||||
pub fn move_caret_down(old_caret_pos: Position, old_selection_opt: Option<RawSelection>, shift_pressed: bool, lines: &[String]) -> (Position, Option<RawSelection>) {
|
||||
let old_line_nr = old_caret_pos.line;
|
||||
let old_col_nr = old_caret_pos.column;
|
||||
|
||||
let (line_nr, col_nr) =
|
||||
if old_line_nr + 1 >= lines.len() {
|
||||
(old_line_nr, old_col_nr)
|
||||
} else if let Some(next_line) = lines.get(old_line_nr + 1) {
|
||||
if next_line.len() < old_col_nr {
|
||||
if let Some(last_char) = next_line.chars().last() {
|
||||
if is_newline(&last_char) {
|
||||
(old_line_nr + 1, next_line.len() - 1)
|
||||
} else {
|
||||
(old_line_nr + 1, next_line.len())
|
||||
}
|
||||
} else {
|
||||
(old_line_nr + 1, 0)
|
||||
}
|
||||
|
||||
} else {
|
||||
(old_line_nr + 1, old_col_nr)
|
||||
}
|
||||
} else {
|
||||
(0, 0) // this should never happen, should this method return Result?
|
||||
};
|
||||
|
||||
let new_caret_pos = Position {
|
||||
line: line_nr,
|
||||
column: col_nr
|
||||
};
|
||||
|
||||
let new_selection_opt =
|
||||
if shift_pressed {
|
||||
if let Some(old_selection) = old_selection_opt {
|
||||
Some(
|
||||
RawSelection {
|
||||
start_pos:
|
||||
old_selection.start_pos
|
||||
,
|
||||
end_pos:
|
||||
new_caret_pos
|
||||
,
|
||||
}
|
||||
)
|
||||
} else if !(old_line_nr == line_nr && old_col_nr == col_nr){
|
||||
Some(
|
||||
RawSelection {
|
||||
start_pos:
|
||||
min(old_caret_pos, new_caret_pos)
|
||||
,
|
||||
end_pos:
|
||||
max(old_caret_pos, new_caret_pos)
|
||||
,
|
||||
}
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(
|
||||
new_caret_pos,
|
||||
new_selection_opt
|
||||
)
|
||||
}
|
Loading…
Reference in New Issue
Block a user