mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
restructuring with dedicated app_model update file
This commit is contained in:
parent
7613730ada
commit
fa2480ed4f
7 changed files with 144 additions and 126 deletions
|
@ -1,13 +1,8 @@
|
||||||
use crate::mvc;
|
|
||||||
use crate::mvc::ed_model::{EdModel, Position};
|
|
||||||
use crate::error::EdResult;
|
use crate::error::EdResult;
|
||||||
use crate::mvc::app_model::AppModel;
|
use crate::mvc::app_model::AppModel;
|
||||||
use crate::mvc::update::{
|
use crate::mvc::app_update::{pass_keydown_to_focused, handle_copy, handle_paste};
|
||||||
move_caret_down, move_caret_left, move_caret_right, move_caret_up, MoveCaretFun,
|
|
||||||
};
|
|
||||||
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
|
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
|
||||||
use winit::event::VirtualKeyCode::*;
|
use winit::event::VirtualKeyCode::*;
|
||||||
use crate::error::EdError::{ClipboardWriteFailed, ClipboardReadFailed};
|
|
||||||
|
|
||||||
pub fn handle_keydown(
|
pub fn handle_keydown(
|
||||||
elem_state: ElementState,
|
elem_state: ElementState,
|
||||||
|
@ -21,127 +16,29 @@ pub fn handle_keydown(
|
||||||
}
|
}
|
||||||
|
|
||||||
match virtual_keycode {
|
match virtual_keycode {
|
||||||
Left => pass_to_focused(app_model, &modifiers, virtual_keycode),
|
Left => pass_keydown_to_focused(&modifiers, virtual_keycode, app_model),
|
||||||
Up => pass_to_focused(app_model, &modifiers, virtual_keycode),
|
Up => pass_keydown_to_focused(&modifiers, virtual_keycode, app_model),
|
||||||
Right => pass_to_focused(app_model, &modifiers, virtual_keycode),
|
Right => pass_keydown_to_focused(&modifiers, virtual_keycode, app_model),
|
||||||
Down => pass_to_focused(app_model, &modifiers, virtual_keycode),
|
Down => pass_keydown_to_focused(&modifiers, virtual_keycode, app_model),
|
||||||
|
|
||||||
Copy => handle_copy(app_model),
|
Copy => handle_copy(app_model)?,
|
||||||
Paste => handle_paste(app_model),
|
Paste => handle_paste(app_model)?,
|
||||||
Cut => {
|
Cut => {
|
||||||
|
//handle_cut(app_model)?
|
||||||
todo!("cut");
|
todo!("cut");
|
||||||
}
|
}
|
||||||
|
|
||||||
C => if modifiers.ctrl() {
|
C => if modifiers.ctrl() {
|
||||||
handle_copy(app_model)
|
handle_copy(app_model)?
|
||||||
} else { Ok(()) },
|
},
|
||||||
V => if modifiers.ctrl() {
|
V => if modifiers.ctrl() {
|
||||||
handle_paste(app_model)
|
handle_paste(app_model)?
|
||||||
} else { Ok(()) },
|
},
|
||||||
_ => Ok(())
|
X => if modifiers.ctrl() {
|
||||||
}
|
//handle_cut(app_model)?
|
||||||
}
|
todo!("cut");
|
||||||
|
},
|
||||||
fn pass_to_focused(
|
_ => ()
|
||||||
app_model: &mut AppModel,
|
|
||||||
modifiers: &ModifiersState,
|
|
||||||
virtual_keycode: VirtualKeyCode,
|
|
||||||
) -> EdResult<()> {
|
|
||||||
if let Some(ref mut ed_model) = app_model.ed_model_opt {
|
|
||||||
if ed_model.has_focus {
|
|
||||||
match virtual_keycode {
|
|
||||||
Left => handle_arrow(move_caret_left, modifiers, ed_model),
|
|
||||||
Up => handle_arrow(move_caret_up, modifiers, ed_model),
|
|
||||||
Right => handle_arrow(move_caret_right, modifiers, ed_model),
|
|
||||||
Down => handle_arrow(move_caret_down, modifiers, ed_model),
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_arrow(move_caret_fun: MoveCaretFun, modifiers: &ModifiersState, ed_model: &mut EdModel) {
|
|
||||||
let (new_caret_pos, new_selection_opt) = move_caret_fun(
|
|
||||||
ed_model.caret_pos,
|
|
||||||
ed_model.selection_opt,
|
|
||||||
modifiers.shift(),
|
|
||||||
&ed_model.text_buf,
|
|
||||||
);
|
|
||||||
ed_model.caret_pos = new_caret_pos;
|
|
||||||
ed_model.selection_opt = new_selection_opt;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_copy(app_model: &mut AppModel) -> EdResult<()> {
|
|
||||||
if let Some(ref mut ed_model) = app_model.ed_model_opt {
|
|
||||||
if ed_model.has_focus {
|
|
||||||
let selected_str_opt = mvc::ed_model::get_selected_str(ed_model)?;
|
|
||||||
|
|
||||||
if let Some(selected_str) = selected_str_opt {
|
|
||||||
if let Some(ref mut clipboard) = app_model.clipboard_opt {
|
|
||||||
clipboard.set_content(selected_str.to_owned())?;
|
|
||||||
} else {
|
|
||||||
return Err(ClipboardWriteFailed {
|
|
||||||
err_msg: "Clipboard was never initialized succesfully.".to_owned()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_paste(app_model: &mut AppModel) -> EdResult<()> {
|
|
||||||
|
|
||||||
if let Some(ref mut ed_model) = app_model.ed_model_opt {
|
|
||||||
if ed_model.has_focus {
|
|
||||||
if let Some(ref mut clipboard) = app_model.clipboard_opt {
|
|
||||||
let clipboard_content = clipboard.get_content()?;
|
|
||||||
|
|
||||||
if !clipboard_content.is_empty() {
|
|
||||||
|
|
||||||
let mut rsplit_iter = clipboard_content.rsplit('\n');
|
|
||||||
// safe unwrap because we checked if empty
|
|
||||||
let last_line_nr_chars = rsplit_iter.next().unwrap().len();
|
|
||||||
let clipboard_nr_lines = rsplit_iter.count();
|
|
||||||
|
|
||||||
let old_caret_pos = ed_model.caret_pos;
|
|
||||||
|
|
||||||
if let Some(selection) = ed_model.selection_opt {
|
|
||||||
let start_caret_pos = selection.start_pos;
|
|
||||||
ed_model.text_buf.del_selection(selection)?;
|
|
||||||
ed_model.selection_opt = None;
|
|
||||||
|
|
||||||
ed_model.text_buf.insert_str(
|
|
||||||
start_caret_pos,
|
|
||||||
&clipboard_content
|
|
||||||
)?;
|
|
||||||
|
|
||||||
ed_model.caret_pos = Position {
|
|
||||||
line: start_caret_pos.line + clipboard_nr_lines,
|
|
||||||
column: start_caret_pos.column + last_line_nr_chars
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ed_model.text_buf.insert_str(
|
|
||||||
old_caret_pos,
|
|
||||||
&clipboard_content
|
|
||||||
)?;
|
|
||||||
|
|
||||||
ed_model.caret_pos = Position {
|
|
||||||
line: old_caret_pos.line + clipboard_nr_lines,
|
|
||||||
column: old_caret_pos.column + last_line_nr_chars
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
return Err(ClipboardReadFailed {
|
|
||||||
err_msg: "Clipboard was never initialized succesfully.".to_owned()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -25,7 +25,7 @@ use crate::graphics::style::CODE_FONT_SIZE;
|
||||||
use crate::graphics::style::CODE_TXT_XY;
|
use crate::graphics::style::CODE_TXT_XY;
|
||||||
use crate::mvc::app_model::AppModel;
|
use crate::mvc::app_model::AppModel;
|
||||||
use crate::mvc::ed_model::EdModel;
|
use crate::mvc::ed_model::EdModel;
|
||||||
use crate::mvc::{ed_model, ed_view, update};
|
use crate::mvc::{ed_model, ed_view, ed_update};
|
||||||
use crate::resources::strings::NOTHING_OPENED;
|
use crate::resources::strings::NOTHING_OPENED;
|
||||||
use crate::vec_result::get_res;
|
use crate::vec_result::get_res;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
@ -213,7 +213,7 @@ fn run_event_loop(file_path_opt: Option<&Path>) -> Result<(), Box<dyn Error>> {
|
||||||
event: event::WindowEvent::ReceivedCharacter(ch),
|
event: event::WindowEvent::ReceivedCharacter(ch),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if let Err(e) = update::handle_new_char(&mut app_model, &ch) {
|
if let Err(e) = ed_update::handle_new_char(&mut app_model, &ch) {
|
||||||
print_err(&e)
|
print_err(&e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::error::EdError::{ClipboardReadFailed, ClipboardWriteFailed, Clipboard
|
||||||
use clipboard::{ClipboardContext, ClipboardProvider};
|
use clipboard::{ClipboardContext, ClipboardProvider};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AppModel {
|
pub struct AppModel {
|
||||||
pub ed_model_opt: Option<EdModel>,
|
pub ed_model_opt: Option<EdModel>,
|
||||||
|
|
92
editor/src/mvc/app_update.rs
Normal file
92
editor/src/mvc/app_update.rs
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
use super::app_model::AppModel;
|
||||||
|
use super::ed_update;
|
||||||
|
use super::ed_model::{Position};
|
||||||
|
use crate::error::EdResult;
|
||||||
|
use crate::error::EdError::{ClipboardWriteFailed, ClipboardReadFailed};
|
||||||
|
use winit::event::{ModifiersState, VirtualKeyCode};
|
||||||
|
|
||||||
|
pub fn handle_copy(app_model: &mut AppModel) -> EdResult<()> {
|
||||||
|
if let Some(ref mut ed_model) = app_model.ed_model_opt {
|
||||||
|
if ed_model.has_focus {
|
||||||
|
let selected_str_opt = super::ed_model::get_selected_str(ed_model)?;
|
||||||
|
|
||||||
|
if let Some(selected_str) = selected_str_opt {
|
||||||
|
if let Some(ref mut clipboard) = app_model.clipboard_opt {
|
||||||
|
clipboard.set_content(selected_str.to_owned())?;
|
||||||
|
} else {
|
||||||
|
return Err(ClipboardWriteFailed {
|
||||||
|
err_msg: "Clipboard was never initialized succesfully.".to_owned()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_paste(app_model: &mut AppModel) -> EdResult<()> {
|
||||||
|
|
||||||
|
if let Some(ref mut ed_model) = app_model.ed_model_opt {
|
||||||
|
if ed_model.has_focus {
|
||||||
|
if let Some(ref mut clipboard) = app_model.clipboard_opt {
|
||||||
|
let clipboard_content = clipboard.get_content()?;
|
||||||
|
|
||||||
|
if !clipboard_content.is_empty() {
|
||||||
|
|
||||||
|
let mut rsplit_iter = clipboard_content.rsplit('\n');
|
||||||
|
// safe unwrap because we checked if empty
|
||||||
|
let last_line_nr_chars = rsplit_iter.next().unwrap().len();
|
||||||
|
let clipboard_nr_lines = rsplit_iter.count();
|
||||||
|
|
||||||
|
let old_caret_pos = ed_model.caret_pos;
|
||||||
|
|
||||||
|
if let Some(selection) = ed_model.selection_opt {
|
||||||
|
let start_caret_pos = selection.start_pos;
|
||||||
|
ed_model.text_buf.del_selection(selection)?;
|
||||||
|
ed_model.selection_opt = None;
|
||||||
|
|
||||||
|
ed_model.text_buf.insert_str(
|
||||||
|
start_caret_pos,
|
||||||
|
&clipboard_content
|
||||||
|
)?;
|
||||||
|
|
||||||
|
ed_model.caret_pos = Position {
|
||||||
|
line: start_caret_pos.line + clipboard_nr_lines,
|
||||||
|
column: start_caret_pos.column + last_line_nr_chars
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ed_model.text_buf.insert_str(
|
||||||
|
old_caret_pos,
|
||||||
|
&clipboard_content
|
||||||
|
)?;
|
||||||
|
|
||||||
|
ed_model.caret_pos = Position {
|
||||||
|
line: old_caret_pos.line + clipboard_nr_lines,
|
||||||
|
column: old_caret_pos.column + last_line_nr_chars
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return Err(ClipboardReadFailed {
|
||||||
|
err_msg: "Clipboard was never initialized succesfully.".to_owned()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pass_keydown_to_focused(
|
||||||
|
modifiers: &ModifiersState,
|
||||||
|
virtual_keycode: VirtualKeyCode,
|
||||||
|
app_model: &mut AppModel,
|
||||||
|
) {
|
||||||
|
if let Some(ref mut ed_model) = app_model.ed_model_opt {
|
||||||
|
if ed_model.has_focus {
|
||||||
|
ed_update::handle_key_down(modifiers, virtual_keycode, ed_model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,8 @@ use crate::error::EdResult;
|
||||||
use crate::text_buffer::TextBuffer;
|
use crate::text_buffer::TextBuffer;
|
||||||
use crate::util::is_newline;
|
use crate::util::is_newline;
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
|
use winit::event::{ModifiersState, VirtualKeyCode};
|
||||||
|
use winit::event::VirtualKeyCode::*;
|
||||||
|
|
||||||
pub type MoveCaretFun =
|
pub type MoveCaretFun =
|
||||||
fn(Position, Option<RawSelection>, bool, &TextBuffer) -> (Position, Option<RawSelection>);
|
fn(Position, Option<RawSelection>, bool, &TextBuffer) -> (Position, Option<RawSelection>);
|
||||||
|
@ -299,6 +301,17 @@ pub fn move_caret_down(
|
||||||
(new_caret_pos, new_selection_opt)
|
(new_caret_pos, new_selection_opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn handle_arrow(move_caret_fun: MoveCaretFun, modifiers: &ModifiersState, ed_model: &mut EdModel) {
|
||||||
|
let (new_caret_pos, new_selection_opt) = move_caret_fun(
|
||||||
|
ed_model.caret_pos,
|
||||||
|
ed_model.selection_opt,
|
||||||
|
modifiers.shift(),
|
||||||
|
&ed_model.text_buf,
|
||||||
|
);
|
||||||
|
ed_model.caret_pos = new_caret_pos;
|
||||||
|
ed_model.selection_opt = new_selection_opt;
|
||||||
|
}
|
||||||
|
|
||||||
fn del_selection(selection: RawSelection, ed_model: &mut EdModel) -> EdResult<()> {
|
fn del_selection(selection: RawSelection, ed_model: &mut EdModel) -> EdResult<()> {
|
||||||
ed_model.text_buf.del_selection(selection)?;
|
ed_model.text_buf.del_selection(selection)?;
|
||||||
ed_model.caret_pos = selection.start_pos;
|
ed_model.caret_pos = selection.start_pos;
|
||||||
|
@ -340,7 +353,7 @@ pub fn handle_new_char(app_model: &mut AppModel, received_char: &char) -> EdResu
|
||||||
|
|
||||||
ed_model.selection_opt = None;
|
ed_model.selection_opt = None;
|
||||||
}
|
}
|
||||||
'\u{0}'..='\u{32}' | '\u{e000}'..='\u{f8ff}' | '\u{f0000}'..='\u{ffffd}' | '\u{100000}'..='\u{10fffd}' => {
|
'\u{3}' | '\u{16}' | '\u{30}' | '\u{e000}'..='\u{f8ff}' | '\u{f0000}'..='\u{ffffd}' | '\u{100000}'..='\u{10fffd}' => {
|
||||||
// chars that can be ignored
|
// chars that can be ignored
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -371,11 +384,25 @@ pub fn handle_new_char(app_model: &mut AppModel, received_char: &char) -> EdResu
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn handle_key_down(
|
||||||
|
modifiers: &ModifiersState,
|
||||||
|
virtual_keycode: VirtualKeyCode,
|
||||||
|
ed_model: &mut EdModel
|
||||||
|
) {
|
||||||
|
match virtual_keycode {
|
||||||
|
Left => handle_arrow(move_caret_left, modifiers, ed_model),
|
||||||
|
Up => handle_arrow(move_caret_up, modifiers, ed_model),
|
||||||
|
Right => handle_arrow(move_caret_right, modifiers, ed_model),
|
||||||
|
Down => handle_arrow(move_caret_down, modifiers, ed_model),
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_update {
|
mod test_update {
|
||||||
use crate::mvc::app_model::AppModel;
|
use crate::mvc::app_model::AppModel;
|
||||||
use crate::mvc::ed_model::{EdModel, Position, RawSelection};
|
use crate::mvc::ed_model::{EdModel, Position, RawSelection};
|
||||||
use crate::mvc::update::handle_new_char;
|
use crate::mvc::ed_update::handle_new_char;
|
||||||
use crate::selection::test_selection::{
|
use crate::selection::test_selection::{
|
||||||
all_lines_vec, convert_dsl_to_selection, convert_selection_to_dsl, text_buffer_from_dsl_str,
|
all_lines_vec, convert_dsl_to_selection, convert_selection_to_dsl, text_buffer_from_dsl_str,
|
||||||
};
|
};
|
|
@ -1,4 +1,5 @@
|
||||||
pub mod app_model;
|
pub mod app_model;
|
||||||
|
pub mod app_update;
|
||||||
pub mod ed_model;
|
pub mod ed_model;
|
||||||
pub mod ed_view;
|
pub mod ed_view;
|
||||||
pub mod update;
|
pub mod ed_update;
|
||||||
|
|
|
@ -126,7 +126,7 @@ pub fn create_selection_rects<'a>(
|
||||||
pub mod test_selection {
|
pub mod test_selection {
|
||||||
use crate::error::{EdResult, OutOfBounds};
|
use crate::error::{EdResult, OutOfBounds};
|
||||||
use crate::mvc::ed_model::{Position, RawSelection};
|
use crate::mvc::ed_model::{Position, RawSelection};
|
||||||
use crate::mvc::update::{
|
use crate::mvc::ed_update::{
|
||||||
move_caret_down, move_caret_left, move_caret_right, move_caret_up, MoveCaretFun,
|
move_caret_down, move_caret_left, move_caret_right, move_caret_up, MoveCaretFun,
|
||||||
};
|
};
|
||||||
use crate::text_buffer::TextBuffer;
|
use crate::text_buffer::TextBuffer;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue