making progressgit diff

main
Elijah Voigt 2 years ago
parent bb9b37ef17
commit 41be0f42bf

@ -72,40 +72,57 @@ fn init_ui(mut commands: 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((
GameUi::Nav,
// Name::new("Game Nav"),
NodeBundle { ..default() },
))
.with_children(|parent| { .with_children(|parent| {
parent parent
.spawn(( .spawn((
GameUiTab, GameUi::Tab,
Name::new("Grow/Shrink Container"), Name::new("Grow/Shrink Tab"),
NodeBundle { ..default() }, NodeBundle { ..default() },
)) ))
.with_children(|parent| { .with_children(|parent| {
parent.spawn((Container, GameUiSet, NodeBundle { ..default() })); parent.spawn((
Container,
GameUi::Set,
// Name::new("Grow/Shrink Set"),
NodeBundle { ..default() },
));
}); });
parent parent
.spawn(( .spawn((
GameUiTab, GameUi::Tab,
Name::new("Cursor Icons"), Name::new("Cursor Icons Tab"),
NodeBundle { NodeBundle { ..default() },
background_color: BackgroundColor(Color::BLACK),
..default()
},
)) ))
.with_children(|parent| { .with_children(|parent| {
parent parent
.spawn(( .spawn((
GameUiTab, GameUi::Set,
NodeBundle { // Name::new("Cursor Icons Set"),
background_color: BackgroundColor(Color::BLACK), NodeBundle { ..default() },
..default()
},
)) ))
.with_children(|parent| { .with_children(|parent| {
CURSORS.iter().for_each(|&icon| { CURSORS.iter().for_each(|&icon| {
parent.spawn(( parent.spawn((
GameUiButton, GameUi::Button,
Name::new(format!("{:?}", icon)), Name::new(format!("{:?}", icon)),
NodeBundle { ..default() }, NodeBundle { ..default() },
Icon(icon), Icon(icon),
@ -114,6 +131,7 @@ fn init_ui(mut commands: Commands) {
}); });
}); });
}); });
});
} }
fn cursors( fn cursors(
@ -155,7 +173,7 @@ fn container(
(Some(KeyCode::Up), ButtonState::Pressed) => { (Some(KeyCode::Up), ButtonState::Pressed) => {
commands.entity(root.single()).with_children(|parent| { commands.entity(root.single()).with_children(|parent| {
parent.spawn(( parent.spawn((
GameUiButton, GameUi::Button,
Name::new("asdfwtf"), Name::new("asdfwtf"),
NodeBundle { ..default() }, NodeBundle { ..default() },
)); ));

@ -1,250 +1,210 @@
/// TODO: Sorted list/set /// TODO:
/// /// * Titles on top left of window/tab
/// *
use bevy::{prelude::*, window::PrimaryWindow}; use bevy::{prelude::*, window::PrimaryWindow};
pub struct GameUiPlugin; pub struct GameUiPlugin;
impl Plugin for GameUiPlugin { impl Plugin for GameUiPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems( app.add_systems(PreUpdate, (spawn_nav, spawn_tab, spawn_set, spawn_button))
Update, .add_systems(Update, (manage_names, manage_tab));
(
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( /// Component for marking UI Nodes
events: Query< #[derive(Component, PartialEq)]
(Entity, &Name), pub enum GameUi {
( /// Navigation container
Added<Name>, Nav,
Or<( /// Tab container
With<GameUiNav>, Tab,
With<GameUiTab>, /// Game UI Set
With<GameUiSet>, Set,
With<GameUiList>, /// Game UI Button
With<GameUiButton>, Button,
)>,
),
>,
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 fn spawn_nav(events: Query<(Entity, &GameUi), Added<GameUi>>, mut commands: Commands) {
#[derive(Debug, Component)] events
pub struct GameUiNav; .iter()
.filter(|(_, ui)| **ui == GameUi::Nav)
fn init_ui_nav(events: Query<Entity, Added<GameUiNav>>, mut commands: Commands) { .for_each(|(entity, _)| {
events.iter().for_each(|entity| { info!("Spawning Nav UI");
let parent = commands commands.entity(entity).insert(NodeBundle {
.spawn(NodeBundle {
style: Style { 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() ..default()
}, },
background_color: BackgroundColor(Color::PINK), background_color: BackgroundColor(Color::PURPLE),
..default()
})
.id();
commands
.entity(entity)
.insert(NodeBundle {
style: Style { ..default() },
..default() ..default()
}) });
.set_parent(parent);
}); });
} }
/// Ui Tab Element fn spawn_tab(
#[derive(Debug, Component)] events: Query<(Entity, &GameUi, &Name, &Parent), Added<GameUi>>,
pub struct GameUiTab; mut commands: Commands,
) {
fn init_ui_tab(events: Query<Entity, Added<GameUiTab>>, mut commands: Commands) { events
events.iter().for_each(|entity| { .iter()
let parent = commands .filter(|(_, ui, _, _)| **ui == GameUi::Tab)
.for_each(|(entity, _, name, parent)| {
info!("Spawning Tab");
// Create container for this tab
let parent_id = commands
.spawn(NodeBundle { .spawn(NodeBundle {
style: Style { style: Style {
flex_direction: FlexDirection::Column, flex_direction: FlexDirection::Column,
padding: UiRect::all(Val::Px(3.0)),
margin: UiRect::all(Val::Px(3.0)),
..default() ..default()
}, },
background_color: BackgroundColor(Color::GREEN),
..default() ..default()
}) })
.set_parent(parent.get())
.with_children(|parent| {
parent.spawn((GameUi::Button, name.clone(), NodeBundle { ..default() }));
})
.id(); .id();
// Insert spawn container with tab
commands commands
.entity(entity) .entity(entity)
.remove::<Name>()
.insert(NodeBundle { .insert(NodeBundle {
style: Style { style: Style {
flex_wrap: FlexWrap::Wrap, flex_direction: FlexDirection::Column,
padding: UiRect::all(Val::Px(3.0)),
margin: UiRect::all(Val::Px(3.0)),
display: Display::None,
..default() ..default()
}, },
background_color: BackgroundColor(Color::TEAL), background_color: BackgroundColor(Color::PINK),
..default() ..default()
}) })
.set_parent(parent); .set_parent(parent_id);
}); });
} }
/// Describes the state of an element fn spawn_set(events: Query<(Entity, &GameUi), Added<GameUi>>, mut commands: Commands) {
#[derive(Debug, Component)] events
pub enum UiElementState { .iter()
Enabled, .filter(|(_, ui)| **ui == GameUi::Set)
Disabled, .for_each(|(entity, _)| {
Active, info!("Spawning UI Set");
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<Entity, Added<GameUiList>>, mut commands: Commands) {
events.iter().for_each(|entity| {
commands.entity(entity).insert(NodeBundle { commands.entity(entity).insert(NodeBundle {
style: Style { style: Style {
flex_direction: FlexDirection::Column, flex_direction: FlexDirection::Row,
justify_items: JustifyItems::Center, flex_wrap: FlexWrap::Wrap,
border: UiRect::all(Val::Px(2.0)), padding: UiRect::all(Val::Px(3.0)),
margin: UiRect::all(Val::Px(2.0)), margin: UiRect::all(Val::Px(3.0)),
padding: UiRect::all(Val::Px(2.0)),
..default() ..default()
}, },
background_color: BackgroundColor(Color::RED), background_color: BackgroundColor(Color::RED),
border_color: BorderColor(Color::BLACK),
..default() ..default()
}); });
}); });
} }
/// GameUiSet Component for holding collections of objects fn spawn_button(events: Query<(Entity, &GameUi), Added<GameUi>>, mut commands: Commands) {
#[derive(Debug, Component)] events
pub struct GameUiSet; .iter()
.filter(|(_, ui)| **ui == GameUi::Button)
/// Manage UI Sets: collections of UI entities. .for_each(|(entity, _)| {
fn init_ui_set(events: Query<Entity, Added<GameUiSet>>, mut commands: Commands) { info!("Spawning UI Button");
events.iter().for_each(|entity| { commands.entity(entity).insert(ButtonBundle {
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 { style: Style {
flex_direction: FlexDirection::Row, padding: UiRect::all(Val::Px(3.0)),
flex_wrap: FlexWrap::Wrap, margin: UiRect::all(Val::Px(3.0)),
border: UiRect::all(Val::Px(2.0)),
margin: UiRect::all(Val::Px(2.0)),
padding: UiRect::all(Val::Px(2.0)),
..default() ..default()
}, },
background_color: BackgroundColor(Color::BLUE), background_color: BackgroundColor(Color::BLUE),
border_color: BorderColor(Color::BLACK),
..default() ..default()
}) });
.set_parent(parent);
}); });
} }
/// GameUiButton for interactive elements fn manage_names(
#[derive(Debug, Component)] events: Query<(Entity, &Name), (With<GameUi>, Or<(Added<Name>, Changed<Name>)>)>,
pub struct GameUiButton; mut commands: Commands,
) {
/// Manage UI Buttons. interactive buttons. events.iter().for_each(|(entity, name)| {
fn init_ui_button(events: Query<Entity, Added<GameUiButton>>, mut commands: Commands) { commands.entity(entity).with_children(|parent| {
events.iter().for_each(|entity| { parent
commands.entity(entity).insert(( .spawn(NodeBundle {
ButtonBundle {
style: Style { style: Style {
margin: UiRect::all(Val::Px(2.0)), align_self: AlignSelf::FlexStart,
padding: UiRect::all(Val::Px(2.0)), padding: UiRect::all(Val::Px(3.0)),
border: UiRect::all(Val::Px(2.0)), margin: UiRect::all(Val::Px(3.0)),
..default() ..default()
}, },
background_color: BackgroundColor(Color::GREEN), background_color: BackgroundColor(Color::CRIMSON),
border_color: BorderColor(Color::BLACK),
..default() ..default()
}, })
UiElementState::Enabled, .with_children(|parent| {
parent.spawn(TextBundle::from_section(
name.as_str(),
TextStyle { ..default() },
)); ));
}); });
});
});
} }
/// Manage button style for interactivity fn manage_tab(
fn manage_button_interaction( events: Query<
mut events: Query< (&Interaction, Entity, &Parent),
(&Interaction, &UiElementState, &mut BackgroundColor), (Changed<Interaction>, With<Button>, With<GameUi>),
(Changed<Interaction>, With<Button>),
>, >,
children: Query<&Children>,
parents: Query<&Parent>,
ui_elements: Query<(Entity, &GameUi)>,
mut styles: Query<&mut Style>,
mut commands: Commands,
) { ) {
events events
.iter_mut()
.for_each(|(interaction, state, mut bg_color)| {
bg_color.0 = match state {
UiElementState::Enabled => match interaction {
Interaction::Pressed => Color::BLACK,
Interaction::Hovered => Color::ORANGE,
Interaction::None => Color::GREEN,
},
UiElementState::Active => Color::PINK,
UiElementState::Error => Color::RED,
UiElementState::Disabled => Color::GRAY,
}
});
}
/// Manage the cursor icon for better immersion
fn manage_cursor(
mut primary_window: Query<&mut Window, With<PrimaryWindow>>,
events: Query<&Interaction, (Changed<Interaction>, With<Button>)>,
) {
if !events.is_empty() {
let mut window = primary_window.single_mut();
window.cursor.icon = events
.iter() .iter()
.find(|&event| *event != Interaction::None) .for_each(|(interaction, interacted_entity, parent)| {
.map_or(CursorIcon::Default, |event| match event { // Checks:
Interaction::Hovered | Interaction::Pressed => CursorIcon::Hand, // entity pressed
Interaction::None => CursorIcon::Help, // Shouldn't be reachable // entity is button
// entity parent is a tab
//
// Find all other tabs
// Display::None all except for tab button
match interaction {
Interaction::Pressed => {
children.get(parent.get()).iter().for_each(|&children| {
children
.iter()
.filter(|&child| *child != interacted_entity)
.for_each(|&child| {
let mut style = styles.get_mut(child).expect("child has style");
style.display = match style.display {
Display::Flex => Display::None,
Display::None => Display::Flex,
_ => Display::Flex, // Not Reachable
}
}); });
})
} }
_ => (),
}
// When tab button is clicked
// For all children of parent (the tab)
// If selected:
// display: Display::Flex,
// else:
// Set display: Display::None,
});
} }

Loading…
Cancel
Save