1use crate::model::marker::{MarkerId, MarkerList};
22use fresh_core::overlay::OverlayNamespace;
23
24#[derive(Debug, Clone)]
26pub struct SoftBreakPoint {
27 pub namespace: OverlayNamespace,
29
30 pub marker_id: MarkerId,
32
33 pub indent: u16,
35}
36
37impl SoftBreakPoint {
38 pub fn position(&self, marker_list: &MarkerList) -> usize {
40 marker_list.get_position(self.marker_id).unwrap_or(0)
41 }
42
43 pub fn in_range(&self, start: usize, end: usize, marker_list: &MarkerList) -> bool {
45 let pos = self.position(marker_list);
46 pos >= start && pos < end
47 }
48}
49
50#[derive(Debug, Clone)]
52pub struct SoftBreakManager {
53 breaks: Vec<SoftBreakPoint>,
54}
55
56impl SoftBreakManager {
57 pub fn new() -> Self {
59 Self { breaks: Vec::new() }
60 }
61
62 pub fn add(
64 &mut self,
65 marker_list: &mut MarkerList,
66 namespace: OverlayNamespace,
67 position: usize,
68 indent: u16,
69 ) {
70 let marker_id = marker_list.create(position, false); self.breaks.push(SoftBreakPoint {
73 namespace,
74 marker_id,
75 indent,
76 });
77 }
78
79 pub fn clear_namespace(&mut self, namespace: &OverlayNamespace, marker_list: &mut MarkerList) {
81 let markers_to_delete: Vec<_> = self
82 .breaks
83 .iter()
84 .filter(|b| &b.namespace == namespace)
85 .map(|b| b.marker_id)
86 .collect();
87
88 self.breaks.retain(|b| &b.namespace != namespace);
89
90 for marker_id in markers_to_delete {
91 marker_list.delete(marker_id);
92 }
93 }
94
95 pub fn remove_in_range(&mut self, start: usize, end: usize, marker_list: &mut MarkerList) {
97 let markers_to_delete: Vec<_> = self
98 .breaks
99 .iter()
100 .filter(|b| b.in_range(start, end, marker_list))
101 .map(|b| b.marker_id)
102 .collect();
103
104 self.breaks.retain(|b| !b.in_range(start, end, marker_list));
105
106 for marker_id in markers_to_delete {
107 marker_list.delete(marker_id);
108 }
109 }
110
111 pub fn clear(&mut self, marker_list: &mut MarkerList) {
113 for bp in &self.breaks {
114 marker_list.delete(bp.marker_id);
115 }
116 self.breaks.clear();
117 }
118
119 pub fn query_viewport(
122 &self,
123 start: usize,
124 end: usize,
125 marker_list: &MarkerList,
126 ) -> Vec<(usize, u16)> {
127 let mut results: Vec<(usize, u16)> = self
128 .breaks
129 .iter()
130 .filter_map(|b| {
131 let pos = b.position(marker_list);
132 if pos >= start && pos < end {
133 Some((pos, b.indent))
134 } else {
135 None
136 }
137 })
138 .collect();
139
140 results.sort_by_key(|(pos, _)| *pos);
142
143 results
144 }
145
146 pub fn is_empty(&self) -> bool {
148 self.breaks.is_empty()
149 }
150}
151
152impl Default for SoftBreakManager {
153 fn default() -> Self {
154 Self::new()
155 }
156}