Skip to main content

ferroui_controls/flyouts/
flyout_presenter.rs

1use crate::primitives::{Popup, TemplatedControlImpl};
2use crate::{ContentControl, ContentControlImpl, ControlImpl};
3use ferroui_base::input::{InputElementImpl, InputElementImplExt, Key, KeyEventArgs};
4use ferroui_base::interactivity::InteractiveImpl;
5use ferroui_base::layout::LayoutableImpl;
6use ferroui_base::{
7    ferro_class, ferro_impl_classes, instantiate, FerroObjectImpl, Ref, StyledElementImpl, VisualImpl,
8};
9
10/// The control that hosts the content of a flyout.
11#[repr(C)]
12pub struct FlyoutPresenter {
13    base: ContentControl,
14}
15
16ferro_class!(FlyoutPresenter: ContentControl);
17ferroui_base::ferro_class_info!(FlyoutPresenter { new: FlyoutPresenter::new });
18ferro_impl_classes!(
19    FlyoutPresenter: FerroObjectImpl,
20    StyledElementImpl,
21    VisualImpl,
22    LayoutableImpl,
23    InteractiveImpl,
24    ControlImpl,
25    TemplatedControlImpl,
26    ContentControlImpl
27);
28
29impl InputElementImpl for FlyoutPresenter {
30    fn on_key_down(this: &Self, e: &KeyEventArgs) {
31        if e.key == Key::Escape {
32            let mut host = None;
33            let mut parent = this.parent();
34            while let Some(current) = parent {
35                if let Some(popup) = current.cast::<Popup>() {
36                    host = Some(popup);
37                    break;
38                }
39                parent = current.parent();
40            }
41
42            if let Some(host) = host {
43                host.set_is_open(false);
44                e.set_handled(true);
45            }
46        }
47
48        Self::parent_on_key_down(this, e);
49    }
50}
51
52impl FlyoutPresenter {
53    /// Creates the class data; see [`ferroui_base::FerroObject::construct`].
54    pub fn construct() -> Self {
55        Self { base: ContentControl::construct() }
56    }
57
58    /// Creates a flyout presenter.
59    pub fn new() -> Ref<Self> {
60        instantiate(Self::construct())
61    }
62}