keymap ui: Improve resize columns on double click (#34961)

This PR splits the resize logic into separate left/right propagation
methods and improve code organization around column width adjustments.
It also allows resize to work for both the left and right sides as well,
instead of only checking the right side for room

Release Notes:

- N/A *or* Added/Fixed/Improved ...

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
This commit is contained in:
Anthony Eid 2025-07-23 13:45:49 -04:00 committed by GitHub
parent fdcd86617a
commit 56b64b1d3f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -510,39 +510,48 @@ impl<const COLS: usize> ColumnWidths<COLS> {
) { ) {
let bounds_width = self.cached_bounds_width; let bounds_width = self.cached_bounds_width;
let rem_size = window.rem_size(); let rem_size = window.rem_size();
let initial_sizes =
initial_sizes.map(|length| Self::get_fraction(&length, bounds_width, rem_size));
let mut widths = self
.widths
.map(|length| Self::get_fraction(&length, bounds_width, rem_size));
let diff = let diff = initial_sizes[double_click_position] - widths[double_click_position];
Self::get_fraction(
&initial_sizes[double_click_position],
bounds_width,
rem_size,
) - Self::get_fraction(&self.widths[double_click_position], bounds_width, rem_size);
let mut curr_column = double_click_position + 1; if diff > 0.0 {
let mut diff_left = diff; let diff_remaining = self.propagate_resize_diff_right(
diff,
while diff_left != 0.0 && curr_column < COLS { double_click_position,
let Some(min_size) = resize_behavior[curr_column].min_size() else { &mut widths,
curr_column += 1; resize_behavior,
continue;
};
let mut curr_width =
Self::get_fraction(&self.widths[curr_column], bounds_width, rem_size) - diff_left;
diff_left = 0.0;
if min_size > curr_width {
diff_left += min_size - curr_width;
curr_width = min_size;
}
self.widths[curr_column] = DefiniteLength::Fraction(curr_width);
curr_column += 1;
}
self.widths[double_click_position] = DefiniteLength::Fraction(
Self::get_fraction(&self.widths[double_click_position], bounds_width, rem_size)
+ (diff - diff_left),
); );
if diff_remaining > 0.0 && double_click_position > 0 {
self.propagate_resize_diff_left(
-diff_remaining,
double_click_position - 1,
&mut widths,
resize_behavior,
);
}
} else if double_click_position > 0 {
let diff_remaining = self.propagate_resize_diff_left(
diff,
double_click_position,
&mut widths,
resize_behavior,
);
if diff_remaining < 0.0 {
self.propagate_resize_diff_right(
-diff_remaining,
double_click_position,
&mut widths,
resize_behavior,
);
}
}
self.widths = widths.map(DefiniteLength::Fraction);
} }
fn on_drag_move( fn on_drag_move(
@ -552,7 +561,6 @@ impl<const COLS: usize> ColumnWidths<COLS> {
window: &mut Window, window: &mut Window,
cx: &mut Context<Self>, cx: &mut Context<Self>,
) { ) {
// - [ ] Fix bugs in resize
let drag_position = drag_event.event.position; let drag_position = drag_event.event.position;
let bounds = drag_event.bounds; let bounds = drag_event.bounds;
@ -561,13 +569,17 @@ impl<const COLS: usize> ColumnWidths<COLS> {
let bounds_width = bounds.right() - bounds.left(); let bounds_width = bounds.right() - bounds.left();
let col_idx = drag_event.drag(cx).0; let col_idx = drag_event.drag(cx).0;
for length in self.widths[0..=col_idx].iter() { let mut widths = self
col_position += Self::get_fraction(length, bounds_width, rem_size); .widths
.map(|length| Self::get_fraction(&length, bounds_width, rem_size));
for length in widths[0..=col_idx].iter() {
col_position += length;
} }
let mut total_length_ratio = col_position; let mut total_length_ratio = col_position;
for length in self.widths[col_idx + 1..].iter() { for length in widths[col_idx + 1..].iter() {
total_length_ratio += Self::get_fraction(length, bounds_width, rem_size); total_length_ratio += length;
} }
let drag_fraction = (drag_position.x - bounds.left()) / bounds_width; let drag_fraction = (drag_position.x - bounds.left()) / bounds_width;
@ -576,37 +588,56 @@ impl<const COLS: usize> ColumnWidths<COLS> {
let is_dragging_right = diff > 0.0; let is_dragging_right = diff > 0.0;
let mut diff_left = diff; if is_dragging_right {
self.propagate_resize_diff_right(diff, col_idx, &mut widths, resize_behavior);
} else {
// Resize behavior should be improved in the future by also seeking to the right column when there's not enough space
self.propagate_resize_diff_left(diff, col_idx, &mut widths, resize_behavior);
}
self.widths = widths.map(DefiniteLength::Fraction);
}
fn propagate_resize_diff_right(
&self,
diff: f32,
col_idx: usize,
widths: &mut [f32; COLS],
resize_behavior: &[ResizeBehavior; COLS],
) -> f32 {
let mut diff_remaining = diff;
let mut curr_column = col_idx + 1; let mut curr_column = col_idx + 1;
if is_dragging_right { while diff_remaining > 0.0 && curr_column < COLS {
while diff_left > 0.0 && curr_column < COLS {
let Some(min_size) = resize_behavior[curr_column - 1].min_size() else { let Some(min_size) = resize_behavior[curr_column - 1].min_size() else {
curr_column += 1; curr_column += 1;
continue; continue;
}; };
let mut curr_width = let mut curr_width = widths[curr_column] - diff_remaining;
Self::get_fraction(&self.widths[curr_column], bounds_width, rem_size)
- diff_left;
diff_left = 0.0; diff_remaining = 0.0;
if min_size > curr_width { if min_size > curr_width {
diff_left += min_size - curr_width; diff_remaining += min_size - curr_width;
curr_width = min_size; curr_width = min_size;
} }
self.widths[curr_column] = DefiniteLength::Fraction(curr_width); widths[curr_column] = curr_width;
curr_column += 1; curr_column += 1;
} }
self.widths[col_idx] = DefiniteLength::Fraction( widths[col_idx] = widths[col_idx] + (diff - diff_remaining);
Self::get_fraction(&self.widths[col_idx], bounds_width, rem_size) return diff_remaining;
+ (diff - diff_left), }
);
} else { fn propagate_resize_diff_left(
curr_column = col_idx; &mut self,
// Resize behavior should be improved in the future by also seeking to the right column when there's not enough space diff: f32,
while diff_left < 0.0 { mut curr_column: usize,
widths: &mut [f32; COLS],
resize_behavior: &[ResizeBehavior; COLS],
) -> f32 {
let mut diff_remaining = diff;
let col_idx = curr_column;
while diff_remaining < 0.0 {
let Some(min_size) = resize_behavior[curr_column].min_size() else { let Some(min_size) = resize_behavior[curr_column].min_size() else {
if curr_column == 0 { if curr_column == 0 {
break; break;
@ -615,28 +646,23 @@ impl<const COLS: usize> ColumnWidths<COLS> {
continue; continue;
}; };
let mut curr_width = let mut curr_width = widths[curr_column] + diff_remaining;
Self::get_fraction(&self.widths[curr_column], bounds_width, rem_size)
+ diff_left;
diff_left = 0.0; diff_remaining = 0.0;
if curr_width < min_size { if curr_width < min_size {
diff_left = curr_width - min_size; diff_remaining = curr_width - min_size;
curr_width = min_size curr_width = min_size
} }
self.widths[curr_column] = DefiniteLength::Fraction(curr_width); widths[curr_column] = curr_width;
if curr_column == 0 { if curr_column == 0 {
break; break;
} }
curr_column -= 1; curr_column -= 1;
} }
widths[col_idx + 1] = widths[col_idx + 1] - (diff - diff_remaining);
self.widths[col_idx + 1] = DefiniteLength::Fraction( return diff_remaining;
Self::get_fraction(&self.widths[col_idx + 1], bounds_width, rem_size)
- (diff - diff_left),
);
}
} }
} }