Skip to content

Commit c9a3f34

Browse files
authored
Fixes for a few minor borders and outlines bugs (#16071)
# Objective 1. Nodes with `Display::None` set are removed from the layout and have no position or size. Outlines should not be drawn for a node with `Display::None` set. 2. The outline and border colors are checked for transparency together. If only one of the two is transparent, both will get queued. 3. The `node.is_empty()` check is insufficient to check if a border is present since a non-zero sized node can have a zero width border. ## Solution 1. Add a check to `extract_uinode_borders` and ignore the node if `Display::None` is set. 2. Filter the border and outline optional components by `is_fully_transparent`. 3. Check if all the border widths are zero instead. ## Testing I added dark cyan outlines around the left and right sections in the `display_and_visibility` example. If you run the example and set the outermost node to `Display::None` on the right, then you'll see the that the outline on the left disappears.
1 parent 7577895 commit c9a3f34

File tree

2 files changed

+36
-21
lines changed

2 files changed

+36
-21
lines changed

crates/bevy_ui/src/render/mod.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ mod ui_material_pipeline;
55
pub mod ui_texture_slice_pipeline;
66

77
use crate::{
8-
BackgroundColor, BorderColor, CalculatedClip, ComputedNode, DefaultUiCamera, Outline,
9-
ResolvedBorderRadius, TargetCamera, UiAntiAlias, UiBoxShadowSamples, UiImage, UiScale,
8+
BackgroundColor, BorderColor, CalculatedClip, ComputedNode, DefaultUiCamera, Display, Node,
9+
Outline, ResolvedBorderRadius, TargetCamera, UiAntiAlias, UiBoxShadowSamples, UiImage, UiScale,
1010
};
1111
use bevy_app::prelude::*;
1212
use bevy_asset::{load_internal_asset, AssetEvent, AssetId, Assets, Handle};
@@ -399,6 +399,7 @@ pub fn extract_uinode_borders(
399399
uinode_query: Extract<
400400
Query<(
401401
Entity,
402+
&Node,
402403
&ComputedNode,
403404
&GlobalTransform,
404405
&ViewVisibility,
@@ -415,7 +416,8 @@ pub fn extract_uinode_borders(
415416

416417
for (
417418
entity,
418-
uinode,
419+
node,
420+
computed_node,
419421
global_transform,
420422
view_visibility,
421423
maybe_clip,
@@ -435,24 +437,22 @@ pub fn extract_uinode_borders(
435437
continue;
436438
};
437439

438-
// Skip invisible borders
439-
if !view_visibility.get()
440-
|| maybe_border_color.is_some_and(|border_color| border_color.0.is_fully_transparent())
441-
&& maybe_outline.is_some_and(|outline| outline.color.is_fully_transparent())
442-
{
440+
// Skip invisible borders and removed nodes
441+
if !view_visibility.get() || node.display == Display::None {
443442
continue;
444443
}
445444

446-
// don't extract border if no border or the node is zero-sized (a zero sized node can still have an outline).
447-
if !uinode.is_empty() && uinode.border() != BorderRect::ZERO {
448-
if let Some(border_color) = maybe_border_color {
445+
// Don't extract borders with zero width along all edges
446+
if computed_node.border() != BorderRect::ZERO {
447+
if let Some(border_color) = maybe_border_color.filter(|bc| !bc.0.is_fully_transparent())
448+
{
449449
extracted_uinodes.uinodes.insert(
450450
commands.spawn(TemporaryRenderEntity).id(),
451451
ExtractedUiNode {
452-
stack_index: uinode.stack_index,
452+
stack_index: computed_node.stack_index,
453453
color: border_color.0.into(),
454454
rect: Rect {
455-
max: uinode.size(),
455+
max: computed_node.size(),
456456
..Default::default()
457457
},
458458
image,
@@ -463,8 +463,8 @@ pub fn extract_uinode_borders(
463463
transform: global_transform.compute_matrix(),
464464
flip_x: false,
465465
flip_y: false,
466-
border: uinode.border(),
467-
border_radius: uinode.border_radius(),
466+
border: computed_node.border(),
467+
border_radius: computed_node.border_radius(),
468468
node_type: NodeType::Border,
469469
},
470470
main_entity: entity.into(),
@@ -473,15 +473,20 @@ pub fn extract_uinode_borders(
473473
}
474474
}
475475

476-
if let Some(outline) = maybe_outline {
477-
let outline_size = uinode.outlined_node_size();
476+
if computed_node.outline_width() <= 0. {
477+
continue;
478+
}
479+
480+
if let Some(outline) = maybe_outline.filter(|outline| !outline.color.is_fully_transparent())
481+
{
482+
let outline_size = computed_node.outlined_node_size();
478483
let parent_clip =
479484
maybe_parent.and_then(|parent| parent_clip_query.get(parent.get()).ok());
480485

481486
extracted_uinodes.uinodes.insert(
482487
commands.spawn(TemporaryRenderEntity).id(),
483488
ExtractedUiNode {
484-
stack_index: uinode.stack_index,
489+
stack_index: computed_node.stack_index,
485490
color: outline.color.into(),
486491
rect: Rect {
487492
max: outline_size,
@@ -495,8 +500,8 @@ pub fn extract_uinode_borders(
495500
atlas_scaling: None,
496501
flip_x: false,
497502
flip_y: false,
498-
border: BorderRect::square(uinode.outline_width()),
499-
border_radius: uinode.outline_radius(),
503+
border: BorderRect::square(computed_node.outline_width()),
504+
border_radius: computed_node.outline_radius(),
500505
node_type: NodeType::Border,
501506
},
502507
main_entity: entity.into(),

examples/ui/display_and_visibility.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Demonstrates how Display and Visibility work in the UI.
22
33
use bevy::{
4-
color::palettes::css::{DARK_GRAY, YELLOW},
4+
color::palettes::css::{DARK_CYAN, DARK_GRAY, YELLOW},
55
prelude::*,
66
winit::WinitSettings,
77
};
@@ -187,6 +187,11 @@ fn spawn_left_panel(builder: &mut ChildBuilder, palette: &[Color; 4]) -> Vec<Ent
187187
..default()
188188
},
189189
BackgroundColor(palette[0]),
190+
Outline {
191+
width: Val::Px(4.),
192+
color: DARK_CYAN.into(),
193+
offset: Val::Px(10.),
194+
},
190195
))
191196
.with_children(|parent| {
192197
parent.spawn(Node {
@@ -289,6 +294,11 @@ fn spawn_right_panel(
289294
..default()
290295
},
291296
BackgroundColor(palette[0]),
297+
Outline {
298+
width: Val::Px(4.),
299+
color: DARK_CYAN.into(),
300+
offset: Val::Px(10.),
301+
},
292302
))
293303
.with_children(|parent| {
294304
spawn_buttons(parent, target_ids.pop().unwrap());

0 commit comments

Comments
 (0)