diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index c7fbb658a3cf106e1ee7cc6212cf67a18481c84c..fc3c53f34343684ed5d39305d1c30d4fe7872881 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -28,7 +28,7 @@ use gpui::{ AnchorCorner, AnyElement, AvailableSpace, BorrowWindow, Bounds, ContentMask, Corners, CursorStyle, DispatchPhase, Edges, Element, ElementInputHandler, Hsla, InteractiveBounds, InteractiveElement, IntoElement, ModifiersChangedEvent, MouseButton, MouseDownEvent, - MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, ScrollWheelEvent, ShapedLine, + MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, ScrollDelta, ScrollWheelEvent, ShapedLine, SharedString, Size, StackingOrder, StatefulInteractiveElement, Style, Styled, TextRun, TextStyle, View, ViewContext, WindowContext, }; @@ -581,41 +581,6 @@ impl EditorElement { } } - fn scroll( - editor: &mut Editor, - event: &ScrollWheelEvent, - position_map: &PositionMap, - bounds: &InteractiveBounds, - cx: &mut ViewContext, - ) { - if !bounds.visibly_contains(&event.position, cx) { - return; - } - - let line_height = position_map.line_height; - let max_glyph_width = position_map.em_width; - let (delta, axis) = match event.delta { - gpui::ScrollDelta::Pixels(mut pixels) => { - //Trackpad - let axis = position_map.snapshot.ongoing_scroll.filter(&mut pixels); - (pixels, axis) - } - - gpui::ScrollDelta::Lines(lines) => { - //Not trackpad - let pixels = point(lines.x * max_glyph_width, lines.y * line_height); - (pixels, None) - } - }; - - let scroll_position = position_map.snapshot.scroll_position(); - let x = f32::from((scroll_position.x * max_glyph_width - delta.x) / max_glyph_width); - let y = f32::from((scroll_position.y * line_height - delta.y) / line_height); - let scroll_position = point(x, y).clamp(&point(0., 0.), &position_map.scroll_max); - editor.scroll(scroll_position, axis, cx); - cx.stop_propagation(); - } - fn paint_background( &self, gutter_bounds: Bounds, @@ -2450,34 +2415,78 @@ impl EditorElement { ) } - fn paint_mouse_listeners( + fn paint_scroll_wheel_listener( &mut self, - bounds: Bounds, - gutter_bounds: Bounds, - text_bounds: Bounds, + interactive_bounds: &InteractiveBounds, layout: &LayoutState, cx: &mut WindowContext, ) { - let interactive_bounds = InteractiveBounds { - bounds: bounds.intersect(&cx.content_mask().bounds), - stacking_order: cx.stacking_order().clone(), - }; - cx.on_mouse_event({ let position_map = layout.position_map.clone(); let editor = self.editor.clone(); let interactive_bounds = interactive_bounds.clone(); + let mut delta = ScrollDelta::default(); move |event: &ScrollWheelEvent, phase, cx| { if phase == DispatchPhase::Bubble && interactive_bounds.visibly_contains(&event.position, cx) { + delta = delta.coalesce(event.delta); editor.update(cx, |editor, cx| { - Self::scroll(editor, event, &position_map, &interactive_bounds, cx) + let position = event.position; + let position_map: &PositionMap = &position_map; + let bounds = &interactive_bounds; + if !bounds.visibly_contains(&position, cx) { + return; + } + + let line_height = position_map.line_height; + let max_glyph_width = position_map.em_width; + let (delta, axis) = match delta { + gpui::ScrollDelta::Pixels(mut pixels) => { + //Trackpad + let axis = position_map.snapshot.ongoing_scroll.filter(&mut pixels); + (pixels, axis) + } + + gpui::ScrollDelta::Lines(lines) => { + //Not trackpad + let pixels = + point(lines.x * max_glyph_width, lines.y * line_height); + (pixels, None) + } + }; + + let scroll_position = position_map.snapshot.scroll_position(); + let x = f32::from( + (scroll_position.x * max_glyph_width - delta.x) / max_glyph_width, + ); + let y = + f32::from((scroll_position.y * line_height - delta.y) / line_height); + let scroll_position = + point(x, y).clamp(&point(0., 0.), &position_map.scroll_max); + editor.scroll(scroll_position, axis, cx); + cx.stop_propagation(); }); } } }); + } + + fn paint_mouse_listeners( + &mut self, + bounds: Bounds, + gutter_bounds: Bounds, + text_bounds: Bounds, + layout: &LayoutState, + cx: &mut WindowContext, + ) { + let interactive_bounds = InteractiveBounds { + bounds: bounds.intersect(&cx.content_mask().bounds), + stacking_order: cx.stacking_order().clone(), + }; + + self.paint_scroll_wheel_listener(&interactive_bounds, layout, cx); cx.on_mouse_event({ let position_map = layout.position_map.clone(); diff --git a/crates/gpui/src/interactive.rs b/crates/gpui/src/interactive.rs index 6f396d31aa481571d3331e816f30dbf788d47816..dfccfc35307f1eb2e75e2d7e8fe8eb73b2c4b7ef 100644 --- a/crates/gpui/src/interactive.rs +++ b/crates/gpui/src/interactive.rs @@ -178,6 +178,20 @@ impl ScrollDelta { ScrollDelta::Lines(delta) => point(line_height * delta.x, line_height * delta.y), } } + + pub fn coalesce(self, other: ScrollDelta) -> ScrollDelta { + match (self, other) { + (ScrollDelta::Pixels(px_a), ScrollDelta::Pixels(px_b)) => { + ScrollDelta::Pixels(px_a + px_b) + } + + (ScrollDelta::Lines(lines_a), ScrollDelta::Lines(lines_b)) => { + ScrollDelta::Lines(lines_a + lines_b) + } + + _ => other, + } + } } #[derive(Clone, Debug, Default)]