mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
added InvalidSelection error, moved all selection stuff to separate file
This commit is contained in:
parent
8c55f4b172
commit
8219293e65
5 changed files with 210 additions and 144 deletions
|
@ -51,6 +51,7 @@ These are potentially inspirational resources for the editor's design.
|
||||||
* [Blueprints](https://docs.unrealengine.com/en-US/Engine/Blueprints/index.html) visual scripting (not suggesting visual scripting for Roc)
|
* [Blueprints](https://docs.unrealengine.com/en-US/Engine/Blueprints/index.html) visual scripting (not suggesting visual scripting for Roc)
|
||||||
|
|
||||||
* [Live Programing](https://www.microsoft.com/en-us/research/project/live-programming/?from=http%3A%2F%2Fresearch.microsoft.com%2Fen-us%2Fprojects%2Fliveprogramming%2Ftypography.aspx#!publications) by [Microsoft Research] it contains many interesting research papers.
|
* [Live Programing](https://www.microsoft.com/en-us/research/project/live-programming/?from=http%3A%2F%2Fresearch.microsoft.com%2Fen-us%2Fprojects%2Fliveprogramming%2Ftypography.aspx#!publications) by [Microsoft Research] it contains many interesting research papers.
|
||||||
|
* When refactoring; cutting and pasting code to a new file should automatically add imports to the new file and delete them from the old file.
|
||||||
|
|
||||||
### Non-Code Related Inspiration
|
### Non-Code Related Inspiration
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,14 @@ pub enum EdError {
|
||||||
vec_len: usize,
|
vec_len: usize,
|
||||||
backtrace: Backtrace
|
backtrace: Backtrace
|
||||||
},
|
},
|
||||||
|
#[snafu(display(
|
||||||
|
"InvalidSelection: {}",
|
||||||
|
err_msg
|
||||||
|
))]
|
||||||
|
InvalidSelection {
|
||||||
|
err_msg: String,
|
||||||
|
backtrace: Backtrace
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type EdResult<T, E = EdError> = std::result::Result<T, E>;
|
pub type EdResult<T, E = EdError> = std::result::Result<T, E>;
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::buffer::create_rect_buffers;
|
||||||
use crate::text::{build_glyph_brush, Text};
|
use crate::text::{build_glyph_brush, Text};
|
||||||
use crate::vertex::Vertex;
|
use crate::vertex::Vertex;
|
||||||
use crate::rect::{Rect};
|
use crate::rect::{Rect};
|
||||||
use crate::error::{EdResult, print_err};
|
use crate::error::{print_err};
|
||||||
use ortho::{init_ortho, update_ortho_buffer, OrthoResources};
|
use ortho::{init_ortho, update_ortho_buffer, OrthoResources};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::io;
|
use std::io;
|
||||||
|
@ -20,7 +20,7 @@ use std::path::Path;
|
||||||
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 vec_result::{get_res};
|
use selection::{create_selection_rects, RawSelection};
|
||||||
|
|
||||||
pub mod ast;
|
pub mod ast;
|
||||||
mod buffer;
|
mod buffer;
|
||||||
|
@ -39,6 +39,7 @@ mod vertex;
|
||||||
mod colors;
|
mod colors;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
mod vec_result;
|
mod vec_result;
|
||||||
|
mod selection;
|
||||||
|
|
||||||
/// 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.
|
||||||
|
@ -206,7 +207,14 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
&mut glyph_brush,
|
&mut glyph_brush,
|
||||||
);
|
);
|
||||||
|
|
||||||
let selection_rects_res = create_selection_rects(1, 5, 4, 2, &glyph_bounds_rects);
|
let selection =
|
||||||
|
RawSelection {
|
||||||
|
start_line_indx: 1,
|
||||||
|
pos_in_start_line: 3,
|
||||||
|
stop_line_indx: 4,
|
||||||
|
pos_in_stop_line: 5,
|
||||||
|
};
|
||||||
|
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) =>
|
||||||
|
@ -269,146 +277,6 @@ fn run_event_loop() -> Result<(), Box<dyn Error>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn create_selection_rects(
|
|
||||||
start_line_indx: usize,
|
|
||||||
pos_in_start_line: usize,
|
|
||||||
stop_line_indx: usize,
|
|
||||||
pos_in_stop_line: usize,
|
|
||||||
glyph_bound_rects: &Vec<Vec<Rect>>
|
|
||||||
) -> EdResult<Vec<Rect>> {
|
|
||||||
//TODO assert start_line <= stop_line, if start_line == stop_line => pos_in_start_line <= pos_in_stop_line
|
|
||||||
|
|
||||||
let mut all_rects = Vec::new();
|
|
||||||
|
|
||||||
if start_line_indx == stop_line_indx {
|
|
||||||
let start_glyph_rect =
|
|
||||||
get_res(
|
|
||||||
pos_in_start_line,
|
|
||||||
get_res(start_line_indx, glyph_bound_rects)?,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let stop_glyph_rect =
|
|
||||||
get_res(
|
|
||||||
pos_in_stop_line,
|
|
||||||
get_res(stop_line_indx, glyph_bound_rects)?
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let top_left_coords =
|
|
||||||
start_glyph_rect.top_left_coords;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
all_rects.push(
|
|
||||||
Rect {
|
|
||||||
top_left_coords,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
color: colors::WHITE
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(all_rects)
|
|
||||||
} else {
|
|
||||||
// first line
|
|
||||||
let start_line = get_res(start_line_indx, glyph_bound_rects)?;
|
|
||||||
|
|
||||||
let start_glyph_rect =
|
|
||||||
get_res(
|
|
||||||
pos_in_start_line,
|
|
||||||
start_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let start_line_last_glyph_rect =
|
|
||||||
get_res(
|
|
||||||
start_line.len() - 1,
|
|
||||||
start_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let top_left_coords =
|
|
||||||
start_glyph_rect.top_left_coords;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
all_rects.push(
|
|
||||||
Rect {
|
|
||||||
top_left_coords,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
color: colors::WHITE
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
//middle lines
|
|
||||||
let nr_mid_lines = (stop_line_indx - start_line_indx) - 1;
|
|
||||||
let first_mid_line = start_line_indx + 1;
|
|
||||||
|
|
||||||
for i in first_mid_line..(first_mid_line + nr_mid_lines) {
|
|
||||||
let mid_line = get_res(i, glyph_bound_rects)?;
|
|
||||||
|
|
||||||
let mid_line_first_glyph_rect =
|
|
||||||
get_res(
|
|
||||||
0,
|
|
||||||
mid_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let mid_line_last_glyph_rect =
|
|
||||||
get_res(
|
|
||||||
mid_line.len() - 1,
|
|
||||||
mid_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let top_left_coords =
|
|
||||||
mid_line_first_glyph_rect.top_left_coords;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
all_rects.push(
|
|
||||||
Rect {
|
|
||||||
top_left_coords,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
color: colors::WHITE
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
//last line
|
|
||||||
let stop_line = get_res(stop_line_indx, glyph_bound_rects)?;
|
|
||||||
|
|
||||||
let stop_line_first_glyph_rect =
|
|
||||||
get_res(
|
|
||||||
0,
|
|
||||||
stop_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let stop_glyph_rect =
|
|
||||||
get_res(
|
|
||||||
pos_in_stop_line,
|
|
||||||
stop_line
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let top_left_coords =
|
|
||||||
stop_line_first_glyph_rect.top_left_coords;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
all_rects.push(
|
|
||||||
Rect {
|
|
||||||
top_left_coords,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
color: colors::WHITE
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(all_rects)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn make_rect_pipeline(
|
fn make_rect_pipeline(
|
||||||
gpu_device: &wgpu::Device,
|
gpu_device: &wgpu::Device,
|
||||||
swap_chain_descr: &wgpu::SwapChainDescriptor,
|
swap_chain_descr: &wgpu::SwapChainDescriptor,
|
||||||
|
|
189
editor/src/selection.rs
Normal file
189
editor/src/selection.rs
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
|
||||||
|
use crate::rect::{Rect};
|
||||||
|
use crate::vec_result::{get_res};
|
||||||
|
use crate::error::{EdResult, InvalidSelection};
|
||||||
|
use crate::colors;
|
||||||
|
use snafu::ensure;
|
||||||
|
|
||||||
|
pub struct RawSelection {
|
||||||
|
pub start_line_indx: usize,
|
||||||
|
pub pos_in_start_line: usize,
|
||||||
|
pub stop_line_indx: usize,
|
||||||
|
pub pos_in_stop_line: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
//using the "parse don't validate" pattern
|
||||||
|
struct ValidSelection {
|
||||||
|
selection: RawSelection
|
||||||
|
}
|
||||||
|
|
||||||
|
fn validate_selection( selection: RawSelection) -> EdResult<ValidSelection> {
|
||||||
|
let RawSelection {start_line_indx, pos_in_start_line, stop_line_indx, pos_in_stop_line} = selection;
|
||||||
|
|
||||||
|
ensure!(
|
||||||
|
start_line_indx <= stop_line_indx,
|
||||||
|
InvalidSelection { err_msg:
|
||||||
|
format!(
|
||||||
|
"start_line_indx ({}) should be smaller than or equal to stop_line_indx ({})",
|
||||||
|
start_line_indx,
|
||||||
|
stop_line_indx
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
ensure!(
|
||||||
|
!(start_line_indx == stop_line_indx && pos_in_start_line > pos_in_stop_line),
|
||||||
|
InvalidSelection { err_msg:
|
||||||
|
format!(
|
||||||
|
"pos_in_start_line ({}) should be smaller than or equal to pos_in_stop_line ({}) when start_line_indx equals stop_line_indx",
|
||||||
|
pos_in_start_line,
|
||||||
|
pos_in_stop_line
|
||||||
|
)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
ValidSelection {
|
||||||
|
selection
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn create_selection_rects(
|
||||||
|
raw_sel: RawSelection,
|
||||||
|
glyph_bound_rects: &Vec<Vec<Rect>>
|
||||||
|
) -> EdResult<Vec<Rect>> {
|
||||||
|
let valid_sel = validate_selection(raw_sel)?;
|
||||||
|
let RawSelection {start_line_indx, pos_in_start_line, stop_line_indx, pos_in_stop_line} = valid_sel.selection;
|
||||||
|
|
||||||
|
let mut all_rects = Vec::new();
|
||||||
|
|
||||||
|
if start_line_indx == stop_line_indx {
|
||||||
|
let start_glyph_rect =
|
||||||
|
get_res(
|
||||||
|
pos_in_start_line,
|
||||||
|
get_res(start_line_indx, glyph_bound_rects)?,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let stop_glyph_rect =
|
||||||
|
get_res(
|
||||||
|
pos_in_stop_line,
|
||||||
|
get_res(stop_line_indx, glyph_bound_rects)?
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let top_left_coords =
|
||||||
|
start_glyph_rect.top_left_coords;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
all_rects.push(
|
||||||
|
Rect {
|
||||||
|
top_left_coords,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
color: colors::WHITE
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(all_rects)
|
||||||
|
} else {
|
||||||
|
// first line
|
||||||
|
let start_line = get_res(start_line_indx, glyph_bound_rects)?;
|
||||||
|
|
||||||
|
let start_glyph_rect =
|
||||||
|
get_res(
|
||||||
|
pos_in_start_line,
|
||||||
|
start_line
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let start_line_last_glyph_rect =
|
||||||
|
get_res(
|
||||||
|
start_line.len() - 1,
|
||||||
|
start_line
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let top_left_coords =
|
||||||
|
start_glyph_rect.top_left_coords;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
all_rects.push(
|
||||||
|
Rect {
|
||||||
|
top_left_coords,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
color: colors::WHITE
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
//middle lines
|
||||||
|
let nr_mid_lines = (stop_line_indx - start_line_indx) - 1;
|
||||||
|
let first_mid_line = start_line_indx + 1;
|
||||||
|
|
||||||
|
for i in first_mid_line..(first_mid_line + nr_mid_lines) {
|
||||||
|
let mid_line = get_res(i, glyph_bound_rects)?;
|
||||||
|
|
||||||
|
let mid_line_first_glyph_rect =
|
||||||
|
get_res(
|
||||||
|
0,
|
||||||
|
mid_line
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let mid_line_last_glyph_rect =
|
||||||
|
get_res(
|
||||||
|
mid_line.len() - 1,
|
||||||
|
mid_line
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let top_left_coords =
|
||||||
|
mid_line_first_glyph_rect.top_left_coords;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
all_rects.push(
|
||||||
|
Rect {
|
||||||
|
top_left_coords,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
color: colors::WHITE
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//last line
|
||||||
|
let stop_line = get_res(stop_line_indx, glyph_bound_rects)?;
|
||||||
|
|
||||||
|
let stop_line_first_glyph_rect =
|
||||||
|
get_res(
|
||||||
|
0,
|
||||||
|
stop_line
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let stop_glyph_rect =
|
||||||
|
get_res(
|
||||||
|
pos_in_stop_line,
|
||||||
|
stop_line
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let top_left_coords =
|
||||||
|
stop_line_first_glyph_rect.top_left_coords;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
all_rects.push(
|
||||||
|
Rect {
|
||||||
|
top_left_coords,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
color: colors::WHITE
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(all_rects)
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,7 @@ 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: &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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue