makepad_code_editor/
decoration.rs1use {
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}