gpui: Unify the index_for_x methods (#42162)
Supersedes https://github.com/zed-industries/zed/pull/39910 At some point, these two (`index_for_x` and `closest_index_for_x`) methods where separated out and some code paths used one, while other code paths took the other. That said, their behavior is almost identical: - `index_for_x` computes the index behind the pixel offset, and returns `None` if there's an overshoot - `closest_index_for_x` computes the nearest index to the pixel offset, taking into account whether the offset is over halfway through or not. If there's an overshoot, it returns the length of the line. Given these two behaviors, `closest_index_for_x` seems to be a more useful API than `index_for_x`, and indeed the display map and other core editor features use it extensively. So this PR is an experiment in simply replacing one behavior with the other. Release Notes: - Improved the accuracy of mouse selections in Markdown
This commit is contained in:
@@ -54,25 +54,9 @@ pub struct ShapedGlyph {
|
||||
}
|
||||
|
||||
impl LineLayout {
|
||||
/// The index for the character at the given x coordinate
|
||||
pub fn index_for_x(&self, x: Pixels) -> Option<usize> {
|
||||
if x >= self.width {
|
||||
None
|
||||
} else {
|
||||
for run in self.runs.iter().rev() {
|
||||
for glyph in run.glyphs.iter().rev() {
|
||||
if glyph.position.x <= x {
|
||||
return Some(glyph.index);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(0)
|
||||
}
|
||||
}
|
||||
|
||||
/// 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: Pixels) -> usize {
|
||||
pub fn index_for_x(&self, x: Pixels) -> usize {
|
||||
let mut prev_index = 0;
|
||||
let mut prev_x = px(0.);
|
||||
|
||||
@@ -278,34 +262,10 @@ impl WrappedLineLayout {
|
||||
}
|
||||
|
||||
/// The index corresponding to a given position in this layout for the given line height.
|
||||
///
|
||||
/// See also [`Self::closest_index_for_position`].
|
||||
pub fn index_for_position(
|
||||
&self,
|
||||
position: Point<Pixels>,
|
||||
line_height: Pixels,
|
||||
) -> Result<usize, usize> {
|
||||
self._index_for_position(position, line_height, false)
|
||||
}
|
||||
|
||||
/// The closest index to a given position in this layout for the given line height.
|
||||
///
|
||||
/// Closest means the character boundary closest to the given position.
|
||||
///
|
||||
/// See also [`LineLayout::closest_index_for_x`].
|
||||
pub fn closest_index_for_position(
|
||||
&self,
|
||||
position: Point<Pixels>,
|
||||
line_height: Pixels,
|
||||
) -> Result<usize, usize> {
|
||||
self._index_for_position(position, line_height, true)
|
||||
}
|
||||
|
||||
fn _index_for_position(
|
||||
&self,
|
||||
mut position: Point<Pixels>,
|
||||
line_height: Pixels,
|
||||
closest: bool,
|
||||
) -> Result<usize, usize> {
|
||||
let wrapped_line_ix = (position.y / line_height) as usize;
|
||||
|
||||
@@ -345,16 +305,9 @@ impl WrappedLineLayout {
|
||||
} else if position_in_unwrapped_line.x >= wrapped_line_end_x {
|
||||
Err(wrapped_line_end_index)
|
||||
} else {
|
||||
if closest {
|
||||
Ok(self
|
||||
.unwrapped_layout
|
||||
.closest_index_for_x(position_in_unwrapped_line.x))
|
||||
} else {
|
||||
Ok(self
|
||||
.unwrapped_layout
|
||||
.index_for_x(position_in_unwrapped_line.x)
|
||||
.unwrap())
|
||||
}
|
||||
Ok(self
|
||||
.unwrapped_layout
|
||||
.index_for_x(position_in_unwrapped_line.x))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user