actions.rs

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