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

[Merged by Bors] - Flip UI image #6292

Closed
wants to merge 11 commits into from
23 changes: 17 additions & 6 deletions crates/bevy_ui/src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ pub struct ExtractedUiNode {
pub image: Handle<Image>,
pub atlas_size: Option<Vec2>,
pub clip: Option<Rect>,
pub flip_x: bool,
pub flip_y: bool,
pub scale_factor: f32,
}

Expand Down Expand Up @@ -225,13 +227,11 @@ pub fn extract_uinodes(
if !visibility.is_visible() {
continue;
}

let image = if let Some(image) = maybe_image {
image.0.clone_weak()
let (image, flip_x, flip_y) = if let Some(image) = maybe_image {
(image.texture.clone_weak(), image.flip_x, image.flip_y)
} else {
DEFAULT_IMAGE_HANDLE.typed().clone_weak()
(DEFAULT_IMAGE_HANDLE.typed().clone_weak(), false, false)
};

// Skip loading images
if !images.contains(&image) {
continue;
Expand All @@ -252,6 +252,8 @@ pub fn extract_uinodes(
image,
atlas_size: None,
clip: clip.map(|clip| clip.clip),
flip_x,
flip_y,
scale_factor,
});
}
Expand Down Expand Up @@ -378,6 +380,8 @@ pub fn extract_text_uinodes(
image: texture,
atlas_size,
clip: clip.map(|clip| clip.clip),
flip_x: false,
flip_y: false,
scale_factor,
});
}
Expand Down Expand Up @@ -512,7 +516,7 @@ pub fn prepare_uinodes(
}

let atlas_extent = extracted_uinode.atlas_size.unwrap_or(uinode_rect.max);
let uvs = [
let mut uvs = [
Vec2::new(
uinode_rect.min.x + positions_diff[0].x * extracted_uinode.scale_factor,
uinode_rect.min.y + positions_diff[0].y * extracted_uinode.scale_factor,
Expand All @@ -532,6 +536,13 @@ pub fn prepare_uinodes(
]
.map(|pos| pos / atlas_extent);

if extracted_uinode.flip_x {
uvs = [uvs[1], uvs[0], uvs[3], uvs[2]];
}
if extracted_uinode.flip_y {
uvs = [uvs[3], uvs[2], uvs[1], uvs[0]];
}

for i in QUAD_INDICES {
ui_meta.vertices.push(UiVertex {
position: positions_clipped[i].into(),
Expand Down
33 changes: 26 additions & 7 deletions crates/bevy_ui/src/ui_node.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{Size, UiRect};
use bevy_asset::Handle;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{prelude::Component, reflect::ReflectComponent};
use bevy_math::{Rect, Vec2};
use bevy_reflect::prelude::*;
Expand Down Expand Up @@ -455,19 +454,39 @@ impl From<Color> for BackgroundColor {
}

/// The 2D texture displayed for this UI node
#[derive(Component, Clone, Debug, Reflect, Deref, DerefMut)]
#[derive(Component, Clone, Debug, Reflect)]
#[reflect(Component, Default)]
pub struct UiImage(pub Handle<Image>);
pub struct UiImage {
/// Handle to the texture
pub texture: Handle<Image>,
/// 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,
}

impl Default for UiImage {
fn default() -> Self {
Self(DEFAULT_IMAGE_HANDLE.typed())
fn default() -> UiImage {
UiImage {
texture: DEFAULT_IMAGE_HANDLE.typed(),
flip_x: false,
flip_y: false,
}
}
}

impl UiImage {
pub fn new(texture: Handle<Image>) -> Self {
Self {
texture,
..Default::default()
}
}
}

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

Expand Down
2 changes: 1 addition & 1 deletion crates/bevy_ui/src/widget/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub fn image_node_system(
mut query: Query<(&mut CalculatedSize, &UiImage), (With<ImageMode>, Without<Text>)>,
) {
for (mut calculated_size, image) in &mut query {
if let Some(texture) = textures.get(image) {
if let Some(texture) = textures.get(&image.texture) {
let size = Size {
width: Val::Px(texture.texture_descriptor.size.width as f32),
height: Val::Px(texture.texture_descriptor.size.height as f32),
Expand Down
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(icon),
image: UiImage::new(icon),
..default()
},
OnSplashScreen,
Expand Down Expand Up @@ -462,7 +462,7 @@ mod menu {
let icon = asset_server.load("textures/Game Icons/right.png");
parent.spawn(ImageBundle {
style: button_icon_style.clone(),
image: UiImage(icon),
image: UiImage::new(icon),
..default()
});
parent.spawn(TextBundle::from_section(
Expand All @@ -483,7 +483,7 @@ mod menu {
let icon = asset_server.load("textures/Game Icons/wrench.png");
parent.spawn(ImageBundle {
style: button_icon_style.clone(),
image: UiImage(icon),
image: UiImage::new(icon),
..default()
});
parent.spawn(TextBundle::from_section(
Expand All @@ -504,7 +504,7 @@ mod menu {
let icon = asset_server.load("textures/Game Icons/exitRight.png");
parent.spawn(ImageBundle {
style: button_icon_style,
image: UiImage(icon),
image: UiImage::new(icon),
..default()
});
parent.spawn(TextBundle::from_section("Quit", button_text_style));
Expand Down