Skip to content
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

Move UiImage from ui_node to the widget::image module #16084

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/bevy_ui/src/accessibility.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::{
experimental::UiChildren,
prelude::{Button, Label},
widget::TextUiReader,
ComputedNode, UiImage,
widget::{TextUiReader, UiImage},
ComputedNode,
};
use bevy_a11y::{
accesskit::{NodeBuilder, Rect, Role},
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_ui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub use measurement::*;
pub use render::*;
pub use ui_material::*;
pub use ui_node::*;
use widget::UiImageSize;
use widget::{UiImage, UiImageSize};

/// The UI prelude.
///
Expand All @@ -58,7 +58,7 @@ pub mod prelude {
node_bundles::*,
ui_material::*,
ui_node::*,
widget::{Button, Label},
widget::{Button, Label, UiImage},
Interaction, MaterialNode, UiMaterialPlugin, UiScale,
},
// `bevy_sprite` re-exports for texture slicing
Expand Down
3 changes: 2 additions & 1 deletion crates/bevy_ui/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ mod render_pass;
mod ui_material_pipeline;
pub mod ui_texture_slice_pipeline;

use crate::widget::UiImage;
use crate::{
experimental::UiChildren, BackgroundColor, BorderColor, CalculatedClip, ComputedNode,
DefaultUiCamera, Outline, ResolvedBorderRadius, TargetCamera, UiAntiAlias, UiBoxShadowSamples,
UiImage, UiScale,
UiScale,
};
use bevy_app::prelude::*;
use bevy_asset::{load_internal_asset, AssetEvent, AssetId, Assets, Handle};
Expand Down
1 change: 1 addition & 0 deletions crates/bevy_ui/src/render/ui_texture_slice_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use bevy_transform::prelude::GlobalTransform;
use bevy_utils::HashMap;
use binding_types::{sampler, texture_2d};
use bytemuck::{Pod, Zeroable};
use widget::UiImage;

pub const UI_SLICER_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(11156288772117983964);

Expand Down
124 changes: 2 additions & 122 deletions crates/bevy_ui/src/ui_node.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
use crate::{widget::UiImageSize, ContentSize, FocusPolicy, UiRect, Val};
use bevy_asset::Handle;
use crate::{ContentSize, FocusPolicy, UiRect, Val};
use bevy_color::Color;
use bevy_ecs::{prelude::*, system::SystemParam};
use bevy_math::{vec4, Rect, Vec2, Vec4Swizzles};
use bevy_reflect::prelude::*;
use bevy_render::{
camera::{Camera, RenderTarget},
texture::{Image, TRANSPARENT_IMAGE_HANDLE},
view::Visibility,
};
use bevy_sprite::{BorderRect, TextureAtlas};
use bevy_sprite::BorderRect;
use bevy_transform::components::Transform;
use bevy_utils::warn_once;
use bevy_window::{PrimaryWindow, WindowRef};
Expand Down Expand Up @@ -2040,124 +2038,6 @@ impl Outline {
}
}

/// The 2D texture displayed for this UI node
#[derive(Component, Clone, Debug, Reflect)]
#[reflect(Component, Default, Debug)]
#[require(Node, UiImageSize)]
pub struct UiImage {
/// The tint color used to draw the image.
///
/// This is multiplied by the color of each pixel in the image.
/// The field value defaults to solid white, which will pass the image through unmodified.
pub color: Color,
/// Handle to the texture.
///
/// This defaults to a [`TRANSPARENT_IMAGE_HANDLE`], which points to a fully transparent 1x1 texture.
pub image: Handle<Image>,
/// The (optional) texture atlas used to render the image
pub texture_atlas: Option<TextureAtlas>,
/// Whether the image should be flipped along its x-axis
pub flip_x: bool,
/// Whether the image should be flipped along its y-axis
pub flip_y: bool,
/// An optional rectangle representing the region of the image to render, instead of rendering
/// the full image. This is an easy one-off alternative to using a [`TextureAtlas`].
///
/// When used with a [`TextureAtlas`], the rect
/// is offset by the atlas's minimal (top-left) corner position.
pub rect: Option<Rect>,
}

impl Default for UiImage {
/// A transparent 1x1 image with a solid white tint.
///
/// # Warning
///
/// This will be invisible by default.
/// To set this to a visible image, you need to set the `texture` field to a valid image handle,
/// or use [`Handle<Image>`]'s default 1x1 solid white texture (as is done in [`UiImage::solid_color`]).
fn default() -> Self {
UiImage {
// This should be white because the tint is multiplied with the image,
// so if you set an actual image with default tint you'd want its original colors
color: Color::WHITE,
texture_atlas: None,
// This texture needs to be transparent by default, to avoid covering the background color
image: TRANSPARENT_IMAGE_HANDLE,
flip_x: false,
flip_y: false,
rect: None,
}
}
}

impl UiImage {
/// Create a new [`UiImage`] with the given texture.
pub fn new(texture: Handle<Image>) -> Self {
Self {
image: texture,
color: Color::WHITE,
..Default::default()
}
}

/// Create a solid color [`UiImage`].
///
/// This is primarily useful for debugging / mocking the extents of your image.
pub fn solid_color(color: Color) -> Self {
Self {
image: Handle::default(),
color,
flip_x: false,
flip_y: false,
texture_atlas: None,
rect: None,
}
}

/// Create a [`UiImage`] from an image, with an associated texture atlas
pub fn from_atlas_image(image: Handle<Image>, atlas: TextureAtlas) -> Self {
Self {
image,
texture_atlas: Some(atlas),
..Default::default()
}
}

/// Set the color tint
#[must_use]
pub const fn with_color(mut self, color: Color) -> Self {
self.color = color;
self
}

/// Flip the image along its x-axis
#[must_use]
pub const fn with_flip_x(mut self) -> Self {
self.flip_x = true;
self
}

/// Flip the image along its y-axis
#[must_use]
pub const fn with_flip_y(mut self) -> Self {
self.flip_y = true;
self
}

#[must_use]
pub const fn with_rect(mut self, rect: Rect) -> Self {
self.rect = Some(rect);
self
}
}

impl From<Handle<Image>> for UiImage {
fn from(texture: Handle<Image>) -> Self {
Self::new(texture)
}
}

/// The calculated clip of the node
#[derive(Component, Default, Copy, Clone, Debug, Reflect)]
#[reflect(Component, Default, Debug)]
Expand Down
129 changes: 124 additions & 5 deletions crates/bevy_ui/src/widget/image.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,132 @@
use crate::{ContentSize, Measure, MeasureArgs, Node, NodeMeasure, UiImage, UiScale};
use bevy_asset::Assets;
use crate::{ContentSize, Measure, MeasureArgs, Node, NodeMeasure, UiScale};
use bevy_asset::{Assets, Handle};
use bevy_color::Color;
use bevy_ecs::prelude::*;
use bevy_math::{UVec2, Vec2};
use bevy_math::{Rect, UVec2, Vec2};
use bevy_reflect::{std_traits::ReflectDefault, Reflect};
use bevy_render::texture::Image;
use bevy_sprite::TextureAtlasLayout;
use bevy_render::texture::{Image, TRANSPARENT_IMAGE_HANDLE};
use bevy_sprite::{TextureAtlas, TextureAtlasLayout};
use bevy_window::{PrimaryWindow, Window};
use taffy::{MaybeMath, MaybeResolve};

/// The 2D texture displayed for this UI node
#[derive(Component, Clone, Debug, Reflect)]
#[reflect(Component, Default, Debug)]
#[require(Node, UiImageSize)]
pub struct UiImage {
/// The tint color used to draw the image.
///
/// This is multiplied by the color of each pixel in the image.
/// The field value defaults to solid white, which will pass the image through unmodified.
pub color: Color,
/// Handle to the texture.
///
/// This defaults to a [`TRANSPARENT_IMAGE_HANDLE`], which points to a fully transparent 1x1 texture.
pub image: Handle<Image>,
/// The (optional) texture atlas used to render the image
pub texture_atlas: Option<TextureAtlas>,
/// Whether the image should be flipped along its x-axis
pub flip_x: bool,
/// Whether the image should be flipped along its y-axis
pub flip_y: bool,
/// An optional rectangle representing the region of the image to render, instead of rendering
/// the full image. This is an easy one-off alternative to using a [`TextureAtlas`].
///
/// When used with a [`TextureAtlas`], the rect
/// is offset by the atlas's minimal (top-left) corner position.
pub rect: Option<Rect>,
}

impl Default for UiImage {
/// A transparent 1x1 image with a solid white tint.
///
/// # Warning
///
/// This will be invisible by default.
/// To set this to a visible image, you need to set the `texture` field to a valid image handle,
/// or use [`Handle<Image>`]'s default 1x1 solid white texture (as is done in [`UiImage::solid_color`]).
fn default() -> Self {
UiImage {
// This should be white because the tint is multiplied with the image,
// so if you set an actual image with default tint you'd want its original colors
color: Color::WHITE,
texture_atlas: None,
// This texture needs to be transparent by default, to avoid covering the background color
image: TRANSPARENT_IMAGE_HANDLE,
flip_x: false,
flip_y: false,
rect: None,
}
}
}

impl UiImage {
/// Create a new [`UiImage`] with the given texture.
pub fn new(texture: Handle<Image>) -> Self {
Self {
image: texture,
color: Color::WHITE,
..Default::default()
}
}

/// Create a solid color [`UiImage`].
///
/// This is primarily useful for debugging / mocking the extents of your image.
pub fn solid_color(color: Color) -> Self {
Self {
image: Handle::default(),
color,
flip_x: false,
flip_y: false,
texture_atlas: None,
rect: None,
}
}

/// Create a [`UiImage`] from an image, with an associated texture atlas
pub fn from_atlas_image(image: Handle<Image>, atlas: TextureAtlas) -> Self {
Self {
image,
texture_atlas: Some(atlas),
..Default::default()
}
}

/// Set the color tint
#[must_use]
pub const fn with_color(mut self, color: Color) -> Self {
self.color = color;
self
}

/// Flip the image along its x-axis
#[must_use]
pub const fn with_flip_x(mut self) -> Self {
self.flip_x = true;
self
}

/// Flip the image along its y-axis
#[must_use]
pub const fn with_flip_y(mut self) -> Self {
self.flip_y = true;
self
}

#[must_use]
pub const fn with_rect(mut self, rect: Rect) -> Self {
self.rect = Some(rect);
self
}
}

impl From<Handle<Image>> for UiImage {
fn from(texture: Handle<Image>) -> Self {
Self::new(texture)
}
}

/// The size of the image's texture
///
/// This component is updated automatically by [`update_image_content_size_system`]
Expand Down