restructuring with dedicated app_model update file

This commit is contained in:
Anton-4 2021-01-29 16:12:56 +01:00
parent 7613730ada
commit fa2480ed4f
7 changed files with 144 additions and 126 deletions

View file

@ -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(())

View file

@ -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)
} }
} }

View file

@ -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>,

View 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);
}
}
}

View file

@ -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,
}; };

View file

@ -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;

View file

@ -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;