diff --git a/bin/ui-wtf.rs b/bin/ui-wtf.rs index 30f4298..bbb8299 100644 --- a/bin/ui-wtf.rs +++ b/bin/ui-wtf.rs @@ -72,45 +72,63 @@ fn init_ui(mut commands: Commands) { )); commands - .spawn((GameUiNav, NodeBundle { ..default() })) + .spawn(NodeBundle { + style: Style { + height: Val::Percent(100.0), + width: Val::Percent(100.0), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + ..default() + }, + background_color: BackgroundColor(Color::GRAY), + ..default() + }) .with_children(|parent| { parent .spawn(( - GameUiTab, - Name::new("Grow/Shrink Container"), + GameUi::Nav, + // Name::new("Game Nav"), NodeBundle { ..default() }, )) .with_children(|parent| { - parent.spawn((Container, GameUiSet, NodeBundle { ..default() })); - }); + parent + .spawn(( + GameUi::Tab, + Name::new("Grow/Shrink Tab"), + NodeBundle { ..default() }, + )) + .with_children(|parent| { + parent.spawn(( + Container, + GameUi::Set, + // Name::new("Grow/Shrink Set"), + NodeBundle { ..default() }, + )); + }); - parent - .spawn(( - GameUiTab, - Name::new("Cursor Icons"), - NodeBundle { - background_color: BackgroundColor(Color::BLACK), - ..default() - }, - )) - .with_children(|parent| { parent .spawn(( - GameUiTab, - NodeBundle { - background_color: BackgroundColor(Color::BLACK), - ..default() - }, + GameUi::Tab, + Name::new("Cursor Icons Tab"), + NodeBundle { ..default() }, )) .with_children(|parent| { - CURSORS.iter().for_each(|&icon| { - parent.spawn(( - GameUiButton, - Name::new(format!("{:?}", icon)), + parent + .spawn(( + GameUi::Set, + // Name::new("Cursor Icons Set"), NodeBundle { ..default() }, - Icon(icon), - )); - }); + )) + .with_children(|parent| { + CURSORS.iter().for_each(|&icon| { + parent.spawn(( + GameUi::Button, + Name::new(format!("{:?}", icon)), + NodeBundle { ..default() }, + Icon(icon), + )); + }); + }); }); }); }); @@ -155,7 +173,7 @@ fn container( (Some(KeyCode::Up), ButtonState::Pressed) => { commands.entity(root.single()).with_children(|parent| { parent.spawn(( - GameUiButton, + GameUi::Button, Name::new("asdfwtf"), NodeBundle { ..default() }, )); diff --git a/src/ui.rs b/src/ui.rs index de7df98..ad4802c 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,250 +1,210 @@ -/// TODO: Sorted list/set -/// +/// TODO: +/// * Titles on top left of window/tab +/// * 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, - ), - ); + app.add_systems(PreUpdate, (spawn_nav, spawn_tab, spawn_set, spawn_button)) + .add_systems(Update, (manage_names, manage_tab)); } } -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() - }), - ); - }); - }); +/// Component for marking UI Nodes +#[derive(Component, PartialEq)] +pub enum GameUi { + /// Navigation container + Nav, + /// Tab container + Tab, + /// Game UI Set + Set, + /// Game UI Button + Button, } -/// 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 { +fn spawn_nav(events: Query<(Entity, &GameUi), Added>, mut commands: Commands) { + events + .iter() + .filter(|(_, ui)| **ui == GameUi::Nav) + .for_each(|(entity, _)| { + info!("Spawning Nav UI"); + commands.entity(entity).insert(NodeBundle { style: Style { - flex_direction: FlexDirection::Row, + flex_direction: FlexDirection::Row, // ? + padding: UiRect::all(Val::Px(3.0)), + margin: UiRect::all(Val::Px(3.0)), + width: Val::Percent(80.0), + max_height: Val::Percent(80.0), + overflow: Overflow::clip(), + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, ..default() }, - background_color: BackgroundColor(Color::PINK), - ..default() - }) - .id(); - - commands - .entity(entity) - .insert(NodeBundle { - style: Style { ..default() }, + background_color: BackgroundColor(Color::PURPLE), ..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, +fn spawn_tab( + events: Query<(Entity, &GameUi, &Name, &Parent), Added>, + mut commands: Commands, +) { + events + .iter() + .filter(|(_, ui, _, _)| **ui == GameUi::Tab) + .for_each(|(entity, _, name, parent)| { + info!("Spawning Tab"); + // Create container for this tab + let parent_id = commands + .spawn(NodeBundle { + style: Style { + flex_direction: FlexDirection::Column, + padding: UiRect::all(Val::Px(3.0)), + margin: UiRect::all(Val::Px(3.0)), + ..default() + }, + background_color: BackgroundColor(Color::GREEN), ..default() - }, - ..default() - }) - .id(); - - commands - .entity(entity) - .insert(NodeBundle { - style: Style { - flex_wrap: FlexWrap::Wrap, + }) + .set_parent(parent.get()) + .with_children(|parent| { + parent.spawn((GameUi::Button, name.clone(), NodeBundle { ..default() })); + }) + .id(); + + // Insert spawn container with tab + commands + .entity(entity) + .remove::() + .insert(NodeBundle { + style: Style { + flex_direction: FlexDirection::Column, + padding: UiRect::all(Val::Px(3.0)), + margin: UiRect::all(Val::Px(3.0)), + display: Display::None, + ..default() + }, + background_color: BackgroundColor(Color::PINK), ..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() + }) + .set_parent(parent_id); }); - }); } -/// 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 { +fn spawn_set(events: Query<(Entity, &GameUi), Added>, mut commands: Commands) { + events + .iter() + .filter(|(_, ui)| **ui == GameUi::Set) + .for_each(|(entity, _)| { + info!("Spawning UI Set"); + commands.entity(entity).insert(NodeBundle { style: Style { - flex_direction: FlexDirection::Column, - padding: UiRect::all(Val::Px(5.0)), - margin: UiRect::all(Val::Px(5.0)), + flex_direction: FlexDirection::Row, + flex_wrap: FlexWrap::Wrap, + padding: UiRect::all(Val::Px(3.0)), + margin: UiRect::all(Val::Px(3.0)), ..default() }, - background_color: BackgroundColor(Color::BLUE), - border_color: BorderColor(Color::BLACK), + background_color: BackgroundColor(Color::RED), ..default() - }) - .id(); + }); + }); +} - commands - .entity(entity) - .insert(NodeBundle { +fn spawn_button(events: Query<(Entity, &GameUi), Added>, mut commands: Commands) { + events + .iter() + .filter(|(_, ui)| **ui == GameUi::Button) + .for_each(|(entity, _)| { + info!("Spawning UI Button"); + commands.entity(entity).insert(ButtonBundle { 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)), + padding: UiRect::all(Val::Px(3.0)), + margin: UiRect::all(Val::Px(3.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)), +fn manage_names( + events: Query<(Entity, &Name), (With, Or<(Added, Changed)>)>, + mut commands: Commands, +) { + events.iter().for_each(|(entity, name)| { + commands.entity(entity).with_children(|parent| { + parent + .spawn(NodeBundle { + style: Style { + align_self: AlignSelf::FlexStart, + padding: UiRect::all(Val::Px(3.0)), + margin: UiRect::all(Val::Px(3.0)), + ..default() + }, + background_color: BackgroundColor(Color::CRIMSON), ..default() - }, - background_color: BackgroundColor(Color::GREEN), - border_color: BorderColor(Color::BLACK), - ..default() - }, - UiElementState::Enabled, - )); + }) + .with_children(|parent| { + parent.spawn(TextBundle::from_section( + name.as_str(), + TextStyle { ..default() }, + )); + }); + }); }); } -/// Manage button style for interactivity -fn manage_button_interaction( - mut events: Query< - (&Interaction, &UiElementState, &mut BackgroundColor), - (Changed, With