bevy_ui_navigation/
components.rs

1//! Focusable components and bundles to ease navigable UI declaration.
2use bevy::prelude::{Bundle, ButtonBundle, Component, NodeBundle};
3
4use crate::{
5    menu::{MenuBuilder, MenuSetting, NavMarker},
6    resolve::Focusable,
7};
8
9/// A button like the default bevy [`ButtonBundle`], but with an added
10/// [`Focusable`] component so that it can be used with this crate.
11#[derive(Default, Clone, Bundle)]
12pub struct FocusableButtonBundle {
13    /// The bevy components.
14    pub button_bundle: ButtonBundle,
15    /// The [`Focusable`] type.
16    pub focus: Focusable,
17}
18impl From<ButtonBundle> for FocusableButtonBundle {
19    fn from(button_bundle: ButtonBundle) -> Self {
20        FocusableButtonBundle {
21            button_bundle,
22            ..Default::default()
23        }
24    }
25}
26
27/// A [`NodeBundle`] delimiting a menu,
28/// which [`Focusable`] will be marked with `marker`.
29///
30/// - See [`MenuSetting`] for details on how menus work.
31/// - See [`NavMarker`] for how marking works.
32#[derive(Bundle)]
33pub struct MarkingMenuBundle<T: Component> {
34    /// How navigation within that menu works.
35    pub setting: MenuSetting,
36    /// Specify from where this menu is reachable.
37    pub builder: MenuBuilder,
38    /// What component of type `T` to add to all [`Focusable`]s within
39    /// this menu.
40    pub marker: NavMarker<T>,
41    /// The bevy components.
42    pub node: NodeBundle,
43}
44/// A [`NodeBundle`] delimiting a menu.
45///
46/// - See [`MenuSetting`] for details on how menus work.
47/// - Use [`MenuBundle::marking`] if you need [`Focusable`]s in your menu to
48///   share a specific component.
49#[derive(Clone, Bundle)]
50pub struct MenuBundle {
51    /// How navigation within that menu works.
52    pub setting: MenuSetting,
53    /// Specify from where this menu is reachable.
54    pub builder: MenuBuilder,
55    /// The bevy components.
56    pub node: NodeBundle,
57}
58impl MenuBundle {
59    /// Add `marker` to all [`Focusable`]s in this menu whenever it is created.
60    ///
61    /// See [`NavMarker`] for how marking works.
62    pub fn marking<T: Component>(self, marker: T) -> MarkingMenuBundle<T> {
63        let Self {
64            setting,
65            builder,
66            node,
67        } = self;
68        MarkingMenuBundle {
69            setting,
70            builder,
71            marker: NavMarker(marker),
72            node,
73        }
74    }
75}