mirror of
https://github.com/emilk/egui.git
synced 2026-08-31 05:40:03 -04:00
Add layer transforms, interaction in layer (#3906)
⚠️ Removes `Context::translate_layer`, replacing it with a sticky `set_transform_layer` Adds the capability to scale layers. Allows interaction with scaled and transformed widgets inside transformed layers. I've also added a demo of how to have zooming and panning in a window (see the video below). This probably closes #1811. Having a panning and zooming container would just be creating a new `Area` with a new id, and applying zooming and panning with `ctx.transform_layer`. I've run the github workflow scripts in my repository, so hopefully the formatting and `cargo cranky` is satisfied. I'm not sure if all call sites where transforms would be relevant have been handled. This might also be missing are transforming clipping rects, but I'm not sure where / how to accomplish that. In the demo, the clipping rect is transformed to match, which seems to work. https://github.com/emilk/egui/assets/70821802/77e7e743-cdfe-402f-86e3-7744b3ee7b0f --------- Co-authored-by: tweoss <fchua@puffer5.stanford.edu> Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
This commit is contained in:
@@ -356,48 +356,70 @@ impl Shape {
|
||||
}
|
||||
|
||||
/// Move the shape by this many points, in-place.
|
||||
pub fn translate(&mut self, delta: Vec2) {
|
||||
///
|
||||
/// If using a [`PaintCallback`], note that only the rect is scaled as opposed
|
||||
/// to other shapes where the stroke is also scaled.
|
||||
pub fn transform(&mut self, transform: TSTransform) {
|
||||
match self {
|
||||
Self::Noop => {}
|
||||
Self::Vec(shapes) => {
|
||||
for shape in shapes {
|
||||
shape.translate(delta);
|
||||
shape.transform(transform);
|
||||
}
|
||||
}
|
||||
Self::Circle(circle_shape) => {
|
||||
circle_shape.center += delta;
|
||||
circle_shape.center = transform * circle_shape.center;
|
||||
circle_shape.radius *= transform.scaling;
|
||||
circle_shape.stroke.width *= transform.scaling;
|
||||
}
|
||||
Self::LineSegment { points, .. } => {
|
||||
Self::LineSegment { points, stroke } => {
|
||||
for p in points {
|
||||
*p += delta;
|
||||
*p = transform * *p;
|
||||
}
|
||||
stroke.width *= transform.scaling;
|
||||
}
|
||||
Self::Path(path_shape) => {
|
||||
for p in &mut path_shape.points {
|
||||
*p += delta;
|
||||
*p = transform * *p;
|
||||
}
|
||||
path_shape.stroke.width *= transform.scaling;
|
||||
}
|
||||
Self::Rect(rect_shape) => {
|
||||
rect_shape.rect = rect_shape.rect.translate(delta);
|
||||
rect_shape.rect = transform * rect_shape.rect;
|
||||
rect_shape.stroke.width *= transform.scaling;
|
||||
}
|
||||
Self::Text(text_shape) => {
|
||||
text_shape.pos += delta;
|
||||
text_shape.pos = transform * text_shape.pos;
|
||||
|
||||
// Scale text:
|
||||
let galley = Arc::make_mut(&mut text_shape.galley);
|
||||
for row in &mut galley.rows {
|
||||
row.visuals.mesh_bounds = transform.scaling * row.visuals.mesh_bounds;
|
||||
for v in &mut row.visuals.mesh.vertices {
|
||||
v.pos = Pos2::new(transform.scaling * v.pos.x, transform.scaling * v.pos.y);
|
||||
}
|
||||
}
|
||||
|
||||
galley.mesh_bounds = transform.scaling * galley.mesh_bounds;
|
||||
galley.rect = transform.scaling * galley.rect;
|
||||
}
|
||||
Self::Mesh(mesh) => {
|
||||
mesh.translate(delta);
|
||||
mesh.transform(transform);
|
||||
}
|
||||
Self::QuadraticBezier(bezier_shape) => {
|
||||
bezier_shape.points[0] += delta;
|
||||
bezier_shape.points[1] += delta;
|
||||
bezier_shape.points[2] += delta;
|
||||
bezier_shape.points[0] = transform * bezier_shape.points[0];
|
||||
bezier_shape.points[1] = transform * bezier_shape.points[1];
|
||||
bezier_shape.points[2] = transform * bezier_shape.points[2];
|
||||
bezier_shape.stroke.width *= transform.scaling;
|
||||
}
|
||||
Self::CubicBezier(cubic_curve) => {
|
||||
for p in &mut cubic_curve.points {
|
||||
*p += delta;
|
||||
*p = transform * *p;
|
||||
}
|
||||
cubic_curve.stroke.width *= transform.scaling;
|
||||
}
|
||||
Self::Callback(shape) => {
|
||||
shape.rect = shape.rect.translate(delta);
|
||||
shape.rect = transform * shape.rect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user