diff --git a/assets/icons/debug_disabled_log_breakpoint.svg b/assets/icons/debug_disabled_log_breakpoint.svg index a028ead3a0..2ccc37623d 100644 --- a/assets/icons/debug_disabled_log_breakpoint.svg +++ b/assets/icons/debug_disabled_log_breakpoint.svg @@ -1,3 +1,5 @@ - + + + diff --git a/assets/icons/debug_ignore_breakpoints.svg b/assets/icons/debug_ignore_breakpoints.svg index a0bbabfb26..b2a345d314 100644 --- a/assets/icons/debug_ignore_breakpoints.svg +++ b/assets/icons/debug_ignore_breakpoints.svg @@ -1 +1,3 @@ - + + + diff --git a/assets/icons/debug_log_breakpoint.svg b/assets/icons/debug_log_breakpoint.svg index 7c652db1e9..22eae9d029 100644 --- a/assets/icons/debug_log_breakpoint.svg +++ b/assets/icons/debug_log_breakpoint.svg @@ -1,3 +1,3 @@ - + diff --git a/crates/debugger_ui/src/debugger_panel.rs b/crates/debugger_ui/src/debugger_panel.rs index 91382c74ae..1d44c5c244 100644 --- a/crates/debugger_ui/src/debugger_panel.rs +++ b/crates/debugger_ui/src/debugger_panel.rs @@ -36,7 +36,7 @@ use settings::Settings; use std::sync::{Arc, LazyLock}; use task::{DebugScenario, TaskContext}; use tree_sitter::{Query, StreamingIterator as _}; -use ui::{ContextMenu, Divider, PopoverMenuHandle, Tooltip, prelude::*}; +use ui::{ContextMenu, Divider, PopoverMenuHandle, Tab, Tooltip, prelude::*}; use util::{ResultExt, debug_panic, maybe}; use workspace::SplitDirection; use workspace::item::SaveOptions; @@ -642,12 +642,14 @@ impl DebugPanel { } }) }; + let documentation_button = || { IconButton::new("debug-open-documentation", IconName::CircleHelp) .icon_size(IconSize::Small) .on_click(move |_, _, cx| cx.open_url("https://zed.dev/docs/debugger")) .tooltip(Tooltip::text("Open Documentation")) }; + let logs_button = || { IconButton::new("debug-open-logs", IconName::Notepad) .icon_size(IconSize::Small) @@ -658,16 +660,18 @@ impl DebugPanel { }; Some( - div.border_b_1() - .border_color(cx.theme().colors().border) - .p_1() + div.w_full() + .py_1() + .px_1p5() .justify_between() - .w_full() + .border_b_1() + .border_color(cx.theme().colors().border) .when(is_side, |this| this.gap_1()) .child( h_flex() + .justify_between() .child( - h_flex().gap_2().w_full().when_some( + h_flex().gap_1().w_full().when_some( active_session .as_ref() .map(|session| session.read(cx).running_state()), @@ -679,6 +683,7 @@ impl DebugPanel { let capabilities = running_state.read(cx).capabilities(cx); let supports_detach = running_state.read(cx).session().read(cx).is_attached(); + this.map(|this| { if thread_status == ThreadStatus::Running { this.child( @@ -686,8 +691,7 @@ impl DebugPanel { "debug-pause", IconName::DebugPause, ) - .icon_size(IconSize::XSmall) - .shape(ui::IconButtonShape::Square) + .icon_size(IconSize::Small) .on_click(window.listener_for( &running_state, |this, _, _window, cx| { @@ -698,7 +702,7 @@ impl DebugPanel { let focus_handle = focus_handle.clone(); move |window, cx| { Tooltip::for_action_in( - "Pause program", + "Pause Program", &Pause, &focus_handle, window, @@ -713,8 +717,7 @@ impl DebugPanel { "debug-continue", IconName::DebugContinue, ) - .icon_size(IconSize::XSmall) - .shape(ui::IconButtonShape::Square) + .icon_size(IconSize::Small) .on_click(window.listener_for( &running_state, |this, _, _window, cx| this.continue_thread(cx), @@ -724,7 +727,7 @@ impl DebugPanel { let focus_handle = focus_handle.clone(); move |window, cx| { Tooltip::for_action_in( - "Continue program", + "Continue Program", &Continue, &focus_handle, window, @@ -737,8 +740,7 @@ impl DebugPanel { }) .child( IconButton::new("debug-step-over", IconName::ArrowRight) - .icon_size(IconSize::XSmall) - .shape(ui::IconButtonShape::Square) + .icon_size(IconSize::Small) .on_click(window.listener_for( &running_state, |this, _, _window, cx| { @@ -750,7 +752,7 @@ impl DebugPanel { let focus_handle = focus_handle.clone(); move |window, cx| { Tooltip::for_action_in( - "Step over", + "Step Over", &StepOver, &focus_handle, window, @@ -764,8 +766,7 @@ impl DebugPanel { "debug-step-into", IconName::ArrowDownRight, ) - .icon_size(IconSize::XSmall) - .shape(ui::IconButtonShape::Square) + .icon_size(IconSize::Small) .on_click(window.listener_for( &running_state, |this, _, _window, cx| { @@ -777,7 +778,7 @@ impl DebugPanel { let focus_handle = focus_handle.clone(); move |window, cx| { Tooltip::for_action_in( - "Step in", + "Step In", &StepInto, &focus_handle, window, @@ -789,7 +790,6 @@ impl DebugPanel { .child( IconButton::new("debug-step-out", IconName::ArrowUpRight) .icon_size(IconSize::Small) - .shape(ui::IconButtonShape::Square) .on_click(window.listener_for( &running_state, |this, _, _window, cx| { @@ -801,7 +801,7 @@ impl DebugPanel { let focus_handle = focus_handle.clone(); move |window, cx| { Tooltip::for_action_in( - "Step out", + "Step Out", &StepOut, &focus_handle, window, @@ -813,7 +813,7 @@ impl DebugPanel { .child(Divider::vertical()) .child( IconButton::new("debug-restart", IconName::RotateCcw) - .icon_size(IconSize::XSmall) + .icon_size(IconSize::Small) .on_click(window.listener_for( &running_state, |this, _, window, cx| { @@ -835,7 +835,7 @@ impl DebugPanel { ) .child( IconButton::new("debug-stop", IconName::Power) - .icon_size(IconSize::XSmall) + .icon_size(IconSize::Small) .on_click(window.listener_for( &running_state, |this, _, _window, cx| { @@ -890,7 +890,7 @@ impl DebugPanel { thread_status != ThreadStatus::Stopped && thread_status != ThreadStatus::Running, ) - .icon_size(IconSize::XSmall) + .icon_size(IconSize::Small) .on_click(window.listener_for( &running_state, |this, _, _, cx| { @@ -915,7 +915,6 @@ impl DebugPanel { }, ), ) - .justify_around() .when(is_side, |this| { this.child(new_session_button()) .child(logs_button()) @@ -924,7 +923,7 @@ impl DebugPanel { ) .child( h_flex() - .gap_2() + .gap_0p5() .when(is_side, |this| this.justify_between()) .child( h_flex().when_some( @@ -954,12 +953,15 @@ impl DebugPanel { ) }) }) - .when(!is_side, |this| this.gap_2().child(Divider::vertical())) + .when(!is_side, |this| { + this.gap_0p5().child(Divider::vertical()) + }) }, ), ) .child( h_flex() + .gap_0p5() .children(self.render_session_menu( self.active_session(), self.running_state(cx), @@ -1702,6 +1704,7 @@ impl Render for DebugPanel { this.child(active_session) } else { let docked_to_bottom = self.position(window, cx) == DockPosition::Bottom; + let welcome_experience = v_flex() .when_else( docked_to_bottom, @@ -1767,54 +1770,58 @@ impl Render for DebugPanel { ); }), ); - 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( + + let breakpoint_list = v_flex() + .group("base-breakpoint-list") + .when_else( + docked_to_bottom, + |this| this.min_w_1_3().h_full(), + |this| this.size_full().h_2_3(), + ) + .child( + h_flex() + .track_focus(&self.breakpoint_list.focus_handle(cx)) + .h(Tab::container_height(cx)) + .p_1p5() + .w_full() + .justify_between() + .border_b_1() + .border_color(cx.theme().colors().border_variant) + .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()); + ), + ), + ) + .child(self.breakpoint_list.clone()); + this.child( v_flex() - .h_full() + .size_full() .gap_1() .items_center() .justify_center() - .child( - 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) - .child(Divider::vertical()) - } else { - this.items_end() - .child(welcome_experience) - .child(Divider::horizontal()) - .child(breakpoint_list) - } - }), - ), + .map(|this| { + if docked_to_bottom { + this.child( + h_flex() + .size_full() + .child(breakpoint_list) + .child(Divider::vertical()) + .child(welcome_experience) + .child(Divider::vertical()), + ) + } else { + this.child( + v_flex() + .size_full() + .child(welcome_experience) + .child(Divider::horizontal()) + .child(breakpoint_list), + ) + } + }), ) } }) diff --git a/crates/debugger_ui/src/session/running.rs b/crates/debugger_ui/src/session/running.rs index a3e2805e2b..c8bee42039 100644 --- a/crates/debugger_ui/src/session/running.rs +++ b/crates/debugger_ui/src/session/running.rs @@ -48,10 +48,8 @@ use task::{ }; use terminal_view::TerminalView; use ui::{ - ActiveTheme, AnyElement, App, ButtonCommon as _, Clickable as _, Context, FluentBuilder, - IconButton, IconName, IconSize, InteractiveElement, IntoElement, Label, LabelCommon as _, - ParentElement, Render, SharedString, StatefulInteractiveElement, Styled, Tab, Tooltip, - VisibleOnHover, VisualContext, Window, div, h_flex, v_flex, + FluentBuilder, IntoElement, Render, StatefulInteractiveElement, Tab, Tooltip, VisibleOnHover, + VisualContext, prelude::*, }; use util::ResultExt; use variable_list::VariableList; @@ -419,13 +417,14 @@ pub(crate) fn new_debugger_pane( .map_or(false, |item| item.read(cx).hovered); h_flex() - .group(pane_group_id.clone()) - .justify_between() - .bg(cx.theme().colors().tab_bar_background) - .border_b_1() - .px_2() - .border_color(cx.theme().colors().border) .track_focus(&focus_handle) + .group(pane_group_id.clone()) + .pl_1p5() + .pr_1() + .justify_between() + .border_b_1() + .border_color(cx.theme().colors().border) + .bg(cx.theme().colors().tab_bar_background) .on_action(|_: &menu::Cancel, window, cx| { if cx.stop_active_drag(window) { return; @@ -514,6 +513,7 @@ pub(crate) fn new_debugger_pane( ) .child({ let zoomed = pane.is_zoomed(); + h_flex() .visible_on_hover(pane_group_id) .when(is_hovered, |this| this.visible()) @@ -537,7 +537,7 @@ pub(crate) fn new_debugger_pane( IconName::Maximize }, ) - .icon_size(IconSize::XSmall) + .icon_size(IconSize::Small) .on_click(cx.listener(move |pane, _, _, cx| { let is_zoomed = pane.is_zoomed(); pane.set_zoomed(!is_zoomed, cx); @@ -592,10 +592,11 @@ impl DebugTerminal { } impl gpui::Render for DebugTerminal { - fn render(&mut self, _window: &mut Window, _: &mut Context) -> impl IntoElement { + fn render(&mut self, _window: &mut Window, cx: &mut Context) -> impl IntoElement { div() - .size_full() .track_focus(&self.focus_handle) + .size_full() + .bg(cx.theme().colors().editor_background) .children(self.terminal.clone()) } } diff --git a/crates/debugger_ui/src/session/running/breakpoint_list.rs b/crates/debugger_ui/src/session/running/breakpoint_list.rs index 326fb84e20..38108dbfbc 100644 --- a/crates/debugger_ui/src/session/running/breakpoint_list.rs +++ b/crates/debugger_ui/src/session/running/breakpoint_list.rs @@ -23,11 +23,8 @@ use project::{ worktree_store::WorktreeStore, }; use ui::{ - ActiveTheme, AnyElement, App, ButtonCommon, Clickable, Color, Context, Disableable, Div, - Divider, FluentBuilder as _, Icon, IconButton, IconName, IconSize, InteractiveElement, - IntoElement, Label, LabelCommon, LabelSize, ListItem, ParentElement, Render, RenderOnce, - Scrollbar, ScrollbarState, SharedString, StatefulInteractiveElement, Styled, Toggleable, - Tooltip, Window, div, h_flex, px, v_flex, + Divider, DividerColor, FluentBuilder as _, Indicator, IntoElement, ListItem, Render, Scrollbar, + ScrollbarState, StatefulInteractiveElement, Tooltip, prelude::*, }; use workspace::Workspace; use zed_actions::{ToggleEnableBreakpoint, UnsetBreakpoint}; @@ -569,6 +566,7 @@ impl BreakpointList { .map(|session| SupportedBreakpointProperties::from(session.read(cx).capabilities())) .unwrap_or_else(SupportedBreakpointProperties::empty); let strip_mode = self.strip_mode; + uniform_list( "breakpoint-list", self.breakpoints.len(), @@ -591,7 +589,7 @@ impl BreakpointList { }), ) .track_scroll(self.scroll_handle.clone()) - .flex_grow() + .flex_1() } fn render_vertical_scrollbar(&self, cx: &mut Context) -> Stateful
{ @@ -630,6 +628,7 @@ impl BreakpointList { pub(crate) fn render_control_strip(&self) -> AnyElement { let selection_kind = self.selection_kind(); let focus_handle = self.focus_handle.clone(); + let remove_breakpoint_tooltip = selection_kind.map(|(kind, _)| match kind { SelectedBreakpointKind::Source => "Remove breakpoint from a breakpoint list", SelectedBreakpointKind::Exception => { @@ -637,6 +636,7 @@ impl BreakpointList { } SelectedBreakpointKind::Data => "Remove data breakpoint from a breakpoint list", }); + let toggle_label = selection_kind.map(|(_, is_enabled)| { if is_enabled { ( @@ -649,13 +649,12 @@ impl BreakpointList { }); h_flex() - .gap_2() .child( IconButton::new( "disable-breakpoint-breakpoint-list", IconName::DebugDisabledBreakpoint, ) - .icon_size(IconSize::XSmall) + .icon_size(IconSize::Small) .when_some(toggle_label, |this, (label, meta)| { this.tooltip({ let focus_handle = focus_handle.clone(); @@ -681,9 +680,8 @@ impl BreakpointList { }), ) .child( - IconButton::new("remove-breakpoint-breakpoint-list", IconName::Close) - .icon_size(IconSize::XSmall) - .icon_color(ui::Color::Error) + IconButton::new("remove-breakpoint-breakpoint-list", IconName::Trash) + .icon_size(IconSize::Small) .when_some(remove_breakpoint_tooltip, |this, tooltip| { this.tooltip({ let focus_handle = focus_handle.clone(); @@ -710,7 +708,6 @@ impl BreakpointList { } }), ) - .mr_2() .into_any_element() } } @@ -791,6 +788,7 @@ impl Render for BreakpointList { .chain(data_breakpoints) .chain(exception_breakpoints), ); + v_flex() .id("breakpoint-list") .key_context("BreakpointList") @@ -806,35 +804,33 @@ impl Render for BreakpointList { .on_action(cx.listener(Self::next_breakpoint_property)) .on_action(cx.listener(Self::previous_breakpoint_property)) .size_full() - .m_0p5() - .child( - v_flex() - .size_full() - .child(self.render_list(cx)) - .child(self.render_vertical_scrollbar(cx)), - ) + .pt_1() + .child(self.render_list(cx)) + .child(self.render_vertical_scrollbar(cx)) .when_some(self.strip_mode, |this, _| { - this.child(Divider::horizontal()).child( - h_flex() - // .w_full() - .m_0p5() - .p_0p5() - .border_1() - .rounded_sm() - .when( - self.input.focus_handle(cx).contains_focused(window, cx), - |this| { - let colors = cx.theme().colors(); - let border = if self.input.read(cx).read_only(cx) { - colors.border_disabled - } else { - colors.border_focused - }; - this.border_color(border) - }, - ) - .child(self.input.clone()), - ) + this.child(Divider::horizontal().color(DividerColor::Border)) + .child( + h_flex() + .p_1() + .rounded_sm() + .bg(cx.theme().colors().editor_background) + .border_1() + .when( + self.input.focus_handle(cx).contains_focused(window, cx), + |this| { + let colors = cx.theme().colors(); + + let border_color = if self.input.read(cx).read_only(cx) { + colors.border_disabled + } else { + colors.border_transparent + }; + + this.border_color(border_color) + }, + ) + .child(self.input.clone()), + ) }) } } @@ -865,12 +861,17 @@ impl LineBreakpoint { let path = self.breakpoint.path.clone(); let row = self.breakpoint.row; let is_enabled = self.breakpoint.state.is_enabled(); + let indicator = div() .id(SharedString::from(format!( "breakpoint-ui-toggle-{:?}/{}:{}", self.dir, self.name, self.line ))) - .cursor_pointer() + .child( + Icon::new(icon_name) + .color(Color::Debugger) + .size(IconSize::XSmall), + ) .tooltip({ let focus_handle = focus_handle.clone(); move |window, cx| { @@ -902,17 +903,14 @@ impl LineBreakpoint { .ok(); } }) - .child( - Icon::new(icon_name) - .color(Color::Debugger) - .size(IconSize::XSmall), - ) .on_mouse_down(MouseButton::Left, move |_, _, _| {}); ListItem::new(SharedString::from(format!( "breakpoint-ui-item-{:?}/{}:{}", self.dir, self.name, self.line ))) + .toggle_state(is_selected) + .inset(true) .on_click({ let weak = weak.clone(); move |_, window, cx| { @@ -922,23 +920,20 @@ impl LineBreakpoint { .ok(); } }) - .start_slot(indicator) - .rounded() .on_secondary_mouse_down(|_, _, cx| { cx.stop_propagation(); }) + .start_slot(indicator) .child( h_flex() - .w_full() - .mr_4() - .py_0p5() - .gap_1() - .min_h(px(26.)) - .justify_between() .id(SharedString::from(format!( "breakpoint-ui-on-click-go-to-line-{:?}/{}:{}", self.dir, self.name, self.line ))) + .w_full() + .gap_1() + .min_h(rems_from_px(26.)) + .justify_between() .on_click({ let weak = weak.clone(); move |_, window, cx| { @@ -949,9 +944,9 @@ impl LineBreakpoint { .ok(); } }) - .cursor_pointer() .child( h_flex() + .id("label-container") .gap_0p5() .child( Label::new(format!("{}:{}", self.name, self.line)) @@ -971,11 +966,13 @@ impl LineBreakpoint { .line_height_style(ui::LineHeightStyle::UiLabel) .truncate(), ) - })), + })) + .when_some(self.dir.as_ref(), |this, parent_dir| { + this.tooltip(Tooltip::text(format!( + "Worktree parent path: {parent_dir}" + ))) + }), ) - .when_some(self.dir.as_ref(), |this, parent_dir| { - this.tooltip(Tooltip::text(format!("Worktree parent path: {parent_dir}"))) - }) .child(BreakpointOptionsStrip { props, breakpoint: BreakpointEntry { @@ -988,15 +985,16 @@ impl LineBreakpoint { index: ix, }), ) - .toggle_state(is_selected) } } + #[derive(Clone, Debug)] struct ExceptionBreakpoint { id: String, data: ExceptionBreakpointsFilter, is_enabled: bool, } + #[derive(Clone, Debug)] struct DataBreakpoint(project::debugger::session::DataBreakpointState); @@ -1017,17 +1015,24 @@ impl DataBreakpoint { }; let is_enabled = self.0.is_enabled; let id = self.0.dap.data_id.clone(); + ListItem::new(SharedString::from(format!( "data-breakpoint-ui-item-{}", self.0.dap.data_id ))) - .rounded() + .toggle_state(is_selected) + .inset(true) .start_slot( div() .id(SharedString::from(format!( "data-breakpoint-ui-item-{}-click-handler", self.0.dap.data_id ))) + .child( + Icon::new(IconName::Binary) + .color(color) + .size(IconSize::Small), + ) .tooltip({ let focus_handle = focus_handle.clone(); move |window, cx| { @@ -1052,25 +1057,18 @@ impl DataBreakpoint { }) .ok(); } - }) - .cursor_pointer() - .child( - Icon::new(IconName::Binary) - .color(color) - .size(IconSize::Small), - ), + }), ) .child( h_flex() .w_full() - .mr_4() - .py_0p5() + .gap_1() + .min_h(rems_from_px(26.)) .justify_between() .child( v_flex() .py_1() .gap_1() - .min_h(px(26.)) .justify_center() .id(("data-breakpoint-label", ix)) .child( @@ -1091,7 +1089,6 @@ impl DataBreakpoint { index: ix, }), ) - .toggle_state(is_selected) } } @@ -1113,10 +1110,13 @@ impl ExceptionBreakpoint { let id = SharedString::from(&self.id); let is_enabled = self.is_enabled; let weak = list.clone(); + ListItem::new(SharedString::from(format!( "exception-breakpoint-ui-item-{}", self.id ))) + .toggle_state(is_selected) + .inset(true) .on_click({ let list = list.clone(); move |_, window, cx| { @@ -1124,7 +1124,6 @@ impl ExceptionBreakpoint { .ok(); } }) - .rounded() .on_secondary_mouse_down(|_, _, cx| { cx.stop_propagation(); }) @@ -1134,6 +1133,11 @@ impl ExceptionBreakpoint { "exception-breakpoint-ui-item-{}-click-handler", self.id ))) + .child( + Icon::new(IconName::Flame) + .color(color) + .size(IconSize::Small), + ) .tooltip({ let focus_handle = focus_handle.clone(); move |window, cx| { @@ -1158,25 +1162,18 @@ impl ExceptionBreakpoint { }) .ok(); } - }) - .cursor_pointer() - .child( - Icon::new(IconName::Flame) - .color(color) - .size(IconSize::Small), - ), + }), ) .child( h_flex() .w_full() - .mr_4() - .py_0p5() + .gap_1() + .min_h(rems_from_px(26.)) .justify_between() .child( v_flex() .py_1() .gap_1() - .min_h(px(26.)) .justify_center() .id(("exception-breakpoint-label", ix)) .child( @@ -1200,7 +1197,6 @@ impl ExceptionBreakpoint { index: ix, }), ) - .toggle_state(is_selected) } } #[derive(Clone, Debug)] @@ -1302,6 +1298,7 @@ impl BreakpointEntry { } } } + bitflags::bitflags! { #[derive(Clone, Copy)] pub struct SupportedBreakpointProperties: u32 { @@ -1360,6 +1357,7 @@ impl BreakpointOptionsStrip { fn is_toggled(&self, expected_mode: ActiveBreakpointStripMode) -> bool { self.is_selected && self.strip_mode == Some(expected_mode) } + fn on_click_callback( &self, mode: ActiveBreakpointStripMode, @@ -1379,7 +1377,8 @@ impl BreakpointOptionsStrip { .ok(); } } - fn add_border( + + fn add_focus_styles( &self, kind: ActiveBreakpointStripMode, available: bool, @@ -1388,22 +1387,25 @@ impl BreakpointOptionsStrip { ) -> impl Fn(Div) -> Div { move |this: Div| { // Avoid layout shifts in case there's no colored border - let this = this.border_2().rounded_sm(); + let this = this.border_1().rounded_sm(); + let color = cx.theme().colors(); + if self.is_selected && self.strip_mode == Some(kind) { - let theme = cx.theme().colors(); if self.focus_handle.is_focused(window) { - this.border_color(theme.border_selected) + this.bg(color.editor_background) + .border_color(color.border_focused) } else { - this.border_color(theme.border_disabled) + this.border_color(color.border) } } else if !available { - this.border_color(cx.theme().colors().border_disabled) + this.border_color(color.border_transparent) } else { this } } } } + impl RenderOnce for BreakpointOptionsStrip { fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement { let id = self.breakpoint.id(); @@ -1426,73 +1428,117 @@ impl RenderOnce for BreakpointOptionsStrip { }; let color_for_toggle = |is_enabled| { if is_enabled { - ui::Color::Default + Color::Default } else { - ui::Color::Muted + Color::Muted } }; h_flex() - .gap_1() + .gap_px() + .mr_3() // Space to avoid overlapping with the scrollbar .child( - div().map(self.add_border(ActiveBreakpointStripMode::Log, supports_logs, window, cx)) + div() + .map(self.add_focus_styles( + ActiveBreakpointStripMode::Log, + supports_logs, + window, + cx, + )) .child( IconButton::new( SharedString::from(format!("{id}-log-toggle")), IconName::Notepad, ) - .icon_size(IconSize::XSmall) + .shape(ui::IconButtonShape::Square) .style(style_for_toggle(ActiveBreakpointStripMode::Log, has_logs)) + .icon_size(IconSize::Small) .icon_color(color_for_toggle(has_logs)) + .when(has_logs, |this| this.indicator(Indicator::dot().color(Color::Info))) .disabled(!supports_logs) .toggle_state(self.is_toggled(ActiveBreakpointStripMode::Log)) - .on_click(self.on_click_callback(ActiveBreakpointStripMode::Log)).tooltip(|window, cx| Tooltip::with_meta("Set Log Message", None, "Set log message to display (instead of stopping) when a breakpoint is hit", window, cx)) + .on_click(self.on_click_callback(ActiveBreakpointStripMode::Log)) + .tooltip(|window, cx| { + Tooltip::with_meta( + "Set Log Message", + None, + "Set log message to display (instead of stopping) when a breakpoint is hit.", + window, + cx, + ) + }), ) .when(!has_logs && !self.is_selected, |this| this.invisible()), ) .child( - div().map(self.add_border( - ActiveBreakpointStripMode::Condition, - supports_condition, - window, cx - )) + div() + .map(self.add_focus_styles( + ActiveBreakpointStripMode::Condition, + supports_condition, + window, + cx, + )) .child( IconButton::new( SharedString::from(format!("{id}-condition-toggle")), IconName::SplitAlt, ) - .icon_size(IconSize::XSmall) + .shape(ui::IconButtonShape::Square) .style(style_for_toggle( ActiveBreakpointStripMode::Condition, - has_condition + has_condition, )) + .icon_size(IconSize::Small) .icon_color(color_for_toggle(has_condition)) + .when(has_condition, |this| this.indicator(Indicator::dot().color(Color::Info))) .disabled(!supports_condition) .toggle_state(self.is_toggled(ActiveBreakpointStripMode::Condition)) .on_click(self.on_click_callback(ActiveBreakpointStripMode::Condition)) - .tooltip(|window, cx| Tooltip::with_meta("Set Condition", None, "Set condition to evaluate when a breakpoint is hit. Program execution will stop only when the condition is met", window, cx)) + .tooltip(|window, cx| { + Tooltip::with_meta( + "Set Condition", + None, + "Set condition to evaluate when a breakpoint is hit. Program execution will stop only when the condition is met.", + window, + cx, + ) + }), ) .when(!has_condition && !self.is_selected, |this| this.invisible()), ) .child( - div().map(self.add_border( - ActiveBreakpointStripMode::HitCondition, - supports_hit_condition,window, cx - )) + div() + .map(self.add_focus_styles( + ActiveBreakpointStripMode::HitCondition, + supports_hit_condition, + window, + cx, + )) .child( IconButton::new( SharedString::from(format!("{id}-hit-condition-toggle")), IconName::ArrowDown10, ) - .icon_size(IconSize::XSmall) .style(style_for_toggle( ActiveBreakpointStripMode::HitCondition, has_hit_condition, )) + .shape(ui::IconButtonShape::Square) + .icon_size(IconSize::Small) .icon_color(color_for_toggle(has_hit_condition)) + .when(has_hit_condition, |this| this.indicator(Indicator::dot().color(Color::Info))) .disabled(!supports_hit_condition) .toggle_state(self.is_toggled(ActiveBreakpointStripMode::HitCondition)) - .on_click(self.on_click_callback(ActiveBreakpointStripMode::HitCondition)).tooltip(|window, cx| Tooltip::with_meta("Set Hit Condition", None, "Set expression that controls how many hits of the breakpoint are ignored.", window, cx)) + .on_click(self.on_click_callback(ActiveBreakpointStripMode::HitCondition)) + .tooltip(|window, cx| { + Tooltip::with_meta( + "Set Hit Condition", + None, + "Set expression that controls how many hits of the breakpoint are ignored.", + window, + cx, + ) + }), ) .when(!has_hit_condition && !self.is_selected, |this| { this.invisible() diff --git a/crates/debugger_ui/src/session/running/console.rs b/crates/debugger_ui/src/session/running/console.rs index daf4486f81..e6308518e4 100644 --- a/crates/debugger_ui/src/session/running/console.rs +++ b/crates/debugger_ui/src/session/running/console.rs @@ -367,7 +367,7 @@ impl Console { .when_some(keybinding_target.clone(), |el, keybinding_target| { el.context(keybinding_target.clone()) }) - .action("Watch expression", WatchExpression.boxed_clone()) + .action("Watch Expression", WatchExpression.boxed_clone()) })) }) }, @@ -452,18 +452,22 @@ impl Render for Console { fn render(&mut self, window: &mut Window, cx: &mut Context) -> impl IntoElement { let query_focus_handle = self.query_bar.focus_handle(cx); self.update_output(window, cx); + v_flex() .track_focus(&self.focus_handle) .key_context("DebugConsole") .on_action(cx.listener(Self::evaluate)) .on_action(cx.listener(Self::watch_expression)) .size_full() + .border_2() + .bg(cx.theme().colors().editor_background) .child(self.render_console(cx)) .when(self.is_running(cx), |this| { this.child(Divider::horizontal()).child( h_flex() .on_action(cx.listener(Self::previous_query)) .on_action(cx.listener(Self::next_query)) + .p_1() .gap_1() .bg(cx.theme().colors().editor_background) .child(self.render_query_bar(cx)) @@ -474,6 +478,9 @@ impl Render for Console { .on_click(move |_, window, cx| { window.dispatch_action(Box::new(Confirm), cx) }) + .layer(ui::ElevationIndex::ModalSurface) + .size(ui::ButtonSize::Compact) + .child(Label::new("Evaluate")) .tooltip({ let query_focus_handle = query_focus_handle.clone(); @@ -486,10 +493,7 @@ impl Render for Console { cx, ) } - }) - .layer(ui::ElevationIndex::ModalSurface) - .size(ui::ButtonSize::Compact) - .child(Label::new("Evaluate")), + }), self.render_submit_menu( ElementId::Name("split-button-right-confirm-button".into()), Some(query_focus_handle.clone()), @@ -499,7 +503,6 @@ impl Render for Console { )), ) }) - .border_2() } } diff --git a/crates/debugger_ui/src/session/running/memory_view.rs b/crates/debugger_ui/src/session/running/memory_view.rs index 75b8938371..f936d908b1 100644 --- a/crates/debugger_ui/src/session/running/memory_view.rs +++ b/crates/debugger_ui/src/session/running/memory_view.rs @@ -18,10 +18,8 @@ use project::debugger::{MemoryCell, dap_command::DataBreakpointContext, session: use settings::Settings; use theme::ThemeSettings; use ui::{ - ActiveTheme, AnyElement, App, Color, Context, ContextMenu, Div, Divider, DropdownMenu, Element, - FluentBuilder, Icon, IconName, InteractiveElement, IntoElement, Label, LabelCommon, - ParentElement, Pixels, PopoverMenuHandle, Render, Scrollbar, ScrollbarState, SharedString, - StatefulInteractiveElement, Styled, TextSize, Tooltip, Window, div, h_flex, px, v_flex, + ContextMenu, Divider, DropdownMenu, FluentBuilder, IntoElement, PopoverMenuHandle, Render, + Scrollbar, ScrollbarState, StatefulInteractiveElement, Tooltip, prelude::*, }; use workspace::Workspace;