Compare commits
9 commits
main
...
scroll-man
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ac307dd836 | ||
![]() |
b24f75663d | ||
![]() |
638eceda0e | ||
![]() |
9553650588 | ||
![]() |
10f5d616a4 | ||
![]() |
e68a84e027 | ||
![]() |
bd4098ca2d | ||
![]() |
86324b0935 | ||
![]() |
a70c76ce8b |
4 changed files with 103 additions and 73 deletions
|
@ -3695,7 +3695,7 @@ impl Editor {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.apply_scroll_delta(scroll_delta, window, cx);
|
self.apply_scroll_delta(scroll_delta, &display_map, window, cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1018,7 +1018,7 @@ impl EditorElement {
|
||||||
drop_cursor.start = drop_anchor;
|
drop_cursor.start = drop_anchor;
|
||||||
drop_cursor.end = drop_anchor;
|
drop_cursor.end = drop_anchor;
|
||||||
*hide_drop_cursor = !text_hitbox.is_hovered(window);
|
*hide_drop_cursor = !text_hitbox.is_hovered(window);
|
||||||
editor.apply_scroll_delta(scroll_delta, window, cx);
|
editor.apply_scroll_delta(scroll_delta, &position_map.snapshot, window, cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
SelectionDragState::ReadyToDrag {
|
SelectionDragState::ReadyToDrag {
|
||||||
|
@ -1042,7 +1042,7 @@ impl EditorElement {
|
||||||
drop_cursor,
|
drop_cursor,
|
||||||
hide_drop_cursor: false,
|
hide_drop_cursor: false,
|
||||||
};
|
};
|
||||||
editor.apply_scroll_delta(scroll_delta, window, cx);
|
editor.apply_scroll_delta(scroll_delta, &position_map.snapshot, window, cx);
|
||||||
cx.notify();
|
cx.notify();
|
||||||
} else {
|
} else {
|
||||||
let click_point = position_map.point_for_position(*click_position);
|
let click_point = position_map.point_for_position(*click_position);
|
||||||
|
@ -8060,7 +8060,14 @@ impl Element for EditorElement {
|
||||||
autoscroll_request.is_some() || editor.has_pending_selection();
|
autoscroll_request.is_some() || editor.has_pending_selection();
|
||||||
|
|
||||||
let (needs_horizontal_autoscroll, was_scrolled) = editor
|
let (needs_horizontal_autoscroll, was_scrolled) = editor
|
||||||
.autoscroll_vertically(bounds, line_height, max_scroll_top, window, cx);
|
.autoscroll_vertically(
|
||||||
|
bounds,
|
||||||
|
line_height,
|
||||||
|
max_scroll_top,
|
||||||
|
&snapshot,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
);
|
||||||
if was_scrolled.0 {
|
if was_scrolled.0 {
|
||||||
snapshot = editor.snapshot(window, cx);
|
snapshot = editor.snapshot(window, cx);
|
||||||
}
|
}
|
||||||
|
@ -8496,6 +8503,7 @@ impl Element for EditorElement {
|
||||||
scroll_width,
|
scroll_width,
|
||||||
em_advance,
|
em_advance,
|
||||||
&line_layouts,
|
&line_layouts,
|
||||||
|
&snapshot,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
)
|
)
|
||||||
|
|
|
@ -211,10 +211,10 @@ impl ScrollManager {
|
||||||
fn set_scroll_position(
|
fn set_scroll_position(
|
||||||
&mut self,
|
&mut self,
|
||||||
scroll_position: gpui::Point<f32>,
|
scroll_position: gpui::Point<f32>,
|
||||||
map: &DisplaySnapshot,
|
|
||||||
local: bool,
|
local: bool,
|
||||||
autoscroll: bool,
|
autoscroll: bool,
|
||||||
workspace_id: Option<WorkspaceId>,
|
workspace_id: Option<WorkspaceId>,
|
||||||
|
display_snapshot: &DisplaySnapshot,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Editor>,
|
cx: &mut Context<Editor>,
|
||||||
) -> WasScrolled {
|
) -> WasScrolled {
|
||||||
|
@ -223,7 +223,7 @@ impl ScrollManager {
|
||||||
ScrollBeyondLastLine::OnePage => scroll_top,
|
ScrollBeyondLastLine::OnePage => scroll_top,
|
||||||
ScrollBeyondLastLine::Off => {
|
ScrollBeyondLastLine::Off => {
|
||||||
if let Some(height_in_lines) = self.visible_line_count {
|
if let Some(height_in_lines) = self.visible_line_count {
|
||||||
let max_row = map.max_point().row().0 as f32;
|
let max_row = display_snapshot.max_point().row().0 as f32;
|
||||||
scroll_top.min(max_row - height_in_lines + 1.).max(0.)
|
scroll_top.min(max_row - height_in_lines + 1.).max(0.)
|
||||||
} else {
|
} else {
|
||||||
scroll_top
|
scroll_top
|
||||||
|
@ -231,7 +231,7 @@ impl ScrollManager {
|
||||||
}
|
}
|
||||||
ScrollBeyondLastLine::VerticalScrollMargin => {
|
ScrollBeyondLastLine::VerticalScrollMargin => {
|
||||||
if let Some(height_in_lines) = self.visible_line_count {
|
if let Some(height_in_lines) = self.visible_line_count {
|
||||||
let max_row = map.max_point().row().0 as f32;
|
let max_row = display_snapshot.max_point().row().0 as f32;
|
||||||
scroll_top
|
scroll_top
|
||||||
.min(max_row - height_in_lines + 1. + self.vertical_scroll_margin)
|
.min(max_row - height_in_lines + 1. + self.vertical_scroll_margin)
|
||||||
.max(0.)
|
.max(0.)
|
||||||
|
@ -242,13 +242,13 @@ impl ScrollManager {
|
||||||
};
|
};
|
||||||
|
|
||||||
let scroll_top_row = DisplayRow(scroll_top as u32);
|
let scroll_top_row = DisplayRow(scroll_top as u32);
|
||||||
let scroll_top_buffer_point = map
|
let scroll_top_buffer_point = display_snapshot
|
||||||
.clip_point(
|
.clip_point(
|
||||||
DisplayPoint::new(scroll_top_row, scroll_position.x as u32),
|
DisplayPoint::new(scroll_top_row, scroll_position.x as u32),
|
||||||
Bias::Left,
|
Bias::Left,
|
||||||
)
|
)
|
||||||
.to_point(map);
|
.to_point(display_snapshot);
|
||||||
let top_anchor = map
|
let top_anchor = display_snapshot
|
||||||
.buffer_snapshot
|
.buffer_snapshot
|
||||||
.anchor_at(scroll_top_buffer_point, Bias::Right);
|
.anchor_at(scroll_top_buffer_point, Bias::Right);
|
||||||
|
|
||||||
|
@ -257,7 +257,7 @@ impl ScrollManager {
|
||||||
anchor: top_anchor,
|
anchor: top_anchor,
|
||||||
offset: point(
|
offset: point(
|
||||||
scroll_position.x.max(0.),
|
scroll_position.x.max(0.),
|
||||||
scroll_top - top_anchor.to_display_point(map).row().as_f32(),
|
scroll_top - top_anchor.to_display_point(display_snapshot).row().as_f32(),
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
scroll_top_buffer_point.row,
|
scroll_top_buffer_point.row,
|
||||||
|
@ -512,6 +512,7 @@ impl Editor {
|
||||||
pub fn apply_scroll_delta(
|
pub fn apply_scroll_delta(
|
||||||
&mut self,
|
&mut self,
|
||||||
scroll_delta: gpui::Point<f32>,
|
scroll_delta: gpui::Point<f32>,
|
||||||
|
display_snapshot: &DisplaySnapshot,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
|
@ -519,9 +520,8 @@ impl Editor {
|
||||||
if self.scroll_manager.forbid_vertical_scroll {
|
if self.scroll_manager.forbid_vertical_scroll {
|
||||||
delta.y = 0.0;
|
delta.y = 0.0;
|
||||||
}
|
}
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let position = self.scroll_manager.anchor.scroll_position(display_snapshot) + delta;
|
||||||
let position = self.scroll_manager.anchor.scroll_position(&display_map) + delta;
|
self.set_scroll_position_internal(position, true, false, display_snapshot, window, cx);
|
||||||
self.set_scroll_position_taking_display_map(position, true, false, display_map, window, cx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_scroll_position(
|
pub fn set_scroll_position(
|
||||||
|
@ -535,7 +535,17 @@ impl Editor {
|
||||||
let current_position = self.scroll_position(cx);
|
let current_position = self.scroll_position(cx);
|
||||||
position.y = current_position.y;
|
position.y = current_position.y;
|
||||||
}
|
}
|
||||||
self.set_scroll_position_internal(position, true, false, window, cx)
|
if let Some(display_snapshot) = self
|
||||||
|
.last_position_map
|
||||||
|
.clone()
|
||||||
|
.as_ref()
|
||||||
|
.map(|position_map| &position_map.snapshot)
|
||||||
|
{
|
||||||
|
self.set_scroll_position_internal(position, true, false, &display_snapshot, window, cx)
|
||||||
|
} else {
|
||||||
|
let display_snapshot = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||||
|
self.set_scroll_position_internal(position, true, false, &display_snapshot, window, cx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Scrolls so that `row` is at the top of the editor view.
|
/// Scrolls so that `row` is at the top of the editor view.
|
||||||
|
@ -565,26 +575,7 @@ impl Editor {
|
||||||
scroll_position: gpui::Point<f32>,
|
scroll_position: gpui::Point<f32>,
|
||||||
local: bool,
|
local: bool,
|
||||||
autoscroll: bool,
|
autoscroll: bool,
|
||||||
window: &mut Window,
|
display_map: &DisplaySnapshot,
|
||||||
cx: &mut Context<Self>,
|
|
||||||
) -> WasScrolled {
|
|
||||||
let map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
|
||||||
self.set_scroll_position_taking_display_map(
|
|
||||||
scroll_position,
|
|
||||||
local,
|
|
||||||
autoscroll,
|
|
||||||
map,
|
|
||||||
window,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_scroll_position_taking_display_map(
|
|
||||||
&mut self,
|
|
||||||
scroll_position: gpui::Point<f32>,
|
|
||||||
local: bool,
|
|
||||||
autoscroll: bool,
|
|
||||||
display_map: DisplaySnapshot,
|
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> WasScrolled {
|
) -> WasScrolled {
|
||||||
|
@ -595,7 +586,7 @@ impl Editor {
|
||||||
.set_previous_scroll_position(None);
|
.set_previous_scroll_position(None);
|
||||||
|
|
||||||
let adjusted_position = if self.scroll_manager.forbid_vertical_scroll {
|
let adjusted_position = if self.scroll_manager.forbid_vertical_scroll {
|
||||||
let current_position = self.scroll_manager.anchor.scroll_position(&display_map);
|
let current_position = self.scroll_manager.anchor.scroll_position(display_map);
|
||||||
gpui::Point::new(scroll_position.x, current_position.y)
|
gpui::Point::new(scroll_position.x, current_position.y)
|
||||||
} else {
|
} else {
|
||||||
scroll_position
|
scroll_position
|
||||||
|
@ -603,10 +594,10 @@ impl Editor {
|
||||||
|
|
||||||
let editor_was_scrolled = self.scroll_manager.set_scroll_position(
|
let editor_was_scrolled = self.scroll_manager.set_scroll_position(
|
||||||
adjusted_position,
|
adjusted_position,
|
||||||
&display_map,
|
|
||||||
local,
|
local,
|
||||||
autoscroll,
|
autoscroll,
|
||||||
workspace_id,
|
workspace_id,
|
||||||
|
display_map,
|
||||||
window,
|
window,
|
||||||
cx,
|
cx,
|
||||||
);
|
);
|
||||||
|
@ -617,8 +608,20 @@ impl Editor {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_position(&self, cx: &mut Context<Self>) -> gpui::Point<f32> {
|
pub fn scroll_position(&self, cx: &mut Context<Self>) -> gpui::Point<f32> {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
self.last_position_map
|
||||||
self.scroll_manager.anchor.scroll_position(&display_map)
|
.as_ref()
|
||||||
|
.map(|position_map| {
|
||||||
|
self.scroll_manager
|
||||||
|
.anchor
|
||||||
|
.scroll_position(&position_map.snapshot)
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
self.scroll_manager.anchor.scroll_position(
|
||||||
|
&self
|
||||||
|
.display_map
|
||||||
|
.update(cx, |display_map, cx| display_map.snapshot(cx)),
|
||||||
|
)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_scroll_anchor(
|
pub fn set_scroll_anchor(
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
DisplayRow, Editor, EditorMode, LineWithInvisibles, RowExt, SelectionEffects,
|
DisplayRow, Editor, EditorMode, LineWithInvisibles, RowExt, SelectionEffects,
|
||||||
display_map::ToDisplayPoint, scroll::WasScrolled,
|
display_map::{DisplaySnapshot, ToDisplayPoint},
|
||||||
|
scroll::WasScrolled,
|
||||||
};
|
};
|
||||||
use gpui::{Bounds, Context, Pixels, Window, px};
|
use gpui::{Bounds, Context, Pixels, Window, px};
|
||||||
use language::Point;
|
use language::Point;
|
||||||
|
@ -111,13 +112,13 @@ impl Editor {
|
||||||
bounds: Bounds<Pixels>,
|
bounds: Bounds<Pixels>,
|
||||||
line_height: Pixels,
|
line_height: Pixels,
|
||||||
max_scroll_top: f32,
|
max_scroll_top: f32,
|
||||||
|
display_snapshot: &DisplaySnapshot,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Editor>,
|
cx: &mut Context<Editor>,
|
||||||
) -> (NeedsHorizontalAutoscroll, WasScrolled) {
|
) -> (NeedsHorizontalAutoscroll, WasScrolled) {
|
||||||
let viewport_height = bounds.size.height;
|
let viewport_height = bounds.size.height;
|
||||||
let visible_lines = viewport_height / line_height;
|
let visible_lines = viewport_height / line_height;
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
let mut scroll_position = self.scroll_manager.scroll_position(display_snapshot);
|
||||||
let mut scroll_position = self.scroll_manager.scroll_position(&display_map);
|
|
||||||
let original_y = scroll_position.y;
|
let original_y = scroll_position.y;
|
||||||
if let Some(last_bounds) = self.expect_bounds_change.take() {
|
if let Some(last_bounds) = self.expect_bounds_change.take() {
|
||||||
if scroll_position.y != 0. {
|
if scroll_position.y != 0. {
|
||||||
|
@ -144,7 +145,7 @@ impl Editor {
|
||||||
let mut target_top;
|
let mut target_top;
|
||||||
let mut target_bottom;
|
let mut target_bottom;
|
||||||
if let Some(first_highlighted_row) =
|
if let Some(first_highlighted_row) =
|
||||||
self.highlighted_display_row_for_autoscroll(&display_map)
|
self.highlighted_display_row_for_autoscroll(display_snapshot)
|
||||||
{
|
{
|
||||||
target_top = first_highlighted_row.as_f32();
|
target_top = first_highlighted_row.as_f32();
|
||||||
target_bottom = target_top + 1.;
|
target_bottom = target_top + 1.;
|
||||||
|
@ -155,14 +156,14 @@ impl Editor {
|
||||||
.first()
|
.first()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.head()
|
.head()
|
||||||
.to_display_point(&display_map)
|
.to_display_point(display_snapshot)
|
||||||
.row()
|
.row()
|
||||||
.as_f32();
|
.as_f32();
|
||||||
target_bottom = selections
|
target_bottom = selections
|
||||||
.last()
|
.last()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.head()
|
.head()
|
||||||
.to_display_point(&display_map)
|
.to_display_point(display_snapshot)
|
||||||
.row()
|
.row()
|
||||||
.next_row()
|
.next_row()
|
||||||
.as_f32();
|
.as_f32();
|
||||||
|
@ -179,7 +180,7 @@ impl Editor {
|
||||||
.max_by_key(|s| s.id)
|
.max_by_key(|s| s.id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.head()
|
.head()
|
||||||
.to_display_point(&display_map)
|
.to_display_point(display_snapshot)
|
||||||
.row()
|
.row()
|
||||||
.as_f32();
|
.as_f32();
|
||||||
target_top = newest_selection_top;
|
target_top = newest_selection_top;
|
||||||
|
@ -212,11 +213,11 @@ impl Editor {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Autoscroll::Strategy(_, Some(anchor)) = autoscroll {
|
if let Autoscroll::Strategy(_, Some(anchor)) = autoscroll {
|
||||||
target_top = anchor.to_display_point(&display_map).row().as_f32();
|
target_top = anchor.to_display_point(display_snapshot).row().as_f32();
|
||||||
target_bottom = target_top + 1.;
|
target_bottom = target_top + 1.;
|
||||||
}
|
}
|
||||||
|
|
||||||
let was_autoscrolled = match strategy {
|
let needs_autoscroll = match strategy {
|
||||||
AutoscrollStrategy::Fit | AutoscrollStrategy::Newest => {
|
AutoscrollStrategy::Fit | AutoscrollStrategy::Newest => {
|
||||||
let margin = margin.min(self.scroll_manager.vertical_scroll_margin);
|
let margin = margin.min(self.scroll_manager.vertical_scroll_margin);
|
||||||
let target_top = (target_top - margin).max(0.0);
|
let target_top = (target_top - margin).max(0.0);
|
||||||
|
@ -233,39 +234,48 @@ impl Editor {
|
||||||
scroll_position.y = target_bottom - visible_lines;
|
scroll_position.y = target_bottom - visible_lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
if needs_scroll_up ^ needs_scroll_down {
|
needs_scroll_up ^ needs_scroll_down
|
||||||
self.set_scroll_position_internal(scroll_position, local, true, window, cx)
|
|
||||||
} else {
|
|
||||||
WasScrolled(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
AutoscrollStrategy::Center => {
|
AutoscrollStrategy::Center => {
|
||||||
scroll_position.y = (target_top - margin).max(0.0);
|
scroll_position.y = (target_top - margin).max(0.0);
|
||||||
self.set_scroll_position_internal(scroll_position, local, true, window, cx)
|
true
|
||||||
}
|
}
|
||||||
AutoscrollStrategy::Focused => {
|
AutoscrollStrategy::Focused => {
|
||||||
let margin = margin.min(self.scroll_manager.vertical_scroll_margin);
|
let margin = margin.min(self.scroll_manager.vertical_scroll_margin);
|
||||||
scroll_position.y = (target_top - margin).max(0.0);
|
scroll_position.y = (target_top - margin).max(0.0);
|
||||||
self.set_scroll_position_internal(scroll_position, local, true, window, cx)
|
true
|
||||||
}
|
}
|
||||||
AutoscrollStrategy::Top => {
|
AutoscrollStrategy::Top => {
|
||||||
scroll_position.y = (target_top).max(0.0);
|
scroll_position.y = (target_top).max(0.0);
|
||||||
self.set_scroll_position_internal(scroll_position, local, true, window, cx)
|
true
|
||||||
}
|
}
|
||||||
AutoscrollStrategy::Bottom => {
|
AutoscrollStrategy::Bottom => {
|
||||||
scroll_position.y = (target_bottom - visible_lines).max(0.0);
|
scroll_position.y = (target_bottom - visible_lines).max(0.0);
|
||||||
self.set_scroll_position_internal(scroll_position, local, true, window, cx)
|
true
|
||||||
}
|
}
|
||||||
AutoscrollStrategy::TopRelative(lines) => {
|
AutoscrollStrategy::TopRelative(lines) => {
|
||||||
scroll_position.y = target_top - lines as f32;
|
scroll_position.y = target_top - lines as f32;
|
||||||
self.set_scroll_position_internal(scroll_position, local, true, window, cx)
|
true
|
||||||
}
|
}
|
||||||
AutoscrollStrategy::BottomRelative(lines) => {
|
AutoscrollStrategy::BottomRelative(lines) => {
|
||||||
scroll_position.y = target_bottom + lines as f32;
|
scroll_position.y = target_bottom + lines as f32;
|
||||||
self.set_scroll_position_internal(scroll_position, local, true, window, cx)
|
true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let was_autoscrolled = needs_autoscroll
|
||||||
|
.then(|| {
|
||||||
|
self.set_scroll_position_internal(
|
||||||
|
scroll_position,
|
||||||
|
local,
|
||||||
|
true,
|
||||||
|
display_snapshot,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap_or(WasScrolled(false));
|
||||||
|
|
||||||
self.scroll_manager.last_autoscroll = Some((
|
self.scroll_manager.last_autoscroll = Some((
|
||||||
self.scroll_manager.anchor.offset,
|
self.scroll_manager.anchor.offset,
|
||||||
target_top,
|
target_top,
|
||||||
|
@ -284,29 +294,29 @@ impl Editor {
|
||||||
scroll_width: Pixels,
|
scroll_width: Pixels,
|
||||||
em_advance: Pixels,
|
em_advance: Pixels,
|
||||||
layouts: &[LineWithInvisibles],
|
layouts: &[LineWithInvisibles],
|
||||||
|
display_snapshot: &DisplaySnapshot,
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) -> Option<gpui::Point<f32>> {
|
) -> Option<gpui::Point<f32>> {
|
||||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
|
||||||
let selections = self.selections.all::<Point>(cx);
|
let selections = self.selections.all::<Point>(cx);
|
||||||
let mut scroll_position = self.scroll_manager.scroll_position(&display_map);
|
let mut scroll_position = self.scroll_manager.scroll_position(display_snapshot);
|
||||||
|
|
||||||
let mut target_left;
|
let mut target_left;
|
||||||
let mut target_right;
|
let mut target_right;
|
||||||
|
|
||||||
if self
|
if self
|
||||||
.highlighted_display_row_for_autoscroll(&display_map)
|
.highlighted_display_row_for_autoscroll(display_snapshot)
|
||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
target_left = px(f32::INFINITY);
|
target_left = px(f32::INFINITY);
|
||||||
target_right = px(0.);
|
target_right = px(0.);
|
||||||
for selection in selections {
|
for selection in selections {
|
||||||
let head = selection.head().to_display_point(&display_map);
|
let head = selection.head().to_display_point(display_snapshot);
|
||||||
if head.row() >= start_row
|
if head.row() >= start_row
|
||||||
&& head.row() < DisplayRow(start_row.0 + layouts.len() as u32)
|
&& head.row() < DisplayRow(start_row.0 + layouts.len() as u32)
|
||||||
{
|
{
|
||||||
let start_column = head.column();
|
let start_column = head.column();
|
||||||
let end_column = cmp::min(display_map.line_len(head.row()), head.column());
|
let end_column = cmp::min(display_snapshot.line_len(head.row()), head.column());
|
||||||
target_left = target_left.min(
|
target_left = target_left.min(
|
||||||
layouts[head.row().minus(start_row) as usize]
|
layouts[head.row().minus(start_row) as usize]
|
||||||
.x_for_index(start_column as usize)
|
.x_for_index(start_column as usize)
|
||||||
|
@ -333,21 +343,30 @@ impl Editor {
|
||||||
let scroll_left = self.scroll_manager.anchor.offset.x * em_advance;
|
let scroll_left = self.scroll_manager.anchor.offset.x * em_advance;
|
||||||
let scroll_right = scroll_left + viewport_width;
|
let scroll_right = scroll_left + viewport_width;
|
||||||
|
|
||||||
let was_scrolled = if target_left < scroll_left {
|
let needs_scroll = if target_left < scroll_left {
|
||||||
scroll_position.x = target_left / em_advance;
|
scroll_position.x = target_left / em_advance;
|
||||||
self.set_scroll_position_internal(scroll_position, true, true, window, cx)
|
true
|
||||||
} else if target_right > scroll_right {
|
} else if target_right > scroll_right {
|
||||||
scroll_position.x = (target_right - viewport_width) / em_advance;
|
scroll_position.x = (target_right - viewport_width) / em_advance;
|
||||||
self.set_scroll_position_internal(scroll_position, true, true, window, cx)
|
true
|
||||||
} else {
|
} else {
|
||||||
WasScrolled(false)
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
if was_scrolled.0 {
|
let was_scrolled = needs_scroll
|
||||||
Some(scroll_position)
|
.then(|| {
|
||||||
} else {
|
self.set_scroll_position_internal(
|
||||||
None
|
scroll_position,
|
||||||
}
|
true,
|
||||||
|
true,
|
||||||
|
display_snapshot,
|
||||||
|
window,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.unwrap_or(WasScrolled(false));
|
||||||
|
|
||||||
|
was_scrolled.0.then_some(scroll_position)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request_autoscroll(&mut self, autoscroll: Autoscroll, cx: &mut Context<Self>) {
|
pub fn request_autoscroll(&mut self, autoscroll: Autoscroll, cx: &mut Context<Self>) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue