`Scene`: Set transform layer before calling user content (#5884)

This changes the `Scene` behaviour to call `set_transform_layer` prior
to calling the user content fn, rather than after.

### Motivation

This provides a simple way for the user to access the `TSTransform` that
will be applied to the `Scene` within the user content function, e.g.

```rust
ui.ctx().layer_transform_to_global(ui.layer_id())
```

Previously getting the transform like this still kind of worked, but
resulted in the user content lagging behind the actual scene position by
a single frame, which looks a bit strange.

With this PR, the user content using the transform no longer lags by a
frame, and matches the scene's transform perfectly.

Accessing the `TSTransform` of the `Scene` within the user content
function is useful for the case where the user may want to instantiate
new `Ui` sublayers that also track the scene (by default, sublayers do
*not* apply the same transform as the scene, likely the cause of #5682).
With these changes, the user can have sublayers track the scene like so:

```rust
let scene_layer = ui.layer_id();
let sub_layer = egui::LayerId::new(scene_layer.order, self.id);
ui.ctx().set_sublayer(scene_layer, sub_layer);
let scene_transform = ui.ctx().layer_transform_to_global(scene_layer).unwrap();
ui.ctx().set_transform_layer(sub_layer, scene_transform);
```

### Tested with

- `egui_demo_app` scene example.
- Local `egui_graph` demo example.

---

<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/master/CONTRIBUTING.md)
before opening a Pull Request!

* Keep your PR:s small and focused.
* The PR title is what ends up in the changelog, so make it descriptive!
* If applicable, add a screenshot or gif.
* If it is a non-trivial addition, consider adding a demo for it to
`egui_demo_lib`, or a new example.
* Do NOT open PR:s from your `master` branch, as that makes it hard for
maintainers to test and add commits to your PR.
* Remember to run `cargo fmt` and `cargo clippy`.
* Open the PR as a draft until you have self-reviewed it and run
`./scripts/check.sh`.
* When you have addressed a PR comment, mark it as resolved.

Please be patient! I will review your PR, but my time is limited!
-->

* Closes <https://github.com/emilk/egui/issues/THE_RELEVANT_ISSUE>
* [x] I have followed the instructions in the PR template
This commit is contained in:
mitchmindtree 2025-04-08 10:16:29 +01:00 committed by GitHub
parent fe631ff9ea
commit 4445497546
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 5 additions and 5 deletions

View File

@ -160,17 +160,17 @@ impl Scene {
// Set a correct global clip rect:
local_ui.set_clip_rect(to_global.inverse() * outer_rect);
// Tell egui to apply the transform on the layer:
local_ui
.ctx()
.set_transform_layer(scene_layer_id, *to_global);
// Add the actual contents to the area:
let ret = add_contents(&mut local_ui);
// This ensures we catch clicks/drags/pans anywhere on the background.
local_ui.force_set_min_rect((to_global.inverse() * outer_rect).round_ui());
// Tell egui to apply the transform on the layer:
local_ui
.ctx()
.set_transform_layer(scene_layer_id, *to_global);
InnerResponse {
response: pan_response,
inner: ret,