Add tooltips for sidebar buttons

Antonio Scandurra created

Change summary

crates/workspace/src/sidebar.rs | 55 +++++++++++++++++++---------------
crates/zed/src/zed.rs           | 14 +++++++-
2 files changed, 43 insertions(+), 26 deletions(-)

Detailed changes

crates/workspace/src/sidebar.rs 🔗

@@ -68,6 +68,7 @@ pub enum Side {
 
 struct Item {
     icon_path: &'static str,
+    tooltip: String,
     view: Rc<dyn SidebarItemHandle>,
     _subscriptions: [Subscription; 2],
 }
@@ -104,6 +105,7 @@ impl Sidebar {
     pub fn add_item<T: SidebarItem>(
         &mut self,
         icon_path: &'static str,
+        tooltip: String,
         view: ViewHandle<T>,
         cx: &mut ViewContext<Self>,
     ) {
@@ -123,6 +125,7 @@ impl Sidebar {
         ];
         self.items.push(Item {
             icon_path,
+            tooltip,
             view: Rc::new(view),
             _subscriptions: subscriptions,
         });
@@ -239,12 +242,9 @@ impl View for SidebarButtons {
     }
 
     fn render(&mut self, cx: &mut RenderContext<Self>) -> ElementBox {
-        let theme = &cx
-            .global::<Settings>()
-            .theme
-            .workspace
-            .status_bar
-            .sidebar_buttons;
+        let theme = &cx.global::<Settings>().theme;
+        let tooltip_style = theme.tooltip.clone();
+        let theme = &theme.workspace.status_bar.sidebar_buttons;
         let sidebar = self.sidebar.read(cx);
         let item_style = theme.item;
         let badge_style = theme.badge;
@@ -257,15 +257,19 @@ impl View for SidebarButtons {
         let items = sidebar
             .items
             .iter()
-            .map(|item| (item.icon_path, item.view.clone()))
+            .map(|item| (item.icon_path, item.tooltip.clone(), item.view.clone()))
             .collect::<Vec<_>>();
         Flex::row()
-            .with_children(
-                items
-                    .into_iter()
-                    .enumerate()
-                    .map(|(ix, (icon_path, item_view))| {
-                        MouseEventHandler::new::<Self, _, _>(ix, cx, move |state, cx| {
+            .with_children(items.into_iter().enumerate().map(
+                |(ix, (icon_path, tooltip, item_view))| {
+                    let action = ToggleSidebarItem {
+                        side,
+                        item_index: ix,
+                    };
+                    MouseEventHandler::new::<Self, _, _>(ix, cx, {
+                        let action = action.clone();
+                        let tooltip_style = tooltip_style.clone();
+                        move |state, cx| {
                             let is_active = Some(ix) == active_ix;
                             let style = item_style.style_for(state, is_active);
                             Stack::new()
@@ -291,18 +295,21 @@ impl View for SidebarButtons {
                                 .with_height(style.icon_size)
                                 .contained()
                                 .with_style(style.container)
+                                .with_tooltip(
+                                    ix,
+                                    tooltip,
+                                    Some(Box::new(action.clone())),
+                                    tooltip_style.clone(),
+                                    cx,
+                                )
                                 .boxed()
-                        })
-                        .with_cursor_style(CursorStyle::PointingHand)
-                        .on_click(move |_, _, cx| {
-                            cx.dispatch_action(ToggleSidebarItem {
-                                side,
-                                item_index: ix,
-                            })
-                        })
-                        .boxed()
-                    }),
-            )
+                        }
+                    })
+                    .with_cursor_style(CursorStyle::PointingHand)
+                    .on_click(move |_, _, cx| cx.dispatch_action(action.clone()))
+                    .boxed()
+                },
+            ))
             .contained()
             .with_style(group_style)
             .boxed()

crates/zed/src/zed.rs 🔗

@@ -191,10 +191,20 @@ pub fn initialize_workspace(
     });
 
     workspace.left_sidebar().update(cx, |sidebar, cx| {
-        sidebar.add_item("icons/folder-tree-solid-14.svg", project_panel.into(), cx)
+        sidebar.add_item(
+            "icons/folder-tree-solid-14.svg",
+            "Project Panel".to_string(),
+            project_panel.into(),
+            cx,
+        )
     });
     workspace.right_sidebar().update(cx, |sidebar, cx| {
-        sidebar.add_item("icons/contacts-solid-14.svg", contact_panel.into(), cx)
+        sidebar.add_item(
+            "icons/contacts-solid-14.svg",
+            "Contacts Panel".to_string(),
+            contact_panel.into(),
+            cx,
+        )
     });
 
     let diagnostic_summary =