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, _, cx| {
71 let drop_index = dock_pane.read(cx).items_len() + 1;
72 handle_dropped_item(event, &dock_pane.downgrade(), drop_index, false, None, cx);
73 });
74
75 if dock_position.is_visible() {
76 button
77 .on_click(MouseButton::Left, |_, _, cx| {
78 cx.dispatch_action(HideDock);
79 })
80 .with_tooltip::<Self>(
81 0,
82 "Hide Dock".into(),
83 Some(Box::new(HideDock)),
84 theme.tooltip.clone(),
85 cx,
86 )
87 } else {
88 button
89 .on_click(MouseButton::Left, |_, _, cx| {
90 cx.dispatch_action(FocusDock);
91 })
92 .with_tooltip::<Self>(
93 0,
94 "Focus Dock".into(),
95 Some(Box::new(FocusDock)),
96 theme.tooltip.clone(),
97 cx,
98 )
99 }
100 .into_any()
101 }
102}
103
104impl StatusItemView for ToggleDockButton {
105 fn set_active_pane_item(
106 &mut self,
107 _active_pane_item: Option<&dyn crate::ItemHandle>,
108 _cx: &mut ViewContext<Self>,
109 ) {
110 //Not applicable
111 }
112}