1use serde::Deserialize;
2use ui::Pixels;
3
4#[derive(Debug)]
5pub enum ScrollDirection {
6 Upwards,
7 Downwards,
8 Rightwards,
9 Leftwards,
10}
11
12impl ScrollDirection {
13 pub fn is_upwards(&self) -> bool {
14 matches!(self, ScrollDirection::Upwards)
15 }
16}
17
18#[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
19pub enum ScrollAmount {
20 // Scroll N lines (positive is towards the end of the document)
21 Line(f32),
22 // Scroll N pages (positive is towards the end of the document)
23 Page(f32),
24 // Scroll N columns (positive is towards the right of the document)
25 Column(f32),
26 // Scroll N page width (positive is towards the right of the document)
27 PageWidth(f32),
28}
29
30impl ScrollAmount {
31 pub fn lines(&self, mut visible_line_count: f64) -> f64 {
32 match self {
33 Self::Line(count) => *count as f64,
34 Self::Page(count) => {
35 // for full pages subtract one to leave an anchor line
36 if self.is_full_page() {
37 visible_line_count -= 1.0
38 }
39 (visible_line_count * (*count as f64)).trunc()
40 }
41 Self::Column(_count) => 0.0,
42 Self::PageWidth(_count) => 0.0,
43 }
44 }
45
46 pub fn columns(&self, visible_column_count: f64) -> f64 {
47 match self {
48 Self::Line(_count) => 0.0,
49 Self::Page(_count) => 0.0,
50 Self::Column(count) => *count as f64,
51 Self::PageWidth(count) => (visible_column_count * *count as f64).trunc(),
52 }
53 }
54
55 pub fn pixels(&self, line_height: Pixels, height: Pixels) -> Pixels {
56 match self {
57 ScrollAmount::Line(x) => line_height * *x,
58 ScrollAmount::Page(x) => height * *x,
59 // This function seems to only be leveraged by the popover that is
60 // displayed by the editor when, for example, viewing a function's
61 // documentation. Right now that only supports vertical scrolling,
62 // so I'm leaving this at 0.0 for now to try and make it clear that
63 // this should not have an impact on that?
64 ScrollAmount::Column(_) => Pixels::ZERO,
65 ScrollAmount::PageWidth(_) => Pixels::ZERO,
66 }
67 }
68
69 pub fn is_full_page(&self) -> bool {
70 matches!(self, ScrollAmount::Page(count) if count.abs() == 1.0)
71 }
72
73 pub fn direction(&self) -> ScrollDirection {
74 match self {
75 Self::Line(amount) if amount.is_sign_positive() => ScrollDirection::Downwards,
76 Self::Page(amount) if amount.is_sign_positive() => ScrollDirection::Downwards,
77 Self::Column(amount) if amount.is_sign_positive() => ScrollDirection::Rightwards,
78 Self::Column(amount) if amount.is_sign_negative() => ScrollDirection::Leftwards,
79 _ => ScrollDirection::Upwards,
80 }
81 }
82}