Implement cascading resize algorithm

This commit is contained in:
Mikayla Maki 2023-07-24 08:04:46 -07:00
parent 429a2fc623
commit 25e4bcea7f
No known key found for this signature in database

View file

@ -584,7 +584,7 @@ impl SplitDirection {
} }
mod element { mod element {
use std::{cell::RefCell, ops::Range, rc::Rc}; use std::{cell::RefCell, iter::from_fn, ops::Range, rc::Rc};
use gpui::{ use gpui::{
geometry::{ geometry::{
@ -687,7 +687,7 @@ mod element {
fn handle_resize( fn handle_resize(
flexes: Rc<RefCell<Vec<f32>>>, flexes: Rc<RefCell<Vec<f32>>>,
axis: Axis, axis: Axis,
ix: usize, preceding_ix: usize,
child_start: Vector2F, child_start: Vector2F,
drag_bounds: RectF, drag_bounds: RectF,
) -> impl Fn(MouseDrag, &mut Workspace, &mut EventContext<Workspace>) { ) -> impl Fn(MouseDrag, &mut Workspace, &mut EventContext<Workspace>) {
@ -697,7 +697,7 @@ mod element {
move |drag, workspace: &mut Workspace, cx| { move |drag, workspace: &mut Workspace, cx| {
if drag.end { if drag.end {
dbg!("FINISHED"); // Clear cascading resize state
return; return;
} }
let min_size = match axis { let min_size = match axis {
@ -707,60 +707,66 @@ mod element {
let mut flexes = flexes.borrow_mut(); let mut flexes = flexes.borrow_mut();
// Don't allow resizing to less than the minimum size, if elements are already too small // Don't allow resizing to less than the minimum size, if elements are already too small
if min_size - 1. > size(ix, flexes.as_slice()) { if min_size - 1. > size(preceding_ix, flexes.as_slice()) {
return; return;
} }
let mut current_target_size = (drag.position - child_start).along(axis); let mut proposed_current_pixel_change = (drag.position - child_start).along(axis)
- size(preceding_ix, flexes.as_slice());
let mut proposed_current_pixel_change =
current_target_size - size(ix, flexes.as_slice());
let flex_changes = |pixel_dx, target_ix, next: isize, flexes: &[f32]| { let flex_changes = |pixel_dx, target_ix, next: isize, flexes: &[f32]| {
let flex_change = pixel_dx / drag_bounds.length_along(axis); let flex_change = pixel_dx / drag_bounds.length_along(axis);
let current_target_flex = flexes[target_ix] + flex_change; let current_target_flex = flexes[target_ix] + flex_change;
let next_target_flex = flexes[(target_ix as isize + next) as usize] - flex_change; let next_target_flex =
flexes[(target_ix as isize + next) as usize] - flex_change;
(current_target_flex, next_target_flex) (current_target_flex, next_target_flex)
}; };
if proposed_current_pixel_change < 0. { let mut successors = from_fn({
current_target_size = f32::max(current_target_size, min_size); let forward = proposed_current_pixel_change > 0.;
let current_pixel_change = current_target_size - size(ix, flexes.as_slice()); let mut ix_offset = 0;
let len = flexes.len();
move || {
let result = if forward {
(preceding_ix + 1 + ix_offset < len).then(|| preceding_ix + ix_offset)
} else {
(preceding_ix as isize - ix_offset as isize >= 0)
.then(|| preceding_ix - ix_offset)
};
ix_offset += 1;
result
}
});
while proposed_current_pixel_change.abs() > 0. {
let Some(current_ix) = successors.next() else {
break;
};
let next_target_size = f32::max(
size(current_ix + 1, flexes.as_slice()) - proposed_current_pixel_change,
min_size,
);
let current_target_size = f32::max(
size(current_ix, flexes.as_slice())
+ size(current_ix + 1, flexes.as_slice())
- next_target_size,
min_size,
);
let current_pixel_change =
current_target_size - size(current_ix, flexes.as_slice());
let (current_target_flex, next_target_flex) = let (current_target_flex, next_target_flex) =
flex_changes(current_pixel_change, ix, 1, flexes.as_slice()); flex_changes(current_pixel_change, current_ix, 1, flexes.as_slice());
flexes[ix] = current_target_flex; flexes[current_ix] = current_target_flex;
flexes[ix + 1] = next_target_flex; flexes[current_ix + 1] = next_target_flex;
} else if proposed_current_pixel_change > 0. {
let mut ix_offset = 0;
while proposed_current_pixel_change > 0.01 && ix + 1 + ix_offset < flexes.len()
{
let current_ix = ix_offset + ix;
let next_target_size = f32::max(
size(current_ix + 1, flexes.as_slice()) - proposed_current_pixel_change,
min_size,
);
current_target_size = f32::min( proposed_current_pixel_change -= current_pixel_change;
current_target_size,
size(current_ix, flexes.as_slice())
+ size(current_ix + 1, flexes.as_slice())
- next_target_size,
);
let current_pixel_change =
current_target_size - size(current_ix, flexes.as_slice());
let (current_target_flex, next_target_flex) =
flex_changes(current_pixel_change, current_ix, 1, flexes.as_slice());
flexes[current_ix] = current_target_flex;
flexes[current_ix + 1] = next_target_flex;
proposed_current_pixel_change -= current_pixel_change;
ix_offset += 1;
}
} }
workspace.schedule_serialize(cx); workspace.schedule_serialize(cx);
@ -924,7 +930,7 @@ mod element {
), ),
) )
.on_down(MouseButton::Left, |_, _: &mut Workspace, _| { .on_down(MouseButton::Left, |_, _: &mut Workspace, _| {
dbg!("INITIATE"); // Save cascading resize state
}) })
.on_click(MouseButton::Left, { .on_click(MouseButton::Left, {
let flexes = self.flexes.clone(); let flexes = self.flexes.clone();