diff --git a/assets/icons/arrow-left.svg b/assets/icons/arrow-left.svg
new file mode 100644
index 0000000000..904fdaa1a7
--- /dev/null
+++ b/assets/icons/arrow-left.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/icons/arrow-right.svg b/assets/icons/arrow-right.svg
new file mode 100644
index 0000000000..b7e1bec6d8
--- /dev/null
+++ b/assets/icons/arrow-right.svg
@@ -0,0 +1,3 @@
+
diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs
index 184b1880f0..c3052ff6c5 100644
--- a/crates/theme/src/theme.rs
+++ b/crates/theme/src/theme.rs
@@ -108,6 +108,7 @@ pub struct Toolbar {
pub container: ContainerStyle,
pub height: f32,
pub item_spacing: f32,
+ pub nav_button: Interactive,
}
#[derive(Clone, Deserialize, Default)]
diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs
index bbc086395b..0fb5225cc5 100644
--- a/crates/workspace/src/pane.rs
+++ b/crates/workspace/src/pane.rs
@@ -168,12 +168,13 @@ pub struct NavigationEntry {
impl Pane {
pub fn new(cx: &mut ViewContext) -> Self {
+ let handle = cx.weak_handle();
Self {
items: Vec::new(),
active_item_index: 0,
autoscroll: false,
nav_history: Default::default(),
- toolbar: cx.add_view(|_| Toolbar::new()),
+ toolbar: cx.add_view(|_| Toolbar::new(handle)),
}
}
diff --git a/crates/workspace/src/toolbar.rs b/crates/workspace/src/toolbar.rs
index e9b20bf3a0..9d8274288b 100644
--- a/crates/workspace/src/toolbar.rs
+++ b/crates/workspace/src/toolbar.rs
@@ -1,7 +1,7 @@
-use crate::ItemHandle;
+use crate::{ItemHandle, Pane};
use gpui::{
- elements::*, AnyViewHandle, AppContext, ElementBox, Entity, MutableAppContext, RenderContext,
- View, ViewContext, ViewHandle,
+ elements::*, platform::CursorStyle, Action, AnyViewHandle, AppContext, ElementBox, Entity,
+ MutableAppContext, RenderContext, View, ViewContext, ViewHandle, WeakViewHandle,
};
use settings::Settings;
@@ -42,6 +42,7 @@ pub enum ToolbarItemLocation {
pub struct Toolbar {
active_pane_item: Option>,
+ pane: WeakViewHandle,
items: Vec<(Box, ToolbarItemLocation)>,
}
@@ -60,6 +61,7 @@ impl View for Toolbar {
let mut primary_left_items = Vec::new();
let mut primary_right_items = Vec::new();
let mut secondary_item = None;
+ let spacing = theme.item_spacing;
for (item, position) in &self.items {
match *position {
@@ -68,7 +70,7 @@ impl View for Toolbar {
let left_item = ChildView::new(item.as_ref())
.aligned()
.contained()
- .with_margin_right(theme.item_spacing);
+ .with_margin_right(spacing);
if let Some((flex, expanded)) = flex {
primary_left_items.push(left_item.flex(flex, expanded).boxed());
} else {
@@ -79,7 +81,7 @@ impl View for Toolbar {
let right_item = ChildView::new(item.as_ref())
.aligned()
.contained()
- .with_margin_left(theme.item_spacing)
+ .with_margin_left(spacing)
.flex_float();
if let Some((flex, expanded)) = flex {
primary_right_items.push(right_item.flex(flex, expanded).boxed());
@@ -98,26 +100,78 @@ impl View for Toolbar {
}
}
+ let pane = self.pane.clone();
+ let container_style = theme.container;
+ let height = theme.height;
+ let button_style = theme.nav_button;
+
Flex::column()
.with_child(
Flex::row()
+ .with_child(nav_button(
+ "icons/arrow-left.svg",
+ button_style,
+ spacing,
+ super::GoBack {
+ pane: Some(pane.clone()),
+ },
+ cx,
+ ))
+ .with_child(nav_button(
+ "icons/arrow-right.svg",
+ button_style,
+ spacing,
+ super::GoForward {
+ pane: Some(pane.clone()),
+ },
+ cx,
+ ))
.with_children(primary_left_items)
.with_children(primary_right_items)
.constrained()
- .with_height(theme.height)
+ .with_height(height)
.boxed(),
)
.with_children(secondary_item)
.contained()
- .with_style(theme.container)
+ .with_style(container_style)
.boxed()
}
}
+fn nav_button(
+ svg_path: &'static str,
+ style: theme::Interactive,
+ spacing: f32,
+ action: A,
+ cx: &mut RenderContext,
+) -> ElementBox {
+ MouseEventHandler::new::(0, cx, |state, _| {
+ let style = style.style_for(state, false);
+ 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(style.button_width)
+ .boxed()
+ })
+ .with_cursor_style(CursorStyle::PointingHand)
+ .on_mouse_down(move |_, cx| cx.dispatch_action(action.clone()))
+ .contained()
+ .with_margin_right(spacing)
+ .boxed()
+}
+
impl Toolbar {
- pub fn new() -> Self {
+ pub fn new(pane: WeakViewHandle) -> Self {
Self {
active_pane_item: None,
+ pane,
items: Default::default(),
}
}
diff --git a/styles/src/styleTree/workspace.ts b/styles/src/styleTree/workspace.ts
index 2deadc02e7..ba3978fc74 100644
--- a/styles/src/styleTree/workspace.ts
+++ b/styles/src/styleTree/workspace.ts
@@ -139,6 +139,15 @@ export default function workspace(theme: Theme) {
background: backgroundColor(theme, 500),
border: border(theme, "secondary", { bottom: true }),
itemSpacing: 8,
+ navButton: {
+ color: iconColor(theme, "secondary"),
+ iconWidth: 8,
+ buttonWidth: 12,
+ margin: { left: 8, right: 8 },
+ hover: {
+ color: iconColor(theme, "active"),
+ },
+ },
padding: { left: 16, right: 8, top: 4, bottom: 4 },
},
breadcrumbs: {