diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index adfde717f532..440fe522c650 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -2278,9 +2278,13 @@ impl Context { impl Context { /// Transform the graphics of the given layer. /// + /// This will also affect input. + /// /// This is a sticky setting, remembered from one frame to the next. /// /// Can be used to implement pan and zoom (see relevant demo). + /// + /// For a temporary transform, use [`Self::transform_layer_shapes`] instead. pub fn set_transform_layer(&self, layer_id: LayerId, transform: TSTransform) { self.memory_mut(|m| { if transform == TSTransform::IDENTITY { @@ -2291,6 +2295,34 @@ impl Context { }); } + /// Move all the graphics at the given layer. + /// + /// Is used to implement drag-and-drop preview. + /// + /// This only applied to the existing graphics at the layer, not to new graphics added later. + /// + /// For a persistent transform, use [`Self::set_transform_layer`] instead. + #[deprecated = "Use `transform_layer_shapes` instead"] + pub fn translate_layer(&self, layer_id: LayerId, delta: Vec2) { + if delta != Vec2::ZERO { + let transform = emath::TSTransform::from_translation(delta); + self.transform_layer_shapes(layer_id, transform); + } + } + + /// Transform all the graphics at the given layer. + /// + /// Is used to implement drag-and-drop preview. + /// + /// This only applied to the existing graphics at the layer, not to new graphics added later. + /// + /// For a persistent transform, use [`Self::set_transform_layer`] instead. + pub fn transform_layer_shapes(&self, layer_id: LayerId, transform: TSTransform) { + if transform != TSTransform::IDENTITY { + self.graphics_mut(|g| g.entry(layer_id).transform(transform)); + } + } + /// Top-most layer at the given position. pub fn layer_id_at(&self, pos: Pos2) -> Option { self.memory(|mem| { diff --git a/crates/egui/src/layers.rs b/crates/egui/src/layers.rs index 2c97017106f6..b9b1fb5a5c38 100644 --- a/crates/egui/src/layers.rs +++ b/crates/egui/src/layers.rs @@ -227,8 +227,17 @@ impl GraphicLayers { } // Also draw areas that are missing in `area_order`: - for shapes in order_map.values_mut() { - all_shapes.append(&mut shapes.0); + for (id, list) in order_map { + let layer_id = LayerId::new(order, *id); + + if let Some(transform) = transforms.get(&layer_id) { + for clipped_shape in &mut list.0 { + clipped_shape.clip_rect = *transform * clipped_shape.clip_rect; + clipped_shape.shape.transform(*transform); + } + } + + all_shapes.append(&mut list.0); } } diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index c5244900c886..4c5184e39f8d 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -2177,7 +2177,7 @@ impl Ui { if let Some(pointer_pos) = self.ctx().pointer_interact_pos() { let delta = pointer_pos - response.rect.center(); self.ctx() - .set_transform_layer(layer_id, emath::TSTransform::from_translation(delta)); + .transform_layer_shapes(layer_id, emath::TSTransform::from_translation(delta)); } InnerResponse::new(inner, response)