Skip to main content

egui_elements/widgets/particles/shared/
layer.rs

1//! Layer selection for the particle effects.
2
3use egui::{Context, Id, LayerId, Order, Rect};
4
5/// Layer a particle effect is painted on.
6#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum ParticleLayer {
9   /// Behind everything (`Order::Background`).
10   Background,
11   /// In front of windows (`Order::Foreground`).
12   Foreground,
13   /// On top of everything including debug/tooltips (`Order::Debug`).
14   Top,
15}
16
17impl ParticleLayer {
18   /// Human-readable name, matching the settings window labels.
19   pub fn to_str(&self) -> &str {
20      match self {
21         ParticleLayer::Background => "Background",
22         ParticleLayer::Foreground => "Foreground",
23         ParticleLayer::Top => "Top",
24      }
25   }
26}
27
28/// Resolves the concrete layer and area an effect paints into.
29///
30/// `order` is the already-resolved [`ParticleLayer`] order; `custom_layer` wins
31/// over it and `custom_area` wins over `ctx.content_rect()`. Returns `None` for
32/// a degenerate (≤ 0) area so the caller can bail out before touching any state.
33pub(crate) fn resolve_target(
34   ctx: &Context,
35   id: Id,
36   order: Order,
37   custom_layer: Option<LayerId>,
38   custom_area: Option<Rect>,
39) -> Option<(LayerId, Rect)> {
40   let area = custom_area.unwrap_or_else(|| ctx.content_rect());
41   if area.width() <= 0.0 || area.height() <= 0.0 {
42      return None;
43   }
44
45   let layer_id = custom_layer.unwrap_or_else(|| LayerId::new(order, id));
46
47   Some((layer_id, area))
48}
49
50#[cfg(test)]
51mod tests {
52   use super::*;
53
54   #[test]
55   fn particle_layer_to_str() {
56      assert_eq!(ParticleLayer::Background.to_str(), "Background");
57      assert_eq!(ParticleLayer::Foreground.to_str(), "Foreground");
58      assert_eq!(ParticleLayer::Top.to_str(), "Top");
59   }
60}