diff --git a/assets/icons/panel-bottom.svg b/assets/icons/panel-bottom.svg
new file mode 100644
index 00000000..ebe599c7
--- /dev/null
+++ b/assets/icons/panel-bottom.svg
@@ -0,0 +1 @@
+
diff --git a/assets/icons/panel-left.svg b/assets/icons/panel-left.svg
new file mode 100644
index 00000000..2eed2667
--- /dev/null
+++ b/assets/icons/panel-left.svg
@@ -0,0 +1 @@
+
diff --git a/assets/icons/panel-right.svg b/assets/icons/panel-right.svg
new file mode 100644
index 00000000..d29a4a51
--- /dev/null
+++ b/assets/icons/panel-right.svg
@@ -0,0 +1 @@
+
diff --git a/crates/app/src/story_workspace.rs b/crates/app/src/story_workspace.rs
index 0e00c91b..c1af7f9d 100644
--- a/crates/app/src/story_workspace.rs
+++ b/crates/app/src/story_workspace.rs
@@ -15,7 +15,7 @@ use ui::{
h_flex,
popup_menu::PopupMenuExt,
theme::{ActiveTheme, Colorize as _, Theme},
- ContextModal, IconName, Root, Sizable,
+ ContextModal, IconName, Root, Selectable, Sizable,
};
use workspace::TitleBar;
@@ -274,6 +274,61 @@ impl StoryWorkspace {
Ok(window)
})
}
+
+ fn render_panel_buttons(&self, cx: &mut ViewContext) -> impl IntoElement {
+ let left_open = self
+ .dock_area
+ .read(cx)
+ .is_dock_open(ui::dock::DockPlacement::Left, cx);
+ let bottom_open = self
+ .dock_area
+ .read(cx)
+ .is_dock_open(ui::dock::DockPlacement::Bottom, cx);
+ let right_open = self
+ .dock_area
+ .read(cx)
+ .is_dock_open(ui::dock::DockPlacement::Right, cx);
+
+ h_flex()
+ .mr_2()
+ .gap_1()
+ .child(
+ Button::new("panel-left")
+ .icon(IconName::PanelLeft)
+ .small()
+ .ghost()
+ .selected(left_open)
+ .on_click(cx.listener(move |this, _: &ClickEvent, cx| {
+ this.dock_area.update(cx, |dock_area, cx| {
+ dock_area.toggle_dock(ui::dock::DockPlacement::Left, cx);
+ })
+ })),
+ )
+ .child(
+ Button::new("panel-bottom")
+ .icon(IconName::PanelBottom)
+ .small()
+ .ghost()
+ .selected(bottom_open)
+ .on_click(cx.listener(move |this, _: &ClickEvent, cx| {
+ this.dock_area.update(cx, |dock_area, cx| {
+ dock_area.toggle_dock(ui::dock::DockPlacement::Bottom, cx);
+ })
+ })),
+ )
+ .child(
+ Button::new("panel-right")
+ .icon(IconName::PanelRight)
+ .small()
+ .ghost()
+ .selected(right_open)
+ .on_click(cx.listener(move |this, _: &ClickEvent, cx| {
+ this.dock_area.update(cx, |dock_area, cx| {
+ dock_area.toggle_dock(ui::dock::DockPlacement::Right, cx);
+ })
+ })),
+ )
+ }
}
pub fn open_new(
@@ -324,6 +379,7 @@ impl Render for StoryWorkspace {
.justify_end()
.px_2()
.gap_2()
+ .child(self.render_panel_buttons(cx))
.child(self.theme_color_picker.clone())
.child(
Button::new("theme-mode")
diff --git a/crates/ui/src/dock/dock.rs b/crates/ui/src/dock/dock.rs
index a9b6b47b..a52ea28c 100644
--- a/crates/ui/src/dock/dock.rs
+++ b/crates/ui/src/dock/dock.rs
@@ -105,12 +105,6 @@ impl Dock {
Self::new(dock_area, panels, DockPlacement::Right, cx)
}
- /// Set the Dock to be open.
- pub fn open(mut self) -> Self {
- self.open = true;
- self
- }
-
/// Set the Dock to be resizeable, default: true
pub fn resizeable(mut self, resizeable: bool) -> Self {
self.resizeable = resizeable;
@@ -122,6 +116,15 @@ impl Dock {
&self.panels
}
+ pub fn is_open(&self) -> bool {
+ self.open
+ }
+
+ pub fn toggle_open(&mut self, cx: &mut ViewContext) {
+ self.open = !self.open;
+ cx.notify();
+ }
+
/// Returns the active panel index.
pub fn active_ix(&self) -> usize {
self.active_ix
@@ -177,7 +180,6 @@ impl Dock {
.occlude()
.absolute()
.flex_shrink_0()
- .bg(gpui::transparent_white())
.when(self.placement.is_left(), |this| {
// FIXME: Improve this to let the scroll bar have px(HANDLE_PADDING)
this.cursor_col_resize()
diff --git a/crates/ui/src/dock/mod.rs b/crates/ui/src/dock/mod.rs
index c9980aa2..84835f16 100644
--- a/crates/ui/src/dock/mod.rs
+++ b/crates/ui/src/dock/mod.rs
@@ -253,6 +253,26 @@ impl DockArea {
});
}
+ pub fn is_dock_open(&self, placement: DockPlacement, cx: &AppContext) -> bool {
+ match placement {
+ DockPlacement::Left => self.left_dock.read(cx).is_open(),
+ DockPlacement::Bottom => self.bottom_dock.read(cx).is_open(),
+ DockPlacement::Right => self.right_dock.read(cx).is_open(),
+ }
+ }
+
+ pub fn toggle_dock(&self, placement: DockPlacement, cx: &mut ViewContext) {
+ let dock = match placement {
+ DockPlacement::Left => &self.left_dock,
+ DockPlacement::Bottom => &self.bottom_dock,
+ DockPlacement::Right => &self.right_dock,
+ };
+
+ dock.update(cx, |view, cx| {
+ view.toggle_open(cx);
+ })
+ }
+
/// Dump the dock panels layout to DockItemState.
///
/// See also `DockItemState::to_item` for the load DockItem from DockItemState.
diff --git a/crates/ui/src/icon.rs b/crates/ui/src/icon.rs
index c9dd751a..08a21694 100644
--- a/crates/ui/src/icon.rs
+++ b/crates/ui/src/icon.rs
@@ -43,6 +43,9 @@ pub enum IconName {
Minus,
Moon,
Palette,
+ PanelBottom,
+ PanelLeft,
+ PanelRight,
Plus,
Search,
SortAscending,
@@ -105,6 +108,9 @@ impl IconName {
IconName::ThumbsDown => "icons/thumbs-down.svg",
IconName::ThumbsUp => "icons/thumbs-up.svg",
IconName::TriangleAlert => "icons/triangle-alert.svg",
+ IconName::PanelLeft => "icons/panel-left.svg",
+ IconName::PanelBottom => "icons/panel-bottom.svg",
+ IconName::PanelRight => "icons/panel-right.svg",
}
.into()
}