Move navigation buttons to the tab bar.

Co-authored-by: Kyle <kyle@zed.dev>
This commit is contained in:
Piotr Osiewicz 2023-08-03 16:05:24 +02:00
parent b4f6d6eadc
commit 7d83d15bf3
4 changed files with 126 additions and 69 deletions

View File

@ -295,6 +295,7 @@ pub struct TabBar {
pub inactive_pane: TabStyles,
pub dragged_tab: Tab,
pub height: f32,
pub nav_button: Interactive<IconButton>,
}
impl TabBar {
@ -359,7 +360,6 @@ pub struct Toolbar {
pub container: ContainerStyle,
pub height: f32,
pub item_spacing: f32,
pub nav_button: Interactive<IconButton>,
}
#[derive(Clone, Deserialize, Default, JsonSchema)]

View File

@ -222,6 +222,56 @@ impl TabBarContextMenu {
}
}
#[allow(clippy::too_many_arguments)]
fn nav_button<A: Action, F: 'static + Fn(&mut Pane, &mut ViewContext<Pane>)>(
svg_path: &'static str,
style: theme::Interactive<theme::IconButton>,
nav_button_height: f32,
tooltip_style: TooltipStyle,
enabled: bool,
on_click: F,
tooltip_action: A,
action_name: &str,
cx: &mut ViewContext<Pane>,
) -> AnyElement<Pane> {
MouseEventHandler::<A, _>::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::<A>(
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<Workspace>,
@ -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,

View File

@ -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);

View File

@ -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
}
}