well it only works vertically (probably) but it works. Im tired.

main
Elijah Voigt 2 years ago
parent 28d1bd8790
commit 87a4c6fd40

@ -18,54 +18,114 @@ fn main() {
}), }),
GameUiPlugin, GameUiPlugin,
)) ))
.init_resource::<Icon>() // .init_resource::<Icon>()
.add_systems(Startup, init_ui) .add_systems(Startup, init_ui2)
.add_systems(Update, (cursors, container)) .add_systems(Update, toggle)
// .add_systems(Startup, init_ui)
// .add_systems(Update, (cursors, container()))
.run(); .run();
} }
const CURSORS: [CursorIcon; 35] = [ fn container() -> NodeBundle {
CursorIcon::Default, NodeBundle {
CursorIcon::Crosshair, style: Style {
CursorIcon::Hand, border: UiRect::all(Val::Px(2.0)),
CursorIcon::Arrow, right: Val::Percent(-100.0),
CursorIcon::Move, top: Val::Px(-4.0),
CursorIcon::Text, flex_direction: FlexDirection::Column,
CursorIcon::Wait, display: Display::None,
CursorIcon::Help, ..default()
CursorIcon::Progress, },
CursorIcon::NotAllowed, background_color: BackgroundColor(Color::PURPLE),
CursorIcon::ContextMenu, border_color: BorderColor(Color::BLACK),
CursorIcon::Cell, ..default()
CursorIcon::VerticalText, }
CursorIcon::Alias, }
CursorIcon::Copy,
CursorIcon::NoDrop,
CursorIcon::Grab,
CursorIcon::Grabbing,
CursorIcon::AllScroll,
CursorIcon::ZoomIn,
CursorIcon::ZoomOut,
CursorIcon::EResize,
CursorIcon::NResize,
CursorIcon::NeResize,
CursorIcon::NwResize,
CursorIcon::SResize,
CursorIcon::SeResize,
CursorIcon::SwResize,
CursorIcon::WResize,
CursorIcon::EwResize,
CursorIcon::NsResize,
CursorIcon::NeswResize,
CursorIcon::NwseResize,
CursorIcon::ColResize,
CursorIcon::RowResize,
];
#[derive(Debug, Component, Resource, Default)] fn spec(color: Color) -> ButtonBundle {
struct Icon(CursorIcon); ButtonBundle {
style: Style {
border: UiRect::all(Val::Px(2.0)),
width: Val::Px(100.0),
height: Val::Px(50.0),
flex_direction: FlexDirection::Column,
..default()
},
background_color: BackgroundColor(color),
border_color: BorderColor(Color::BLACK),
..default()
}
}
fn init_ui(mut commands: Commands) { fn toggle(
mut events: Query<
(&mut BackgroundColor, &Interaction, &Children),
(Changed<Interaction>, With<Button>),
>,
mut styles: Query<&mut Style>,
) {
events
.iter_mut()
.for_each(|(mut bg_color, interaction, children)| match interaction {
Interaction::Pressed => {
bg_color.0 = Color::RED;
children.iter().for_each(|&child| {
if let Ok(mut style) = styles.get_mut(child) {
style.display = match style.display {
Display::Flex => Display::None,
Display::None | _ => Display::Flex,
};
}
});
}
Interaction::Hovered => {
bg_color.0 = Color::RED;
}
Interaction::None => {
bg_color.0 = Color::PINK;
}
});
}
// const CURSORS: [CursorIcon; 35] = [
// CursorIcon::Default,
// CursorIcon::Crosshair,
// CursorIcon::Hand,
// CursorIcon::Arrow,
// CursorIcon::Move,
// CursorIcon::Text,
// CursorIcon::Wait,
// CursorIcon::Help,
// CursorIcon::Progress,
// CursorIcon::NotAllowed,
// CursorIcon::ContextMenu,
// CursorIcon::Cell,
// CursorIcon::VerticalText,
// CursorIcon::Alias,
// CursorIcon::Copy,
// CursorIcon::NoDrop,
// CursorIcon::Grab,
// CursorIcon::Grabbing,
// CursorIcon::AllScroll,
// CursorIcon::ZoomIn,
// CursorIcon::ZoomOut,
// CursorIcon::EResize,
// CursorIcon::NResize,
// CursorIcon::NeResize,
// CursorIcon::NwResize,
// CursorIcon::SResize,
// CursorIcon::SeResize,
// CursorIcon::SwResize,
// CursorIcon::WResize,
// CursorIcon::EwResize,
// CursorIcon::NsResize,
// CursorIcon::NeswResize,
// CursorIcon::NwseResize,
// CursorIcon::ColResize,
// CursorIcon::RowResize,
// ];
fn init_ui2(mut commands: Commands) {
commands.spawn(( commands.spawn((
Camera2dBundle { ..default() }, Camera2dBundle { ..default() },
UiCameraConfig { show_ui: true }, UiCameraConfig { show_ui: true },
@ -74,118 +134,217 @@ fn init_ui(mut commands: Commands) {
commands commands
.spawn(NodeBundle { .spawn(NodeBundle {
style: Style { style: Style {
height: Val::Percent(100.0), border: UiRect::all(Val::Px(2.0)),
width: Val::Percent(100.0), flex_direction: FlexDirection::Column,
justify_content: JustifyContent::Start,
align_items: AlignItems::Start,
..default() ..default()
}, },
background_color: BackgroundColor(Color::GRAY), background_color: BackgroundColor(Color::PURPLE),
border_color: BorderColor(Color::BLACK),
..default() ..default()
}) })
.with_children(|parent| { .with_children(|parent| {
parent parent.spawn(spec(Color::PINK)).with_children(|parent| {
.spawn(( parent.spawn(container()).with_children(|parent| {
GameUi::Nav, parent.spawn(spec(Color::PINK)).with_children(|parent| {
// Name::new("Game Nav"), parent.spawn(container()).with_children(|parent| {
NodeBundle { ..default() }, parent.spawn(spec(Color::PINK));
)) parent.spawn(spec(Color::PINK));
.with_children(|parent| { parent.spawn(spec(Color::PINK));
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 parent.spawn(spec(Color::PINK)).with_children(|parent| {
.spawn(( parent.spawn(container()).with_children(|parent| {
GameUi::Tab, parent.spawn(spec(Color::PINK));
Name::new("Cursor Icons Tab"), parent.spawn(spec(Color::PINK));
NodeBundle { ..default() }, parent.spawn(spec(Color::PINK));
))
.with_children(|parent| {
parent
.spawn((
GameUi::Set,
// Name::new("Cursor Icons Set"),
NodeBundle { ..default() },
))
.with_children(|parent| {
CURSORS.iter().for_each(|&icon| {
parent.spawn((
GameUi::Button,
Name::new(format!("{:?}", icon)),
NodeBundle { ..default() },
Icon(icon),
));
});
});
}); });
});
parent.spawn(spec(Color::PINK)).with_children(|parent| {
parent.spawn(container()).with_children(|parent| {
parent.spawn(spec(Color::PINK));
parent.spawn(spec(Color::PINK));
parent.spawn(spec(Color::PINK));
});
});
}); });
}); });
} parent.spawn(spec(Color::PINK)).with_children(|parent| {
parent.spawn(container()).with_children(|parent| {
fn cursors( parent.spawn(spec(Color::PINK)).with_children(|parent| {
events: Query<(&Interaction, &Icon), (Changed<Interaction>, With<Button>)>, parent.spawn(container()).with_children(|parent| {
mut primary_window: Query<&mut Window, With<PrimaryWindow>>, parent.spawn(spec(Color::PINK));
mut curr: ResMut<Icon>, parent.spawn(spec(Color::PINK));
) { parent.spawn(spec(Color::PINK));
events.iter().for_each(|(&interaction, &ref icon)| { });
let mut window = primary_window.single_mut();
match interaction {
Interaction::Hovered => {
(*window).cursor.icon = icon.0.clone();
}
Interaction::Pressed => {
curr.0 = icon.0.clone();
}
Interaction::None => {
(*window).cursor.icon = curr.0.clone();
}
}
})
}
#[derive(Debug, Component)]
struct Container;
fn container(
mut events: EventReader<KeyboardInput>,
mut commands: Commands,
root: Query<Entity, With<Container>>,
children: Query<&Children, With<Container>>,
) {
events.iter().for_each(
|KeyboardInput {
key_code, state, ..
}| {
match (key_code, state) {
(Some(KeyCode::Up), ButtonState::Pressed) => {
commands.entity(root.single()).with_children(|parent| {
parent.spawn((
GameUi::Button,
Name::new("asdfwtf"),
NodeBundle { ..default() },
));
}); });
} parent.spawn(spec(Color::PINK)).with_children(|parent| {
(Some(KeyCode::Down), ButtonState::Pressed) => { parent.spawn(container()).with_children(|parent| {
children.single().iter().last().iter().for_each(|&&child| { parent.spawn(spec(Color::PINK));
commands.entity(child).despawn_recursive(); parent.spawn(spec(Color::PINK));
parent.spawn(spec(Color::PINK));
});
}); });
} parent.spawn(spec(Color::PINK)).with_children(|parent| {
_ => (), parent.spawn(container()).with_children(|parent| {
} parent.spawn(spec(Color::PINK));
}, parent.spawn(spec(Color::PINK));
) parent.spawn(spec(Color::PINK));
});
});
});
});
parent.spawn(spec(Color::PINK)).with_children(|parent| {
parent.spawn(container()).with_children(|parent| {
parent.spawn(spec(Color::PINK)).with_children(|parent| {
parent.spawn(container()).with_children(|parent| {
parent.spawn(spec(Color::PINK));
parent.spawn(spec(Color::PINK));
parent.spawn(spec(Color::PINK));
});
});
parent.spawn(spec(Color::PINK)).with_children(|parent| {
parent.spawn(container()).with_children(|parent| {
parent.spawn(spec(Color::PINK));
parent.spawn(spec(Color::PINK));
parent.spawn(spec(Color::PINK));
});
});
parent.spawn(spec(Color::PINK)).with_children(|parent| {
parent.spawn(container()).with_children(|parent| {
parent.spawn(spec(Color::PINK));
parent.spawn(spec(Color::PINK));
parent.spawn(spec(Color::PINK));
});
});
});
});
});
} }
// #[derive(Debug, Component, Resource, Default)]
// struct Icon(CursorIcon);
//
// fn init_ui(mut commands: Commands) {
// commands.spawn((
// Camera2dBundle { ..default() },
// UiCameraConfig { show_ui: true },
// ));
//
// commands
// .spawn(NodeBundle {
// style: Style {
// height: Val::Percent(100.0),
// width: Val::Percent(100.0),
// justify_content: JustifyContent::Start,
// align_items: AlignItems::Start,
// ..default()
// },
// background_color: BackgroundColor(Color::GRAY),
// ..default()
// })
// .with_children(|parent| {
// parent
// .spawn((
// GameUiNav,
// // Name::new("Game Nav"),
// NodeBundle { ..default() },
// ))
// .with_children(|parent| {
// parent
// .spawn((
// GameUiTab,
// Name::new("Grow/Shrink Tab"),
// NodeBundle { ..default() },
// ))
// .with_children(|parent| {
// parent.spawn((
// container,
// GameUiSet,
// // Name::new("Grow/Shrink Set"),
// NodeBundle { ..default() },
// ));
// });
//
// parent
// .spawn((
// GameUiTab,
// Name::new("Cursor Icons Tab"),
// NodeBundle { ..default() },
// ))
// .with_children(|parent| {
// parent
// .spawn((
// GameUiSet,
// // Name::new("Cursor Icons Set"),
// NodeBundle { ..default() },
// ))
// .with_children(|parent| {
// CURSORS.iter().for_each(|&icon| {
// parent.spawn((
// GameUiButton,
// Name::new(format!("{:?}", icon)),
// NodeBundle { ..default() },
// Icon(icon),
// ));
// });
// });
// });
// });
// });
// }
//
// fn cursors(
// events: Query<(&Interaction, &Icon), (Changed<Interaction>, With<Button>)>,
// mut primary_window: Query<&mut Window, With<PrimaryWindow>>,
// mut curr: ResMut<Icon>,
// ) {
// events.iter().for_each(|(&interaction, &ref icon)| {
// let mut window = primary_window.single_mut();
//
// match interaction {
// Interaction::Hovered => {
// (*window).cursor.icon = icon.0.clone();
// }
// Interaction::Pressed => {
// curr.0 = icon.0.clone();
// }
// Interaction::None => {
// (*window).cursor.icon = curr.0.clone();
// }
// }
// })
// }
//
// #[derive(Debug, Component)]
// struct container;
//
// fn container(
// mut events: EventReader<KeyboardInput>,
// mut commands: Commands,
// root: Query<Entity, With<container>>,
// children: Query<&Children, With<container>>,
// ) {
// events.iter().for_each(
// |KeyboardInput {
// key_code, state, ..
// }| {
// match (key_code, state) {
// (Some(KeyCode::Up), ButtonState::Pressed) => {
// commands.entity(root.single()).with_children(|parent| {
// parent.spawn((
// GameUiButton,
// Name::new("asdfwtf"),
// NodeBundle { ..default() },
// ));
// });
// }
// (Some(KeyCode::Down), ButtonState::Pressed) => {
// children.single().iter().last().iter().for_each(|&&child| {
// commands.entity(child).despawn_recursive();
// });
// }
// _ => (),
// }
// },
// )
// }

@ -12,129 +12,63 @@ impl Plugin for GameUiPlugin {
} }
} }
/// Component for marking UI Nodes /// Navigation UI Container
/// Buttons in a nav correspond to Tabs in a navbar/navmenu
#[derive(Component, PartialEq)] #[derive(Component, PartialEq)]
pub enum GameUi { pub struct GameUiNav;
/// Navigation container
Nav,
/// Tab container
Tab,
/// Game UI Set
Set,
/// Game UI Button
Button,
}
fn spawn_nav(events: Query<(Entity, &GameUi), Added<GameUi>>, mut commands: Commands) { /// Sets contain a variety of elements like action buttons
events /// Usually the "leaf" of a navigation tree
.iter() #[derive(Component, PartialEq)]
.filter(|(_, ui)| **ui == GameUi::Nav) pub struct GameUiSet;
.for_each(|(entity, _)| {
info!("Spawning Nav UI");
commands.entity(entity).insert(NodeBundle {
style: Style {
flex_direction: FlexDirection::Row, // ?
padding: UiRect::all(Val::Px(3.0)),
margin: UiRect::all(Val::Px(3.0)),
width: Val::Percent(100.0),
max_height: Val::Percent(100.0),
overflow: Overflow::clip(),
justify_content: JustifyContent::Start,
align_items: AlignItems::Start,
..default()
},
background_color: BackgroundColor(Color::PURPLE),
..default()
});
});
}
fn spawn_tab( /// Buttons are used for interaction in the UI
events: Query<(Entity, &GameUi, &Name, &Parent), Added<GameUi>>, #[derive(Component, PartialEq)]
mut commands: Commands, pub struct GameUiButton;
) {
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()
})
.set_parent(parent.get())
.with_children(|parent| {
parent.spawn((GameUi::Button, name.clone(), NodeBundle { ..default() }));
})
.id();
// Insert spawn container with tab #[derive(Component, PartialEq)]
commands pub struct GameUiTab;
.entity(entity)
.remove::<Name>() fn spawn_nav(events: Query<(Entity, &GameUiNav), Added<GameUiNav>>, mut commands: Commands) {
.insert(NodeBundle { events.iter().for_each(|(entity, _)| {
style: Style { info!("Spawning Nav UI");
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()
})
.set_parent(parent_id);
});
} }
fn spawn_set(events: Query<(Entity, &GameUi), Added<GameUi>>, mut commands: Commands) { fn spawn_tab(events: Query<Entity, Added<GameUiTab>>, mut commands: Commands) {
events events.iter().for_each(|entity| {});
.iter()
.filter(|(_, ui)| **ui == GameUi::Set)
.for_each(|(entity, _)| {
info!("Spawning UI Set");
commands.entity(entity).insert(NodeBundle {
style: Style {
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::RED),
..default()
});
});
} }
fn spawn_button(events: Query<(Entity, &GameUi), Added<GameUi>>, mut commands: Commands) { fn spawn_set(events: Query<Entity, Added<GameUiSet>>, mut commands: Commands) {
events events.iter().for_each(|entity| {});
.iter() }
.filter(|(_, ui)| **ui == GameUi::Button)
.for_each(|(entity, _)| { fn spawn_button(
info!("Spawning UI Button"); events: Query<(Entity, &GameUiButton), Added<GameUiButton>>,
commands.entity(entity).insert(ButtonBundle { mut commands: Commands,
style: Style { ) {
padding: UiRect::all(Val::Px(3.0)), events.iter().for_each(|(entity, _)| {
margin: UiRect::all(Val::Px(3.0)), info!("Spawning UI Button");
..default() commands.entity(entity).insert(ButtonBundle {
}, style: Style {
background_color: BackgroundColor(Color::BLUE), padding: UiRect::all(Val::Px(3.0)),
margin: UiRect::all(Val::Px(3.0)),
..default() ..default()
}); },
background_color: BackgroundColor(Color::BLUE),
..default()
}); });
});
} }
fn manage_names( fn manage_names(
events: Query<(Entity, &Name), (With<GameUi>, Or<(Added<Name>, Changed<Name>)>)>, events: Query<
(Entity, &Name),
(
Or<(With<GameUiNav>, With<GameUiButton>)>,
Or<(Added<Name>, Changed<Name>)>,
),
>,
mut commands: Commands, mut commands: Commands,
) { ) {
events.iter().for_each(|(entity, name)| { events.iter().for_each(|(entity, name)| {
@ -160,51 +94,8 @@ fn manage_names(
}); });
} }
fn manage_tab( fn manage_tab(events: Query<&Interaction, Changed<Interaction>>) {
events: Query< events.iter().for_each(|interaction| {
(&Interaction, Entity, &Parent), info!("When tab is clicked, show/hide content");
(Changed<Interaction>, With<Button>, With<GameUi>), });
>,
children: Query<&Children>,
parents: Query<&Parent>,
ui_elements: Query<(Entity, &GameUi)>,
mut styles: Query<&mut Style>,
mut commands: Commands,
) {
events
.iter()
.for_each(|(interaction, interacted_entity, parent)| {
// Checks:
// entity pressed
// 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