ferroui_controls/primitives/
overlay_layer.rs1use super::{AdornerLayer, VisualLayerManager};
2use crate::{Canvas, CanvasImpl, ControlImpl, PanelImpl, TopLevel};
3use ferroui_base::input::InputElementImpl;
4use ferroui_base::interactivity::InteractiveImpl;
5use ferroui_base::layout::{LayoutableImpl, LayoutableImplExt};
6use ferroui_base::{
7 ferro_class, ferro_impl_classes, instantiate, FerroObjectImpl, Ref, Size, StyledElementImpl, Visual, VisualImpl,
8};
9use std::cell::{Cell, RefCell};
10
11#[repr(C)]
14pub struct OverlayLayer {
15 base: Canvas,
16 available_size: Cell<Size>,
17 adorner_layer: RefCell<Option<Ref<AdornerLayer>>>,
18}
19
20ferro_class!(OverlayLayer: Canvas);
21ferro_impl_classes!(
22 OverlayLayer: FerroObjectImpl,
23 StyledElementImpl,
24 InteractiveImpl,
25 InputElementImpl,
26 ControlImpl,
27 PanelImpl,
28 CanvasImpl
29);
30
31impl VisualImpl for OverlayLayer {
32 fn bypass_flow_direction_policies(_this: &Self) -> bool {
33 true
34 }
35}
36
37impl LayoutableImpl for OverlayLayer {
38 fn measure_override(this: &Self, available_size: Size) -> Size {
39 for child in this.children().snapshot().iter() {
40 child.measure(available_size);
41 }
42 available_size
43 }
44
45 fn arrange_override(this: &Self, final_size: Size) -> Size {
46 this.available_size.set(final_size);
49 Self::parent_arrange_override(this, final_size)
50 }
51}
52
53impl OverlayLayer {
54 pub(crate) fn new() -> Ref<Self> {
57 instantiate(Self {
58 base: Canvas::construct(),
59 available_size: Cell::new(Size::default()),
60 adorner_layer: RefCell::new(None),
61 })
62 }
63
64 pub fn available_size(&self) -> Size {
66 self.available_size.get()
67 }
68
69 pub fn adorner_layer(&self) -> Option<Ref<AdornerLayer>> {
72 self.adorner_layer.borrow().clone()
73 }
74
75 pub(crate) fn set_adorner_layer(&self, value: Option<Ref<AdornerLayer>>) {
76 *self.adorner_layer.borrow_mut() = value;
77 }
78
79 pub fn get_overlay_layer(visual: &Visual) -> Option<Ref<OverlayLayer>> {
82 for v in visual.get_self_and_visual_ancestors() {
83 if let Some(layer) = v.cast::<VisualLayerManager>().and_then(|manager| manager.overlay_layer()) {
84 return Some(layer);
85 }
86 }
87
88 if let Some(tl) = TopLevel::get_top_level(Some(visual)) {
89 let layers = tl.get_visual_descendants().find_map(|v| v.cast::<VisualLayerManager>());
90 return layers.and_then(|layers| layers.overlay_layer());
91 }
92
93 None
94 }
95}