/// TODO: Sorted list/set /// use bevy::{prelude::*, window::PrimaryWindow}; pub struct GameUiPlugin; impl Plugin for GameUiPlugin { fn build(&self, app: &mut App) { app.add_systems( Update, ( init_ui_nav, init_ui_tab, // UI lists init_ui_list, // UI Set init_ui_set, // Buttons init_ui_button, manage_button_interaction, // Cursor manage_cursor, // Initialize name labels init_name, ), ); } } fn init_name( events: Query< (Entity, &Name), ( Added, Or<( With, With, With, With, With, )>, ), >, mut commands: Commands, ) { events.iter().for_each(|(entity, name)| { commands.entity(entity).with_children(|parent| { parent.spawn( TextBundle::from_section(name, TextStyle { ..default() }).with_style(Style { top: Val::Px(0.0), left: Val::Px(0.0), ..default() }), ); }); }); } /// Ui Navigation #[derive(Debug, Component)] pub struct GameUiNav; fn init_ui_nav(events: Query>, mut commands: Commands) { events.iter().for_each(|entity| { let parent = commands .spawn(NodeBundle { style: Style { flex_direction: FlexDirection::Row, ..default() }, background_color: BackgroundColor(Color::PINK), ..default() }) .id(); commands .entity(entity) .insert(NodeBundle { style: Style { ..default() }, ..default() }) .set_parent(parent); }); } /// Ui Tab Element #[derive(Debug, Component)] pub struct GameUiTab; fn init_ui_tab(events: Query>, mut commands: Commands) { events.iter().for_each(|entity| { let parent = commands .spawn(NodeBundle { style: Style { flex_direction: FlexDirection::Column, ..default() }, ..default() }) .id(); commands .entity(entity) .insert(NodeBundle { style: Style { flex_wrap: FlexWrap::Wrap, ..default() }, background_color: BackgroundColor(Color::TEAL), ..default() }) .set_parent(parent); }); } /// Describes the state of an element #[derive(Debug, Component)] pub enum UiElementState { Enabled, Disabled, Active, Error, } /// GameUiList for holding ordered collections of objects #[derive(Debug, Component)] pub struct GameUiList; /// Manage UI Lists: lists of UI entities. fn init_ui_list(events: Query>, mut commands: Commands) { events.iter().for_each(|entity| { commands.entity(entity).insert(NodeBundle { style: Style { flex_direction: FlexDirection::Column, justify_items: JustifyItems::Center, border: UiRect::all(Val::Px(2.0)), margin: UiRect::all(Val::Px(2.0)), padding: UiRect::all(Val::Px(2.0)), ..default() }, background_color: BackgroundColor(Color::RED), border_color: BorderColor(Color::BLACK), ..default() }); }); } /// GameUiSet Component for holding collections of objects #[derive(Debug, Component)] pub struct GameUiSet; /// Manage UI Sets: collections of UI entities. fn init_ui_set(events: Query>, mut commands: Commands) { events.iter().for_each(|entity| { let parent = commands .spawn(NodeBundle { style: Style { flex_direction: FlexDirection::Column, padding: UiRect::all(Val::Px(5.0)), margin: UiRect::all(Val::Px(5.0)), ..default() }, background_color: BackgroundColor(Color::BLUE), border_color: BorderColor(Color::BLACK), ..default() }) .id(); commands .entity(entity) .insert(NodeBundle { style: Style { flex_direction: FlexDirection::Row, flex_wrap: FlexWrap::Wrap, border: UiRect::all(Val::Px(2.0)), margin: UiRect::all(Val::Px(2.0)), padding: UiRect::all(Val::Px(2.0)), ..default() }, background_color: BackgroundColor(Color::BLUE), border_color: BorderColor(Color::BLACK), ..default() }) .set_parent(parent); }); } /// GameUiButton for interactive elements #[derive(Debug, Component)] pub struct GameUiButton; /// Manage UI Buttons. interactive buttons. fn init_ui_button(events: Query>, mut commands: Commands) { events.iter().for_each(|entity| { commands.entity(entity).insert(( ButtonBundle { style: Style { margin: UiRect::all(Val::Px(2.0)), padding: UiRect::all(Val::Px(2.0)), border: UiRect::all(Val::Px(2.0)), ..default() }, background_color: BackgroundColor(Color::GREEN), border_color: BorderColor(Color::BLACK), ..default() }, UiElementState::Enabled, )); }); } /// Manage button style for interactivity fn manage_button_interaction( mut events: Query< (&Interaction, &UiElementState, &mut BackgroundColor), (Changed, With