diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index c3b3502770..da6a188527 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -295,6 +295,7 @@ pub struct TabBar { pub inactive_pane: TabStyles, pub dragged_tab: Tab, pub height: f32, + pub nav_button: Interactive, } impl TabBar { @@ -359,7 +360,6 @@ pub struct Toolbar { pub container: ContainerStyle, pub height: f32, pub item_spacing: f32, - pub nav_button: Interactive, } #[derive(Clone, Deserialize, Default, JsonSchema)] diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index ee658c9cc9..be1460f200 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -222,6 +222,56 @@ impl TabBarContextMenu { } } +#[allow(clippy::too_many_arguments)] +fn nav_button)>( + svg_path: &'static str, + style: theme::Interactive, + nav_button_height: f32, + tooltip_style: TooltipStyle, + enabled: bool, + on_click: F, + tooltip_action: A, + action_name: &str, + cx: &mut ViewContext, +) -> AnyElement { + MouseEventHandler::::new(0, cx, |state, _| { + let style = if enabled { + style.style_for(state) + } else { + style.disabled_style() + }; + Svg::new(svg_path) + .with_color(style.color) + .constrained() + .with_width(style.icon_width) + .aligned() + .contained() + .with_style(style.container) + .constrained() + .with_width(style.button_width) + .with_height(nav_button_height) + .aligned() + .top() + }) + .with_cursor_style(if enabled { + CursorStyle::PointingHand + } else { + CursorStyle::default() + }) + .on_click(MouseButton::Left, move |_, toolbar, cx| { + on_click(toolbar, cx) + }) + .with_tooltip::( + 0, + action_name.to_string(), + Some(Box::new(tooltip_action)), + tooltip_style, + cx, + ) + .contained() + .into_any_named("nav button") +} + impl Pane { pub fn new( workspace: WeakViewHandle, @@ -236,6 +286,11 @@ impl Pane { context_menu.update(cx, |menu, _| { menu.set_position_mode(OverlayPositionMode::Local) }); + let theme = theme::current(cx).workspace.tab_bar.clone(); + let mut border_for_nav_buttons = theme.tab_style(false, false).container.border.clone(); + border_for_nav_buttons.left = false; + let nav_button_height = theme.height; + let button_style = theme.nav_button; Self { items: Vec::new(), @@ -265,8 +320,59 @@ impl Pane { has_focus: false, can_drop: Rc::new(|_, _| true), can_split: true, - render_tab_bar_buttons: Rc::new(|pane, cx| { + render_tab_bar_buttons: Rc::new(move |pane, cx| { + let tooltip_style = theme::current(cx).tooltip.clone(); Flex::row() + .with_child(nav_button( + "icons/arrow_left_16.svg", + button_style.clone(), + nav_button_height, + tooltip_style.clone(), + pane.can_navigate_backward(), + { + move |pane, cx| { + if let Some(workspace) = pane.workspace.upgrade(cx) { + let pane = cx.weak_handle(); + cx.window_context().defer(move |cx| { + workspace.update(cx, |workspace, cx| { + workspace.go_back(pane, cx).detach_and_log_err(cx) + }) + }) + } + } + }, + super::GoBack, + "Go Back", + cx, + )) + .with_child( + nav_button( + "icons/arrow_right_16.svg", + button_style.clone(), + nav_button_height, + tooltip_style, + pane.can_navigate_forward(), + { + move |pane, cx| { + if let Some(workspace) = pane.workspace.upgrade(cx) { + let pane = cx.weak_handle(); + cx.window_context().defer(move |cx| { + workspace.update(cx, |workspace, cx| { + workspace + .go_forward(pane, cx) + .detach_and_log_err(cx) + }) + }) + } + } + }, + super::GoForward, + "Go Forward", + cx, + ) + .contained() + .with_border(border_for_nav_buttons), + ) // New menu .with_child(Self::render_tab_bar_button( 0, diff --git a/crates/workspace/src/toolbar.rs b/crates/workspace/src/toolbar.rs index 3fa37f3666..1d6e8b7e4b 100644 --- a/crates/workspace/src/toolbar.rs +++ b/crates/workspace/src/toolbar.rs @@ -118,76 +118,10 @@ impl View for Toolbar { } } - let pane = self.pane.clone(); - let mut enable_go_backward = false; - let mut enable_go_forward = false; - if let Some(pane) = pane.and_then(|pane| pane.upgrade(cx)) { - let pane = pane.read(cx); - enable_go_backward = pane.can_navigate_backward(); - enable_go_forward = pane.can_navigate_forward(); - } - let container_style = theme.container; let height = theme.height * primary_items_row_count as f32; - let nav_button_height = theme.height; - let button_style = theme.nav_button; - let tooltip_style = theme::current(cx).tooltip.clone(); let mut primary_items = Flex::row(); - if self.can_navigate { - primary_items.add_child(nav_button( - "icons/arrow_left_16.svg", - button_style, - nav_button_height, - tooltip_style.clone(), - enable_go_backward, - spacing, - { - move |toolbar, cx| { - if let Some(pane) = toolbar.pane.as_ref().and_then(|pane| pane.upgrade(cx)) - { - if let Some(workspace) = pane.read(cx).workspace().upgrade(cx) { - let pane = pane.downgrade(); - cx.window_context().defer(move |cx| { - workspace.update(cx, |workspace, cx| { - workspace.go_back(pane, cx).detach_and_log_err(cx); - }); - }) - } - } - } - }, - super::GoBack, - "Go Back", - cx, - )); - primary_items.add_child(nav_button( - "icons/arrow_right_16.svg", - button_style, - nav_button_height, - tooltip_style, - enable_go_forward, - spacing, - { - move |toolbar, cx| { - if let Some(pane) = toolbar.pane.as_ref().and_then(|pane| pane.upgrade(cx)) - { - if let Some(workspace) = pane.read(cx).workspace().upgrade(cx) { - let pane = pane.downgrade(); - cx.window_context().defer(move |cx| { - workspace.update(cx, |workspace, cx| { - workspace.go_forward(pane, cx).detach_and_log_err(cx); - }); - }) - } - } - } - }, - super::GoForward, - "Go Forward", - cx, - )); - } primary_items.extend(primary_left_items); primary_items.extend(primary_right_items); diff --git a/styles/src/style_tree/tab_bar.ts b/styles/src/style_tree/tab_bar.ts index e7b04246c4..f27ae4b2e6 100644 --- a/styles/src/style_tree/tab_bar.ts +++ b/styles/src/style_tree/tab_bar.ts @@ -84,7 +84,23 @@ export default function tab_bar(): any { bottom: false, }, } - + const nav_button = interactive({ + base: { + color: foreground(theme.highest, "on"), + icon_width: 12, + button_width: 24, + corner_radius: 6, + }, + state: { + hovered: { + color: foreground(theme.highest, "on", "hovered"), + background: background(theme.highest, "on", "hovered"), + }, + disabled: { + color: foreground(theme.highest, "on", "disabled"), + }, + }, + }); const dragged_tab = { ...active_pane_active_tab, background: with_opacity(tab.background, 0.9), @@ -141,5 +157,6 @@ export default function tab_bar(): any { right: false, }, }, + nav_button: nav_button } }