type-render
korin 3 years ago
parent bf803eaf75
commit b02c1deb79
  1. 39
      src/input.rs
  2. 162
      src/main.rs
  3. 120
      src/render.rs
  4. 2
      src/syntax-highlight.rs

@ -1,5 +1,6 @@
use sdl2::keyboard::Keycode; //use sdl2::keyboard::Keycode;
/*
mod keybinds { mod keybinds {
pub(super) enum Clipboard { pub(super) enum Clipboard {
CutSelection, CutSelection,
@ -42,7 +43,41 @@ mod keybinds {
WholeLines, WholeLines,
} }
} }
*/
fn process_input(buffer: &str, modifiers: crate::ModifierKeys, key: Keycode) { pub struct ModifierKeys {
pub alt: bool,
pub ctrl: bool,
pub shift: bool,
}
impl ModifierKeys {
pub fn new() -> ModifierKeys {
ModifierKeys { alt: false, ctrl: false, shift: false }
}
}
pub fn delete(buffer: &mut String, cursor_position: usize, modifiers: &ModifierKeys) {
if modifiers.ctrl {
loop {
let buffer_chars: Vec<char> = buffer.chars()
.collect();
if cursor_position == buffer.len() {
break
}
if !buffer_chars[cursor_position].is_whitespace() {
buffer.remove(cursor_position);
} else {
break
}
}
} else {
buffer.remove(cursor_position);
}
}
/*
fn process_input(buffer: &str, modifiers: ModifierKeys, key: Keycode) {
} }
*/

@ -1,31 +1,25 @@
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;
// TODO: Make this configurable // TODO: Make this configurable
static REFRESH_RATE: u32 = 50; static REFRESH_RATE: u32 = 50;
// TODO: Make this configurable // TODO: Make this configurable
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,38 +76,32 @@ 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
}, // DELETE key
Some(Keycode::LShift) | Some(Keycode::RShift) => { Some(Keycode::Delete) => {
modifier_keys.shift = true if buffer.len() > 0 && cursor_position < buffer.len() {
}, undo_timer = 0;
Some(Keycode::LGui) | Some(Keycode::RGui) => { selection_anchor = None;
break input::delete(&mut buffer, cursor_position, &modifier_keys);
},
draw!();
}
}
_ => (), _ => (),
}; };
@ -121,18 +109,6 @@ pub fn main() -> Result<(), String> {
// All modifiers up // All modifiers up
(false, false, false) => { (false, false, false) => {
match keycode { match keycode {
// DELETE key
Some(Keycode::Delete) => {
if buffer.len() > 0 && cursor_position < buffer.len() {
undo_timer = 0;
selection_anchor = None;
buffer.remove(cursor_position);
draw!();
}
},
// 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,48 +228,46 @@ 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;
} }
buffer.remove(cursor_position - 1); buffer.remove(cursor_position - 1);
cursor_position -= 1; cursor_position -= 1;
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; let last_redo = undo_history[undo_position - 1].clone();
let last_redo = undo_history[undo_position - 1].clone(); buffer = last_redo.0;
buffer = last_redo.0; cursor_position = last_redo.1;
cursor_position = last_redo.1;
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!();
}, }
_ => {} _ => {}
} }

@ -16,7 +16,7 @@ use crate::file;
type Glyph = Vec<Point>; type Glyph = Vec<Point>;
struct GlyphMetrics { struct GlyphMetrics {
width: usize, width: usize,
height: usize, height: usize,
} }
@ -64,20 +64,20 @@ enum Colors {
impl Colors { impl Colors {
fn color(&self) -> ColorRGB { fn color(&self) -> ColorRGB {
match self { match self {
Colors::Background => ColorRGB::new( 32, 32, 32), Colors::Background => ColorRGB::new(32, 32, 32),
Colors::Foreground => ColorRGB::new(255, 255, 255), Colors::Foreground => ColorRGB::new(255, 255, 255),
Colors::Error => ColorRGB::new(255, 0, 0), Colors::Error => ColorRGB::new(255, 0, 0),
Colors::Warning => ColorRGB::new(255, 170, 0), Colors::Warning => ColorRGB::new(255, 170, 0),
Colors::FindBg => ColorRGB::new(246, 185, 63), Colors::FindBg => ColorRGB::new(246, 185, 63),
Colors::StdFunction => ColorRGB::new(170, 255, 255), Colors::StdFunction => ColorRGB::new(170, 255, 255),
Colors::Comment => ColorRGB::new( 0, 255, 0), Colors::Comment => ColorRGB::new(0, 255, 0),
Colors::Keyword => ColorRGB::new( 0, 170, 255), Colors::Keyword => ColorRGB::new(0, 170, 255),
Colors::Number => ColorRGB::new( 85, 255, 255), Colors::Number => ColorRGB::new(85, 255, 255),
Colors::Operator => ColorRGB::new(255, 85, 0), Colors::Operator => ColorRGB::new(255, 85, 0),
Colors::Preprocessor => ColorRGB::new(127, 0, 0), Colors::Preprocessor => ColorRGB::new(127, 0, 0),
Colors::SelectionBg => ColorRGB::new(110, 161, 241), Colors::SelectionBg => ColorRGB::new(110, 161, 241),
Colors::SelectionFg => ColorRGB::new(255, 255, 255), Colors::SelectionFg => ColorRGB::new(255, 255, 255),
Colors::String => ColorRGB::new(255, 85, 255), Colors::String => ColorRGB::new(255, 85, 255),
} }
} }
} }
@ -89,17 +89,20 @@ pub fn generate_glyph_data() -> Result<GlyphAtlas, String> {
let contents = file::read_file(file_path)?; let contents = file::read_file(file_path)?;
// Get glyph metrics // Get glyph metrics
let glyph_metrics = GlyphMetrics { width: 8, height: 16 }; let glyph_metrics = GlyphMetrics {
let glyph_width = glyph_metrics.width; width: 8,
height: 16,
};
let glyph_width = glyph_metrics.width;
// Get width of image for proper positioning of pixels // Get width of image for proper positioning of pixels
let width_left_byte = contents[0]; let width_left_byte = contents[0];
let width_right_byte = contents[1]; let width_right_byte = contents[1];
let width_bytes = [width_left_byte, width_right_byte]; let width_bytes = [width_left_byte, width_right_byte];
let width = u16::from_be_bytes(width_bytes); let width = u16::from_be_bytes(width_bytes);
println!("Left Byte: {width_left_byte}, Right Byte: {width_right_byte}, Byte Pair: {width}"); println!("Left Byte: {width_left_byte}, Right Byte: {width_right_byte}, Byte Pair: {width}");
let pruned_glyph_table = &contents[width as usize + 2 ..]; let pruned_glyph_table = &contents[width as usize + 2..];
// Generate the glyph atlas // Generate the glyph atlas
let mut glyph_atlas: Vec<Glyph> = vec![]; let mut glyph_atlas: Vec<Glyph> = vec![];
@ -121,15 +124,23 @@ pub fn generate_glyph_data() -> Result<GlyphAtlas, String> {
} }
glyph_atlas.push(new_glyph); glyph_atlas.push(new_glyph);
} }
Ok(GlyphAtlas { glyphs: glyph_atlas, metrics: glyph_metrics }) Ok(GlyphAtlas {
glyphs: glyph_atlas,
metrics: glyph_metrics,
})
} }
/// Method for generating points to render, using given string /// Method for generating points to render, using given string
fn draw_text(glyph_atlas: &GlyphAtlas, content: &str, offset: Point) -> Vec<Point> { fn draw_text(
glyph_atlas: &GlyphAtlas,
window_size: (u32, u32),
content: &str,
offset: Point,
) -> Vec<Point> {
let mut points: Vec<Point> = vec![]; let mut points: Vec<Point> = vec![];
let glyph_width = glyph_atlas.metrics.width; let glyph_width = glyph_atlas.metrics.width;
let glyph_height = glyph_atlas.metrics.height; let glyph_height = glyph_atlas.metrics.height;
let content_lines = content.split('\n'); let content_lines = content.split('\n');
for (y, line) in content_lines.enumerate() { for (y, line) in content_lines.enumerate() {
@ -147,20 +158,30 @@ fn draw_text(glyph_atlas: &GlyphAtlas, content: &str, offset: Point) -> Vec<Poin
let positioned_pixel = Point::new( let positioned_pixel = Point::new(
pixel.x + x_glyph as i32 + offset.x, pixel.x + x_glyph as i32 + offset.x,
pixel.y + y_glyph as i32 + offset.y pixel.y + y_glyph as i32 + offset.y,
); );
points.push(positioned_pixel); points.push(positioned_pixel);
} }
// TODO: Limit X drawing
if x >= (window_size.0 as usize / glyph_width) - 3 {
break;
}
}
if y >= (window_size.1 as usize / glyph_height) - 3 {
break;
} }
// TODO: Limit Y drawing
} }
points points
} }
pub fn draw_cursor(glyph_atlas: &GlyphAtlas, mut cursor_position: usize, content: &str, offset: Point) -> (Point, Point) { pub fn draw_cursor(
let glyph_width = glyph_atlas.metrics.width; glyph_atlas: &GlyphAtlas,
let glyph_height = glyph_atlas.metrics.height; mut cursor_position: usize,
content: &str,
offset: Point,
) -> (Point, Point) {
let glyph_width = glyph_atlas.metrics.width;
let glyph_height = glyph_atlas.metrics.height;
let mut x = 0; let mut x = 0;
let mut y = 0; let mut y = 0;
@ -173,24 +194,28 @@ pub fn draw_cursor(glyph_atlas: &GlyphAtlas, mut cursor_position: usize, content
y += 1; y += 1;
} }
if idx == cursor_position { if idx == cursor_position {
let point_a = Point::new((x * glyph_width) as i32 + offset.x, let point_a = Point::new(
(y * glyph_height) as i32 + offset.y (x * glyph_width) as i32 + offset.x,
); (y * glyph_height) as i32 + offset.y,
let point_b = Point::new(point_a.x,
point_a.y + glyph_height as i32
); );
return (point_a, point_b) let point_b = Point::new(point_a.x, point_a.y + glyph_height as i32);
return (point_a, point_b);
} }
} }
} }
(Point::new(offset.x, offset.y), Point::new(offset.x, offset.y + glyph_height as i32)) (
Point::new(offset.x, offset.y),
Point::new(offset.x, offset.y + glyph_height as i32),
)
} }
/// Draw all contents to the window /// Draw all contents to the window
pub fn draw_everything(canvas: &mut Canvas<Window>, pub fn draw_everything(
glyph_atlas: &GlyphAtlas, canvas: &mut Canvas<Window>,
buffer: &str, glyph_atlas: &GlyphAtlas,
cursor_position: usize) -> Result<(), String> { buffer: &str,
cursor_position: usize,
) -> Result<(), String> {
// Quick initialization // Quick initialization
let window_size = canvas.output_size()?; let window_size = canvas.output_size()?;
let text_offset = Point::new(10, 10); let text_offset = Point::new(10, 10);
@ -204,25 +229,26 @@ pub fn draw_everything(canvas: &mut Canvas<Window>,
// Draw text // Draw text
canvas.set_draw_color(Color::RGB(fg_color.red, fg_color.green, fg_color.blue)); canvas.set_draw_color(Color::RGB(fg_color.red, fg_color.green, fg_color.blue));
let fb_text = draw_text(&glyph_atlas, buffer, text_offset); let fb_text = draw_text(&glyph_atlas, window_size, buffer, text_offset);
canvas.draw_points(&fb_text[..])?; canvas.draw_points(&fb_text[..])?;
// Draw info // Draw info
let status = buffer.len().to_formatted_string(&Locale::en); let status = buffer.len().to_formatted_string(&Locale::en);
let status_position = Point::new( let status_position = Point::new(
text_offset.x, text_offset.x,
window_size.1 as i32 - glyph_atlas.metrics.height as i32 * 2 window_size.1 as i32 - glyph_atlas.metrics.height as i32 * 2,
); );
canvas.set_draw_color(Color::RGB(16, 64, 64)); canvas.set_draw_color(Color::RGB(16, 64, 64));
canvas.fill_rect(Rect::new(0, canvas.fill_rect(Rect::new(
status_position.y - 5, 0,
window_size.0, status_position.y - 5,
glyph_atlas.metrics.height as u32 + 10 window_size.0,
glyph_atlas.metrics.height as u32 + 10,
))?; ))?;
canvas.set_draw_color(Color::RGB(127, 240, 240)); canvas.set_draw_color(Color::RGB(127, 240, 240));
let status_bar = draw_text(&glyph_atlas, &status, status_position); let status_bar = draw_text(&glyph_atlas, window_size, &status, status_position);
canvas.draw_points(&status_bar[..])?; canvas.draw_points(&status_bar[..])?;
// Draw cursor // Draw cursor

@ -1,3 +1,4 @@
/*
pub enum Token { pub enum Token {
ILLEGAL, ILLEGAL,
EOF, EOF,
@ -25,6 +26,7 @@ pub enum Token {
LT(char), LT(char),
GT(char) GT(char)
} }
*/
fn find_keyword(input: &str) { fn find_keyword(input: &str) {
match input { match input {

Loading…
Cancel
Save