diff --git a/crates/bevy_image/src/image.rs b/crates/bevy_image/src/image.rs index d9f02379f41fe..451a57ceb8778 100644 --- a/crates/bevy_image/src/image.rs +++ b/crates/bevy_image/src/image.rs @@ -5,7 +5,7 @@ use super::dds::*; #[cfg(feature = "ktx2")] use super::ktx2::*; -use bevy_asset::{Asset, RenderAssetUsages}; +use bevy_asset::{Asset, Handle, RenderAssetUsages}; use bevy_color::{Color, ColorToComponents, Gray, LinearRgba, Srgba, Xyza}; use bevy_math::{AspectRatio, UVec2, UVec3, Vec2}; use bevy_reflect::std_traits::ReflectDefault; @@ -282,6 +282,14 @@ impl ImageFormat { } } +/// A handle to a 1 x 1 transparent white image. +/// +/// Like [`Handle::default`], this is a handle to a fallback image asset. +/// While that handle points to an opaque white 1 x 1 image, this handle points to a transparent 1 x 1 white image. +// Number randomly selected by fair WolframAlpha query. Totally arbitrary. +pub const TRANSPARENT_IMAGE_HANDLE: Handle = + Handle::weak_from_u128(154728948001857810431816125397303024160); + #[derive(Asset, Reflect, Debug, Clone)] #[reflect(opaque)] #[reflect(Default, Debug)] diff --git a/crates/bevy_render/src/texture/mod.rs b/crates/bevy_render/src/texture/mod.rs index 3671b7a0c83db..7cba824ca640c 100644 --- a/crates/bevy_render/src/texture/mod.rs +++ b/crates/bevy_render/src/texture/mod.rs @@ -6,9 +6,13 @@ mod texture_cache; pub use crate::render_resource::DefaultImageSampler; #[cfg(feature = "basis-universal")] use bevy_image::CompressedImageSaver; +#[cfg(feature = "exr")] +use bevy_image::ExrTextureLoader; #[cfg(feature = "hdr")] use bevy_image::HdrTextureLoader; -use bevy_image::{CompressedImageFormats, Image, ImageLoader, ImageSamplerDescriptor}; +use bevy_image::{ + CompressedImageFormats, Image, ImageLoader, ImageSamplerDescriptor, TRANSPARENT_IMAGE_HANDLE, +}; pub use fallback_image::*; pub use gpu_image::*; pub use texture_attachment::*; @@ -21,14 +25,6 @@ use bevy_app::{App, Plugin}; use bevy_asset::{AssetApp, Assets, Handle}; use bevy_ecs::prelude::*; -/// A handle to a 1 x 1 transparent white image. -/// -/// Like [`Handle::default`], this is a handle to a fallback image asset. -/// While that handle points to an opaque white 1 x 1 image, this handle points to a transparent 1 x 1 white image. -// Number randomly selected by fair WolframAlpha query. Totally arbitrary. -pub const TRANSPARENT_IMAGE_HANDLE: Handle = - Handle::weak_from_u128(154728948001857810431816125397303024160); - // TODO: replace Texture names with Image names? /// Adds the [`Image`] as an asset and makes sure that they are extracted and prepared for the GPU. pub struct ImagePlugin { @@ -62,7 +58,7 @@ impl Plugin for ImagePlugin { fn build(&self, app: &mut App) { #[cfg(feature = "exr")] { - app.init_asset_loader::(); + app.init_asset_loader::(); } #[cfg(feature = "hdr")] diff --git a/crates/bevy_ui/Cargo.toml b/crates/bevy_ui/Cargo.toml index e8548a405df2f..f2486a816baf8 100644 --- a/crates/bevy_ui/Cargo.toml +++ b/crates/bevy_ui/Cargo.toml @@ -24,9 +24,10 @@ bevy_math = { path = "../bevy_math", version = "0.15.0-dev" } bevy_reflect = { path = "../bevy_reflect", version = "0.15.0-dev", features = [ "bevy", ] } -bevy_render = { path = "../bevy_render", version = "0.15.0-dev" } +bevy_render = { path = "../bevy_render", version = "0.15.0-dev", optional = true } +bevy_animation = { path = "../bevy_animation", version = "0.15.0-dev" } bevy_sprite = { path = "../bevy_sprite", version = "0.15.0-dev" } -bevy_text = { path = "../bevy_text", version = "0.15.0-dev" } +bevy_text = { path = "../bevy_text", version = "0.15.0-dev", optional = true } bevy_picking = { path = "../bevy_picking", version = "0.15.0-dev", optional = true } bevy_transform = { path = "../bevy_transform", version = "0.15.0-dev" } bevy_window = { path = "../bevy_window", version = "0.15.0-dev" } @@ -43,7 +44,7 @@ smallvec = "1.11" accesskit = "0.17" [features] -default = [] +default = ["bevy_ui_picking_backend", "bevy_render", "bevy_text"] serialize = ["serde", "smallvec/serde", "bevy_math/serialize"] bevy_ui_picking_backend = ["bevy_picking"] bevy_ui_debug = [] diff --git a/crates/bevy_ui/src/accessibility.rs b/crates/bevy_ui/src/accessibility.rs index 95686530ce37e..4bbeea89282b2 100644 --- a/crates/bevy_ui/src/accessibility.rs +++ b/crates/bevy_ui/src/accessibility.rs @@ -9,7 +9,7 @@ use bevy_app::{App, Plugin, PostUpdate}; use bevy_ecs::{ prelude::{DetectChanges, Entity}, query::{Changed, Without}, - schedule::IntoSystemConfigs, + schedule::IntoSystemConfigs as _, system::{Commands, Query}, world::Ref, }; diff --git a/crates/bevy_ui/src/experimental/ghost_hierarchy.rs b/crates/bevy_ui/src/experimental/ghost_hierarchy.rs index 42832c0483500..2cc569d33cb28 100644 --- a/crates/bevy_ui/src/experimental/ghost_hierarchy.rs +++ b/crates/bevy_ui/src/experimental/ghost_hierarchy.rs @@ -3,6 +3,7 @@ use bevy_ecs::{prelude::*, system::SystemParam}; use bevy_hierarchy::{Children, HierarchyQueryExt, Parent}; use bevy_reflect::prelude::*; +#[cfg(feature = "bevy_render")] use bevy_render::view::Visibility; use bevy_transform::prelude::Transform; use core::marker::PhantomData; @@ -20,7 +21,8 @@ use crate::Node; #[derive(Component, Debug, Copy, Clone, Reflect)] #[cfg_attr(feature = "ghost_nodes", derive(Default))] #[reflect(Component, Debug)] -#[require(Visibility, Transform)] +#[cfg_attr(feature = "bevy_render", require(Visibility))] +#[require(Transform)] pub struct GhostNode { // This is a workaround to ensure that GhostNode is only constructable when the appropriate feature flag is enabled #[reflect(ignore)] diff --git a/crates/bevy_ui/src/focus.rs b/crates/bevy_ui/src/focus.rs index f5175c61a8594..6e7e0e297de06 100644 --- a/crates/bevy_ui/src/focus.rs +++ b/crates/bevy_ui/src/focus.rs @@ -1,23 +1,24 @@ -use crate::{ - CalculatedClip, ComputedNode, DefaultUiCamera, ResolvedBorderRadius, TargetCamera, UiStack, -}; -use bevy_ecs::{ - change_detection::DetectChangesMut, - entity::{Entity, EntityBorrow}, - prelude::{Component, With}, - query::QueryData, - reflect::ReflectComponent, - system::{Local, Query, Res}, -}; -use bevy_input::{mouse::MouseButton, touch::Touches, ButtonInput}; +use crate::{CalculatedClip, ComputedNode}; +use bevy_ecs::{entity::Entity, prelude::Component, query::QueryData, reflect::ReflectComponent}; use bevy_math::{Rect, Vec2}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_render::{camera::NormalizedRenderTarget, prelude::Camera, view::ViewVisibility}; use bevy_transform::components::GlobalTransform; -use bevy_utils::HashMap; -use bevy_window::{PrimaryWindow, Window}; -use smallvec::SmallVec; +#[cfg(feature = "bevy_render")] +use { + crate::{DefaultUiCamera, ResolvedBorderRadius, TargetCamera, UiStack}, + bevy_ecs::{ + change_detection::DetectChangesMut as _, + entity::EntityBorrow as _, + prelude::With, + system::{Local, Query, Res}, + }, + bevy_input::{mouse::MouseButton, touch::Touches, ButtonInput}, + bevy_render::{camera::NormalizedRenderTarget, prelude::Camera, view::ViewVisibility}, + bevy_utils::HashMap, + bevy_window::{PrimaryWindow, Window}, + smallvec::SmallVec, +}; #[cfg(feature = "serialize")] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; @@ -125,6 +126,7 @@ impl Default for FocusPolicy { /// Contains entities whose Interaction should be set to None #[derive(Default)] +#[cfg(feature = "bevy_render")] pub struct State { entities_to_reset: SmallVec<[Entity; 1]>, } @@ -140,7 +142,9 @@ pub struct NodeQuery { relative_cursor_position: Option<&'static mut RelativeCursorPosition>, focus_policy: Option<&'static FocusPolicy>, calculated_clip: Option<&'static CalculatedClip>, + #[cfg(feature = "bevy_render")] view_visibility: Option<&'static ViewVisibility>, + #[cfg(feature = "bevy_render")] target_camera: Option<&'static TargetCamera>, } @@ -148,6 +152,7 @@ pub struct NodeQuery { /// /// Entities with a hidden [`ViewVisibility`] are always treated as released. #[allow(clippy::too_many_arguments)] +#[cfg(feature = "bevy_render")] pub fn ui_focus_system( mut state: Local, camera_query: Query<(Entity, &Camera)>, @@ -346,6 +351,7 @@ pub fn ui_focus_system( // the given size and border radius. // // Matches the sdf function in `ui.wgsl` that is used by the UI renderer to draw rounded rectangles. +#[cfg(feature = "bevy_render")] pub(crate) fn pick_rounded_rect( point: Vec2, size: Vec2, diff --git a/crates/bevy_ui/src/layout/mod.rs b/crates/bevy_ui/src/layout/mod.rs index 4c24ca322e065..08cf8e6d266fb 100644 --- a/crates/bevy_ui/src/layout/mod.rs +++ b/crates/bevy_ui/src/layout/mod.rs @@ -22,9 +22,8 @@ use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged}; use thiserror::Error; use ui_surface::UiSurface; -use bevy_text::ComputedTextBlock; - -use bevy_text::CosmicFontSystem; +#[cfg(feature = "bevy_text")] +use bevy_text::{ComputedTextBlock, CosmicFontSystem}; mod convert; pub mod debug; @@ -126,8 +125,8 @@ pub fn ui_layout_system( Option<&ScrollPosition>, )>, - mut buffer_query: Query<&mut ComputedTextBlock>, - mut font_system: ResMut, + #[cfg(feature = "bevy_text")] mut buffer_query: Query<&mut ComputedTextBlock>, + #[cfg(feature = "bevy_text")] mut font_system: ResMut, ) { let UiLayoutSystemBuffers { interned_root_nodes, @@ -269,6 +268,7 @@ with UI components as a child of an entity without UI components, your UI layout } }); + #[cfg(feature = "bevy_text")] let text_buffers = &mut buffer_query; // clean up removed nodes after syncing children to avoid potential panic (invalid SlotMap key used) ui_surface.remove_entities( @@ -288,8 +288,14 @@ with UI components as a child of an entity without UI components, your UI layout for (camera_id, mut camera) in camera_layout_info.drain() { let inverse_target_scale_factor = camera.scale_factor.recip(); - ui_surface.compute_camera_layout(camera_id, camera.size, text_buffers, &mut font_system); - + ui_surface.compute_camera_layout( + camera_id, + camera.size, + #[cfg(feature = "bevy_text")] + text_buffers, + #[cfg(feature = "bevy_text")] + &mut font_system, + ); for root in &camera.root_nodes { update_uinode_geometry_recursive( &mut commands, @@ -488,6 +494,7 @@ mod tests { }; use bevy_image::Image; use bevy_math::{Rect, UVec2, Vec2}; + use bevy_render::camera::Viewport; use bevy_render::{camera::ManualTextureViews, prelude::Camera}; use bevy_transform::{ prelude::GlobalTransform, @@ -504,6 +511,9 @@ mod tests { update::update_target_camera_system, ContentSize, LayoutContext, }; + #[cfg(feature = "bevy_text")] + use bevy_text::{ComputedTextBlock, CosmicFontSystem, SwashCache, TextPipeline}; + // these window dimensions are easy to convert to and from percentage values const WINDOW_WIDTH: f32 = 1000.; const WINDOW_HEIGHT: f32 = 100.; @@ -519,13 +529,12 @@ mod tests { world.init_resource::>>(); world.init_resource::>(); world.init_resource::(); - - world.init_resource::(); - - world.init_resource::(); - - world.init_resource::(); - + #[cfg(feature = "bevy_text")] + { + world.init_resource::(); + world.init_resource::(); + world.init_resource::(); + } // spawn a dummy primary window and camera world.spawn(( Window { @@ -915,7 +924,7 @@ mod tests { let viewport_height = primary_window.resolution.physical_height(); let physical_position = UVec2::new(viewport_width * camera_index as u32, 0); let physical_size = UVec2::new(viewport_width, viewport_height); - camera.viewport = Some(bevy_render::camera::Viewport { + camera.viewport = Some(Viewport { physical_position, physical_size, ..default() @@ -1164,13 +1173,12 @@ mod tests { world.init_resource::>>(); world.init_resource::>(); world.init_resource::(); - - world.init_resource::(); - - world.init_resource::(); - - world.init_resource::(); - + #[cfg(feature = "bevy_text")] + { + world.init_resource::(); + world.init_resource::(); + world.init_resource::(); + } // spawn a dummy primary window and camera world.spawn(( Window { @@ -1230,8 +1238,10 @@ mod tests { fn test_system( params: In, mut ui_surface: ResMut, - mut computed_text_block_query: Query<&mut bevy_text::ComputedTextBlock>, - mut font_system: ResMut, + #[cfg(feature = "bevy_text")] mut computed_text_block_query: Query< + &mut ComputedTextBlock, + >, + #[cfg(feature = "bevy_text")] mut font_system: ResMut, ) { ui_surface.upsert_node( &LayoutContext::TEST_CONTEXT, @@ -1239,11 +1249,12 @@ mod tests { &Node::default(), None, ); - ui_surface.compute_camera_layout( params.camera_entity, UVec2::new(800, 600), + #[cfg(feature = "bevy_text")] &mut computed_text_block_query, + #[cfg(feature = "bevy_text")] &mut font_system, ); } diff --git a/crates/bevy_ui/src/layout/ui_surface.rs b/crates/bevy_ui/src/layout/ui_surface.rs index 149623b81804c..ebd0a09187884 100644 --- a/crates/bevy_ui/src/layout/ui_surface.rs +++ b/crates/bevy_ui/src/layout/ui_surface.rs @@ -1,16 +1,15 @@ -use core::fmt; - -use taffy::TaffyTree; - +use crate::{layout::convert, LayoutContext, LayoutError, Node, NodeMeasure}; +use crate::{Measure, MeasureArgs}; use bevy_ecs::{ entity::{Entity, EntityHashMap}, prelude::Resource, }; use bevy_math::{UVec2, Vec2}; -use bevy_utils::default; - -use crate::{layout::convert, LayoutContext, LayoutError, Measure, MeasureArgs, Node, NodeMeasure}; +#[cfg(feature = "bevy_text")] use bevy_text::CosmicFontSystem; +use bevy_utils::default; +use core::fmt; +use taffy::TaffyTree; #[derive(Debug, Clone, PartialEq, Eq)] pub struct RootNodePair { @@ -198,8 +197,10 @@ impl UiSurface { &mut self, camera: Entity, render_target_resolution: UVec2, - buffer_query: &'a mut bevy_ecs::prelude::Query<&mut bevy_text::ComputedTextBlock>, - font_system: &'a mut CosmicFontSystem, + #[cfg(feature = "bevy_text")] buffer_query: &'a mut bevy_ecs::prelude::Query< + &mut bevy_text::ComputedTextBlock, + >, + #[cfg(feature = "bevy_text")] font_system: &'a mut CosmicFontSystem, ) { let Some(camera_root_nodes) = self.camera_roots.get(&camera) else { return; @@ -222,6 +223,7 @@ impl UiSurface { -> taffy::Size { context .map(|ctx| { + #[cfg(feature = "bevy_text")] let buffer = get_text_buffer( crate::widget::TextMeasure::needs_buffer( known_dimensions.height, @@ -236,8 +238,11 @@ impl UiSurface { height: known_dimensions.height, available_width: available_space.width, available_height: available_space.height, + #[cfg(feature = "bevy_text")] font_system, + #[cfg(feature = "bevy_text")] buffer, + _phantom: default(), }, style, ); @@ -307,6 +312,7 @@ impl UiSurface { } } +#[cfg(feature = "bevy_text")] fn get_text_buffer<'a>( needs_buffer: bool, ctx: &mut NodeMeasure, diff --git a/crates/bevy_ui/src/lib.rs b/crates/bevy_ui/src/lib.rs index 508f133b81cd9..02faffb6d8bf2 100644 --- a/crates/bevy_ui/src/lib.rs +++ b/crates/bevy_ui/src/lib.rs @@ -12,6 +12,7 @@ pub mod measurement; pub mod node_bundles; +#[cfg(feature = "bevy_render")] pub mod ui_material; pub mod update; pub mod widget; @@ -21,22 +22,29 @@ pub mod picking_backend; use bevy_derive::{Deref, DerefMut}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; +#[cfg(all(feature = "bevy_text", feature = "bevy_render"))] mod accessibility; // This module is not re-exported, but is instead made public. // This is intended to discourage accidental use of the experimental API. pub mod experimental; mod focus; mod geometry; +#[cfg(feature = "bevy_render")] mod layout; +#[cfg(feature = "bevy_render")] mod render; mod stack; mod ui_node; pub use focus::*; pub use geometry::*; +#[cfg(feature = "bevy_render")] pub use layout::*; pub use measurement::*; +#[cfg(feature = "bevy_render")] pub use render::*; +pub use stack::UiStack; +#[cfg(feature = "bevy_render")] pub use ui_material::*; pub use ui_node::*; @@ -51,18 +59,22 @@ pub mod prelude { pub use crate::render::UiDebugOptions; #[allow(deprecated)] #[doc(hidden)] + #[cfg(feature = "bevy_text")] pub use crate::widget::TextBundle; #[doc(hidden)] + #[cfg(feature = "bevy_text")] pub use crate::widget::{Text, TextUiReader, TextUiWriter}; #[doc(hidden)] + #[cfg(feature = "bevy_render")] + pub use crate::{ui_material::*, MaterialNode, UiMaterialPlugin}; + #[doc(hidden)] pub use { crate::{ geometry::*, node_bundles::*, - ui_material::*, ui_node::*, widget::{Button, ImageNode, Label}, - Interaction, MaterialNode, UiMaterialPlugin, UiScale, + Interaction, UiScale, }, // `bevy_sprite` re-exports for texture slicing bevy_sprite::{BorderRect, SliceScaleMode, SpriteImageMode, TextureSlicer}, @@ -71,13 +83,16 @@ pub mod prelude { use bevy_app::{prelude::*, Animation}; use bevy_ecs::prelude::*; -use bevy_input::InputSystem; -use bevy_render::{camera::CameraUpdateSystem, RenderApp}; use bevy_transform::TransformSystem; -use layout::ui_surface::UiSurface; use stack::ui_stack_system; -pub use stack::UiStack; -use update::{update_clipping_system, update_target_camera_system}; +use update::update_clipping_system; + +#[cfg(feature = "bevy_render")] +use { + bevy_input::InputSystem, + bevy_render::{camera::CameraUpdateSystem, RenderApp}, + update::update_target_camera_system, +}; /// The basic plugin for Bevy UI pub struct UiPlugin { @@ -139,15 +154,18 @@ impl Default for UiScale { // Marks systems that can be ambiguous with [`widget::text_system`] if the `bevy_text` feature is enabled. // See https://github.com/bevyengine/bevy/pull/11391 for more details. #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] +#[cfg(feature = "bevy_text")] struct AmbiguousWithTextSystem; #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] +#[cfg(feature = "bevy_text")] struct AmbiguousWithUpdateText2DLayout; impl Plugin for UiPlugin { fn build(&self, app: &mut App) { - app.init_resource::() - .init_resource::() + #[cfg(feature = "bevy_render")] + app.init_resource::(); + app.init_resource::() .init_resource::() .register_type::() .register_type::() @@ -157,9 +175,10 @@ impl Plugin for UiPlugin { .register_type::() .register_type::() .register_type::() - .register_type::() - .register_type::() - .register_type::() + .register_type::(); + #[cfg(feature = "bevy_render")] + app.register_type::(); + app.register_type::() .register_type::() .register_type::() .register_type::() @@ -175,49 +194,66 @@ impl Plugin for UiPlugin { .configure_sets( PostUpdate, ( + #[cfg(feature = "bevy_render")] CameraUpdateSystem, UiSystem::Prepare.before(UiSystem::Stack).after(Animation), UiSystem::Layout, UiSystem::PostLayout, ) .chain(), - ) - .add_systems( - PreUpdate, - ui_focus_system.in_set(UiSystem::Focus).after(InputSystem), ); + #[cfg(feature = "bevy_render")] + app.add_systems( + PreUpdate, + ui_focus_system.in_set(UiSystem::Focus).after(InputSystem), + ); - let ui_layout_system_config = ui_layout_system - .in_set(UiSystem::Layout) - .before(TransformSystem::TransformPropagate); - - let ui_layout_system_config = ui_layout_system_config - // Text and Text2D operate on disjoint sets of entities - .ambiguous_with(bevy_text::update_text2d_layout) - .ambiguous_with(bevy_text::detect_text_needs_rerender::); + #[cfg(feature = "bevy_render")] + { + let systems = ui_layout_system + .in_set(UiSystem::Layout) + .before(TransformSystem::TransformPropagate); + #[cfg(feature = "bevy_text")] + let systems = systems + // Text and Text2D operate on disjoint sets of entities + .ambiguous_with(bevy_text::update_text2d_layout) + .ambiguous_with(bevy_text::detect_text_needs_rerender::); + app.add_systems(PostUpdate, systems); + } + let systems = ui_stack_system + .in_set(UiSystem::Stack) + // the systems don't care about stack index + .ambiguous_with(update_clipping_system); + #[cfg(feature = "bevy_render")] + let systems = systems.ambiguous_with(ui_layout_system); + #[cfg(feature = "bevy_text")] + let systems = systems.in_set(AmbiguousWithTextSystem); + #[cfg(feature = "bevy_render")] + app.add_systems( + PostUpdate, + update_target_camera_system.in_set(UiSystem::Prepare), + ); app.add_systems( PostUpdate, ( - update_target_camera_system.in_set(UiSystem::Prepare), - ui_layout_system_config, - ui_stack_system - .in_set(UiSystem::Stack) - // the systems don't care about stack index - .ambiguous_with(update_clipping_system) - .ambiguous_with(ui_layout_system) - .in_set(AmbiguousWithTextSystem), + systems, update_clipping_system.after(TransformSystem::TransformPropagate), - // Potential conflicts: `Assets` - // They run independently since `widget::image_node_system` will only ever observe - // its own ImageNode, and `widget::text_system` & `bevy_text::update_text2d_layout` - // will never modify a pre-existing `Image` asset. - widget::update_image_content_size_system - .in_set(UiSystem::Prepare) - .in_set(AmbiguousWithTextSystem) - .in_set(AmbiguousWithUpdateText2DLayout), ), ); + + // Potential conflicts: `Assets` + // They run independently since `widget::image_node_system` will only ever observe + // its own ImageNode, and `widget::text_system` & `update_text2d_layout` + // will never modify a pre-existing `Image` asset. + let systems = widget::update_image_content_size_system.in_set(UiSystem::Prepare); + #[cfg(feature = "bevy_text")] + let systems = systems + .in_set(AmbiguousWithTextSystem) + .in_set(AmbiguousWithUpdateText2DLayout); + app.add_systems(PostUpdate, systems); + + #[cfg(feature = "bevy_text")] build_text_interop(app); #[cfg(feature = "bevy_ui_picking_backend")] @@ -232,25 +268,25 @@ impl Plugin for UiPlugin { #[cfg(feature = "bevy_ui_debug")] app.init_resource::(); + #[cfg(feature = "bevy_render")] build_ui_render(app); } - fn finish(&self, app: &mut App) { - if !self.enable_rendering { - return; + fn finish(&self, _app: &mut App) { + #[cfg(feature = "bevy_render")] + { + let Some(render_app) = _app.get_sub_app_mut(RenderApp) else { + return; + }; + render_app.init_resource::(); } - - let Some(render_app) = app.get_sub_app_mut(RenderApp) else { - return; - }; - - render_app.init_resource::(); } } +#[cfg(feature = "bevy_text")] fn build_text_interop(app: &mut App) { use crate::widget::TextNodeFlags; - use bevy_text::TextLayoutInfo; + use bevy_text::*; use widget::Text; app.register_type::() @@ -261,32 +297,36 @@ fn build_text_interop(app: &mut App) { PostUpdate, ( ( - bevy_text::detect_text_needs_rerender::, + detect_text_needs_rerender::, + #[cfg(feature = "bevy_render")] widget::measure_text_system, ) .chain() .in_set(UiSystem::Prepare) // Text and Text2d are independent. - .ambiguous_with(bevy_text::detect_text_needs_rerender::) + .ambiguous_with(detect_text_needs_rerender::) // Potential conflict: `Assets` // Since both systems will only ever insert new [`Image`] assets, // they will never observe each other's effects. - .ambiguous_with(bevy_text::update_text2d_layout) + .ambiguous_with(update_text2d_layout) // We assume Text is on disjoint UI entities to ImageNode and UiTextureAtlasImage // FIXME: Add an archetype invariant for this https://github.com/bevyengine/bevy/issues/1481. .ambiguous_with(widget::update_image_content_size_system), + #[cfg(feature = "bevy_render")] widget::text_system .in_set(UiSystem::PostLayout) - .after(bevy_text::remove_dropped_font_atlas_sets) + .after(remove_dropped_font_atlas_sets) // Text2d and bevy_ui text are entirely on separate entities - .ambiguous_with(bevy_text::detect_text_needs_rerender::) - .ambiguous_with(bevy_text::update_text2d_layout) - .ambiguous_with(bevy_text::calculate_bounds_text2d), + .ambiguous_with(detect_text_needs_rerender::) + .ambiguous_with(update_text2d_layout) + .ambiguous_with(calculate_bounds_text2d), ), ); + #[cfg(all(feature = "bevy_text", feature = "bevy_render"))] app.add_plugins(accessibility::AccessibilityPlugin); + #[cfg(feature = "bevy_render")] app.configure_sets( PostUpdate, AmbiguousWithTextSystem.ambiguous_with(widget::text_system), @@ -294,6 +334,6 @@ fn build_text_interop(app: &mut App) { app.configure_sets( PostUpdate, - AmbiguousWithUpdateText2DLayout.ambiguous_with(bevy_text::update_text2d_layout), + AmbiguousWithUpdateText2DLayout.ambiguous_with(update_text2d_layout), ); } diff --git a/crates/bevy_ui/src/measurement.rs b/crates/bevy_ui/src/measurement.rs index 029498ab8de9d..9c6101918070d 100644 --- a/crates/bevy_ui/src/measurement.rs +++ b/crates/bevy_ui/src/measurement.rs @@ -1,13 +1,14 @@ +use crate::widget::ImageMeasure; use bevy_ecs::{prelude::Component, reflect::ReflectComponent}; use bevy_math::Vec2; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_text::CosmicFontSystem; -use core::fmt::Formatter; +use core::{fmt::Formatter, marker::PhantomData}; pub use taffy::style::AvailableSpace; - -use crate::widget::ImageMeasure; - -use crate::widget::TextMeasure; +#[cfg(feature = "bevy_text")] +use { + crate::widget::TextMeasure, + bevy_text::{ComputedTextBlock, CosmicFontSystem}, +}; impl core::fmt::Debug for ContentSize { fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { @@ -20,8 +21,11 @@ pub struct MeasureArgs<'a> { pub height: Option, pub available_width: AvailableSpace, pub available_height: AvailableSpace, + #[cfg(feature = "bevy_text")] pub font_system: &'a mut CosmicFontSystem, - pub buffer: Option<&'a mut bevy_text::ComputedTextBlock>, + #[cfg(feature = "bevy_text")] + pub buffer: Option<&'a mut ComputedTextBlock>, + pub _phantom: PhantomData<&'a ()>, } /// A `Measure` is used to compute the size of a ui node @@ -38,6 +42,7 @@ pub trait Measure: Send + Sync + 'static { pub enum NodeMeasure { Fixed(FixedMeasure), + #[cfg(feature = "bevy_text")] Text(TextMeasure), Image(ImageMeasure), Custom(Box), @@ -47,7 +52,7 @@ impl Measure for NodeMeasure { fn measure(&mut self, measure_args: MeasureArgs, style: &taffy::Style) -> Vec2 { match self { NodeMeasure::Fixed(fixed) => fixed.measure(measure_args, style), - + #[cfg(feature = "bevy_text")] NodeMeasure::Text(text) => text.measure(measure_args, style), NodeMeasure::Image(image) => image.measure(measure_args, style), NodeMeasure::Custom(custom) => custom.measure(measure_args, style), diff --git a/crates/bevy_ui/src/node_bundles.rs b/crates/bevy_ui/src/node_bundles.rs index 4d318c78c46fa..e2f96440b531a 100644 --- a/crates/bevy_ui/src/node_bundles.rs +++ b/crates/bevy_ui/src/node_bundles.rs @@ -4,12 +4,17 @@ use crate::{ widget::{Button, ImageNodeSize}, BackgroundColor, BorderColor, BorderRadius, ComputedNode, ContentSize, FocusPolicy, ImageNode, - Interaction, MaterialNode, Node, ScrollPosition, UiMaterial, ZIndex, + Interaction, Node, ScrollPosition, ZIndex, }; use bevy_ecs::bundle::Bundle; -use bevy_render::view::{InheritedVisibility, ViewVisibility, Visibility}; use bevy_transform::prelude::{GlobalTransform, Transform}; +#[cfg(feature = "bevy_render")] +use { + crate::{MaterialNode, UiMaterial}, + bevy_render::view::{InheritedVisibility, ViewVisibility, Visibility}, +}; + /// The basic UI node. /// /// Contains the [`Node`] component and other components required to make a container. @@ -47,10 +52,13 @@ pub struct NodeBundle { /// To alter the position of the `NodeBundle`, use the properties of the [`Node`] component. pub global_transform: GlobalTransform, /// Describes the visibility properties of the node + #[cfg(feature = "bevy_render")] pub visibility: Visibility, /// Inherited visibility of an entity. + #[cfg(feature = "bevy_render")] pub inherited_visibility: InheritedVisibility, /// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering + #[cfg(feature = "bevy_render")] pub view_visibility: ViewVisibility, /// Indicates the depth at which the node should appear in the UI pub z_index: ZIndex, @@ -94,10 +102,13 @@ pub struct ImageBundle { /// This component is automatically updated by the [`TransformPropagate`](`bevy_transform::TransformSystem::TransformPropagate`) systems. pub global_transform: GlobalTransform, /// Describes the visibility properties of the node + #[cfg(feature = "bevy_render")] pub visibility: Visibility, /// Inherited visibility of an entity. + #[cfg(feature = "bevy_render")] pub inherited_visibility: InheritedVisibility, /// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering + #[cfg(feature = "bevy_render")] pub view_visibility: ViewVisibility, /// Indicates the depth at which the node should appear in the UI pub z_index: ZIndex, @@ -139,10 +150,13 @@ pub struct ButtonBundle { /// This component is automatically updated by the [`TransformPropagate`](`bevy_transform::TransformSystem::TransformPropagate`) systems. pub global_transform: GlobalTransform, /// Describes the visibility properties of the node + #[cfg(feature = "bevy_render")] pub visibility: Visibility, /// Inherited visibility of an entity. + #[cfg(feature = "bevy_render")] pub inherited_visibility: InheritedVisibility, /// Algorithmically-computed indication of whether an entity is visible and should be extracted for rendering + #[cfg(feature = "bevy_render")] pub view_visibility: ViewVisibility, /// Indicates the depth at which the node should appear in the UI pub z_index: ZIndex, @@ -162,8 +176,11 @@ impl Default for ButtonBundle { background_color: Default::default(), transform: Default::default(), global_transform: Default::default(), + #[cfg(feature = "bevy_render")] visibility: Default::default(), + #[cfg(feature = "bevy_render")] inherited_visibility: Default::default(), + #[cfg(feature = "bevy_render")] view_visibility: Default::default(), z_index: Default::default(), } @@ -179,6 +196,7 @@ impl Default for ButtonBundle { since = "0.15.0", note = "Use the `MaterialNode` component instead. Inserting `MaterialNode` will also insert the other components required automatically." )] +#[cfg(feature = "bevy_render")] pub struct MaterialNodeBundle { /// Describes the logical size of the node pub computed_node: ComputedNode, @@ -209,6 +227,7 @@ pub struct MaterialNodeBundle { pub z_index: ZIndex, } +#[cfg(feature = "bevy_render")] impl Default for MaterialNodeBundle { fn default() -> Self { Self { @@ -218,8 +237,11 @@ impl Default for MaterialNodeBundle { focus_policy: Default::default(), transform: Default::default(), global_transform: Default::default(), + #[cfg(feature = "bevy_render")] visibility: Default::default(), + #[cfg(feature = "bevy_render")] inherited_visibility: Default::default(), + #[cfg(feature = "bevy_render")] view_visibility: Default::default(), z_index: Default::default(), } diff --git a/crates/bevy_ui/src/picking_backend.rs b/crates/bevy_ui/src/picking_backend.rs index 279acdb880241..bc18d6b1b47b2 100644 --- a/crates/bevy_ui/src/picking_backend.rs +++ b/crates/bevy_ui/src/picking_backend.rs @@ -27,6 +27,7 @@ use crate::{focus::pick_rounded_rect, prelude::*, UiStack}; use bevy_app::prelude::*; use bevy_ecs::{prelude::*, query::QueryData}; use bevy_math::{Rect, Vec2}; +#[cfg(feature = "bevy_render")] use bevy_render::prelude::*; use bevy_transform::prelude::*; use bevy_utils::HashMap; diff --git a/crates/bevy_ui/src/render/box_shadow.rs b/crates/bevy_ui/src/render/box_shadow.rs index 40363bf386c48..74862587a5a55 100644 --- a/crates/bevy_ui/src/render/box_shadow.rs +++ b/crates/bevy_ui/src/render/box_shadow.rs @@ -9,9 +9,8 @@ use crate::{ use bevy_app::prelude::*; use bevy_asset::*; use bevy_color::{Alpha, ColorToComponents, LinearRgba}; -use bevy_ecs::prelude::*; use bevy_ecs::{ - prelude::Component, + prelude::*, storage::SparseSet, system::{ lifetimeless::{Read, SRes}, @@ -20,16 +19,14 @@ use bevy_ecs::{ }; use bevy_image::BevyDefault as _; use bevy_math::{vec2, FloatOrd, Mat4, Rect, Vec2, Vec3Swizzles, Vec4Swizzles}; -use bevy_render::sync_world::MainEntity; -use bevy_render::RenderApp; use bevy_render::{ camera::Camera, render_phase::*, render_resource::{binding_types::uniform_buffer, *}, renderer::{RenderDevice, RenderQueue}, - sync_world::{RenderEntity, TemporaryRenderEntity}, + sync_world::{MainEntity, RenderEntity, TemporaryRenderEntity}, view::*, - Extract, ExtractSchedule, Render, RenderSet, + Extract, ExtractSchedule, Render, RenderApp, RenderSet, }; use bevy_transform::prelude::GlobalTransform; use bytemuck::{Pod, Zeroable}; diff --git a/crates/bevy_ui/src/render/debug_overlay.rs b/crates/bevy_ui/src/render/debug_overlay.rs index 6ee7f14732141..8fbfc78b370fd 100644 --- a/crates/bevy_ui/src/render/debug_overlay.rs +++ b/crates/bevy_ui/src/render/debug_overlay.rs @@ -1,28 +1,20 @@ -use crate::CalculatedClip; -use crate::ComputedNode; -use crate::DefaultUiCamera; -use crate::TargetCamera; use bevy_asset::AssetId; use bevy_color::Hsla; -use bevy_ecs::entity::Entity; -use bevy_ecs::system::Commands; -use bevy_ecs::system::Query; -use bevy_ecs::system::Res; -use bevy_ecs::system::ResMut; -use bevy_ecs::system::Resource; -use bevy_math::Rect; -use bevy_math::Vec2; -use bevy_render::sync_world::RenderEntity; -use bevy_render::sync_world::TemporaryRenderEntity; -use bevy_render::view::ViewVisibility; -use bevy_render::Extract; +use bevy_ecs::{ + entity::Entity, + system::{Commands, Query, Res, ResMut, Resource}, +}; +use bevy_math::{Rect, Vec2}; +use bevy_render::{ + sync_world::{RenderEntity, TemporaryRenderEntity}, + view::ViewVisibility, + Extract, +}; use bevy_sprite::BorderRect; use bevy_transform::components::GlobalTransform; -use super::ExtractedUiItem; -use super::ExtractedUiNode; -use super::ExtractedUiNodes; -use super::NodeType; +use super::{ExtractedUiItem, ExtractedUiNode, ExtractedUiNodes, NodeType}; +use crate::{CalculatedClip, ComputedNode, DefaultUiCamera, TargetCamera}; /// Configuration for the UI debug overlay #[derive(Resource)] diff --git a/crates/bevy_ui/src/render/mod.rs b/crates/bevy_ui/src/render/mod.rs index 54795e885f629..2b08e9f230714 100644 --- a/crates/bevy_ui/src/render/mod.rs +++ b/crates/bevy_ui/src/render/mod.rs @@ -20,27 +20,22 @@ use bevy_core_pipeline::core_3d::graph::{Core3d, Node3d}; use bevy_core_pipeline::{core_2d::Camera2d, core_3d::Camera3d}; use bevy_ecs::entity::{EntityHashMap, EntityHashSet}; use bevy_ecs::prelude::*; -use bevy_image::Image; +use bevy_image::{Image, TRANSPARENT_IMAGE_HANDLE}; use bevy_math::{FloatOrd, Mat4, Rect, UVec4, Vec2, Vec3, Vec3Swizzles, Vec4Swizzles}; -use bevy_render::render_phase::ViewSortedRenderPhases; -use bevy_render::sync_world::MainEntity; -use bevy_render::texture::TRANSPARENT_IMAGE_HANDLE; use bevy_render::{ camera::Camera, render_asset::RenderAssets, render_graph::{RenderGraph, RunGraphOnViewNode}, - render_phase::{sort_phase_system, AddRenderCommand, DrawFunctions}, + render_phase::{ + sort_phase_system, AddRenderCommand, DrawFunctions, PhaseItem, PhaseItemExtraIndex, + ViewSortedRenderPhases, + }, render_resource::*, renderer::{RenderDevice, RenderQueue}, - view::{ExtractedView, ViewUniforms}, - Extract, RenderApp, RenderSet, -}; -use bevy_render::{ - render_phase::{PhaseItem, PhaseItemExtraIndex}, - sync_world::{RenderEntity, TemporaryRenderEntity}, + sync_world::{MainEntity, RenderEntity, TemporaryRenderEntity}, texture::GpuImage, - view::ViewVisibility, - ExtractSchedule, Render, + view::{ExtractedView, ViewUniforms, ViewVisibility}, + Extract, ExtractSchedule, Render, RenderApp, RenderSet, }; use bevy_sprite::TextureAtlasLayout; use bevy_sprite::{BorderRect, SpriteAssetEvents}; @@ -48,6 +43,7 @@ use bevy_sprite::{BorderRect, SpriteAssetEvents}; pub use debug_overlay::UiDebugOptions; use crate::{Display, Node}; +#[cfg(feature = "bevy_text")] use bevy_text::{ComputedTextBlock, PositionedGlyph, TextColor, TextLayoutInfo}; use bevy_transform::components::GlobalTransform; use bevy_utils::HashMap; @@ -142,6 +138,7 @@ pub fn build_ui_render(app: &mut App) { extract_uinode_background_colors.in_set(RenderUiSystem::ExtractBackgrounds), extract_uinode_images.in_set(RenderUiSystem::ExtractImages), extract_uinode_borders.in_set(RenderUiSystem::ExtractBorders), + #[cfg(feature = "bevy_text")] extract_text_sections.in_set(RenderUiSystem::ExtractText), #[cfg(feature = "bevy_ui_debug")] debug_overlay::extract_debug_overlay.in_set(RenderUiSystem::ExtractDebug), @@ -614,6 +611,7 @@ pub fn extract_default_ui_camera_view( } #[allow(clippy::too_many_arguments)] +#[cfg(feature = "bevy_text")] pub fn extract_text_sections( mut commands: Commands, mut extracted_uinodes: ResMut, diff --git a/crates/bevy_ui/src/render/render_pass.rs b/crates/bevy_ui/src/render/render_pass.rs index 1e3a9d81ba43c..3d2babd63c58c 100644 --- a/crates/bevy_ui/src/render/render_pass.rs +++ b/crates/bevy_ui/src/render/render_pass.rs @@ -7,13 +7,13 @@ use bevy_ecs::{ system::{lifetimeless::*, SystemParamItem}, }; use bevy_math::FloatOrd; -use bevy_render::sync_world::MainEntity; use bevy_render::{ camera::ExtractedCamera, render_graph::*, render_phase::*, render_resource::{CachedRenderPipelineId, RenderPassDescriptor}, renderer::*, + sync_world::MainEntity, view::*, }; use bevy_utils::tracing::error; diff --git a/crates/bevy_ui/src/render/ui_material_pipeline.rs b/crates/bevy_ui/src/render/ui_material_pipeline.rs index 481dce07d37f1..fe61dc5e48228 100644 --- a/crates/bevy_ui/src/render/ui_material_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_material_pipeline.rs @@ -13,7 +13,6 @@ use bevy_ecs::{ }; use bevy_image::BevyDefault as _; use bevy_math::{FloatOrd, Mat4, Rect, Vec2, Vec4Swizzles}; -use bevy_render::sync_world::MainEntity; use bevy_render::{ extract_component::ExtractComponentPlugin, globals::{GlobalsBuffer, GlobalsUniform}, @@ -21,7 +20,7 @@ use bevy_render::{ render_phase::*, render_resource::{binding_types::uniform_buffer, *}, renderer::{RenderDevice, RenderQueue}, - sync_world::{RenderEntity, TemporaryRenderEntity}, + sync_world::{MainEntity, RenderEntity, TemporaryRenderEntity}, view::*, Extract, ExtractSchedule, Render, RenderSet, }; diff --git a/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs b/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs index 657e4a95aef9c..a2dbf8062a17e 100644 --- a/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs +++ b/crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs @@ -11,16 +11,15 @@ use bevy_ecs::{ *, }, }; -use bevy_image::{BevyDefault, Image}; +use bevy_image::{BevyDefault as _, Image, TRANSPARENT_IMAGE_HANDLE}; use bevy_math::{FloatOrd, Mat4, Rect, Vec2, Vec4Swizzles}; -use bevy_render::sync_world::MainEntity; use bevy_render::{ render_asset::RenderAssets, render_phase::*, render_resource::{binding_types::uniform_buffer, *}, renderer::{RenderDevice, RenderQueue}, - sync_world::{RenderEntity, TemporaryRenderEntity}, - texture::{GpuImage, TRANSPARENT_IMAGE_HANDLE}, + sync_world::{MainEntity, RenderEntity, TemporaryRenderEntity}, + texture::GpuImage, view::*, Extract, ExtractSchedule, Render, RenderSet, }; diff --git a/crates/bevy_ui/src/ui_node.rs b/crates/bevy_ui/src/ui_node.rs index 392ee86d115c9..616d06fba72de 100644 --- a/crates/bevy_ui/src/ui_node.rs +++ b/crates/bevy_ui/src/ui_node.rs @@ -1,22 +1,27 @@ use crate::{FocusPolicy, UiRect, Val}; use bevy_color::Color; use bevy_derive::{Deref, DerefMut}; -use bevy_ecs::{prelude::*, system::SystemParam}; +use bevy_ecs::prelude::*; use bevy_math::{vec4, Rect, Vec2, Vec4Swizzles}; use bevy_reflect::prelude::*; -use bevy_render::{ - camera::{Camera, RenderTarget}, - view::{self, Visibility, VisibilityClass}, -}; use bevy_sprite::BorderRect; use bevy_transform::components::Transform; -use bevy_utils::warn_once; -use bevy_window::{PrimaryWindow, WindowRef}; use core::num::NonZero; use derive_more::derive::From; use smallvec::SmallVec; use thiserror::Error; +#[cfg(feature = "bevy_render")] +use { + bevy_ecs::system::SystemParam, + bevy_render::{ + camera::{Camera, RenderTarget}, + view::{self, Visibility, VisibilityClass}, + }, + bevy_utils::warn_once, + bevy_window::{PrimaryWindow, WindowRef}, +}; + /// Provides the computed size and layout properties of the node. /// /// Fields in this struct are public but should not be modified under most circumstances. @@ -327,12 +332,11 @@ impl From for ScrollPosition { FocusPolicy, ScrollPosition, Transform, - Visibility, - VisibilityClass, ZIndex )] +#[cfg_attr(feature = "bevy_render", require(Visibility, VisibilityClass))] #[reflect(Component, Default, PartialEq, Debug)] -#[component(on_add = view::add_visibility_class::)] +#[cfg_attr(feature = "bevy_render", component(on_add = view::add_visibility_class::))] #[cfg_attr( feature = "serialize", derive(serde::Serialize, serde::Deserialize), @@ -2614,8 +2618,10 @@ mod tests { /// Optional if there is only one camera in the world. Required otherwise. #[derive(Component, Clone, Debug, Reflect, Eq, PartialEq)] #[reflect(Component, Debug, PartialEq)] +#[cfg(feature = "bevy_render")] pub struct TargetCamera(pub Entity); +#[cfg(feature = "bevy_render")] impl TargetCamera { pub fn entity(&self) -> Entity { self.0 @@ -2659,12 +2665,14 @@ impl TargetCamera { pub struct IsDefaultUiCamera; #[derive(SystemParam)] +#[cfg(feature = "bevy_render")] pub struct DefaultUiCamera<'w, 's> { cameras: Query<'w, 's, (Entity, &'static Camera)>, default_cameras: Query<'w, 's, Entity, (With, With)>, primary_window: Query<'w, 's, Entity, With>, } +#[cfg(feature = "bevy_render")] impl<'w, 's> DefaultUiCamera<'w, 's> { pub fn get(&self) -> Option { self.default_cameras.get_single().ok().or_else(|| { diff --git a/crates/bevy_ui/src/update.rs b/crates/bevy_ui/src/update.rs index 9d8883d81ddbe..f1c0860153aae 100644 --- a/crates/bevy_ui/src/update.rs +++ b/crates/bevy_ui/src/update.rs @@ -2,19 +2,24 @@ use crate::{ experimental::{UiChildren, UiRootNodes}, - CalculatedClip, Display, Node, OverflowAxis, TargetCamera, + CalculatedClip, Display, Node, OverflowAxis, }; use super::ComputedNode; use bevy_ecs::{ entity::Entity, - query::{Changed, With}, system::{Commands, Query}, }; use bevy_math::Rect; use bevy_sprite::BorderRect; use bevy_transform::components::GlobalTransform; -use bevy_utils::HashSet; + +#[cfg(feature = "bevy_render")] +use { + crate::TargetCamera, + bevy_ecs::query::{Changed, With}, + bevy_utils::HashSet, +}; /// Updates clipping for all nodes pub fn update_clipping_system( @@ -134,6 +139,7 @@ fn update_clipping( } } +#[cfg(feature = "bevy_render")] pub fn update_target_camera_system( mut commands: Commands, changed_root_nodes_query: Query< @@ -180,6 +186,7 @@ pub fn update_target_camera_system( } } +#[cfg(feature = "bevy_render")] fn update_children_target_camera( entity: Entity, camera_to_set: Option<&TargetCamera>, diff --git a/crates/bevy_ui/src/widget/image.rs b/crates/bevy_ui/src/widget/image.rs index 55fb34373765f..a84d8e759ee6e 100644 --- a/crates/bevy_ui/src/widget/image.rs +++ b/crates/bevy_ui/src/widget/image.rs @@ -2,10 +2,9 @@ use crate::{ContentSize, Measure, MeasureArgs, Node, NodeMeasure, UiScale}; use bevy_asset::{Assets, Handle}; use bevy_color::Color; use bevy_ecs::prelude::*; -use bevy_image::Image; +use bevy_image::{Image, TRANSPARENT_IMAGE_HANDLE}; use bevy_math::{Rect, UVec2, Vec2}; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_render::texture::TRANSPARENT_IMAGE_HANDLE; use bevy_sprite::{TextureAtlas, TextureAtlasLayout, TextureSlicer}; use bevy_window::{PrimaryWindow, Window}; use taffy::{MaybeMath, MaybeResolve}; @@ -250,7 +249,10 @@ impl Measure for ImageMeasure { } } +#[cfg(feature = "bevy_text")] type UpdateImageFilter = (With, Without); +#[cfg(not(feature = "bevy_text"))] +type UpdateImageFilter = With; /// Updates content size of the node based on the image provided pub fn update_image_content_size_system( diff --git a/crates/bevy_ui/src/widget/mod.rs b/crates/bevy_ui/src/widget/mod.rs index 9be6a7673dbdf..f21dae546ec59 100644 --- a/crates/bevy_ui/src/widget/mod.rs +++ b/crates/bevy_ui/src/widget/mod.rs @@ -4,10 +4,12 @@ mod button; mod image; mod label; +#[cfg(feature = "bevy_text")] mod text; pub use button::*; pub use image::*; pub use label::*; +#[cfg(feature = "bevy_text")] pub use text::*; diff --git a/crates/bevy_ui/src/widget/text.rs b/crates/bevy_ui/src/widget/text.rs index 1b365c07e6aed..3ab989d107126 100644 --- a/crates/bevy_ui/src/widget/text.rs +++ b/crates/bevy_ui/src/widget/text.rs @@ -1,32 +1,33 @@ -use crate::{ - ComputedNode, ContentSize, DefaultUiCamera, FixedMeasure, Measure, MeasureArgs, Node, - NodeMeasure, TargetCamera, UiScale, -}; +use crate::{ComputedNode, ContentSize, Measure, MeasureArgs, Node}; use bevy_asset::Assets; -use bevy_color::Color; use bevy_derive::{Deref, DerefMut}; -use bevy_ecs::{ - change_detection::DetectChanges, - entity::{Entity, EntityHashMap}, - prelude::{require, Component}, - query::With, - reflect::ReflectComponent, - system::{Local, Query, Res, ResMut}, - world::{Mut, Ref}, -}; +use bevy_ecs::prelude::*; use bevy_image::Image; use bevy_math::Vec2; use bevy_reflect::{std_traits::ReflectDefault, Reflect}; -use bevy_render::camera::Camera; use bevy_sprite::TextureAtlasLayout; use bevy_text::{ - scale_value, ComputedTextBlock, CosmicFontSystem, Font, FontAtlasSets, LineBreak, SwashCache, - TextBounds, TextColor, TextError, TextFont, TextLayout, TextLayoutInfo, TextMeasureInfo, - TextPipeline, TextReader, TextRoot, TextSpanAccess, TextWriter, YAxisOrientation, + prelude::*, scale_value, ComputedTextBlock, CosmicFontSystem, FontAtlasSets, SwashCache, + TextBounds, TextLayoutInfo, TextMeasureInfo, TextPipeline, TextReader, TextRoot, + TextSpanAccess, TextWriter, YAxisOrientation, }; -use bevy_utils::{tracing::error, Entry}; use taffy::style::AvailableSpace; +#[cfg(feature = "bevy_render")] +use { + crate::{DefaultUiCamera, FixedMeasure, NodeMeasure, TargetCamera, UiScale}, + bevy_color::Color, + bevy_ecs::{ + change_detection::DetectChanges, + entity::EntityHashMap, + query::With, + system::{Local, Query, Res}, + world::Mut, + }, + bevy_render::camera::Camera, + bevy_utils::Entry, +}; + /// UI text system flags. /// /// Used internally by [`measure_text_system`] and [`text_system`] to schedule text for processing. @@ -51,7 +52,7 @@ impl Default for TextNodeFlags { /// [`TextBundle`] was removed in favor of required components. /// The core component is now [`Text`] which can contain a single text segment. /// Indexed access to segments can be done with the new [`TextUiReader`] and [`TextUiWriter`] system params. -/// Additional segments can be added through children with [`TextSpan`](bevy_text::TextSpan). +/// Additional segments can be added through children with [`TextSpan`]. /// Text configuration can be done with [`TextLayout`], [`TextFont`] and [`TextColor`], /// while node-related configuration uses [`TextNodeFlags`] component. #[deprecated( @@ -65,7 +66,7 @@ pub struct TextBundle {} /// Adding [`Text`] to an entity will pull in required components for setting up a UI text node. /// /// The string in this component is the first 'text span' in a hierarchy of text spans that are collected into -/// a [`ComputedTextBlock`]. See [`TextSpan`](bevy_text::TextSpan) for the component used by children of entities with [`Text`]. +/// a [`ComputedTextBlock`]. See [`TextSpan`] for the component used by children of entities with [`Text`]. /// /// Note that [`Transform`](bevy_transform::components::Transform) on this entity is managed automatically by the UI layout system. /// @@ -187,7 +188,7 @@ impl Measure for TextMeasure { font_system, ) } else { - error!("text measure failed, buffer is missing"); + bevy_utils::tracing::error!("text measure failed, buffer is missing"); Vec2::default() } } @@ -202,6 +203,7 @@ impl Measure for TextMeasure { #[allow(clippy::too_many_arguments)] #[inline] +#[cfg(feature = "bevy_render")] fn create_text_measure<'a>( entity: Entity, fonts: &Assets, @@ -255,6 +257,7 @@ fn create_text_measure<'a>( /// color changes. This can be expensive, particularly for large blocks of text, and the [`bypass_change_detection`](bevy_ecs::change_detection::DetectChangesMut::bypass_change_detection) /// method should be called when only changing the `Text`'s colors. #[allow(clippy::too_many_arguments)] +#[cfg(feature = "bevy_render")] pub fn measure_text_system( mut scale_factors_buffer: Local>, mut last_scale_factors: Local>,