|
|
|
@ -1,14 +1,14 @@ |
|
|
|
extern crate sdl2; |
|
|
|
extern crate sdl2; |
|
|
|
|
|
|
|
|
|
|
|
use clipboard::{ClipboardProvider, ClipboardContext}; |
|
|
|
use clipboard::{ClipboardContext, ClipboardProvider}; |
|
|
|
use sdl2::{ |
|
|
|
use sdl2::{ |
|
|
|
event::{Event, WindowEvent}, |
|
|
|
event::{Event, WindowEvent}, |
|
|
|
keyboard::Keycode, |
|
|
|
keyboard::Keycode, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
mod render; |
|
|
|
|
|
|
|
mod input; |
|
|
|
|
|
|
|
mod file; |
|
|
|
mod file; |
|
|
|
|
|
|
|
mod input; |
|
|
|
|
|
|
|
mod render; |
|
|
|
|
|
|
|
|
|
|
|
static SCREEN_WIDTH: u32 = 1280; |
|
|
|
static SCREEN_WIDTH: u32 = 1280; |
|
|
|
static SCREEN_HEIGHT: u32 = 720; |
|
|
|
static SCREEN_HEIGHT: u32 = 720; |
|
|
|
@ -20,12 +20,6 @@ static REFRESH_RATE: u32 = 50; |
|
|
|
static UNDO_TIME: u32 = 250; |
|
|
|
static UNDO_TIME: u32 = 250; |
|
|
|
static UNDO_TIME_COUNT: u32 = (REFRESH_RATE as f32 * (UNDO_TIME as f32 / 1000.0)) as u32; |
|
|
|
static UNDO_TIME_COUNT: u32 = (REFRESH_RATE as f32 * (UNDO_TIME as f32 / 1000.0)) as u32; |
|
|
|
|
|
|
|
|
|
|
|
struct ModifierKeys { |
|
|
|
|
|
|
|
alt: bool, |
|
|
|
|
|
|
|
ctrl: bool, |
|
|
|
|
|
|
|
shift: bool, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pub fn main() -> Result<(), String> { |
|
|
|
pub fn main() -> Result<(), String> { |
|
|
|
// Initialize clipboard
|
|
|
|
// Initialize clipboard
|
|
|
|
let mut clipboard_context: ClipboardContext = ClipboardProvider::new().unwrap(); |
|
|
|
let mut clipboard_context: ClipboardContext = ClipboardProvider::new().unwrap(); |
|
|
|
@ -53,7 +47,7 @@ pub fn main() -> Result<(), String> { |
|
|
|
let mut undo_timer: u32 = UNDO_TIME_COUNT; |
|
|
|
let mut undo_timer: u32 = UNDO_TIME_COUNT; |
|
|
|
|
|
|
|
|
|
|
|
// Initialize input values
|
|
|
|
// Initialize input values
|
|
|
|
let mut modifier_keys = ModifierKeys {alt: false, ctrl: false, shift: false}; |
|
|
|
let mut modifier_keys = input::ModifierKeys::new(); |
|
|
|
let mut cursor_position = 0; |
|
|
|
let mut cursor_position = 0; |
|
|
|
let mut selection_anchor: Option<usize> = None; |
|
|
|
let mut selection_anchor: Option<usize> = None; |
|
|
|
|
|
|
|
|
|
|
|
@ -82,57 +76,39 @@ pub fn main() -> Result<(), String> { |
|
|
|
// Event::KeyDown { keycode: Some(Keycode::Escape), .. } |
|
|
|
|
// Event::KeyDown { keycode: Some(Keycode::Escape), .. } |
|
|
|
|
Event::Quit { .. } => break 'mainloop, |
|
|
|
Event::Quit { .. } => break 'mainloop, |
|
|
|
|
|
|
|
|
|
|
|
Event::KeyUp { keycode, .. } => { |
|
|
|
Event::KeyUp { keycode, .. } => match keycode { |
|
|
|
match keycode{ |
|
|
|
Some(Keycode::LAlt) | Some(Keycode::RAlt) => modifier_keys.alt = false, |
|
|
|
Some(Keycode::LAlt) | Some(Keycode::RAlt) => { |
|
|
|
Some(Keycode::LCtrl) | Some(Keycode::RCtrl) => modifier_keys.ctrl = false, |
|
|
|
modifier_keys.alt = false |
|
|
|
Some(Keycode::LShift) | Some(Keycode::RShift) => modifier_keys.shift = false, |
|
|
|
}, |
|
|
|
Some(Keycode::LGui) | Some(Keycode::RGui) => break, |
|
|
|
Some(Keycode::LCtrl) | Some(Keycode::RCtrl) => { |
|
|
|
|
|
|
|
modifier_keys.ctrl = false |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Some(Keycode::LShift) | Some(Keycode::RShift) => { |
|
|
|
|
|
|
|
modifier_keys.shift = false |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Some(Keycode::LGui) | Some(Keycode::RGui) => { |
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
_ => (), |
|
|
|
_ => (), |
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
Event::KeyDown { keycode, .. } => { |
|
|
|
Event::KeyDown { keycode, .. } => { |
|
|
|
match keycode { |
|
|
|
match keycode { |
|
|
|
Some(Keycode::LAlt) | Some(Keycode::RAlt) => { |
|
|
|
Some(Keycode::LAlt) | Some(Keycode::RAlt) => modifier_keys.alt = true, |
|
|
|
modifier_keys.alt = true |
|
|
|
Some(Keycode::LCtrl) | Some(Keycode::RCtrl) => modifier_keys.ctrl = true, |
|
|
|
}, |
|
|
|
Some(Keycode::LShift) | Some(Keycode::RShift) => modifier_keys.shift = true, |
|
|
|
Some(Keycode::LCtrl) | Some(Keycode::RCtrl) => { |
|
|
|
Some(Keycode::LGui) | Some(Keycode::RGui) => break, |
|
|
|
modifier_keys.ctrl = true |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Some(Keycode::LShift) | Some(Keycode::RShift) => { |
|
|
|
|
|
|
|
modifier_keys.shift = true |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
Some(Keycode::LGui) | Some(Keycode::RGui) => { |
|
|
|
|
|
|
|
break
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
_ => (), |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
match (modifier_keys.shift, modifier_keys.ctrl, modifier_keys.alt) { |
|
|
|
|
|
|
|
// All modifiers up
|
|
|
|
|
|
|
|
(false, false, false) => { |
|
|
|
|
|
|
|
match keycode { |
|
|
|
|
|
|
|
// DELETE key
|
|
|
|
// DELETE key
|
|
|
|
Some(Keycode::Delete) => { |
|
|
|
Some(Keycode::Delete) => { |
|
|
|
if buffer.len() > 0 && cursor_position < buffer.len() { |
|
|
|
if buffer.len() > 0 && cursor_position < buffer.len() { |
|
|
|
undo_timer = 0; |
|
|
|
undo_timer = 0; |
|
|
|
selection_anchor = None; |
|
|
|
selection_anchor = None; |
|
|
|
|
|
|
|
input::delete(&mut buffer, cursor_position, &modifier_keys); |
|
|
|
buffer.remove(cursor_position); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
draw!(); |
|
|
|
draw!(); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_ => (), |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
match (modifier_keys.shift, modifier_keys.ctrl, modifier_keys.alt) { |
|
|
|
|
|
|
|
// All modifiers up
|
|
|
|
|
|
|
|
(false, false, false) => { |
|
|
|
|
|
|
|
match keycode { |
|
|
|
// ENTER key
|
|
|
|
// ENTER key
|
|
|
|
Some(Keycode::Return) => { |
|
|
|
Some(Keycode::Return) => { |
|
|
|
undo_timer = 0; |
|
|
|
undo_timer = 0; |
|
|
|
@ -143,7 +119,7 @@ pub fn main() -> Result<(), String> { |
|
|
|
cursor_position += 1; |
|
|
|
cursor_position += 1; |
|
|
|
|
|
|
|
|
|
|
|
draw!(); |
|
|
|
draw!(); |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// HOME key
|
|
|
|
// HOME key
|
|
|
|
Some(Keycode::Home) => { |
|
|
|
Some(Keycode::Home) => { |
|
|
|
@ -152,7 +128,7 @@ pub fn main() -> Result<(), String> { |
|
|
|
cursor_position = 0; |
|
|
|
cursor_position = 0; |
|
|
|
|
|
|
|
|
|
|
|
draw!(); |
|
|
|
draw!(); |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// END key
|
|
|
|
// END key
|
|
|
|
Some(Keycode::End) => { |
|
|
|
Some(Keycode::End) => { |
|
|
|
@ -161,17 +137,17 @@ pub fn main() -> Result<(), String> { |
|
|
|
cursor_position = buffer.len(); |
|
|
|
cursor_position = buffer.len(); |
|
|
|
|
|
|
|
|
|
|
|
draw!(); |
|
|
|
draw!(); |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Left/Back arrow
|
|
|
|
// Left/Back arrow
|
|
|
|
Some(Keycode::Left) => { |
|
|
|
Some(Keycode::Left) => { |
|
|
|
selection_anchor = None; |
|
|
|
selection_anchor = None; |
|
|
|
|
|
|
|
|
|
|
|
cursor_position = usize::checked_sub(cursor_position, 1) |
|
|
|
cursor_position = |
|
|
|
.unwrap_or(0); |
|
|
|
usize::checked_sub(cursor_position, 1).unwrap_or(0); |
|
|
|
|
|
|
|
|
|
|
|
draw!(); |
|
|
|
draw!(); |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Right/Forward arrow
|
|
|
|
// Right/Forward arrow
|
|
|
|
Some(Keycode::Right) => { |
|
|
|
Some(Keycode::Right) => { |
|
|
|
@ -180,7 +156,7 @@ pub fn main() -> Result<(), String> { |
|
|
|
cursor_position = (cursor_position + 1).min(buffer.len()); |
|
|
|
cursor_position = (cursor_position + 1).min(buffer.len()); |
|
|
|
|
|
|
|
|
|
|
|
draw!(); |
|
|
|
draw!(); |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// BACKSPACE key
|
|
|
|
// BACKSPACE key
|
|
|
|
// Character backspace
|
|
|
|
// Character backspace
|
|
|
|
@ -194,11 +170,11 @@ pub fn main() -> Result<(), String> { |
|
|
|
|
|
|
|
|
|
|
|
draw!(); |
|
|
|
draw!(); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_ => (), |
|
|
|
_ => (), |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// CTRL down
|
|
|
|
// CTRL down
|
|
|
|
(false, true, false) => { |
|
|
|
(false, true, false) => { |
|
|
|
@ -209,7 +185,7 @@ pub fn main() -> Result<(), String> { |
|
|
|
cursor_position = 0; |
|
|
|
cursor_position = 0; |
|
|
|
|
|
|
|
|
|
|
|
draw!() |
|
|
|
draw!() |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Undo
|
|
|
|
// Undo
|
|
|
|
Some(Keycode::Z) => { |
|
|
|
Some(Keycode::Z) => { |
|
|
|
@ -221,7 +197,7 @@ pub fn main() -> Result<(), String> { |
|
|
|
|
|
|
|
|
|
|
|
draw!() |
|
|
|
draw!() |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// TODO: Cut
|
|
|
|
// TODO: Cut
|
|
|
|
Some(Keycode::X) => println!("Cut"), |
|
|
|
Some(Keycode::X) => println!("Cut"), |
|
|
|
@ -230,7 +206,7 @@ pub fn main() -> Result<(), String> { |
|
|
|
// TODO: Use selection
|
|
|
|
// TODO: Use selection
|
|
|
|
Some(Keycode::C) => { |
|
|
|
Some(Keycode::C) => { |
|
|
|
clipboard_context.set_contents(buffer.clone()).unwrap() |
|
|
|
clipboard_context.set_contents(buffer.clone()).unwrap() |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Paste
|
|
|
|
// Paste
|
|
|
|
Some(Keycode::V) => { |
|
|
|
Some(Keycode::V) => { |
|
|
|
@ -242,7 +218,7 @@ pub fn main() -> Result<(), String> { |
|
|
|
undo_timer = UNDO_TIME_COUNT; |
|
|
|
undo_timer = UNDO_TIME_COUNT; |
|
|
|
} |
|
|
|
} |
|
|
|
draw!() |
|
|
|
draw!() |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// BACKSPACE key
|
|
|
|
// BACKSPACE key
|
|
|
|
// Word backspace
|
|
|
|
// Word backspace
|
|
|
|
@ -252,11 +228,11 @@ pub fn main() -> Result<(), String> { |
|
|
|
undo_timer = 0; |
|
|
|
undo_timer = 0; |
|
|
|
selection_anchor = None; |
|
|
|
selection_anchor = None; |
|
|
|
|
|
|
|
|
|
|
|
let buffer_chars: Vec<char> = buffer.chars() |
|
|
|
let buffer_chars: Vec<char> = buffer.chars().collect(); |
|
|
|
.collect(); |
|
|
|
while !(buffer_chars[cursor_position - 1] == ' ' |
|
|
|
while !(buffer_chars[cursor_position - 1] == ' ' || |
|
|
|
|| buffer_chars[cursor_position - 1] == '\n') |
|
|
|
buffer_chars[cursor_position - 1] == '\n') && |
|
|
|
&& cursor_position > 1 |
|
|
|
cursor_position > 1 { |
|
|
|
{ |
|
|
|
buffer.remove(cursor_position - 1); |
|
|
|
buffer.remove(cursor_position - 1); |
|
|
|
cursor_position -= 1; |
|
|
|
cursor_position -= 1; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -265,14 +241,13 @@ pub fn main() -> Result<(), String> { |
|
|
|
|
|
|
|
|
|
|
|
draw!() |
|
|
|
draw!() |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
_ => (), |
|
|
|
_ => (), |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// SHIFT + CTRL down
|
|
|
|
// SHIFT + CTRL down
|
|
|
|
(true, true, false) => { |
|
|
|
(true, true, false) => match keycode { |
|
|
|
match keycode { |
|
|
|
|
|
|
|
Some(Keycode::Z) => { |
|
|
|
Some(Keycode::Z) => { |
|
|
|
if undo_position < undo_history.len() { |
|
|
|
if undo_position < undo_history.len() { |
|
|
|
undo_position += 1; |
|
|
|
undo_position += 1; |
|
|
|
@ -282,18 +257,17 @@ pub fn main() -> Result<(), String> { |
|
|
|
|
|
|
|
|
|
|
|
draw!(); |
|
|
|
draw!(); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Some(Keycode::X) => println!("Cut line(s)"), |
|
|
|
Some(Keycode::X) => println!("Cut line(s)"), |
|
|
|
|
|
|
|
|
|
|
|
Some(Keycode::C) => println!("Copy line(s)"), |
|
|
|
Some(Keycode::C) => println!("Copy line(s)"), |
|
|
|
_ => (), |
|
|
|
_ => (), |
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
_ => (), |
|
|
|
_ => (), |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Process user input
|
|
|
|
// Process user input
|
|
|
|
Event::TextInput { text, .. } => { |
|
|
|
Event::TextInput { text, .. } => { |
|
|
|
@ -305,7 +279,7 @@ pub fn main() -> Result<(), String> { |
|
|
|
cursor_position += 1; |
|
|
|
cursor_position += 1; |
|
|
|
|
|
|
|
|
|
|
|
draw!(); |
|
|
|
draw!(); |
|
|
|
}, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
_ => {} |
|
|
|
_ => {} |
|
|
|
} |
|
|
|
} |
|
|
|
|