mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-05 10:20:51 +00:00
Don't rely on action propagation for zooming in and out
Co-Authored-By: Antonio Scandurra <antonio@zed.dev>
This commit is contained in:
parent
adf361b374
commit
f87ae6032e
6 changed files with 94 additions and 64 deletions
|
@ -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<T> PartialEq<ViewHandle<T>> for AnyViewHandle {
|
impl<T> PartialEq<ViewHandle<T>> for AnyViewHandle {
|
||||||
fn eq(&self, other: &ViewHandle<T>) -> bool {
|
fn eq(&self, other: &ViewHandle<T>) -> bool {
|
||||||
self.window_id == other.window_id && self.view_id == other.view_id
|
self.window_id == other.window_id && self.view_id == other.view_id
|
||||||
|
|
|
@ -1373,10 +1373,16 @@ impl workspace::dock::Panel for ProjectPanel {
|
||||||
cx.global::<Settings>().project_panel.default_width
|
cx.global::<Settings>().project_panel.default_width
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_zoom(&self, _cx: &gpui::WindowContext) -> bool {
|
fn should_zoom_in_on_event(_: &Self::Event) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn should_zoom_out_on_event(_: &Self::Event) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_zoomed(&mut self, _: bool, _: &mut ViewContext<Self>) {}
|
||||||
|
|
||||||
fn icon_path(&self) -> &'static str {
|
fn icon_path(&self) -> &'static str {
|
||||||
"icons/folder_tree_16.svg"
|
"icons/folder_tree_16.svg"
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ pub fn init(cx: &mut AppContext) {
|
||||||
pub enum Event {
|
pub enum Event {
|
||||||
Close,
|
Close,
|
||||||
DockPositionChanged,
|
DockPositionChanged,
|
||||||
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TerminalPanel {
|
pub struct TerminalPanel {
|
||||||
|
@ -96,6 +98,8 @@ impl TerminalPanel {
|
||||||
) {
|
) {
|
||||||
match event {
|
match event {
|
||||||
pane::Event::Remove => cx.emit(Event::Close),
|
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 {
|
fn should_zoom_in_on_event(event: &Event) -> bool {
|
||||||
true
|
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>) {
|
||||||
|
self.pane.update(cx, |pane, cx| pane.set_zoomed(zoomed, cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_path(&self) -> &'static str {
|
fn icon_path(&self) -> &'static str {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{StatusItemView, ToggleZoom, Workspace};
|
use crate::{StatusItemView, Workspace};
|
||||||
use context_menu::{ContextMenu, ContextMenuItem};
|
use context_menu::{ContextMenu, ContextMenuItem};
|
||||||
use gpui::{
|
use gpui::{
|
||||||
elements::*, impl_actions, platform::CursorStyle, platform::MouseButton, AnyViewHandle,
|
elements::*, impl_actions, platform::CursorStyle, platform::MouseButton, AnyViewHandle,
|
||||||
|
@ -9,22 +9,20 @@ use serde::Deserialize;
|
||||||
use settings::Settings;
|
use settings::Settings;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub fn init(cx: &mut AppContext) {
|
|
||||||
cx.add_action(Dock::toggle_zoom);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Panel: View {
|
pub trait Panel: View {
|
||||||
fn position(&self, cx: &WindowContext) -> DockPosition;
|
fn position(&self, cx: &WindowContext) -> DockPosition;
|
||||||
fn position_is_valid(&self, position: DockPosition) -> bool;
|
fn position_is_valid(&self, position: DockPosition) -> bool;
|
||||||
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>);
|
fn set_position(&mut self, position: DockPosition, cx: &mut ViewContext<Self>);
|
||||||
fn default_size(&self, cx: &WindowContext) -> f32;
|
fn default_size(&self, cx: &WindowContext) -> f32;
|
||||||
fn can_zoom(&self, cx: &WindowContext) -> bool;
|
|
||||||
fn icon_path(&self) -> &'static str;
|
fn icon_path(&self) -> &'static str;
|
||||||
fn icon_tooltip(&self) -> String;
|
fn icon_tooltip(&self) -> String;
|
||||||
fn icon_label(&self, _: &AppContext) -> Option<String> {
|
fn icon_label(&self, _: &AppContext) -> Option<String> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
fn should_change_position_on_event(_: &Self::Event) -> bool;
|
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<Self>);
|
||||||
fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool;
|
fn should_activate_on_event(&self, _: &Self::Event, _: &AppContext) -> bool;
|
||||||
fn should_close_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(&self, cx: &WindowContext) -> DockPosition;
|
||||||
fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool;
|
fn position_is_valid(&self, position: DockPosition, cx: &WindowContext) -> bool;
|
||||||
fn set_position(&self, position: DockPosition, cx: &mut WindowContext);
|
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 default_size(&self, cx: &WindowContext) -> f32;
|
||||||
fn can_zoom(&self, cx: &WindowContext) -> bool;
|
|
||||||
fn icon_path(&self, cx: &WindowContext) -> &'static str;
|
fn icon_path(&self, cx: &WindowContext) -> &'static str;
|
||||||
fn icon_tooltip(&self, cx: &WindowContext) -> String;
|
fn icon_tooltip(&self, cx: &WindowContext) -> String;
|
||||||
fn icon_label(&self, cx: &WindowContext) -> Option<String>;
|
fn icon_label(&self, cx: &WindowContext) -> Option<String>;
|
||||||
|
@ -67,8 +65,8 @@ where
|
||||||
self.read(cx).default_size(cx)
|
self.read(cx).default_size(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_zoom(&self, cx: &WindowContext) -> bool {
|
fn set_zoomed(&self, zoomed: bool, cx: &mut WindowContext) {
|
||||||
self.read(cx).can_zoom(cx)
|
self.update(cx, |this, cx| this.set_zoomed(zoomed, cx))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn icon_path(&self, cx: &WindowContext) -> &'static str {
|
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 {
|
pub struct Dock {
|
||||||
position: DockPosition,
|
position: DockPosition,
|
||||||
panel_entries: Vec<PanelEntry>,
|
panel_entries: Vec<PanelEntry>,
|
||||||
|
@ -192,22 +186,33 @@ impl Dock {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_zoomed(&mut self, zoomed: bool, cx: &mut ViewContext<Self>) {
|
pub fn set_panel_zoomed(
|
||||||
for (ix, entry) in self.panel_entries.iter_mut().enumerate() {
|
&mut self,
|
||||||
if ix == self.active_panel_index && entry.panel.can_zoom(cx) {
|
panel: &AnyViewHandle,
|
||||||
entry.zoomed = zoomed;
|
zoomed: bool,
|
||||||
} else {
|
cx: &mut ViewContext<Self>,
|
||||||
|
) {
|
||||||
|
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.zoomed = false;
|
||||||
|
entry.panel.set_zoomed(false, cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_zoom(&mut self, _: &ToggleZoom, cx: &mut ViewContext<Self>) {
|
pub fn zoom_out(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
cx.propagate_action();
|
for entry in &mut self.panel_entries {
|
||||||
if !self.active_entry().map_or(false, |entry| entry.zoomed) {
|
if entry.zoomed {
|
||||||
cx.emit(Event::ZoomIn);
|
entry.zoomed = false;
|
||||||
|
entry.panel.set_zoomed(false, cx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,7 +347,7 @@ impl Dock {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Entity for Dock {
|
impl Entity for Dock {
|
||||||
type Event = Event;
|
type Event = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
impl View for Dock {
|
impl View for Dock {
|
||||||
|
@ -568,6 +573,10 @@ pub(crate) mod test {
|
||||||
cx.emit(TestPanelEvent::PositionChanged);
|
cx.emit(TestPanelEvent::PositionChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn set_zoomed(&mut self, _zoomed: bool, _cx: &mut ViewContext<Self>) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
fn default_size(&self, _: &WindowContext) -> f32 {
|
fn default_size(&self, _: &WindowContext) -> f32 {
|
||||||
match self.position.axis() {
|
match self.position.axis() {
|
||||||
Axis::Horizontal => 300.,
|
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 {
|
fn icon_path(&self) -> &'static str {
|
||||||
"icons/test_panel.svg"
|
"icons/test_panel.svg"
|
||||||
}
|
}
|
||||||
|
@ -591,6 +596,14 @@ pub(crate) mod test {
|
||||||
matches!(event, TestPanelEvent::PositionChanged)
|
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 {
|
fn should_activate_on_event(&self, event: &Self::Event, _: &gpui::AppContext) -> bool {
|
||||||
matches!(event, TestPanelEvent::Activated)
|
matches!(event, TestPanelEvent::Activated)
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,7 @@ pub enum Event {
|
||||||
ChangeItemTitle,
|
ChangeItemTitle,
|
||||||
Focus,
|
Focus,
|
||||||
ZoomIn,
|
ZoomIn,
|
||||||
|
ZoomOut,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Pane {
|
pub struct Pane {
|
||||||
|
@ -661,8 +662,9 @@ impl Pane {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_zoom(&mut self, _: &ToggleZoom, cx: &mut ViewContext<Self>) {
|
pub fn toggle_zoom(&mut self, _: &ToggleZoom, cx: &mut ViewContext<Self>) {
|
||||||
cx.propagate_action();
|
if self.zoomed {
|
||||||
if !self.zoomed {
|
cx.emit(Event::ZoomOut);
|
||||||
|
} else {
|
||||||
cx.emit(Event::ZoomIn);
|
cx.emit(Event::ZoomIn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,6 @@ pub type WorkspaceId = i64;
|
||||||
impl_actions!(workspace, [ActivatePane]);
|
impl_actions!(workspace, [ActivatePane]);
|
||||||
|
|
||||||
pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
||||||
dock::init(cx);
|
|
||||||
pane::init(cx);
|
pane::init(cx);
|
||||||
notifications::init(cx);
|
notifications::init(cx);
|
||||||
|
|
||||||
|
@ -232,7 +231,6 @@ pub fn init(app_state: Arc<AppState>, cx: &mut AppContext) {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
cx.add_action(Workspace::toggle_panel);
|
cx.add_action(Workspace::toggle_panel);
|
||||||
cx.add_action(Workspace::toggle_zoom);
|
|
||||||
cx.add_action(Workspace::focus_center);
|
cx.add_action(Workspace::focus_center);
|
||||||
cx.add_action(|workspace: &mut Workspace, _: &ActivatePreviousPane, cx| {
|
cx.add_action(|workspace: &mut Workspace, _: &ActivatePreviousPane, cx| {
|
||||||
workspace.activate_previous_pane(cx)
|
workspace.activate_previous_pane(cx)
|
||||||
|
@ -595,7 +593,7 @@ impl Workspace {
|
||||||
active_call = Some((call, subscriptions));
|
active_call = Some((call, subscriptions));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut subscriptions = vec![
|
let subscriptions = vec![
|
||||||
cx.observe_fullscreen(|_, _, cx| cx.notify()),
|
cx.observe_fullscreen(|_, _, cx| cx.notify()),
|
||||||
cx.observe_window_activation(Self::on_window_activation_changed),
|
cx.observe_window_activation(Self::on_window_activation_changed),
|
||||||
cx.observe_window_bounds(move |_, mut bounds, display, cx| {
|
cx.observe_window_bounds(move |_, mut bounds, display, cx| {
|
||||||
|
@ -615,10 +613,19 @@ impl Workspace {
|
||||||
.spawn(DB.set_window_bounds(workspace_id, bounds, display))
|
.spawn(DB.set_window_bounds(workspace_id, bounds, display))
|
||||||
.detach_and_log_err(cx);
|
.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 {
|
let mut this = Workspace {
|
||||||
weak_self: weak_handle.clone(),
|
weak_self: weak_handle.clone(),
|
||||||
|
@ -881,6 +888,11 @@ impl Workspace {
|
||||||
dock.activate_panel(dock.panels_len() - 1, cx);
|
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();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn toggle_zoom(&mut self, _: &ToggleZoom, cx: &mut ViewContext<Self>) {
|
|
||||||
// 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<Self>) {
|
fn zoom_out(&mut self, cx: &mut ViewContext<Self>) {
|
||||||
for pane in &self.panes {
|
for pane in &self.panes {
|
||||||
pane.update(cx, |pane, cx| pane.set_zoomed(false, cx));
|
pane.update(cx, |pane, cx| pane.set_zoomed(false, cx));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.left_dock
|
self.left_dock.update(cx, |dock, cx| dock.zoom_out(cx));
|
||||||
.update(cx, |dock, cx| dock.set_zoomed(false, cx));
|
self.bottom_dock.update(cx, |dock, cx| dock.zoom_out(cx));
|
||||||
self.bottom_dock
|
self.right_dock.update(cx, |dock, cx| dock.zoom_out(cx));
|
||||||
.update(cx, |dock, cx| dock.set_zoomed(false, cx));
|
|
||||||
self.right_dock
|
|
||||||
.update(cx, |dock, cx| dock.set_zoomed(false, cx));
|
|
||||||
|
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
@ -1490,20 +1493,6 @@ impl Workspace {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_dock(dock: &ViewHandle<Dock>, cx: &mut ViewContext<Self>) -> [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<Self>) -> ViewHandle<Pane> {
|
fn add_pane(&mut self, cx: &mut ViewContext<Self>) -> ViewHandle<Pane> {
|
||||||
let pane =
|
let pane =
|
||||||
cx.add_view(|cx| Pane::new(self.weak_handle(), self.app_state.background_actions, cx));
|
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);
|
self.handle_pane_focused(pane.clone(), cx);
|
||||||
}
|
}
|
||||||
pane::Event::ZoomIn => {
|
pane::Event::ZoomIn => {
|
||||||
|
self.zoom_out(cx);
|
||||||
pane.update(cx, |pane, cx| pane.set_zoomed(true, cx));
|
pane.update(cx, |pane, cx| pane.set_zoomed(true, cx));
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
pane::Event::ZoomOut => self.zoom_out(cx),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.serialize_workspace(cx);
|
self.serialize_workspace(cx);
|
||||||
|
|
Loading…
Reference in a new issue