1use gpui::{
2 elements::{Empty, MouseEventHandler, Svg},
3 CursorStyle, Element, ElementBox, Entity, MouseButton, View, ViewContext, ViewHandle,
4 WeakViewHandle,
5};
6use settings::Settings;
7
8use crate::{handle_dropped_item, StatusItemView, Workspace};
9
10use super::{icon_for_dock_anchor, FocusDock, HideDock};
11
12pub struct ToggleDockButton {
13 workspace: WeakViewHandle<Workspace>,
14}
15
16impl ToggleDockButton {
17 pub fn new(workspace: ViewHandle<Workspace>, cx: &mut ViewContext<Self>) -> Self {
18 // When dock moves, redraw so that the icon and toggle status matches.
19 cx.subscribe(&workspace, |_, _, _, cx| cx.notify()).detach();
20
21 Self {
22 workspace: workspace.downgrade(),
23 }
24 }
25}
26
27impl Entity for ToggleDockButton {
28 type Event = ();
29}
30
31impl View for ToggleDockButton {
32 fn ui_name() -> &'static str {
33 "Dock Toggle"
34 }
35
36 fn render(&mut self, cx: &mut gpui::RenderContext<'_, Self>) -> ElementBox {
37 let workspace = self.workspace.upgrade(cx);
38
39 if workspace.is_none() {
40 return Empty::new().boxed();
41 }
42
43 let workspace = workspace.unwrap();
44 let dock_position = workspace.read(cx).dock.position;
45 let dock_pane = workspace.read(cx.app).dock_pane().clone();
46
47 let theme = cx.global::<Settings>().theme.clone();
48
49 let button = MouseEventHandler::<Self>::new(0, cx, {
50 let theme = theme.clone();
51 move |state, _| {
52 let style = theme
53 .workspace
54 .status_bar
55 .sidebar_buttons
56 .item
57 .style_for(state, dock_position.is_visible());
58
59 Svg::new(icon_for_dock_anchor(dock_position.anchor()))
60 .with_color(style.icon_color)
61 .constrained()
62 .with_width(style.icon_size)
63 .with_height(style.icon_size)
64 .contained()
65 .with_style(style.container)
66 .boxed()
67 }
68 })
69 .with_cursor_style(CursorStyle::PointingHand)
70 .on_up(MouseButton::Left, move |event, cx| {
71 let drop_index = dock_pane.read(cx.app).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 .boxed()
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}