@@ -587,14 +587,16 @@ mod element {
use std::{cell::RefCell, ops::Range, rc::Rc};
use gpui::{
+ elements::MouseEventHandler,
geometry::{
rect::RectF,
vector::{vec2f, Vector2F},
},
json::{self, ToJson},
platform::{CursorStyle, MouseButton},
- AnyElement, Axis, CursorRegion, Element, LayoutContext, MouseRegion, RectFExt,
- SceneBuilder, SizeConstraint, Vector2FExt, ViewContext,
+ scene::MouseDrag,
+ AnyElement, Axis, CursorRegion, Element, EventContext, LayoutContext, MouseRegion,
+ RectFExt, SceneBuilder, SizeConstraint, Vector2FExt, ViewContext,
};
use crate::{
@@ -682,6 +684,90 @@ mod element {
*cross_axis_max = cross_axis_max.max(child_size.along(cross_axis));
}
}
+
+ fn handle_resize(
+ flexes: Rc<RefCell<Vec<f32>>>,
+ axis: Axis,
+ ix: usize,
+ child_start: Vector2F,
+ drag_bounds: RectF,
+ ) -> impl Fn(MouseDrag, &mut Workspace, &mut EventContext<Workspace>) {
+ let size = move |ix, flexes: &[f32]| {
+ drag_bounds.length_along(axis) * (flexes[ix] / flexes.len() as f32)
+ };
+
+ move |drag, workspace: &mut Workspace, cx| {
+ let min_size = match axis {
+ Axis::Horizontal => HORIZONTAL_MIN_SIZE,
+ Axis::Vertical => VERTICAL_MIN_SIZE,
+ };
+ let mut flexes = flexes.borrow_mut();
+
+ // 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()) {
+ return;
+ }
+
+ let mut current_target_size = (drag.position - child_start).along(axis);
+
+ let mut proposed_current_pixel_change =
+ current_target_size - size(ix, flexes.as_slice());
+
+ let flex_changes = |pixel_dx, target_ix, flexes: &[f32]| {
+ let flex_change = pixel_dx / drag_bounds.length_along(axis);
+ let current_target_flex = flexes[target_ix] + flex_change;
+ let next_target_flex = flexes[target_ix + 1] - flex_change;
+ (current_target_flex, next_target_flex)
+ };
+
+ if proposed_current_pixel_change < 0. {
+ current_target_size = f32::max(current_target_size, min_size);
+ let current_pixel_change = current_target_size - size(ix, flexes.as_slice());
+
+ let (current_target_flex, next_target_flex) =
+ flex_changes(current_pixel_change, ix, flexes.as_slice());
+
+ flexes[ix] = current_target_flex;
+ flexes[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 next_target_size = f32::max(
+ size(ix + 1, flexes.as_slice()) - proposed_current_pixel_change,
+ min_size,
+ );
+
+ current_target_size = f32::min(
+ current_target_size,
+ size(ix, flexes.as_slice()) + size(ix + 1, flexes.as_slice())
+ - next_target_size,
+ );
+
+ let current_pixel_change =
+ current_target_size - size(ix, flexes.as_slice());
+
+ let (current_target_flex, next_target_flex) =
+ flex_changes(current_pixel_change, ix, flexes.as_slice());
+
+ flexes[ix_offset + ix] = current_target_flex;
+ flexes[ix_offset + ix + 1] = next_target_flex;
+
+ dbg!(
+ current_pixel_change,
+ proposed_current_pixel_change,
+ proposed_current_pixel_change - current_pixel_change
+ );
+ proposed_current_pixel_change -= current_pixel_change;
+ ix_offset += 1;
+ }
+ dbg!("done");
+ }
+
+ workspace.schedule_serialize(cx);
+ cx.notify();
+ }
+ }
}
impl Extend<AnyElement<Workspace>> for PaneAxisElement {
@@ -780,11 +866,6 @@ mod element {
let mut bounding_boxes = self.bounding_boxes.borrow_mut();
bounding_boxes.clear();
- let sizes = self
- .children
- .iter()
- .map(|child| child.size())
- .collect::<Vec<_>>();
let mut children_iter = self.children.iter_mut().enumerate().peekable();
while let Some((ix, child)) = children_iter.next() {
let child_start = child_origin.clone();
@@ -826,8 +907,6 @@ mod element {
style,
});
- let axis = self.axis;
- let drag_bounds = visible_bounds.clone();
enum ResizeHandle {}
let mut mouse_region = MouseRegion::new::<ResizeHandle>(
cx.view_id(),
@@ -835,75 +914,16 @@ mod element {
handle_bounds,
);
mouse_region = mouse_region
- .on_drag(MouseButton::Left, {
- let flexes = self.flexes.clone();
- let sizes = sizes.clone();
- move |drag, workspace: &mut Workspace, cx| {
- let min_size = match axis {
- Axis::Horizontal => HORIZONTAL_MIN_SIZE,
- Axis::Vertical => VERTICAL_MIN_SIZE,
- };
- // Don't allow resizing to less than the minimum size, if elements are already too small
- if min_size - 1. > sizes[ix].along(axis) {
- return;
- }
-
- let mut flexes = flexes.borrow_mut();
-
- let mut current_target_size =
- (drag.position - child_start).along(axis);
-
- let mut proposed_current_pixel_change =
- current_target_size - sizes[ix].along(axis);
-
- let flex_changes = |target_size, target_ix| {
- let current_pixel_change = target_size - sizes[ix].along(axis);
- let flex_change =
- current_pixel_change / drag_bounds.length_along(axis);
- let current_target_flex = flexes[target_ix] + flex_change;
- let next_target_flex = flexes[target_ix + 1] - flex_change;
- (current_target_flex, next_target_flex)
- };
-
- if proposed_current_pixel_change < 0. {
- current_target_size = f32::max(current_target_size, min_size);
- let (current_target_flex, next_target_flex) =
- flex_changes(current_target_size, ix);
-
- *flexes.get_mut(ix).unwrap() = current_target_flex;
- *flexes.get_mut(ix + 1).unwrap() = next_target_flex;
- } else if proposed_current_pixel_change > 0. {
- let mut next_target_size = f32::max(
- sizes[ix + 1].along(axis) - proposed_current_pixel_change,
- min_size,
- );
-
- current_target_size = f32::min(
- current_target_size,
- sizes[ix].along(axis) + sizes[ix + 1].along(axis)
- - next_target_size,
- );
-
- let (current_target_flex, next_target_flex) =
- flex_changes(current_target_size, ix);
-
- // TODO: make this into a loop
- *flexes.get_mut(ix).unwrap() = current_target_flex;
- *flexes.get_mut(ix + 1).unwrap() = next_target_flex;
-
- // let mut ix_offset = 0;
-
- // while proposed_current_pixel_change > 0.
- // && ix + 1 + ix_offset < flexes.len()
- // {
-
- // }
- }
-
- workspace.schedule_serialize(cx);
- cx.notify();
- }
- })
+ .on_drag(
+ MouseButton::Left,
+ Self::handle_resize(
+ self.flexes.clone(),
+ self.axis,
+ ix,
+ child_start,
+ visible_bounds.clone(),
+ ),
+ )
.on_click(MouseButton::Left, {
let flexes = self.flexes.clone();
move |e, v: &mut Workspace, cx| {