diff --git a/assets/settings/default.json b/assets/settings/default.json index 58fb28bc62577b6219fbfb59475b76b08a9d9b0e..5d85e751d482445c7bce29cda0ba08cb89e1fdfa 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -107,6 +107,9 @@ // Automatically update Zed "auto_update": true, // Git gutter behavior configuration. + "project_panel": { + "dock": "left" + }, "git": { // Control whether the git gutter is shown. May take 2 values: // 1. Show the gutter @@ -149,6 +152,8 @@ // } // } "shell": "system", + // Where to dock terminals panel. Can be 'left', 'right', 'bottom'. + "dock": "bottom", // What working directory to use when launching the terminal. // May take 4 values: // 1. Use the current file's project directory. Will Fallback to the diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index a595ec62255c6564600d3c402823a2652deb424d..8ee701c3cc56ae68267cb47bfa50d54ecb8a934c 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -135,12 +135,25 @@ pub enum Event { entry_id: ProjectEntryId, focus_opened_item: bool, }, + DockPositionChanged, } impl ProjectPanel { pub fn new(workspace: &mut Workspace, cx: &mut ViewContext) -> ViewHandle { let project = workspace.project().clone(); let project_panel = cx.add_view(|cx: &mut ViewContext| { + // Update the dock position when the setting changes. + let mut old_dock_position = cx.global::().project_panel_overrides.dock; + dbg!(old_dock_position); + cx.observe_global::(move |_, cx| { + let new_dock_position = cx.global::().project_panel_overrides.dock; + dbg!(new_dock_position); + if new_dock_position != old_dock_position { + old_dock_position = new_dock_position; + cx.emit(Event::DockPositionChanged); + } + }).detach(); + cx.observe(&project, |this, _, cx| { this.update_visible_entries(None, cx); cx.notify(); @@ -242,7 +255,8 @@ impl ProjectPanel { } } } - } + }, + Event::DockPositionChanged => {}, } }) .detach(); @@ -1344,8 +1358,8 @@ impl workspace::dock::Panel for ProjectPanel { "Project Panel".into() } - fn should_change_position_on_event(&self, _: &Self::Event, _: &AppContext) -> bool { - todo!() + fn should_change_position_on_event(event: &Self::Event) -> bool { + matches!(event, Event::DockPositionChanged) } fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool { diff --git a/crates/settings/src/settings.rs b/crates/settings/src/settings.rs index 528812af878febfbd8f2e184c42a5d0b73a028ff..0eb9eb9e5db0b1cb4d799531465d3b117ffcec3a 100644 --- a/crates/settings/src/settings.rs +++ b/crates/settings/src/settings.rs @@ -131,7 +131,7 @@ impl TelemetrySettings { } } -#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema)] +#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, Eq, PartialEq)] #[serde(rename_all="lowercase")] pub enum DockPosition { Left, @@ -407,6 +407,7 @@ pub struct SettingsFileContent { pub autosave: Option, #[serde(flatten)] pub editor: EditorSettings, + pub project_panel: ProjectPanelSettings, #[serde(default)] pub journal: JournalSettings, #[serde(default)] @@ -609,6 +610,7 @@ impl Settings { } } self.editor_overrides = data.editor; + self.project_panel_overrides = data.project_panel; self.git_overrides = data.git.unwrap_or_default(); self.journal_overrides = data.journal; self.terminal_defaults.font_size = data.terminal.font_size; diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index e9cdb5a1ea58431ec649b40ac112fce52b328b32..e2bf2c9e32d9c7239ddbf223709b09640e21e01a 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -160,7 +160,7 @@ impl Panel for TerminalPanel { } } - fn should_change_position_on_event(&self, _: &Self::Event, _: &AppContext) -> bool { + fn should_change_position_on_event(_: &Self::Event) -> bool { todo!() } diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 100b8e8661e59338e30acb01a1009e9b73629eb7..0e2d84e626738bc2c7064c17aec77c22ad79001e 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -15,7 +15,7 @@ pub trait Panel: View { fn icon_label(&self, _: &AppContext) -> Option { None } - fn should_change_position_on_event(&self, _: &Self::Event, _: &AppContext) -> bool; + fn should_change_position_on_event(_: &Self::Event) -> bool; fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool; fn should_close_on_event(&self, _: &Self::Event, _: &AppContext) -> bool; } @@ -80,7 +80,7 @@ pub enum Event { pub struct Dock { position: DockPosition, - items: Vec, + panels: Vec, is_open: bool, active_item_ix: usize, } @@ -112,8 +112,8 @@ impl DockPosition { } } -struct Item { - view: Rc, +struct PanelEntry { + panel: Rc, _subscriptions: [Subscription; 2], } @@ -134,7 +134,7 @@ impl Dock { pub fn new(position: DockPosition) -> Self { Self { position, - items: Default::default(), + panels: Default::default(), active_item_ix: 0, is_open: false, } @@ -161,15 +161,15 @@ impl Dock { cx.notify(); } - pub fn add_panel(&mut self, view: ViewHandle, cx: &mut ViewContext) { + pub fn add_panel(&mut self, panel: ViewHandle, cx: &mut ViewContext) { let subscriptions = [ - cx.observe(&view, |_, _, cx| cx.notify()), - cx.subscribe(&view, |this, view, event, cx| { + cx.observe(&panel, |_, _, cx| cx.notify()), + cx.subscribe(&panel, |this, view, event, cx| { if view.read(cx).should_activate_on_event(event, cx) { if let Some(ix) = this - .items + .panels .iter() - .position(|item| item.view.id() == view.id()) + .position(|item| item.panel.id() == view.id()) { this.activate_item(ix, cx); } @@ -179,13 +179,18 @@ impl Dock { }), ]; - self.items.push(Item { - view: Rc::new(view), + self.panels.push(PanelEntry { + panel: Rc::new(panel), _subscriptions: subscriptions, }); cx.notify() } + pub fn remove_panel(&mut self, panel: &ViewHandle, cx: &mut ViewContext) { + self.panels.retain(|entry| entry.panel.id() != panel.id()); + cx.notify(); + } + pub fn activate_item(&mut self, item_ix: usize, cx: &mut ViewContext) { self.active_item_ix = item_ix; cx.notify(); @@ -202,7 +207,7 @@ impl Dock { pub fn active_item(&self) -> Option<&Rc> { if self.is_open { - self.items.get(self.active_item_ix).map(|item| &item.view) + self.panels.get(self.active_item_ix).map(|item| &item.panel) } else { None } @@ -275,9 +280,9 @@ impl View for PanelButtons { }; let items = dock - .items + .panels .iter() - .map(|item| item.view.clone()) + .map(|item| item.panel.clone()) .collect::>(); Flex::row() .with_children(items.into_iter().enumerate().map(|(ix, view)| { diff --git a/crates/workspace/src/item.rs b/crates/workspace/src/item.rs index a4e034d7412406f5a37543a02222ecaf2b9a994c..d2b9251a6294349780368789c17232ad2ac2437d 100644 --- a/crates/workspace/src/item.rs +++ b/crates/workspace/src/item.rs @@ -1077,7 +1077,7 @@ pub(crate) mod test { unimplemented!() } - fn should_change_position_on_event(&self, _: &Self::Event, _: &AppContext) -> bool { + fn should_change_position_on_event(_: &Self::Event) -> bool { unimplemented!() } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index d86b25b7463e3e704ce573e7e187bec139959088..1708555f50ce0e9aa78fdf091ac06f300f31697a 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -836,10 +836,26 @@ impl Workspace { pub fn add_panel(&mut self, panel: ViewHandle, cx: &mut ViewContext) { let dock = match panel.position(cx) { - DockPosition::Left => &mut self.left_dock, - DockPosition::Bottom => &mut self.bottom_dock, - DockPosition::Right => &mut self.right_dock, + DockPosition::Left => &self.left_dock, + DockPosition::Bottom => &self.bottom_dock, + DockPosition::Right => &self.right_dock, }; + + cx.subscribe(&panel, { + let mut dock = dock.clone(); + move |this, panel, event, cx| { + if T::should_change_position_on_event(event) { + dock.update(cx, |dock, cx| dock.remove_panel(&panel, cx)); + dock = match panel.read(cx).position(cx) { + DockPosition::Left => &this.left_dock, + DockPosition::Bottom => &this.bottom_dock, + DockPosition::Right => &this.right_dock, + }.clone(); + dock.update(cx, |dock, cx| dock.add_panel(panel, cx)); + } + } + }).detach(); + dock.update(cx, |dock, cx| dock.add_panel(panel, cx)); }