From 4f9c20742500a30aaa5e8e745090b04b051225a4 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 31 May 2022 15:56:59 +0200 Subject: [PATCH] Show a clickable jump icon for each diagnostic group header --- assets/icons/jump.svg | 3 +++ crates/diagnostics/src/diagnostics.rs | 37 +++++++++++++++++++++++---- crates/theme/src/theme.rs | 3 ++- styles/src/styleTree/editor.ts | 8 ++++++ 4 files changed, 45 insertions(+), 6 deletions(-) create mode 100644 assets/icons/jump.svg diff --git a/assets/icons/jump.svg b/assets/icons/jump.svg new file mode 100644 index 0000000000..4e89fc4339 --- /dev/null +++ b/assets/icons/jump.svg @@ -0,0 +1,3 @@ + + + diff --git a/crates/diagnostics/src/diagnostics.rs b/crates/diagnostics/src/diagnostics.rs index cd258b98f1..8dc1b27d70 100644 --- a/crates/diagnostics/src/diagnostics.rs +++ b/crates/diagnostics/src/diagnostics.rs @@ -8,9 +8,9 @@ use editor::{ highlight_diagnostic_message, Autoscroll, Editor, ExcerptId, MultiBuffer, ToOffset, }; use gpui::{ - actions, elements::*, fonts::TextStyle, serde_json, AnyViewHandle, AppContext, Entity, - ModelHandle, MutableAppContext, RenderContext, Task, View, ViewContext, ViewHandle, - WeakViewHandle, + actions, elements::*, fonts::TextStyle, platform::CursorStyle, serde_json, AnyViewHandle, + AppContext, Entity, ModelHandle, MutableAppContext, RenderContext, Task, View, ViewContext, + ViewHandle, WeakViewHandle, }; use language::{ Bias, Buffer, Diagnostic, DiagnosticEntry, DiagnosticSeverity, Point, Selection, SelectionGoal, @@ -576,11 +576,13 @@ impl workspace::Item for ProjectDiagnosticsEditor { } fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock { + enum JumpIcon {} + let (message, highlights) = highlight_diagnostic_message(&diagnostic.message); Arc::new(move |cx| { let settings = cx.global::(); let theme = &settings.theme.editor; - let style = &theme.diagnostic_header; + let style = theme.diagnostic_header.clone(); let font_size = (style.text_scale_factor * settings.buffer_font_size).round(); let icon_width = cx.em_width * style.icon_width_factor; let icon = if diagnostic.severity == DiagnosticSeverity::ERROR { @@ -591,6 +593,7 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock { .with_color(theme.warning_diagnostic.message.text.color) }; + let x_padding = cx.gutter_padding + cx.scroll_x * cx.em_width; Flex::row() .with_child( icon.constrained() @@ -618,9 +621,33 @@ fn diagnostic_header_renderer(diagnostic: Diagnostic) -> RenderBlock { .aligned() .boxed() })) + .with_child( + MouseEventHandler::new::(0, cx, |state, _| { + let style = style.jump_icon.style_for(state, false); + Svg::new("icons/jump.svg") + .with_color(style.color) + .constrained() + .with_width(style.icon_width) + .aligned() + .contained() + .with_style(style.container) + .constrained() + .with_width(style.button_width) + .with_height(style.button_width) + .boxed() + }) + .with_cursor_style(CursorStyle::PointingHand) + .on_click(|_, _, cx| { + dbg!("click!"); + }) + .aligned() + .flex_float() + .boxed(), + ) .contained() .with_style(style.container) - .with_padding_left(cx.gutter_padding + cx.scroll_x * cx.em_width) + .with_padding_left(x_padding) + .with_padding_right(x_padding) .expanded() .named("diagnostic header") }) diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index a8c28f41f3..d5f50b08e2 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -317,7 +317,7 @@ pub struct Icon { pub path: String, } -#[derive(Deserialize, Default)] +#[derive(Clone, Deserialize, Default)] pub struct IconButton { #[serde(flatten)] pub container: ContainerStyle, @@ -461,6 +461,7 @@ pub struct DiagnosticHeader { pub code: ContainedText, pub text_scale_factor: f32, pub icon_width_factor: f32, + pub jump_icon: Interactive, } #[derive(Clone, Deserialize, Default)] diff --git a/styles/src/styleTree/editor.ts b/styles/src/styleTree/editor.ts index 06f0d98d70..3edd205f9a 100644 --- a/styles/src/styleTree/editor.ts +++ b/styles/src/styleTree/editor.ts @@ -98,6 +98,14 @@ export default function editor(theme: Theme) { background: backgroundColor(theme, 300), iconWidthFactor: 1.5, textScaleFactor: 0.857, // NateQ: Will we need dynamic sizing for text? If so let's create tokens for these. + jumpIcon: { + color: iconColor(theme, "primary"), + iconWidth: 10, + buttonWidth: 10, + hover: { + color: iconColor(theme, "active") + } + }, border: border(theme, "secondary", { bottom: true, top: true,