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