From 4445497546266f2499d63dba0c0e037c49c5af68 Mon Sep 17 00:00:00 2001 From: mitchmindtree Date: Tue, 8 Apr 2025 10:16:29 +0100 Subject: [PATCH] `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. --- * Closes * [x] I have followed the instructions in the PR template --- crates/egui/src/containers/scene.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/egui/src/containers/scene.rs b/crates/egui/src/containers/scene.rs index fff4136f..5b8d9741 100644 --- a/crates/egui/src/containers/scene.rs +++ b/crates/egui/src/containers/scene.rs @@ -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,