diff --git a/crates/gpui/src/elements/resizable.rs b/crates/gpui/src/elements/resizable.rs index b4bc512496..814353ce85 100644 --- a/crates/gpui/src/elements/resizable.rs +++ b/crates/gpui/src/elements/resizable.rs @@ -1,14 +1,14 @@ use std::{cell::Cell, rc::Rc}; -use pathfinder_geometry::vector::Vector2F; +use pathfinder_geometry::vector::{vec2f, Vector2F}; use serde_json::json; use crate::{ - color::Color, scene::DragRegionEvent, Axis, Border, CursorStyle, Element, ElementBox, - ElementStateHandle, MouseButton, RenderContext, View, MouseRegion, + geometry::rect::RectF, scene::DragRegionEvent, Axis, CursorStyle, Element, ElementBox, + ElementStateHandle, MouseButton, MouseRegion, RenderContext, View, }; -use super::{ConstrainedBox, Empty, Flex, Hook, MouseEventHandler, Padding, ParentElement}; +use super::{ConstrainedBox, Flex, Hook, ParentElement}; #[derive(Copy, Clone, Debug)] pub enum Side { @@ -35,13 +35,6 @@ impl Side { } } - fn resize_padding(&self, padding_size: f32) -> Padding { - match self.axis() { - Axis::Horizontal => Padding::horizontal(padding_size), - Axis::Vertical => Padding::vertical(padding_size), - } - } - fn relevant_component(&self, vector: Vector2F) -> f32 { match self.axis() { Axis::Horizontal => vector.x(), @@ -56,6 +49,19 @@ impl Side { self.relevant_component(e.position) - self.relevant_component(e.prev_mouse_position) } } + + fn of_rect(&self, bounds: RectF, handle_size: f32) -> RectF { + match self { + Side::Top => RectF::new(bounds.origin(), vec2f(bounds.width(), handle_size)), + Side::Bottom => RectF::new(bounds.lower_left(), vec2f(bounds.width(), handle_size)), + Side::Left => RectF::new(bounds.origin(), vec2f(handle_size, bounds.height())), + Side::Right => { + let mut origin = bounds.upper_right(); + origin.set_x(origin.x() - handle_size); + RectF::new(origin, vec2f(handle_size, bounds.height())) + } + } + } } struct ResizeHandleState { @@ -65,6 +71,7 @@ struct ResizeHandleState { pub struct Resizable { side: Side, + handle_size: f32, child: ElementBox, state: Rc, _state_handle: ElementStateHandle>, @@ -91,11 +98,6 @@ impl Resizable { let mut flex = Flex::new(side.axis()); - if side.before_content() { - dbg!("HANDLE BEING RENDERED BEFORE"); - flex.add_child(render_resize_handle(state.clone(), side, handle_size, cx)) - } - flex.add_child( Hook::new({ let constrained = ConstrainedBox::new(child); @@ -114,57 +116,18 @@ impl Resizable { .boxed(), ); - if !side.before_content() { - dbg!("HANDLE BEING RENDERED AFTER"); - flex.add_child(render_resize_handle(state.clone(), side, handle_size, cx)) - } - let child = flex.boxed(); Self { side, child, + handle_size, state, _state_handle: state_handle, } } } -fn render_resize_handle( - state: Rc, - side: Side, - padding_size: f32, - cx: &mut RenderContext, -) -> ElementBox { - enum ResizeHandle {} - MouseEventHandler::::new(side as usize, cx, |_, _| { - Empty::new() - // Border necessary to properly add a MouseRegion - .contained() - .with_border(Border { - width: 4., - left: true, - color: Color::red(), - ..Default::default() - }) - .boxed() - }) - .with_padding(side.resize_padding(padding_size)) - .with_cursor_style(match side.axis() { - Axis::Horizontal => CursorStyle::ResizeLeftRight, - Axis::Vertical => CursorStyle::ResizeUpDown, - }) - .on_down(MouseButton::Left, |_, _| {}) // This prevents the mouse down event from being propagated elsewhere - .on_drag(MouseButton::Left, move |e, cx| { - let prev_width = state.actual_dimension.get(); - state - .custom_dimension - .set(0f32.max(prev_width + side.compute_delta(e)).round()); - cx.notify(); - }) - .boxed() -} - impl Element for Resizable { type LayoutState = Vector2F; type PaintState = (); @@ -182,19 +145,42 @@ impl Element for Resizable { &mut self, bounds: pathfinder_geometry::rect::RectF, visible_bounds: pathfinder_geometry::rect::RectF, - child_size: &mut Self::LayoutState, + _child_size: &mut Self::LayoutState, cx: &mut crate::PaintContext, ) -> Self::PaintState { cx.scene.push_stacking_context(None); - - // Render a mouse region on the appropriate border (likely just bounds) - // Use the padding in the above code to decide the size of the rect to pass to the mouse region - // Add handlers for Down and Drag like above - - // Maybe try pushing a quad to visually inspect where the region gets placed - // Push a cursor region - cx.scene.push_mouse_region(MouseRegion::) - + + let handle_region = self.side.of_rect(bounds, self.handle_size); + + enum ResizeHandle {} + cx.scene.push_mouse_region( + MouseRegion::new::( + cx.current_view_id(), + self.side as usize, + handle_region, + ) + .on_down(MouseButton::Left, |_, _| {}) // This prevents the mouse down event from being propagated elsewhere + .on_drag(MouseButton::Left, { + let state = self.state.clone(); + let side = self.side; + move |e, cx| { + let prev_width = state.actual_dimension.get(); + state + .custom_dimension + .set(0f32.max(prev_width + side.compute_delta(e)).round()); + cx.notify(); + } + }), + ); + + cx.scene.push_cursor_region(crate::CursorRegion { + bounds: handle_region, + style: match self.side.axis() { + Axis::Horizontal => CursorStyle::ResizeLeftRight, + Axis::Vertical => CursorStyle::ResizeUpDown, + }, + }); + cx.scene.pop_stacking_context(); self.child.paint(bounds.origin(), visible_bounds, cx); diff --git a/crates/workspace/src/dock.rs b/crates/workspace/src/dock.rs index 4ba9617be9..aa49d24b47 100644 --- a/crates/workspace/src/dock.rs +++ b/crates/workspace/src/dock.rs @@ -1,6 +1,6 @@ use gpui::{ actions, - elements::{ChildView, Container, Empty, FlexItem, Margin, MouseEventHandler, Side, Svg}, + elements::{ChildView, Container, Empty, Margin, MouseEventHandler, Side, Svg}, impl_internal_actions, CursorStyle, Element, ElementBox, Entity, MouseButton, MutableAppContext, RenderContext, View, ViewContext, ViewHandle, WeakViewHandle, };