1use gpui::{
2 elements::{Empty, MouseEventHandler, Svg},
3 platform::CursorStyle,
4 platform::MouseButton,
5 Element, ElementBox, 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::RenderContext<'_, Self>) -> ElementBox {
38 let workspace = self.workspace.upgrade(cx);
39
40 if workspace.is_none() {
41 return Empty::new().boxed();
42 }
43
44 let workspace = workspace.unwrap();
45 let dock_position = workspace.read(cx).dock.position;
46 let dock_pane = workspace.read(cx.app).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 .boxed()
68 }
69 })
70 .with_cursor_style(CursorStyle::PointingHand)
71 .on_up(MouseButton::Left, move |event, cx| {
72 let drop_index = dock_pane.read(cx.app).items_len() + 1;
73 handle_dropped_item(event, &dock_pane.downgrade(), drop_index, false, None, cx);
74 });
75
76 if dock_position.is_visible() {
77 button
78 .on_click(MouseButton::Left, |_, cx| {
79 cx.dispatch_action(HideDock);
80 })
81 .with_tooltip::<Self, _>(
82 0,
83 "Hide Dock".into(),
84 Some(Box::new(HideDock)),
85 theme.tooltip.clone(),
86 cx,
87 )
88 } else {
89 button
90 .on_click(MouseButton::Left, |_, cx| {
91 cx.dispatch_action(FocusDock);
92 })
93 .with_tooltip::<Self, _>(
94 0,
95 "Focus Dock".into(),
96 Some(Box::new(FocusDock)),
97 theme.tooltip.clone(),
98 cx,
99 )
100 }
101 .boxed()
102 }
103}
104
105impl StatusItemView for ToggleDockButton {
106 fn set_active_pane_item(
107 &mut self,
108 _active_pane_item: Option<&dyn crate::ItemHandle>,
109 _cx: &mut ViewContext<Self>,
110 ) {
111 //Not applicable
112 }
113}