toggle_dock_button.rs

  1use super::{icon_for_dock_anchor, Dock, FocusDock, HideDock};
  2use crate::{handle_dropped_item, StatusItemView, Workspace};
  3use gpui::{
  4    elements::{Empty, MouseEventHandler, Svg},
  5    platform::CursorStyle,
  6    platform::MouseButton,
  7    AnyElement, Element, Entity, View, ViewContext, ViewHandle, WeakViewHandle,
  8};
  9
 10pub struct ToggleDockButton {
 11    workspace: WeakViewHandle<Workspace>,
 12}
 13
 14impl ToggleDockButton {
 15    pub fn new(workspace: ViewHandle<Workspace>, cx: &mut ViewContext<Self>) -> Self {
 16        // When dock moves, redraw so that the icon and toggle status matches.
 17        cx.subscribe(&workspace, |_, _, _, cx| cx.notify()).detach();
 18
 19        Self {
 20            workspace: workspace.downgrade(),
 21        }
 22    }
 23}
 24
 25impl Entity for ToggleDockButton {
 26    type Event = ();
 27}
 28
 29impl View for ToggleDockButton {
 30    fn ui_name() -> &'static str {
 31        "Dock Toggle"
 32    }
 33
 34    fn render(&mut self, cx: &mut gpui::ViewContext<Self>) -> AnyElement<Self> {
 35        let workspace = self.workspace.upgrade(cx);
 36
 37        if workspace.is_none() {
 38            return Empty::new().into_any();
 39        }
 40
 41        let workspace = workspace.unwrap();
 42        let dock_position = workspace.read(cx).dock.position;
 43        let dock_pane = workspace.read(cx).dock_pane().clone();
 44
 45        let theme = theme::current(cx).clone();
 46
 47        let button = MouseEventHandler::<Self, _>::new(0, cx, {
 48            let theme = theme.clone();
 49            move |state, _| {
 50                let style = theme
 51                    .workspace
 52                    .status_bar
 53                    .sidebar_buttons
 54                    .item
 55                    .style_for(state, dock_position.is_visible());
 56
 57                Svg::new(icon_for_dock_anchor(dock_position.anchor()))
 58                    .with_color(style.icon_color)
 59                    .constrained()
 60                    .with_width(style.icon_size)
 61                    .with_height(style.icon_size)
 62                    .contained()
 63                    .with_style(style.container)
 64            }
 65        })
 66        .with_cursor_style(CursorStyle::PointingHand)
 67        .on_up(MouseButton::Left, move |event, this, cx| {
 68            let drop_index = dock_pane.read(cx).items_len() + 1;
 69            handle_dropped_item(
 70                event,
 71                this.workspace.clone(),
 72                &dock_pane.downgrade(),
 73                drop_index,
 74                false,
 75                None,
 76                cx,
 77            );
 78        });
 79
 80        if dock_position.is_visible() {
 81            button
 82                .on_click(MouseButton::Left, |_, this, cx| {
 83                    if let Some(workspace) = this.workspace.upgrade(cx) {
 84                        workspace.update(cx, |workspace, cx| {
 85                            Dock::hide_dock(workspace, &Default::default(), cx)
 86                        })
 87                    }
 88                })
 89                .with_tooltip::<Self>(
 90                    0,
 91                    "Hide Dock".into(),
 92                    Some(Box::new(HideDock)),
 93                    theme.tooltip.clone(),
 94                    cx,
 95                )
 96        } else {
 97            button
 98                .on_click(MouseButton::Left, |_, this, cx| {
 99                    if let Some(workspace) = this.workspace.upgrade(cx) {
100                        workspace.update(cx, |workspace, cx| {
101                            Dock::focus_dock(workspace, &Default::default(), cx)
102                        })
103                    }
104                })
105                .with_tooltip::<Self>(
106                    0,
107                    "Focus Dock".into(),
108                    Some(Box::new(FocusDock)),
109                    theme.tooltip.clone(),
110                    cx,
111                )
112        }
113        .into_any()
114    }
115}
116
117impl StatusItemView for ToggleDockButton {
118    fn set_active_pane_item(
119        &mut self,
120        _active_pane_item: Option<&dyn crate::ItemHandle>,
121        _cx: &mut ViewContext<Self>,
122    ) {
123        //Not applicable
124    }
125}