ferroui_controls/flyouts/
menu_flyout_presenter.rs1use crate::platform::{DefaultMenuInteractionHandler, IMenuInteractionHandler};
2use crate::primitives::{Popup, SelectingItemsControlImpl, TemplatedControlImpl};
3use crate::{ControlImpl, ItemsControlImpl, MenuBase, MenuBaseImpl, MenuItem};
4use ferroui_base::input::InputElementImpl;
5use ferroui_base::interactivity::InteractiveImpl;
6use ferroui_base::layout::LayoutableImpl;
7use ferroui_base::{
8 ferro_class, ferro_class_info, ferro_impl_classes, instantiate, FerroObjectImpl, Ref, StyledElement,
9 StyledElementImpl, VisualImpl, VisualImplExt, VisualTreeAttachmentEventArgs,
10};
11use std::rc::Rc;
12
13#[repr(C)]
15pub struct MenuFlyoutPresenter {
16 base: MenuBase,
17}
18
19ferro_class!(MenuFlyoutPresenter: MenuBase);
20ferro_class_info!(MenuFlyoutPresenter { new: MenuFlyoutPresenter::new });
21
22ferro_impl_classes!(
23 MenuFlyoutPresenter: FerroObjectImpl,
24 StyledElementImpl,
25 LayoutableImpl,
26 InteractiveImpl,
27 InputElementImpl,
28 ControlImpl,
29 TemplatedControlImpl,
30 ItemsControlImpl,
31 SelectingItemsControlImpl
32);
33
34impl VisualImpl for MenuFlyoutPresenter {
35 fn on_detached_from_visual_tree(this: &Self, e: &VisualTreeAttachmentEventArgs) {
36 Self::parent_on_detached_from_visual_tree(this, e);
37
38 let children = StyledElement::logical_children(this).to_vec();
39 for i in children {
40 if let Some(menu_item) = i.cast::<MenuItem>() {
41 menu_item.set_is_sub_menu_open(false);
42 }
43 }
44 }
45}
46
47impl MenuBaseImpl for MenuFlyoutPresenter {
48 fn close(this: &Self) {
49 let host = this.find_logical_ancestor_of_type::<Popup>(false);
51 if let Some(host) = host {
52 this.set_selected_index(-1);
53 host.set_is_open(false);
54 }
55 }
56
57 fn open(_this: &Self) {
58 panic!("Use MenuFlyout.ShowAt(Control) instead");
59 }
60}
61
62impl MenuFlyoutPresenter {
63 pub fn construct() -> Self {
67 Self::construct_with(DefaultMenuInteractionHandler::new(true))
68 }
69
70 pub fn construct_with(menu_interaction_handler: Rc<dyn IMenuInteractionHandler>) -> Self {
73 Self { base: MenuBase::construct_with(menu_interaction_handler) }
74 }
75
76 pub fn new() -> Ref<Self> {
78 instantiate(Self::construct())
79 }
80
81 pub fn with_interaction_handler(menu_interaction_handler: Rc<dyn IMenuInteractionHandler>) -> Ref<Self> {
83 instantiate(Self::construct_with(menu_interaction_handler))
84 }
85}