makepad_code_editor/
decoration.rs

1use {
2    crate::text::{Edit, Length, Position},
3    std::{ops::Deref, slice::Iter},
4};
5
6#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
7pub struct Decoration {
8    pub id: usize,
9    start: Position,
10    end: Position,
11}
12
13impl Decoration {
14    pub fn new(id: usize, start: Position, end: Position) -> Self {
15        if start > end{
16            return Self {
17                id,
18                start:end,
19                end:start,
20            }
21        }
22        Self {
23            id,
24            start,
25            end,
26        }
27    }
28
29    pub fn is_empty(self) -> bool {
30        self.start == self.end
31    }
32
33    pub fn overlaps_with(self, other: Self) -> bool {
34        self.end() > other.start()
35    }
36
37    pub fn length(self) -> Length {
38        self.end - self.start
39    }
40
41    pub fn start(self) -> Position {
42        self.start
43    }
44
45    pub fn end(self) -> Position {
46        self.end
47    }
48
49    pub fn apply_edit(self, edit: &Edit) -> Self {
50        Self {
51            start: self.start.apply_edit(edit),
52            end: self.end.apply_edit(edit),
53            ..self
54        }
55    }
56}
57
58#[derive(Clone, Debug, Eq, Hash, PartialEq)]
59pub struct DecorationSet {
60    decorations: Vec<Decoration>
61}
62
63impl DecorationSet {
64    pub fn new() -> Self {
65        Self::default()
66    }
67
68    pub fn as_decorations(&self) -> &[Decoration] {
69        &self.decorations
70    }
71
72    pub fn add_decoration(&mut self, decoration: Decoration) {
73        let index = match self
74            .decorations
75            .binary_search_by_key(&decoration.start(), |decoration| decoration.start())
76        {
77            Ok(index) => {
78                self.decorations[index] = decoration;
79                index
80            }
81            Err(index) => {
82                self.decorations.insert(index, decoration);
83                index
84            }
85        };
86        self.remove_overlapping_decorations(index);
87    }
88
89    pub fn clear(&mut self) {
90        self.decorations.clear();
91    }
92
93    pub fn apply_edit(&mut self, edit: &Edit) {
94        for decoration in &mut self.decorations {
95            *decoration = decoration.apply_edit(edit);
96        }
97    }
98
99    fn remove_overlapping_decorations(&mut self, index: usize) {
100        let mut index = index;
101        while index > 0 {
102            let prev_index = index - 1;
103            if !self.decorations[prev_index].overlaps_with(self.decorations[index]) {
104                break;
105            }
106            self.decorations.remove(prev_index);
107            index -= 1;
108        }
109        while index + 1 < self.decorations.len() {
110            let next_index = index + 1;
111            if !self.decorations[index].overlaps_with(self.decorations[next_index]) {
112                break;
113            }
114            self.decorations.remove(next_index);
115        }
116    }
117}
118
119impl Default for DecorationSet {
120    fn default() -> Self {
121        Self {
122            decorations: vec![]
123        }
124    }
125}
126
127impl Deref for DecorationSet {
128    type Target = [Decoration];
129
130    fn deref(&self) -> &Self::Target {
131        self.decorations.as_slice()
132    }
133}
134
135impl<'a> IntoIterator for &'a DecorationSet {
136    type Item = &'a Decoration;
137    type IntoIter = Iter<'a, Decoration>;
138
139    fn into_iter(self) -> Self::IntoIter {
140        self.iter()
141    }
142}