actions.rs

  1use gpui::{
  2    actions, geometry::vector::Vector2F, impl_internal_actions, AppContext, Axis, ViewContext,
  3};
  4use language::Bias;
  5
  6use crate::{Editor, EditorMode};
  7
  8use super::{autoscroll::Autoscroll, scroll_amount::ScrollAmount, ScrollAnchor};
  9
 10actions!(
 11    editor,
 12    [
 13        LineDown,
 14        LineUp,
 15        HalfPageDown,
 16        HalfPageUp,
 17        PageDown,
 18        PageUp,
 19        NextScreen,
 20        ScrollCursorTop,
 21        ScrollCursorCenter,
 22        ScrollCursorBottom,
 23    ]
 24);
 25
 26#[derive(Clone, PartialEq)]
 27pub struct Scroll {
 28    pub scroll_position: Vector2F,
 29    pub axis: Option<Axis>,
 30}
 31
 32impl_internal_actions!(editor, [Scroll]);
 33
 34pub fn init(cx: &mut AppContext) {
 35    cx.add_action(Editor::next_screen);
 36    cx.add_action(Editor::scroll);
 37    cx.add_action(Editor::scroll_cursor_top);
 38    cx.add_action(Editor::scroll_cursor_center);
 39    cx.add_action(Editor::scroll_cursor_bottom);
 40    cx.add_action(|this: &mut Editor, _: &LineDown, cx| {
 41        this.scroll_screen(&ScrollAmount::LineDown, cx)
 42    });
 43    cx.add_action(|this: &mut Editor, _: &LineUp, cx| {
 44        this.scroll_screen(&ScrollAmount::LineUp, cx)
 45    });
 46    cx.add_action(|this: &mut Editor, _: &HalfPageDown, cx| {
 47        this.scroll_screen(&ScrollAmount::HalfPageDown, cx)
 48    });
 49    cx.add_action(|this: &mut Editor, _: &HalfPageUp, cx| {
 50        this.scroll_screen(&ScrollAmount::HalfPageUp, cx)
 51    });
 52    cx.add_action(|this: &mut Editor, _: &PageDown, cx| {
 53        this.scroll_screen(&ScrollAmount::PageDown, cx)
 54    });
 55    cx.add_action(|this: &mut Editor, _: &PageUp, cx| {
 56        this.scroll_screen(&ScrollAmount::PageUp, cx)
 57    });
 58}
 59
 60impl Editor {
 61    pub fn next_screen(&mut self, _: &NextScreen, cx: &mut ViewContext<Editor>) -> Option<()> {
 62        if self.take_rename(true, cx).is_some() {
 63            return None;
 64        }
 65
 66        if self.mouse_context_menu.read(cx).visible() {
 67            return None;
 68        }
 69
 70        if matches!(self.mode, EditorMode::SingleLine) {
 71            cx.propagate_action();
 72            return None;
 73        }
 74        self.request_autoscroll(Autoscroll::Next, cx);
 75        Some(())
 76    }
 77
 78    fn scroll(&mut self, action: &Scroll, cx: &mut ViewContext<Self>) {
 79        self.scroll_manager.update_ongoing_scroll(action.axis);
 80        self.set_scroll_position(action.scroll_position, cx);
 81    }
 82
 83    fn scroll_cursor_top(editor: &mut Editor, _: &ScrollCursorTop, cx: &mut ViewContext<Editor>) {
 84        let snapshot = editor.snapshot(cx).display_snapshot;
 85        let scroll_margin_rows = editor.vertical_scroll_margin() as u32;
 86
 87        let mut new_screen_top = editor.selections.newest_display(cx).head();
 88        *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(scroll_margin_rows);
 89        *new_screen_top.column_mut() = 0;
 90        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
 91        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
 92
 93        editor.set_scroll_anchor(
 94            ScrollAnchor {
 95                top_anchor: new_anchor,
 96                offset: Default::default(),
 97            },
 98            cx,
 99        )
100    }
101
102    fn scroll_cursor_center(
103        editor: &mut Editor,
104        _: &ScrollCursorCenter,
105        cx: &mut ViewContext<Editor>,
106    ) {
107        let snapshot = editor.snapshot(cx).display_snapshot;
108        let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
109            visible_rows as u32
110        } else {
111            return;
112        };
113
114        let mut new_screen_top = editor.selections.newest_display(cx).head();
115        *new_screen_top.row_mut() = new_screen_top.row().saturating_sub(visible_rows / 2);
116        *new_screen_top.column_mut() = 0;
117        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
118        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
119
120        editor.set_scroll_anchor(
121            ScrollAnchor {
122                top_anchor: new_anchor,
123                offset: Default::default(),
124            },
125            cx,
126        )
127    }
128
129    fn scroll_cursor_bottom(
130        editor: &mut Editor,
131        _: &ScrollCursorBottom,
132        cx: &mut ViewContext<Editor>,
133    ) {
134        let snapshot = editor.snapshot(cx).display_snapshot;
135        let scroll_margin_rows = editor.vertical_scroll_margin() as u32;
136        let visible_rows = if let Some(visible_rows) = editor.visible_line_count() {
137            visible_rows as u32
138        } else {
139            return;
140        };
141
142        let mut new_screen_top = editor.selections.newest_display(cx).head();
143        *new_screen_top.row_mut() = new_screen_top
144            .row()
145            .saturating_sub(visible_rows.saturating_sub(scroll_margin_rows));
146        *new_screen_top.column_mut() = 0;
147        let new_screen_top = new_screen_top.to_offset(&snapshot, Bias::Left);
148        let new_anchor = snapshot.buffer_snapshot.anchor_before(new_screen_top);
149
150        editor.set_scroll_anchor(
151            ScrollAnchor {
152                top_anchor: new_anchor,
153                offset: Default::default(),
154            },
155            cx,
156        )
157    }
158}