diff --git a/crates/bevy_lunex/src/logic/cursor.rs b/crates/bevy_lunex/src/logic/cursor.rs index e08e982..b636883 100644 --- a/crates/bevy_lunex/src/logic/cursor.rs +++ b/crates/bevy_lunex/src/logic/cursor.rs @@ -8,7 +8,7 @@ use pointer::{InputMove, InputPress, Location}; /// Component for easy cursor control. /// Read more about it in the [docs](https://bytestring-net.github.io/bevy_lunex/advanced/3_cursor.html) -#[derive(Component, Default)] +#[derive(Component, Debug, Clone, PartialEq)] pub struct Cursor2d { /// Indicates which cursor is being requested. cursor_request: CursorIcon, @@ -48,7 +48,18 @@ impl Cursor2d { self } } - +impl Default for Cursor2d { + fn default() -> Self { + Self { + cursor_request: Default::default(), + cursor_request_priority: Default::default(), + cursor_atlas_map: Default::default(), + location: Default::default(), + confined: Default::default(), + visible: true, + } + } +} /// This will make the [`Cursor2d`] controllable by specific gamepad. #[derive(Component, Debug, Clone, PartialEq)] @@ -84,6 +95,56 @@ pub enum GamepadCursorMode { } +// #======================# +// #=== CURSOR BUNDLES ===# + +/// Use this bundle to spawn native cursor +#[derive(Bundle)] +pub struct CursorBundle { + /// Main cursor component + pub cursor: Cursor2d, + /// The virtual pointer that the cursor controls + pub pointer: PointerBundle, + /// Required for Cursor to exist + pub spatial: SpatialBundle, +} +impl Default for CursorBundle { + fn default() -> Self { + Self { + cursor: default(), + pointer: PointerBundle::new(PointerId::Custom(pointer::Uuid::new_v4())), + spatial: default(), + } + } +} + +/// Use this bundle to spawn styled custom cursor +#[derive(Bundle)] +pub struct StyledCursorBundle { + /// Main cursor component + pub cursor: Cursor2d, + /// The virtual pointer that the cursor controls + pub pointer: PointerBundle, + /// Sprite atlas for the cursor + pub atlas: TextureAtlas, + /// Sprite cursor + pub sprite: SpriteBundle, + /// Required to be [`Pickable::IGNORE`] + pub pickable: Pickable, +} +impl Default for StyledCursorBundle { + fn default() -> Self { + Self { + cursor: default(), + pointer: PointerBundle::new(PointerId::Custom(pointer::Uuid::new_v4())), + atlas: default(), + sprite: default(), + pickable: Pickable::IGNORE, + } + } +} + + // #========================# // #=== CURSOR FUNCTIONS ===# @@ -158,13 +219,16 @@ fn gamepad_move_cursor( fn mouse_move_cursor( windows: Query<&Window, With>, cameras: Query<&OrthographicProjection>, - mut query: Query<(&mut Cursor2d, &Parent), Without> + mut query: Query<(&mut Cursor2d, Option<&Parent>), Without> ) { if let Ok(window) = windows.get_single() { - for (mut cursor, parent) in &mut query { + for (mut cursor, parent_option) in &mut query { if let Some(position) = window.cursor_position() { // Get projection scale to account for zoomed cameras - let scale = if let Ok(projection) = cameras.get(**parent) { projection.scale } else { 1.0 }; + let scale = if let Some(parent) = parent_option { + if let Ok(projection) = cameras.get(**parent) { projection.scale } else { 1.0 } + } else { 1.0 }; + // Move the cursor cursor.location.x = (position.x - window.width()*0.5) * scale; diff --git a/crates/bevy_lunex/src/structs.rs b/crates/bevy_lunex/src/structs.rs index 13e30da..fa096d3 100644 --- a/crates/bevy_lunex/src/structs.rs +++ b/crates/bevy_lunex/src/structs.rs @@ -1,5 +1,5 @@ use crate::*; -use bevy::{render::primitives::Aabb, sprite::{Anchor, SpriteSource}, text::{Text2dBounds, TextLayoutInfo}}; +use bevy::{render::primitives::Aabb, sprite::{Anchor, Material2d, Mesh2dHandle, SpriteSource}, text::{Text2dBounds, TextLayoutInfo}}; // #=====================# @@ -488,6 +488,31 @@ impl UiMaterial3dBundle { } +/// Additional bundle for `UiNode` entity. +/// Provides functionality to bind mesh in 2D to a `UiNode`. +#[derive(Bundle, Default, Clone)] +pub struct UiMaterial2dBundle { + /// The mesh + pub mesh: Mesh2dHandle, + /// Material of the mesh + pub material: Handle, + /// Marks this as node element. + pub element: Element, + /// Contains the ui node size. + pub dimension: Dimension, + /// The visibility of the entity. + pub visibility: Visibility, + /// The inherited visibility of the entity. + pub inherited_visibility: InheritedVisibility, + /// The view visibility of the entity. + pub view_visibility: ViewVisibility, + /// The transform of the entity. + pub transform: Transform, + /// The global transform of the entity. + pub global_transform: GlobalTransform, +} + + /// Additional bundle for `UiNode` entity. /// Provides functionality to bind sprite to `UiNode`. #[derive(Bundle, Clone, Debug, Default)] diff --git a/docs/src/advanced/abstraction/1_components.md b/docs/src/advanced/abstraction/1_components.md index 2c38b86..96e86dd 100644 --- a/docs/src/advanced/abstraction/1_components.md +++ b/docs/src/advanced/abstraction/1_components.md @@ -11,7 +11,7 @@ Begin by creating a new `.rs` file in the `components` folder. First, define a p /// When this component is added, a UI system is built #[derive(Component)] -pub struct CustomButtom { +pub struct CustomButton { // Any fields we want to interact with should be here. text: String, } diff --git a/examples/bevypunk/goto.md b/examples/bevypunk/goto.md new file mode 100644 index 0000000..4f9a58f --- /dev/null +++ b/examples/bevypunk/goto.md @@ -0,0 +1 @@ +This example has it's own repository: https://github.com/IDEDARY/Calculator \ No newline at end of file diff --git a/examples/calculator/goto.md b/examples/calculator/goto.md new file mode 100644 index 0000000..4172d12 --- /dev/null +++ b/examples/calculator/goto.md @@ -0,0 +1 @@ +This example has it's own repository: https://github.com/IDEDARY/Bevypunk \ No newline at end of file diff --git a/examples/mesh2d/assets/background.png b/examples/mesh2d/assets/background.png deleted file mode 100644 index 9c9ad3e..0000000 Binary files a/examples/mesh2d/assets/background.png and /dev/null differ diff --git a/examples/mesh2d/src/main.rs b/examples/mesh2d/src/main.rs index 9a664cb..c43bd27 100644 --- a/examples/mesh2d/src/main.rs +++ b/examples/mesh2d/src/main.rs @@ -1,4 +1,4 @@ -use bevy::{prelude::*, sprite::{MaterialMesh2dBundle, Mesh2dHandle}}; +use bevy::prelude::*; use bevy_lunex::prelude::*; @@ -9,8 +9,9 @@ fn main() { .run(); } -fn setup(mut cmd: Commands, mut meshes: ResMut>, mut materials: ResMut>) { +fn setup(mut cmd: Commands, mut materials: ResMut>) { + // Spawn camera cmd.spawn(( MainUi, Camera2dBundle { @@ -20,6 +21,7 @@ fn setup(mut cmd: Commands, mut meshes: ResMut>, mut materials: Res } )); + // Spawn UiTree cmd.spawn(( UiTreeBundle:: { tree: UiTree::new("MyUiSystem"), @@ -28,23 +30,20 @@ fn setup(mut cmd: Commands, mut meshes: ResMut>, mut materials: Res MovableByCamera, )).with_children(|ui| { + // Spawn boundary node ui.spawn(( UiLink::::path("Root"), UiLayout::boundary().pos1(Ab(20.0)).pos2(Rl(100.0) - Ab(20.0)).pack::(), )); + // Spawn a color filled node ui.spawn(( UiLink::::path("Root/Rectangle"), UiLayout::solid().size((Ab(1920.0), Ab(1080.0))).pack::(), - Element, - Dimension::default(), - MaterialMesh2dBundle { - mesh: Mesh2dHandle(meshes.add(Rectangle { half_size: Vec2::splat(50.0) })), + UiMaterial2dBundle { material: materials.add(Color::srgb(1.0, 0.5, 0.5)), ..default() } )); - }); - } \ No newline at end of file diff --git a/examples/minimal/src/main.rs b/examples/minimal/src/main.rs index 436cae5..b4c0f1f 100644 --- a/examples/minimal/src/main.rs +++ b/examples/minimal/src/main.rs @@ -11,6 +11,7 @@ fn main() { fn setup(mut cmd: Commands, assets: Res) { + // Spawn camera cmd.spawn(( MainUi, Camera2dBundle { @@ -20,6 +21,7 @@ fn setup(mut cmd: Commands, assets: Res) { } )); + // Spawn UiTree cmd.spawn(( UiTreeBundle:: { tree: UiTree::new("MyUiSystem"), @@ -28,17 +30,17 @@ fn setup(mut cmd: Commands, assets: Res) { MovableByCamera, )).with_children(|ui| { + // Spawn boundary node ui.spawn(( UiLink::::path("Root"), UiLayout::boundary().pos1(Ab(20.0)).pos2(Rl(100.0) - Ab(20.0)).pack::(), )); + // Spawn image with a node ui.spawn(( UiLink::::path("Root/Rectangle"), UiLayout::solid().size((Ab(1920.0), Ab(1080.0))).pack::(), UiImage2dBundle::from(assets.load("background.png")), )); - }); - } \ No newline at end of file