From 002e2cc42c41f4fcb847061ce0b25721fa1895d5 Mon Sep 17 00:00:00 2001 From: Conrad Irwin Date: Thu, 28 Sep 2023 22:40:27 -0600 Subject: [PATCH] Round better for up/down --- crates/editor/src/display_map.rs | 4 ++-- crates/editor/src/movement.rs | 8 ++------ crates/gpui/src/text_layout.rs | 24 ++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index cebafbd651..424ff1518a 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -618,9 +618,9 @@ impl DisplaySnapshot { display_row: u32, x_coordinate: f32, text_layout_details: &TextLayoutDetails, - ) -> Option { + ) -> u32 { let layout_line = self.layout_line_for_row(display_row, text_layout_details); - layout_line.index_for_x(x_coordinate).map(|c| c as u32) + layout_line.closest_index_for_x(x_coordinate) as u32 } // column_for_x(row, x) diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index e2306a1b2d..38cf5cd6c1 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -115,9 +115,7 @@ pub fn up_by_rows( Bias::Left, ); if point.row() < start.row() { - *point.column_mut() = map - .column_for_x(point.row(), goal_x, text_layout_details) - .unwrap_or(point.column()); + *point.column_mut() = map.column_for_x(point.row(), goal_x, text_layout_details) } else if preserve_column_at_start { return (start, goal); } else { @@ -149,9 +147,7 @@ pub fn down_by_rows( let new_row = start.row() + row_count; let mut point = map.clip_point(DisplayPoint::new(new_row, 0), Bias::Right); if point.row() > start.row() { - *point.column_mut() = map - .column_for_x(point.row(), goal_x, text_layout_details) - .unwrap_or(map.line_len(point.row())); + *point.column_mut() = map.column_for_x(point.row(), goal_x, text_layout_details) } else if preserve_column_at_end { return (start, goal); } else { diff --git a/crates/gpui/src/text_layout.rs b/crates/gpui/src/text_layout.rs index 97f4b7a12d..7fb87b10df 100644 --- a/crates/gpui/src/text_layout.rs +++ b/crates/gpui/src/text_layout.rs @@ -266,6 +266,8 @@ impl Line { self.layout.len == 0 } + /// index_for_x returns the character containing the given x coordinate. + /// (e.g. to handle a mouse-click) pub fn index_for_x(&self, x: f32) -> Option { if x >= self.layout.width { None @@ -281,6 +283,28 @@ impl Line { } } + /// closest_index_for_x returns the character boundary closest to the given x coordinate + /// (e.g. to handle aligning up/down arrow keys) + pub fn closest_index_for_x(&self, x: f32) -> usize { + let mut prev_index = 0; + let mut prev_x = 0.0; + + for run in self.layout.runs.iter() { + for glyph in run.glyphs.iter() { + if glyph.position.x() >= x { + if glyph.position.x() - x < x - prev_x { + return glyph.index; + } else { + return prev_index; + } + } + prev_index = glyph.index; + prev_x = glyph.position.x(); + } + } + prev_index + } + pub fn paint( &self, origin: Vector2F,