1use crate::{Id, *};
5use epaint::{emath::TSTransform, ClippedShape, Shape};
6
7#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
9#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
10pub enum Order {
11 Background,
13
14 PanelResizeLine,
16
17 Middle,
19
20 Foreground,
23
24 Tooltip,
27
28 Debug,
30}
31
32impl Order {
33 const COUNT: usize = 6;
34 const ALL: [Self; Self::COUNT] = [
35 Self::Background,
36 Self::PanelResizeLine,
37 Self::Middle,
38 Self::Foreground,
39 Self::Tooltip,
40 Self::Debug,
41 ];
42 pub const TOP: Self = Self::Debug;
43
44 #[inline(always)]
45 pub fn allow_interaction(&self) -> bool {
46 match self {
47 Self::Background
48 | Self::PanelResizeLine
49 | Self::Middle
50 | Self::Foreground
51 | Self::Tooltip
52 | Self::Debug => true,
53 }
54 }
55
56 pub fn short_debug_format(&self) -> &'static str {
58 match self {
59 Self::Background => "backg",
60 Self::PanelResizeLine => "panel",
61 Self::Middle => "middl",
62 Self::Foreground => "foreg",
63 Self::Tooltip => "toolt",
64 Self::Debug => "debug",
65 }
66 }
67}
68
69#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
72#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
73pub struct LayerId {
74 pub order: Order,
75 pub id: Id,
76}
77
78impl LayerId {
79 pub fn new(order: Order, id: Id) -> Self {
80 Self { order, id }
81 }
82
83 pub fn debug() -> Self {
84 Self {
85 order: Order::Debug,
86 id: Id::new("debug"),
87 }
88 }
89
90 pub fn background() -> Self {
91 Self {
92 order: Order::Background,
93 id: Id::new("background"),
94 }
95 }
96
97 #[inline(always)]
98 pub fn allow_interaction(&self) -> bool {
99 self.order.allow_interaction()
100 }
101
102 pub fn short_debug_format(&self) -> String {
104 format!(
105 "{} {}",
106 self.order.short_debug_format(),
107 self.id.short_debug_format()
108 )
109 }
110}
111
112#[derive(Clone, Copy, Debug, PartialEq, Eq)]
115pub struct ShapeIdx(pub usize);
116
117#[derive(Clone, Default)]
119pub struct PaintList(Vec<ClippedShape>);
120
121impl PaintList {
122 #[inline(always)]
123 pub fn is_empty(&self) -> bool {
124 self.0.is_empty()
125 }
126
127 #[inline(always)]
129 pub fn add(&mut self, clip_rect: Rect, shape: Shape) -> ShapeIdx {
130 let idx = ShapeIdx(self.0.len());
131 self.0.push(ClippedShape { clip_rect, shape });
132 idx
133 }
134
135 pub fn extend<I: IntoIterator<Item = Shape>>(&mut self, clip_rect: Rect, shapes: I) {
136 self.0.extend(
137 shapes
138 .into_iter()
139 .map(|shape| ClippedShape { clip_rect, shape }),
140 );
141 }
142
143 #[inline(always)]
151 pub fn set(&mut self, idx: ShapeIdx, clip_rect: Rect, shape: Shape) {
152 self.0[idx.0] = ClippedShape { clip_rect, shape };
153 }
154
155 #[inline(always)]
157 pub fn reset_shape(&mut self, idx: ShapeIdx) {
158 self.0[idx.0].shape = Shape::Noop;
159 }
160
161 pub fn transform(&mut self, transform: TSTransform) {
163 for ClippedShape { clip_rect, shape } in &mut self.0 {
164 *clip_rect = transform.mul_rect(*clip_rect);
165 shape.transform(transform);
166 }
167 }
168
169 pub fn all_entries(&self) -> impl ExactSizeIterator<Item = &ClippedShape> {
171 self.0.iter()
172 }
173}
174
175#[derive(Clone, Default)]
177pub struct GraphicLayers([IdMap<PaintList>; Order::COUNT]);
178
179impl GraphicLayers {
180 pub fn entry(&mut self, layer_id: LayerId) -> &mut PaintList {
182 self.0[layer_id.order as usize]
183 .entry(layer_id.id)
184 .or_default()
185 }
186
187 pub fn get(&self, layer_id: LayerId) -> Option<&PaintList> {
189 self.0[layer_id.order as usize].get(&layer_id.id)
190 }
191
192 pub fn get_mut(&mut self, layer_id: LayerId) -> Option<&mut PaintList> {
194 self.0[layer_id.order as usize].get_mut(&layer_id.id)
195 }
196
197 pub fn drain(
198 &mut self,
199 area_order: &[LayerId],
200 transforms: &ahash::HashMap<LayerId, TSTransform>,
201 ) -> Vec<ClippedShape> {
202 crate::profile_function!();
203
204 let mut all_shapes: Vec<_> = Default::default();
205
206 for &order in &Order::ALL {
207 let order_map = &mut self.0[order as usize];
208
209 order_map.retain(|_, list| !list.is_empty());
213
214 for layer_id in area_order {
216 if layer_id.order == order {
217 if let Some(list) = order_map.get_mut(&layer_id.id) {
218 if let Some(transform) = transforms.get(layer_id) {
219 for clipped_shape in &mut list.0 {
220 clipped_shape.clip_rect = *transform * clipped_shape.clip_rect;
221 clipped_shape.shape.transform(*transform);
222 }
223 }
224 all_shapes.append(&mut list.0);
225 }
226 }
227 }
228
229 for (id, list) in order_map {
231 let layer_id = LayerId::new(order, *id);
232
233 if let Some(transform) = transforms.get(&layer_id) {
234 for clipped_shape in &mut list.0 {
235 clipped_shape.clip_rect = *transform * clipped_shape.clip_rect;
236 clipped_shape.shape.transform(*transform);
237 }
238 }
239
240 all_shapes.append(&mut list.0);
241 }
242 }
243
244 all_shapes
245 }
246}