Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
Peter Tripp
88a37b04aa
Up or Down 2025-08-01 16:23:32 -04:00
Peter Tripp
23dddba1e6
Upper controls. 2025-08-01 15:43:30 -04:00
3 changed files with 56 additions and 13 deletions

View file

@ -30,7 +30,7 @@ use std::{
sync::Arc, sync::Arc,
time::Duration, time::Duration,
}; };
use ui::{IconButtonShape, KeyBinding, Tooltip, prelude::*, vertical_divider}; use ui::{ButtonSize, IconButtonShape, KeyBinding, Tooltip, prelude::*, vertical_divider};
use util::ResultExt; use util::ResultExt;
use workspace::{ use workspace::{
Item, ItemHandle, ItemNavHistory, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView, Item, ItemHandle, ItemNavHistory, ToolbarItemEvent, ToolbarItemLocation, ToolbarItemView,
@ -791,22 +791,32 @@ fn render_diff_hunk_controls(
) -> AnyElement { ) -> AnyElement {
let editor = editor.clone(); let editor = editor.clone();
h_flex() // Get controls positioning from editor state
let controls_above = editor.read(cx).diff_hunk_controls_above();
let mut container = h_flex()
.h(line_height) .h(line_height)
.mr_0p5() .mr_0p5()
.gap_1() .gap_1()
.px_0p5() .px_0p5()
.pb_1() .py_0p5()
.border_x_1() .border_x_1()
.border_b_1()
.border_color(cx.theme().colors().border) .border_color(cx.theme().colors().border)
.rounded_b_md()
.bg(cx.theme().colors().editor_background) .bg(cx.theme().colors().editor_background)
.gap_1() .gap_1()
.block_mouse_except_scroll() .block_mouse_except_scroll()
.shadow_md() .shadow_md();
if controls_above {
container = container.border_t_1().rounded_t_md();
} else {
container = container.border_b_1().rounded_b_md();
}
container
.children(vec![ .children(vec![
Button::new(("reject", row as u64), "Reject") Button::new(("reject", row as u64), "Reject")
.size(ButtonSize::Compact)
.disabled(is_created_file) .disabled(is_created_file)
.key_binding( .key_binding(
KeyBinding::for_action_in( KeyBinding::for_action_in(
@ -835,6 +845,7 @@ fn render_diff_hunk_controls(
} }
}), }),
Button::new(("keep", row as u64), "Keep") Button::new(("keep", row as u64), "Keep")
.size(ButtonSize::Compact)
.key_binding( .key_binding(
KeyBinding::for_action_in(&Keep, &editor.read(cx).focus_handle(cx), window, cx) KeyBinding::for_action_in(&Keep, &editor.read(cx).focus_handle(cx), window, cx)
.map(|kb| kb.size(rems_from_px(12.))), .map(|kb| kb.size(rems_from_px(12.))),

View file

@ -1126,6 +1126,7 @@ pub struct Editor {
show_git_blame_inline_delay_task: Option<Task<()>>, show_git_blame_inline_delay_task: Option<Task<()>>,
git_blame_inline_enabled: bool, git_blame_inline_enabled: bool,
render_diff_hunk_controls: RenderDiffHunkControlsFn, render_diff_hunk_controls: RenderDiffHunkControlsFn,
diff_hunk_controls_above: bool,
serialize_dirty_buffers: bool, serialize_dirty_buffers: bool,
show_selection_menu: Option<bool>, show_selection_menu: Option<bool>,
blame: Option<Entity<GitBlame>>, blame: Option<Entity<GitBlame>>,
@ -2137,6 +2138,7 @@ impl Editor {
git_blame_inline_enabled: full_mode git_blame_inline_enabled: full_mode
&& ProjectSettings::get_global(cx).git.inline_blame_enabled(), && ProjectSettings::get_global(cx).git.inline_blame_enabled(),
render_diff_hunk_controls: Arc::new(render_diff_hunk_controls), render_diff_hunk_controls: Arc::new(render_diff_hunk_controls),
diff_hunk_controls_above: true,
serialize_dirty_buffers: !is_minimap serialize_dirty_buffers: !is_minimap
&& ProjectSettings::get_global(cx) && ProjectSettings::get_global(cx)
.session .session
@ -23641,6 +23643,12 @@ struct LineManipulationResult {
pub line_count_after: usize, pub line_count_after: usize,
} }
impl Editor {
pub fn diff_hunk_controls_above(&self) -> bool {
self.diff_hunk_controls_above
}
}
fn render_diff_hunk_controls( fn render_diff_hunk_controls(
row: u32, row: u32,
status: &DiffHunkStatus, status: &DiffHunkStatus,
@ -23651,22 +23659,31 @@ fn render_diff_hunk_controls(
_window: &mut Window, _window: &mut Window,
cx: &mut App, cx: &mut App,
) -> AnyElement { ) -> AnyElement {
h_flex() // Get controls positioning from editor state
let controls_above = editor.read(cx).diff_hunk_controls_above();
let mut container = h_flex()
.h(line_height) .h(line_height)
.mr_1() .mr_1()
.gap_1() .gap_1()
.px_0p5() .px_0p5()
.pb_1() .py_0p5()
.border_x_1() .border_x_1()
.border_b_1()
.border_color(cx.theme().colors().border_variant) .border_color(cx.theme().colors().border_variant)
.rounded_b_lg()
.bg(cx.theme().colors().editor_background) .bg(cx.theme().colors().editor_background)
.gap_1() .gap_1()
.block_mouse_except_scroll() .block_mouse_except_scroll()
.shadow_md() .shadow_md();
if controls_above {
container = container.border_t_1().rounded_t_lg();
} else {
container = container.border_b_1().rounded_b_lg();
}
container
.child(if status.has_secondary_hunk() { .child(if status.has_secondary_hunk() {
Button::new(("stage", row as u64), "Stage") Button::new(("stage", row as u64), "Stage")
.size(ButtonSize::Compact)
.alpha(if status.is_pending() { 0.66 } else { 1.0 }) .alpha(if status.is_pending() { 0.66 } else { 1.0 })
.tooltip({ .tooltip({
let focus_handle = editor.focus_handle(cx); let focus_handle = editor.focus_handle(cx);
@ -23694,6 +23711,7 @@ fn render_diff_hunk_controls(
}) })
} else { } else {
Button::new(("unstage", row as u64), "Unstage") Button::new(("unstage", row as u64), "Unstage")
.size(ButtonSize::Compact)
.alpha(if status.is_pending() { 0.66 } else { 1.0 }) .alpha(if status.is_pending() { 0.66 } else { 1.0 })
.tooltip({ .tooltip({
let focus_handle = editor.focus_handle(cx); let focus_handle = editor.focus_handle(cx);
@ -23722,6 +23740,7 @@ fn render_diff_hunk_controls(
}) })
.child( .child(
Button::new(("restore", row as u64), "Restore") Button::new(("restore", row as u64), "Restore")
.size(ButtonSize::Compact)
.tooltip({ .tooltip({
let focus_handle = editor.focus_handle(cx); let focus_handle = editor.focus_handle(cx);
move |window, cx| { move |window, cx| {

View file

@ -4985,8 +4985,21 @@ impl EditorElement {
.iter() .iter()
.any(|p| p.map_or(false, |p| display_row_range.contains(&p.row()))) .any(|p| p.map_or(false, |p| display_row_range.contains(&p.row())))
{ {
let y = display_row_range.start.as_f32() * line_height // Get controls positioning from editor state
+ text_hitbox.bounds.top() let controls_above = editor.read(cx).diff_hunk_controls_above();
let control_row = if controls_above {
// Position controls one line above the diff hunk to avoid covering diff content
if display_row_range.start.0 > 0 {
display_row_range.start.0 - 1
} else {
display_row_range.start.0
}
} else {
// Position controls at the start of the diff hunk (original behavior)
display_row_range.start.0
};
let y = control_row as f32 * line_height + text_hitbox.bounds.top()
- scroll_pixel_position.y; - scroll_pixel_position.y;
let mut element = render_diff_hunk_controls( let mut element = render_diff_hunk_controls(