mirror of
https://github.com/bevyengine/bevy
synced 2024-09-20 06:22:01 +00:00
Update layout/style when scale factor changes too (#4689)
# Objective - Fix https://github.com/bevyengine/bevy/issues/4688 ## Solution - Fixes https://github.com/bevyengine/bevy/issues/4688 - This raises an interesting question about our change detection system - is filtered queries actually a good UX for this? They're ergonomic in the easy case, but what do we recommend when it's not so. - In this case, the system should have been migrated similary to https://github.com/bevyengine/bevy/pull/4180 anyway, so I've done that.
This commit is contained in:
parent
fca1c861d2
commit
33a4df8008
2 changed files with 25 additions and 32 deletions
|
@ -47,7 +47,10 @@ impl Plugin for TextPlugin {
|
|||
.register_type::<HorizontalAlign>()
|
||||
.init_asset_loader::<FontLoader>()
|
||||
.insert_resource(DefaultTextPipeline::default())
|
||||
.add_system_to_stage(CoreStage::PostUpdate, text2d_system.after(ModifiesWindows));
|
||||
.add_system_to_stage(
|
||||
CoreStage::PostUpdate,
|
||||
update_text2d_layout.after(ModifiesWindows),
|
||||
);
|
||||
|
||||
if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
|
||||
render_app.add_system_to_stage(
|
||||
|
|
|
@ -3,16 +3,18 @@ use bevy_ecs::{
|
|||
bundle::Bundle,
|
||||
component::Component,
|
||||
entity::Entity,
|
||||
query::{Changed, With},
|
||||
event::EventReader,
|
||||
query::Changed,
|
||||
reflect::ReflectComponent,
|
||||
system::{Local, ParamSet, Query, Res, ResMut},
|
||||
system::{Local, Query, Res, ResMut},
|
||||
};
|
||||
use bevy_math::{Vec2, Vec3};
|
||||
use bevy_reflect::Reflect;
|
||||
use bevy_render::{texture::Image, view::Visibility, RenderWorld};
|
||||
use bevy_sprite::{Anchor, ExtractedSprite, ExtractedSprites, TextureAtlas};
|
||||
use bevy_transform::prelude::{GlobalTransform, Transform};
|
||||
use bevy_window::{WindowId, Windows};
|
||||
use bevy_utils::HashSet;
|
||||
use bevy_window::{WindowId, WindowScaleFactorChanged, Windows};
|
||||
|
||||
use crate::{
|
||||
DefaultTextPipeline, Font, FontAtlasSet, HorizontalAlign, Text, TextError, VerticalAlign,
|
||||
|
@ -123,44 +125,34 @@ pub fn extract_text2d_sprite(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct QueuedText2d {
|
||||
entities: Vec<Entity>,
|
||||
}
|
||||
|
||||
/// Updates the layout and size information whenever the text or style is changed.
|
||||
/// This information is computed by the `TextPipeline` on insertion, then stored.
|
||||
#[allow(clippy::too_many_arguments, clippy::type_complexity)]
|
||||
pub fn text2d_system(
|
||||
mut queued_text: Local<QueuedText2d>,
|
||||
pub fn update_text2d_layout(
|
||||
// Text items which should be reprocessed again, generally when the font hasn't loaded yet.
|
||||
mut queue: Local<HashSet<Entity>>,
|
||||
mut textures: ResMut<Assets<Image>>,
|
||||
fonts: Res<Assets<Font>>,
|
||||
windows: Res<Windows>,
|
||||
mut scale_factor_changed: EventReader<WindowScaleFactorChanged>,
|
||||
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
|
||||
mut font_atlas_set_storage: ResMut<Assets<FontAtlasSet>>,
|
||||
mut text_pipeline: ResMut<DefaultTextPipeline>,
|
||||
mut text_queries: ParamSet<(
|
||||
Query<Entity, (With<Text2dSize>, Changed<Text>)>,
|
||||
Query<(&Text, Option<&Text2dBounds>, &mut Text2dSize), With<Text2dSize>>,
|
||||
mut text_query: Query<(
|
||||
Entity,
|
||||
Changed<Text>,
|
||||
&Text,
|
||||
Option<&Text2dBounds>,
|
||||
&mut Text2dSize,
|
||||
)>,
|
||||
) {
|
||||
// Adds all entities where the text or the style has changed to the local queue
|
||||
for entity in text_queries.p0().iter_mut() {
|
||||
queued_text.entities.push(entity);
|
||||
}
|
||||
|
||||
if queued_text.entities.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
// We need to consume the entire iterator, hence `last`
|
||||
let factor_changed = scale_factor_changed.iter().last().is_some();
|
||||
let scale_factor = windows.scale_factor(WindowId::primary());
|
||||
|
||||
// Computes all text in the local queue
|
||||
let mut new_queue = Vec::new();
|
||||
let mut query = text_queries.p1();
|
||||
for entity in queued_text.entities.drain(..) {
|
||||
if let Ok((text, bounds, mut calculated_size)) = query.get_mut(entity) {
|
||||
let text_bounds = match bounds {
|
||||
for (entity, text_changed, text, maybe_bounds, mut calculated_size) in text_query.iter_mut() {
|
||||
if factor_changed || text_changed || queue.remove(&entity) {
|
||||
let text_bounds = match maybe_bounds {
|
||||
Some(bounds) => Vec2::new(
|
||||
scale_value(bounds.size.x, scale_factor),
|
||||
scale_value(bounds.size.y, scale_factor),
|
||||
|
@ -181,7 +173,7 @@ pub fn text2d_system(
|
|||
Err(TextError::NoSuchFont) => {
|
||||
// There was an error processing the text layout, let's add this entity to the
|
||||
// queue for further processing
|
||||
new_queue.push(entity);
|
||||
queue.insert(entity);
|
||||
}
|
||||
Err(e @ TextError::FailedToAddGlyph(_)) => {
|
||||
panic!("Fatal error when processing text: {}.", e);
|
||||
|
@ -198,8 +190,6 @@ pub fn text2d_system(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
queued_text.entities = new_queue;
|
||||
}
|
||||
|
||||
pub fn scale_value(value: f32, factor: f64) -> f32 {
|
||||
|
|
Loading…
Reference in a new issue