debugger: Tweak layout of debug landing page in vertical dock position (#33625)

Piotr Osiewicz created

Release Notes:

- Reorganized layout of a debug panel without any sessions for a
vertical dock position.
- Moved parent directories of source breakpoints into a tooltip.

Change summary

crates/debugger_ui/src/debugger_panel.rs                  | 164 +++++---
crates/debugger_ui/src/session/running/breakpoint_list.rs |  19 
2 files changed, 111 insertions(+), 72 deletions(-)

Detailed changes

crates/debugger_ui/src/debugger_panel.rs 🔗

@@ -1468,6 +1468,94 @@ impl Render for DebugPanel {
                 if has_sessions {
                     this.children(self.active_session.clone())
                 } else {
+                    let docked_to_bottom = self.position(window, cx) == DockPosition::Bottom;
+                    let welcome_experience = v_flex()
+                        .when_else(
+                            docked_to_bottom,
+                            |this| this.w_2_3().h_full().pr_8(),
+                            |this| this.w_full().h_1_3(),
+                        )
+                        .items_center()
+                        .justify_center()
+                        .gap_2()
+                        .child(
+                            Button::new("spawn-new-session-empty-state", "New Session")
+                                .icon(IconName::Plus)
+                                .icon_size(IconSize::XSmall)
+                                .icon_color(Color::Muted)
+                                .icon_position(IconPosition::Start)
+                                .on_click(|_, window, cx| {
+                                    window.dispatch_action(crate::Start.boxed_clone(), cx);
+                                }),
+                        )
+                        .child(
+                            Button::new("edit-debug-settings", "Edit debug.json")
+                                .icon(IconName::Code)
+                                .icon_size(IconSize::XSmall)
+                                .color(Color::Muted)
+                                .icon_color(Color::Muted)
+                                .icon_position(IconPosition::Start)
+                                .on_click(|_, window, cx| {
+                                    window.dispatch_action(
+                                        zed_actions::OpenProjectDebugTasks.boxed_clone(),
+                                        cx,
+                                    );
+                                }),
+                        )
+                        .child(
+                            Button::new("open-debugger-docs", "Debugger Docs")
+                                .icon(IconName::Book)
+                                .color(Color::Muted)
+                                .icon_size(IconSize::XSmall)
+                                .icon_color(Color::Muted)
+                                .icon_position(IconPosition::Start)
+                                .on_click(|_, _, cx| cx.open_url("https://zed.dev/docs/debugger")),
+                        )
+                        .child(
+                            Button::new(
+                                "spawn-new-session-install-extensions",
+                                "Debugger Extensions",
+                            )
+                            .icon(IconName::Blocks)
+                            .color(Color::Muted)
+                            .icon_size(IconSize::XSmall)
+                            .icon_color(Color::Muted)
+                            .icon_position(IconPosition::Start)
+                            .on_click(|_, window, cx| {
+                                window.dispatch_action(
+                                    zed_actions::Extensions {
+                                        category_filter: Some(
+                                            zed_actions::ExtensionCategoryFilter::DebugAdapters,
+                                        ),
+                                    }
+                                    .boxed_clone(),
+                                    cx,
+                                );
+                            }),
+                        );
+                    let breakpoint_list =
+                        v_flex()
+                            .group("base-breakpoint-list")
+                            .items_start()
+                            .when_else(
+                                docked_to_bottom,
+                                |this| this.min_w_1_3().h_full(),
+                                |this| this.w_full().h_2_3(),
+                            )
+                            .p_1()
+                            .child(
+                                h_flex()
+                                    .pl_1()
+                                    .w_full()
+                                    .justify_between()
+                                    .child(Label::new("Breakpoints").size(LabelSize::Small))
+                                    .child(h_flex().visible_on_hover("base-breakpoint-list").child(
+                                        self.breakpoint_list.read(cx).render_control_strip(),
+                                    ))
+                                    .track_focus(&self.breakpoint_list.focus_handle(cx)),
+                            )
+                            .child(Divider::horizontal())
+                            .child(self.breakpoint_list.clone());
                     this.child(
                         v_flex()
                             .h_full()
@@ -1475,65 +1563,23 @@ impl Render for DebugPanel {
                             .items_center()
                             .justify_center()
                             .child(
-                                h_flex().size_full()
-                                    .items_start()
-
-                                    .child(v_flex().group("base-breakpoint-list").items_start().min_w_1_3().h_full().p_1()
-                                        .child(h_flex().pl_1().w_full().justify_between()
-                                            .child(Label::new("Breakpoints").size(LabelSize::Small))
-                                            .child(h_flex().visible_on_hover("base-breakpoint-list").child(self.breakpoint_list.read(cx).render_control_strip())))
-                                        .child(Divider::horizontal())
-                                        .child(self.breakpoint_list.clone()))
-                                    .child(Divider::vertical())
-                                    .child(
-                                        v_flex().w_2_3().h_full().items_center().justify_center()
-                                            .gap_2()
-                                            .pr_8()
-                                            .child(
-                                                Button::new("spawn-new-session-empty-state", "New Session")
-                                                    .icon(IconName::Plus)
-                                                    .icon_size(IconSize::XSmall)
-                                                    .icon_color(Color::Muted)
-                                                    .icon_position(IconPosition::Start)
-                                                    .on_click(|_, window, cx| {
-                                                        window.dispatch_action(crate::Start.boxed_clone(), cx);
-                                                    })
-                                            )
-                                            .child(
-                                                Button::new("edit-debug-settings", "Edit debug.json")
-                                                    .icon(IconName::Code)
-                                                    .icon_size(IconSize::XSmall)
-                                                    .color(Color::Muted)
-                                                    .icon_color(Color::Muted)
-                                                    .icon_position(IconPosition::Start)
-                                                    .on_click(|_, window, cx| {
-                                                        window.dispatch_action(zed_actions::OpenProjectDebugTasks.boxed_clone(), cx);
-                                                    })
-                                            )
-                                            .child(
-                                                Button::new("open-debugger-docs", "Debugger Docs")
-                                                    .icon(IconName::Book)
-                                                    .color(Color::Muted)
-                                                    .icon_size(IconSize::XSmall)
-                                                    .icon_color(Color::Muted)
-                                                    .icon_position(IconPosition::Start)
-                                                    .on_click(|_, _, cx| {
-                                                        cx.open_url("https://zed.dev/docs/debugger")
-                                                    })
-                                            )
-                                            .child(
-                                                Button::new("spawn-new-session-install-extensions", "Debugger Extensions")
-                                                    .icon(IconName::Blocks)
-                                                    .color(Color::Muted)
-                                                    .icon_size(IconSize::XSmall)
-                                                    .icon_color(Color::Muted)
-                                                    .icon_position(IconPosition::Start)
-                                                    .on_click(|_, window, cx| {
-                                                        window.dispatch_action(zed_actions::Extensions { category_filter: Some(zed_actions::ExtensionCategoryFilter::DebugAdapters)}.boxed_clone(), cx);
-                                                    })
-                                            )
-                                    )
-                            )
+                                div()
+                                    .when_else(docked_to_bottom, Div::h_flex, Div::v_flex)
+                                    .size_full()
+                                    .map(|this| {
+                                        if docked_to_bottom {
+                                            this.items_start()
+                                                .child(breakpoint_list)
+                                                .child(Divider::vertical())
+                                                .child(welcome_experience)
+                                        } else {
+                                            this.items_end()
+                                                .child(welcome_experience)
+                                                .child(Divider::horizontal())
+                                                .child(breakpoint_list)
+                                        }
+                                    }),
+                            ),
                     )
                 }
             })

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

@@ -877,20 +877,13 @@ impl LineBreakpoint {
                 })
                 .cursor_pointer()
                 .child(
-                    h_flex()
-                        .gap_1()
-                        .child(
-                            Label::new(format!("{}:{}", self.name, self.line))
-                                .size(LabelSize::Small)
-                                .line_height_style(ui::LineHeightStyle::UiLabel),
-                        )
-                        .children(self.dir.clone().map(|dir| {
-                            Label::new(dir)
-                                .color(Color::Muted)
-                                .size(LabelSize::Small)
-                                .line_height_style(ui::LineHeightStyle::UiLabel)
-                        })),
+                    Label::new(format!("{}:{}", self.name, self.line))
+                        .size(LabelSize::Small)
+                        .line_height_style(ui::LineHeightStyle::UiLabel),
                 )
+                .when_some(self.dir.as_ref(), |this, parent_dir| {
+                    this.tooltip(Tooltip::text(format!("Worktree parent path: {parent_dir}")))
+                })
                 .child(BreakpointOptionsStrip {
                     props,
                     breakpoint: BreakpointEntry {