-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ignore clicks on uinodes outside of rounded corners #14957
Ignore clicks on uinodes outside of rounded corners #14957
Conversation
* Changed `Node` to use the `ResolvedBorderRadius` type.
…values from `Node`.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks generally correct to me. There might be a branchless way to do this, but it's probably not worth optimizing that for picking.
@ickshonpe once merge conflicts are resolved I'd like to get this in ASAP :) |
Should be ready now. |
@ickshonpe |
…15053) # Objective #14957 added the `pick_rounded_rect` function to `bevy_ui` in the `picking_backend` module, which is gated behind the `bevy_picking` feature. This function is used in that module, as well as in the `focus` module. The latter usage is not gated behind the `bevy_picking` feature, causing a compile error when the feature is disabled. ## Solution Move the `pick_rounded_rect` function out of the `picking_backend` module, as it does not depend on anything defined in that module. I put it in `lib.rs` but it could reasonably be moved somewhere else instead. ## Testing Encountered this compile error in a project and confirmed that this patch fixes it.
Fixes #14941 1. Add a `resolved_border_radius` field to `Node` to hold the resolved border radius values. 2. Remove the border radius calculations from the UI's extraction functions. 4. Compute the border radius during UI relayouts in `ui_layout_system` and store them in `Node`. 5. New `pick_rounded_rect` function based on the border radius SDF from `ui.wgsl`. 6. Use `pick_rounded_rect` in `focus` and `picking_backend` to check if the pointer is hovering UI nodes with rounded corners. --- ``` cargo run --example button ``` https://github.com/user-attachments/assets/ea951a64-17ef-455e-b5c9-a2e6f6360648 Modified button example with buttons with different corner radius: ``` use bevy::{color::palettes::basic::*, prelude::*, winit::WinitSettings}; fn main() { App::new() .add_plugins(DefaultPlugins) // Only run the app when there is user input. This will significantly reduce CPU/GPU use. .insert_resource(WinitSettings::desktop_app()) .add_systems(Startup, setup) .add_systems(Update, button_system) .run(); } const NORMAL_BUTTON: Color = Color::srgb(0.15, 0.15, 0.15); const HOVERED_BUTTON: Color = Color::srgb(0.25, 0.25, 0.25); const PRESSED_BUTTON: Color = Color::srgb(0.35, 0.75, 0.35); fn button_system( mut interaction_query: Query< ( &Interaction, &mut BackgroundColor, &mut BorderColor, &Children, ), (Changed<Interaction>, With<Button>), >, mut text_query: Query<&mut Text>, ) { for (interaction, mut color, mut border_color, children) in &mut interaction_query { let mut text = text_query.get_mut(children[0]).unwrap(); match *interaction { Interaction::Pressed => { text.sections[0].value = "Press".to_string(); *color = PRESSED_BUTTON.into(); border_color.0 = RED.into(); } Interaction::Hovered => { text.sections[0].value = "Hover".to_string(); *color = HOVERED_BUTTON.into(); border_color.0 = Color::WHITE; } Interaction::None => { text.sections[0].value = "Button".to_string(); *color = NORMAL_BUTTON.into(); border_color.0 = Color::BLACK; } } } } fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { // ui camera commands.spawn(Camera2dBundle::default()); commands .spawn(NodeBundle { style: Style { width: Val::Percent(100.0), height: Val::Percent(100.0), align_items: AlignItems::Center, justify_content: JustifyContent::Center, row_gap: Val::Px(10.), ..default() }, ..default() }) .with_children(|parent| { for border_radius in [ BorderRadius { top_left: Val::ZERO, ..BorderRadius::MAX }, BorderRadius { top_right: Val::ZERO, ..BorderRadius::MAX }, BorderRadius { bottom_right: Val::ZERO, ..BorderRadius::MAX }, BorderRadius { bottom_left: Val::ZERO, ..BorderRadius::MAX }, ] { parent .spawn(ButtonBundle { style: Style { width: Val::Px(150.0), height: Val::Px(65.0), border: UiRect::all(Val::Px(5.0)), // horizontally center child text justify_content: JustifyContent::Center, // vertically center child text align_items: AlignItems::Center, ..default() }, border_color: BorderColor(Color::BLACK), border_radius, background_color: NORMAL_BUTTON.into(), ..default() }) .with_child(TextBundle::from_section( "Button", TextStyle { font: asset_server.load("fonts/FiraSans-Bold.ttf"), font_size: 40.0, color: Color::srgb(0.9, 0.9, 0.9), }, )); } }); } ``` --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Matty <weatherleymatthew@gmail.com>
…evyengine#15053) # Objective bevyengine#14957 added the `pick_rounded_rect` function to `bevy_ui` in the `picking_backend` module, which is gated behind the `bevy_picking` feature. This function is used in that module, as well as in the `focus` module. The latter usage is not gated behind the `bevy_picking` feature, causing a compile error when the feature is disabled. ## Solution Move the `pick_rounded_rect` function out of the `picking_backend` module, as it does not depend on anything defined in that module. I put it in `lib.rs` but it could reasonably be moved somewhere else instead. ## Testing Encountered this compile error in a project and confirmed that this patch fixes it.
Objective
Fixes #14941
Solution
resolved_border_radius
field toNode
to hold the resolved border radius values.ui_layout_system
and store them inNode
.pick_rounded_rect
function based on the border radius SDF fromui.wgsl
.pick_rounded_rect
infocus
andpicking_backend
to check if the pointer is hovering UI nodes with rounded corners.Showcase
App.2024-08-28.15-28-19.mp4
Testing
Modified button example with buttons with different corner radius: