bevy/examples/window/scale_factor_override.rs
Pietro 061bee7e3c
fix: upgrade to winit v0.30 (#13366)
# Objective

- Upgrade winit to v0.30
- Fixes https://github.com/bevyengine/bevy/issues/13331

## Solution

This is a rewrite/adaptation of the new trait system described and
implemented in `winit` v0.30.

## Migration Guide

The custom UserEvent is now renamed as WakeUp, used to wake up the loop
if anything happens outside the app (a new
[custom_user_event](https://github.com/bevyengine/bevy/pull/13366/files#diff-2de8c0a8d3028d0059a3d80ae31b2bbc1cde2595ce2d317ea378fe3e0cf6ef2d)
shows this behavior.

The internal `UpdateState` has been removed and replaced internally by
the AppLifecycle. When changed, the AppLifecycle is sent as an event.

The `UpdateMode` now accepts only two values: `Continuous` and
`Reactive`, but the latter exposes 3 new properties to enable reactive
to device, user or window events. The previous `UpdateMode::Reactive` is
now equivalent to `UpdateMode::reactive()`, while
`UpdateMode::ReactiveLowPower` to `UpdateMode::reactive_low_power()`.

The `ApplicationLifecycle` has been renamed as `AppLifecycle`, and now
contains the possible values of the application state inside the event
loop:
* `Idle`: the loop has not started yet
* `Running` (previously called `Started`): the loop is running
* `WillSuspend`: the loop is going to be suspended
* `Suspended`: the loop is suspended
* `WillResume`: the loop is going to be resumed

Note: the `Resumed` state has been removed since the resumed app is just
running.

Finally, now that `winit` enables this, it extends the `WinitPlugin` to
support custom events.

## Test platforms

- [x] Windows
- [x] MacOs
- [x] Linux (x11)
- [x] Linux (Wayland)
- [x] Android
- [x] iOS
- [x] WASM/WebGPU
- [x] WASM/WebGL2

## Outstanding issues / regressions

- [ ] iOS: build failed in CI
   - blocking, but may just be flakiness
- [x] Cross-platform: when the window is maximised, changes in the scale
factor don't apply, to make them apply one has to make the window
smaller again. (Re-maximising keeps the updated scale factor)
    - non-blocking, but good to fix
- [ ] Android: it's pretty easy to quickly open and close the app and
then the music keeps playing when suspended.
    - non-blocking but worrying
- [ ]  Web: the application will hang when switching tabs
- Not new, duplicate of https://github.com/bevyengine/bevy/issues/13486
- [ ] Cross-platform?: Screenshot failure, `ERROR present_frames:
wgpu_core::present: No work has been submitted for this frame before`
taking the first screenshot, but after pressing space
    - non-blocking, but good to fix

---------

Co-authored-by: François <francois.mockers@vleue.com>
2024-06-03 13:06:48 +00:00

120 lines
3.8 KiB
Rust

//! This example illustrates how to override the window scale factor imposed by the
//! operating system.
use bevy::{prelude::*, window::WindowResolution};
#[derive(Component)]
struct CustomText;
fn main() {
App::new()
.add_plugins(DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
resolution: WindowResolution::new(500., 300.).with_scale_factor_override(1.0),
..default()
}),
..default()
}))
.add_systems(Startup, setup)
.add_systems(
Update,
(display_override, toggle_override, change_scale_factor),
)
.run();
}
fn setup(mut commands: Commands) {
// camera
commands.spawn(Camera2dBundle::default());
// root node
commands
.spawn(NodeBundle {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
justify_content: JustifyContent::SpaceBetween,
..default()
},
..default()
})
.with_children(|parent| {
// left vertical fill (border)
parent
.spawn(NodeBundle {
style: Style {
width: Val::Px(300.0),
height: Val::Percent(100.0),
border: UiRect::all(Val::Px(2.0)),
..default()
},
background_color: Color::srgb(0.65, 0.65, 0.65).into(),
..default()
})
.with_children(|parent| {
parent.spawn((
CustomText,
TextBundle::from_section(
"Example text",
TextStyle {
font_size: 30.0,
..default()
},
)
.with_style(Style {
align_self: AlignSelf::FlexEnd,
..default()
}),
));
});
});
}
/// Set the title of the window to the current override
fn display_override(
mut windows: Query<&mut Window>,
mut custom_text: Query<&mut Text, With<CustomText>>,
) {
let mut window = windows.single_mut();
let text = format!(
"Scale factor: {:.1} {}",
window.scale_factor(),
if window.resolution.scale_factor_override().is_some() {
"(overridden)"
} else {
"(default)"
}
);
window.title.clone_from(&text);
let mut custom_text = custom_text.single_mut();
custom_text.sections[0].value = text;
}
/// This system toggles scale factor overrides when enter is pressed
fn toggle_override(input: Res<ButtonInput<KeyCode>>, mut windows: Query<&mut Window>) {
let mut window = windows.single_mut();
if input.just_pressed(KeyCode::Enter) {
let scale_factor_override = window.resolution.scale_factor_override();
window
.resolution
.set_scale_factor_override(scale_factor_override.xor(Some(1.0)));
}
}
/// This system changes the scale factor override when up or down is pressed
fn change_scale_factor(input: Res<ButtonInput<KeyCode>>, mut windows: Query<&mut Window>) {
let mut window = windows.single_mut();
let scale_factor_override = window.resolution.scale_factor_override();
if input.just_pressed(KeyCode::ArrowUp) {
window
.resolution
.set_scale_factor_override(scale_factor_override.map(|n| n + 1.0));
} else if input.just_pressed(KeyCode::ArrowDown) {
window
.resolution
.set_scale_factor_override(scale_factor_override.map(|n| (n - 1.0).max(1.0)));
}
}