Detailed changes
@@ -10,7 +10,7 @@ use gpui::{
use settings::{settings_file::SettingsFile, Settings};
use workspace::{
- item::Item, open_new, dock::DockPosition, AppState, PaneBackdrop, Welcome, Workspace,
+ dock::DockPosition, item::Item, open_new, AppState, PaneBackdrop, Welcome, Workspace,
WorkspaceId,
};
@@ -202,6 +202,8 @@ impl Dock {
if panel_ix == self.active_panel_index {
self.active_panel_index = 0;
self.set_open(false, cx);
+ } else if panel_ix < self.active_panel_index {
+ self.active_panel_index -= 1;
}
self.panel_entries.remove(panel_ix);
cx.notify();
@@ -228,7 +230,9 @@ impl Dock {
pub fn active_panel(&self) -> Option<&Rc<dyn PanelHandle>> {
if self.is_open {
- self.panel_entries.get(self.active_panel_index).map(|entry| &entry.panel)
+ self.panel_entries
+ .get(self.active_panel_index)
+ .map(|entry| &entry.panel)
} else {
None
}
@@ -416,3 +420,68 @@ impl StatusItemView for PanelButtons {
) {
}
}
+
+#[cfg(test)]
+pub(crate) mod test {
+ use super::*;
+ use gpui::Entity;
+
+ pub enum TestPanelEvent {
+ PositionChanged,
+ Activated,
+ Closed,
+ }
+
+ pub struct TestPanel {
+ pub position: DockPosition,
+ }
+
+ impl Entity for TestPanel {
+ type Event = TestPanelEvent;
+ }
+
+ impl View for TestPanel {
+ fn ui_name() -> &'static str {
+ "TestPanel"
+ }
+
+ fn render(&mut self, _: &mut ViewContext<'_, '_, Self>) -> AnyElement<Self> {
+ Empty::new().into_any()
+ }
+ }
+
+ impl Panel for TestPanel {
+ fn position(&self, _: &gpui::WindowContext) -> super::DockPosition {
+ self.position
+ }
+
+ fn position_is_valid(&self, _: super::DockPosition) -> bool {
+ true
+ }
+
+ fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>) {
+ self.position = position;
+ cx.emit(TestPanelEvent::PositionChanged);
+ }
+
+ fn icon_path(&self) -> &'static str {
+ "icons/test_panel.svg"
+ }
+
+ fn icon_tooltip(&self) -> String {
+ "Test Panel".into()
+ }
+
+ fn should_change_position_on_event(event: &Self::Event) -> bool {
+ matches!(event, TestPanelEvent::PositionChanged)
+ }
+
+ fn should_activate_on_event(&self, event: &Self::Event, _: &gpui::AppContext) -> bool {
+ matches!(event, TestPanelEvent::Activated)
+ }
+
+ fn should_close_on_event(&self, event: &Self::Event, _: &gpui::AppContext) -> bool {
+ matches!(event, TestPanelEvent::Closed)
+ }
+ }
+}
@@ -214,10 +214,7 @@ impl WorkspaceDb {
workspace_location = ?2,
left_sidebar_open = ?3,
timestamp = CURRENT_TIMESTAMP
- ))?((
- workspace.id,
- &workspace.location,
- ))
+ ))?((workspace.id, &workspace.location))
.context("Updating workspace")?;
// Save center pane group
@@ -454,7 +451,6 @@ impl WorkspaceDb {
#[cfg(test)]
mod tests {
-
use db::open_test_db;
use super::*;
@@ -1,6 +1,4 @@
-use crate::{
- ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId,
-};
+use crate::{ItemDeserializers, Member, Pane, PaneAxis, Workspace, WorkspaceId};
use anyhow::{anyhow, Context, Result};
use async_recursion::async_recursion;
use db::sqlez::{
@@ -859,7 +859,7 @@ impl Workspace {
was_visible = dock.is_open()
&& dock
.active_panel()
- .map_or(false, |item| item.as_any().is::<T>());
+ .map_or(false, |active_panel| active_panel.id() == panel.id());
dock.remove_panel(&panel, cx);
});
dock = match panel.read(cx).position(cx) {
@@ -2688,7 +2688,11 @@ impl View for Workspace {
.flex(1., true),
)
.with_children(
- if self.bottom_dock.read(cx).active_panel().is_some()
+ if self
+ .bottom_dock
+ .read(cx)
+ .active_panel()
+ .is_some()
{
Some(ChildView::new(&self.bottom_dock, cx))
} else {
@@ -3074,7 +3078,10 @@ fn parse_pixel_position_env_var(value: &str) -> Option<Vector2F> {
mod tests {
use std::{cell::RefCell, rc::Rc};
- use crate::item::test::{TestItem, TestItemEvent, TestProjectItem};
+ use crate::{
+ dock::test::TestPanel,
+ item::test::{TestItem, TestItemEvent, TestProjectItem},
+ };
use super::*;
use fs::FakeFs;
@@ -3644,4 +3651,89 @@ mod tests {
assert!(pane.can_navigate_forward());
});
}
+
+ #[gpui::test]
+ async fn test_panels(deterministic: Arc<Deterministic>, cx: &mut gpui::TestAppContext) {
+ deterministic.forbid_parking();
+ Settings::test_async(cx);
+ let fs = FakeFs::new(cx.background());
+
+ let project = Project::test(fs, [], cx).await;
+ let (_window_id, workspace) = cx.add_window(|cx| Workspace::test_new(project, cx));
+
+ let (panel_1, panel_2) = workspace.update(cx, |workspace, cx| {
+ // Add panel_1 on the left, panel_2 on the right.
+ let panel_1 = cx.add_view(|_| TestPanel {
+ position: DockPosition::Left,
+ });
+ workspace.add_panel(panel_1.clone(), cx);
+ workspace
+ .left_dock()
+ .update(cx, |left_dock, cx| left_dock.set_open(true, cx));
+ let panel_2 = cx.add_view(|_| TestPanel {
+ position: DockPosition::Right,
+ });
+ workspace.add_panel(panel_2.clone(), cx);
+ workspace
+ .right_dock()
+ .update(cx, |right_dock, cx| right_dock.set_open(true, cx));
+
+ assert_eq!(
+ workspace.left_dock().read(cx).active_panel().unwrap().id(),
+ panel_1.id()
+ );
+ assert_eq!(
+ workspace.right_dock().read(cx).active_panel().unwrap().id(),
+ panel_2.id()
+ );
+
+ (panel_1, panel_2)
+ });
+
+ // Move panel_1 to the right
+ panel_1.update(cx, |panel_1, cx| {
+ panel_1.set_position(DockPosition::Right, cx)
+ });
+
+ workspace.update(cx, |workspace, cx| {
+ // Since panel_1 was visible on the left, it should now be visible now that it's been moved to the right.
+ // Since it was the only panel on the left, the left dock should now be closed.
+ assert!(!workspace.left_dock().read(cx).is_open());
+ assert!(workspace.left_dock().read(cx).active_panel().is_none());
+ assert_eq!(
+ workspace.right_dock().read(cx).active_panel().unwrap().id(),
+ panel_1.id()
+ );
+
+ // Now we move panel_2Β to the left
+ panel_2.set_position(DockPosition::Left, cx);
+ });
+
+ workspace.update(cx, |workspace, cx| {
+ // Since panel_2 was not visible on the right, we don't open the left dock.
+ assert!(!workspace.left_dock().read(cx).is_open());
+ // And the right dock is unaffected in it's displaying of panel_1
+ assert!(workspace.right_dock().read(cx).is_open());
+ assert_eq!(
+ workspace.right_dock().read(cx).active_panel().unwrap().id(),
+ panel_1.id()
+ );
+ });
+
+ // Move panel_1 back to the left
+ panel_1.update(cx, |panel_1, cx| {
+ panel_1.set_position(DockPosition::Left, cx)
+ });
+
+ workspace.update(cx, |workspace, cx| {
+ // Since panel_1 was visible on the right, we open the left dock and make panel_1 active.
+ assert!(workspace.left_dock().read(cx).is_open());
+ assert_eq!(
+ workspace.left_dock().read(cx).active_panel().unwrap().id(),
+ panel_1.id()
+ );
+ // And right the dock should be closed as it no longer has any panels.
+ assert!(!workspace.right_dock().read(cx).is_open());
+ });
+ }
}
@@ -52,8 +52,7 @@ use staff_mode::StaffMode;
use theme::ThemeRegistry;
use util::{channel::RELEASE_CHANNEL, paths, ResultExt, TryFutureExt};
use workspace::{
- item::ItemHandle, notifications::NotifyResultExt, AppState, OpenSettings,
- Workspace,
+ item::ItemHandle, notifications::NotifyResultExt, AppState, OpenSettings, Workspace,
};
use zed::{self, build_window_options, initialize_workspace, languages, menus};