mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-06 18:46:49 +00:00
Scrollbar markers enhancements (#9080)
Several improvements in how various markers are displayed in the editor scrollbar, as described in #9070, if you're ok with the proposal: - Scrollbar has three columns: - 1st is for git markers - 2nd is for selections and search resulta highlightings - 3rd is for diagnostics - Height of all markers is scaled, but there's a minimal allowed height of 2px. - Right border removed from both the scrollbar and thumb to make more room for markers. Release Notes: - Improved scrollbar markers visualization (#9070).
This commit is contained in:
parent
b65aa7e2a7
commit
6ae5274954
1 changed files with 54 additions and 85 deletions
|
@ -2167,12 +2167,16 @@ impl EditorElement {
|
|||
top: Pixels::ZERO,
|
||||
right: Pixels::ZERO,
|
||||
bottom: Pixels::ZERO,
|
||||
left: px(1.),
|
||||
left: ScrollbarLayout::BORDER_WIDTH,
|
||||
},
|
||||
cx.theme().colors().scrollbar_track_border,
|
||||
));
|
||||
let scrollbar_settings = EditorSettings::get_global(cx).scrollbar;
|
||||
let is_singleton = self.editor.read(cx).is_singleton(cx);
|
||||
let left = scrollbar_layout.hitbox.left();
|
||||
let right = scrollbar_layout.hitbox.right();
|
||||
let column_width =
|
||||
px(((right - left - ScrollbarLayout::BORDER_WIDTH).0 / 3.0).floor());
|
||||
if is_singleton && scrollbar_settings.selections {
|
||||
let start_anchor = Anchor::min();
|
||||
let end_anchor = Anchor::max();
|
||||
|
@ -2184,26 +2188,18 @@ impl EditorElement {
|
|||
&layout.position_map.snapshot,
|
||||
50000,
|
||||
);
|
||||
let left_x = left + ScrollbarLayout::BORDER_WIDTH + column_width;
|
||||
let right_x = left_x + column_width;
|
||||
for range in background_ranges {
|
||||
let start_y = scrollbar_layout.y_for_row(range.start().row() as f32);
|
||||
let mut end_y = scrollbar_layout.y_for_row(range.end().row() as f32);
|
||||
if end_y - start_y < px(1.) {
|
||||
end_y = start_y + px(1.);
|
||||
}
|
||||
let bounds = Bounds::from_corners(
|
||||
point(scrollbar_layout.hitbox.left(), start_y),
|
||||
point(scrollbar_layout.hitbox.right(), end_y),
|
||||
);
|
||||
let (start_y, end_y) =
|
||||
scrollbar_layout.ys_for_marker(range.start().row(), range.end().row());
|
||||
let bounds =
|
||||
Bounds::from_corners(point(left_x, start_y), point(right_x, end_y));
|
||||
cx.paint_quad(quad(
|
||||
bounds,
|
||||
Corners::default(),
|
||||
cx.theme().status().info,
|
||||
Edges {
|
||||
top: Pixels::ZERO,
|
||||
right: px(1.),
|
||||
bottom: Pixels::ZERO,
|
||||
left: px(1.),
|
||||
},
|
||||
Edges::default(),
|
||||
cx.theme().colors().scrollbar_thumb_border,
|
||||
));
|
||||
}
|
||||
|
@ -2215,68 +2211,49 @@ impl EditorElement {
|
|||
&layout.position_map.snapshot,
|
||||
cx.theme().colors(),
|
||||
);
|
||||
let left_x = left + ScrollbarLayout::BORDER_WIDTH + column_width;
|
||||
let right_x = left_x + column_width;
|
||||
for hunk in selection_ranges {
|
||||
let start_display = Point::new(hunk.0.start.row(), 0)
|
||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||
let end_display = Point::new(hunk.0.end.row(), 0)
|
||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||
let start_y = scrollbar_layout.y_for_row(start_display.row() as f32);
|
||||
let mut end_y = if hunk.0.start == hunk.0.end {
|
||||
scrollbar_layout.y_for_row((end_display.row() + 1) as f32)
|
||||
} else {
|
||||
scrollbar_layout.y_for_row(end_display.row() as f32)
|
||||
};
|
||||
|
||||
if end_y - start_y < px(1.) {
|
||||
end_y = start_y + px(1.);
|
||||
}
|
||||
let bounds = Bounds::from_corners(
|
||||
point(scrollbar_layout.hitbox.left(), start_y),
|
||||
point(scrollbar_layout.hitbox.right(), end_y),
|
||||
);
|
||||
|
||||
let (start_y, end_y) =
|
||||
scrollbar_layout.ys_for_marker(start_display.row(), end_display.row());
|
||||
let bounds =
|
||||
Bounds::from_corners(point(left_x, start_y), point(right_x, end_y));
|
||||
cx.paint_quad(quad(
|
||||
bounds,
|
||||
Corners::default(),
|
||||
cx.theme().status().info,
|
||||
Edges {
|
||||
top: Pixels::ZERO,
|
||||
right: px(1.),
|
||||
bottom: Pixels::ZERO,
|
||||
left: px(1.),
|
||||
},
|
||||
Edges::default(),
|
||||
cx.theme().colors().scrollbar_thumb_border,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
if is_singleton && scrollbar_settings.git_diff {
|
||||
let left_x = left + ScrollbarLayout::BORDER_WIDTH;
|
||||
let right_x = left_x + column_width;
|
||||
for hunk in layout
|
||||
.position_map
|
||||
.snapshot
|
||||
.buffer_snapshot
|
||||
.git_diff_hunks_in_range(0..layout.max_row)
|
||||
{
|
||||
let start_display = Point::new(hunk.associated_range.start, 0)
|
||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||
let end_display = Point::new(hunk.associated_range.end, 0)
|
||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||
let start_y = scrollbar_layout.y_for_row(start_display.row() as f32);
|
||||
let mut end_y = if hunk.associated_range.start == hunk.associated_range.end
|
||||
{
|
||||
scrollbar_layout.y_for_row((end_display.row() + 1) as f32)
|
||||
} else {
|
||||
scrollbar_layout.y_for_row(end_display.row() as f32)
|
||||
};
|
||||
|
||||
if end_y - start_y < px(1.) {
|
||||
end_y = start_y + px(1.);
|
||||
let start_display_row = Point::new(hunk.associated_range.start, 0)
|
||||
.to_display_point(&layout.position_map.snapshot.display_snapshot)
|
||||
.row();
|
||||
let mut end_display_row = Point::new(hunk.associated_range.end, 0)
|
||||
.to_display_point(&layout.position_map.snapshot.display_snapshot)
|
||||
.row();
|
||||
if end_display_row != start_display_row {
|
||||
end_display_row -= 1;
|
||||
}
|
||||
let bounds = Bounds::from_corners(
|
||||
point(scrollbar_layout.hitbox.left(), start_y),
|
||||
point(scrollbar_layout.hitbox.right(), end_y),
|
||||
);
|
||||
|
||||
let (start_y, end_y) =
|
||||
scrollbar_layout.ys_for_marker(start_display_row, end_display_row);
|
||||
let bounds =
|
||||
Bounds::from_corners(point(left_x, start_y), point(right_x, end_y));
|
||||
let color = match hunk.status() {
|
||||
DiffHunkStatus::Added => cx.theme().status().created,
|
||||
DiffHunkStatus::Modified => cx.theme().status().modified,
|
||||
|
@ -2286,12 +2263,7 @@ impl EditorElement {
|
|||
bounds,
|
||||
Corners::default(),
|
||||
color,
|
||||
Edges {
|
||||
top: Pixels::ZERO,
|
||||
right: px(1.),
|
||||
bottom: Pixels::ZERO,
|
||||
left: px(1.),
|
||||
},
|
||||
Edges::default(),
|
||||
cx.theme().colors().scrollbar_thumb_border,
|
||||
));
|
||||
}
|
||||
|
@ -2315,6 +2287,7 @@ impl EditorElement {
|
|||
std::cmp::Reverse(diagnostic.diagnostic.severity)
|
||||
});
|
||||
|
||||
let left_x = left + ScrollbarLayout::BORDER_WIDTH + 2.0 * column_width;
|
||||
for diagnostic in diagnostics {
|
||||
let start_display = diagnostic
|
||||
.range
|
||||
|
@ -2324,21 +2297,10 @@ impl EditorElement {
|
|||
.range
|
||||
.end
|
||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||
let start_y = scrollbar_layout.y_for_row(start_display.row() as f32);
|
||||
let mut end_y = if diagnostic.range.start == diagnostic.range.end {
|
||||
scrollbar_layout.y_for_row((end_display.row() + 1) as f32)
|
||||
} else {
|
||||
scrollbar_layout.y_for_row(end_display.row() as f32)
|
||||
};
|
||||
|
||||
if end_y - start_y < px(1.) {
|
||||
end_y = start_y + px(1.);
|
||||
}
|
||||
let bounds = Bounds::from_corners(
|
||||
point(scrollbar_layout.hitbox.left(), start_y),
|
||||
point(scrollbar_layout.hitbox.right(), end_y),
|
||||
);
|
||||
|
||||
let (start_y, end_y) =
|
||||
scrollbar_layout.ys_for_marker(start_display.row(), end_display.row());
|
||||
let bounds =
|
||||
Bounds::from_corners(point(left_x, start_y), point(right, end_y));
|
||||
let color = match diagnostic.diagnostic.severity {
|
||||
DiagnosticSeverity::ERROR => cx.theme().status().error,
|
||||
DiagnosticSeverity::WARNING => cx.theme().status().warning,
|
||||
|
@ -2349,12 +2311,7 @@ impl EditorElement {
|
|||
bounds,
|
||||
Corners::default(),
|
||||
color,
|
||||
Edges {
|
||||
top: Pixels::ZERO,
|
||||
right: px(1.),
|
||||
bottom: Pixels::ZERO,
|
||||
left: px(1.),
|
||||
},
|
||||
Edges::default(),
|
||||
cx.theme().colors().scrollbar_thumb_border,
|
||||
));
|
||||
}
|
||||
|
@ -2366,9 +2323,9 @@ impl EditorElement {
|
|||
cx.theme().colors().scrollbar_thumb_background,
|
||||
Edges {
|
||||
top: Pixels::ZERO,
|
||||
right: px(1.),
|
||||
right: Pixels::ZERO,
|
||||
bottom: Pixels::ZERO,
|
||||
left: px(1.),
|
||||
left: ScrollbarLayout::BORDER_WIDTH,
|
||||
},
|
||||
cx.theme().colors().scrollbar_thumb_border,
|
||||
));
|
||||
|
@ -3466,6 +3423,9 @@ struct ScrollbarLayout {
|
|||
}
|
||||
|
||||
impl ScrollbarLayout {
|
||||
const BORDER_WIDTH: Pixels = px(1.0);
|
||||
const MIN_MARKER_HEIGHT: Pixels = px(2.0);
|
||||
|
||||
fn thumb_bounds(&self) -> Bounds<Pixels> {
|
||||
let thumb_top = self.y_for_row(self.visible_row_range.start) - self.first_row_y_offset;
|
||||
let thumb_bottom = self.y_for_row(self.visible_row_range.end) + self.first_row_y_offset;
|
||||
|
@ -3478,6 +3438,15 @@ impl ScrollbarLayout {
|
|||
fn y_for_row(&self, row: f32) -> Pixels {
|
||||
self.hitbox.top() + self.first_row_y_offset + row * self.row_height
|
||||
}
|
||||
|
||||
fn ys_for_marker(&self, start_row: u32, end_row: u32) -> (Pixels, Pixels) {
|
||||
let start_y = self.y_for_row(start_row as f32);
|
||||
let mut end_y = self.y_for_row((end_row + 1) as f32);
|
||||
if end_y - start_y < Self::MIN_MARKER_HEIGHT {
|
||||
end_y = start_y + Self::MIN_MARKER_HEIGHT;
|
||||
}
|
||||
(start_y, end_y)
|
||||
}
|
||||
}
|
||||
|
||||
struct FoldLayout {
|
||||
|
|
Loading…
Reference in a new issue