summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/event.rs12
-rw-r--r--src/input.rs87
-rw-r--r--src/selection.rs27
-rw-r--r--src/term/mod.rs22
4 files changed, 83 insertions, 65 deletions
diff --git a/src/event.rs b/src/event.rs
index 14ec0b0e..b0987d58 100644
--- a/src/event.rs
+++ b/src/event.rs
@@ -154,8 +154,8 @@ pub enum ClickState {
/// State of the mouse
pub struct Mouse {
- pub x: u32,
- pub y: u32,
+ pub x: usize,
+ pub y: usize,
pub left_button_state: ElementState,
pub middle_button_state: ElementState,
pub right_button_state: ElementState,
@@ -315,13 +315,11 @@ impl<N: Notify> Processor<N> {
processor.ctx.terminal.dirty = true;
},
CursorMoved { position: (x, y), modifiers, .. } => {
- let x = x as i32;
- let y = y as i32;
- let x = limit(x, 0, processor.ctx.size_info.width as i32);
- let y = limit(y, 0, processor.ctx.size_info.height as i32);
+ let x = limit(x as i32, 0, processor.ctx.size_info.width as i32);
+ let y = limit(y as i32, 0, processor.ctx.size_info.height as i32);
*hide_cursor = false;
- processor.mouse_moved(x as u32, y as u32, modifiers);
+ processor.mouse_moved(x as usize, y as usize, modifiers);
},
MouseWheel { delta, phase, modifiers, .. } => {
*hide_cursor = false;
diff --git a/src/input.rs b/src/input.rs
index 7b9eda56..98e0d241 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -266,55 +266,52 @@ impl From<&'static str> for Action {
impl<'a, A: ActionContext + 'a> Processor<'a, A> {
#[inline]
- pub fn mouse_moved(&mut self, x: u32, y: u32, modifiers: ModifiersState) {
+ pub fn mouse_moved(&mut self, x: usize, y: usize, modifiers: ModifiersState) {
self.ctx.mouse_mut().x = x;
self.ctx.mouse_mut().y = y;
let size_info = self.ctx.size_info();
- if let Some(point) = size_info.pixels_to_coords(x as usize, y as usize) {
- let prev_line = mem::replace(&mut self.ctx.mouse_mut().line, point.line);
- let prev_col = mem::replace(&mut self.ctx.mouse_mut().column, point.col);
-
- let cell_x = (x as usize - size_info.padding_x as usize) % size_info.cell_width as usize;
- let half_cell_width = (size_info.cell_width / 2.0) as usize;
-
- let cell_side = if cell_x > half_cell_width
- // Edge case when mouse leaves the window
- || x as f32 >= size_info.width - size_info.padding_x
- {
- Side::Right
- } else {
- Side::Left
- };
- self.ctx.mouse_mut().cell_side = cell_side;
-
- let motion_mode = TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG;
- if self.ctx.mouse_mut().left_button_state == ElementState::Pressed
- && (
- modifiers.shift
- || !self.ctx.terminal_mode().intersects(TermMode::MOUSE_REPORT_CLICK | motion_mode)
- )
- {
- self.ctx.update_selection(Point {
- line: point.line,
- col: point.col
- }, cell_side);
- } else if self.ctx.terminal_mode().intersects(motion_mode)
- // Only report motion when changing cells
- && (
- prev_line != self.ctx.mouse_mut().line
- || prev_col != self.ctx.mouse_mut().column
- )
- {
- if self.ctx.mouse_mut().left_button_state == ElementState::Pressed {
- self.mouse_report(32, ElementState::Pressed, modifiers);
- } else if self.ctx.mouse_mut().middle_button_state == ElementState::Pressed {
- self.mouse_report(33, ElementState::Pressed, modifiers);
- } else if self.ctx.mouse_mut().right_button_state == ElementState::Pressed {
- self.mouse_report(34, ElementState::Pressed, modifiers);
- } else if self.ctx.terminal_mode().contains(TermMode::MOUSE_MOTION) {
- self.mouse_report(35, ElementState::Pressed, modifiers);
- }
+ let point = size_info.pixels_to_coords(x, y);
+
+ let prev_line = mem::replace(&mut self.ctx.mouse_mut().line, point.line);
+ let prev_col = mem::replace(&mut self.ctx.mouse_mut().column, point.col);
+
+ let cell_x = x.saturating_sub(size_info.padding_x as usize) % size_info.cell_width as usize;
+ let half_cell_width = (size_info.cell_width / 2.0) as usize;
+
+ let cell_side = if cell_x > half_cell_width
+ // Edge case when mouse leaves the window
+ || x as f32 >= size_info.width - size_info.padding_x
+ {
+ Side::Right
+ } else {
+ Side::Left
+ };
+ self.ctx.mouse_mut().cell_side = cell_side;
+
+ let motion_mode = TermMode::MOUSE_MOTION | TermMode::MOUSE_DRAG;
+ let report_mode = TermMode::MOUSE_REPORT_CLICK | motion_mode;
+
+ if self.ctx.mouse_mut().left_button_state == ElementState::Pressed &&
+ ( modifiers.shift || !self.ctx.terminal_mode().intersects(report_mode))
+ {
+ self.ctx.update_selection(Point {
+ line: point.line,
+ col: point.col
+ }, cell_side);
+ } else if self.ctx.terminal_mode().intersects(motion_mode)
+ // Only report motion when changing cells
+ && (prev_line != self.ctx.mouse_mut().line || prev_col != self.ctx.mouse_mut().column)
+ && size_info.contains_point(x, y)
+ {
+ if self.ctx.mouse_mut().left_button_state == ElementState::Pressed {
+ self.mouse_report(32, ElementState::Pressed, modifiers);
+ } else if self.ctx.mouse_mut().middle_button_state == ElementState::Pressed {
+ self.mouse_report(33, ElementState::Pressed, modifiers);
+ } else if self.ctx.mouse_mut().right_button_state == ElementState::Pressed {
+ self.mouse_report(34, ElementState::Pressed, modifiers);
+ } else if self.ctx.terminal_mode().contains(TermMode::MOUSE_MOTION) {
+ self.mouse_report(35, ElementState::Pressed, modifiers);
}
}
}
diff --git a/src/selection.rs b/src/selection.rs
index 8e7fa29b..d49236a4 100644
--- a/src/selection.rs
+++ b/src/selection.rs
@@ -253,8 +253,31 @@ impl Selection {
// Handle some edge cases
if start.line > end.line {
- start.col += 1;
- end.col -= 1;
+ if end.col > Column(0) {
+ start.col += 1;
+ end.col -= 1;
+ }
+ // Special case for when a multi-line selection to the
+ // bottom ends on a new line with just one cell selected
+ // and the first cell should not be selected
+ else {
+ if start_side == Side::Right {
+ start.col += 1;
+ }
+
+ // Remove the single selected cell if mouse left window
+ if end_side == Side::Left {
+ end.line += 1;
+ end.col = cols - 1;
+ }
+
+ return Some(Span {
+ cols,
+ front: end,
+ tail: start,
+ ty: SpanType::Inclusive,
+ });
+ }
} else if start.line < end.line {
start.col -= 1;
end.col += 1;
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 6318c680..8db21402 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -791,25 +791,21 @@ impl SizeInfo {
Column(((self.width - 2. * self.padding_x) / self.cell_width) as usize)
}
- fn contains_point(&self, x: usize, y:usize) -> bool {
+ pub fn contains_point(&self, x: usize, y:usize) -> bool {
x <= (self.width - self.padding_x) as usize &&
x >= self.padding_x as usize &&
y <= (self.height - self.padding_y) as usize &&
y >= self.padding_y as usize
}
- pub fn pixels_to_coords(&self, x: usize, y: usize) -> Option<Point> {
- if !self.contains_point(x, y) {
- return None;
- }
+ pub fn pixels_to_coords(&self, x: usize, y: usize) -> Point {
+ let col = Column(x.saturating_sub(self.padding_x as usize) / (self.cell_width as usize));
+ let line = Line(y.saturating_sub(self.padding_y as usize) / (self.cell_height as usize));
- let col = Column((x - self.padding_x as usize) / (self.cell_width as usize));
- let line = Line((y - self.padding_y as usize) / (self.cell_height as usize));
-
- Some(Point {
+ Point {
line: min(line, self.lines() - 1),
col: min(col, self.cols() - 1)
- })
+ }
}
}
@@ -1036,7 +1032,11 @@ impl Term {
///
/// Returns None if the coordinates are outside the screen
pub fn pixels_to_coords(&self, x: usize, y: usize) -> Option<Point> {
- self.size_info().pixels_to_coords(x, y)
+ if self.size_info.contains_point(x, y) {
+ Some(self.size_info.pixels_to_coords(x, y))
+ } else {
+ None
+ }
}
/// Access to the raw grid data structure