terminal_button.rs

 1use gpui::{
 2    elements::{Empty, MouseEventHandler, Svg},
 3    CursorStyle, Element, ElementBox, Entity, MouseButton, RenderContext, View, ViewContext,
 4    ViewHandle, WeakViewHandle,
 5};
 6use settings::Settings;
 7
 8use crate::{dock::FocusDock, item::ItemHandle, StatusItemView, Workspace};
 9
10pub struct TerminalButton {
11    workspace: WeakViewHandle<Workspace>,
12}
13
14impl TerminalButton {
15    pub fn new(workspace: ViewHandle<Workspace>, cx: &mut ViewContext<Self>) -> Self {
16        // When terminal moves, redraw so that the icon and toggle status matches.
17        cx.subscribe(&workspace, |_, _, _, cx| cx.notify()).detach();
18
19        Self {
20            workspace: workspace.downgrade(),
21        }
22    }
23}
24
25impl Entity for TerminalButton {
26    type Event = ();
27}
28
29impl View for TerminalButton {
30    fn ui_name() -> &'static str {
31        "TerminalButton"
32    }
33
34    fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox {
35        let workspace = self.workspace.upgrade(cx);
36
37        if workspace.is_none() {
38            return Empty::new().boxed();
39        }
40
41        let focused_view = cx.focused_view_id(cx.window_id());
42
43        // FIXME: Don't hardcode "Terminal" in here
44        let active = focused_view
45            .map(|view| cx.view_ui_name(cx.window_id(), view) == Some("Terminal"))
46            .unwrap_or(false);
47
48        // let workspace = workspace.unwrap();
49        let theme = cx.global::<Settings>().theme.clone();
50
51        MouseEventHandler::<Self>::new(0, cx, {
52            let theme = theme.clone();
53            move |state, _| {
54                let style = theme
55                    .workspace
56                    .status_bar
57                    .sidebar_buttons
58                    .item
59                    .style_for(state, active);
60
61                Svg::new("icons/terminal_12.svg")
62                    .with_color(style.icon_color)
63                    .constrained()
64                    .with_width(style.icon_size)
65                    .with_height(style.icon_size)
66                    .contained()
67                    .with_style(style.container)
68                    .boxed()
69            }
70        })
71        .with_cursor_style(CursorStyle::PointingHand)
72        .on_click(MouseButton::Left, move |_, cx| {
73            if !active {
74                cx.dispatch_action(FocusDock);
75            }
76        })
77        .with_tooltip::<Self, _>(
78            0,
79            "Show Terminal".into(),
80            Some(Box::new(FocusDock)),
81            theme.tooltip.clone(),
82            cx,
83        )
84        .boxed()
85    }
86}
87
88impl StatusItemView for TerminalButton {
89    fn set_active_pane_item(&mut self, _: Option<&dyn ItemHandle>, cx: &mut ViewContext<Self>) {
90        cx.notify();
91    }
92}