ferroui_controls/primitives/
popup_overlay_layer.rs1use super::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;
10
11#[repr(C)]
14pub struct PopupOverlayLayer {
15 base: Canvas,
16 available_size: Cell<Size>,
17}
18
19ferro_class!(PopupOverlayLayer: Canvas);
20ferroui_base::ferro_class_info!(PopupOverlayLayer { new: PopupOverlayLayer::new });
21ferro_impl_classes!(
22 PopupOverlayLayer: FerroObjectImpl,
23 StyledElementImpl,
24 InteractiveImpl,
25 InputElementImpl,
26 ControlImpl,
27 PanelImpl,
28 CanvasImpl
29);
30
31impl VisualImpl for PopupOverlayLayer {
32 fn bypass_flow_direction_policies(_this: &Self) -> bool {
33 true
34 }
35}
36
37impl LayoutableImpl for PopupOverlayLayer {
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 PopupOverlayLayer {
54 pub fn new() -> Ref<Self> {
55 instantiate(Self { base: Canvas::construct(), available_size: Cell::new(Size::default()) })
56 }
57
58 pub fn available_size(&self) -> Size {
60 self.available_size.get()
61 }
62
63 pub fn get_popup_overlay_layer(visual: &Visual) -> Option<Ref<PopupOverlayLayer>> {
66 for v in visual.get_self_and_visual_ancestors() {
67 if let Some(layer) = v.cast::<VisualLayerManager>().and_then(|manager| manager.popup_overlay_layer()) {
68 return Some(layer);
69 }
70 }
71
72 if let Some(tl) = TopLevel::get_top_level(Some(visual)) {
73 let layers = tl.get_visual_descendants().find_map(|v| v.cast::<VisualLayerManager>());
74 return layers.and_then(|layers| layers.popup_overlay_layer());
75 }
76
77 None
78 }
79}