Use a new `Workspace::activate_item` API in project diagnostics

Antonio Scandurra created

Previously, we would only activate the pane without switching the
pane's *active item*.

Change summary

crates/diagnostics/src/diagnostics.rs |  2 +-
crates/workspace/src/pane.rs          |  8 ++++++--
crates/workspace/src/workspace.rs     | 19 ++++++++++++++++++-
3 files changed, 25 insertions(+), 4 deletions(-)

Detailed changes

crates/diagnostics/src/diagnostics.rs 🔗

@@ -167,7 +167,7 @@ impl ProjectDiagnosticsEditor {
 
     fn deploy(workspace: &mut Workspace, _: &Deploy, cx: &mut ViewContext<Workspace>) {
         if let Some(existing) = workspace.item_of_type::<ProjectDiagnostics>(cx) {
-            workspace.activate_pane_for_item(&existing, cx);
+            workspace.activate_item(&existing, cx);
         } else {
             let diagnostics =
                 cx.add_model(|_| ProjectDiagnostics::new(workspace.project().clone()));

crates/workspace/src/pane.rs 🔗

@@ -139,10 +139,14 @@ impl Pane {
             .map(|(_, view)| view.clone())
     }
 
-    pub fn item_index(&self, item: &dyn ItemViewHandle) -> Option<usize> {
+    pub fn index_for_item_view(&self, item_view: &dyn ItemViewHandle) -> Option<usize> {
         self.item_views
             .iter()
-            .position(|(_, i)| i.id() == item.id())
+            .position(|(_, i)| i.id() == item_view.id())
+    }
+
+    pub fn index_for_item(&self, item: &dyn ItemHandle) -> Option<usize> {
+        self.item_views.iter().position(|(id, _)| *id == item.id())
     }
 
     pub fn activate_item(&mut self, index: usize, cx: &mut ViewContext<Self>) {

crates/workspace/src/workspace.rs 🔗

@@ -334,7 +334,7 @@ impl<T: ItemView> ItemViewHandle for ViewHandle<T> {
                 return;
             }
             if T::should_activate_item_on_event(event) {
-                if let Some(ix) = pane.item_index(&item) {
+                if let Some(ix) = pane.index_for_item_view(&item) {
                     pane.activate_item(ix, cx);
                     pane.activate(cx);
                 }
@@ -962,6 +962,23 @@ impl Workspace {
         }
     }
 
+    pub fn activate_item(&mut self, item: &dyn ItemHandle, cx: &mut ViewContext<Self>) -> bool {
+        let result = self.panes.iter().find_map(|pane| {
+            if let Some(ix) = pane.read(cx).index_for_item(item) {
+                Some((pane.clone(), ix))
+            } else {
+                None
+            }
+        });
+        if let Some((pane, ix)) = result {
+            self.activate_pane(pane.clone(), cx);
+            pane.update(cx, |pane, cx| pane.activate_item(ix, cx));
+            true
+        } else {
+            false
+        }
+    }
+
     fn activate_pane(&mut self, pane: ViewHandle<Pane>, cx: &mut ViewContext<Self>) {
         self.active_pane = pane;
         self.status_bar.update(cx, |status_bar, cx| {