diff --git a/crates/editor2/src/editor.rs b/crates/editor2/src/editor.rs index 6a73b5cf3a..4c26a914f7 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 b84aedd76a..4d8cd57abc 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, @@ -774,91 +777,72 @@ impl EditorElement { let line_end_overshoot = 0.15 * layout.position_map.line_height; let whitespace_setting = editor.buffer.read(cx).settings_at(0, cx).show_whitespaces; - // todo!("cursor region") - // cx.scene().push_cursor_region(CursorRegion { - // bounds, - // style: if !editor.link_go_to_definition_state.definitions.is_empty { - // CursorStyle::PointingHand - // } else { - // CursorStyle::IBeam - // }, - // }); + cx.with_content_mask(ContentMask { bounds }, |cx| { + // todo!("cursor region") + // cx.scene().push_cursor_region(CursorRegion { + // bounds, + // style: if !editor.link_go_to_definition_state.definitions.is_empty { + // CursorStyle::PointingHand + // } else { + // CursorStyle::IBeam + // }, + // }); - // todo!("fold ranges") - // let fold_corner_radius = - // self.style.folds.ellipses.corner_radius_factor * layout.position_map.line_height; - // for (id, range, color) in layout.fold_ranges.iter() { - // self.paint_highlighted_range( - // range.clone(), - // *color, - // fold_corner_radius, - // fold_corner_radius * 2., - // layout, - // content_origin, - // scroll_top, - // scroll_left, - // bounds, - // cx, - // ); + // todo!("fold ranges") + // let fold_corner_radius = + // self.style.folds.ellipses.corner_radius_factor * layout.position_map.line_height; + // for (id, range, color) in layout.fold_ranges.iter() { + // self.paint_highlighted_range( + // range.clone(), + // *color, + // fold_corner_radius, + // fold_corner_radius * 2., + // layout, + // content_origin, + // scroll_top, + // scroll_left, + // bounds, + // cx, + // ); - // for bound in range_to_bounds( - // &range, - // content_origin, - // scroll_left, - // scroll_top, - // &layout.visible_display_row_range, - // line_end_overshoot, - // &layout.position_map, - // ) { - // cx.scene().push_cursor_region(CursorRegion { - // bounds: bound, - // style: CursorStyle::PointingHand, - // }); + // for bound in range_to_bounds( + // &range, + // content_origin, + // scroll_left, + // scroll_top, + // &layout.visible_display_row_range, + // line_end_overshoot, + // &layout.position_map, + // ) { + // cx.scene().push_cursor_region(CursorRegion { + // bounds: bound, + // style: CursorStyle::PointingHand, + // }); - // let display_row = range.start.row(); + // let display_row = range.start.row(); - // let buffer_row = DisplayPoint::new(display_row, 0) - // .to_point(&layout.position_map.snapshot.display_snapshot) - // .row; + // let buffer_row = DisplayPoint::new(display_row, 0) + // .to_point(&layout.position_map.snapshot.display_snapshot) + // .row; - // let view_id = cx.view_id(); - // cx.scene().push_mouse_region( - // MouseRegion::new::(view_id, *id as usize, bound) - // .on_click(MouseButton::Left, move |_, editor: &mut Editor, cx| { - // editor.unfold_at(&UnfoldAt { buffer_row }, cx) - // }) - // .with_notify_on_hover(true) - // .with_notify_on_click(true), - // ) - // } - // } + // let view_id = cx.view_id(); + // cx.scene().push_mouse_region( + // MouseRegion::new::(view_id, *id as usize, bound) + // .on_click(MouseButton::Left, move |_, editor: &mut Editor, cx| { + // editor.unfold_at(&UnfoldAt { buffer_row }, cx) + // }) + // .with_notify_on_hover(true) + // .with_notify_on_click(true), + // ) + // } + // } - for (range, color) in &layout.highlighted_ranges { - self.paint_highlighted_range( - range.clone(), - *color, - Pixels::ZERO, - line_end_overshoot, - layout, - content_origin, - scroll_top, - scroll_left, - bounds, - cx, - ); - } - - let mut cursors = SmallVec::<[Cursor; 32]>::new(); - let corner_radius = 0.15 * layout.position_map.line_height; - let mut invisible_display_ranges = SmallVec::<[Range; 32]>::new(); - - for (selection_style, selections) in &layout.selections { - for selection in selections { + for (range, color) in &layout.highlighted_ranges { self.paint_highlighted_range( - selection.range.clone(), - selection_style.selection, - corner_radius, - corner_radius * 2., + range.clone(), + *color, + Pixels::ZERO, + line_end_overshoot, layout, content_origin, scroll_top, @@ -866,205 +850,226 @@ impl EditorElement { bounds, cx, ); + } - if selection.is_local && !selection.range.is_empty() { - invisible_display_ranges.push(selection.range.clone()); - } + let mut cursors = SmallVec::<[Cursor; 32]>::new(); + let corner_radius = 0.15 * layout.position_map.line_height; + let mut invisible_display_ranges = SmallVec::<[Range; 32]>::new(); - if !selection.is_local || editor.show_local_cursors(cx) { - let cursor_position = selection.head; - if layout - .visible_display_row_range - .contains(&cursor_position.row()) - { - let cursor_row_layout = &layout.position_map.line_layouts - [(cursor_position.row() - start_row) as usize] - .line; - let cursor_column = cursor_position.column() as usize; + for (selection_style, selections) in &layout.selections { + for selection in selections { + self.paint_highlighted_range( + selection.range.clone(), + selection_style.selection, + corner_radius, + corner_radius * 2., + layout, + content_origin, + scroll_top, + scroll_left, + bounds, + cx, + ); - let cursor_character_x = cursor_row_layout.x_for_index(cursor_column); - let mut block_width = - cursor_row_layout.x_for_index(cursor_column + 1) - cursor_character_x; - if block_width == Pixels::ZERO { - block_width = layout.position_map.em_width; + if selection.is_local && !selection.range.is_empty() { + invisible_display_ranges.push(selection.range.clone()); + } + + if !selection.is_local || editor.show_local_cursors(cx) { + let cursor_position = selection.head; + if layout + .visible_display_row_range + .contains(&cursor_position.row()) + { + let cursor_row_layout = &layout.position_map.line_layouts + [(cursor_position.row() - start_row) as usize] + .line; + let cursor_column = cursor_position.column() as usize; + + let cursor_character_x = cursor_row_layout.x_for_index(cursor_column); + let mut block_width = cursor_row_layout.x_for_index(cursor_column + 1) + - cursor_character_x; + if block_width == Pixels::ZERO { + block_width = layout.position_map.em_width; + } + let block_text = if let CursorShape::Block = selection.cursor_shape { + layout + .position_map + .snapshot + .chars_at(cursor_position) + .next() + .and_then(|(character, _)| { + let text = character.to_string(); + cx.text_system() + .layout_text( + &text, + cursor_row_layout.font_size, + &[TextRun { + len: text.len(), + font: self.style.text.font(), + color: self.style.background, + underline: None, + }], + None, + ) + .unwrap() + .pop() + }) + } else { + None + }; + + let x = cursor_character_x - scroll_left; + let y = cursor_position.row() as f32 * layout.position_map.line_height + - scroll_top; + if selection.is_newest { + editor.pixel_position_of_newest_cursor = Some(point( + bounds.origin.x + x + block_width / 2., + bounds.origin.y + y + layout.position_map.line_height / 2., + )); + } + cursors.push(Cursor { + color: selection_style.cursor, + block_width, + origin: point(x, y), + line_height: layout.position_map.line_height, + shape: selection.cursor_shape, + block_text, + }); } - let block_text = if let CursorShape::Block = selection.cursor_shape { - layout - .position_map - .snapshot - .chars_at(cursor_position) - .next() - .and_then(|(character, _)| { - let text = character.to_string(); - cx.text_system() - .layout_text( - &text, - cursor_row_layout.font_size, - &[TextRun { - len: text.len(), - font: self.style.text.font(), - color: self.style.background, - underline: None, - }], - None, - ) - .unwrap() - .pop() - }) - } else { - None - }; - - let x = cursor_character_x - scroll_left; - let y = cursor_position.row() as f32 * layout.position_map.line_height - - scroll_top; - if selection.is_newest { - editor.pixel_position_of_newest_cursor = Some(point( - bounds.origin.x + x + block_width / 2., - bounds.origin.y + y + layout.position_map.line_height / 2., - )); - } - cursors.push(Cursor { - color: selection_style.cursor, - block_width, - origin: point(x, y), - line_height: layout.position_map.line_height, - shape: selection.cursor_shape, - block_text, - }); } } } - } - for (ix, line_with_invisibles) in layout.position_map.line_layouts.iter().enumerate() { - let row = start_row + ix as u32; - line_with_invisibles.draw( - layout, - row, - scroll_top, - content_origin, - scroll_left, - whitespace_setting, - &invisible_display_ranges, - cx, - ) - } - - cx.stack(9999, |cx| { - for cursor in cursors { - cursor.paint(content_origin, cx); + for (ix, line_with_invisibles) in layout.position_map.line_layouts.iter().enumerate() { + let row = start_row + ix as u32; + line_with_invisibles.draw( + layout, + row, + scroll_top, + content_origin, + scroll_left, + whitespace_setting, + &invisible_display_ranges, + cx, + ) } - }); - // cx.scene().push_layer(Some(bounds)); - // cx.scene().pop_layer(); + cx.stack(0, |cx| { + for cursor in cursors { + cursor.paint(content_origin, cx); + } + }); + // cx.scene().push_layer(Some(bounds)); - // if let Some((position, context_menu)) = layout.context_menu.as_mut() { - // cx.scene().push_stacking_context(None, None); - // let cursor_row_layout = - // &layout.position_map.line_layouts[(position.row() - start_row) as usize].line; - // let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left; - // let y = (position.row() + 1) as f32 * layout.position_map.line_height - scroll_top; - // let mut list_origin = content_origin + point(x, y); - // let list_width = context_menu.size().x; - // let list_height = context_menu.size().y; + // cx.scene().pop_layer(); - // // Snap the right edge of the list to the right edge of the window if - // // its horizontal bounds overflow. - // if list_origin.x + list_width > cx.window_size().x { - // list_origin.set_x((cx.window_size().x - list_width).max(0.)); - // } + // if let Some((position, context_menu)) = layout.context_menu.as_mut() { + // cx.scene().push_stacking_context(None, None); + // let cursor_row_layout = + // &layout.position_map.line_layouts[(position.row() - start_row) as usize].line; + // let x = cursor_row_layout.x_for_index(position.column() as usize) - scroll_left; + // let y = (position.row() + 1) as f32 * layout.position_map.line_height - scroll_top; + // let mut list_origin = content_origin + point(x, y); + // let list_width = context_menu.size().x; + // let list_height = context_menu.size().y; - // if list_origin.y + list_height > bounds.max_y { - // list_origin - // .set_y(list_origin.y - layout.position_map.line_height - list_height); - // } + // // Snap the right edge of the list to the right edge of the window if + // // its horizontal bounds overflow. + // if list_origin.x + list_width > cx.window_size().x { + // list_origin.set_x((cx.window_size().x - list_width).max(0.)); + // } - // context_menu.paint( - // list_origin, - // Bounds::::from_points( - // gpui::Point::::zero(), - // point(f32::MAX, f32::MAX), - // ), // Let content bleed outside of editor - // editor, - // cx, - // ); + // if list_origin.y + list_height > bounds.max_y { + // list_origin + // .set_y(list_origin.y - layout.position_map.line_height - list_height); + // } - // cx.scene().pop_stacking_context(); - // } + // context_menu.paint( + // list_origin, + // Bounds::::from_points( + // gpui::Point::::zero(), + // point(f32::MAX, f32::MAX), + // ), // Let content bleed outside of editor + // editor, + // cx, + // ); - // if let Some((position, hover_popovers)) = layout.hover_popovers.as_mut() { - // cx.scene().push_stacking_context(None, None); + // cx.scene().pop_stacking_context(); + // } - // // This is safe because we check on layout whether the required row is available - // let hovered_row_layout = - // &layout.position_map.line_layouts[(position.row() - start_row) as usize].line; + // if let Some((position, hover_popovers)) = layout.hover_popovers.as_mut() { + // cx.scene().push_stacking_context(None, None); - // // Minimum required size: Take the first popover, and add 1.5 times the minimum popover - // // height. This is the size we will use to decide whether to render popovers above or below - // // the hovered line. - // let first_size = hover_popovers[0].size(); - // let height_to_reserve = first_size.y - // + 1.5 * MIN_POPOVER_LINE_HEIGHT as f32 * layout.position_map.line_height; + // // This is safe because we check on layout whether the required row is available + // let hovered_row_layout = + // &layout.position_map.line_layouts[(position.row() - start_row) as usize].line; - // // Compute Hovered Point - // let x = hovered_row_layout.x_for_index(position.column() as usize) - scroll_left; - // let y = position.row() as f32 * layout.position_map.line_height - scroll_top; - // let hovered_point = content_origin + point(x, y); + // // Minimum required size: Take the first popover, and add 1.5 times the minimum popover + // // height. This is the size we will use to decide whether to render popovers above or below + // // the hovered line. + // let first_size = hover_popovers[0].size(); + // let height_to_reserve = first_size.y + // + 1.5 * MIN_POPOVER_LINE_HEIGHT as f32 * layout.position_map.line_height; - // if hovered_point.y - height_to_reserve > 0.0 { - // // There is enough space above. Render popovers above the hovered point - // let mut current_y = hovered_point.y; - // for hover_popover in hover_popovers { - // let size = hover_popover.size(); - // let mut popover_origin = point(hovered_point.x, current_y - size.y); + // // Compute Hovered Point + // let x = hovered_row_layout.x_for_index(position.column() as usize) - scroll_left; + // let y = position.row() as f32 * layout.position_map.line_height - scroll_top; + // let hovered_point = content_origin + point(x, y); - // let x_out_of_bounds = bounds.max_x - (popover_origin.x + size.x); - // if x_out_of_bounds < 0.0 { - // popover_origin.set_x(popover_origin.x + x_out_of_bounds); - // } + // if hovered_point.y - height_to_reserve > 0.0 { + // // There is enough space above. Render popovers above the hovered point + // let mut current_y = hovered_point.y; + // for hover_popover in hover_popovers { + // let size = hover_popover.size(); + // let mut popover_origin = point(hovered_point.x, current_y - size.y); - // hover_popover.paint( - // popover_origin, - // Bounds::::from_points( - // gpui::Point::::zero(), - // point(f32::MAX, f32::MAX), - // ), // Let content bleed outside of editor - // editor, - // cx, - // ); + // let x_out_of_bounds = bounds.max_x - (popover_origin.x + size.x); + // if x_out_of_bounds < 0.0 { + // popover_origin.set_x(popover_origin.x + x_out_of_bounds); + // } - // current_y = popover_origin.y - HOVER_POPOVER_GAP; - // } - // } else { - // // There is not enough space above. Render popovers below the hovered point - // let mut current_y = hovered_point.y + layout.position_map.line_height; - // for hover_popover in hover_popovers { - // let size = hover_popover.size(); - // let mut popover_origin = point(hovered_point.x, current_y); + // hover_popover.paint( + // popover_origin, + // Bounds::::from_points( + // gpui::Point::::zero(), + // point(f32::MAX, f32::MAX), + // ), // Let content bleed outside of editor + // editor, + // cx, + // ); - // let x_out_of_bounds = bounds.max_x - (popover_origin.x + size.x); - // if x_out_of_bounds < 0.0 { - // popover_origin.set_x(popover_origin.x + x_out_of_bounds); - // } + // current_y = popover_origin.y - HOVER_POPOVER_GAP; + // } + // } else { + // // There is not enough space above. Render popovers below the hovered point + // let mut current_y = hovered_point.y + layout.position_map.line_height; + // for hover_popover in hover_popovers { + // let size = hover_popover.size(); + // let mut popover_origin = point(hovered_point.x, current_y); - // hover_popover.paint( - // popover_origin, - // Bounds::::from_points( - // gpui::Point::::zero(), - // point(f32::MAX, f32::MAX), - // ), // Let content bleed outside of editor - // editor, - // cx, - // ); + // let x_out_of_bounds = bounds.max_x - (popover_origin.x + size.x); + // if x_out_of_bounds < 0.0 { + // popover_origin.set_x(popover_origin.x + x_out_of_bounds); + // } - // current_y = popover_origin.y + size.y + HOVER_POPOVER_GAP; - // } - // } + // hover_popover.paint( + // popover_origin, + // Bounds::::from_points( + // gpui::Point::::zero(), + // point(f32::MAX, f32::MAX), + // ), // Let content bleed outside of editor + // editor, + // cx, + // ); - // cx.scene().pop_stacking_context(); - // } + // current_y = popover_origin.y + size.y + HOVER_POPOVER_GAP; + // } + // } + + // cx.scene().pop_stacking_context(); + // } + }) } fn scrollbar_left(&self, bounds: &Bounds) -> Pixels { @@ -2573,6 +2578,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 ba39d3849b..5ea502c456 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 930ba4db6f..e16635be36 100644 --- a/crates/gpui2/src/geometry.rs +++ b/crates/gpui2/src/geometry.rs @@ -124,6 +124,10 @@ where }, } } + + pub fn clamp(&self, min: &Self, max: &Self) -> Self { + self.max(min).min(max) + } } impl Clone for Point {