editor: Reapply fix for wrap guide positioning (#33776)
Reapplies the fix from #33514 which was removed in #33554. Wrap guides are currently drifting again due to this on main. Slightly changed the approach here so that we now actually only save the wrap guides in the `EditorLayout` that will actually be painted. Also ensures that we paint indent guides that were previously hidden behind the vertical scrollbar once it auto-hides. I wanted to add tests for this, however, I am rather sure this depends on the work/fixes in #33590 and thus I'd prefer to add these later so we can have this fix in the next release. Release Notes: - N/A
This commit is contained in:
parent
5c88e9c66b
commit
06ddc74917
1 changed files with 58 additions and 50 deletions
|
@ -2444,7 +2444,7 @@ impl EditorElement {
|
|||
.git
|
||||
.inline_blame
|
||||
.and_then(|settings| settings.min_column)
|
||||
.map(|col| self.column_pixels(col as usize, window, cx))
|
||||
.map(|col| self.column_pixels(col as usize, window))
|
||||
.unwrap_or(px(0.));
|
||||
let min_start = content_origin.x - scroll_pixel_position.x + min_column_in_pixels;
|
||||
|
||||
|
@ -2629,7 +2629,7 @@ impl EditorElement {
|
|||
.enumerate()
|
||||
.filter_map(|(i, indent_guide)| {
|
||||
let single_indent_width =
|
||||
self.column_pixels(indent_guide.tab_size as usize, window, cx);
|
||||
self.column_pixels(indent_guide.tab_size as usize, window);
|
||||
let total_width = single_indent_width * indent_guide.depth as f32;
|
||||
let start_x = content_origin.x + total_width - scroll_pixel_position.x;
|
||||
if start_x >= text_origin.x {
|
||||
|
@ -2657,6 +2657,39 @@ impl EditorElement {
|
|||
)
|
||||
}
|
||||
|
||||
fn layout_wrap_guides(
|
||||
&self,
|
||||
em_advance: Pixels,
|
||||
scroll_position: gpui::Point<f32>,
|
||||
content_origin: gpui::Point<Pixels>,
|
||||
scrollbar_layout: Option<&EditorScrollbars>,
|
||||
vertical_scrollbar_width: Pixels,
|
||||
hitbox: &Hitbox,
|
||||
window: &Window,
|
||||
cx: &App,
|
||||
) -> SmallVec<[(Pixels, bool); 2]> {
|
||||
let scroll_left = scroll_position.x * em_advance;
|
||||
let content_origin = content_origin.x;
|
||||
let horizontal_offset = content_origin - scroll_left;
|
||||
let vertical_scrollbar_width = scrollbar_layout
|
||||
.and_then(|layout| layout.visible.then_some(vertical_scrollbar_width))
|
||||
.unwrap_or_default();
|
||||
|
||||
self.editor
|
||||
.read(cx)
|
||||
.wrap_guides(cx)
|
||||
.into_iter()
|
||||
.flat_map(|(guide, active)| {
|
||||
let wrap_position = self.column_pixels(guide, window);
|
||||
let wrap_guide_x = wrap_position + horizontal_offset;
|
||||
let display_wrap_guide = wrap_guide_x >= content_origin
|
||||
&& wrap_guide_x <= hitbox.bounds.right() - vertical_scrollbar_width;
|
||||
|
||||
display_wrap_guide.then_some((wrap_guide_x, active))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn calculate_indent_guide_bounds(
|
||||
row_range: Range<MultiBufferRow>,
|
||||
line_height: Pixels,
|
||||
|
@ -5240,26 +5273,7 @@ impl EditorElement {
|
|||
paint_highlight(range.start, range.end, color, edges);
|
||||
}
|
||||
|
||||
let scroll_left =
|
||||
layout.position_map.snapshot.scroll_position().x * layout.position_map.em_width;
|
||||
|
||||
for (wrap_position, active) in layout.wrap_guides.iter() {
|
||||
let x = (layout.position_map.text_hitbox.origin.x
|
||||
+ *wrap_position
|
||||
+ layout.position_map.em_width / 2.)
|
||||
- scroll_left;
|
||||
|
||||
let show_scrollbars = layout
|
||||
.scrollbars_layout
|
||||
.as_ref()
|
||||
.map_or(false, |layout| layout.visible);
|
||||
|
||||
if x < layout.position_map.text_hitbox.origin.x
|
||||
|| (show_scrollbars && x > self.scrollbar_left(&layout.hitbox.bounds))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (guide_x, active) in layout.wrap_guides.iter() {
|
||||
let color = if *active {
|
||||
cx.theme().colors().editor_active_wrap_guide
|
||||
} else {
|
||||
|
@ -5267,7 +5281,7 @@ impl EditorElement {
|
|||
};
|
||||
window.paint_quad(fill(
|
||||
Bounds {
|
||||
origin: point(x, layout.position_map.text_hitbox.origin.y),
|
||||
origin: point(*guide_x, layout.position_map.text_hitbox.origin.y),
|
||||
size: size(px(1.), layout.position_map.text_hitbox.size.height),
|
||||
},
|
||||
color,
|
||||
|
@ -6678,7 +6692,7 @@ impl EditorElement {
|
|||
let position_map: &PositionMap = &position_map;
|
||||
|
||||
let line_height = position_map.line_height;
|
||||
let max_glyph_width = position_map.em_width;
|
||||
let max_glyph_advance = position_map.em_advance;
|
||||
let (delta, axis) = match delta {
|
||||
gpui::ScrollDelta::Pixels(mut pixels) => {
|
||||
//Trackpad
|
||||
|
@ -6689,15 +6703,15 @@ impl EditorElement {
|
|||
gpui::ScrollDelta::Lines(lines) => {
|
||||
//Not trackpad
|
||||
let pixels =
|
||||
point(lines.x * max_glyph_width, lines.y * line_height);
|
||||
point(lines.x * max_glyph_advance, lines.y * line_height);
|
||||
(pixels, None)
|
||||
}
|
||||
};
|
||||
|
||||
let current_scroll_position = position_map.snapshot.scroll_position();
|
||||
let x = (current_scroll_position.x * max_glyph_width
|
||||
let x = (current_scroll_position.x * max_glyph_advance
|
||||
- (delta.x * scroll_sensitivity))
|
||||
/ max_glyph_width;
|
||||
/ max_glyph_advance;
|
||||
let y = (current_scroll_position.y * line_height
|
||||
- (delta.y * scroll_sensitivity))
|
||||
/ line_height;
|
||||
|
@ -6858,11 +6872,7 @@ impl EditorElement {
|
|||
});
|
||||
}
|
||||
|
||||
fn scrollbar_left(&self, bounds: &Bounds<Pixels>) -> Pixels {
|
||||
bounds.top_right().x - self.style.scrollbar_width
|
||||
}
|
||||
|
||||
fn column_pixels(&self, column: usize, window: &mut Window, _: &mut App) -> Pixels {
|
||||
fn column_pixels(&self, column: usize, window: &Window) -> Pixels {
|
||||
let style = &self.style;
|
||||
let font_size = style.text.font_size.to_pixels(window.rem_size());
|
||||
let layout = window.text_system().shape_line(
|
||||
|
@ -6881,14 +6891,9 @@ impl EditorElement {
|
|||
layout.width
|
||||
}
|
||||
|
||||
fn max_line_number_width(
|
||||
&self,
|
||||
snapshot: &EditorSnapshot,
|
||||
window: &mut Window,
|
||||
cx: &mut App,
|
||||
) -> Pixels {
|
||||
fn max_line_number_width(&self, snapshot: &EditorSnapshot, window: &mut Window) -> Pixels {
|
||||
let digit_count = snapshot.widest_line_number().ilog10() + 1;
|
||||
self.column_pixels(digit_count as usize, window, cx)
|
||||
self.column_pixels(digit_count as usize, window)
|
||||
}
|
||||
|
||||
fn shape_line_number(
|
||||
|
@ -7789,7 +7794,7 @@ impl Element for EditorElement {
|
|||
} => {
|
||||
let editor_handle = cx.entity().clone();
|
||||
let max_line_number_width =
|
||||
self.max_line_number_width(&editor.snapshot(window, cx), window, cx);
|
||||
self.max_line_number_width(&editor.snapshot(window, cx), window);
|
||||
window.request_measured_layout(
|
||||
Style::default(),
|
||||
move |known_dimensions, available_space, window, cx| {
|
||||
|
@ -7879,7 +7884,7 @@ impl Element for EditorElement {
|
|||
.gutter_dimensions(
|
||||
font_id,
|
||||
font_size,
|
||||
self.max_line_number_width(&snapshot, window, cx),
|
||||
self.max_line_number_width(&snapshot, window),
|
||||
cx,
|
||||
)
|
||||
.or_else(|| {
|
||||
|
@ -7954,14 +7959,6 @@ impl Element for EditorElement {
|
|||
}
|
||||
});
|
||||
|
||||
let wrap_guides = self
|
||||
.editor
|
||||
.read(cx)
|
||||
.wrap_guides(cx)
|
||||
.iter()
|
||||
.map(|(guide, active)| (self.column_pixels(*guide, window, cx), *active))
|
||||
.collect::<SmallVec<[_; 2]>>();
|
||||
|
||||
let hitbox = window.insert_hitbox(bounds, HitboxBehavior::Normal);
|
||||
let gutter_hitbox = window.insert_hitbox(
|
||||
gutter_bounds(bounds, gutter_dimensions),
|
||||
|
@ -8593,7 +8590,7 @@ impl Element for EditorElement {
|
|||
start_row,
|
||||
editor_content_width,
|
||||
scroll_width,
|
||||
em_width,
|
||||
em_advance,
|
||||
&line_layouts,
|
||||
cx,
|
||||
)
|
||||
|
@ -8797,6 +8794,17 @@ impl Element for EditorElement {
|
|||
self.prepaint_expand_toggles(&mut expand_toggles, window, cx)
|
||||
});
|
||||
|
||||
let wrap_guides = self.layout_wrap_guides(
|
||||
em_advance,
|
||||
scroll_position,
|
||||
content_origin,
|
||||
scrollbars_layout.as_ref(),
|
||||
vertical_scrollbar_width,
|
||||
&hitbox,
|
||||
window,
|
||||
cx,
|
||||
);
|
||||
|
||||
let minimap = window.with_element_namespace("minimap", |window| {
|
||||
self.layout_minimap(
|
||||
&snapshot,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue