Skip to main content

ferroui_controls/primitives/
text_selector_layer.rs

1use super::VisualLayerManager;
2use crate::{Canvas, CanvasImpl, Control, 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, IntoRef, Ref, Size, StyledElementImpl, Visual,
8    VisualImpl,
9};
10use std::cell::Cell;
11
12/// The surface that hosts the text selection handles.
13#[repr(C)]
14pub struct TextSelectorLayer {
15    base: Canvas,
16    available_size: Cell<Size>,
17}
18
19ferro_class!(TextSelectorLayer: Canvas);
20ferroui_base::ferro_class_info!(TextSelectorLayer { new: TextSelectorLayer::new });
21ferro_impl_classes!(
22    TextSelectorLayer: FerroObjectImpl,
23    StyledElementImpl,
24    InteractiveImpl,
25    InputElementImpl,
26    ControlImpl,
27    PanelImpl,
28    CanvasImpl
29);
30
31impl VisualImpl for TextSelectorLayer {
32    fn bypass_flow_direction_policies(_this: &Self) -> bool {
33        true
34    }
35}
36
37impl LayoutableImpl for TextSelectorLayer {
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        Size::default()
43    }
44
45    fn arrange_override(this: &Self, final_size: Size) -> Size {
46        this.available_size.set(final_size);
47        Self::parent_arrange_override(this, final_size)
48    }
49}
50
51impl TextSelectorLayer {
52    pub fn new() -> Ref<Self> {
53        instantiate(Self { base: Canvas::construct(), available_size: Cell::new(Size::default()) })
54    }
55
56    /// The size the layer was last arranged with.
57    pub fn available_size(&self) -> Size {
58        self.available_size.get()
59    }
60
61    /// Retrieves the text selector layer associated with the specified
62    /// visual, if any.
63    pub fn get_text_selector_layer(visual: &Visual) -> Option<Ref<TextSelectorLayer>> {
64        for v in visual.get_self_and_visual_ancestors() {
65            if let Some(layer) = v.cast::<VisualLayerManager>().and_then(|manager| manager.text_selector_layer()) {
66                return Some(layer);
67            }
68        }
69
70        if let Some(tl) = TopLevel::get_top_level(Some(visual)) {
71            let layers = tl.get_visual_descendants().find_map(|v| v.cast::<VisualLayerManager>());
72            return layers.and_then(|layers| layers.text_selector_layer());
73        }
74
75        None
76    }
77
78    /// Adds a control to the layer.
79    pub fn add(&self, control: impl IntoRef<Control>) {
80        self.children().add(control);
81    }
82
83    /// Removes a control from the layer.
84    pub fn remove(&self, control: impl IntoRef<Control>) {
85        self.children().remove(control);
86    }
87}