1use super::Axis;
2use crate::{
3 Autoscroll, Bias, Editor, EditorMode, NextScreen, NextScrollCursorCenterTopBottom,
4 ScrollAnchor, ScrollCursorBottom, ScrollCursorCenter, ScrollCursorCenterTopBottom,
5 ScrollCursorTop, SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT,
6};
7use gpui::{Context, Point, Window};
8
9impl Editor {
10 pub fn next_screen(&mut self, _: &NextScreen, window: &mut Window, cx: &mut Context<Editor>) {
11 if self.take_rename(true, window, cx).is_some() {
12 return;
13 }
14
15 if self.mouse_context_menu.is_some() {
16 return;
17 }
18
19 if matches!(self.mode, EditorMode::SingleLine { .. }) {
20 cx.propagate();
21 return;
22 }
23 self.request_autoscroll(Autoscroll::Next, cx);
24 }
25
26 pub fn scroll(
27 &mut self,
28 scroll_position: Point<f32>,
29 axis: Option<Axis>,
30 window: &mut Window,
31 cx: &mut Context<Self>,
32 ) {
33 self.scroll_manager.update_ongoing_scroll(axis);
34 self.set_scroll_position(scroll_position, window, cx);
35 }
36
37 pub fn scroll_cursor_center_top_bottom(
38 &mut self,
39 _: &ScrollCursorCenterTopBottom,
40 window: &mut Window,
41 cx: &mut Context<Self>,
42 ) {
43 let snapshot = self.snapshot(window, cx).display_snapshot;
44 let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
45 visible_rows as u32
46 } else {
47 return;
48 };
49
50 let scroll_margin_rows = self.vertical_scroll_margin() as u32;
51 let mut new_screen_top = self.selections.newest_display(cx).head();
52 *new_screen_top.column_mut() = 0;
53 match self.next_scroll_position {
54 NextScrollCursorCenterTopBottom::Center => {
55 *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(visible_rows / 2);
56 }
57 NextScrollCursorCenterTopBottom::Top => {
58 *new_screen_top.row_mut() =
59 new_screen_top.row().0.saturating_sub(scroll_margin_rows);
60 }
61 NextScrollCursorCenterTopBottom::Bottom => {
62 *new_screen_top.row_mut() = new_screen_top
63 .row()
64 .0
65 .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
66 }
67 }
68 self.set_scroll_anchor(
69 ScrollAnchor {
70 anchor: snapshot
71 .buffer_snapshot
72 .anchor_before(new_screen_top.to_offset(&snapshot, Bias::Left)),
73 offset: Default::default(),
74 },
75 window,
76 cx,
77 );
78
79 self.next_scroll_position = self.next_scroll_position.next();
80 self._scroll_cursor_center_top_bottom_task = cx.spawn(async move |editor, cx| {
81 cx.background_executor()
82 .timer(SCROLL_CENTER_TOP_BOTTOM_DEBOUNCE_TIMEOUT)
83 .await;
84 editor
85 .update(cx, |editor, _| {
86 editor.next_scroll_position = NextScrollCursorCenterTopBottom::default();
87 })
88 .ok();
89 });
90 }
91
92 pub fn scroll_cursor_top(
93 &mut self,
94 _: &ScrollCursorTop,
95 window: &mut Window,
96 cx: &mut Context<Editor>,
97 ) {
98 let snapshot = self.snapshot(window, cx).display_snapshot;
99 let scroll_margin_rows = self.vertical_scroll_margin() as u32;
100
101 let mut new_screen_top = self.selections.newest_display(cx).head();
102 *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(scroll_margin_rows);
103 *new_screen_top.column_mut() = 0;
104 let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
105 let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
106
107 self.set_scroll_anchor(
108 ScrollAnchor {
109 anchor: new_anchor,
110 offset: Default::default(),
111 },
112 window,
113 cx,
114 )
115 }
116
117 pub fn scroll_cursor_center(
118 &mut self,
119 _: &ScrollCursorCenter,
120 window: &mut Window,
121 cx: &mut Context<Editor>,
122 ) {
123 let snapshot = self.snapshot(window, cx).display_snapshot;
124 let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
125 visible_rows as u32
126 } else {
127 return;
128 };
129
130 let mut new_screen_top = self.selections.newest_display(cx).head();
131 *new_screen_top.row_mut() = new_screen_top.row().0.saturating_sub(visible_rows / 2);
132 *new_screen_top.column_mut() = 0;
133 let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
134 let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
135
136 self.set_scroll_anchor(
137 ScrollAnchor {
138 anchor: new_anchor,
139 offset: Default::default(),
140 },
141 window,
142 cx,
143 )
144 }
145
146 pub fn scroll_cursor_bottom(
147 &mut self,
148 _: &ScrollCursorBottom,
149 window: &mut Window,
150 cx: &mut Context<Editor>,
151 ) {
152 let snapshot = self.snapshot(window, cx).display_snapshot;
153 let scroll_margin_rows = self.vertical_scroll_margin() as u32;
154 let visible_rows = if let Some(visible_rows) = self.visible_line_count() {
155 visible_rows as u32
156 } else {
157 return;
158 };
159
160 let mut new_screen_top = self.selections.newest_display(cx).head();
161 *new_screen_top.row_mut() = new_screen_top
162 .row()
163 .0
164 .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
165 *new_screen_top.column_mut() = 0;
166 let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
167 let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
168
169 self.set_scroll_anchor(
170 ScrollAnchor {
171 anchor: new_anchor,
172 offset: Default::default(),
173 },
174 window,
175 cx,
176 )
177 }
178}