1use serde::Deserialize;
2use ui::{Pixels, px};
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, 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}
27
28impl ScrollAmount {
29 pub fn lines(&self, mut visible_line_count: f32) -> f32 {
30 match self {
31 Self::Line(count) => *count,
32 Self::Page(count) => {
33 // for full pages subtract one to leave an anchor line
34 if self.is_full_page() {
35 visible_line_count -= 1.0
36 }
37 (visible_line_count * count).trunc()
38 }
39 Self::Column(_count) => 0.0,
40 }
41 }
42
43 pub fn columns(&self) -> f32 {
44 match self {
45 Self::Line(_count) => 0.0,
46 Self::Page(_count) => 0.0,
47 Self::Column(count) => *count,
48 }
49 }
50
51 pub fn pixels(&self, line_height: Pixels, height: Pixels) -> Pixels {
52 match self {
53 ScrollAmount::Line(x) => px(line_height.0 * x),
54 ScrollAmount::Page(x) => px(height.0 * x),
55 // This function seems to only be leveraged by the popover that is
56 // displayed by the editor when, for example, viewing a function's
57 // documentation. Right now that only supports vertical scrolling,
58 // so I'm leaving this at 0.0 for now to try and make it clear that
59 // this should not have an impact on that?
60 ScrollAmount::Column(_) => px(0.0),
61 }
62 }
63
64 pub fn is_full_page(&self) -> bool {
65 match self {
66 ScrollAmount::Page(count) if count.abs() == 1.0 => true,
67 _ => false,
68 }
69 }
70
71 pub fn direction(&self) -> ScrollDirection {
72 match self {
73 Self::Line(amount) if amount.is_sign_positive() => ScrollDirection::Downwards,
74 Self::Page(amount) if amount.is_sign_positive() => ScrollDirection::Downwards,
75 Self::Column(amount) if amount.is_sign_positive() => ScrollDirection::Rightwards,
76 Self::Column(amount) if amount.is_sign_negative() => ScrollDirection::Leftwards,
77 _ => ScrollDirection::Upwards,
78 }
79 }
80}