Compare commits
No commits in common. '87a4c6fd409d15ea120bfa5f7397c7e48e9116f9' and 'e159346b8946e9bfa095dbe6a897218a7e516b68' have entirely different histories.
87a4c6fd40
...
e159346b89
@ -0,0 +1,26 @@
|
|||||||
|
# Exploration
|
||||||
|
|
||||||
|
## Inspectors
|
||||||
|
|
||||||
|
### Model Inspector
|
||||||
|
|
||||||
|
- [ ] Construct Scene from Nodes/Meshes (not auto-scene builder)
|
||||||
|
- [ ] Show debug info about selected model
|
||||||
|
- [ ] Wireframe view
|
||||||
|
- [ ] Automatic tighter bounding box for selection
|
||||||
|
|
||||||
|
### Audio Inspector
|
||||||
|
|
||||||
|
- [ ] UI for selecting sound
|
||||||
|
- [ ] Play/Pause/Volume
|
||||||
|
- [x] Load sounds
|
||||||
|
- [ ] Scrolling list of sounds
|
||||||
|
|
||||||
|
## WASM
|
||||||
|
|
||||||
|
- [ ] Build and run using model/text inspector
|
||||||
|
- https://github.com/bevyengine/bevy/blob/main/examples/README.md#wasm
|
||||||
|
|
||||||
|
## Text Inspector
|
||||||
|
|
||||||
|
- [ ] Performance improvements?
|
||||||
@ -1,350 +1,101 @@
|
|||||||
use bevy::{
|
use bevy::{input::mouse::MouseWheel, prelude::*};
|
||||||
input::{keyboard::KeyboardInput, ButtonState},
|
|
||||||
prelude::*,
|
|
||||||
window::PrimaryWindow,
|
|
||||||
};
|
|
||||||
use monologue_trees::{debug::*, ui::*};
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::new()
|
App::new()
|
||||||
.add_plugins((
|
.add_plugins(DefaultPlugins.set(WindowPlugin {
|
||||||
DefaultPlugins.set(WindowPlugin {
|
primary_window: Some(Window {
|
||||||
primary_window: Some(Window {
|
title: "UI WTF".into(),
|
||||||
title: "UI WTF".into(),
|
resolution: (640., 480.).into(),
|
||||||
resolution: (640., 480.).into(),
|
|
||||||
..default()
|
|
||||||
}),
|
|
||||||
..default()
|
..default()
|
||||||
}),
|
}),
|
||||||
GameUiPlugin,
|
|
||||||
))
|
|
||||||
// .init_resource::<Icon>()
|
|
||||||
.add_systems(Startup, init_ui2)
|
|
||||||
.add_systems(Update, toggle)
|
|
||||||
// .add_systems(Startup, init_ui)
|
|
||||||
// .add_systems(Update, (cursors, container()))
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn container() -> NodeBundle {
|
|
||||||
NodeBundle {
|
|
||||||
style: Style {
|
|
||||||
border: UiRect::all(Val::Px(2.0)),
|
|
||||||
right: Val::Percent(-100.0),
|
|
||||||
top: Val::Px(-4.0),
|
|
||||||
flex_direction: FlexDirection::Column,
|
|
||||||
display: Display::None,
|
|
||||||
..default()
|
|
||||||
},
|
|
||||||
background_color: BackgroundColor(Color::PURPLE),
|
|
||||||
border_color: BorderColor(Color::BLACK),
|
|
||||||
..default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spec(color: Color) -> ButtonBundle {
|
|
||||||
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()
|
..default()
|
||||||
},
|
}))
|
||||||
background_color: BackgroundColor(color),
|
.add_systems(Startup, (init,))
|
||||||
border_color: BorderColor(Color::BLACK),
|
.add_systems(Update, (scroll,))
|
||||||
..default()
|
.run();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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] = [
|
#[derive(Component)]
|
||||||
// CursorIcon::Default,
|
struct ScrollingList;
|
||||||
// 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) {
|
fn init(mut commands: Commands) {
|
||||||
commands.spawn((
|
info!("Spawning camera");
|
||||||
Camera2dBundle { ..default() },
|
commands.spawn(Camera2dBundle { ..default() });
|
||||||
UiCameraConfig { show_ui: true },
|
|
||||||
));
|
|
||||||
|
|
||||||
|
info!("Initializing UI");
|
||||||
commands
|
commands
|
||||||
.spawn(NodeBundle {
|
.spawn(NodeBundle {
|
||||||
|
background_color: BackgroundColor(Color::WHITE),
|
||||||
style: Style {
|
style: Style {
|
||||||
border: UiRect::all(Val::Px(2.0)),
|
justify_content: JustifyContent::Center,
|
||||||
flex_direction: FlexDirection::Column,
|
width: Val::Percent(90.0),
|
||||||
|
height: Val::Percent(90.0),
|
||||||
|
overflow: Overflow::clip(),
|
||||||
..default()
|
..default()
|
||||||
},
|
},
|
||||||
background_color: BackgroundColor(Color::PURPLE),
|
|
||||||
border_color: BorderColor(Color::BLACK),
|
|
||||||
..default()
|
..default()
|
||||||
})
|
})
|
||||||
.with_children(|parent| {
|
.with_children(|parent| {
|
||||||
parent.spawn(spec(Color::PINK)).with_children(|parent| {
|
parent
|
||||||
parent.spawn(container()).with_children(|parent| {
|
.spawn((
|
||||||
parent.spawn(spec(Color::PINK)).with_children(|parent| {
|
NodeBundle {
|
||||||
parent.spawn(container()).with_children(|parent| {
|
background_color: BackgroundColor(Color::OLIVE),
|
||||||
parent.spawn(spec(Color::PINK));
|
style: Style {
|
||||||
parent.spawn(spec(Color::PINK));
|
flex_wrap: FlexWrap::Wrap,
|
||||||
parent.spawn(spec(Color::PINK));
|
flex_direction: FlexDirection::Row,
|
||||||
|
justify_content: JustifyContent::SpaceAround,
|
||||||
|
width: Val::Auto,
|
||||||
|
height: Val::Auto,
|
||||||
|
max_width: Val::Auto,
|
||||||
|
max_height: Val::Auto,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
ScrollingList,
|
||||||
|
))
|
||||||
|
.with_children(|parent| {
|
||||||
|
info!("Initializing Child Element");
|
||||||
|
let colors = [
|
||||||
|
Color::ORANGE,
|
||||||
|
Color::BLUE,
|
||||||
|
Color::GREEN,
|
||||||
|
Color::SALMON,
|
||||||
|
Color::SEA_GREEN,
|
||||||
|
Color::MAROON,
|
||||||
|
Color::ORANGE,
|
||||||
|
Color::BLUE,
|
||||||
|
Color::GREEN,
|
||||||
|
Color::SALMON,
|
||||||
|
Color::SEA_GREEN,
|
||||||
|
Color::MAROON,
|
||||||
|
];
|
||||||
|
for i in 0..12 {
|
||||||
|
parent.spawn(NodeBundle {
|
||||||
|
background_color: BackgroundColor(colors[i]),
|
||||||
|
style: Style {
|
||||||
|
width: Val::Px(256.0),
|
||||||
|
height: Val::Px(256.0),
|
||||||
|
padding: UiRect::all(Val::Px(5.0)),
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
..default()
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
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)).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));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
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)]
|
fn scroll(
|
||||||
// struct Icon(CursorIcon);
|
mut scroll_evr: EventReader<MouseWheel>,
|
||||||
//
|
mut query: Query<&mut Style, With<ScrollingList>>,
|
||||||
// fn init_ui(mut commands: Commands) {
|
) {
|
||||||
// commands.spawn((
|
for ev in scroll_evr.iter() {
|
||||||
// Camera2dBundle { ..default() },
|
for mut s in query.iter_mut() {
|
||||||
// UiCameraConfig { show_ui: true },
|
s.top = match s.top {
|
||||||
// ));
|
Val::Px(current) => Val::Px(current + (ev.y * 5.0)),
|
||||||
//
|
_ => Val::Px(0.0),
|
||||||
// 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();
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// _ => (),
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
|
|||||||
@ -1,101 +1,121 @@
|
|||||||
/// 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(PreUpdate, (spawn_nav, spawn_tab, spawn_set, spawn_button))
|
app.add_systems(
|
||||||
.add_systems(Update, (manage_names, manage_tab));
|
Update,
|
||||||
|
(
|
||||||
|
manage_ui_list,
|
||||||
|
manage_ui_set,
|
||||||
|
manage_ui_button,
|
||||||
|
manage_cursor,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Navigation UI Container
|
/// GameUiList for holding ordered collections of objects
|
||||||
/// Buttons in a nav correspond to Tabs in a navbar/navmenu
|
#[derive(Debug, Component)]
|
||||||
#[derive(Component, PartialEq)]
|
pub struct GameUiList;
|
||||||
pub struct GameUiNav;
|
|
||||||
|
|
||||||
/// Sets contain a variety of elements like action buttons
|
/// Manage UI Lists: lists of UI entities.
|
||||||
/// Usually the "leaf" of a navigation tree
|
fn manage_ui_list(events: Query<(Entity, &Name), Added<GameUiList>>, mut commands: Commands) {
|
||||||
#[derive(Component, PartialEq)]
|
events.iter().for_each(|(entity, name)| {
|
||||||
pub struct GameUiSet;
|
commands
|
||||||
|
.entity(entity)
|
||||||
/// Buttons are used for interaction in the UI
|
.insert(NodeBundle {
|
||||||
#[derive(Component, PartialEq)]
|
style: Style {
|
||||||
pub struct GameUiButton;
|
// width: Val::Px(100.0),
|
||||||
|
margin: UiRect::all(Val::Px(2.0)),
|
||||||
#[derive(Component, PartialEq)]
|
padding: UiRect::all(Val::Px(2.0)),
|
||||||
pub struct GameUiTab;
|
border: UiRect::all(Val::Px(2.0)),
|
||||||
|
flex_direction: FlexDirection::Column,
|
||||||
fn spawn_nav(events: Query<(Entity, &GameUiNav), Added<GameUiNav>>, mut commands: Commands) {
|
align_items: AlignItems::Stretch,
|
||||||
events.iter().for_each(|(entity, _)| {
|
justify_items: JustifyItems::Center,
|
||||||
info!("Spawning Nav UI");
|
align_content: AlignContent::FlexStart,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
background_color: BackgroundColor(Color::RED),
|
||||||
|
border_color: BorderColor(Color::BLACK),
|
||||||
|
..default()
|
||||||
|
})
|
||||||
|
.with_children(|parent| {
|
||||||
|
parent.spawn(TextBundle::from_section(name, TextStyle { ..default() }));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_tab(events: Query<Entity, Added<GameUiTab>>, mut commands: Commands) {
|
/// GameUiSet Component for holding collections of objects
|
||||||
events.iter().for_each(|entity| {});
|
#[derive(Debug, Component)]
|
||||||
}
|
pub struct GameUiSet;
|
||||||
|
|
||||||
fn spawn_set(events: Query<Entity, Added<GameUiSet>>, mut commands: Commands) {
|
|
||||||
events.iter().for_each(|entity| {});
|
|
||||||
}
|
|
||||||
|
|
||||||
fn spawn_button(
|
/// Manage UI Sets: collections of UI entities.
|
||||||
events: Query<(Entity, &GameUiButton), Added<GameUiButton>>,
|
fn manage_ui_set(events: Query<(Entity, &Name), Added<GameUiSet>>, mut commands: Commands) {
|
||||||
mut commands: Commands,
|
events.iter().for_each(|(entity, name)| {
|
||||||
) {
|
commands
|
||||||
events.iter().for_each(|(entity, _)| {
|
.entity(entity)
|
||||||
info!("Spawning UI Button");
|
.insert(NodeBundle {
|
||||||
commands.entity(entity).insert(ButtonBundle {
|
style: Style {
|
||||||
style: Style {
|
// width: Val::Px(100.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)),
|
||||||
|
border: UiRect::all(Val::Px(2.0)),
|
||||||
|
align_items: AlignItems::FlexStart,
|
||||||
|
align_content: AlignContent::FlexStart,
|
||||||
|
flex_direction: FlexDirection::Row,
|
||||||
|
flex_wrap: FlexWrap::Wrap,
|
||||||
|
..default()
|
||||||
|
},
|
||||||
|
background_color: BackgroundColor(Color::BLUE),
|
||||||
|
border_color: BorderColor(Color::BLACK),
|
||||||
..default()
|
..default()
|
||||||
},
|
})
|
||||||
background_color: BackgroundColor(Color::BLUE),
|
.with_children(|parent| {
|
||||||
..default()
|
parent.spawn(TextBundle::from_section(name, TextStyle { ..default() }));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn manage_names(
|
/// GameUiButton for interactive elements
|
||||||
events: Query<
|
#[derive(Debug, Component)]
|
||||||
(Entity, &Name),
|
pub struct GameUiButton;
|
||||||
(
|
|
||||||
Or<(With<GameUiNav>, With<GameUiButton>)>,
|
/// Manage UI Buttons. interactive buttons.
|
||||||
Or<(Added<Name>, Changed<Name>)>,
|
fn manage_ui_button(events: Query<(Entity, &Name), Added<GameUiButton>>, mut commands: Commands) {
|
||||||
),
|
|
||||||
>,
|
|
||||||
mut commands: Commands,
|
|
||||||
) {
|
|
||||||
events.iter().for_each(|(entity, name)| {
|
events.iter().for_each(|(entity, name)| {
|
||||||
commands.entity(entity).with_children(|parent| {
|
commands
|
||||||
parent
|
.entity(entity)
|
||||||
.spawn(NodeBundle {
|
.insert(ButtonBundle {
|
||||||
style: Style {
|
style: Style {
|
||||||
align_self: AlignSelf::FlexStart,
|
margin: UiRect::all(Val::Px(2.0)),
|
||||||
padding: UiRect::all(Val::Px(3.0)),
|
padding: UiRect::all(Val::Px(2.0)),
|
||||||
margin: UiRect::all(Val::Px(3.0)),
|
border: UiRect::all(Val::Px(2.0)),
|
||||||
..default()
|
justify_content: JustifyContent::Center,
|
||||||
},
|
|
||||||
background_color: BackgroundColor(Color::CRIMSON),
|
|
||||||
..default()
|
..default()
|
||||||
})
|
},
|
||||||
.with_children(|parent| {
|
background_color: BackgroundColor(Color::GREEN),
|
||||||
parent.spawn(TextBundle::from_section(
|
border_color: BorderColor(Color::BLACK),
|
||||||
name.as_str(),
|
..default()
|
||||||
TextStyle { ..default() },
|
})
|
||||||
));
|
.with_children(|parent| {
|
||||||
});
|
parent.spawn(TextBundle::from_section(name, TextStyle::default()));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn manage_tab(events: Query<&Interaction, Changed<Interaction>>) {
|
/// Manage the cursor icon for better immersion
|
||||||
events.iter().for_each(|interaction| {
|
fn manage_cursor(
|
||||||
info!("When tab is clicked, show/hide content");
|
mut primary_window: Query<&mut Window, With<PrimaryWindow>>,
|
||||||
|
events: Query<&Interaction, With<Interaction>>,
|
||||||
|
) {
|
||||||
|
events.iter().for_each(|event| {
|
||||||
|
let mut window = primary_window.single_mut();
|
||||||
|
window.cursor.icon = match event {
|
||||||
|
Interaction::Pressed => CursorIcon::Grabbing,
|
||||||
|
Interaction::Hovered => CursorIcon::Hand,
|
||||||
|
Interaction::None => CursorIcon::Default,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,14 @@
|
|||||||
|
if *duration > Duration::ZERO {
|
||||||
|
let mut text = texts.single_mut();
|
||||||
|
let total_sections = text.sections.len();
|
||||||
|
|
||||||
|
*duration = duration.saturating_sub(time.delta());
|
||||||
|
|
||||||
|
for (idx, section) in text.sections.iter_mut().enumerate() {
|
||||||
|
let ratio = ((idx + 1) as f32) / (total_sections as f32);
|
||||||
|
let cursor = 1.0 - ((*duration).as_secs_f32() / 30.0);
|
||||||
|
let alpha = if cursor > ratio { 1.0 } else { 0.0 };
|
||||||
|
section.style.color.set_a(alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue