diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 65418dd997..9cc1ad908a 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -3972,6 +3972,12 @@ impl Clone for AnyViewHandle { } } +impl PartialEq for AnyViewHandle { + fn eq(&self, other: &Self) -> bool { + self.window_id == other.window_id && self.view_id == other.view_id + } +} + impl PartialEq> for AnyViewHandle { fn eq(&self, other: &ViewHandle) -> bool { self.window_id == other.window_id && self.view_id == other.view_id diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index b1f0740df0..c448ac4e43 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -1373,10 +1373,16 @@ impl workspace::dock::Panel for ProjectPanel { cx.global::().project_panel.default_width } - fn can_zoom(&self, _cx: &gpui::WindowContext) -> bool { + fn should_zoom_in_on_event(_: &Self::Event) -> bool { false } + fn should_zoom_out_on_event(_: &Self::Event) -> bool { + false + } + + fn set_zoomed(&mut self, _: bool, _: &mut ViewContext) {} + fn icon_path(&self) -> &'static str { "icons/folder_tree_16.svg" } diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index f3bfbdd730..68783a5bc1 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -18,6 +18,8 @@ pub fn init(cx: &mut AppContext) { pub enum Event { Close, DockPositionChanged, + ZoomIn, + ZoomOut, } pub struct TerminalPanel { @@ -96,6 +98,8 @@ impl TerminalPanel { ) { match event { pane::Event::Remove => cx.emit(Event::Close), + pane::Event::ZoomIn => cx.emit(Event::ZoomIn), + pane::Event::ZoomOut => cx.emit(Event::ZoomOut), _ => {} } } @@ -187,8 +191,16 @@ impl Panel for TerminalPanel { } } - fn can_zoom(&self, _: &WindowContext) -> bool { - true + fn should_zoom_in_on_event(event: &Event) -> bool { + matches!(event, Event::ZoomIn) + } + + fn should_zoom_out_on_event(event: &Event) -> bool { + matches!(event, Event::ZoomOut) + } + + fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext) { + self.pane.update(cx, |pane, cx| pane.set_zoomed(zoomed, cx)); } fn icon_path(&self) -> &'static str { diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 2e4303e70f..40e7288de0 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -1,4 +1,4 @@ -use crate::{StatusItemView, ToggleZoom, Workspace}; +use crate::{StatusItemView, Workspace}; use context_menu::{ContextMenu, ContextMenuItem}; use gpui::{ elements::*, impl_actions, platform::CursorStyle, platform::MouseButton, AnyViewHandle, @@ -9,22 +9,20 @@ use serde::Deserialize; use settings::Settings; use std::rc::Rc; -pub fn init(cx: &mut AppContext) { - cx.add_action(Dock::toggle_zoom); -} - pub trait Panel: View { fn position(&self, cx: &WindowContext) -> DockPosition; fn position_is_valid(&self, position: DockPosition) -> bool; fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext); fn default_size(&self, cx: &WindowContext) -> f32; - fn can_zoom(&self, cx: &WindowContext) -> bool; fn icon_path(&self) -> &'static str; fn icon_tooltip(&self) -> String; fn icon_label(&self, _: &AppContext) -> Option { None } fn should_change_position_on_event(_: &Self::Event) -> bool; + fn should_zoom_in_on_event(_: &Self::Event) -> bool; + fn should_zoom_out_on_event(_: &Self::Event) -> bool; + fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext); fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool; fn should_close_on_event(&self, _: &Self::Event, _: &AppContext) -> bool; } @@ -34,8 +32,8 @@ pub trait PanelHandle { fn position(&self, cx: &WindowContext) -> DockPosition; fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool; fn set_position(&self, position: DockPosition, cx: &mut WindowContext); + fn set_zoomed(&self, zoomed: bool, cx: &mut WindowContext); fn default_size(&self, cx: &WindowContext) -> f32; - fn can_zoom(&self, cx: &WindowContext) -> bool; fn icon_path(&self, cx: &WindowContext) -> &'static str; fn icon_tooltip(&self, cx: &WindowContext) -> String; fn icon_label(&self, cx: &WindowContext) -> Option; @@ -67,8 +65,8 @@ where self.read(cx).default_size(cx) } - fn can_zoom(&self, cx: &WindowContext) -> bool { - self.read(cx).can_zoom(cx) + fn set_zoomed(&self, zoomed: bool, cx: &mut WindowContext) { + self.update(cx, |this, cx| this.set_zoomed(zoomed, cx)) } fn icon_path(&self, cx: &WindowContext) -> &'static str { @@ -98,10 +96,6 @@ impl From<&dyn PanelHandle> for AnyViewHandle { } } -pub enum Event { - ZoomIn, -} - pub struct Dock { position: DockPosition, panel_entries: Vec, @@ -192,22 +186,33 @@ impl Dock { cx.notify(); } - pub fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext) { - for (ix, entry) in self.panel_entries.iter_mut().enumerate() { - if ix == self.active_panel_index && entry.panel.can_zoom(cx) { - entry.zoomed = zoomed; - } else { + pub fn set_panel_zoomed( + &mut self, + panel: &AnyViewHandle, + zoomed: bool, + cx: &mut ViewContext, + ) { + for entry in &mut self.panel_entries { + if entry.panel.as_any() == panel { + if zoomed != entry.zoomed { + entry.zoomed = zoomed; + entry.panel.set_zoomed(zoomed, cx); + } + } else if entry.zoomed { entry.zoomed = false; + entry.panel.set_zoomed(false, cx); } } cx.notify(); } - pub fn toggle_zoom(&mut self, _: &ToggleZoom, cx: &mut ViewContext) { - cx.propagate_action(); - if !self.active_entry().map_or(false, |entry| entry.zoomed) { - cx.emit(Event::ZoomIn); + pub fn zoom_out(&mut self, cx: &mut ViewContext) { + for entry in &mut self.panel_entries { + if entry.zoomed { + entry.zoomed = false; + entry.panel.set_zoomed(false, cx); + } } } @@ -342,7 +347,7 @@ impl Dock { } impl Entity for Dock { - type Event = Event; + type Event = (); } impl View for Dock { @@ -568,6 +573,10 @@ pub(crate) mod test { cx.emit(TestPanelEvent::PositionChanged); } + fn set_zoomed(&mut self, _zoomed: bool, _cx: &mut ViewContext) { + unimplemented!() + } + fn default_size(&self, _: &WindowContext) -> f32 { match self.position.axis() { Axis::Horizontal => 300., @@ -575,10 +584,6 @@ pub(crate) mod test { } } - fn can_zoom(&self, _cx: &WindowContext) -> bool { - unimplemented!() - } - fn icon_path(&self) -> &'static str { "icons/test_panel.svg" } @@ -591,6 +596,14 @@ pub(crate) mod test { matches!(event, TestPanelEvent::PositionChanged) } + fn should_zoom_in_on_event(_: &Self::Event) -> bool { + false + } + + fn should_zoom_out_on_event(_: &Self::Event) -> bool { + false + } + fn should_activate_on_event(&self, event: &Self::Event, _: &gpui::AppContext) -> bool { matches!(event, TestPanelEvent::Activated) } diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 6ccd1573bc..73738ab413 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -135,6 +135,7 @@ pub enum Event { ChangeItemTitle, Focus, ZoomIn, + ZoomOut, } pub struct Pane { @@ -661,8 +662,9 @@ impl Pane { } pub fn toggle_zoom(&mut self, _: &ToggleZoom, cx: &mut ViewContext) { - cx.propagate_action(); - if !self.zoomed { + if self.zoomed { + cx.emit(Event::ZoomOut); + } else { cx.emit(Event::ZoomIn); } } diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index af8c958db5..06832e1385 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -182,7 +182,6 @@ pub type WorkspaceId = i64; impl_actions!(workspace, [ActivatePane]); pub fn init(app_state: Arc, cx: &mut AppContext) { - dock::init(cx); pane::init(cx); notifications::init(cx); @@ -232,7 +231,6 @@ pub fn init(app_state: Arc, cx: &mut AppContext) { }, ); cx.add_action(Workspace::toggle_panel); - cx.add_action(Workspace::toggle_zoom); cx.add_action(Workspace::focus_center); cx.add_action(|workspace: &mut Workspace, _: &ActivatePreviousPane, cx| { workspace.activate_previous_pane(cx) @@ -595,7 +593,7 @@ impl Workspace { active_call = Some((call, subscriptions)); } - let mut subscriptions = vec![ + let subscriptions = vec![ cx.observe_fullscreen(|_, _, cx| cx.notify()), cx.observe_window_activation(Self::on_window_activation_changed), cx.observe_window_bounds(move |_, mut bounds, display, cx| { @@ -615,10 +613,19 @@ impl Workspace { .spawn(DB.set_window_bounds(workspace_id, bounds, display)) .detach_and_log_err(cx); }), + cx.observe(&left_dock, |this, _, cx| { + this.serialize_workspace(cx); + cx.notify(); + }), + cx.observe(&bottom_dock, |this, _, cx| { + this.serialize_workspace(cx); + cx.notify(); + }), + cx.observe(&right_dock, |this, _, cx| { + this.serialize_workspace(cx); + cx.notify(); + }), ]; - subscriptions.extend(Self::register_dock(&left_dock, cx)); - subscriptions.extend(Self::register_dock(&bottom_dock, cx)); - subscriptions.extend(Self::register_dock(&right_dock, cx)); let mut this = Workspace { weak_self: weak_handle.clone(), @@ -881,6 +888,11 @@ impl Workspace { dock.activate_panel(dock.panels_len() - 1, cx); } }); + } else if T::should_zoom_in_on_event(event) { + this.zoom_out(cx); + dock.update(cx, |dock, cx| dock.set_panel_zoomed(&panel, true, cx)); + } else if T::should_zoom_out_on_event(event) { + this.zoom_out(cx); } } }) @@ -1464,23 +1476,14 @@ impl Workspace { cx.notify(); } - fn toggle_zoom(&mut self, _: &ToggleZoom, cx: &mut ViewContext) { - // Any time the zoom is toggled we will zoom out all panes and docks. Then, - // the dock or pane that was zoomed will emit an event to zoom itself back in. - self.zoom_out(cx); - } - fn zoom_out(&mut self, cx: &mut ViewContext) { for pane in &self.panes { pane.update(cx, |pane, cx| pane.set_zoomed(false, cx)); } - self.left_dock - .update(cx, |dock, cx| dock.set_zoomed(false, cx)); - self.bottom_dock - .update(cx, |dock, cx| dock.set_zoomed(false, cx)); - self.right_dock - .update(cx, |dock, cx| dock.set_zoomed(false, cx)); + self.left_dock.update(cx, |dock, cx| dock.zoom_out(cx)); + self.bottom_dock.update(cx, |dock, cx| dock.zoom_out(cx)); + self.right_dock.update(cx, |dock, cx| dock.zoom_out(cx)); cx.notify(); } @@ -1490,20 +1493,6 @@ impl Workspace { cx.notify(); } - fn register_dock(dock: &ViewHandle, cx: &mut ViewContext) -> [Subscription; 2] { - [ - cx.observe(dock, |this, _, cx| { - this.serialize_workspace(cx); - cx.notify(); - }), - cx.subscribe(dock, |_, dock, event, cx| { - dock.update(cx, |dock, cx| match event { - dock::Event::ZoomIn => dock.set_zoomed(true, cx), - }) - }), - ] - } - fn add_pane(&mut self, cx: &mut ViewContext) -> ViewHandle { let pane = cx.add_view(|cx| Pane::new(self.weak_handle(), self.app_state.background_actions, cx)); @@ -1727,9 +1716,11 @@ impl Workspace { self.handle_pane_focused(pane.clone(), cx); } pane::Event::ZoomIn => { + self.zoom_out(cx); pane.update(cx, |pane, cx| pane.set_zoomed(true, cx)); cx.notify(); } + pane::Event::ZoomOut => self.zoom_out(cx), } self.serialize_workspace(cx);