Unify Cursor, Location and name it Point

This commit is contained in:
Joe Wilm 2016-12-29 11:09:29 -05:00
parent 5ee031f55f
commit 689e0f4ad7
5 changed files with 60 additions and 67 deletions

View File

@ -27,7 +27,7 @@ use std::ops::{Deref, DerefMut, Range, RangeTo, RangeFrom, RangeFull, Index, Ind
use std::ops::RangeInclusive;
use std::slice::{self, Iter, IterMut};
use index::{self, Cursor};
use index::{self, Point};
/// Convert a type to a linear index range.
pub trait ToRange {
@ -141,8 +141,8 @@ impl<T> Grid<T> {
}
#[inline]
pub fn contains(&self, cursor: &Cursor) -> bool {
self.lines > cursor.line && self.cols > cursor.col
pub fn contains(&self, point: &Point) -> bool {
self.lines > point.line && self.cols > point.col
}
/// Swap two lines in the grid
@ -210,19 +210,19 @@ impl<T> IndexMut<index::Line> for Grid<T> {
}
}
impl<'cursor, T> Index<&'cursor Cursor> for Grid<T> {
impl<'point, T> Index<&'point Point> for Grid<T> {
type Output = T;
#[inline]
fn index<'a>(&'a self, cursor: &Cursor) -> &'a T {
&self.raw[cursor.line.0][cursor.col]
fn index<'a>(&'a self, point: &Point) -> &'a T {
&self.raw[point.line.0][point.col]
}
}
impl<'cursor, T> IndexMut<&'cursor Cursor> for Grid<T> {
impl<'point, T> IndexMut<&'point Point> for Grid<T> {
#[inline]
fn index_mut<'a, 'b>(&'a mut self, cursor: &'b Cursor) -> &'a mut T {
&mut self.raw[cursor.line.0][cursor.col]
fn index_mut<'a, 'b>(&'a mut self, point: &'b Point) -> &'a mut T {
&mut self.raw[point.line.0][point.col]
}
}

View File

@ -29,27 +29,20 @@ pub enum Side {
}
/// Index in the grid using row, column notation
#[derive(Debug, Clone, Default, Eq, PartialEq, Serialize, Deserialize)]
pub struct Cursor {
pub line: Line,
pub col: Column,
}
/// Location
#[derive(Debug, Clone, Copy, Default, Eq, PartialEq, Serialize, Deserialize, PartialOrd)]
pub struct Location {
pub struct Point {
pub line: Line,
pub col: Column,
}
impl Location {
pub fn new(line: Line, col: Column) -> Location {
Location { line: line, col: col }
impl Point {
pub fn new(line: Line, col: Column) -> Point {
Point { line: line, col: col }
}
}
impl Ord for Location {
fn cmp(&self, other: &Location) -> Ordering {
impl Ord for Point {
fn cmp(&self, other: &Point) -> Ordering {
use std::cmp::Ordering::*;
match (self.line.cmp(&other.line), self.col.cmp(&other.col)) {
(Equal, Equal) => Equal,
@ -331,15 +324,15 @@ ops!(Linear, Linear);
#[cfg(test)]
mod tests {
use super::{Line, Column, Location};
use super::{Line, Column, Point};
#[test]
fn location_ordering() {
assert!(Location::new(Line(0), Column(0)) == Location::new(Line(0), Column(0)));
assert!(Location::new(Line(1), Column(0)) > Location::new(Line(0), Column(0)));
assert!(Location::new(Line(0), Column(1)) > Location::new(Line(0), Column(0)));
assert!(Location::new(Line(1), Column(1)) > Location::new(Line(0), Column(0)));
assert!(Location::new(Line(1), Column(1)) > Location::new(Line(0), Column(1)));
assert!(Location::new(Line(1), Column(1)) > Location::new(Line(1), Column(0)));
assert!(Point::new(Line(0), Column(0)) == Point::new(Line(0), Column(0)));
assert!(Point::new(Line(1), Column(0)) > Point::new(Line(0), Column(0)));
assert!(Point::new(Line(0), Column(1)) > Point::new(Line(0), Column(0)));
assert!(Point::new(Line(1), Column(1)) > Point::new(Line(0), Column(0)));
assert!(Point::new(Line(1), Column(1)) > Point::new(Line(0), Column(1)));
assert!(Point::new(Line(1), Column(1)) > Point::new(Line(1), Column(0)));
}
}

View File

@ -29,7 +29,7 @@ use glutin::{Mods, mods};
use glutin::{TouchPhase, MouseScrollDelta};
use event::Notify;
use index::{Line, Column, Side, Location};
use index::{Line, Column, Side, Point};
use selection::Selection;
use term::mode::{self, TermMode};
use term::{self, Term};
@ -209,7 +209,7 @@ impl<'a, N: Notify + 'a> Processor<'a, N> {
if self.ctx.mouse.left_button_state == ElementState::Pressed &&
!self.ctx.terminal.mode().contains(mode::MOUSE_REPORT_CLICK)
{
self.ctx.selection.update(Location {
self.ctx.selection.update(Point {
line: line,
col: column
}, self.ctx.mouse.cell_side);

View File

@ -21,7 +21,7 @@
use std::mem;
use std::ops::RangeInclusive;
use index::{Location, Column, Side, Linear, Line};
use index::{Point, Column, Side, Linear, Line};
use grid::ToRange;
/// The area selected
@ -34,8 +34,8 @@ pub enum Selection {
Empty,
Active {
start: Location,
end: Location,
start: Point,
end: Point,
start_side: Side,
end_side: Side
},
@ -66,7 +66,7 @@ impl Selection {
}
}
pub fn update(&mut self, location: Location, side: Side) {
pub fn update(&mut self, location: Point, side: Side) {
let selection = mem::replace(self, Selection::Empty);
let selection = match selection {
Selection::Empty => {
@ -172,15 +172,15 @@ pub enum SpanType {
/// Represents a span of selected cells
#[derive(Debug, Eq, PartialEq)]
pub struct Span {
front: Location,
tail: Location,
front: Point,
tail: Point,
/// The type says whether ends are included or not.
ty: SpanType,
}
impl Span {
pub fn to_locations(&self, cols: Column) -> (Location, Location) {
pub fn to_locations(&self, cols: Column) -> (Point, Point) {
match self.ty {
SpanType::Inclusive => (self.front, self.tail),
SpanType::Exclusive => {
@ -191,9 +191,9 @@ impl Span {
}
}
fn wrap_start(mut start: Location, cols: Column) -> Location {
fn wrap_start(mut start: Point, cols: Column) -> Point {
if start.col == cols - 1 {
Location {
Point {
line: start.line + 1,
col: Column(0),
}
@ -203,14 +203,14 @@ impl Span {
}
}
fn wrap_end(end: Location, cols: Column) -> Location {
fn wrap_end(end: Point, cols: Column) -> Point {
if end.col == Column(0) && end.line != Line(0) {
Location {
Point {
line: end.line - 1,
col: cols
}
} else {
Location {
Point {
line: end.line,
col: end.col - 1
}
@ -259,7 +259,7 @@ impl ToRange for Span {
/// look like [ B] and [E ].
#[cfg(test)]
mod test {
use index::{Line, Column, Side, Location};
use index::{Line, Column, Side, Point};
use super::{Selection, Span, SpanType};
/// Test case of single cell selection
@ -269,7 +269,7 @@ mod test {
/// 3. [BE]
#[test]
fn single_cell_left_to_right() {
let location = Location { line: Line(0), col: Column(0) };
let location = Point { line: Line(0), col: Column(0) };
let mut selection = Selection::Empty;
selection.update(location, Side::Left);
selection.update(location, Side::Right);
@ -288,7 +288,7 @@ mod test {
/// 3. [EB]
#[test]
fn single_cell_right_to_left() {
let location = Location { line: Line(0), col: Column(0) };
let location = Point { line: Line(0), col: Column(0) };
let mut selection = Selection::Empty;
selection.update(location, Side::Right);
selection.update(location, Side::Left);
@ -308,8 +308,8 @@ mod test {
#[test]
fn between_adjacent_cells_left_to_right() {
let mut selection = Selection::Empty;
selection.update(Location::new(Line(0), Column(0)), Side::Right);
selection.update(Location::new(Line(0), Column(1)), Side::Left);
selection.update(Point::new(Line(0), Column(0)), Side::Right);
selection.update(Point::new(Line(0), Column(1)), Side::Left);
assert_eq!(selection.span(), None);
}
@ -322,8 +322,8 @@ mod test {
#[test]
fn between_adjacent_cells_right_to_left() {
let mut selection = Selection::Empty;
selection.update(Location::new(Line(0), Column(1)), Side::Left);
selection.update(Location::new(Line(0), Column(0)), Side::Right);
selection.update(Point::new(Line(0), Column(1)), Side::Left);
selection.update(Point::new(Line(0), Column(0)), Side::Right);
assert_eq!(selection.span(), None);
}
@ -340,12 +340,12 @@ mod test {
#[test]
fn across_adjacent_lines_upward_final_cell_exclusive() {
let mut selection = Selection::Empty;
selection.update(Location::new(Line(1), Column(1)), Side::Right);
selection.update(Location::new(Line(0), Column(1)), Side::Right);
selection.update(Point::new(Line(1), Column(1)), Side::Right);
selection.update(Point::new(Line(0), Column(1)), Side::Right);
assert_eq!(selection.span().unwrap(), Span {
front: Location::new(Line(0), Column(1)),
tail: Location::new(Line(1), Column(1)),
front: Point::new(Line(0), Column(1)),
tail: Point::new(Line(1), Column(1)),
ty: SpanType::ExcludeFront
});
}
@ -364,13 +364,13 @@ mod test {
#[test]
fn selection_bigger_then_smaller() {
let mut selection = Selection::Empty;
selection.update(Location::new(Line(0), Column(1)), Side::Right);
selection.update(Location::new(Line(1), Column(1)), Side::Right);
selection.update(Location::new(Line(1), Column(0)), Side::Right);
selection.update(Point::new(Line(0), Column(1)), Side::Right);
selection.update(Point::new(Line(1), Column(1)), Side::Right);
selection.update(Point::new(Line(1), Column(0)), Side::Right);
assert_eq!(selection.span().unwrap(), Span {
front: Location::new(Line(0), Column(1)),
tail: Location::new(Line(1), Column(0)),
front: Point::new(Line(0), Column(1)),
tail: Point::new(Line(1), Column(0)),
ty: SpanType::ExcludeFront
});
}

View File

@ -20,7 +20,7 @@ use std::io;
use ansi::{self, Color, NamedColor, Attr, Handler};
use grid::{Grid, ClearRegion, ToRange};
use index::{self, Cursor, Column, Line, Linear};
use index::{self, Point, Column, Line, Linear};
use selection::{Span, Selection};
pub mod cell;
@ -37,7 +37,7 @@ use self::cell::LineLength;
/// draw it, and reverted after drawing to maintain state.
pub struct RenderableCellsIter<'a> {
grid: &'a mut Grid<Cell>,
cursor: &'a Cursor,
cursor: &'a Point,
mode: TermMode,
line: Line,
column: Column,
@ -51,7 +51,7 @@ impl<'a> RenderableCellsIter<'a> {
/// cursor.
fn new<'b>(
grid: &'b mut Grid<Cell>,
cursor: &'b Cursor,
cursor: &'b Point,
mode: TermMode,
selection: &Selection,
) -> RenderableCellsIter<'b> {
@ -207,10 +207,10 @@ pub struct Term {
alt: bool,
/// The cursor
cursor: Cursor,
cursor: Point,
/// Alt cursor
alt_cursor: Cursor,
alt_cursor: Point,
/// Tabstops
tabs: Vec<bool>,
@ -299,8 +299,8 @@ impl Term {
grid: grid,
alt_grid: alt,
alt: false,
cursor: Cursor::default(),
alt_cursor: Cursor::default(),
cursor: Point::default(),
alt_cursor: Point::default(),
tabs: tabs,
mode: Default::default(),
scroll_region: scroll_region,
@ -585,7 +585,7 @@ impl ansi::Handler for Term {
if self.cursor.col == self.grid.num_cols() {
debug_println!("wrapping");
{
let location = Cursor {
let location = Point {
line: self.cursor.line,
col: self.cursor.col - 1
};