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,
|
top: Pixels::ZERO,
|
||||||
right: Pixels::ZERO,
|
right: Pixels::ZERO,
|
||||||
bottom: Pixels::ZERO,
|
bottom: Pixels::ZERO,
|
||||||
left: px(1.),
|
left: ScrollbarLayout::BORDER_WIDTH,
|
||||||
},
|
},
|
||||||
cx.theme().colors().scrollbar_track_border,
|
cx.theme().colors().scrollbar_track_border,
|
||||||
));
|
));
|
||||||
let scrollbar_settings = EditorSettings::get_global(cx).scrollbar;
|
let scrollbar_settings = EditorSettings::get_global(cx).scrollbar;
|
||||||
let is_singleton = self.editor.read(cx).is_singleton(cx);
|
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 {
|
if is_singleton && scrollbar_settings.selections {
|
||||||
let start_anchor = Anchor::min();
|
let start_anchor = Anchor::min();
|
||||||
let end_anchor = Anchor::max();
|
let end_anchor = Anchor::max();
|
||||||
|
@ -2184,26 +2188,18 @@ impl EditorElement {
|
||||||
&layout.position_map.snapshot,
|
&layout.position_map.snapshot,
|
||||||
50000,
|
50000,
|
||||||
);
|
);
|
||||||
|
let left_x = left + ScrollbarLayout::BORDER_WIDTH + column_width;
|
||||||
|
let right_x = left_x + column_width;
|
||||||
for range in background_ranges {
|
for range in background_ranges {
|
||||||
let start_y = scrollbar_layout.y_for_row(range.start().row() as f32);
|
let (start_y, end_y) =
|
||||||
let mut end_y = scrollbar_layout.y_for_row(range.end().row() as f32);
|
scrollbar_layout.ys_for_marker(range.start().row(), range.end().row());
|
||||||
if end_y - start_y < px(1.) {
|
let bounds =
|
||||||
end_y = start_y + px(1.);
|
Bounds::from_corners(point(left_x, start_y), point(right_x, end_y));
|
||||||
}
|
|
||||||
let bounds = Bounds::from_corners(
|
|
||||||
point(scrollbar_layout.hitbox.left(), start_y),
|
|
||||||
point(scrollbar_layout.hitbox.right(), end_y),
|
|
||||||
);
|
|
||||||
cx.paint_quad(quad(
|
cx.paint_quad(quad(
|
||||||
bounds,
|
bounds,
|
||||||
Corners::default(),
|
Corners::default(),
|
||||||
cx.theme().status().info,
|
cx.theme().status().info,
|
||||||
Edges {
|
Edges::default(),
|
||||||
top: Pixels::ZERO,
|
|
||||||
right: px(1.),
|
|
||||||
bottom: Pixels::ZERO,
|
|
||||||
left: px(1.),
|
|
||||||
},
|
|
||||||
cx.theme().colors().scrollbar_thumb_border,
|
cx.theme().colors().scrollbar_thumb_border,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2215,68 +2211,49 @@ impl EditorElement {
|
||||||
&layout.position_map.snapshot,
|
&layout.position_map.snapshot,
|
||||||
cx.theme().colors(),
|
cx.theme().colors(),
|
||||||
);
|
);
|
||||||
|
let left_x = left + ScrollbarLayout::BORDER_WIDTH + column_width;
|
||||||
|
let right_x = left_x + column_width;
|
||||||
for hunk in selection_ranges {
|
for hunk in selection_ranges {
|
||||||
let start_display = Point::new(hunk.0.start.row(), 0)
|
let start_display = Point::new(hunk.0.start.row(), 0)
|
||||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||||
let end_display = Point::new(hunk.0.end.row(), 0)
|
let end_display = Point::new(hunk.0.end.row(), 0)
|
||||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||||
let start_y = scrollbar_layout.y_for_row(start_display.row() as f32);
|
let (start_y, end_y) =
|
||||||
let mut end_y = if hunk.0.start == hunk.0.end {
|
scrollbar_layout.ys_for_marker(start_display.row(), end_display.row());
|
||||||
scrollbar_layout.y_for_row((end_display.row() + 1) as f32)
|
let bounds =
|
||||||
} else {
|
Bounds::from_corners(point(left_x, start_y), point(right_x, end_y));
|
||||||
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),
|
|
||||||
);
|
|
||||||
|
|
||||||
cx.paint_quad(quad(
|
cx.paint_quad(quad(
|
||||||
bounds,
|
bounds,
|
||||||
Corners::default(),
|
Corners::default(),
|
||||||
cx.theme().status().info,
|
cx.theme().status().info,
|
||||||
Edges {
|
Edges::default(),
|
||||||
top: Pixels::ZERO,
|
|
||||||
right: px(1.),
|
|
||||||
bottom: Pixels::ZERO,
|
|
||||||
left: px(1.),
|
|
||||||
},
|
|
||||||
cx.theme().colors().scrollbar_thumb_border,
|
cx.theme().colors().scrollbar_thumb_border,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_singleton && scrollbar_settings.git_diff {
|
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
|
for hunk in layout
|
||||||
.position_map
|
.position_map
|
||||||
.snapshot
|
.snapshot
|
||||||
.buffer_snapshot
|
.buffer_snapshot
|
||||||
.git_diff_hunks_in_range(0..layout.max_row)
|
.git_diff_hunks_in_range(0..layout.max_row)
|
||||||
{
|
{
|
||||||
let start_display = Point::new(hunk.associated_range.start, 0)
|
let start_display_row = Point::new(hunk.associated_range.start, 0)
|
||||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
.to_display_point(&layout.position_map.snapshot.display_snapshot)
|
||||||
let end_display = Point::new(hunk.associated_range.end, 0)
|
.row();
|
||||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
let mut end_display_row = Point::new(hunk.associated_range.end, 0)
|
||||||
let start_y = scrollbar_layout.y_for_row(start_display.row() as f32);
|
.to_display_point(&layout.position_map.snapshot.display_snapshot)
|
||||||
let mut end_y = if hunk.associated_range.start == hunk.associated_range.end
|
.row();
|
||||||
{
|
if end_display_row != start_display_row {
|
||||||
scrollbar_layout.y_for_row((end_display.row() + 1) as f32)
|
end_display_row -= 1;
|
||||||
} 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(
|
let (start_y, end_y) =
|
||||||
point(scrollbar_layout.hitbox.left(), start_y),
|
scrollbar_layout.ys_for_marker(start_display_row, end_display_row);
|
||||||
point(scrollbar_layout.hitbox.right(), end_y),
|
let bounds =
|
||||||
);
|
Bounds::from_corners(point(left_x, start_y), point(right_x, end_y));
|
||||||
|
|
||||||
let color = match hunk.status() {
|
let color = match hunk.status() {
|
||||||
DiffHunkStatus::Added => cx.theme().status().created,
|
DiffHunkStatus::Added => cx.theme().status().created,
|
||||||
DiffHunkStatus::Modified => cx.theme().status().modified,
|
DiffHunkStatus::Modified => cx.theme().status().modified,
|
||||||
|
@ -2286,12 +2263,7 @@ impl EditorElement {
|
||||||
bounds,
|
bounds,
|
||||||
Corners::default(),
|
Corners::default(),
|
||||||
color,
|
color,
|
||||||
Edges {
|
Edges::default(),
|
||||||
top: Pixels::ZERO,
|
|
||||||
right: px(1.),
|
|
||||||
bottom: Pixels::ZERO,
|
|
||||||
left: px(1.),
|
|
||||||
},
|
|
||||||
cx.theme().colors().scrollbar_thumb_border,
|
cx.theme().colors().scrollbar_thumb_border,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2315,6 +2287,7 @@ impl EditorElement {
|
||||||
std::cmp::Reverse(diagnostic.diagnostic.severity)
|
std::cmp::Reverse(diagnostic.diagnostic.severity)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let left_x = left + ScrollbarLayout::BORDER_WIDTH + 2.0 * column_width;
|
||||||
for diagnostic in diagnostics {
|
for diagnostic in diagnostics {
|
||||||
let start_display = diagnostic
|
let start_display = diagnostic
|
||||||
.range
|
.range
|
||||||
|
@ -2324,21 +2297,10 @@ impl EditorElement {
|
||||||
.range
|
.range
|
||||||
.end
|
.end
|
||||||
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
.to_display_point(&layout.position_map.snapshot.display_snapshot);
|
||||||
let start_y = scrollbar_layout.y_for_row(start_display.row() as f32);
|
let (start_y, end_y) =
|
||||||
let mut end_y = if diagnostic.range.start == diagnostic.range.end {
|
scrollbar_layout.ys_for_marker(start_display.row(), end_display.row());
|
||||||
scrollbar_layout.y_for_row((end_display.row() + 1) as f32)
|
let bounds =
|
||||||
} else {
|
Bounds::from_corners(point(left_x, start_y), point(right, end_y));
|
||||||
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 color = match diagnostic.diagnostic.severity {
|
let color = match diagnostic.diagnostic.severity {
|
||||||
DiagnosticSeverity::ERROR => cx.theme().status().error,
|
DiagnosticSeverity::ERROR => cx.theme().status().error,
|
||||||
DiagnosticSeverity::WARNING => cx.theme().status().warning,
|
DiagnosticSeverity::WARNING => cx.theme().status().warning,
|
||||||
|
@ -2349,12 +2311,7 @@ impl EditorElement {
|
||||||
bounds,
|
bounds,
|
||||||
Corners::default(),
|
Corners::default(),
|
||||||
color,
|
color,
|
||||||
Edges {
|
Edges::default(),
|
||||||
top: Pixels::ZERO,
|
|
||||||
right: px(1.),
|
|
||||||
bottom: Pixels::ZERO,
|
|
||||||
left: px(1.),
|
|
||||||
},
|
|
||||||
cx.theme().colors().scrollbar_thumb_border,
|
cx.theme().colors().scrollbar_thumb_border,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -2366,9 +2323,9 @@ impl EditorElement {
|
||||||
cx.theme().colors().scrollbar_thumb_background,
|
cx.theme().colors().scrollbar_thumb_background,
|
||||||
Edges {
|
Edges {
|
||||||
top: Pixels::ZERO,
|
top: Pixels::ZERO,
|
||||||
right: px(1.),
|
right: Pixels::ZERO,
|
||||||
bottom: Pixels::ZERO,
|
bottom: Pixels::ZERO,
|
||||||
left: px(1.),
|
left: ScrollbarLayout::BORDER_WIDTH,
|
||||||
},
|
},
|
||||||
cx.theme().colors().scrollbar_thumb_border,
|
cx.theme().colors().scrollbar_thumb_border,
|
||||||
));
|
));
|
||||||
|
@ -3466,6 +3423,9 @@ struct ScrollbarLayout {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScrollbarLayout {
|
impl ScrollbarLayout {
|
||||||
|
const BORDER_WIDTH: Pixels = px(1.0);
|
||||||
|
const MIN_MARKER_HEIGHT: Pixels = px(2.0);
|
||||||
|
|
||||||
fn thumb_bounds(&self) -> Bounds<Pixels> {
|
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_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;
|
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 {
|
fn y_for_row(&self, row: f32) -> Pixels {
|
||||||
self.hitbox.top() + self.first_row_y_offset + row * self.row_height
|
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 {
|
struct FoldLayout {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue