diff --git a/crates/project/src/terminals.rs b/crates/project/src/terminals.rs index f7b4105dd2..0f3092ca41 100644 --- a/crates/project/src/terminals.rs +++ b/crates/project/src/terminals.rs @@ -43,11 +43,12 @@ impl Project { .push(terminal_handle.downgrade()); let id = terminal_handle.id(); - cx.observe_release(&terminal_handle, move |project, _terminal, _cx| { + cx.observe_release(&terminal_handle, move |project, _terminal, cx| { let handles = &mut project.terminals.local_handles; if let Some(index) = handles.iter().position(|terminal| terminal.id() == id) { handles.remove(index); + cx.notify(); } }) .detach(); diff --git a/crates/terminal_view/src/terminal_button.rs b/crates/terminal_view/src/terminal_button.rs index 8c723ad4d4..87f0a2deba 100644 --- a/crates/terminal_view/src/terminal_button.rs +++ b/crates/terminal_view/src/terminal_button.rs @@ -19,7 +19,6 @@ pub struct FocusTerminal { terminal_handle: WeakModelHandle, } -//actions!(terminal, [DeployTerminalMenu]); impl_internal_actions!(terminal, [FocusTerminal, DeployTerminalMenu]); pub fn init(cx: &mut MutableAppContext) { @@ -56,13 +55,14 @@ impl View for TerminalButton { .unwrap_or(false); let has_terminals = !project.local_terminal_handles().is_empty(); + let terminal_count = project.local_terminal_handles().len() as i32; let theme = cx.global::().theme.clone(); Stack::new() .with_child( MouseEventHandler::::new(0, cx, { let theme = theme.clone(); - move |state, _| { + move |state, _cx| { let style = theme .workspace .status_bar @@ -70,10 +70,23 @@ impl View for TerminalButton { .item .style_for(state, active); - Svg::new("icons/terminal_12.svg") - .with_color(style.icon_color) + Flex::row() + .with_child( + Svg::new("icons/terminal_12.svg") + .with_color(style.icon_color) + .constrained() + .with_width(style.icon_size) + .aligned() + .named("terminals-icon"), + ) + .with_children(has_terminals.then(|| { + Label::new(terminal_count.to_string(), style.label.text.clone()) + .contained() + .with_style(style.label.container) + .aligned() + .boxed() + })) .constrained() - .with_width(style.icon_size) .with_height(style.icon_size) .contained() .with_style(style.container) @@ -112,8 +125,7 @@ impl View for TerminalButton { impl TerminalButton { pub fn new(workspace: ViewHandle, cx: &mut ViewContext) -> Self { - // When terminal moves, redraw so that the icon and toggle status matches. - cx.subscribe(&workspace, |_, _, _, cx| cx.notify()).detach(); + cx.observe(&workspace, |_, _, cx| cx.notify()).detach(); Self { workspace: workspace.downgrade(), popup_menu: cx.add_view(|cx| { diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index 87de31f635..d64a1d2499 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -340,12 +340,13 @@ pub struct Sidebar { pub container: ContainerStyle, } -#[derive(Clone, Copy, Deserialize, Default)] +#[derive(Clone, Deserialize, Default)] pub struct SidebarItem { #[serde(flatten)] pub container: ContainerStyle, pub icon_color: Color, pub icon_size: f32, + pub label: ContainedText, } #[derive(Deserialize, Default)] diff --git a/crates/workspace/src/sidebar.rs b/crates/workspace/src/sidebar.rs index 214f227757..37375b7e4a 100644 --- a/crates/workspace/src/sidebar.rs +++ b/crates/workspace/src/sidebar.rs @@ -230,7 +230,7 @@ impl View for SidebarButtons { let tooltip_style = theme.tooltip.clone(); let theme = &theme.workspace.status_bar.sidebar_buttons; let sidebar = self.sidebar.read(cx); - let item_style = theme.item; + let item_style = theme.item.clone(); let badge_style = theme.badge; let active_ix = sidebar.active_item_ix; let is_open = sidebar.is_open; @@ -254,7 +254,7 @@ impl View for SidebarButtons { sidebar_side, item_index: ix, }; - MouseEventHandler::::new(ix, cx, move |state, cx| { + MouseEventHandler::::new(ix, cx, |state, cx| { let is_active = is_open && ix == active_ix; let style = item_style.style_for(state, is_active); Stack::new() diff --git a/styles/src/styleTree/statusBar.ts b/styles/src/styleTree/statusBar.ts index b7e9696488..41961c4615 100644 --- a/styles/src/styleTree/statusBar.ts +++ b/styles/src/styleTree/statusBar.ts @@ -100,6 +100,10 @@ export default function statusBar(colorScheme: ColorScheme) { ...statusContainer, iconSize: 16, iconColor: foreground(layer, "variant"), + label: { + margin: { left: 6 }, + ...text(layer, "sans", { size: "sm" }), + }, hover: { iconColor: foreground(layer, "hovered"), background: background(layer, "variant"),