From b9e98c112fe4423bc950832092fec63d0f3d3658 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Tue, 7 Nov 2023 15:48:08 +0100 Subject: [PATCH] Re-enable scrolling for `EditorElement` Co-Authored-By: Julia Co-Authored-By: Piotr --- crates/editor2/src/editor.rs | 6 +- crates/editor2/src/element.rs | 81 +++++++----- crates/editor2/src/scroll/actions.rs | 188 ++++++++++++++------------- crates/gpui2/src/geometry.rs | 4 + 4 files changed, 151 insertions(+), 128 deletions(-) diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index be8375336c604f9ca87f390128ab01c3991b37f1..7a2511fa6dc1d6144a43618fe1dbd6bc7b01b394 100644 --- a/crates/editor2/src/editor.rs +++ b/crates/editor2/src/editor.rs @@ -36,9 +36,9 @@ pub use element::{ use futures::FutureExt; use fuzzy::{StringMatch, StringMatchCandidate}; use gpui::{ - div, px, AnyElement, AppContext, BackgroundExecutor, Context, Div, Element, EventEmitter, - FocusHandle, FontStyle, FontWeight, Hsla, Model, Pixels, Render, Styled, Subscription, Task, - TextStyle, View, ViewContext, VisualContext, WeakView, WindowContext, + div, px, AnyElement, AppContext, BackgroundExecutor, Context, Div, Element, Entity, + EventEmitter, FocusHandle, FontStyle, FontWeight, Hsla, Model, Pixels, Render, Styled, + Subscription, Task, TextStyle, View, ViewContext, VisualContext, WeakView, WindowContext, }; use highlight_matching_bracket::refresh_matching_bracket_highlights; use hover_popover::{hide_hover, HoverState}; diff --git a/crates/editor2/src/element.rs b/crates/editor2/src/element.rs index b84aedd76a1d8d68f7431304d17444b68b935f77..3561aca657e60cdd2391cfa8f1d1208ee5d0a1c9 100644 --- a/crates/editor2/src/element.rs +++ b/crates/editor2/src/element.rs @@ -9,8 +9,9 @@ use anyhow::Result; use collections::{BTreeMap, HashMap}; use gpui::{ black, hsla, point, px, relative, size, transparent_black, AnyElement, BorrowWindow, Bounds, - ContentMask, Corners, Edges, Element, Hsla, Line, Pixels, ShapedGlyph, Size, Style, TextRun, - TextStyle, TextSystem, ViewContext, WindowContext, + ContentMask, Corners, DispatchPhase, Edges, Element, ElementId, Hsla, Line, Pixels, + ScrollWheelEvent, ShapedGlyph, Size, StatefulInteraction, Style, TextRun, TextStyle, + TextSystem, ViewContext, WindowContext, }; use itertools::Itertools; use language::language_settings::ShowWhitespaceSetting; @@ -464,39 +465,41 @@ impl EditorElement { // true // } - // fn scroll( - // editor: &mut Editor, - // position: gpui::Point, - // mut delta: gpui::Point, - // precise: bool, - // position_map: &PositionMap, - // bounds: Bounds, - // cx: &mut ViewContext, - // ) -> bool { - // if !bounds.contains_point(position) { - // return false; - // } + fn scroll( + editor: &mut Editor, + event: &ScrollWheelEvent, + position_map: &PositionMap, + bounds: Bounds, + cx: &mut ViewContext, + ) -> bool { + if !bounds.contains_point(&event.position) { + return false; + } - // let line_height = position_map.line_height; - // let max_glyph_width = position_map.em_width; + 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) + } - // let axis = if precise { - // //Trackpad - // position_map.snapshot.ongoing_scroll.filter(&mut delta) - // } else { - // //Not trackpad - // delta *= point(max_glyph_width, line_height); - // None //Resets ongoing scroll - // }; + 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 = (scroll_position.x * max_glyph_width - delta.x) / max_glyph_width; - // let y = (scroll_position.y * line_height - delta.y) / line_height; - // let scroll_position = point(x, y).clamp(gpui::Point::::zero(), position_map.scroll_max); - // editor.scroll(scroll_position, axis, cx); + 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); - // true - // } + true + } fn paint_background( &self, @@ -951,7 +954,7 @@ impl EditorElement { ) } - cx.stack(9999, |cx| { + cx.stack(0, |cx| { for cursor in cursors { cursor.paint(content_origin, cx); } @@ -2573,6 +2576,20 @@ impl Element for EditorElement { cx: &mut gpui::ViewContext, ) { let layout = self.compute_layout(editor, cx, bounds); + + cx.on_mouse_event({ + let position_map = layout.position_map.clone(); + move |editor, event: &ScrollWheelEvent, phase, cx| { + if phase != DispatchPhase::Bubble { + return; + } + + if Self::scroll(editor, event, &position_map, bounds, cx) { + cx.stop_propagation(); + } + } + }); + cx.with_content_mask(ContentMask { bounds }, |cx| { let gutter_bounds = Bounds { origin: bounds.origin, diff --git a/crates/editor2/src/scroll/actions.rs b/crates/editor2/src/scroll/actions.rs index ba39d3849bab612489d40c53a4dca0a346eefb29..5ea502c456b0c2f73f24dc05833f9864ee97f90d 100644 --- a/crates/editor2/src/scroll/actions.rs +++ b/crates/editor2/src/scroll/actions.rs @@ -1,4 +1,6 @@ -use gpui::AppContext; +use super::Axis; +use crate::Editor; +use gpui::{AppContext, Point, ViewContext}; // actions!( // editor, @@ -42,107 +44,107 @@ pub fn init(cx: &mut AppContext) { // }); } -// impl Editor { -// pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext) -> Option<()> { -// if self.take_rename(true, cx).is_some() { -// return None; -// } +impl Editor { + // pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext) -> Option<()> { + // if self.take_rename(true, cx).is_some() { + // return None; + // } -// if self.mouse_context_menu.read(cx).visible() { -// return None; -// } + // if self.mouse_context_menu.read(cx).visible() { + // return None; + // } -// if matches!(self.mode, EditorMode::SingleLine) { -// cx.propagate_action(); -// return None; -// } -// self.request_autoscroll(Autoscroll::Next, cx); -// Some(()) -// } + // if matches!(self.mode, EditorMode::SingleLine) { + // cx.propagate_action(); + // return None; + // } + // self.request_autoscroll(Autoscroll::Next, cx); + // Some(()) + // } -// pub fn scroll( -// &mut self, -// scroll_position: Vector2F, -// axis: Option, -// cx: &mut ViewContext, -// ) { -// self.scroll_manager.update_ongoing_scroll(axis); -// self.set_scroll_position(scroll_position, cx); -// } + pub fn scroll( + &mut self, + scroll_position: Point, + axis: Option, + cx: &mut ViewContext, + ) { + self.scroll_manager.update_ongoing_scroll(axis); + self.set_scroll_position(scroll_position, cx); + } -// fn scroll_cursor_top(editor: &mut Editor, _: &ScrollCursorTop, cx: &mut ViewContext) { -// let snapshot = editor.snapshot(cx).display_snapshot; -// let scroll_margin_rows = editor.vertical_scroll_margin() as u32; + // fn scroll_cursor_top(editor: &mut Editor, _: &ScrollCursorTop, cx: &mut ViewContext) { + // let snapshot = editor.snapshot(cx).display_snapshot; + // let scroll_margin_rows = editor.vertical_scroll_margin() as u32; -// let mut new_screen_top = editor.selections.newest_display(cx).head(); -// *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(scroll_margin_rows); -// *new_screen_top.column_mut() = 0; -// let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left); -// let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top); + // let mut new_screen_top = editor.selections.newest_display(cx).head(); + // *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(scroll_margin_rows); + // *new_screen_top.column_mut() = 0; + // let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left); + // let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top); -// editor.set_scroll_anchor( -// ScrollAnchor { -// anchor: new_anchor, -// offset: Default::default(), -// }, -// cx, -// ) -// } + // editor.set_scroll_anchor( + // ScrollAnchor { + // anchor: new_anchor, + // offset: Default::default(), + // }, + // cx, + // ) + // } -// fn scroll_cursor_center( -// editor: &mut Editor, -// _: &ScrollCursorCenter, -// cx: &mut ViewContext, -// ) { -// let snapshot = editor.snapshot(cx).display_snapshot; -// let visible_rows = if let Some(visible_rows) = editor.visible_line_count() { -// visible_rows as u32 -// } else { -// return; -// }; + // fn scroll_cursor_center( + // editor: &mut Editor, + // _: &ScrollCursorCenter, + // cx: &mut ViewContext, + // ) { + // let snapshot = editor.snapshot(cx).display_snapshot; + // let visible_rows = if let Some(visible_rows) = editor.visible_line_count() { + // visible_rows as u32 + // } else { + // return; + // }; -// let mut new_screen_top = editor.selections.newest_display(cx).head(); -// *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(visible_rows / 2); -// *new_screen_top.column_mut() = 0; -// let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left); -// let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top); + // let mut new_screen_top = editor.selections.newest_display(cx).head(); + // *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(visible_rows / 2); + // *new_screen_top.column_mut() = 0; + // let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left); + // let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top); -// editor.set_scroll_anchor( -// ScrollAnchor { -// anchor: new_anchor, -// offset: Default::default(), -// }, -// cx, -// ) -// } + // editor.set_scroll_anchor( + // ScrollAnchor { + // anchor: new_anchor, + // offset: Default::default(), + // }, + // cx, + // ) + // } -// fn scroll_cursor_bottom( -// editor: &mut Editor, -// _: &ScrollCursorBottom, -// cx: &mut ViewContext, -// ) { -// let snapshot = editor.snapshot(cx).display_snapshot; -// let scroll_margin_rows = editor.vertical_scroll_margin() as u32; -// let visible_rows = if let Some(visible_rows) = editor.visible_line_count() { -// visible_rows as u32 -// } else { -// return; -// }; + // fn scroll_cursor_bottom( + // editor: &mut Editor, + // _: &ScrollCursorBottom, + // cx: &mut ViewContext, + // ) { + // let snapshot = editor.snapshot(cx).display_snapshot; + // let scroll_margin_rows = editor.vertical_scroll_margin() as u32; + // let visible_rows = if let Some(visible_rows) = editor.visible_line_count() { + // visible_rows as u32 + // } else { + // return; + // }; -// let mut new_screen_top = editor.selections.newest_display(cx).head(); -// *new_screen_top.row_mut() = new_screen_top -// .row() -// .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows)); -// *new_screen_top.column_mut() = 0; -// let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left); -// let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top); + // let mut new_screen_top = editor.selections.newest_display(cx).head(); + // *new_screen_top.row_mut() = new_screen_top + // .row() + // .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows)); + // *new_screen_top.column_mut() = 0; + // let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left); + // let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top); -// editor.set_scroll_anchor( -// ScrollAnchor { -// anchor: new_anchor, -// offset: Default::default(), -// }, -// cx, -// ) -// } -// } + // editor.set_scroll_anchor( + // ScrollAnchor { + // anchor: new_anchor, + // offset: Default::default(), + // }, + // cx, + // ) + // } +} diff --git a/crates/gpui2/src/geometry.rs b/crates/gpui2/src/geometry.rs index e26e6e2eccf0bbecc3813977cdc60dea35d5a20f..41f594ade2cdebcede44eef44f51ef108d4b9f14 100644 --- a/crates/gpui2/src/geometry.rs +++ b/crates/gpui2/src/geometry.rs @@ -120,6 +120,10 @@ where }, } } + + pub fn clamp(&self, min: &Self, max: &Self) -> Self { + self.max(min).min(max) + } } impl Clone for Point {