1
1
use crate :: {
2
- measurement:: AvailableSpace , ContentSize , Measure , Node , UiImage , UiTextureAtlasImage ,
2
+ measurement:: AvailableSpace , ContentSize , Measure , Node , UiImage , UiScale , UiTextureAtlasImage ,
3
3
} ;
4
4
use bevy_asset:: { Assets , Handle } ;
5
+
5
6
#[ cfg( feature = "bevy_text" ) ]
6
7
use bevy_ecs:: query:: Without ;
7
8
use bevy_ecs:: {
8
9
prelude:: Component ,
9
10
query:: With ,
10
11
reflect:: ReflectComponent ,
11
- system:: { Query , Res } ,
12
+ system:: { Local , Query , Res } ,
12
13
} ;
13
14
use bevy_math:: Vec2 ;
14
15
use bevy_reflect:: { std_traits:: ReflectDefault , FromReflect , Reflect , ReflectFromReflect } ;
15
16
use bevy_render:: texture:: Image ;
16
17
use bevy_sprite:: TextureAtlas ;
17
18
#[ cfg( feature = "bevy_text" ) ]
18
19
use bevy_text:: Text ;
20
+ use bevy_window:: { PrimaryWindow , Window } ;
19
21
20
- /// The size of the image in physical pixels
22
+ /// The size of the image's texture
21
23
///
22
- /// This field is set automatically by `update_image_calculated_size_system`
24
+ /// This component is updated automatically by [`update_image_content_size_system`]
23
25
#[ derive( Component , Debug , Copy , Clone , Default , Reflect , FromReflect ) ]
24
26
#[ reflect( Component , Default , FromReflect ) ]
25
27
pub struct UiImageSize {
28
+ /// The size of the image's texture
29
+ ///
30
+ /// This field is updated automatically by [`update_image_content_size_system`]
26
31
size : Vec2 ,
27
32
}
28
33
29
34
impl UiImageSize {
35
+ /// The size of the image's texture
30
36
pub fn size ( & self ) -> Vec2 {
31
37
self . size
32
38
}
33
39
}
34
40
35
41
#[ derive( Clone ) ]
42
+ /// Used to calculate the size of UI image nodes
36
43
pub struct ImageMeasure {
37
- // target size of the image
38
- size : Vec2 ,
44
+ /// The size of the image's texture
45
+ pub size : Vec2 ,
39
46
}
40
47
41
48
impl Measure for ImageMeasure {
@@ -68,6 +75,9 @@ impl Measure for ImageMeasure {
68
75
69
76
/// Updates content size of the node based on the image provided
70
77
pub fn update_image_content_size_system (
78
+ mut previous_combined_scale_factor : Local < f64 > ,
79
+ windows : Query < & Window , With < PrimaryWindow > > ,
80
+ ui_scale : Res < UiScale > ,
71
81
textures : Res < Assets < Image > > ,
72
82
#[ cfg( feature = "bevy_text" ) ] mut query : Query <
73
83
( & mut ContentSize , & UiImage , & mut UiImageSize ) ,
@@ -78,23 +88,37 @@ pub fn update_image_content_size_system(
78
88
With < Node > ,
79
89
> ,
80
90
) {
91
+ let combined_scale_factor = windows
92
+ . get_single ( )
93
+ . map ( |window| window. resolution . scale_factor ( ) )
94
+ . unwrap_or ( 1. )
95
+ * ui_scale. scale ;
96
+
81
97
for ( mut content_size, image, mut image_size) in & mut query {
82
98
if let Some ( texture) = textures. get ( & image. texture ) {
83
99
let size = Vec2 :: new (
84
100
texture. texture_descriptor . size . width as f32 ,
85
101
texture. texture_descriptor . size . height as f32 ,
86
102
) ;
87
- // Update only if size has changed to avoid needless layout calculations
88
- if size != image_size. size {
103
+ // Update only if size or scale factor has changed to avoid needless layout calculations
104
+ if size != image_size. size || combined_scale_factor != * previous_combined_scale_factor {
89
105
image_size. size = size;
90
- content_size. set ( ImageMeasure { size } ) ;
106
+ content_size. set ( ImageMeasure {
107
+ // multiply the image size by the scale factor to get the physical size
108
+ size : size * combined_scale_factor as f32 ,
109
+ } ) ;
91
110
}
92
111
}
93
112
}
113
+
114
+ * previous_combined_scale_factor = combined_scale_factor;
94
115
}
95
116
96
117
/// Updates content size of the node based on the texture atlas sprite
97
118
pub fn update_atlas_content_size_system (
119
+ mut previous_combined_scale_factor : Local < f64 > ,
120
+ windows : Query < & Window , With < PrimaryWindow > > ,
121
+ ui_scale : Res < UiScale > ,
98
122
atlases : Res < Assets < TextureAtlas > > ,
99
123
#[ cfg( feature = "bevy_text" ) ] mut atlas_query : Query <
100
124
(
@@ -115,18 +139,25 @@ pub fn update_atlas_content_size_system(
115
139
( With < Node > , Without < UiImage > ) ,
116
140
> ,
117
141
) {
142
+ let combined_scale_factor = windows
143
+ . get_single ( )
144
+ . map ( |window| window. resolution . scale_factor ( ) )
145
+ . unwrap_or ( 1. )
146
+ * ui_scale. scale ;
147
+
118
148
for ( mut content_size, atlas, atlas_image, mut image_size) in & mut atlas_query {
119
149
if let Some ( atlas) = atlases. get ( atlas) {
120
- let texture_rect = atlas. textures [ atlas_image. index ] ;
121
- let size = Vec2 :: new (
122
- texture_rect. max . x - texture_rect. min . x ,
123
- texture_rect. max . y - texture_rect. min . y ,
124
- ) ;
125
- // Update only if size has changed to avoid needless layout calculations
126
- if size != image_size. size {
150
+ let size = atlas. textures [ atlas_image. index ] . size ( ) ;
151
+ // Update only if size or scale factor has changed to avoid needless layout calculations
152
+ if size != image_size. size || combined_scale_factor != * previous_combined_scale_factor {
127
153
image_size. size = size;
128
- content_size. set ( ImageMeasure { size } ) ;
154
+ content_size. set ( ImageMeasure {
155
+ // multiply the image size by the scale factor to get the physical size
156
+ size : size * combined_scale_factor as f32 ,
157
+ } ) ;
129
158
}
130
159
}
131
160
}
161
+
162
+ * previous_combined_scale_factor = combined_scale_factor;
132
163
}
0 commit comments