bevy_ui: Check clip when handling interactions (#3461)
# Objective Fix a bug: UI nodes that are clipped could still be interacted with in the clipped area. ## Solution Clip the position calculation in `ui_focus_system`
This commit is contained in:
parent
3a9d5a63c9
commit
601cc0cbe3
@ -1,4 +1,4 @@
|
|||||||
use crate::Node;
|
use crate::{CalculatedClip, Node};
|
||||||
use bevy_core::FloatOrd;
|
use bevy_core::FloatOrd;
|
||||||
use bevy_ecs::{
|
use bevy_ecs::{
|
||||||
entity::Entity,
|
entity::Entity,
|
||||||
@ -7,6 +7,7 @@ use bevy_ecs::{
|
|||||||
system::{Local, Query, Res},
|
system::{Local, Query, Res},
|
||||||
};
|
};
|
||||||
use bevy_input::{mouse::MouseButton, touch::Touches, Input};
|
use bevy_input::{mouse::MouseButton, touch::Touches, Input};
|
||||||
|
use bevy_math::Vec2;
|
||||||
use bevy_reflect::{Reflect, ReflectDeserialize};
|
use bevy_reflect::{Reflect, ReflectDeserialize};
|
||||||
use bevy_transform::components::GlobalTransform;
|
use bevy_transform::components::GlobalTransform;
|
||||||
use bevy_window::Windows;
|
use bevy_window::Windows;
|
||||||
@ -57,6 +58,7 @@ pub fn ui_focus_system(
|
|||||||
&GlobalTransform,
|
&GlobalTransform,
|
||||||
Option<&mut Interaction>,
|
Option<&mut Interaction>,
|
||||||
Option<&FocusPolicy>,
|
Option<&FocusPolicy>,
|
||||||
|
Option<&CalculatedClip>,
|
||||||
)>,
|
)>,
|
||||||
) {
|
) {
|
||||||
let cursor_position = if let Some(cursor_position) = windows
|
let cursor_position = if let Some(cursor_position) = windows
|
||||||
@ -78,7 +80,8 @@ pub fn ui_focus_system(
|
|||||||
let mouse_released =
|
let mouse_released =
|
||||||
mouse_button_input.just_released(MouseButton::Left) || touches_input.just_released(0);
|
mouse_button_input.just_released(MouseButton::Left) || touches_input.just_released(0);
|
||||||
if mouse_released {
|
if mouse_released {
|
||||||
for (_entity, _node, _global_transform, interaction, _focus_policy) in node_query.iter_mut()
|
for (_entity, _node, _global_transform, interaction, _focus_policy, _clip) in
|
||||||
|
node_query.iter_mut()
|
||||||
{
|
{
|
||||||
if let Some(mut interaction) = interaction {
|
if let Some(mut interaction) = interaction {
|
||||||
if *interaction == Interaction::Clicked {
|
if *interaction == Interaction::Clicked {
|
||||||
@ -94,12 +97,16 @@ pub fn ui_focus_system(
|
|||||||
let mut moused_over_z_sorted_nodes = node_query
|
let mut moused_over_z_sorted_nodes = node_query
|
||||||
.iter_mut()
|
.iter_mut()
|
||||||
.filter_map(
|
.filter_map(
|
||||||
|(entity, node, global_transform, interaction, focus_policy)| {
|
|(entity, node, global_transform, interaction, focus_policy, clip)| {
|
||||||
let position = global_transform.translation;
|
let position = global_transform.translation;
|
||||||
let ui_position = position.truncate();
|
let ui_position = position.truncate();
|
||||||
let extents = node.size / 2.0;
|
let extents = node.size / 2.0;
|
||||||
let min = ui_position - extents;
|
let mut min = ui_position - extents;
|
||||||
let max = ui_position + extents;
|
let mut max = ui_position + extents;
|
||||||
|
if let Some(clip) = clip {
|
||||||
|
min = Vec2::max(min, clip.clip.min);
|
||||||
|
max = Vec2::min(max, clip.clip.max);
|
||||||
|
}
|
||||||
// if the current cursor position is within the bounds of the node, consider it for
|
// if the current cursor position is within the bounds of the node, consider it for
|
||||||
// clicking
|
// clicking
|
||||||
if (min.x..max.x).contains(&cursor_position.x)
|
if (min.x..max.x).contains(&cursor_position.x)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user