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
|
.git
|
||||||
.inline_blame
|
.inline_blame
|
||||||
.and_then(|settings| settings.min_column)
|
.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.));
|
.unwrap_or(px(0.));
|
||||||
let min_start = content_origin.x - scroll_pixel_position.x + min_column_in_pixels;
|
let min_start = content_origin.x - scroll_pixel_position.x + min_column_in_pixels;
|
||||||
|
|
||||||
|
@ -2629,7 +2629,7 @@ impl EditorElement {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter_map(|(i, indent_guide)| {
|
.filter_map(|(i, indent_guide)| {
|
||||||
let single_indent_width =
|
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 total_width = single_indent_width * indent_guide.depth as f32;
|
||||||
let start_x = content_origin.x + total_width - scroll_pixel_position.x;
|
let start_x = content_origin.x + total_width - scroll_pixel_position.x;
|
||||||
if start_x >= text_origin.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(
|
fn calculate_indent_guide_bounds(
|
||||||
row_range: Range<MultiBufferRow>,
|
row_range: Range<MultiBufferRow>,
|
||||||
line_height: Pixels,
|
line_height: Pixels,
|
||||||
|
@ -5240,26 +5273,7 @@ impl EditorElement {
|
||||||
paint_highlight(range.start, range.end, color, edges);
|
paint_highlight(range.start, range.end, color, edges);
|
||||||
}
|
}
|
||||||
|
|
||||||
let scroll_left =
|
for (guide_x, active) in layout.wrap_guides.iter() {
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
let color = if *active {
|
let color = if *active {
|
||||||
cx.theme().colors().editor_active_wrap_guide
|
cx.theme().colors().editor_active_wrap_guide
|
||||||
} else {
|
} else {
|
||||||
|
@ -5267,7 +5281,7 @@ impl EditorElement {
|
||||||
};
|
};
|
||||||
window.paint_quad(fill(
|
window.paint_quad(fill(
|
||||||
Bounds {
|
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),
|
size: size(px(1.), layout.position_map.text_hitbox.size.height),
|
||||||
},
|
},
|
||||||
color,
|
color,
|
||||||
|
@ -6678,7 +6692,7 @@ impl EditorElement {
|
||||||
let position_map: &PositionMap = &position_map;
|
let position_map: &PositionMap = &position_map;
|
||||||
|
|
||||||
let line_height = position_map.line_height;
|
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 {
|
let (delta, axis) = match delta {
|
||||||
gpui::ScrollDelta::Pixels(mut pixels) => {
|
gpui::ScrollDelta::Pixels(mut pixels) => {
|
||||||
//Trackpad
|
//Trackpad
|
||||||
|
@ -6689,15 +6703,15 @@ impl EditorElement {
|
||||||
gpui::ScrollDelta::Lines(lines) => {
|
gpui::ScrollDelta::Lines(lines) => {
|
||||||
//Not trackpad
|
//Not trackpad
|
||||||
let pixels =
|
let pixels =
|
||||||
point(lines.x * max_glyph_width, lines.y * line_height);
|
point(lines.x * max_glyph_advance, lines.y * line_height);
|
||||||
(pixels, None)
|
(pixels, None)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let current_scroll_position = position_map.snapshot.scroll_position();
|
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))
|
- (delta.x * scroll_sensitivity))
|
||||||
/ max_glyph_width;
|
/ max_glyph_advance;
|
||||||
let y = (current_scroll_position.y * line_height
|
let y = (current_scroll_position.y * line_height
|
||||||
- (delta.y * scroll_sensitivity))
|
- (delta.y * scroll_sensitivity))
|
||||||
/ line_height;
|
/ line_height;
|
||||||
|
@ -6858,11 +6872,7 @@ impl EditorElement {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn scrollbar_left(&self, bounds: &Bounds<Pixels>) -> Pixels {
|
fn column_pixels(&self, column: usize, window: &Window) -> Pixels {
|
||||||
bounds.top_right().x - self.style.scrollbar_width
|
|
||||||
}
|
|
||||||
|
|
||||||
fn column_pixels(&self, column: usize, window: &mut Window, _: &mut App) -> Pixels {
|
|
||||||
let style = &self.style;
|
let style = &self.style;
|
||||||
let font_size = style.text.font_size.to_pixels(window.rem_size());
|
let font_size = style.text.font_size.to_pixels(window.rem_size());
|
||||||
let layout = window.text_system().shape_line(
|
let layout = window.text_system().shape_line(
|
||||||
|
@ -6881,14 +6891,9 @@ impl EditorElement {
|
||||||
layout.width
|
layout.width
|
||||||
}
|
}
|
||||||
|
|
||||||
fn max_line_number_width(
|
fn max_line_number_width(&self, snapshot: &EditorSnapshot, window: &mut Window) -> Pixels {
|
||||||
&self,
|
|
||||||
snapshot: &EditorSnapshot,
|
|
||||||
window: &mut Window,
|
|
||||||
cx: &mut App,
|
|
||||||
) -> Pixels {
|
|
||||||
let digit_count = snapshot.widest_line_number().ilog10() + 1;
|
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(
|
fn shape_line_number(
|
||||||
|
@ -7789,7 +7794,7 @@ impl Element for EditorElement {
|
||||||
} => {
|
} => {
|
||||||
let editor_handle = cx.entity().clone();
|
let editor_handle = cx.entity().clone();
|
||||||
let max_line_number_width =
|
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(
|
window.request_measured_layout(
|
||||||
Style::default(),
|
Style::default(),
|
||||||
move |known_dimensions, available_space, window, cx| {
|
move |known_dimensions, available_space, window, cx| {
|
||||||
|
@ -7879,7 +7884,7 @@ impl Element for EditorElement {
|
||||||
.gutter_dimensions(
|
.gutter_dimensions(
|
||||||
font_id,
|
font_id,
|
||||||
font_size,
|
font_size,
|
||||||
self.max_line_number_width(&snapshot, window, cx),
|
self.max_line_number_width(&snapshot, window),
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
.or_else(|| {
|
.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 hitbox = window.insert_hitbox(bounds, HitboxBehavior::Normal);
|
||||||
let gutter_hitbox = window.insert_hitbox(
|
let gutter_hitbox = window.insert_hitbox(
|
||||||
gutter_bounds(bounds, gutter_dimensions),
|
gutter_bounds(bounds, gutter_dimensions),
|
||||||
|
@ -8593,7 +8590,7 @@ impl Element for EditorElement {
|
||||||
start_row,
|
start_row,
|
||||||
editor_content_width,
|
editor_content_width,
|
||||||
scroll_width,
|
scroll_width,
|
||||||
em_width,
|
em_advance,
|
||||||
&line_layouts,
|
&line_layouts,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
|
@ -8797,6 +8794,17 @@ impl Element for EditorElement {
|
||||||
self.prepaint_expand_toggles(&mut expand_toggles, window, cx)
|
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| {
|
let minimap = window.with_element_namespace("minimap", |window| {
|
||||||
self.layout_minimap(
|
self.layout_minimap(
|
||||||
&snapshot,
|
&snapshot,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue