bevy/examples/ui
ickshonpe 9655acebb6
Divide by UiScale when converting UI coordinates from physical to logical (#8720)
# Objective

After the UI layout is computed when the coordinates are converted back
from physical coordinates to logical coordinates the `UiScale` is
ignored. This results in a confusing situation where we have two
different systems of logical coordinates.

Example:

```rust
use bevy::prelude::*;

fn main() {
    App::new()
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, update)
        .run();
}

fn setup(mut commands: Commands, mut ui_scale: ResMut<UiScale>) {
    ui_scale.scale = 4.;

    commands.spawn(Camera2dBundle::default());
    commands.spawn(NodeBundle {
        style: Style {
            align_items: AlignItems::Center,
            justify_content: JustifyContent::Center,
            width: Val::Percent(100.),
            ..Default::default()
        },
        ..Default::default()
    })
    .with_children(|builder| {
        builder.spawn(NodeBundle {
            style: Style {
                width: Val::Px(100.),
                height: Val::Px(100.),
                ..Default::default()
            },
            background_color: Color::MAROON.into(),
            ..Default::default()
        }).with_children(|builder| {
            builder.spawn(TextBundle::from_section("", TextStyle::default());
        });
    });
}

fn update(
    mut text_query: Query<(&mut Text, &Parent)>,
    node_query: Query<Ref<Node>>,
) {
    for (mut text, parent) in text_query.iter_mut() {
        let node = node_query.get(parent.get()).unwrap();
        if node.is_changed() {
            text.sections[0].value = format!("size: {}", node.size());
        }
    }
}
```
result:

![Bevy App 30_05_2023
16_54_32](https://github.com/bevyengine/bevy/assets/27962798/a5ecbf31-0a12-4669-87df-b0c32f058732)

We asked for a 100x100 UI node but the Node's size is multiplied by the
value of `UiScale` to give a logical size of 400x400.

## Solution

Divide the output physical coordinates by `UiScale` in
`ui_layout_system` and multiply the logical viewport size by `UiScale`
when creating the projection matrix for the UI's `ExtractedView` in
`extract_default_ui_camera_view`.

---

## Changelog
* The UI layout's physical coordinates are divided by both the window
scale factor and `UiScale` when converting them back to logical
coordinates. The logical size of Ui nodes now matches the values given
to their size constraints.
* Multiply the logical viewport size by `UiScale` before creating the
projection matrix for the UI's `ExtractedView` in
`extract_default_ui_camera_view`.
* In `ui_focus_system` the cursor position returned from `Window` is
divided by `UiScale`.
* Added a scale factor parameter to `Node::physical_size` and
`Node::physical_rect`.
* The example `viewport_debug` now uses a `UiScale` of 2. to ensure that
viewport coordinates are working correctly with a non-unit `UiScale`.

## Migration Guide

Physical UI coordinates are now divided by both the `UiScale` and the
window's scale factor to compute the logical sizes and positions of UI
nodes.

This ensures that UI Node size and position values, held by the `Node`
and `GlobalTransform` components, conform to the same logical coordinate
system as the style constraints from which they are derived,
irrespective of the current `scale_factor` and `UiScale`.

---------

Co-authored-by: Carter Anderson <mcanders1@gmail.com>
2023-07-06 20:27:54 +00:00
..
borders.rs Ui Node Borders (#7795) 2023-06-14 22:43:38 +00:00
button.rs Rename Interaction::Clicked -> Interaction::Pressed (#8989) (#9027) 2023-07-05 09:25:31 +00:00
display_and_visibility.rs Rename Interaction::Clicked -> Interaction::Pressed (#8989) (#9027) 2023-07-05 09:25:31 +00:00
flex_layout.rs Flatten UI Style properties that use Size + remove Size (#8548) 2023-05-16 01:36:32 +00:00
font_atlas_debug.rs Schedule-First: the new and improved add_systems (#8079) 2023-03-18 01:45:34 +00:00
grid.rs fix example grid (#8940) 2023-06-23 21:28:11 +00:00
overflow.rs Flatten UI Style properties that use Size + remove Size (#8548) 2023-05-16 01:36:32 +00:00
overflow_debug.rs Remove outdated example code/comment (#8635) 2023-05-19 18:21:26 +00:00
relative_cursor_position.rs Flatten UI Style properties that use Size + remove Size (#8548) 2023-05-16 01:36:32 +00:00
size_constraints.rs Rename Interaction::Clicked -> Interaction::Pressed (#8989) (#9027) 2023-07-05 09:25:31 +00:00
text.rs Allow tuples and single plugins in add_plugins, deprecate add_plugin (#8097) 2023-06-21 20:51:03 +00:00
text_debug.rs Allow tuples and single plugins in add_plugins, deprecate add_plugin (#8097) 2023-06-21 20:51:03 +00:00
text_wrap_debug.rs NoWrap Text feature (#8947) 2023-06-26 16:23:00 +00:00
transparency_ui.rs Flatten UI Style properties that use Size + remove Size (#8548) 2023-05-16 01:36:32 +00:00
ui.rs Ui Node Borders (#7795) 2023-06-14 22:43:38 +00:00
ui_scaling.rs Flatten UI Style properties that use Size + remove Size (#8548) 2023-05-16 01:36:32 +00:00
ui_texture_atlas.rs UI texture atlas support (#8822) 2023-06-19 21:52:02 +00:00
viewport_debug.rs Divide by UiScale when converting UI coordinates from physical to logical (#8720) 2023-07-06 20:27:54 +00:00
window_fallthrough.rs Schedule-First: the new and improved add_systems (#8079) 2023-03-18 01:45:34 +00:00
z_index.rs Flatten UI Style properties that use Size + remove Size (#8548) 2023-05-16 01:36:32 +00:00