scroll_amount.rs

 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, 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: f32) -> f32 {
32        match self {
33            Self::Line(count) => *count,
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).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: f32) -> f32 {
47        match self {
48            Self::Line(_count) => 0.0,
49            Self::Page(_count) => 0.0,
50            Self::Column(count) => *count,
51            Self::PageWidth(count) => (visible_column_count * count).trunc(),
52        }
53    }
54
55    pub fn pixels(&self, line_height: Pixels, height: Pixels) -> Pixels {
56        match self {
57            ScrollAmount::Line(x) => px(line_height.0 * x),
58            ScrollAmount::Page(x) => px(height.0 * 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(_) => px(0.0),
65            ScrollAmount::PageWidth(_) => px(0.0),
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}