diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 32a8148cbb..6604472d86 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -15,8 +15,8 @@ use gpui::{ geometry::vector::Vector2F, keymap_matcher::KeymapContext, platform::{CursorStyle, MouseButton, PromptLevel}, - AnyElement, AppContext, AsyncAppContext, ClipboardItem, Element, Entity, ModelHandle, Task, - View, ViewContext, ViewHandle, WeakViewHandle, WindowContext, + Action, AnyElement, AppContext, AsyncAppContext, ClipboardItem, Element, Entity, ModelHandle, + Task, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext, }; use menu::{Confirm, SelectNext, SelectPrev}; use project::{ @@ -1507,8 +1507,8 @@ impl workspace::dock::Panel for ProjectPanel { "icons/folder_tree_16.svg" } - fn icon_tooltip(&self) -> String { - "Project Panel".into() + fn icon_tooltip(&self) -> (String, Option>) { + ("Project Panel".into(), Some(Box::new(ToggleFocus))) } fn should_change_position_on_event(event: &Self::Event) -> bool { diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index 2062d2aff3..791a8b21c5 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use crate::TerminalView; use db::kvp::KEY_VALUE_STORE; use gpui::{ - actions, anyhow::Result, elements::*, serde_json, AppContext, AsyncAppContext, Entity, + actions, anyhow::Result, elements::*, serde_json, Action, AppContext, AsyncAppContext, Entity, Subscription, Task, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext, }; use project::Fs; @@ -365,8 +365,8 @@ impl Panel for TerminalPanel { "icons/terminal_12.svg" } - fn icon_tooltip(&self) -> String { - "Terminal Panel".into() + fn icon_tooltip(&self) -> (String, Option>) { + ("Terminal Panel".into(), Some(Box::new(ToggleFocus))) } fn icon_label(&self, cx: &WindowContext) -> Option { diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 7256ee8704..73d4f79399 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -1,9 +1,8 @@ use crate::{StatusItemView, Workspace}; use context_menu::{ContextMenu, ContextMenuItem}; use gpui::{ - elements::*, impl_actions, platform::CursorStyle, platform::MouseButton, AnyViewHandle, - AppContext, Axis, Entity, Subscription, View, ViewContext, ViewHandle, WeakViewHandle, - WindowContext, + elements::*, platform::CursorStyle, platform::MouseButton, Action, AnyViewHandle, AppContext, + Axis, Entity, Subscription, View, ViewContext, ViewHandle, WeakViewHandle, WindowContext, }; use serde::Deserialize; use std::rc::Rc; @@ -16,7 +15,7 @@ pub trait Panel: View { fn size(&self, cx: &WindowContext) -> f32; fn set_size(&mut self, size: f32, cx: &mut ViewContext); fn icon_path(&self) -> &'static str; - fn icon_tooltip(&self) -> String; + fn icon_tooltip(&self) -> (String, Option>); fn icon_label(&self, _: &WindowContext) -> Option { None } @@ -43,7 +42,7 @@ pub trait PanelHandle { fn size(&self, cx: &WindowContext) -> f32; fn set_size(&self, size: f32, cx: &mut WindowContext); fn icon_path(&self, cx: &WindowContext) -> &'static str; - fn icon_tooltip(&self, cx: &WindowContext) -> String; + fn icon_tooltip(&self, cx: &WindowContext) -> (String, Option>); fn icon_label(&self, cx: &WindowContext) -> Option; fn has_focus(&self, cx: &WindowContext) -> bool; fn as_any(&self) -> &AnyViewHandle; @@ -93,7 +92,7 @@ where self.read(cx).icon_path() } - fn icon_tooltip(&self, cx: &WindowContext) -> String { + fn icon_tooltip(&self, cx: &WindowContext) -> (String, Option>) { self.read(cx).icon_tooltip() } @@ -166,14 +165,6 @@ pub struct PanelButtons { workspace: WeakViewHandle, } -#[derive(Clone, Debug, Deserialize, PartialEq)] -pub struct TogglePanel { - pub dock_position: DockPosition, - pub panel_index: usize, -} - -impl_actions!(workspace, [TogglePanel]); - impl Dock { pub fn new(position: DockPosition) -> Self { Self { @@ -480,98 +471,89 @@ impl View for PanelButtons { .map(|item| (item.panel.clone(), item.context_menu.clone())) .collect::>(); Flex::row() - .with_children( - panels - .into_iter() - .enumerate() - .map(|(ix, (view, context_menu))| { - let action = TogglePanel { - dock_position, - panel_index: ix, - }; - - Stack::new() - .with_child( - MouseEventHandler::::new(ix, cx, |state, cx| { - let is_active = is_open && ix == active_ix; - let style = button_style.style_for(state, is_active); - Flex::row() - .with_child( - Svg::new(view.icon_path(cx)) - .with_color(style.icon_color) - .constrained() - .with_width(style.icon_size) + .with_children(panels.into_iter().enumerate().map( + |(panel_ix, (view, context_menu))| { + let (tooltip, tooltip_action) = view.icon_tooltip(cx); + Stack::new() + .with_child( + MouseEventHandler::::new(panel_ix, cx, |state, cx| { + let is_active = is_open && panel_ix == active_ix; + let style = button_style.style_for(state, is_active); + Flex::row() + .with_child( + Svg::new(view.icon_path(cx)) + .with_color(style.icon_color) + .constrained() + .with_width(style.icon_size) + .aligned(), + ) + .with_children(if let Some(label) = view.icon_label(cx) { + Some( + Label::new(label, style.label.text.clone()) + .contained() + .with_style(style.label.container) .aligned(), ) - .with_children(if let Some(label) = view.icon_label(cx) { - Some( - Label::new(label, style.label.text.clone()) - .contained() - .with_style(style.label.container) - .aligned(), - ) - } else { - None - }) - .constrained() - .with_height(style.icon_size) - .contained() - .with_style(style.container) - }) - .with_cursor_style(CursorStyle::PointingHand) - .on_click(MouseButton::Left, { - let action = action.clone(); - move |_, this, cx| { - if let Some(workspace) = this.workspace.upgrade(cx) { - let action = action.clone(); - cx.window_context().defer(move |cx| { - workspace.update(cx, |workspace, cx| { - workspace.toggle_panel(&action, cx) - }); + } else { + None + }) + .constrained() + .with_height(style.icon_size) + .contained() + .with_style(style.container) + }) + .with_cursor_style(CursorStyle::PointingHand) + .on_click(MouseButton::Left, { + move |_, this, cx| { + if let Some(workspace) = this.workspace.upgrade(cx) { + cx.window_context().defer(move |cx| { + workspace.update(cx, |workspace, cx| { + workspace.toggle_panel(dock_position, panel_ix, cx) }); - } + }); } - }) - .on_click(MouseButton::Right, { - let view = view.clone(); - let menu = context_menu.clone(); - move |_, _, cx| { - const POSITIONS: [DockPosition; 3] = [ - DockPosition::Left, - DockPosition::Right, - DockPosition::Bottom, - ]; + } + }) + .on_click(MouseButton::Right, { + let view = view.clone(); + let menu = context_menu.clone(); + move |_, _, cx| { + const POSITIONS: [DockPosition; 3] = [ + DockPosition::Left, + DockPosition::Right, + DockPosition::Bottom, + ]; - menu.update(cx, |menu, cx| { - let items = POSITIONS - .into_iter() - .filter(|position| { - *position != dock_position - && view.position_is_valid(*position, cx) - }) - .map(|position| { - let view = view.clone(); - ContextMenuItem::handler( - format!("Dock {}", position.to_label()), - move |cx| view.set_position(position, cx), - ) - }) - .collect(); - menu.show(Default::default(), menu_corner, items, cx); - }) - } - }) - .with_tooltip::( - ix, - view.icon_tooltip(cx), - Some(Box::new(action)), - tooltip_style.clone(), - cx, - ), - ) - .with_child(ChildView::new(&context_menu, cx)) - }), - ) + menu.update(cx, |menu, cx| { + let items = POSITIONS + .into_iter() + .filter(|position| { + *position != dock_position + && view.position_is_valid(*position, cx) + }) + .map(|position| { + let view = view.clone(); + ContextMenuItem::handler( + format!("Dock {}", position.to_label()), + move |cx| view.set_position(position, cx), + ) + }) + .collect(); + menu.show(Default::default(), menu_corner, items, cx); + }) + } + }) + .with_tooltip::( + panel_ix, + tooltip, + tooltip_action, + tooltip_style.clone(), + cx, + ), + ) + .with_child(ChildView::new(&context_menu, cx)) + }, + )) .contained() .with_style(group_style) .into_any() @@ -682,8 +664,8 @@ pub(crate) mod test { "icons/test_panel.svg" } - fn icon_tooltip(&self) -> String { - "Test Panel".into() + fn icon_tooltip(&self) -> (String, Option>) { + ("Test Panel".into(), None) } fn should_change_position_on_event(event: &Self::Event) -> bool { diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 39ecce2ca5..1c2b33214e 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -64,7 +64,7 @@ use crate::{ DockData, DockStructure, SerializedPane, SerializedPaneGroup, SerializedWorkspace, }, }; -use dock::{Dock, DockPosition, Panel, PanelButtons, PanelHandle, TogglePanel}; +use dock::{Dock, DockPosition, Panel, PanelButtons, PanelHandle}; use lazy_static::lazy_static; use notifications::{NotificationHandle, NotifyResultExt}; pub use pane::*; @@ -259,7 +259,6 @@ pub fn init(app_state: Arc, cx: &mut AppContext) { workspace.save_active_item(true, cx).detach_and_log_err(cx); }, ); - cx.add_action(Workspace::toggle_panel); cx.add_action(|workspace: &mut Workspace, _: &ActivatePreviousPane, cx| { workspace.activate_previous_pane(cx) }); @@ -1497,19 +1496,24 @@ impl Workspace { self.serialize_workspace(cx); } - pub fn toggle_panel(&mut self, action: &TogglePanel, cx: &mut ViewContext) { - let dock = match action.dock_position { + pub fn toggle_panel( + &mut self, + position: DockPosition, + panel_index: usize, + cx: &mut ViewContext, + ) { + let dock = match position { DockPosition::Left => &mut self.left_dock, DockPosition::Bottom => &mut self.bottom_dock, DockPosition::Right => &mut self.right_dock, }; let active_item = dock.update(cx, move |dock, cx| { - if dock.is_open() && dock.active_panel_index() == action.panel_index { + if dock.is_open() && dock.active_panel_index() == panel_index { dock.set_open(false, cx); None } else { dock.set_open(true, cx); - dock.activate_panel(action.panel_index, cx); + dock.activate_panel(panel_index, cx); dock.active_panel().cloned() } });