1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-27 07:03:14 -04:00
Files
egui/crates/epaint/src/shape_transform.rs
Ryan Bluth 5d5f0dedcc Allow rotation of rectangles and ellipses (#7682)
<!--
Please read the "Making a PR" section of
[`CONTRIBUTING.md`](https://github.com/emilk/egui/blob/main/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!
-->

Added the ability to rotate rectangles and ellipses. Similar to the
existing text implementation

* [x ] I have followed the instructions in the PR template
2026-03-24 13:58:02 +01:00

137 lines
3.6 KiB
Rust

use std::sync::Arc;
use crate::{
CircleShape, Color32, ColorMode, CubicBezierShape, EllipseShape, Mesh, PathShape,
QuadraticBezierShape, RectShape, Shape, TextShape, color,
};
/// Remember to handle [`Color32::PLACEHOLDER`] specially!
pub fn adjust_colors(
shape: &mut Shape,
adjust_color: impl Fn(&mut Color32) + Send + Sync + Copy + 'static,
) {
#![expect(clippy::match_same_arms)]
match shape {
Shape::Noop => {}
Shape::Vec(shapes) => {
for shape in shapes {
adjust_colors(shape, adjust_color);
}
}
Shape::LineSegment { stroke, points: _ } => {
adjust_color(&mut stroke.color);
}
Shape::Path(PathShape {
points: _,
closed: _,
fill,
stroke,
})
| Shape::QuadraticBezier(QuadraticBezierShape {
points: _,
closed: _,
fill,
stroke,
})
| Shape::CubicBezier(CubicBezierShape {
points: _,
closed: _,
fill,
stroke,
}) => {
adjust_color(fill);
adjust_color_mode(&mut stroke.color, adjust_color);
}
Shape::Circle(CircleShape {
center: _,
radius: _,
fill,
stroke,
})
| Shape::Ellipse(EllipseShape {
center: _,
radius: _,
fill,
stroke,
angle: _,
})
| Shape::Rect(RectShape {
rect: _,
corner_radius: _,
fill,
stroke,
stroke_kind: _,
round_to_pixels: _,
blur_width: _,
brush: _,
angle: _,
}) => {
adjust_color(fill);
adjust_color(&mut stroke.color);
}
Shape::Text(TextShape {
pos: _,
galley,
underline,
fallback_color,
override_text_color,
opacity_factor: _,
angle: _,
}) => {
adjust_color(&mut underline.color);
adjust_color(fallback_color);
if let Some(override_text_color) = override_text_color {
adjust_color(override_text_color);
}
if !galley.is_empty() {
let galley = Arc::make_mut(galley);
for placed_row in &mut galley.rows {
let row = Arc::make_mut(&mut placed_row.row);
for vertex in &mut row.visuals.mesh.vertices {
adjust_color(&mut vertex.color);
}
}
}
}
Shape::Mesh(mesh) => {
let Mesh {
indices: _,
vertices,
texture_id: _,
} = Arc::make_mut(mesh);
for v in vertices {
adjust_color(&mut v.color);
}
}
Shape::Callback(_) => {
// Can't tint user callback code
}
}
}
fn adjust_color_mode(
color_mode: &mut ColorMode,
adjust_color: impl Fn(&mut Color32) + Send + Sync + Copy + 'static,
) {
match color_mode {
color::ColorMode::Solid(color) => adjust_color(color),
color::ColorMode::UV(callback) => {
let callback = Arc::clone(callback);
*color_mode = color::ColorMode::UV(Arc::new(Box::new(move |rect, pos| {
let mut color = callback(rect, pos);
adjust_color(&mut color);
color
})));
}
}
}