Skip to content

Commit

Permalink
Rebased on bevyengine#5103
Browse files Browse the repository at this point in the history
  • Loading branch information
ManevilleF committed Jun 28, 2022
1 parent a133d7d commit ab4e049
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 83 deletions.
30 changes: 14 additions & 16 deletions crates/bevy_ui/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use bevy_render::{
view::{ExtractedView, ViewUniforms, Visibility},
RenderApp, RenderStage, RenderWorld,
};
use bevy_sprite::{Rect, SpriteAssetEvents, TextureAtlas};
use bevy_sprite::{Rect, SpriteAssetEvents, SpriteSheet, TextureAtlas};
use bevy_text::{DefaultTextPipeline, Text};
use bevy_transform::components::GlobalTransform;
use bevy_utils::FloatOrd;
Expand Down Expand Up @@ -183,31 +183,29 @@ pub fn extract_uinodes(
&UiColor,
&UiImage,
&Visibility,
Option<&SpriteSheet>,
Option<&CalculatedClip>,
)>,
) {
let mut extracted_uinodes = render_world.resource_mut::<ExtractedUiNodes>();
extracted_uinodes.uinodes.clear();
for (uinode, transform, color, image, visibility, clip) in uinode_query.iter() {
for (uinode, transform, color, image, visibility, sheet, clip) in uinode_query.iter() {
// Skip if the node is invisible or if its size is set to zero (e.g. when a parent is set to `Display::None`)
if !visibility.is_visible || uinode.size == Vec2::ZERO {
continue;
}

let (image, atlas_size, rect_min) = match image {
UiImage::Image(handle) => (handle.clone_weak(), None, Vec2::ZERO),
UiImage::TextureAtlas { handle, index } => {
if let Some(atlas) = texture_atlases.get(handle) {
let rect = atlas.textures.get(*index).copied().unwrap_or_else(|| {
panic!("TextureAtlas {:?} as no texture at index {}", atlas, index)
});
(atlas.texture.clone_weak(), Some(atlas.size), rect.min)
} else {
// Skip loading images
continue;
}
}
};
let image = image.0.clone_weak();
let sheet: Option<&SpriteSheet> = sheet;
let (atlas_size, rect_min) = sheet
.and_then(|s| texture_atlases.get(&s.texture_atlas).map(|a| (a, s.index)))
.and_then(|(atlas, index)| {
atlas
.textures
.get(index)
.map(|rect| (Some(atlas.size), rect.min))
})
.unwrap_or((None, Vec2::ZERO));
// Skip loading images
if !images.contains(&image) {
continue;
Expand Down
22 changes: 6 additions & 16 deletions crates/bevy_ui/src/ui_node.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::{Size, UiRect};
use bevy_asset::Handle;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{prelude::Component, reflect::ReflectComponent};
use bevy_math::Vec2;
use bevy_reflect::prelude::*;
use bevy_render::{
color::Color,
texture::{Image, DEFAULT_IMAGE_HANDLE},
};
use bevy_sprite::TextureAtlas;
use serde::{Deserialize, Serialize};
use std::ops::{Add, AddAssign};

Expand Down Expand Up @@ -368,30 +368,20 @@ impl From<Color> for UiColor {
}
}

/// The image of the node.
#[derive(Component, Clone, Debug, Reflect)]
/// The base texture of the node.
#[derive(Component, Clone, Debug, Reflect, Deref, DerefMut)]
#[reflect(Component, Default)]
pub enum UiImage {
/// Single texture
Image(Handle<Image>),
/// Texture atlas.
TextureAtlas {
/// Texture atlas handle
handle: Handle<TextureAtlas>,
/// Texture atlas index
index: usize,
},
}
pub struct UiImage(pub Handle<Image>);

impl Default for UiImage {
fn default() -> Self {
Self::Image(DEFAULT_IMAGE_HANDLE.typed())
Self(DEFAULT_IMAGE_HANDLE.typed())
}
}

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

Expand Down
30 changes: 9 additions & 21 deletions crates/bevy_ui/src/widget/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ use bevy_ecs::{
};
use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
use bevy_render::texture::Image;
use bevy_sprite::TextureAtlas;
use serde::{Deserialize, Serialize};

/// Describes how to resize the Image node
Expand All @@ -29,29 +28,18 @@ impl Default for ImageMode {
/// Updates calculated size of the node based on the image provided
pub fn image_node_system(
textures: Res<Assets<Image>>,
texture_atlases: Res<Assets<TextureAtlas>>,
mut query: Query<(&mut CalculatedSize, &UiImage), With<ImageMode>>,
) {
for (mut calculated_size, image) in query.iter_mut() {
let size = match image {
UiImage::Image(handle) => match textures.get(handle) {
None => continue,
Some(texture) => Size {
width: texture.texture_descriptor.size.width as f32,
height: texture.texture_descriptor.size.height as f32,
},
},
UiImage::TextureAtlas { handle, index } => match texture_atlases.get(handle) {
None => continue,
Some(atlas) => {
let rect = atlas.textures[*index];
Size::new(rect.width(), rect.height())
}
},
if let Some(texture) = textures.get(image) {
let size = Size {
width: texture.texture_descriptor.size.width as f32,
height: texture.texture_descriptor.size.height as f32,
};
// Update only if size has changed to avoid needless layout calculations
if size != calculated_size.size {
calculated_size.size = size;
}
};
// Update only if size has changed to avoid needless layout calculations
if size != calculated_size.size {
calculated_size.size = size;
}
}
}
8 changes: 4 additions & 4 deletions examples/games/game_menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ mod splash {
size: Size::new(Val::Px(200.0), Val::Auto),
..default()
},
image: UiImage::Image(icon),
image: UiImage(icon),
..default()
})
.insert(OnSplashScreen);
Expand Down Expand Up @@ -464,7 +464,7 @@ mod menu {
let icon = asset_server.load("textures/Game Icons/right.png");
parent.spawn_bundle(ImageBundle {
style: button_icon_style.clone(),
image: UiImage::Image(icon),
image: UiImage(icon),
..default()
});
parent.spawn_bundle(TextBundle {
Expand All @@ -487,7 +487,7 @@ mod menu {
let icon = asset_server.load("textures/Game Icons/wrench.png");
parent.spawn_bundle(ImageBundle {
style: button_icon_style.clone(),
image: UiImage::Image(icon),
image: UiImage(icon),
..default()
});
parent.spawn_bundle(TextBundle {
Expand All @@ -510,7 +510,7 @@ mod menu {
let icon = asset_server.load("textures/Game Icons/exitRight.png");
parent.spawn_bundle(ImageBundle {
style: button_icon_style,
image: UiImage::Image(icon),
image: UiImage(icon),
..default()
});
parent.spawn_bundle(TextBundle {
Expand Down
51 changes: 25 additions & 26 deletions examples/ui/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//! interaction state.

use bevy::{prelude::*, winit::WinitSettings};
use std::ops::DerefMut;

fn main() {
App::new()
Expand Down Expand Up @@ -47,22 +46,20 @@ fn button_system(

fn sheet_button_system(
mut interaction_query: Query<
(&Interaction, &mut UiImage),
(&Interaction, &mut SpriteSheet),
(Changed<Interaction>, With<Button>),
>,
) {
for (interaction, mut image) in interaction_query.iter_mut() {
if let UiImage::TextureAtlas { index, .. } = image.deref_mut() {
match *interaction {
Interaction::Clicked => {
*index = 2;
}
Interaction::Hovered => {
*index = 1;
}
Interaction::None => {
*index = 0;
}
for (interaction, mut sheet) in interaction_query.iter_mut() {
match *interaction {
Interaction::Clicked => {
sheet.index = 2;
}
Interaction::Hovered => {
sheet.index = 1;
}
Interaction::None => {
sheet.index = 0;
}
}
}
Expand Down Expand Up @@ -107,18 +104,20 @@ fn setup(
});
// Texture sheet button
let handle = asset_server.load("textures/array_texture.png");
let atlas = texture_atlases.add(TextureAtlas::from_grid(handle, Vec2::splat(250.0), 1, 4));
commands.spawn_bundle(ButtonBundle {
style: Style {
size: Size::new(Val::Px(150.0), Val::Px(65.0)),
// center button
margin: UiRect::all(Val::Auto),
let texture_atlas = texture_atlases.add(TextureAtlas::from_grid(Vec2::splat(250.0), 1, 4));
commands
.spawn_bundle(ButtonBundle {
style: Style {
size: Size::new(Val::Px(150.0), Val::Px(65.0)),
// center button
margin: UiRect::all(Val::Auto),
..default()
},
image: handle.into(),
..default()
},
image: UiImage::TextureAtlas {
handle: atlas,
})
.insert(SpriteSheet {
texture_atlas,
index: 0,
},
..default()
});
});
}

0 comments on commit ab4e049

Please sign in to comment.