Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion crates/bevy_input_focus/src/directional_navigation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,6 @@ impl DirectionalNavigationMap {
self.neighbors.get(&entity)
}
}

/// A system parameter for navigating between focusable entities in a directional way.
#[derive(SystemParam, Debug)]
pub struct DirectionalNavigation<'w> {
Expand Down
28 changes: 21 additions & 7 deletions crates/bevy_ui/src/auto_directional_navigation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use crate::{ComputedNode, ComputedUiTargetCamera, UiGlobalTransform};
use bevy_camera::visibility::InheritedVisibility;
use bevy_ecs::{prelude::*, system::SystemParam};
use bevy_math::CompassOctant;
use bevy_math::{ops, CompassOctant, Vec2};

use bevy_input_focus::{
directional_navigation::{
Expand All @@ -16,7 +16,17 @@ use bevy_input_focus::{
};

use bevy_reflect::{prelude::*, Reflect};

fn get_rotated_bounds(size: Vec2, rotation: f32) -> Vec2 {
if rotation == 0.0 {
return size;
}
let cos_r = ops::cos(rotation).abs();
let sin_r = ops::sin(rotation).abs();
Vec2::new(
size.x * cos_r + size.y * sin_r,
size.x * sin_r + size.y * cos_r,
)
}
/// Marker component to enable automatic directional navigation to and from the entity.
///
/// Simply add this component to your UI entities so that the navigation algorithm will
Expand Down Expand Up @@ -101,6 +111,7 @@ pub struct AutoDirectionalNavigation {
/// To use, the [`DirectionalNavigationPlugin`](bevy_input_focus::directional_navigation::DirectionalNavigationPlugin)
/// must be added to the app.
#[derive(SystemParam, Debug)]

pub struct AutoDirectionalNavigator<'w, 's> {
/// A system parameter for the manual directional navigation system provided by `bevy_input_focus`
pub manual_directional_navigation: DirectionalNavigation<'w>,
Expand Down Expand Up @@ -184,12 +195,13 @@ impl<'w, 's> AutoDirectionalNavigator<'w, 's> {
if let Some(tc) = computed_target_camera.get()
&& tc == target_camera
{
let (_scale, _rotation, translation) =
transform.to_scale_angle_translation();
let (scale, rotation, translation) = transform.to_scale_angle_translation();
let scaled_size = computed.size() * computed.inverse_scale_factor() * scale;
let rotated_size = get_rotated_bounds(scaled_size, rotation);
Some(FocusableArea {
entity,
position: translation * computed.inverse_scale_factor(),
size: computed.size() * computed.inverse_scale_factor(),
size: rotated_size,
})
} else {
// The node either does not have a target camera or it is not the same as the desired one.
Expand All @@ -212,13 +224,15 @@ impl<'w, 's> AutoDirectionalNavigator<'w, 's> {
None,
|(entity, computed_target_camera, computed, transform)| {
if let Some(target_camera) = computed_target_camera.get() {
let (_scale, _rotation, translation) = transform.to_scale_angle_translation();
let (scale, rotation, translation) = transform.to_scale_angle_translation();
let scaled_size = computed.size() * computed.inverse_scale_factor() * scale;
let rotated_size = get_rotated_bounds(scaled_size, rotation);
Some((
target_camera,
FocusableArea {
entity,
position: translation * computed.inverse_scale_factor(),
size: computed.size() * computed.inverse_scale_factor(),
size: rotated_size,
},
))
} else {
Expand Down
6 changes: 4 additions & 2 deletions examples/ui/auto_directional_navigation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
//! The automatic system finds the nearest neighbor in each compass direction for every node,
//! completely eliminating the need to manually specify navigation relationships.

use core::time::Duration;

use bevy::ui::UiTransform;
use bevy::{
camera::NormalizedRenderTarget,
input_focus::{
Expand All @@ -29,6 +28,7 @@ use bevy::{
prelude::*,
ui::auto_directional_navigation::{AutoDirectionalNavigation, AutoDirectionalNavigator},
};
use core::time::Duration;

fn main() {
App::new()
Expand Down Expand Up @@ -225,6 +225,8 @@ fn setup_scattered_ui(mut commands: Commands, mut input_focus: ResMut<InputFocus
border_radius: BorderRadius::all(px(12)),
..default()
},
// Apply a scale transform to demonstrate that navigation handles transforms
UiTransform::from_scale(Vec2::splat(2.0)),
// This is the key: just add this component for automatic navigation!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is now misplaced.

AutoDirectionalNavigation::default(),
ResetTimer::default(),
Expand Down