use bevy::ecs::system::EntityCommands;
use bevy::prelude::*;
use bevy_ui_navigation::prelude::{
DefaultNavigationPlugins, FocusState, Focusable, NavRequestSystem, NavigationDsl,
};
use bevy_ui_navigation::systems::InputMapping;
use cuicui_chirp::{parse_dsl_impl, ChirpBundle};
use cuicui_layout::{DslBundle, LayoutRootCamera};
use cuicui_layout_bevy_ui::UiDsl;
#[derive(Default, Deref, DerefMut)]
struct UltimateMenuDsl {
#[deref]
inner: NavigationDsl<UiDsl>,
}
#[parse_dsl_impl(delegate = inner)]
impl UltimateMenuDsl {}
impl DslBundle for UltimateMenuDsl {
fn insert(&mut self, cmds: &mut EntityCommands) {
self.inner.insert(cmds);
}
}
fn main() {
let primary_window = Some(Window {
resolution: (1280., 720.).into(),
..default()
});
App::new()
.add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window,
..default()
}),
DefaultNavigationPlugins,
cuicui_chirp::loader::Plugin::new::<UltimateMenuDsl>(),
cuicui_layout_bevy_ui::Plugin,
))
.add_systems(Startup, setup)
.add_systems(
Update,
(
block_some_focusables.before(NavRequestSystem),
button_system.after(NavRequestSystem),
),
)
.run();
}
fn block_some_focusables(
mut focusables: Query<&mut Focusable>,
mut blocked_index: Local<usize>,
time: Res<Time>,
) {
let delta = time.delta_seconds_f64();
let current_time = time.elapsed_seconds_f64();
let at_interval = |t: f64| current_time % t < delta;
if at_interval(3.0) {
let mut skipped = focusables.iter_mut().skip(*blocked_index);
if skipped.len() == 0 {
*blocked_index = 0;
}
*blocked_index += 3;
for mut to_unblock in skipped.by_ref().take(3) {
to_unblock.unblock();
}
for mut to_block in skipped.take(3) {
to_block.block();
}
}
}
fn button_system(
mut interaction_query: Query<(&Focusable, &mut BackgroundColor), Changed<Focusable>>,
) {
for (focus, mut material) in interaction_query.iter_mut() {
let color = match focus.state() {
FocusState::Focused => Color::ORANGE_RED,
FocusState::Active => Color::GOLD,
FocusState::Prioritized => Color::GRAY,
FocusState::Inert => Color::DARK_GRAY,
FocusState::Blocked => Color::ANTIQUE_WHITE,
};
*material = color.into();
}
}
fn setup(mut commands: Commands, mut input_mapping: ResMut<InputMapping>, serv: Res<AssetServer>) {
input_mapping.keyboard_navigation = true;
input_mapping.focus_follows_mouse = true;
commands.spawn((Camera2dBundle::default(), LayoutRootCamera));
commands.spawn(ChirpBundle::new(serv.load("ultimate_menu.chirp")));
}