Skip to main content

bevy_ui_widgets/
menu.rs

1//! Standard widget components for popup menus.
2//!
3//! Generally menus are structured as follows: there's a "menu" entity which is a container for a
4//! "menu button" and a "menu popup". The popup may be pre-rendered and hidden while closed, or
5//! it can be dynamically spawned on open and despawned on close - it's up to the widget implementer
6//! to decide how they want to manage the popup.
7//!
8//! The popup should have a [`MenuPopup`] component. The menu button should have a [`MenuButton`]
9//! component. The top level menu entity does not have any special component, but should have an
10//! observer for menu events. The menu entity receives these events which bubble upward from both
11//! the button and the popup. These events control the state of the menu (open and close) as well
12//! as help manage focus.
13//!
14//! There's a tight coupling between menus and input focus: in order to detect clicks outside
15//! the popup box (which cause the menu to close), we look for focus changes. This means that menu
16//! popups only remain open as long as some child of the popup has focus. This also means that
17//! when the popup first opens, focus must be set to a child (usually the first or last menu item
18//! depending on what action caused the menu to open). Because opening the popup may not be instant,
19//! especially if it's a queued BSN spawn, we can't set focus directly via the focus API. Instead,
20//! you can insert a [`MenuFocusState`] component on the popup which will automatically focus
21//! the appropriate child item when spawning is complete.
22//!
23//! Pressing the ESC key also closes the menu, but in that case focus reverts back to the menu
24//! button.
25//!
26//! Finally, there's no rule against the menu entity having additional children besides the button
27//! and the popup; for example, for something like a combo box widget, you might have a text input
28//! widget that is a sibling of the menu button, both of which are contained inside a decorative
29//! frame.
30
31use accesskit::Role;
32use bevy_a11y::AccessibilityNode;
33use bevy_app::{App, Plugin, PostUpdate};
34use bevy_camera::visibility::VisibilitySystems;
35use bevy_ecs::{
36    component::Component,
37    entity::Entity,
38    event::EntityEvent,
39    hierarchy::ChildOf,
40    observer::On,
41    query::{Has, With},
42    reflect::{ReflectComponent, ReflectEvent},
43    schedule::{IntoScheduleConfigs, SystemSet},
44    system::{Commands, Query, Res, ResMut},
45};
46use bevy_input::{
47    keyboard::{KeyCode, KeyboardInput},
48    ButtonState,
49};
50use bevy_input_focus::{
51    tab_navigation::{NavAction, TabGroup, TabNavigation},
52    FocusCause, FocusedInput, InputFocus, InputFocusSystems,
53};
54use bevy_log::warn;
55use bevy_picking::events::{
56    PointerCancel, PointerClick, PointerDragEnd, PointerPress, PointerRelease,
57};
58use bevy_reflect::Reflect;
59use bevy_ui::{InteractionDisabled, Pressed, UiSystems};
60
61use crate::{text_input::text_input_autoscroll_system, Activate, ActivateOnPress, Button};
62
63/// Action type for [`MenuEvent`].
64#[derive(#[automatically_derived]
#[doc(hidden)]
unsafe impl ::core::clone::TrivialClone for MenuAction { }
#[automatically_derived]
impl ::core::clone::Clone for MenuAction {
    #[inline]
    fn clone(&self) -> Self {
        let _: ::core::clone::AssertParamIsClone<NavAction>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for MenuAction { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for MenuAction {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Open(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Open",
                    &__self_0),
            Self::Toggle => ::core::fmt::Formatter::write_str(f, "Toggle"),
            Self::CloseAll =>
                ::core::fmt::Formatter::write_str(f, "CloseAll"),
            Self::FocusRoot =>
                ::core::fmt::Formatter::write_str(f, "FocusRoot"),
        }
    }
}Debug, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for MenuAction where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <NavAction as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for MenuAction where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Enum(bevy_reflect::enums::EnumInfo::new::<Self>(&[bevy_reflect::enums::VariantInfo::Tuple(bevy_reflect::enums::TupleVariantInfo::new("Open",
                                                        &[bevy_reflect::UnnamedField::new::<NavAction>(0usize)])),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("Toggle")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("CloseAll")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("FocusRoot"))]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for MenuAction where  {
            fn type_path() -> &'static str {
                "bevy_ui_widgets::menu::MenuAction"
            }
            fn short_type_path() -> &'static str { "MenuAction" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("MenuAction")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu")
            }
        }
        impl bevy_reflect::Reflect for MenuAction where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<MenuAction
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::enums::Enum for MenuAction where  {
            fn field(&self, __name_param: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_at(&self, __index_param: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match self {
                    MenuAction::Open { 0: __value, .. } if
                        __index_param == 0usize =>
                        ::core::option::Option::Some(__value),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, __name_param: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_at_mut(&mut self, __index_param: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match self {
                    MenuAction::Open { 0: __value, .. } if
                        __index_param == 0usize =>
                        ::core::option::Option::Some(__value),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of(&self, __name_param: &str)
                -> ::core::option::Option<usize> {
                match self { _ => ::core::option::Option::None, }
            }
            fn name_at(&self, __index_param: usize)
                -> ::core::option::Option<&str> {
                match self { _ => ::core::option::Option::None, }
            }
            fn iter_fields(&self) -> bevy_reflect::enums::VariantFieldIter {
                bevy_reflect::enums::VariantFieldIter::new(self)
            }
            #[inline]
            fn field_len(&self) -> usize {
                match self {
                    MenuAction::Open { .. } => 1usize,
                    MenuAction::Toggle { .. } => 0usize,
                    MenuAction::CloseAll { .. } => 0usize,
                    MenuAction::FocusRoot { .. } => 0usize,
                    _ => 0,
                }
            }
            #[inline]
            fn variant_name(&self) -> &str {
                match self {
                    MenuAction::Open { .. } => "Open",
                    MenuAction::Toggle { .. } => "Toggle",
                    MenuAction::CloseAll { .. } => "CloseAll",
                    MenuAction::FocusRoot { .. } => "FocusRoot",
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            #[inline]
            fn variant_index(&self) -> usize {
                match self {
                    MenuAction::Open { .. } => 0usize,
                    MenuAction::Toggle { .. } => 1usize,
                    MenuAction::CloseAll { .. } => 2usize,
                    MenuAction::FocusRoot { .. } => 3usize,
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            #[inline]
            fn variant_type(&self) -> bevy_reflect::enums::VariantType {
                match self {
                    MenuAction::Open { .. } =>
                        bevy_reflect::enums::VariantType::Tuple,
                    MenuAction::Toggle { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    MenuAction::CloseAll { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    MenuAction::FocusRoot { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            fn to_dynamic_enum(&self)
                ->
                    ::core::result::Result<bevy_reflect::enums::DynamicEnum,
                    bevy_reflect::ReflectCloneError> {
                bevy_reflect::enums::DynamicEnum::try_from_ref::<Self>(self)
            }
        }
        impl bevy_reflect::PartialReflect for MenuAction where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self,
                __value_param: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Enum(__value_param) =
                        bevy_reflect::PartialReflect::reflect_ref(__value_param) {
                    if bevy_reflect::enums::Enum::variant_name(self) ==
                            bevy_reflect::enums::Enum::variant_name(__value_param) {
                        match bevy_reflect::enums::Enum::variant_type(__value_param)
                            {
                            bevy_reflect::enums::VariantType::Struct => {
                                for field in
                                    bevy_reflect::enums::Enum::iter_fields(__value_param) {
                                    let name = field.name().unwrap();
                                    if let ::core::option::Option::Some(v) =
                                            bevy_reflect::enums::Enum::field_mut(self, name) {
                                        bevy_reflect::PartialReflect::try_apply(v, field.value())?;
                                    }
                                }
                            }
                            bevy_reflect::enums::VariantType::Tuple => {
                                for (index, field) in
                                    ::core::iter::Iterator::enumerate(bevy_reflect::enums::Enum::iter_fields(__value_param))
                                    {
                                    if let ::core::option::Option::Some(v) =
                                            bevy_reflect::enums::Enum::field_at_mut(self, index) {
                                        bevy_reflect::PartialReflect::try_apply(v, field.value())?;
                                    }
                                }
                            }
                            _ => {}
                        }
                    } else {
                        match bevy_reflect::enums::Enum::variant_name(__value_param)
                            {
                            "Open" => {
                                *self =
                                    MenuAction::Open {
                                        0: {
                                            let __0 = __value_param.field_at(0usize);
                                            let __0 =
                                                __0.ok_or(bevy_reflect::ApplyError::MissingEnumField {
                                                            variant_name: ::core::convert::Into::into("Open"),
                                                            field_name: ::core::convert::Into::into(".0"),
                                                        })?;
                                            <NavAction as
                                                            bevy_reflect::FromReflect>::from_reflect(__0).ok_or(bevy_reflect::ApplyError::MismatchedTypes {
                                                        from_type: ::core::convert::Into::into(bevy_reflect::DynamicTypePath::reflect_type_path(__0)),
                                                        to_type: ::core::convert::Into::into(<NavAction as
                                                                    bevy_reflect::TypePath>::type_path()),
                                                    })?
                                        },
                                    }
                            }
                            "Toggle" => { *self = MenuAction::Toggle {} }
                            "CloseAll" => { *self = MenuAction::CloseAll {} }
                            "FocusRoot" => { *self = MenuAction::FocusRoot {} }
                            name => {
                                return ::core::result::Result::Err(bevy_reflect::ApplyError::UnknownVariant {
                                            enum_name: ::core::convert::Into::into(bevy_reflect::DynamicTypePath::reflect_type_path(self)),
                                            variant_name: ::core::convert::Into::into(name),
                                        });
                            }
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(__value_param),
                                to_kind: bevy_reflect::ReflectKind::Enum,
                            });
                }
                ::core::result::Result::Ok(())
            }
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Enum
            }
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Enum(self)
            }
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Enum(self)
            }
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Enum(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_hash(&self) -> ::core::option::Option<u64> {
                (bevy_reflect::enums::enum_hash)(self)
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::enums::enum_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::enums::enum_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                let this = self;
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(match this
                            {
                            MenuAction::Open { 0: __0 } =>
                                MenuAction::Open {
                                    0: <NavAction as
                                                bevy_reflect::PartialReflect>::reflect_clone_and_take(__0)?,
                                },
                            MenuAction::Toggle {} => MenuAction::Toggle {},
                            MenuAction::CloseAll {} => MenuAction::CloseAll {},
                            MenuAction::FocusRoot {} => MenuAction::FocusRoot {},
                        }))
            }
        }
        impl bevy_reflect::FromReflect for MenuAction where  {
            fn from_reflect(__param0: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Enum(__param0) =
                        bevy_reflect::PartialReflect::reflect_ref(__param0) {
                    match bevy_reflect::enums::Enum::variant_name(__param0) {
                        "Open" =>
                            ::core::option::Option::Some(MenuAction::Open {
                                    0: {
                                        let __0 = __param0.field_at(0usize);
                                        let __0 = __0?;
                                        <NavAction as bevy_reflect::FromReflect>::from_reflect(__0)?
                                    },
                                }),
                        "Toggle" =>
                            ::core::option::Option::Some(MenuAction::Toggle {}),
                        "CloseAll" =>
                            ::core::option::Option::Some(MenuAction::CloseAll {}),
                        "FocusRoot" =>
                            ::core::option::Option::Some(MenuAction::FocusRoot {}),
                        name => ::core::option::Option::None,
                    }
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
65pub enum MenuAction {
66    /// Indicates we want to open the menu, if it is not already open, and focus the first or
67    /// last item depending on the [`NavAction`].
68    Open(NavAction),
69    /// Open the menu if it's closed, close it if it's open. Generally sent from a menu button.
70    Toggle,
71    /// Close the entire menu stack.
72    CloseAll,
73    /// Set focus to the menu button or other owner of the popup stack. This happens when
74    /// the menu is closed by pressing the escape key.
75    FocusRoot,
76}
77
78/// Event used to control the state of the open menu. This bubbles upwards from the menu items
79/// and the menu container, through the portal relation, and to the menu owner entity.
80#[derive(impl bevy_ecs::event::Event for MenuEvent where Self: ::core::marker::Send +
    ::core::marker::Sync + 'static {
    type Trigger<'a> =
        bevy_ecs::event::PropagateEntityTrigger<true, Self,
        &'static bevy_ecs::hierarchy::ChildOf>;
}
impl bevy_ecs::event::EntityEvent for MenuEvent where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    fn event_target(&self) -> bevy_ecs::entity::Entity {
        bevy_ecs::entity::ContainsEntity::entity(&self.source)
    }
}
impl bevy_ecs::event::SetEntityEventTarget for MenuEvent where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    fn set_event_target(&mut self, entity: bevy_ecs::entity::Entity) {
        self.source = ::core::convert::Into::into(entity);
    }
}EntityEvent, #[automatically_derived]
impl ::core::clone::Clone for MenuEvent {
    #[inline]
    fn clone(&self) -> Self {
        Self {
            source: ::core::clone::Clone::clone(&self.source),
            action: ::core::clone::Clone::clone(&self.action),
        }
    }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for MenuEvent {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f, "MenuEvent",
            "source", &self.source, "action", &&self.action)
    }
}Debug)]
81#[entity_event(propagate, auto_propagate)]
82#[derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for MenuEvent where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.register_type_data_with::<ReflectEvent, Self,
                    _>(());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Entity as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
                <MenuAction as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for MenuEvent where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Entity>("source"),
                                                bevy_reflect::NamedField::new::<MenuAction>("action")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for MenuEvent where  {
            fn type_path() -> &'static str {
                "bevy_ui_widgets::menu::MenuEvent"
            }
            fn short_type_path() -> &'static str { "MenuEvent" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("MenuEvent")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu")
            }
        }
        impl bevy_reflect::Reflect for MenuEvent where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<MenuEvent
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for MenuEvent where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "source" => ::core::option::Option::Some(&self.source),
                    "action" => ::core::option::Option::Some(&self.action),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "source" => ::core::option::Option::Some(&mut self.source),
                    "action" => ::core::option::Option::Some(&mut self.action),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.source),
                    1usize => ::core::option::Option::Some(&self.action),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.source),
                    1usize => ::core::option::Option::Some(&mut self.action),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("source"),
                    1usize => ::core::option::Option::Some("action"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "source" => ::core::option::Option::Some(0usize),
                    "action" => ::core::option::Option::Some(1usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 2usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                ->
                    ::core::result::Result<bevy_reflect::structs::DynamicStruct,
                    bevy_reflect::ReflectCloneError> {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("source",
                    bevy_reflect::PartialReflect::to_dynamic(&self.source)?);
                dynamic.insert_boxed("action",
                    bevy_reflect::PartialReflect::to_dynamic(&self.action)?);
                ::core::result::Result::Ok(dynamic)
            }
        }
        impl bevy_reflect::PartialReflect for MenuEvent where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            source: <Entity as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.source)?,
                            action: <MenuAction as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.action)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for MenuEvent where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            source: <Entity as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "source")?)?,
                            action: <MenuAction as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "action")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
83#[reflect(Event)]
84pub struct MenuEvent {
85    /// The [`MenuItem`] or [`MenuPopup`] that triggered this event.
86    #[event_target]
87    pub source: Entity,
88
89    /// The desired action in response to this event.
90    pub action: MenuAction,
91}
92
93/// Specifies the layout direction of the menu, for keyboard navigation
94#[derive(#[automatically_derived]
impl ::core::default::Default for MenuLayout {
    #[inline]
    fn default() -> Self { Self::Column }
}Default, #[automatically_derived]
impl ::core::fmt::Debug for MenuLayout {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                MenuLayout::Column => "Column",
                MenuLayout::Row => "Row",
                MenuLayout::Grid => "Grid",
            })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MenuLayout {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::Column => Self::Column,
            Self::Row => Self::Row,
            Self::Grid => Self::Grid,
        }
    }
}Clone, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for MenuLayout { }
#[automatically_derived]
impl ::core::cmp::PartialEq for MenuLayout {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
            ::core::intrinsics::discriminant_value(other)
    }
}PartialEq, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for MenuLayout where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {}
        }
        impl bevy_reflect::Typed for MenuLayout where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Enum(bevy_reflect::enums::EnumInfo::new::<Self>(&[bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("Column")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("Row")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("Grid"))]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for MenuLayout where  {
            fn type_path() -> &'static str {
                "bevy_ui_widgets::menu::MenuLayout"
            }
            fn short_type_path() -> &'static str { "MenuLayout" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("MenuLayout")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu")
            }
        }
        impl bevy_reflect::Reflect for MenuLayout where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<MenuLayout
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::enums::Enum for MenuLayout where  {
            fn field(&self, __name_param: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_at(&self, __index_param: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_mut(&mut self, __name_param: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_at_mut(&mut self, __index_param: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn index_of(&self, __name_param: &str)
                -> ::core::option::Option<usize> {
                match self { _ => ::core::option::Option::None, }
            }
            fn name_at(&self, __index_param: usize)
                -> ::core::option::Option<&str> {
                match self { _ => ::core::option::Option::None, }
            }
            fn iter_fields(&self) -> bevy_reflect::enums::VariantFieldIter {
                bevy_reflect::enums::VariantFieldIter::new(self)
            }
            #[inline]
            fn field_len(&self) -> usize {
                match self {
                    MenuLayout::Column { .. } => 0usize,
                    MenuLayout::Row { .. } => 0usize,
                    MenuLayout::Grid { .. } => 0usize,
                    _ => 0,
                }
            }
            #[inline]
            fn variant_name(&self) -> &str {
                match self {
                    MenuLayout::Column { .. } => "Column",
                    MenuLayout::Row { .. } => "Row",
                    MenuLayout::Grid { .. } => "Grid",
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            #[inline]
            fn variant_index(&self) -> usize {
                match self {
                    MenuLayout::Column { .. } => 0usize,
                    MenuLayout::Row { .. } => 1usize,
                    MenuLayout::Grid { .. } => 2usize,
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            #[inline]
            fn variant_type(&self) -> bevy_reflect::enums::VariantType {
                match self {
                    MenuLayout::Column { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    MenuLayout::Row { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    MenuLayout::Grid { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            fn to_dynamic_enum(&self)
                ->
                    ::core::result::Result<bevy_reflect::enums::DynamicEnum,
                    bevy_reflect::ReflectCloneError> {
                bevy_reflect::enums::DynamicEnum::try_from_ref::<Self>(self)
            }
        }
        impl bevy_reflect::PartialReflect for MenuLayout where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self,
                __value_param: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Enum(__value_param) =
                        bevy_reflect::PartialReflect::reflect_ref(__value_param) {
                    if bevy_reflect::enums::Enum::variant_name(self) ==
                            bevy_reflect::enums::Enum::variant_name(__value_param) {
                        match bevy_reflect::enums::Enum::variant_type(__value_param)
                            {
                            bevy_reflect::enums::VariantType::Struct => {
                                for field in
                                    bevy_reflect::enums::Enum::iter_fields(__value_param) {
                                    let name = field.name().unwrap();
                                    if let ::core::option::Option::Some(v) =
                                            bevy_reflect::enums::Enum::field_mut(self, name) {
                                        bevy_reflect::PartialReflect::try_apply(v, field.value())?;
                                    }
                                }
                            }
                            bevy_reflect::enums::VariantType::Tuple => {
                                for (index, field) in
                                    ::core::iter::Iterator::enumerate(bevy_reflect::enums::Enum::iter_fields(__value_param))
                                    {
                                    if let ::core::option::Option::Some(v) =
                                            bevy_reflect::enums::Enum::field_at_mut(self, index) {
                                        bevy_reflect::PartialReflect::try_apply(v, field.value())?;
                                    }
                                }
                            }
                            _ => {}
                        }
                    } else {
                        match bevy_reflect::enums::Enum::variant_name(__value_param)
                            {
                            "Column" => { *self = MenuLayout::Column {} }
                            "Row" => { *self = MenuLayout::Row {} }
                            "Grid" => { *self = MenuLayout::Grid {} }
                            name => {
                                return ::core::result::Result::Err(bevy_reflect::ApplyError::UnknownVariant {
                                            enum_name: ::core::convert::Into::into(bevy_reflect::DynamicTypePath::reflect_type_path(self)),
                                            variant_name: ::core::convert::Into::into(name),
                                        });
                            }
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(__value_param),
                                to_kind: bevy_reflect::ReflectKind::Enum,
                            });
                }
                ::core::result::Result::Ok(())
            }
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Enum
            }
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Enum(self)
            }
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Enum(self)
            }
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Enum(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_hash(&self) -> ::core::option::Option<u64> {
                (bevy_reflect::enums::enum_hash)(self)
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::enums::enum_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::enums::enum_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                let this = self;
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(match this
                            {
                            MenuLayout::Column {} => MenuLayout::Column {},
                            MenuLayout::Row {} => MenuLayout::Row {},
                            MenuLayout::Grid {} => MenuLayout::Grid {},
                        }))
            }
        }
        impl bevy_reflect::FromReflect for MenuLayout where  {
            fn from_reflect(__param0: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Enum(__param0) =
                        bevy_reflect::PartialReflect::reflect_ref(__param0) {
                    match bevy_reflect::enums::Enum::variant_name(__param0) {
                        "Column" =>
                            ::core::option::Option::Some(MenuLayout::Column {}),
                        "Row" => ::core::option::Option::Some(MenuLayout::Row {}),
                        "Grid" => ::core::option::Option::Some(MenuLayout::Grid {}),
                        name => ::core::option::Option::None,
                    }
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
95pub enum MenuLayout {
96    /// A vertical stack. Up and down arrows to move between items.
97    #[default]
98    Column,
99    /// A horizontal row. Left and right arrows to move between items.
100    Row,
101    /// A 2D grid. Arrow keys are not mapped, you'll need to write your own observer.
102    Grid,
103}
104
105/// Component that defines a popup menu container.
106///
107/// Menus are automatically dismissed when the user clicks outside the menu bounds. Unlike a modal
108/// dialog, where the click event is intercepted, we don't want to actually prevent the click event
109/// from triggering its normal action. The easiest way to detect this kind of click is to look for
110/// keyboard focus loss. When a menu is opened, one of its children will gain focus, and the menu
111/// remains open so long as at least one descendant is focused. Arrow keys can be used to navigate
112/// between menu items.
113///
114/// This means that popup menu *must* contain at least one focusable entity. It also means that two
115/// menus cannot be displayed at the same time unless one is an ancestor of the other.
116///
117/// Some care needs to be taken in implementing a menu button: we normally want menu buttons to
118/// toggle the open state of the menu; but clicking on the button will cause focus loss which means
119/// that the menu will always be closed by the time the click event is processed.
120#[derive(#[doc =
"**Required Components**: [`AccessibilityNode`], [`TabGroup`], [`MenuFocusState`]. \n\n A component's Required Components are inserted whenever it is inserted. Note that this will also insert the required components _of_ the required components, recursively, in depth-first order."]
impl bevy_ecs::component::Component for MenuPopup where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::Table;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {
        required_components.register_required::<AccessibilityNode>(||
                {
                    let x: AccessibilityNode =
                        (||
                                        AccessibilityNode(accesskit::Node::new(Role::MenuListPopup)))().into();
                    x
                });
        required_components.register_required::<TabGroup>(||
                { let x: TabGroup = (|| TabGroup::modal())().into(); x });
        required_components.register_required::<MenuFocusState>(||
                {
                    let x: MenuFocusState =
                        (|| MenuFocusState::Closed)().into();
                    x
                });
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, #[automatically_derived]
impl ::core::fmt::Debug for MenuPopup {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "MenuPopup",
            "layout", &&self.layout)
    }
}Debug, #[automatically_derived]
impl ::core::default::Default for MenuPopup {
    #[inline]
    fn default() -> Self {
        Self { layout: ::core::default::Default::default() }
    }
}Default, #[automatically_derived]
impl ::core::clone::Clone for MenuPopup {
    #[inline]
    fn clone(&self) -> Self {
        Self { layout: ::core::clone::Clone::clone(&self.layout) }
    }
}Clone)]
121#[require(
122    AccessibilityNode(accesskit::Node::new(Role::MenuListPopup)),
123    TabGroup::modal()
124)]
125#[require(MenuFocusState::Closed)]
126#[derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for MenuPopup where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.register_type_data_with::<ReflectComponent, Self,
                    _>(());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <MenuLayout as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for MenuPopup where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<MenuLayout>("layout")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for MenuPopup where  {
            fn type_path() -> &'static str {
                "bevy_ui_widgets::menu::MenuPopup"
            }
            fn short_type_path() -> &'static str { "MenuPopup" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("MenuPopup")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu")
            }
        }
        impl bevy_reflect::Reflect for MenuPopup where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<MenuPopup
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for MenuPopup where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "layout" => ::core::option::Option::Some(&self.layout),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "layout" => ::core::option::Option::Some(&mut self.layout),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.layout),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.layout),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("layout"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "layout" => ::core::option::Option::Some(0usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 1usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                ->
                    ::core::result::Result<bevy_reflect::structs::DynamicStruct,
                    bevy_reflect::ReflectCloneError> {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("layout",
                    bevy_reflect::PartialReflect::to_dynamic(&self.layout)?);
                ::core::result::Result::Ok(dynamic)
            }
        }
        impl bevy_reflect::PartialReflect for MenuPopup where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            layout: <MenuLayout as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.layout)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for MenuPopup where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            layout: <MenuLayout as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "layout")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
127#[reflect(Component)]
128pub struct MenuPopup {
129    /// The layout orientation of the menu
130    pub layout: MenuLayout,
131}
132
133/// Component that defines a menu item.
134#[derive(#[doc =
"**Required Components**: [`AccessibilityNode`]. \n\n A component's Required Components are inserted whenever it is inserted. Note that this will also insert the required components _of_ the required components, recursively, in depth-first order."]
impl bevy_ecs::component::Component for MenuItem where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::Table;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {
        required_components.register_required::<AccessibilityNode>(||
                {
                    let x: AccessibilityNode =
                        (||
                                        AccessibilityNode(accesskit::Node::new(Role::MenuItem)))().into();
                    x
                });
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, #[automatically_derived]
impl ::core::fmt::Debug for MenuItem {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "MenuItem")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MenuItem {
    #[inline]
    fn clone(&self) -> Self { Self }
}Clone, #[automatically_derived]
impl ::core::default::Default for MenuItem {
    #[inline]
    fn default() -> Self { Self }
}Default)]
135#[require(AccessibilityNode(accesskit::Node::new(Role::MenuItem)))]
136#[derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for MenuItem where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.register_type_data_with::<ReflectComponent, Self,
                    _>(());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {}
        }
        impl bevy_reflect::Typed for MenuItem where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for MenuItem where  {
            fn type_path() -> &'static str {
                "bevy_ui_widgets::menu::MenuItem"
            }
            fn short_type_path() -> &'static str { "MenuItem" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("MenuItem")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu")
            }
        }
        impl bevy_reflect::Reflect for MenuItem where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<MenuItem
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for MenuItem where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name { _ => ::core::option::Option::None, }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name { _ => ::core::option::Option::None, }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index { _ => ::core::option::Option::None, }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index { _ => ::core::option::Option::None, }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index { _ => ::core::option::Option::None, }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name { _ => ::core::option::Option::None, }
            }
            fn field_len(&self) -> usize { 0usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                ->
                    ::core::result::Result<bevy_reflect::structs::DynamicStruct,
                    bevy_reflect::ReflectCloneError> {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                ::core::result::Result::Ok(dynamic)
            }
        }
        impl bevy_reflect::PartialReflect for MenuItem where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {}))
            }
        }
        impl bevy_reflect::FromReflect for MenuItem where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this = Self {};
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
137#[reflect(Component)]
138pub struct MenuItem;
139
140/// Component used to manage focus on the popup. Menu popups remain open only so long as they
141/// contain focus.
142#[derive(impl bevy_ecs::component::Component for MenuFocusState where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::Table;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {}
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn map_entities<M: bevy_ecs::entity::EntityMapper>(this: &mut Self,
        mapper: &mut M) {
        use bevy_ecs::entity::MapEntities;
        match this {
            Self::Opening { .. } => {}
            Self::Open { .. } => {}
            Self::Closed { .. } => {}
            _ => {}
        }
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, #[automatically_derived]
impl ::core::fmt::Debug for MenuFocusState {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            Self::Opening(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "Opening", &__self_0),
            Self::Open => ::core::fmt::Formatter::write_str(f, "Open"),
            Self::Closed => ::core::fmt::Formatter::write_str(f, "Closed"),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MenuFocusState {
    #[inline]
    fn clone(&self) -> Self {
        match self {
            Self::Opening(__self_0) =>
                Self::Opening(::core::clone::Clone::clone(__self_0)),
            Self::Open => Self::Open,
            Self::Closed => Self::Closed,
        }
    }
}Clone, #[automatically_derived]
impl ::core::default::Default for MenuFocusState {
    #[inline]
    fn default() -> Self { Self::Closed }
}Default, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for MenuFocusState { }
#[automatically_derived]
impl ::core::cmp::PartialEq for MenuFocusState {
    #[inline]
    fn eq(&self, other: &Self) -> bool {
        ::core::intrinsics::discriminant_value(self) ==
                ::core::intrinsics::discriminant_value(other) &&
            match (self, other) {
                (Self::Opening(__self_0), Self::Opening(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for MenuFocusState where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.register_type_data_with::<ReflectComponent, Self,
                    _>(());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <NavAction as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for MenuFocusState where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Enum(bevy_reflect::enums::EnumInfo::new::<Self>(&[bevy_reflect::enums::VariantInfo::Tuple(bevy_reflect::enums::TupleVariantInfo::new("Opening",
                                                        &[bevy_reflect::UnnamedField::new::<NavAction>(0usize)])),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("Open")),
                                                bevy_reflect::enums::VariantInfo::Unit(bevy_reflect::enums::UnitVariantInfo::new("Closed"))]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for MenuFocusState where  {
            fn type_path() -> &'static str {
                "bevy_ui_widgets::menu::MenuFocusState"
            }
            fn short_type_path() -> &'static str { "MenuFocusState" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("MenuFocusState")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu")
            }
        }
        impl bevy_reflect::Reflect for MenuFocusState where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<MenuFocusState
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::enums::Enum for MenuFocusState where  {
            fn field(&self, __name_param: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_at(&self, __index_param: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match self {
                    MenuFocusState::Opening { 0: __value, .. } if
                        __index_param == 0usize =>
                        ::core::option::Option::Some(__value),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, __name_param: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match self { _ => ::core::option::Option::None, }
            }
            fn field_at_mut(&mut self, __index_param: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match self {
                    MenuFocusState::Opening { 0: __value, .. } if
                        __index_param == 0usize =>
                        ::core::option::Option::Some(__value),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of(&self, __name_param: &str)
                -> ::core::option::Option<usize> {
                match self { _ => ::core::option::Option::None, }
            }
            fn name_at(&self, __index_param: usize)
                -> ::core::option::Option<&str> {
                match self { _ => ::core::option::Option::None, }
            }
            fn iter_fields(&self) -> bevy_reflect::enums::VariantFieldIter {
                bevy_reflect::enums::VariantFieldIter::new(self)
            }
            #[inline]
            fn field_len(&self) -> usize {
                match self {
                    MenuFocusState::Opening { .. } => 1usize,
                    MenuFocusState::Open { .. } => 0usize,
                    MenuFocusState::Closed { .. } => 0usize,
                    _ => 0,
                }
            }
            #[inline]
            fn variant_name(&self) -> &str {
                match self {
                    MenuFocusState::Opening { .. } => "Opening",
                    MenuFocusState::Open { .. } => "Open",
                    MenuFocusState::Closed { .. } => "Closed",
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            #[inline]
            fn variant_index(&self) -> usize {
                match self {
                    MenuFocusState::Opening { .. } => 0usize,
                    MenuFocusState::Open { .. } => 1usize,
                    MenuFocusState::Closed { .. } => 2usize,
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            #[inline]
            fn variant_type(&self) -> bevy_reflect::enums::VariantType {
                match self {
                    MenuFocusState::Opening { .. } =>
                        bevy_reflect::enums::VariantType::Tuple,
                    MenuFocusState::Open { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    MenuFocusState::Closed { .. } =>
                        bevy_reflect::enums::VariantType::Unit,
                    _ =>
                        ::core::panicking::panic("internal error: entered unreachable code"),
                }
            }
            fn to_dynamic_enum(&self)
                ->
                    ::core::result::Result<bevy_reflect::enums::DynamicEnum,
                    bevy_reflect::ReflectCloneError> {
                bevy_reflect::enums::DynamicEnum::try_from_ref::<Self>(self)
            }
        }
        impl bevy_reflect::PartialReflect for MenuFocusState where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self,
                __value_param: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Enum(__value_param) =
                        bevy_reflect::PartialReflect::reflect_ref(__value_param) {
                    if bevy_reflect::enums::Enum::variant_name(self) ==
                            bevy_reflect::enums::Enum::variant_name(__value_param) {
                        match bevy_reflect::enums::Enum::variant_type(__value_param)
                            {
                            bevy_reflect::enums::VariantType::Struct => {
                                for field in
                                    bevy_reflect::enums::Enum::iter_fields(__value_param) {
                                    let name = field.name().unwrap();
                                    if let ::core::option::Option::Some(v) =
                                            bevy_reflect::enums::Enum::field_mut(self, name) {
                                        bevy_reflect::PartialReflect::try_apply(v, field.value())?;
                                    }
                                }
                            }
                            bevy_reflect::enums::VariantType::Tuple => {
                                for (index, field) in
                                    ::core::iter::Iterator::enumerate(bevy_reflect::enums::Enum::iter_fields(__value_param))
                                    {
                                    if let ::core::option::Option::Some(v) =
                                            bevy_reflect::enums::Enum::field_at_mut(self, index) {
                                        bevy_reflect::PartialReflect::try_apply(v, field.value())?;
                                    }
                                }
                            }
                            _ => {}
                        }
                    } else {
                        match bevy_reflect::enums::Enum::variant_name(__value_param)
                            {
                            "Opening" => {
                                *self =
                                    MenuFocusState::Opening {
                                        0: {
                                            let __0 = __value_param.field_at(0usize);
                                            let __0 =
                                                __0.ok_or(bevy_reflect::ApplyError::MissingEnumField {
                                                            variant_name: ::core::convert::Into::into("Opening"),
                                                            field_name: ::core::convert::Into::into(".0"),
                                                        })?;
                                            <NavAction as
                                                            bevy_reflect::FromReflect>::from_reflect(__0).ok_or(bevy_reflect::ApplyError::MismatchedTypes {
                                                        from_type: ::core::convert::Into::into(bevy_reflect::DynamicTypePath::reflect_type_path(__0)),
                                                        to_type: ::core::convert::Into::into(<NavAction as
                                                                    bevy_reflect::TypePath>::type_path()),
                                                    })?
                                        },
                                    }
                            }
                            "Open" => { *self = MenuFocusState::Open {} }
                            "Closed" => { *self = MenuFocusState::Closed {} }
                            name => {
                                return ::core::result::Result::Err(bevy_reflect::ApplyError::UnknownVariant {
                                            enum_name: ::core::convert::Into::into(bevy_reflect::DynamicTypePath::reflect_type_path(self)),
                                            variant_name: ::core::convert::Into::into(name),
                                        });
                            }
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(__value_param),
                                to_kind: bevy_reflect::ReflectKind::Enum,
                            });
                }
                ::core::result::Result::Ok(())
            }
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Enum
            }
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Enum(self)
            }
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Enum(self)
            }
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Enum(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_hash(&self) -> ::core::option::Option<u64> {
                (bevy_reflect::enums::enum_hash)(self)
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::enums::enum_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::enums::enum_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                let this = self;
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(match this
                            {
                            MenuFocusState::Opening { 0: __0 } =>
                                MenuFocusState::Opening {
                                    0: <NavAction as
                                                bevy_reflect::PartialReflect>::reflect_clone_and_take(__0)?,
                                },
                            MenuFocusState::Open {} => MenuFocusState::Open {},
                            MenuFocusState::Closed {} => MenuFocusState::Closed {},
                        }))
            }
        }
        impl bevy_reflect::FromReflect for MenuFocusState where  {
            fn from_reflect(__param0: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Enum(__param0) =
                        bevy_reflect::PartialReflect::reflect_ref(__param0) {
                    match bevy_reflect::enums::Enum::variant_name(__param0) {
                        "Opening" =>
                            ::core::option::Option::Some(MenuFocusState::Opening {
                                    0: {
                                        let __0 = __param0.field_at(0usize);
                                        let __0 = __0?;
                                        <NavAction as bevy_reflect::FromReflect>::from_reflect(__0)?
                                    },
                                }),
                        "Open" =>
                            ::core::option::Option::Some(MenuFocusState::Open {}),
                        "Closed" =>
                            ::core::option::Option::Some(MenuFocusState::Closed {}),
                        name => ::core::option::Option::None,
                    }
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
143#[reflect(Component)]
144pub enum MenuFocusState {
145    /// A newly opened menu, which needs to have focus set to the first or last item depending on
146    /// [`NavAction`].
147    Opening(NavAction),
148    /// Menu is open, and focus is set to an item within the menu
149    Open,
150    /// Menu is no longer visible, and can be cleaned up.
151    #[default]
152    Closed,
153}
154
155/// System set for the system that menus use to acquire focus on one of its items upon first opening.
156/// It potentially modifies [`InputFocus`].
157///
158/// These system runs in the [`PostUpdate`] schedule.
159#[derive(#[automatically_derived]
impl ::core::fmt::Debug for MenuFocusSystem {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "MenuFocusSystem")
    }
}Debug, #[automatically_derived]
impl ::core::marker::StructuralPartialEq for MenuFocusSystem { }
#[automatically_derived]
impl ::core::cmp::PartialEq for MenuFocusSystem {
    #[inline]
    fn eq(&self, other: &Self) -> bool { true }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for MenuFocusSystem { }Eq, #[automatically_derived]
impl ::core::hash::Hash for MenuFocusSystem {
    #[inline]
    fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {}
}Hash, #[automatically_derived]
impl ::core::clone::Clone for MenuFocusSystem {
    #[inline]
    fn clone(&self) -> Self { Self }
}Clone, const _: () =
    {
        extern crate alloc;
        impl bevy_ecs::schedule::SystemSet for MenuFocusSystem where
            Self: 'static + ::core::marker::Send + ::core::marker::Sync +
            ::core::clone::Clone + ::core::cmp::Eq + ::core::fmt::Debug +
            ::core::hash::Hash {
            fn dyn_clone(&self)
                -> alloc::boxed::Box<dyn bevy_ecs::schedule::SystemSet> {
                alloc::boxed::Box::new(::core::clone::Clone::clone(self))
            }
        }
    };SystemSet)]
160pub struct MenuFocusSystem;
161
162/// System that sets the focus to an item in the menu when the menu is opening.
163fn menu_acquire_focus(
164    mut q_menus: Query<(Entity, &mut MenuFocusState), With<MenuPopup>>,
165    mut focus: ResMut<InputFocus>,
166    tab_navigation: TabNavigation,
167) {
168    for (menu, mut menu_focus) in q_menus.iter_mut() {
169        // When a menu is spawned, attempt to find the first focusable menu item, and set focus
170        // to it.
171        if let MenuFocusState::Opening(nav) = *menu_focus {
172            match tab_navigation.initialize(menu, nav) {
173                Ok(next) => {
174                    *menu_focus = MenuFocusState::Open;
175                    focus.set(next, FocusCause::Navigated);
176                }
177                Err(e) => {
178                    {
    use ::tracing::__macro_support::Callsite as _;
    static __CALLSITE: ::tracing::callsite::DefaultCallsite =
        {
            static META: ::tracing::Metadata<'static> =
                {
                    ::tracing_core::metadata::Metadata::new("event src/menu.rs:178",
                        "bevy_ui_widgets::menu", ::tracing::Level::WARN,
                        ::tracing_core::__macro_support::Option::Some("src/menu.rs"),
                        ::tracing_core::__macro_support::Option::Some(178u32),
                        ::tracing_core::__macro_support::Option::Some("bevy_ui_widgets::menu"),
                        ::tracing_core::field::FieldSet::new(&["message"],
                            ::tracing_core::callsite::Identifier(&__CALLSITE)),
                        ::tracing::metadata::Kind::EVENT)
                };
            ::tracing::callsite::DefaultCallsite::new(&META)
        };
    let enabled =
        ::tracing::Level::WARN <= ::tracing::level_filters::STATIC_MAX_LEVEL
                &&
                ::tracing::Level::WARN <=
                    ::tracing::level_filters::LevelFilter::current() &&
            {
                let interest = __CALLSITE.interest();
                !interest.is_never() &&
                    ::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
                        interest)
            };
    if enabled {
        (|value_set: ::tracing::field::ValueSet|
                    {
                        let meta = __CALLSITE.metadata();
                        ::tracing::Event::dispatch(meta, &value_set);
                        ;
                    })({
                #[allow(unused_imports)]
                use ::tracing::field::{debug, display, Value};
                __CALLSITE.metadata().fields().value_set_all(&[(::tracing::__macro_support::Option::Some(&format_args!("No focusable menu items for popup menu: {0}, error: {1:?}",
                                                    menu, e) as &dyn ::tracing::field::Value))])
            });
    } else { ; }
};warn!(
179                        "No focusable menu items for popup menu: {}, error: {:?}",
180                        menu, e
181                    );
182                }
183            }
184        }
185    }
186}
187
188fn menu_on_lose_focus(
189    mut q_menus: Query<(Entity, &mut MenuFocusState), With<MenuPopup>>,
190    q_parent: Query<&ChildOf>,
191    focus: Res<InputFocus>,
192    mut commands: Commands,
193) {
194    // Close any menu which doesn't contain the focus entity.
195    for (menu, mut menu_focus) in q_menus.iter_mut() {
196        match *menu_focus {
197            MenuFocusState::Opening(_) | MenuFocusState::Open => {
198                // TODO: Change this logic when we support submenus. Don't want to send multiple close
199                // events. Perhaps what we can do is add `MenuLostFocus` to the whole stack.
200                let contains_focus = match focus.get() {
201                    Some(focus_ent) => {
202                        focus_ent == menu
203                            || q_parent.iter_ancestors(focus_ent).any(|ent| ent == menu)
204                    }
205                    None => false,
206                };
207
208                if !contains_focus {
209                    *menu_focus = MenuFocusState::Closed;
210                    commands.trigger(MenuEvent {
211                        source: menu,
212                        action: MenuAction::CloseAll,
213                    });
214                }
215            }
216
217            _ => {}
218        }
219    }
220}
221
222fn menu_on_key_event(
223    mut ev: On<FocusedInput<KeyboardInput>>,
224    q_item: Query<Has<InteractionDisabled>, With<MenuItem>>,
225    q_popup: Query<&MenuPopup>,
226    tab_navigation: TabNavigation,
227    mut focus: ResMut<InputFocus>,
228    mut commands: Commands,
229) {
230    if let Ok(disabled) = q_item.get(ev.focused_entity) {
231        if !disabled {
232            let event = &ev.event().input;
233            let entity = ev.event().focused_entity;
234            if !event.repeat && event.state == ButtonState::Pressed {
235                match event.key_code {
236                    // Activate the item and close the popup
237                    KeyCode::Enter | KeyCode::Space => {
238                        ev.propagate(false);
239                        // Trigger the action for this menu item.
240                        commands.trigger(Activate { entity });
241                        // Set the focus to the menu button.
242                        commands.trigger(MenuEvent {
243                            source: entity,
244                            action: MenuAction::FocusRoot,
245                        });
246                        // Close the stack
247                        commands.trigger(MenuEvent {
248                            source: entity,
249                            action: MenuAction::CloseAll,
250                        });
251                    }
252
253                    _ => (),
254                }
255            }
256        }
257    } else if let Ok(menu) = q_popup.get(ev.focused_entity) {
258        let event = &ev.event().input;
259        if !event.repeat && event.state == ButtonState::Pressed {
260            match event.key_code {
261                // Close the popup
262                KeyCode::Escape => {
263                    ev.propagate(false);
264                    // Close the stack
265                    commands.trigger(MenuEvent {
266                        source: ev.focused_entity,
267                        action: MenuAction::CloseAll,
268                    });
269                    // Set the focus to the menu button.
270                    commands.trigger(MenuEvent {
271                        source: ev.focused_entity,
272                        action: MenuAction::FocusRoot,
273                    });
274                }
275
276                // Focus the adjacent item in the up direction
277                KeyCode::ArrowUp if menu.layout == MenuLayout::Column => {
278                    ev.propagate(false);
279                    if let Ok(next) = tab_navigation.navigate(&focus, NavAction::Previous) {
280                        focus.set(next, FocusCause::Navigated);
281                    } else {
282                        focus.clear();
283                    }
284                }
285
286                // Focus the adjacent item in the down direction
287                KeyCode::ArrowDown if menu.layout == MenuLayout::Column => {
288                    ev.propagate(false);
289                    if let Ok(next) = tab_navigation.navigate(&focus, NavAction::Next) {
290                        focus.set(next, FocusCause::Navigated);
291                    } else {
292                        focus.clear();
293                    }
294                }
295
296                // Focus the adjacent item in the left direction
297                KeyCode::ArrowLeft if menu.layout == MenuLayout::Row => {
298                    ev.propagate(false);
299                    if let Ok(next) = tab_navigation.navigate(&focus, NavAction::Previous) {
300                        focus.set(next, FocusCause::Navigated);
301                    } else {
302                        focus.clear();
303                    }
304                }
305
306                // Focus the adjacent item in the right direction
307                KeyCode::ArrowRight if menu.layout == MenuLayout::Row => {
308                    ev.propagate(false);
309                    if let Ok(next) = tab_navigation.navigate(&focus, NavAction::Next) {
310                        focus.set(next, FocusCause::Navigated);
311                        focus.clear();
312                    }
313                }
314
315                // Focus the first item
316                KeyCode::Home => {
317                    ev.propagate(false);
318                    if let Ok(next) = tab_navigation.navigate(&focus, NavAction::First) {
319                        focus.set(next, FocusCause::Navigated);
320                    } else {
321                        focus.clear();
322                    }
323                }
324
325                // Focus the last item
326                KeyCode::End => {
327                    ev.propagate(false);
328                    if let Ok(next) = tab_navigation.navigate(&focus, NavAction::Last) {
329                        focus.set(next, FocusCause::Navigated);
330                    } else {
331                        focus.clear();
332                    }
333                }
334
335                _ => (),
336            }
337        }
338    }
339}
340
341fn menu_item_on_pointer_click(
342    mut ev: On<PointerClick>,
343    mut q_state: Query<(Has<Pressed>, Has<InteractionDisabled>), With<MenuItem>>,
344    mut commands: Commands,
345) {
346    if let Ok((pressed, disabled)) = q_state.get_mut(ev.entity) {
347        ev.propagate(false);
348        if pressed && !disabled {
349            // Trigger the menu action.
350            commands.trigger(Activate { entity: ev.entity });
351            // Set the focus to the menu button.
352            commands.trigger(MenuEvent {
353                source: ev.entity,
354                action: MenuAction::FocusRoot,
355            });
356            // Close the stack
357            commands.trigger(MenuEvent {
358                source: ev.entity,
359                action: MenuAction::CloseAll,
360            });
361        }
362    }
363}
364
365fn menu_item_on_pointer_down(
366    mut ev: On<PointerPress>,
367    mut q_state: Query<(Entity, Has<InteractionDisabled>, Has<Pressed>), With<MenuItem>>,
368    mut commands: Commands,
369) {
370    if let Ok((item, disabled, pressed)) = q_state.get_mut(ev.entity) {
371        ev.propagate(false);
372        if !disabled && !pressed {
373            commands.entity(item).insert(Pressed);
374        }
375    }
376}
377
378fn menu_item_on_pointer_up(
379    mut ev: On<PointerRelease>,
380    mut q_state: Query<(Entity, Has<InteractionDisabled>, Has<Pressed>), With<MenuItem>>,
381    mut commands: Commands,
382) {
383    if let Ok((item, disabled, pressed)) = q_state.get_mut(ev.entity) {
384        ev.propagate(false);
385        if !disabled && pressed {
386            commands.entity(item).remove::<Pressed>();
387        }
388    }
389}
390
391fn menu_item_on_pointer_drag_end(
392    mut ev: On<PointerDragEnd>,
393    mut q_state: Query<(Entity, Has<InteractionDisabled>, Has<Pressed>), With<MenuItem>>,
394    mut commands: Commands,
395) {
396    if let Ok((item, disabled, pressed)) = q_state.get_mut(ev.entity) {
397        ev.propagate(false);
398        if !disabled && pressed {
399            commands.entity(item).remove::<Pressed>();
400        }
401    }
402}
403
404fn menu_item_on_pointer_cancel(
405    mut ev: On<PointerCancel>,
406    mut q_state: Query<(Entity, Has<InteractionDisabled>, Has<Pressed>), With<MenuItem>>,
407    mut commands: Commands,
408) {
409    if let Ok((item, disabled, pressed)) = q_state.get_mut(ev.entity) {
410        ev.propagate(false);
411        if !disabled && pressed {
412            commands.entity(item).remove::<Pressed>();
413        }
414    }
415}
416
417/// Headless menu button widget. This is meant to be combined with the `Button` component, and
418/// adds a few more key codes - arrow keys to open the popup.
419#[derive(#[doc =
"**Required Components**: [`AccessibilityNode`], [`Button`], [`ActivateOnPress`]. \n\n A component's Required Components are inserted whenever it is inserted. Note that this will also insert the required components _of_ the required components, recursively, in depth-first order."]
impl bevy_ecs::component::Component for MenuButton where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    const STORAGE_TYPE: bevy_ecs::component::StorageType =
        bevy_ecs::component::StorageType::Table;
    type Mutability = bevy_ecs::component::Mutable;
    fn register_required_components(_requiree:
            bevy_ecs::component::ComponentId,
        required_components:
            &mut bevy_ecs::component::RequiredComponentsRegistrator) {
        required_components.register_required::<AccessibilityNode>(||
                {
                    let x: AccessibilityNode =
                        (||
                                        AccessibilityNode(accesskit::Node::new(Role::Button)))().into();
                    x
                });
        required_components.register_required::<Button>(<Button as
                ::core::default::Default>::default);
        required_components.register_required::<ActivateOnPress>(<ActivateOnPress
                as ::core::default::Default>::default);
    }
    fn clone_behavior() -> bevy_ecs::component::ComponentCloneBehavior {
        use bevy_ecs::component::{
            DefaultCloneBehaviorBase, DefaultCloneBehaviorViaClone,
        };
        (&&&bevy_ecs::component::DefaultCloneBehaviorSpecialization::<Self>::default()).default_clone_behavior()
    }
    fn relationship_accessor()
        ->
            ::core::option::Option<bevy_ecs::relationship::ComponentRelationshipAccessor<Self>> {
        ::core::option::Option::None
    }
}Component, #[automatically_derived]
impl ::core::default::Default for MenuButton {
    #[inline]
    fn default() -> Self { Self }
}Default, #[automatically_derived]
impl ::core::fmt::Debug for MenuButton {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "MenuButton")
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for MenuButton {
    #[inline]
    fn clone(&self) -> Self { Self }
}Clone)]
420#[require(
421    AccessibilityNode(accesskit::Node::new(Role::Button)),
422    Button,
423    ActivateOnPress
424)]
425#[derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for MenuButton where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert(<bevy_reflect::ReflectFromPtr as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.insert(<bevy_reflect::ReflectFromReflect as
                            bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
                registration.register_type_data_with::<ReflectComponent, Self,
                    _>(());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {}
        }
        impl bevy_reflect::Typed for MenuButton where  {
            #[inline(never)]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(#[inline(never)] ||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for MenuButton where  {
            fn type_path() -> &'static str {
                "bevy_ui_widgets::menu::MenuButton"
            }
            fn short_type_path() -> &'static str { "MenuButton" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("MenuButton")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ui_widgets::menu")
            }
        }
        impl bevy_reflect::Reflect for MenuButton where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        #[allow(non_upper_case_globals)]
        const _: () =
            {
                static __INVENTORY: ::inventory::Node =
                    ::inventory::Node {
                        value: &{
                                bevy_reflect::__macro_exports::auto_register::AutomaticReflectRegistrations(<MenuButton
                                        as
                                        bevy_reflect::__macro_exports::auto_register::RegisterForReflection>::__register)
                            },
                        next: ::inventory::__private::UnsafeCell::new(::inventory::__private::Option::None),
                    };
                #[link_section = ".text.startup"]
                unsafe extern "C" fn __ctor() {
                    unsafe {
                        ::inventory::ErasedNode::submit(__INVENTORY.value,
                            &__INVENTORY)
                    }
                }
                #[used]
                #[link_section = ".init_array"]
                static __CTOR: unsafe extern "C" fn() = __ctor;
            };
        impl bevy_reflect::structs::Struct for MenuButton where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name { _ => ::core::option::Option::None, }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name { _ => ::core::option::Option::None, }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index { _ => ::core::option::Option::None, }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index { _ => ::core::option::Option::None, }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index { _ => ::core::option::Option::None, }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name { _ => ::core::option::Option::None, }
            }
            fn field_len(&self) -> usize { 0usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                ->
                    ::core::result::Result<bevy_reflect::structs::DynamicStruct,
                    bevy_reflect::ReflectCloneError> {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                ::core::result::Result::Ok(dynamic)
            }
        }
        impl bevy_reflect::PartialReflect for MenuButton where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {}))
            }
        }
        impl bevy_reflect::FromReflect for MenuButton where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this = Self {};
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect)]
426#[reflect(Component)]
427pub struct MenuButton;
428
429fn menubutton_on_activate(
430    activate: On<Activate>,
431    q_menu_button: Query<Has<InteractionDisabled>, With<MenuButton>>,
432    mut commands: Commands,
433) {
434    if let Ok(disabled) = q_menu_button.get(activate.entity)
435        && !disabled
436    {
437        commands.trigger(MenuEvent {
438            source: activate.entity,
439            action: MenuAction::Toggle,
440        });
441    }
442}
443
444fn menubutton_on_key_event(
445    mut event: On<FocusedInput<KeyboardInput>>,
446    q_menu_button: Query<Has<InteractionDisabled>, With<MenuButton>>,
447    mut commands: Commands,
448) {
449    if let Ok(disabled) = q_menu_button.get(event.focused_entity) {
450        if disabled {
451            return;
452        }
453        let input_event = &event.input;
454        if !input_event.repeat && input_event.state == ButtonState::Pressed {
455            match input_event.key_code {
456                // Focus the last item in the menu
457                KeyCode::ArrowUp | KeyCode::ArrowLeft => {
458                    event.propagate(false);
459                    commands.trigger(MenuEvent {
460                        action: MenuAction::Open(NavAction::Last),
461                        source: event.focused_entity,
462                    });
463                }
464
465                // Focus the first item in the menu
466                KeyCode::ArrowDown | KeyCode::ArrowRight => {
467                    event.propagate(false);
468                    commands.trigger(MenuEvent {
469                        action: MenuAction::Open(NavAction::First),
470                        source: event.focused_entity,
471                    });
472                }
473
474                _ => {}
475            }
476        }
477    }
478}
479
480/// Plugin that adds the observers for the [`MenuItem`] component.
481pub struct MenuPlugin;
482
483impl Plugin for MenuPlugin {
484    fn build(&self, app: &mut App) {
485        app.add_systems(
486            PostUpdate,
487            (
488                menu_acquire_focus.in_set(MenuFocusSystem),
489                menu_on_lose_focus,
490            )
491                .chain()
492                .after(VisibilitySystems::VisibilityPropagate)
493                .before(InputFocusSystems::FocusChangeEvents)
494                .before(text_input_autoscroll_system)
495                .before(UiSystems::PostLayout),
496        )
497        .add_observer(menu_on_key_event)
498        .add_observer(menu_item_on_pointer_down)
499        .add_observer(menu_item_on_pointer_up)
500        .add_observer(menu_item_on_pointer_click)
501        .add_observer(menu_item_on_pointer_drag_end)
502        .add_observer(menu_item_on_pointer_cancel)
503        .add_observer(menubutton_on_key_event)
504        .add_observer(menubutton_on_activate);
505    }
506}
507
508#[cfg(test)]
509mod tests {
510    use super::*;
511    use bevy_ecs::resource::Resource;
512    use bevy_input::InputPlugin;
513    use bevy_input_focus::{tab_navigation::TabIndex, InputFocusPlugin};
514    use bevy_window::{PrimaryWindow, Window};
515
516    /// Counts `MenuEvent`s with `CloseAll`, so tests can assert the menu asked to close.
517    #[derive(Resource, Default)]
518    struct CloseAllCount(usize);
519
520    fn count_close_all(event: On<MenuEvent>, mut count: ResMut<CloseAllCount>) {
521        // `MenuEvent` bubbles up the `ChildOf` chain, so this observer runs once per ancestor. Count
522        // only the original target hop to get one increment per triggered event.
523        if matches!(event.action, MenuAction::CloseAll)
524            && event.event_target() == event.original_event_target()
525        {
526            count.0 += 1;
527        }
528    }
529
530    fn menu_app() -> (App, Entity) {
531        let mut app = App::new();
532        app.add_plugins((InputPlugin, InputFocusPlugin, MenuPlugin));
533        app.init_resource::<CloseAllCount>();
534        app.add_observer(count_close_all);
535        let window = app
536            .world_mut()
537            .spawn((Window::default(), PrimaryWindow))
538            .id();
539        app.update();
540        (app, window)
541    }
542
543    /// Spawns an open popup (state `Open`) with a single focusable menu item, and focuses that item —
544    /// the steady state of a menu that is open and holding focus.
545    fn spawn_open_menu(app: &mut App, window: Entity) -> (Entity, Entity) {
546        let popup = app
547            .world_mut()
548            .spawn((MenuPopup::default(), MenuFocusState::Open, ChildOf(window)))
549            .id();
550        let item = app
551            .world_mut()
552            .spawn((MenuItem, TabIndex(0), ChildOf(popup)))
553            .id();
554        app.world_mut()
555            .resource_mut::<InputFocus>()
556            .set(item, FocusCause::Navigated);
557        app.update();
558        (popup, item)
559    }
560
561    /// While a menu item holds focus, the menu stays open.
562    #[test]
563    fn menu_stays_open_while_item_focused() {
564        let (mut app, window) = menu_app();
565        let (popup, _item) = spawn_open_menu(&mut app, window);
566
567        app.update();
568
569        assert_eq!(
570            *app.world().entity(popup).get::<MenuFocusState>().unwrap(),
571            MenuFocusState::Open,
572            "menu must remain open while one of its items holds focus"
573        );
574        assert_eq!(app.world().resource::<CloseAllCount>().0, 0);
575    }
576
577    /// When focus leaves the popup subtree (e.g. clicking the trigger or outside), the menu
578    /// transitions to `Closed` and requests `CloseAll` — exactly once, no reopen flicker.
579    #[test]
580    fn menu_closes_when_focus_leaves() {
581        let (mut app, window) = menu_app();
582        let (popup, _item) = spawn_open_menu(&mut app, window);
583
584        // Move focus outside the popup (as clicking the trigger button / empty space would).
585        let outside = app.world_mut().spawn((TabIndex(0), ChildOf(window))).id();
586        app.world_mut()
587            .resource_mut::<InputFocus>()
588            .set(outside, FocusCause::Navigated);
589        app.update();
590
591        assert_eq!(
592            *app.world().entity(popup).get::<MenuFocusState>().unwrap(),
593            MenuFocusState::Closed,
594            "menu must close once focus leaves its subtree"
595        );
596        assert_eq!(
597            app.world().resource::<CloseAllCount>().0,
598            1,
599            "closing must fire exactly one CloseAll (no open/close/reopen flicker)"
600        );
601
602        // A subsequent frame must not fire another CloseAll now that the menu is Closed.
603        app.update();
604        assert_eq!(app.world().resource::<CloseAllCount>().0, 1);
605    }
606
607    /// When focus is cleared entirely (`None`), the menu also closes.
608    #[test]
609    fn menu_closes_when_focus_cleared() {
610        let (mut app, window) = menu_app();
611        let (popup, _item) = spawn_open_menu(&mut app, window);
612
613        app.world_mut().resource_mut::<InputFocus>().clear();
614        app.update();
615
616        assert_eq!(
617            *app.world().entity(popup).get::<MenuFocusState>().unwrap(),
618            MenuFocusState::Closed,
619        );
620        assert_eq!(app.world().resource::<CloseAllCount>().0, 1);
621    }
622}