1use crate::{grouped_diagnostics::GroupedDiagnosticsEditor, ProjectDiagnosticsEditor};
2use futures::future::Either;
3use gpui::{EventEmitter, ParentElement, Render, View, ViewContext, WeakView};
4use ui::prelude::*;
5use ui::{IconButton, IconName, Tooltip};
6use workspace::{item::ItemHandle, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView};
7
8pub struct ToolbarControls {
9 editor: Option<Either<WeakView<ProjectDiagnosticsEditor>, WeakView<GroupedDiagnosticsEditor>>>,
10}
11
12impl Render for ToolbarControls {
13 fn render(&mut self, cx: &mut ViewContext<Self>) -> impl IntoElement {
14 let mut include_warnings = false;
15 let mut has_stale_excerpts = false;
16 let mut is_updating = false;
17
18 if let Some(editor) = self.editor() {
19 match editor {
20 Either::Left(editor) => {
21 let editor = editor.read(cx);
22 include_warnings = editor.include_warnings;
23 has_stale_excerpts = !editor.paths_to_update.is_empty();
24 is_updating = editor.update_paths_tx.len() > 0
25 || editor
26 .project
27 .read(cx)
28 .language_servers_running_disk_based_diagnostics()
29 .next()
30 .is_some();
31 }
32 Either::Right(editor) => {
33 let editor = editor.read(cx);
34 include_warnings = editor.include_warnings;
35 has_stale_excerpts = !editor.paths_to_update.is_empty();
36 is_updating = editor.update_paths_tx.len() > 0
37 || editor
38 .project
39 .read(cx)
40 .language_servers_running_disk_based_diagnostics()
41 .next()
42 .is_some();
43 }
44 }
45 }
46
47 let tooltip = if include_warnings {
48 "Exclude Warnings"
49 } else {
50 "Include Warnings"
51 };
52
53 h_flex()
54 .when(has_stale_excerpts, |div| {
55 div.child(
56 IconButton::new("update-excerpts", IconName::Update)
57 .icon_color(Color::Info)
58 .disabled(is_updating)
59 .tooltip(move |cx| Tooltip::text("Update excerpts", cx))
60 .on_click(cx.listener(|this, _, cx| {
61 if let Some(editor) = this.editor() {
62 match editor {
63 Either::Left(editor) => {
64 editor.update(cx, |editor, _| {
65 editor.enqueue_update_stale_excerpts(None);
66 });
67 }
68 Either::Right(editor) => {
69 editor.update(cx, |editor, _| {
70 editor.enqueue_update_stale_excerpts(None);
71 });
72 }
73 }
74 }
75 })),
76 )
77 })
78 .child(
79 IconButton::new("toggle-warnings", IconName::ExclamationTriangle)
80 .tooltip(move |cx| Tooltip::text(tooltip, cx))
81 .on_click(cx.listener(|this, _, cx| {
82 if let Some(editor) = this.editor() {
83 match editor {
84 Either::Left(editor) => {
85 editor.update(cx, |editor, cx| {
86 editor.toggle_warnings(&Default::default(), cx);
87 });
88 }
89 Either::Right(editor) => {
90 editor.update(cx, |editor, cx| {
91 editor.toggle_warnings(&Default::default(), cx);
92 });
93 }
94 }
95 }
96 })),
97 )
98 }
99}
100
101impl EventEmitter<ToolbarItemEvent> for ToolbarControls {}
102
103impl ToolbarItemView for ToolbarControls {
104 fn set_active_pane_item(
105 &mut self,
106 active_pane_item: Option<&dyn ItemHandle>,
107 _: &mut ViewContext<Self>,
108 ) -> ToolbarItemLocation {
109 if let Some(pane_item) = active_pane_item.as_ref() {
110 if let Some(editor) = pane_item.downcast::<ProjectDiagnosticsEditor>() {
111 self.editor = Some(Either::Left(editor.downgrade()));
112 ToolbarItemLocation::PrimaryRight
113 } else if let Some(editor) = pane_item.downcast::<GroupedDiagnosticsEditor>() {
114 self.editor = Some(Either::Right(editor.downgrade()));
115 ToolbarItemLocation::PrimaryRight
116 } else {
117 ToolbarItemLocation::Hidden
118 }
119 } else {
120 ToolbarItemLocation::Hidden
121 }
122 }
123}
124
125impl ToolbarControls {
126 pub fn new() -> Self {
127 ToolbarControls { editor: None }
128 }
129
130 fn editor(
131 &self,
132 ) -> Option<Either<View<ProjectDiagnosticsEditor>, View<GroupedDiagnosticsEditor>>> {
133 Some(match self.editor.as_ref()? {
134 Either::Left(diagnostics) => Either::Left(diagnostics.upgrade()?),
135 Either::Right(grouped_diagnostics) => Either::Right(grouped_diagnostics.upgrade()?),
136 })
137 }
138}