toggle_dock_button.rs

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