Debugger UI: Update tab content and remove red tint from terminated session (#27475)

Anthony Eid created

The new tab content makes it obvious when a session is shutdown so the
red tint is no longer needed.

Release Notes:

- N/A

Change summary

crates/debugger_ui/src/session.rs         | 51 +++++++++++++++++++-----
crates/debugger_ui/src/session/running.rs |  2 
2 files changed, 39 insertions(+), 14 deletions(-)

Detailed changes

crates/debugger_ui/src/session.rs 🔗

@@ -19,7 +19,7 @@ use project::Project;
 use rpc::proto::{self, PeerId};
 use running::RunningState;
 use starting::{StartingEvent, StartingState};
-use ui::prelude::*;
+use ui::{prelude::*, Indicator};
 use util::ResultExt;
 use workspace::{
     item::{self, Item},
@@ -214,23 +214,48 @@ impl Focusable for DebugSession {
 impl Item for DebugSession {
     type Event = DebugPanelItemEvent;
     fn tab_content(&self, _: item::TabContentParams, _: &Window, cx: &App) -> AnyElement {
-        let (label, color) = match &self.mode {
-            DebugSessionState::Inert(_) => ("New Session", Color::Default),
-            DebugSessionState::Starting(_) => ("Starting", Color::Default),
-            DebugSessionState::Failed(_) => ("Failed", Color::Error),
-            DebugSessionState::Running(state) => (
-                state
-                    .read_with(cx, |state, cx| state.thread_status(cx))
-                    .map(|status| status.label())
-                    .unwrap_or("Running"),
-                Color::Default,
+        let (icon, label, color) = match &self.mode {
+            DebugSessionState::Inert(_) => (None, "New Session", Color::Default),
+            DebugSessionState::Starting(_) => (None, "Starting", Color::Default),
+            DebugSessionState::Failed(_) => (
+                Some(Indicator::dot().color(Color::Error)),
+                "Failed",
+                Color::Error,
             ),
+            DebugSessionState::Running(state) => {
+                if state.read(cx).session().read(cx).is_terminated() {
+                    (
+                        Some(Indicator::dot().color(Color::Error)),
+                        "Terminated",
+                        Color::Error,
+                    )
+                } else {
+                    match state.read(cx).thread_status(cx).unwrap_or_default() {
+                        project::debugger::session::ThreadStatus::Stopped => (
+                            Some(Indicator::dot().color(Color::Conflict)),
+                            state
+                                .read_with(cx, |state, cx| state.thread_status(cx))
+                                .map(|status| status.label())
+                                .unwrap_or("Stopped"),
+                            Color::Conflict,
+                        ),
+                        _ => (
+                            Some(Indicator::dot().color(Color::Success)),
+                            state
+                                .read_with(cx, |state, cx| state.thread_status(cx))
+                                .map(|status| status.label())
+                                .unwrap_or("Running"),
+                            Color::Success,
+                        ),
+                    }
+                }
+            }
         };
 
         let is_starting = matches!(self.mode, DebugSessionState::Starting(_));
 
         h_flex()
-            .gap_1()
+            .gap_2()
             .children(is_starting.then(|| {
                 Icon::new(IconName::ArrowCircle).with_animation(
                     "starting-debug-session",
@@ -238,6 +263,8 @@ impl Item for DebugSession {
                     |this, delta| this.transform(Transformation::rotate(percentage(delta))),
                 )
             }))
+            .when_some(icon, |this, indicator| this.child(indicator))
+            .justify_between()
             .child(Label::new(label).color(color))
             .into_any_element()
     }

crates/debugger_ui/src/session/running.rs 🔗

@@ -61,14 +61,12 @@ impl Render for RunningState {
             this.disabled(thread_status != ThreadStatus::Stopped, cx);
         });
 
-        let is_terminated = self.session.read(cx).is_terminated();
         let active_thread_item = &self.active_thread_item;
 
         let has_no_threads = threads.is_empty();
         let capabilities = self.capabilities(cx);
         let state = cx.entity();
         h_flex()
-            .when(is_terminated, |this| this.bg(gpui::red()))
             .key_context("DebugPanelItem")
             .track_focus(&self.focus_handle(cx))
             .size_full()