Skip to content

Commit

Permalink
Cleaning up NodeBundle, and some slight UI module re-organization (#6473
Browse files Browse the repository at this point in the history
)

# Objective

`NodeBundle` contains an `image` field, which can be misleading, because if you do supply an image there, nothing will be shown to screen. You need to use an `ImageBundle` instead.

## Solution

* `image` (`UiImage`) field is removed from `NodeBundle`, 
* extraction stage queries now make an optional query for `UiImage`, if one is not found, use the image handle that is used as a default by `UiImage`: https://github.com/bevyengine/bevy/blob/c019a60b39c5683656025bc9d24a02744aa59dea/crates/bevy_ui/src/ui_node.rs#L464
* touching up docs for `NodeBundle` to help guide what `NodeBundle` should be used for
* renamed `entity.rs` to `node_bundle.rs` as that gives more of a hint regarding the module's purpose
* separating `camera_config` stuff from the pre-made UI node bundles so that `node_bundle.rs` makes more sense as a module name.
  • Loading branch information
bzm3r committed Nov 5, 2022
1 parent 5ae9475 commit 66f495c
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 47 deletions.
37 changes: 37 additions & 0 deletions crates/bevy_ui/src/camera_config.rs
@@ -0,0 +1,37 @@
//! Configuration for cameras related to UI.

use bevy_ecs::component::Component;
use bevy_ecs::prelude::With;
use bevy_ecs::query::QueryItem;
use bevy_render::camera::Camera;
use bevy_render::extract_component::ExtractComponent;

/// Configuration for cameras related to UI.
///
/// When a [`Camera`] doesn't have the [`UiCameraConfig`] component,
/// it will display the UI by default.
///
/// [`Camera`]: bevy_render::camera::Camera
#[derive(Component, Clone)]
pub struct UiCameraConfig {
/// Whether to output UI to this camera view.
///
/// When a `Camera` doesn't have the [`UiCameraConfig`] component,
/// it will display the UI by default.
pub show_ui: bool,
}

impl Default for UiCameraConfig {
fn default() -> Self {
Self { show_ui: true }
}
}

impl ExtractComponent for UiCameraConfig {
type Query = &'static Self;
type Filter = With<Camera>;

fn extract_component(item: QueryItem<'_, Self::Query>) -> Self {
item.clone()
}
}
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/focus.rs
@@ -1,4 +1,4 @@
use crate::{entity::UiCameraConfig, CalculatedClip, Node, UiStack};
use crate::{camera_config::UiCameraConfig, CalculatedClip, Node, UiStack};
use bevy_ecs::{
entity::Entity,
prelude::Component,
Expand Down
10 changes: 7 additions & 3 deletions crates/bevy_ui/src/lib.rs
@@ -1,6 +1,6 @@
//! This crate contains Bevy's UI system, which can be used to create UI for both 2D and 3D games
//! # Basic usage
//! Spawn UI elements with [`entity::ButtonBundle`], [`entity::ImageBundle`], [`entity::TextBundle`] and [`entity::NodeBundle`]
//! Spawn UI elements with [`node_bundles::ButtonBundle`], [`node_bundles::ImageBundle`], [`node_bundles::TextBundle`] and [`node_bundles::NodeBundle`]
//! This UI is laid out with the Flexbox paradigm (see <https://cssreference.io/flexbox/>)
mod flex;
mod focus;
Expand All @@ -9,7 +9,8 @@ mod render;
mod stack;
mod ui_node;

pub mod entity;
pub mod camera_config;
pub mod node_bundles;
pub mod update;
pub mod widget;

Expand All @@ -23,7 +24,10 @@ pub use ui_node::*;
#[doc(hidden)]
pub mod prelude {
#[doc(hidden)]
pub use crate::{entity::*, geometry::*, ui_node::*, widget::Button, Interaction, UiScale};
pub use crate::{
camera_config::*, geometry::*, node_bundles::*, ui_node::*, widget::Button, Interaction,
UiScale,
};
}

use bevy_app::prelude::*;
Expand Down
@@ -1,24 +1,20 @@
//! This module contains the bundles used in Bevy's UI
//! This module contains basic node bundles used to build UIs

use crate::{
widget::{Button, ImageMode},
BackgroundColor, CalculatedSize, FocusPolicy, Interaction, Node, Style, UiImage, ZIndex,
};
use bevy_ecs::{
bundle::Bundle,
prelude::{Component, With},
query::QueryItem,
};
use bevy_ecs::bundle::Bundle;
use bevy_render::{
camera::Camera,
extract_component::ExtractComponent,
prelude::{Color, ComputedVisibility},
view::Visibility,
};
use bevy_text::{Text, TextAlignment, TextSection, TextStyle};
use bevy_transform::prelude::{GlobalTransform, Transform};

/// The basic UI node
///
/// Useful as a container for a variety of child nodes.
#[derive(Bundle, Clone, Debug)]
pub struct NodeBundle {
/// Describes the size of the node
Expand All @@ -27,8 +23,6 @@ pub struct NodeBundle {
pub style: Style,
/// The background color, which serves as a "fill" for this node
pub background_color: BackgroundColor,
/// Describes the image of the node
pub image: UiImage,
/// Whether this node should block interaction with lower nodes
pub focus_policy: FocusPolicy,
/// The transform of the node
Expand Down Expand Up @@ -56,7 +50,6 @@ impl Default for NodeBundle {
background_color: Color::NONE.into(),
node: Default::default(),
style: Default::default(),
image: Default::default(),
focus_policy: Default::default(),
transform: Default::default(),
global_transform: Default::default(),
Expand Down Expand Up @@ -241,32 +234,3 @@ impl Default for ButtonBundle {
}
}
}
/// Configuration for cameras related to UI.
///
/// When a [`Camera`] doesn't have the [`UiCameraConfig`] component,
/// it will display the UI by default.
///
/// [`Camera`]: bevy_render::camera::Camera
#[derive(Component, Clone)]
pub struct UiCameraConfig {
/// Whether to output UI to this camera view.
///
/// When a `Camera` doesn't have the [`UiCameraConfig`] component,
/// it will display the UI by default.
pub show_ui: bool,
}

impl Default for UiCameraConfig {
fn default() -> Self {
Self { show_ui: true }
}
}

impl ExtractComponent for UiCameraConfig {
type Query = &'static Self;
type Filter = With<Camera>;

fn extract_component(item: QueryItem<'_, Self::Query>) -> Self {
item.clone()
}
}
16 changes: 13 additions & 3 deletions crates/bevy_ui/src/render/mod.rs
Expand Up @@ -11,6 +11,7 @@ use bevy_asset::{load_internal_asset, AssetEvent, Assets, Handle, HandleUntyped}
use bevy_ecs::prelude::*;
use bevy_math::{Mat4, Rect, UVec4, Vec2, Vec3, Vec4Swizzles};
use bevy_reflect::TypeUuid;
use bevy_render::texture::DEFAULT_IMAGE_HANDLE;
use bevy_render::{
camera::Camera,
color::Color,
Expand Down Expand Up @@ -209,7 +210,7 @@ pub fn extract_uinodes(
&Node,
&GlobalTransform,
&BackgroundColor,
&UiImage,
Option<&UiImage>,
&ComputedVisibility,
Option<&CalculatedClip>,
)>,
Expand All @@ -218,11 +219,19 @@ pub fn extract_uinodes(
let scale_factor = windows.scale_factor(WindowId::primary()) as f32;
extracted_uinodes.uinodes.clear();
for (stack_index, entity) in ui_stack.uinodes.iter().enumerate() {
if let Ok((uinode, transform, color, image, visibility, clip)) = uinode_query.get(*entity) {
if let Ok((uinode, transform, color, maybe_image, visibility, clip)) =
uinode_query.get(*entity)
{
if !visibility.is_visible() {
continue;
}
let image = image.0.clone_weak();

let image = if let Some(image) = maybe_image {
image.0.clone_weak()
} else {
DEFAULT_IMAGE_HANDLE.typed().clone_weak()
};

// Skip loading images
if !images.contains(&image) {
continue;
Expand All @@ -231,6 +240,7 @@ pub fn extract_uinodes(
if color.0.a() == 0.0 {
continue;
}

extracted_uinodes.uinodes.push(ExtractedUiNode {
stack_index,
transform: transform.compute_matrix(),
Expand Down

0 comments on commit 66f495c

Please sign in to comment.