toolbar_controls.rs

  1use crate::{ProjectDiagnosticsEditor, ToggleWarnings};
  2use gpui::{
  3    elements::*,
  4    platform::{CursorStyle, MouseButton},
  5    Action, Entity, EventContext, View, ViewContext, WeakViewHandle,
  6};
  7use workspace::{item::ItemHandle, ToolbarItemLocation, ToolbarItemView};
  8
  9pub struct ToolbarControls {
 10    editor: Option<WeakViewHandle<ProjectDiagnosticsEditor>>,
 11}
 12
 13impl Entity for ToolbarControls {
 14    type Event = ();
 15}
 16
 17impl View for ToolbarControls {
 18    fn ui_name() -> &'static str {
 19        "ToolbarControls"
 20    }
 21
 22    fn render(&mut self, cx: &mut ViewContext<Self>) -> AnyElement<Self> {
 23        let include_warnings = self
 24            .editor
 25            .as_ref()
 26            .and_then(|editor| editor.upgrade(cx))
 27            .map(|editor| editor.read(cx).include_warnings)
 28            .unwrap_or(false);
 29        let tooltip = if include_warnings {
 30            "Exclude Warnings".into()
 31        } else {
 32            "Include Warnings".into()
 33        };
 34        Flex::row()
 35            .with_child(render_toggle_button(
 36                0,
 37                "icons/warning.svg",
 38                include_warnings,
 39                (tooltip, Some(Box::new(ToggleWarnings))),
 40                cx,
 41                move |this, cx| {
 42                    if let Some(editor) = this.editor.and_then(|editor| editor.upgrade(cx)) {
 43                        editor.update(cx, |editor, cx| {
 44                            editor.toggle_warnings(&Default::default(), cx)
 45                        });
 46                    }
 47                },
 48            ))
 49            .into_any()
 50    }
 51}
 52
 53impl ToolbarItemView for ToolbarControls {
 54    fn set_active_pane_item(
 55        &mut self,
 56        active_pane_item: Option<&dyn ItemHandle>,
 57        _: &mut ViewContext<Self>,
 58    ) -> ToolbarItemLocation {
 59        if let Some(pane_item) = active_pane_item.as_ref() {
 60            if let Some(editor) = pane_item.downcast::<ProjectDiagnosticsEditor>() {
 61                self.editor = Some(editor.downgrade());
 62                ToolbarItemLocation::PrimaryRight { flex: None }
 63            } else {
 64                ToolbarItemLocation::Hidden
 65            }
 66        } else {
 67            ToolbarItemLocation::Hidden
 68        }
 69    }
 70}
 71
 72impl ToolbarControls {
 73    pub fn new() -> Self {
 74        ToolbarControls { editor: None }
 75    }
 76}
 77
 78fn render_toggle_button<
 79    F: 'static + Fn(&mut ToolbarControls, &mut EventContext<ToolbarControls>),
 80>(
 81    index: usize,
 82    icon: &'static str,
 83    toggled: bool,
 84    tooltip: (String, Option<Box<dyn Action>>),
 85    cx: &mut ViewContext<ToolbarControls>,
 86    on_click: F,
 87) -> AnyElement<ToolbarControls> {
 88    enum Button {}
 89
 90    let theme = theme::current(cx);
 91    let (tooltip_text, action) = tooltip;
 92
 93    MouseEventHandler::new::<Button, _>(index, cx, |mouse_state, _| {
 94        let style = theme
 95            .workspace
 96            .toolbar
 97            .toggleable_tool
 98            .in_state(toggled)
 99            .style_for(mouse_state);
100        Svg::new(icon)
101            .with_color(style.color)
102            .constrained()
103            .with_width(style.icon_width)
104            .aligned()
105            .constrained()
106            .with_width(style.button_width)
107            .with_height(style.button_width)
108            .contained()
109            .with_style(style.container)
110    })
111    .with_cursor_style(CursorStyle::PointingHand)
112    .on_click(MouseButton::Left, move |_, view, cx| on_click(view, cx))
113    .with_tooltip::<Button>(index, tooltip_text, action, theme.tooltip.clone(), cx)
114    .into_any_named("quick action bar button")
115}