mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
rustfmt, renamed caret to txt_cursor
This commit is contained in:
parent
2b0a320734
commit
bae3db0616
11 changed files with 430 additions and 509 deletions
|
@ -87,7 +87,7 @@ pub struct RectBuffers {
|
||||||
pub fn create_rect_buffers(
|
pub fn create_rect_buffers(
|
||||||
gpu_device: &wgpu::Device,
|
gpu_device: &wgpu::Device,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
rects: &[Rect]
|
rects: &[Rect],
|
||||||
) -> RectBuffers {
|
) -> RectBuffers {
|
||||||
let nr_of_rects = rects.len() as u64;
|
let nr_of_rects = rects.len() as u64;
|
||||||
|
|
||||||
|
@ -113,9 +113,7 @@ pub fn create_rect_buffers(
|
||||||
quad_buffer_builder = quad_buffer_builder.push_rect(&rect);
|
quad_buffer_builder = quad_buffer_builder.push_rect(&rect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let (stg_vertex, stg_index, num_indices) = quad_buffer_builder.build(&gpu_device);
|
||||||
let (stg_vertex, stg_index, num_indices) =
|
|
||||||
quad_buffer_builder.build(&gpu_device);
|
|
||||||
|
|
||||||
stg_vertex.copy_to_buffer(encoder, &vertex_buffer);
|
stg_vertex.copy_to_buffer(encoder, &vertex_buffer);
|
||||||
stg_index.copy_to_buffer(encoder, &index_buffer);
|
stg_index.copy_to_buffer(encoder, &index_buffer);
|
||||||
|
|
|
@ -1,2 +1 @@
|
||||||
|
|
||||||
pub const WHITE: [f32; 3] = [1.0, 1.0, 1.0];
|
pub const WHITE: [f32; 3] = [1.0, 1.0, 1.0];
|
|
@ -1,5 +1,5 @@
|
||||||
use snafu::{Backtrace, Snafu, ErrorCompat};
|
|
||||||
use colored::*;
|
use colored::*;
|
||||||
|
use snafu::{Backtrace, ErrorCompat, Snafu};
|
||||||
|
|
||||||
//import errors as follows:
|
//import errors as follows:
|
||||||
// `use crate::error::OutOfBounds;`
|
// `use crate::error::OutOfBounds;`
|
||||||
|
@ -17,15 +17,12 @@ pub enum EdError {
|
||||||
OutOfBounds {
|
OutOfBounds {
|
||||||
index: usize,
|
index: usize,
|
||||||
vec_len: usize,
|
vec_len: usize,
|
||||||
backtrace: Backtrace
|
backtrace: Backtrace,
|
||||||
},
|
},
|
||||||
#[snafu(display(
|
#[snafu(display("InvalidSelection: {}", err_msg))]
|
||||||
"InvalidSelection: {}",
|
|
||||||
err_msg
|
|
||||||
))]
|
|
||||||
InvalidSelection {
|
InvalidSelection {
|
||||||
err_msg: String,
|
err_msg: String,
|
||||||
backtrace: Backtrace
|
backtrace: Backtrace,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,9 +45,7 @@ fn color_backtrace(backtrace: &snafu::Backtrace) -> String {
|
||||||
let mut prev_line_opt: Option<String> = None;
|
let mut prev_line_opt: Option<String> = None;
|
||||||
|
|
||||||
for line in backtrace_split {
|
for line in backtrace_split {
|
||||||
|
let new_line = if line.contains("src") {
|
||||||
let new_line =
|
|
||||||
if line.contains("src") {
|
|
||||||
if !contains_one_of(&line, &irrelevant_src) {
|
if !contains_one_of(&line, &irrelevant_src) {
|
||||||
if let Some(prev_line) = prev_line_opt {
|
if let Some(prev_line) = prev_line_opt {
|
||||||
prev_line_opt = Some(format!("{}", prev_line.truecolor(255, 30, 30)));
|
prev_line_opt = Some(format!("{}", prev_line.truecolor(255, 30, 30)));
|
||||||
|
@ -63,12 +58,10 @@ fn color_backtrace(backtrace: &snafu::Backtrace) -> String {
|
||||||
format!("{}\n", line)
|
format!("{}\n", line)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
if let Some(prev_line) = prev_line_opt {
|
if let Some(prev_line) = prev_line_opt {
|
||||||
ret_str.push_str(&prev_line);
|
ret_str.push_str(&prev_line);
|
||||||
}
|
}
|
||||||
prev_line_opt = Some(new_line);
|
prev_line_opt = Some(new_line);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_str
|
ret_str
|
||||||
|
@ -83,4 +76,3 @@ fn contains_one_of(main_str: &str, contain_slice: &[&str]) -> bool {
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
|
use crate::tea::model::Model;
|
||||||
|
use crate::tea::update::{
|
||||||
|
move_txt_cursor_down, move_txt_cursor_left, move_txt_cursor_right, move_txt_cursor_up,
|
||||||
|
};
|
||||||
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
|
use winit::event::{ElementState, ModifiersState, VirtualKeyCode};
|
||||||
use crate::tea::model::{Model};
|
|
||||||
use crate::tea::update::{move_caret_left, move_caret_right, move_caret_down, move_caret_up};
|
|
||||||
|
|
||||||
pub fn handle_keydown(
|
pub fn handle_keydown(
|
||||||
elem_state: ElementState,
|
elem_state: ElementState,
|
||||||
|
@ -16,25 +18,45 @@ pub fn handle_keydown(
|
||||||
|
|
||||||
match virtual_keycode {
|
match virtual_keycode {
|
||||||
Left => {
|
Left => {
|
||||||
let (new_caret_pos, new_selection_opt) = move_caret_left(model.caret_pos, model.selection_opt, modifiers.shift(), &model.lines);
|
let (new_txt_cursor_pos, new_selection_opt) = move_txt_cursor_left(
|
||||||
model.caret_pos = new_caret_pos;
|
model.txt_cursor_pos,
|
||||||
|
model.selection_opt,
|
||||||
|
modifiers.shift(),
|
||||||
|
&model.lines,
|
||||||
|
);
|
||||||
|
model.txt_cursor_pos = new_txt_cursor_pos;
|
||||||
model.selection_opt = new_selection_opt;
|
model.selection_opt = new_selection_opt;
|
||||||
},
|
}
|
||||||
Up => {
|
Up => {
|
||||||
let (new_caret_pos, new_selection_opt) = move_caret_up(model.caret_pos, model.selection_opt, modifiers.shift(), &model.lines);
|
let (new_txt_cursor_pos, new_selection_opt) = move_txt_cursor_up(
|
||||||
model.caret_pos = new_caret_pos;
|
model.txt_cursor_pos,
|
||||||
|
model.selection_opt,
|
||||||
|
modifiers.shift(),
|
||||||
|
&model.lines,
|
||||||
|
);
|
||||||
|
model.txt_cursor_pos = new_txt_cursor_pos;
|
||||||
model.selection_opt = new_selection_opt;
|
model.selection_opt = new_selection_opt;
|
||||||
},
|
}
|
||||||
Right => {
|
Right => {
|
||||||
let (new_caret_pos, new_selection_opt) = move_caret_right(model.caret_pos, model.selection_opt, modifiers.shift(), &model.lines);
|
let (new_txt_cursor_pos, new_selection_opt) = move_txt_cursor_right(
|
||||||
model.caret_pos = new_caret_pos;
|
model.txt_cursor_pos,
|
||||||
|
model.selection_opt,
|
||||||
|
modifiers.shift(),
|
||||||
|
&model.lines,
|
||||||
|
);
|
||||||
|
model.txt_cursor_pos = new_txt_cursor_pos;
|
||||||
model.selection_opt = new_selection_opt;
|
model.selection_opt = new_selection_opt;
|
||||||
},
|
}
|
||||||
Down => {
|
Down => {
|
||||||
let (new_caret_pos, new_selection_opt) = move_caret_down(model.caret_pos, model.selection_opt, modifiers.shift(), &model.lines);
|
let (new_txt_cursor_pos, new_selection_opt) = move_txt_cursor_down(
|
||||||
model.caret_pos = new_caret_pos;
|
model.txt_cursor_pos,
|
||||||
|
model.selection_opt,
|
||||||
|
modifiers.shift(),
|
||||||
|
&model.lines,
|
||||||
|
);
|
||||||
|
model.txt_cursor_pos = new_txt_cursor_pos;
|
||||||
model.selection_opt = new_selection_opt;
|
model.selection_opt = new_selection_opt;
|
||||||
},
|
}
|
||||||
Copy => {
|
Copy => {
|
||||||
todo!("copy");
|
todo!("copy");
|
||||||
}
|
}
|
||||||
|
@ -100,7 +122,7 @@ pub fn handle_keydown(
|
||||||
// Escape | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | F13 | F14 | F15
|
// Escape | F1 | F2 | F3 | F4 | F5 | F6 | F7 | F8 | F9 | F10 | F11 | F12 | F13 | F14 | F15
|
||||||
// | F16 | F17 | F18 | F19 | F20 | F21 | F22 | F23 | F24 | Snapshot | Scroll | Pause
|
// | F16 | F17 | F18 | F19 | F20 | F21 | F22 | F23 | F24 | Snapshot | Scroll | Pause
|
||||||
// | Insert | Home | Delete | End | PageDown | PageUp | Left | Up | Right | Down | Compose
|
// | Insert | Home | Delete | End | PageDown | PageUp | Left | Up | Right | Down | Compose
|
||||||
// | Caret | Numlock | AbntC1 | AbntC2 | Ax | Calculator | Capital | Convert | Kana
|
// | txt_cursor | Numlock | AbntC1 | AbntC2 | Ax | Calculator | Capital | Convert | Kana
|
||||||
// | Kanji | LAlt | LBracket | LControl | LShift | LWin | Mail | MediaSelect | PlayPause
|
// | Kanji | LAlt | LBracket | LControl | LShift | LWin | Mail | MediaSelect | PlayPause
|
||||||
// | Power | PrevTrack | MediaStop | Mute | MyComputer | NavigateForward
|
// | Power | PrevTrack | MediaStop | Mute | MyComputer | NavigateForward
|
||||||
// | NavigateBackward | NextTrack | NoConvert | OEM102 | RAlt | Sysrq | RBracket
|
// | NavigateBackward | NextTrack | NoConvert | OEM102 | RAlt | Sysrq | RBracket
|
||||||
|
|
|
@ -9,25 +9,26 @@
|
||||||
// See this link to learn wgpu: https://sotrh.github.io/learn-wgpu/
|
// See this link to learn wgpu: https://sotrh.github.io/learn-wgpu/
|
||||||
|
|
||||||
use crate::buffer::create_rect_buffers;
|
use crate::buffer::create_rect_buffers;
|
||||||
use crate::text::{build_glyph_brush, Text, is_newline};
|
use crate::error::print_err;
|
||||||
use crate::vertex::Vertex;
|
|
||||||
use crate::rect::{Rect};
|
|
||||||
use crate::error::{print_err};
|
|
||||||
use crate::ortho::{init_ortho, update_ortho_buffer, OrthoResources};
|
use crate::ortho::{init_ortho, update_ortho_buffer, OrthoResources};
|
||||||
use crate::selection::{create_selection_rects};
|
use crate::rect::Rect;
|
||||||
|
use crate::selection::create_selection_rects;
|
||||||
use crate::tea::{model, update};
|
use crate::tea::{model, update};
|
||||||
use model::{Position};
|
use crate::text::{build_glyph_brush, is_newline, Text};
|
||||||
|
use crate::vertex::Vertex;
|
||||||
|
use model::Position;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use wgpu::{CommandEncoder, RenderPass, TextureView};
|
||||||
use winit::event;
|
use winit::event;
|
||||||
use winit::event::{Event, ModifiersState};
|
use winit::event::{Event, ModifiersState};
|
||||||
use winit::event_loop::ControlFlow;
|
use winit::event_loop::ControlFlow;
|
||||||
use wgpu::{TextureView, CommandEncoder, RenderPass};
|
|
||||||
|
|
||||||
|
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
|
mod colors;
|
||||||
|
pub mod error;
|
||||||
pub mod expr;
|
pub mod expr;
|
||||||
pub mod file;
|
pub mod file;
|
||||||
mod keyboard_input;
|
mod keyboard_input;
|
||||||
|
@ -36,15 +37,13 @@ mod pattern;
|
||||||
pub mod pool;
|
pub mod pool;
|
||||||
mod rect;
|
mod rect;
|
||||||
mod scope;
|
mod scope;
|
||||||
|
mod selection;
|
||||||
|
mod tea;
|
||||||
pub mod text;
|
pub mod text;
|
||||||
mod types;
|
mod types;
|
||||||
mod util;
|
mod util;
|
||||||
mod vertex;
|
|
||||||
mod colors;
|
|
||||||
pub mod error;
|
|
||||||
mod vec_result;
|
mod vec_result;
|
||||||
mod selection;
|
mod vertex;
|
||||||
mod tea;
|
|
||||||
|
|
||||||
/// The editor is actually launched from the CLI if you pass it zero arguments,
|
/// The editor is actually launched from the CLI if you pass it zero arguments,
|
||||||
/// or if you provide it 1 or more files or directories to open on launch.
|
/// or if you provide it 1 or more files or directories to open on launch.
|
||||||
|
@ -183,7 +182,7 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
input.state,
|
input.state,
|
||||||
virtual_keycode,
|
virtual_keycode,
|
||||||
keyboard_modifiers,
|
keyboard_modifiers,
|
||||||
&mut ed_model
|
&mut ed_model,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,15 +209,16 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
let glyph_bounds_rects = queue_all_text(
|
let glyph_bounds_rects = queue_all_text(
|
||||||
&size,
|
&size,
|
||||||
&ed_model.lines,
|
&ed_model.lines,
|
||||||
ed_model.caret_pos,
|
ed_model.txt_cursor_pos,
|
||||||
&mut glyph_brush,
|
&mut glyph_brush,
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(selection) = ed_model.selection_opt {
|
if let Some(selection) = ed_model.selection_opt {
|
||||||
let selection_rects_res = create_selection_rects(selection, &glyph_bounds_rects);
|
let selection_rects_res =
|
||||||
|
create_selection_rects(selection, &glyph_bounds_rects);
|
||||||
|
|
||||||
match selection_rects_res {
|
match selection_rects_res {
|
||||||
Ok(selection_rects) =>
|
Ok(selection_rects) => {
|
||||||
if !selection_rects.is_empty() {
|
if !selection_rects.is_empty() {
|
||||||
let rect_buffers = create_rect_buffers(
|
let rect_buffers = create_rect_buffers(
|
||||||
&gpu_device,
|
&gpu_device,
|
||||||
|
@ -230,10 +230,12 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
|
|
||||||
render_pass.set_pipeline(&rect_pipeline);
|
render_pass.set_pipeline(&rect_pipeline);
|
||||||
render_pass.set_bind_group(0, &ortho.bind_group, &[]);
|
render_pass.set_bind_group(0, &ortho.bind_group, &[]);
|
||||||
render_pass.set_vertex_buffer(0, rect_buffers.vertex_buffer.slice(..));
|
render_pass
|
||||||
|
.set_vertex_buffer(0, rect_buffers.vertex_buffer.slice(..));
|
||||||
render_pass.set_index_buffer(rect_buffers.index_buffer.slice(..));
|
render_pass.set_index_buffer(rect_buffers.index_buffer.slice(..));
|
||||||
render_pass.draw_indexed(0..rect_buffers.num_rects, 0, 0..1);
|
render_pass.draw_indexed(0..rect_buffers.num_rects, 0, 0..1);
|
||||||
},
|
}
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
begin_render_pass(&mut encoder, &frame.view);
|
begin_render_pass(&mut encoder, &frame.view);
|
||||||
print_err(&e) //TODO draw error text on screen
|
print_err(&e) //TODO draw error text on screen
|
||||||
|
@ -274,10 +276,9 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn begin_render_pass<'a>(
|
fn begin_render_pass<'a>(
|
||||||
encoder: &'a mut CommandEncoder,
|
encoder: &'a mut CommandEncoder,
|
||||||
texture_view: &'a TextureView
|
texture_view: &'a TextureView,
|
||||||
) -> RenderPass<'a> {
|
) -> RenderPass<'a> {
|
||||||
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||||
|
@ -365,7 +366,7 @@ fn create_render_pipeline(
|
||||||
fn queue_all_text(
|
fn queue_all_text(
|
||||||
size: &winit::dpi::PhysicalSize<u32>,
|
size: &winit::dpi::PhysicalSize<u32>,
|
||||||
lines: &[String],
|
lines: &[String],
|
||||||
caret_pos: Position,
|
txt_cursor_pos: Position,
|
||||||
glyph_brush: &mut wgpu_glyph::GlyphBrush<()>,
|
glyph_brush: &mut wgpu_glyph::GlyphBrush<()>,
|
||||||
) -> Vec<Vec<Rect>> {
|
) -> Vec<Vec<Rect>> {
|
||||||
let area_bounds = (size.width as f32, size.height as f32).into();
|
let area_bounds = (size.width as f32, size.height as f32).into();
|
||||||
|
@ -388,18 +389,18 @@ fn queue_all_text(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
let caret_pos_label = Text {
|
let txt_cursor_pos_label = Text {
|
||||||
position: (30.0, 530.0).into(),
|
position: (30.0, 530.0).into(),
|
||||||
area_bounds,
|
area_bounds,
|
||||||
color: (0.4666, 0.2, 1.0, 1.0).into(),
|
color: (0.4666, 0.2, 1.0, 1.0).into(),
|
||||||
text: format!("Ln {}, Col {}", caret_pos.line, caret_pos.column),
|
text: format!("Ln {}, Col {}", txt_cursor_pos.line, txt_cursor_pos.column),
|
||||||
size: 30.0,
|
size: 30.0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
text::queue_text_draw(&main_label, glyph_brush);
|
text::queue_text_draw(&main_label, glyph_brush);
|
||||||
|
|
||||||
text::queue_text_draw(&caret_pos_label, glyph_brush);
|
text::queue_text_draw(&txt_cursor_pos_label, glyph_brush);
|
||||||
|
|
||||||
text::queue_text_draw(&code_text, glyph_brush)
|
text::queue_text_draw(&code_text, glyph_brush)
|
||||||
}
|
}
|
||||||
|
@ -417,7 +418,13 @@ fn update_text_state(ed_model: &mut model::Model, received_char: &char) {
|
||||||
} else if ed_model.lines.len() > 1 {
|
} else if ed_model.lines.len() > 1 {
|
||||||
ed_model.lines.pop();
|
ed_model.lines.pop();
|
||||||
}
|
}
|
||||||
ed_model.caret_pos = update::move_caret_left(ed_model.caret_pos, None, false, &ed_model.lines).0;
|
ed_model.txt_cursor_pos = update::move_txt_cursor_left(
|
||||||
|
ed_model.txt_cursor_pos,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
&ed_model.lines,
|
||||||
|
)
|
||||||
|
.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
'\u{e000}'..='\u{f8ff}' | '\u{f0000}'..='\u{ffffd}' | '\u{100000}'..='\u{10fffd}' => {
|
'\u{e000}'..='\u{f8ff}' | '\u{f0000}'..='\u{ffffd}' | '\u{100000}'..='\u{10fffd}' => {
|
||||||
|
@ -429,10 +436,9 @@ fn update_text_state(ed_model: &mut model::Model, received_char: &char) {
|
||||||
last_line.push(*received_char)
|
last_line.push(*received_char)
|
||||||
}
|
}
|
||||||
ed_model.lines.push(String::new());
|
ed_model.lines.push(String::new());
|
||||||
ed_model.caret_pos =
|
ed_model.txt_cursor_pos = Position {
|
||||||
Position {
|
line: ed_model.txt_cursor_pos.line + 1,
|
||||||
line: ed_model.caret_pos.line + 1,
|
column: 0,
|
||||||
column: 0
|
|
||||||
};
|
};
|
||||||
|
|
||||||
ed_model.selection_opt = None;
|
ed_model.selection_opt = None;
|
||||||
|
@ -443,10 +449,9 @@ fn update_text_state(ed_model: &mut model::Model, received_char: &char) {
|
||||||
if let Some(last_line) = ed_model.lines.last_mut() {
|
if let Some(last_line) = ed_model.lines.last_mut() {
|
||||||
last_line.push(*received_char);
|
last_line.push(*received_char);
|
||||||
|
|
||||||
ed_model.caret_pos =
|
ed_model.txt_cursor_pos = Position {
|
||||||
Position {
|
|
||||||
line: nr_lines - 1,
|
line: nr_lines - 1,
|
||||||
column: last_line.len()
|
column: last_line.len(),
|
||||||
};
|
};
|
||||||
|
|
||||||
ed_model.selection_opt = None;
|
ed_model.selection_opt = None;
|
||||||
|
|
|
@ -1,34 +1,32 @@
|
||||||
|
|
||||||
use crate::rect::{Rect};
|
|
||||||
use crate::vec_result::{get_res};
|
|
||||||
use crate::error::{EdResult, InvalidSelection};
|
|
||||||
use crate::colors;
|
use crate::colors;
|
||||||
use crate::tea::model::{RawSelection};
|
use crate::error::{EdResult, InvalidSelection};
|
||||||
|
use crate::rect::Rect;
|
||||||
|
use crate::tea::model::RawSelection;
|
||||||
|
use crate::vec_result::get_res;
|
||||||
use snafu::ensure;
|
use snafu::ensure;
|
||||||
|
|
||||||
//using the "parse don't validate" pattern
|
//using the "parse don't validate" pattern
|
||||||
struct ValidSelection {
|
struct ValidSelection {
|
||||||
selection: RawSelection
|
selection: RawSelection,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate_selection( selection: RawSelection) -> EdResult<ValidSelection> {
|
fn validate_selection(selection: RawSelection) -> EdResult<ValidSelection> {
|
||||||
let RawSelection {start_pos, end_pos} = selection;
|
let RawSelection { start_pos, end_pos } = selection;
|
||||||
|
|
||||||
ensure!(
|
ensure!(
|
||||||
start_pos.line <= end_pos.line,
|
start_pos.line <= end_pos.line,
|
||||||
InvalidSelection { err_msg:
|
InvalidSelection {
|
||||||
format!(
|
err_msg: format!(
|
||||||
"start_pos.line ({}) should be smaller than or equal to end_pos.line ({})",
|
"start_pos.line ({}) should be smaller than or equal to end_pos.line ({})",
|
||||||
start_pos.line,
|
start_pos.line, end_pos.line
|
||||||
end_pos.line
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
ensure!(
|
ensure!(
|
||||||
!(start_pos.line == end_pos.line && start_pos.column > end_pos.column),
|
!(start_pos.line == end_pos.line && start_pos.column > end_pos.column),
|
||||||
InvalidSelection { err_msg:
|
InvalidSelection {
|
||||||
format!(
|
err_msg: format!(
|
||||||
"start_pos.column ({}) should be smaller than or equal to end_pos.column ({}) when start_pos.line equals end_pos.line",
|
"start_pos.column ({}) should be smaller than or equal to end_pos.column ({}) when start_pos.line equals end_pos.line",
|
||||||
start_pos.column,
|
start_pos.column,
|
||||||
end_pos.column
|
end_pos.column
|
||||||
|
@ -36,82 +34,66 @@ fn validate_selection( selection: RawSelection) -> EdResult<ValidSelection> {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(
|
Ok(ValidSelection {
|
||||||
ValidSelection {
|
selection: RawSelection { start_pos, end_pos },
|
||||||
selection: RawSelection {start_pos, end_pos}
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn create_selection_rects(
|
pub fn create_selection_rects(
|
||||||
raw_sel: RawSelection,
|
raw_sel: RawSelection,
|
||||||
glyph_bound_rects: &Vec<Vec<Rect>>
|
glyph_bound_rects: &Vec<Vec<Rect>>,
|
||||||
) -> EdResult<Vec<Rect>> {
|
) -> EdResult<Vec<Rect>> {
|
||||||
let valid_sel = validate_selection(raw_sel)?;
|
let valid_sel = validate_selection(raw_sel)?;
|
||||||
let RawSelection {start_pos, end_pos} = valid_sel.selection;
|
let RawSelection { start_pos, end_pos } = valid_sel.selection;
|
||||||
|
|
||||||
let mut all_rects = Vec::new();
|
let mut all_rects = Vec::new();
|
||||||
|
|
||||||
if start_pos.line == end_pos.line {
|
if start_pos.line == end_pos.line {
|
||||||
let start_glyph_rect =
|
let start_glyph_rect = get_res(
|
||||||
get_res(
|
|
||||||
start_pos.column,
|
start_pos.column,
|
||||||
get_res(start_pos.line, glyph_bound_rects)?,
|
get_res(start_pos.line, glyph_bound_rects)?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let stop_glyph_rect =
|
let stop_glyph_rect = get_res(
|
||||||
get_res(
|
|
||||||
end_pos.column - 1,
|
end_pos.column - 1,
|
||||||
get_res(end_pos.line, glyph_bound_rects)?
|
get_res(end_pos.line, glyph_bound_rects)?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let top_left_coords =
|
let top_left_coords = start_glyph_rect.top_left_coords;
|
||||||
start_glyph_rect.top_left_coords;
|
|
||||||
|
|
||||||
let height = start_glyph_rect.height;
|
let height = start_glyph_rect.height;
|
||||||
let width = (stop_glyph_rect.top_left_coords.x - start_glyph_rect.top_left_coords.x) + stop_glyph_rect.width;
|
let width = (stop_glyph_rect.top_left_coords.x - start_glyph_rect.top_left_coords.x)
|
||||||
|
+ stop_glyph_rect.width;
|
||||||
|
|
||||||
all_rects.push(
|
all_rects.push(Rect {
|
||||||
Rect {
|
|
||||||
top_left_coords,
|
top_left_coords,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
color: colors::WHITE
|
color: colors::WHITE,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
Ok(all_rects)
|
Ok(all_rects)
|
||||||
} else {
|
} else {
|
||||||
// first line
|
// first line
|
||||||
let start_line = get_res(start_pos.line, glyph_bound_rects)?;
|
let start_line = get_res(start_pos.line, glyph_bound_rects)?;
|
||||||
|
|
||||||
let start_glyph_rect =
|
let start_glyph_rect = get_res(start_pos.column, start_line)?;
|
||||||
get_res(
|
|
||||||
start_pos.column,
|
|
||||||
start_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let start_line_last_glyph_rect =
|
let start_line_last_glyph_rect = get_res(start_line.len() - 1, start_line)?;
|
||||||
get_res(
|
|
||||||
start_line.len() - 1,
|
|
||||||
start_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let top_left_coords =
|
let top_left_coords = start_glyph_rect.top_left_coords;
|
||||||
start_glyph_rect.top_left_coords;
|
|
||||||
|
|
||||||
let height = start_glyph_rect.height;
|
let height = start_glyph_rect.height;
|
||||||
let width = (start_line_last_glyph_rect.top_left_coords.x - start_glyph_rect.top_left_coords.x) + start_line_last_glyph_rect.width;
|
let width = (start_line_last_glyph_rect.top_left_coords.x
|
||||||
|
- start_glyph_rect.top_left_coords.x)
|
||||||
|
+ start_line_last_glyph_rect.width;
|
||||||
|
|
||||||
all_rects.push(
|
all_rects.push(Rect {
|
||||||
Rect {
|
|
||||||
top_left_coords,
|
top_left_coords,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
color: colors::WHITE
|
color: colors::WHITE,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
//middle lines
|
//middle lines
|
||||||
let nr_mid_lines = (end_pos.line - start_pos.line) - 1;
|
let nr_mid_lines = (end_pos.line - start_pos.line) - 1;
|
||||||
|
@ -120,64 +102,46 @@ pub fn create_selection_rects(
|
||||||
for i in first_mid_line..(first_mid_line + nr_mid_lines) {
|
for i in first_mid_line..(first_mid_line + nr_mid_lines) {
|
||||||
let mid_line = get_res(i, glyph_bound_rects)?;
|
let mid_line = get_res(i, glyph_bound_rects)?;
|
||||||
|
|
||||||
let mid_line_first_glyph_rect =
|
let mid_line_first_glyph_rect = get_res(0, mid_line)?;
|
||||||
get_res(
|
|
||||||
0,
|
|
||||||
mid_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let mid_line_last_glyph_rect =
|
let mid_line_last_glyph_rect = get_res(mid_line.len() - 1, mid_line)?;
|
||||||
get_res(
|
|
||||||
mid_line.len() - 1,
|
|
||||||
mid_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let top_left_coords =
|
let top_left_coords = mid_line_first_glyph_rect.top_left_coords;
|
||||||
mid_line_first_glyph_rect.top_left_coords;
|
|
||||||
|
|
||||||
let height = mid_line_first_glyph_rect.height;
|
let height = mid_line_first_glyph_rect.height;
|
||||||
let width = (mid_line_last_glyph_rect.top_left_coords.x - mid_line_first_glyph_rect.top_left_coords.x) + mid_line_last_glyph_rect.width;
|
let width = (mid_line_last_glyph_rect.top_left_coords.x
|
||||||
|
- mid_line_first_glyph_rect.top_left_coords.x)
|
||||||
|
+ mid_line_last_glyph_rect.width;
|
||||||
|
|
||||||
all_rects.push(
|
all_rects.push(Rect {
|
||||||
Rect {
|
|
||||||
top_left_coords,
|
top_left_coords,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
color: colors::WHITE
|
color: colors::WHITE,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//last line
|
//last line
|
||||||
if end_pos.column > 0 {
|
if end_pos.column > 0 {
|
||||||
let stop_line = get_res(end_pos.line, glyph_bound_rects)?;
|
let stop_line = get_res(end_pos.line, glyph_bound_rects)?;
|
||||||
|
|
||||||
let stop_line_first_glyph_rect =
|
let stop_line_first_glyph_rect = get_res(0, stop_line)?;
|
||||||
get_res(
|
|
||||||
0,
|
|
||||||
stop_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let stop_glyph_rect =
|
let stop_glyph_rect = get_res(end_pos.column - 1, stop_line)?;
|
||||||
get_res(
|
|
||||||
end_pos.column - 1,
|
|
||||||
stop_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let top_left_coords =
|
let top_left_coords = stop_line_first_glyph_rect.top_left_coords;
|
||||||
stop_line_first_glyph_rect.top_left_coords;
|
|
||||||
|
|
||||||
let height = stop_glyph_rect.height;
|
let height = stop_glyph_rect.height;
|
||||||
let width = (stop_glyph_rect.top_left_coords.x - stop_line_first_glyph_rect.top_left_coords.x) + stop_glyph_rect.width;
|
let width = (stop_glyph_rect.top_left_coords.x
|
||||||
|
- stop_line_first_glyph_rect.top_left_coords.x)
|
||||||
|
+ stop_glyph_rect.width;
|
||||||
|
|
||||||
all_rects.push(
|
all_rects.push(Rect {
|
||||||
Rect {
|
|
||||||
top_left_coords,
|
top_left_coords,
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
color: colors::WHITE
|
color: colors::WHITE,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(all_rects)
|
Ok(all_rects)
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
|
|
||||||
pub mod model;
|
pub mod model;
|
||||||
pub mod update;
|
pub mod update;
|
|
@ -1,23 +1,17 @@
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::cmp::{Ordering};
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Model {
|
pub struct Model {
|
||||||
pub lines: Vec<String>,
|
pub lines: Vec<String>,
|
||||||
pub caret_pos: Position,
|
pub txt_cursor_pos: Position,
|
||||||
pub selection_opt: Option<RawSelection>
|
pub selection_opt: Option<RawSelection>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_model() -> Model {
|
pub fn init_model() -> Model {
|
||||||
Model {
|
Model {
|
||||||
lines:
|
lines: vec![String::new()],
|
||||||
vec![String::new()],
|
txt_cursor_pos: Position { line: 0, column: 0 },
|
||||||
caret_pos:
|
selection_opt: None,
|
||||||
Position {
|
|
||||||
line: 0, column: 0
|
|
||||||
},
|
|
||||||
selection_opt:
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +19,7 @@ pub fn init_model() -> Model {
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
pub line: usize,
|
pub line: usize,
|
||||||
pub column: usize
|
pub column: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ord for Position {
|
impl Ord for Position {
|
||||||
|
@ -46,10 +40,10 @@ impl PartialEq for Position {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Eq for Position { }
|
impl Eq for Position {}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct RawSelection {
|
pub struct RawSelection {
|
||||||
pub start_pos: Position,
|
pub start_pos: Position,
|
||||||
pub end_pos: Position
|
pub end_pos: Position,
|
||||||
}
|
}
|
|
@ -1,15 +1,18 @@
|
||||||
|
|
||||||
use crate::tea::model::{Position, RawSelection};
|
use crate::tea::model::{Position, RawSelection};
|
||||||
use crate::text::{is_newline};
|
use crate::text::is_newline;
|
||||||
use std::cmp::{min, max};
|
use std::cmp::{max, min};
|
||||||
|
|
||||||
pub fn move_caret_left(old_caret_pos: Position, old_selection_opt: Option<RawSelection>, shift_pressed: bool, lines: &[String]) -> (Position, Option<RawSelection>) {
|
pub fn move_txt_cursor_left(
|
||||||
let old_line_nr = old_caret_pos.line;
|
old_txt_cursor_pos: Position,
|
||||||
let old_col_nr = old_caret_pos.column;
|
old_selection_opt: Option<RawSelection>,
|
||||||
|
shift_pressed: bool,
|
||||||
|
lines: &[String],
|
||||||
|
) -> (Position, Option<RawSelection>) {
|
||||||
|
let old_line_nr = old_txt_cursor_pos.line;
|
||||||
|
let old_col_nr = old_txt_cursor_pos.column;
|
||||||
|
|
||||||
let (line_nr, col_nr) =
|
let (line_nr, col_nr) = if old_txt_cursor_pos.column == 0 {
|
||||||
if old_caret_pos.column == 0 {
|
if old_txt_cursor_pos.line == 0 {
|
||||||
if old_caret_pos.line == 0 {
|
|
||||||
(0, 0)
|
(0, 0)
|
||||||
} else if let Some(curr_line) = lines.get(old_line_nr - 1) {
|
} else if let Some(curr_line) = lines.get(old_line_nr - 1) {
|
||||||
(old_line_nr - 1, curr_line.len() - 1)
|
(old_line_nr - 1, curr_line.len() - 1)
|
||||||
|
@ -20,65 +23,51 @@ pub fn move_caret_left(old_caret_pos: Position, old_selection_opt: Option<RawSel
|
||||||
(old_line_nr, old_col_nr - 1)
|
(old_line_nr, old_col_nr - 1)
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_caret_pos = Position {
|
let new_txt_cursor_pos = Position {
|
||||||
line: line_nr,
|
line: line_nr,
|
||||||
column: col_nr
|
column: col_nr,
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_selection_opt =
|
let new_selection_opt = if shift_pressed {
|
||||||
if shift_pressed {
|
|
||||||
if let Some(old_selection) = old_selection_opt {
|
if let Some(old_selection) = old_selection_opt {
|
||||||
Some(
|
Some(RawSelection {
|
||||||
RawSelection {
|
start_pos: Position {
|
||||||
start_pos:
|
|
||||||
Position {
|
|
||||||
line: line_nr,
|
line: line_nr,
|
||||||
column: col_nr
|
column: col_nr,
|
||||||
}
|
},
|
||||||
,
|
end_pos: old_selection.end_pos,
|
||||||
end_pos:
|
})
|
||||||
old_selection.end_pos
|
} else if !(old_line_nr == line_nr && old_col_nr == col_nr) {
|
||||||
,
|
Some(RawSelection {
|
||||||
}
|
start_pos: Position {
|
||||||
)
|
|
||||||
} else if !(old_line_nr == line_nr && old_col_nr == col_nr){
|
|
||||||
Some(
|
|
||||||
RawSelection {
|
|
||||||
start_pos:
|
|
||||||
Position {
|
|
||||||
line: line_nr,
|
line: line_nr,
|
||||||
column: col_nr
|
column: col_nr,
|
||||||
}
|
},
|
||||||
,
|
end_pos: Position {
|
||||||
end_pos:
|
|
||||||
Position {
|
|
||||||
line: old_line_nr,
|
line: old_line_nr,
|
||||||
column: old_col_nr
|
column: old_col_nr,
|
||||||
}
|
},
|
||||||
,
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
(new_txt_cursor_pos, new_selection_opt)
|
||||||
(
|
|
||||||
new_caret_pos,
|
|
||||||
new_selection_opt
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn move_caret_right(old_caret_pos: Position, old_selection_opt: Option<RawSelection>, shift_pressed: bool, lines: &[String]) -> (Position, Option<RawSelection>) {
|
pub fn move_txt_cursor_right(
|
||||||
let old_line_nr = old_caret_pos.line;
|
old_txt_cursor_pos: Position,
|
||||||
let old_col_nr = old_caret_pos.column;
|
old_selection_opt: Option<RawSelection>,
|
||||||
|
shift_pressed: bool,
|
||||||
|
lines: &[String],
|
||||||
|
) -> (Position, Option<RawSelection>) {
|
||||||
|
let old_line_nr = old_txt_cursor_pos.line;
|
||||||
|
let old_col_nr = old_txt_cursor_pos.column;
|
||||||
|
|
||||||
let (line_nr, col_nr) =
|
let (line_nr, col_nr) = if let Some(curr_line) = lines.get(old_line_nr) {
|
||||||
if let Some(curr_line) = lines.get(old_line_nr) {
|
|
||||||
if let Some(last_char) = curr_line.chars().last() {
|
if let Some(last_char) = curr_line.chars().last() {
|
||||||
if is_newline(&last_char) {
|
if is_newline(&last_char) {
|
||||||
if old_col_nr + 1 > curr_line.len() - 1 {
|
if old_col_nr + 1 > curr_line.len() - 1 {
|
||||||
|
@ -98,64 +87,51 @@ 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?
|
(0, 0) // this should never happen, should this method return Result?
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_caret_pos = Position {
|
let new_txt_cursor_pos = Position {
|
||||||
line: line_nr,
|
line: line_nr,
|
||||||
column: col_nr
|
column: col_nr,
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_selection_opt =
|
let new_selection_opt = if shift_pressed {
|
||||||
if shift_pressed {
|
|
||||||
if let Some(old_selection) = old_selection_opt {
|
if let Some(old_selection) = old_selection_opt {
|
||||||
Some(
|
Some(RawSelection {
|
||||||
RawSelection {
|
start_pos: old_selection.start_pos,
|
||||||
start_pos:
|
end_pos: Position {
|
||||||
old_selection.start_pos
|
|
||||||
,
|
|
||||||
end_pos:
|
|
||||||
Position {
|
|
||||||
line: line_nr,
|
line: line_nr,
|
||||||
column: col_nr
|
column: col_nr,
|
||||||
}
|
},
|
||||||
,
|
})
|
||||||
}
|
} else if !(old_line_nr == line_nr && old_col_nr == col_nr) {
|
||||||
)
|
Some(RawSelection {
|
||||||
} else if !(old_line_nr == line_nr && old_col_nr == col_nr){
|
start_pos: Position {
|
||||||
Some(
|
|
||||||
RawSelection {
|
|
||||||
start_pos:
|
|
||||||
Position {
|
|
||||||
line: old_line_nr,
|
line: old_line_nr,
|
||||||
column: old_col_nr
|
column: old_col_nr,
|
||||||
}
|
},
|
||||||
,
|
end_pos: Position {
|
||||||
end_pos:
|
|
||||||
Position {
|
|
||||||
line: line_nr,
|
line: line_nr,
|
||||||
column: col_nr
|
column: col_nr,
|
||||||
}
|
},
|
||||||
,
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(new_txt_cursor_pos, new_selection_opt)
|
||||||
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>) {
|
pub fn move_txt_cursor_up(
|
||||||
let old_line_nr = old_caret_pos.line;
|
old_txt_cursor_pos: Position,
|
||||||
let old_col_nr = old_caret_pos.column;
|
old_selection_opt: Option<RawSelection>,
|
||||||
|
shift_pressed: bool,
|
||||||
|
lines: &[String],
|
||||||
|
) -> (Position, Option<RawSelection>) {
|
||||||
|
let old_line_nr = old_txt_cursor_pos.line;
|
||||||
|
let old_col_nr = old_txt_cursor_pos.column;
|
||||||
|
|
||||||
let (line_nr, col_nr) =
|
let (line_nr, col_nr) = if old_line_nr == 0 {
|
||||||
if old_line_nr == 0 {
|
|
||||||
(old_line_nr, old_col_nr)
|
(old_line_nr, old_col_nr)
|
||||||
} else if let Some(prev_line) = lines.get(old_line_nr - 1) {
|
} else if let Some(prev_line) = lines.get(old_line_nr - 1) {
|
||||||
if prev_line.len() < old_col_nr {
|
if prev_line.len() < old_col_nr {
|
||||||
|
@ -167,55 +143,42 @@ pub fn move_caret_up(old_caret_pos: Position, old_selection_opt: Option<RawSelec
|
||||||
(0, 0) // this should never happen, should this method return Result?
|
(0, 0) // this should never happen, should this method return Result?
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_caret_pos = Position {
|
let new_txt_cursor_pos = Position {
|
||||||
line: line_nr,
|
line: line_nr,
|
||||||
column: col_nr
|
column: col_nr,
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_selection_opt =
|
let new_selection_opt = if shift_pressed {
|
||||||
if shift_pressed {
|
|
||||||
if let Some(old_selection) = old_selection_opt {
|
if let Some(old_selection) = old_selection_opt {
|
||||||
Some(
|
Some(RawSelection {
|
||||||
RawSelection {
|
start_pos: new_txt_cursor_pos,
|
||||||
start_pos:
|
end_pos: old_selection.end_pos,
|
||||||
new_caret_pos
|
})
|
||||||
,
|
} else if !(old_line_nr == line_nr && old_col_nr == col_nr) {
|
||||||
end_pos:
|
Some(RawSelection {
|
||||||
old_selection.end_pos
|
start_pos: min(old_txt_cursor_pos, new_txt_cursor_pos),
|
||||||
,
|
end_pos: max(old_txt_cursor_pos, new_txt_cursor_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 {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(new_txt_cursor_pos, new_selection_opt)
|
||||||
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>) {
|
pub fn move_txt_cursor_down(
|
||||||
let old_line_nr = old_caret_pos.line;
|
old_txt_cursor_pos: Position,
|
||||||
let old_col_nr = old_caret_pos.column;
|
old_selection_opt: Option<RawSelection>,
|
||||||
|
shift_pressed: bool,
|
||||||
|
lines: &[String],
|
||||||
|
) -> (Position, Option<RawSelection>) {
|
||||||
|
let old_line_nr = old_txt_cursor_pos.line;
|
||||||
|
let old_col_nr = old_txt_cursor_pos.column;
|
||||||
|
|
||||||
let (line_nr, col_nr) =
|
let (line_nr, col_nr) = if old_line_nr + 1 >= lines.len() {
|
||||||
if old_line_nr + 1 >= lines.len() {
|
|
||||||
(old_line_nr, old_col_nr)
|
(old_line_nr, old_col_nr)
|
||||||
} else if let Some(next_line) = lines.get(old_line_nr + 1) {
|
} else if let Some(next_line) = lines.get(old_line_nr + 1) {
|
||||||
if next_line.len() < old_col_nr {
|
if next_line.len() < old_col_nr {
|
||||||
|
@ -228,7 +191,6 @@ pub fn move_caret_down(old_caret_pos: Position, old_selection_opt: Option<RawSel
|
||||||
} else {
|
} else {
|
||||||
(old_line_nr + 1, 0)
|
(old_line_nr + 1, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
(old_line_nr + 1, old_col_nr)
|
(old_line_nr + 1, old_col_nr)
|
||||||
}
|
}
|
||||||
|
@ -236,45 +198,28 @@ pub fn move_caret_down(old_caret_pos: Position, old_selection_opt: Option<RawSel
|
||||||
(0, 0) // this should never happen, should this method return Result?
|
(0, 0) // this should never happen, should this method return Result?
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_caret_pos = Position {
|
let new_txt_cursor_pos = Position {
|
||||||
line: line_nr,
|
line: line_nr,
|
||||||
column: col_nr
|
column: col_nr,
|
||||||
};
|
};
|
||||||
|
|
||||||
let new_selection_opt =
|
let new_selection_opt = if shift_pressed {
|
||||||
if shift_pressed {
|
|
||||||
if let Some(old_selection) = old_selection_opt {
|
if let Some(old_selection) = old_selection_opt {
|
||||||
Some(
|
Some(RawSelection {
|
||||||
RawSelection {
|
start_pos: old_selection.start_pos,
|
||||||
start_pos:
|
end_pos: new_txt_cursor_pos,
|
||||||
old_selection.start_pos
|
})
|
||||||
,
|
} else if !(old_line_nr == line_nr && old_col_nr == col_nr) {
|
||||||
end_pos:
|
Some(RawSelection {
|
||||||
new_caret_pos
|
start_pos: min(old_txt_cursor_pos, new_txt_cursor_pos),
|
||||||
,
|
end_pos: max(old_txt_cursor_pos, new_txt_cursor_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 {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
(
|
(new_txt_cursor_pos, new_selection_opt)
|
||||||
new_caret_pos,
|
|
||||||
new_selection_opt
|
|
||||||
)
|
|
||||||
}
|
}
|
|
@ -1,11 +1,11 @@
|
||||||
// Adapted from https://github.com/sotrh/learn-wgpu
|
// Adapted from https://github.com/sotrh/learn-wgpu
|
||||||
// by Benjamin Hansen, licensed under the MIT license
|
// by Benjamin Hansen, licensed under the MIT license
|
||||||
|
|
||||||
use ab_glyph::{FontArc, InvalidFont, Glyph};
|
|
||||||
use cgmath::{Vector2, Vector4};
|
|
||||||
use wgpu_glyph::{ab_glyph, GlyphBrush, GlyphBrushBuilder, GlyphCruncher, Section};
|
|
||||||
use crate::rect::Rect;
|
use crate::rect::Rect;
|
||||||
|
use ab_glyph::{FontArc, Glyph, InvalidFont};
|
||||||
|
use cgmath::{Vector2, Vector4};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use wgpu_glyph::{ab_glyph, GlyphBrush, GlyphBrushBuilder, GlyphCruncher, Section};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Text {
|
pub struct Text {
|
||||||
|
@ -45,7 +45,8 @@ pub fn queue_text_draw(text: &Text, glyph_brush: &mut GlyphBrush<()>) -> Vec<Vec
|
||||||
bounds: text.area_bounds.into(),
|
bounds: text.area_bounds.into(),
|
||||||
layout,
|
layout,
|
||||||
..Section::default()
|
..Section::default()
|
||||||
}.add_text(
|
}
|
||||||
|
.add_text(
|
||||||
wgpu_glyph::Text::new(&text.text)
|
wgpu_glyph::Text::new(&text.text)
|
||||||
.with_color(text.color)
|
.with_color(text.color)
|
||||||
.with_scale(text.size),
|
.with_scale(text.size),
|
||||||
|
@ -55,8 +56,8 @@ pub fn queue_text_draw(text: &Text, glyph_brush: &mut GlyphBrush<()>) -> Vec<Vec
|
||||||
|
|
||||||
let glyph_section_iter = glyph_brush.glyphs_custom_layout(section, &layout);
|
let glyph_section_iter = glyph_brush.glyphs_custom_layout(section, &layout);
|
||||||
|
|
||||||
glyph_section_iter.map(|section_glyph|
|
glyph_section_iter
|
||||||
{
|
.map(|section_glyph| {
|
||||||
let position = section_glyph.glyph.position;
|
let position = section_glyph.glyph.position;
|
||||||
let px_scale = section_glyph.glyph.scale;
|
let px_scale = section_glyph.glyph.scale;
|
||||||
let width = glyph_width(§ion_glyph.glyph);
|
let width = glyph_width(§ion_glyph.glyph);
|
||||||
|
@ -67,10 +68,10 @@ pub fn queue_text_draw(text: &Text, glyph_brush: &mut GlyphBrush<()>) -> Vec<Vec
|
||||||
top_left_coords: [position.x, top_y].into(),
|
top_left_coords: [position.x, top_y].into(),
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
color: [1.0, 1.0, 1.0]
|
color: [1.0, 1.0, 1.0],
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
).group_by(|rect| rect.top_left_coords.y)
|
.group_by(|rect| rect.top_left_coords.y)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(_y_coord, rect_group)| {
|
.map(|(_y_coord, rect_group)| {
|
||||||
let mut rects_vec = rect_group.collect::<Vec<Rect>>();
|
let mut rects_vec = rect_group.collect::<Vec<Rect>>();
|
||||||
|
@ -78,10 +79,14 @@ pub fn queue_text_draw(text: &Text, glyph_brush: &mut GlyphBrush<()>) -> Vec<Vec
|
||||||
// add extra rect to make it easy to highlight the newline character
|
// add extra rect to make it easy to highlight the newline character
|
||||||
if let Some(last_rect) = last_rect_opt {
|
if let Some(last_rect) = last_rect_opt {
|
||||||
rects_vec.push(Rect {
|
rects_vec.push(Rect {
|
||||||
top_left_coords: [last_rect.top_left_coords.x + last_rect.width, last_rect.top_left_coords.y].into(),
|
top_left_coords: [
|
||||||
|
last_rect.top_left_coords.x + last_rect.width,
|
||||||
|
last_rect.top_left_coords.y,
|
||||||
|
]
|
||||||
|
.into(),
|
||||||
width: last_rect.width,
|
width: last_rect.width,
|
||||||
height: last_rect.height,
|
height: last_rect.height,
|
||||||
color: last_rect.color
|
color: last_rect.color,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
rects_vec
|
rects_vec
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
|
use crate::error::EdResult;
|
||||||
use crate::error::OutOfBounds;
|
use crate::error::OutOfBounds;
|
||||||
use crate::error::{EdResult};
|
use snafu::OptionExt;
|
||||||
use std::slice::SliceIndex;
|
use std::slice::SliceIndex;
|
||||||
use snafu::{OptionExt};
|
|
||||||
|
|
||||||
// replace vec methods that return Option with ones that return Result and proper Error
|
// replace vec methods that return Option with ones that return Result and proper Error
|
||||||
|
|
||||||
pub fn get_res<T>(index: usize, vec: &[T]) -> EdResult<&<usize as SliceIndex<[T]>>::Output> {
|
pub fn get_res<T>(index: usize, vec: &[T]) -> EdResult<&<usize as SliceIndex<[T]>>::Output> {
|
||||||
|
|
||||||
let elt_ref = vec.get(index).context(OutOfBounds {
|
let elt_ref = vec.get(index).context(OutOfBounds {
|
||||||
index,
|
index,
|
||||||
vec_len: vec.len()
|
vec_len: vec.len(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(elt_ref)
|
Ok(elt_ref)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue