From 929ebd7175fd434d76e973889c57e4d8bd349a73 Mon Sep 17 00:00:00 2001 From: Joseph Lyons Date: Fri, 3 Mar 2023 11:36:02 -0800 Subject: [PATCH] Add a terminal button to status bar Co-Authored-By: Petros Amoiridis --- crates/workspace/src/terminal_button.rs | 86 +++++++++++++++++++++++++ crates/workspace/src/workspace.rs | 4 ++ 2 files changed, 90 insertions(+) create mode 100644 crates/workspace/src/terminal_button.rs diff --git a/crates/workspace/src/terminal_button.rs b/crates/workspace/src/terminal_button.rs new file mode 100644 index 0000000000..91bbef79d5 --- /dev/null +++ b/crates/workspace/src/terminal_button.rs @@ -0,0 +1,86 @@ +use gpui::{ + elements::{Empty, MouseEventHandler, Svg}, + CursorStyle, Element, ElementBox, Entity, MouseButton, RenderContext, View, ViewContext, + ViewHandle, WeakViewHandle, +}; +use settings::Settings; + +use crate::{dock::FocusDock, item::ItemHandle, StatusItemView, Workspace}; + +pub struct TerminalButton { + workspace: WeakViewHandle, +} + +impl TerminalButton { + pub fn new(workspace: ViewHandle, cx: &mut ViewContext) -> Self { + // When dock moves, redraw so that the icon and toggle status matches. + cx.subscribe(&workspace, |_, _, _, cx| cx.notify()).detach(); + + Self { + workspace: workspace.downgrade(), + } + } +} + +impl Entity for TerminalButton { + type Event = (); +} + +impl View for TerminalButton { + fn ui_name() -> &'static str { + "TerminalButton" + } + + fn render(&mut self, cx: &mut RenderContext<'_, Self>) -> ElementBox { + let workspace = self.workspace.upgrade(cx); + + if workspace.is_none() { + return Empty::new().boxed(); + } + + // let workspace = workspace.unwrap(); + let theme = cx.global::().theme.clone(); + + MouseEventHandler::::new(0, cx, { + let theme = theme.clone(); + move |state, _| { + let style = theme + .workspace + .status_bar + .sidebar_buttons + .item + .style_for(state, true); + + Svg::new("icons/terminal_12.svg") + .with_color(style.icon_color) + .constrained() + .with_width(style.icon_size) + .with_height(style.icon_size) + .contained() + .with_style(style.container) + .boxed() + } + }) + .with_cursor_style(CursorStyle::PointingHand) + .on_up(MouseButton::Left, move |_, _| { + // let dock_pane = workspace.read(cx.app).dock_pane(); + // let drop_index = dock_pane.read(cx.app).items_len() + 1; + // handle_dropped_item(event, &dock_pane.downgrade(), drop_index, false, None, cx); + }) + .on_click(MouseButton::Left, |_, cx| { + cx.dispatch_action(FocusDock); + }) + .with_tooltip::( + 0, + "Show Terminal".into(), + Some(Box::new(FocusDock)), + theme.tooltip.clone(), + cx, + ) + .boxed() + } +} + +impl StatusItemView for TerminalButton { + fn set_active_pane_item(&mut self, _: Option<&dyn ItemHandle>, _: &mut ViewContext) {} +} diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index c134c7f68c..b9d80e7150 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -12,6 +12,7 @@ pub mod searchable; pub mod shared_screen; pub mod sidebar; mod status_bar; +pub mod terminal_button; mod toolbar; pub use smallvec; @@ -56,6 +57,7 @@ use std::{ sync::Arc, time::Duration, }; +use terminal_button::TerminalButton; use crate::{ notifications::simple_message_notification::{MessageNotification, OsOpen}, @@ -584,6 +586,7 @@ impl Workspace { let left_sidebar = cx.add_view(|_| Sidebar::new(SidebarSide::Left)); let right_sidebar = cx.add_view(|_| Sidebar::new(SidebarSide::Right)); let left_sidebar_buttons = cx.add_view(|cx| SidebarButtons::new(left_sidebar.clone(), cx)); + let toggle_terminal = cx.add_view(|cx| TerminalButton::new(handle.clone(), cx)); let toggle_dock = cx.add_view(|cx| ToggleDockButton::new(handle, cx)); let right_sidebar_buttons = cx.add_view(|cx| SidebarButtons::new(right_sidebar.clone(), cx)); @@ -592,6 +595,7 @@ impl Workspace { status_bar.add_left_item(left_sidebar_buttons, cx); status_bar.add_right_item(right_sidebar_buttons, cx); status_bar.add_right_item(toggle_dock, cx); + status_bar.add_right_item(toggle_terminal, cx); status_bar });