diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index b3df31024883aa8a80f9068fb3e4e7bd18669ef5..fb7d84e17338d8a2b1812e818440b6a70b285fad 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -1248,7 +1248,7 @@ impl EditorElement { let bottom = bounds.lower_left().y; let right = bounds.lower_right().x; let left = self.scrollbar_left(&bounds); - let row_range = &layout.scrollbar_row_range; + let row_range = layout.scrollbar_row_range.clone(); let max_row = layout.max_row as f32 + (row_range.end - row_range.start); let mut height = bounds.size.height; @@ -1369,53 +1369,80 @@ impl EditorElement { ); } - // cx.scene().push_cursor_region(CursorRegion { - // bounds: track_bounds, - // style: CursorStyle::Arrow, - // }); - // let region_id = cx.view_id(); - // cx.scene().push_mouse_region( - // MouseRegion::new::(region_id, region_id, track_bounds) - // .on_move(move |event, editor: &mut Editor, cx| { - // if event.pressed_button.is_none() { - // editor.scroll_manager.show_scrollbar(cx); - // } - // }) - // .on_down(MouseButton::Left, { - // let row_range = row_range.clone(); - // move |event, editor: &mut Editor, cx| { - // let y = event.position.y; - // if y < thumb_top || thumb_bottom < y { - // let center_row = ((y - top) * max_row as f32 / height).round() as u32; - // let top_row = center_row - // .saturating_sub((row_range.end - row_range.start) as u32 / 2); - // let mut position = editor.scroll_position(cx); - // position.set_y(top_row as f32); - // editor.set_scroll_position(position, cx); - // } else { - // editor.scroll_manager.show_scrollbar(cx); - // } - // } - // }) - // .on_drag(MouseButton::Left, { - // move |event, editor: &mut Editor, cx| { - // if event.end { - // return; - // } - - // let y = event.prev_mouse_position.y; - // let new_y = event.position.y; - // if thumb_top < y && y < thumb_bottom { - // let mut position = editor.scroll_position(cx); - // position.set_y(position.y + (new_y - y) * (max_row as f32) / height); - // if position.y < 0.0 { - // position.set_y(0.); - // } - // editor.set_scroll_position(position, cx); - // } - // } - // }), - // ); + let mouse_position = cx.mouse_position(); + if track_bounds.contains_point(&mouse_position) { + cx.set_cursor_style(CursorStyle::Arrow); + } + + cx.on_mouse_event({ + let editor = self.editor.clone(); + move |event: &MouseMoveEvent, phase, cx| { + if phase == DispatchPhase::Capture { + return; + } + + editor.update(cx, |editor, cx| { + if event.pressed_button == Some(MouseButton::Left) + && editor.scroll_manager.is_dragging_scrollbar() + { + let y = mouse_position.y; + let new_y = event.position.y; + if thumb_top < y && y < thumb_bottom { + let mut position = editor.scroll_position(cx); + position.y += (new_y - y) * (max_row as f32) / height; + if position.y < 0.0 { + position.y = 0.0; + } + editor.set_scroll_position(position, cx); + } + cx.stop_propagation(); + } else { + editor.scroll_manager.set_is_dragging_scrollbar(false, cx); + if track_bounds.contains_point(&event.position) { + editor.scroll_manager.show_scrollbar(cx); + } + } + }) + } + }); + + if self.editor.read(cx).scroll_manager.is_dragging_scrollbar() { + cx.on_mouse_event({ + let editor = self.editor.clone(); + move |event: &MouseUpEvent, phase, cx| { + editor.update(cx, |editor, cx| { + editor.scroll_manager.set_is_dragging_scrollbar(false, cx); + cx.stop_propagation(); + }); + } + }); + } else { + cx.on_mouse_event({ + let editor = self.editor.clone(); + move |event: &MouseDownEvent, phase, cx| { + editor.update(cx, |editor, cx| { + if track_bounds.contains_point(&event.position) { + editor.scroll_manager.set_is_dragging_scrollbar(true, cx); + + let y = event.position.y; + if y < thumb_top || thumb_bottom < y { + let center_row = + ((y - top) * max_row as f32 / height).round() as u32; + let top_row = center_row + .saturating_sub((row_range.end - row_range.start) as u32 / 2); + let mut position = editor.scroll_position(cx); + position.y = top_row as f32; + editor.set_scroll_position(position, cx); + } else { + editor.scroll_manager.show_scrollbar(cx); + } + + cx.stop_propagation(); + } + }); + } + }); + } } #[allow(clippy::too_many_arguments)] @@ -2819,7 +2846,7 @@ impl Element for EditorElement { }) } - self.paint_scrollbar(bounds, &mut layout, cx); + cx.with_z_index(2, |cx| self.paint_scrollbar(bounds, &mut layout, cx)); }); }); }) diff --git a/crates/editor2/src/scroll.rs b/crates/editor2/src/scroll.rs index d73f6a4d6aecd6517a2e9666a96bd09d7091b159..208dcc0dd3c9c75755176961386ffceb35892c6b 100644 --- a/crates/editor2/src/scroll.rs +++ b/crates/editor2/src/scroll.rs @@ -136,6 +136,7 @@ pub struct ScrollManager { last_autoscroll: Option<(gpui::Point, f32, f32, AutoscrollStrategy)>, show_scrollbars: bool, hide_scrollbar_task: Option>, + dragging_scrollbar: bool, visible_line_count: Option, } @@ -148,6 +149,7 @@ impl ScrollManager { autoscroll_request: None, show_scrollbars: true, hide_scrollbar_task: None, + dragging_scrollbar: false, last_autoscroll: None, visible_line_count: None, } @@ -278,6 +280,17 @@ impl ScrollManager { self.autoscroll_request.is_some() } + pub fn is_dragging_scrollbar(&self) -> bool { + self.dragging_scrollbar + } + + pub fn set_is_dragging_scrollbar(&mut self, dragging: bool, cx: &mut ViewContext) { + if dragging != self.dragging_scrollbar { + self.dragging_scrollbar = dragging; + cx.notify(); + } + } + pub fn clamp_scroll_left(&mut self, max: f32) -> bool { if max < self.anchor.offset.x { self.anchor.offset.x = max;