Add support for dashed lines with offset (#3720)
<!-- 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. * 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 add commits to your PR. * Remember to run `cargo fmt` and `cargo cranky`. * 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/3677>. This can naturally be obtained by starting the drawing a bit "later", but providing support for this directly will simplify interleaved drawing of dashed lines. An even more general approach would be to allow passing an even-length vector of lengths and gaps, in addition to offset. Primarily thinking if it is better to go even further if a new dashed-line-method is introduced. The second commit introduce this (I can naturally squash these!).
This commit is contained in:
parent
76025f2c15
commit
fc18d6f8f4
|
|
@ -144,12 +144,39 @@ impl Shape {
|
||||||
gap_length: f32,
|
gap_length: f32,
|
||||||
) -> Vec<Self> {
|
) -> Vec<Self> {
|
||||||
let mut shapes = Vec::new();
|
let mut shapes = Vec::new();
|
||||||
dashes_from_line(path, stroke.into(), dash_length, gap_length, &mut shapes);
|
dashes_from_line(
|
||||||
|
path,
|
||||||
|
stroke.into(),
|
||||||
|
&[dash_length],
|
||||||
|
&[gap_length],
|
||||||
|
&mut shapes,
|
||||||
|
0.,
|
||||||
|
);
|
||||||
|
shapes
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turn a line into dashes with different dash/gap lengths and a start offset.
|
||||||
|
pub fn dashed_line_with_offset(
|
||||||
|
path: &[Pos2],
|
||||||
|
stroke: impl Into<Stroke>,
|
||||||
|
dash_lengths: &[f32],
|
||||||
|
gap_lengths: &[f32],
|
||||||
|
dash_offset: f32,
|
||||||
|
) -> Vec<Self> {
|
||||||
|
let mut shapes = Vec::new();
|
||||||
|
dashes_from_line(
|
||||||
|
path,
|
||||||
|
stroke.into(),
|
||||||
|
dash_lengths,
|
||||||
|
gap_lengths,
|
||||||
|
&mut shapes,
|
||||||
|
dash_offset,
|
||||||
|
);
|
||||||
shapes
|
shapes
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn a line into dashes. If you need to create many dashed lines use this instead of
|
/// Turn a line into dashes. If you need to create many dashed lines use this instead of
|
||||||
/// [`Self::dashed_line`]
|
/// [`Self::dashed_line`].
|
||||||
pub fn dashed_line_many(
|
pub fn dashed_line_many(
|
||||||
points: &[Pos2],
|
points: &[Pos2],
|
||||||
stroke: impl Into<Stroke>,
|
stroke: impl Into<Stroke>,
|
||||||
|
|
@ -157,7 +184,34 @@ impl Shape {
|
||||||
gap_length: f32,
|
gap_length: f32,
|
||||||
shapes: &mut Vec<Shape>,
|
shapes: &mut Vec<Shape>,
|
||||||
) {
|
) {
|
||||||
dashes_from_line(points, stroke.into(), dash_length, gap_length, shapes);
|
dashes_from_line(
|
||||||
|
points,
|
||||||
|
stroke.into(),
|
||||||
|
&[dash_length],
|
||||||
|
&[gap_length],
|
||||||
|
shapes,
|
||||||
|
0.,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Turn a line into dashes with different dash/gap lengths and a start offset. If you need to
|
||||||
|
/// create many dashed lines use this instead of [`Self::dashed_line_with_offset`].
|
||||||
|
pub fn dashed_line_many_with_offset(
|
||||||
|
points: &[Pos2],
|
||||||
|
stroke: impl Into<Stroke>,
|
||||||
|
dash_lengths: &[f32],
|
||||||
|
gap_lengths: &[f32],
|
||||||
|
dash_offset: f32,
|
||||||
|
shapes: &mut Vec<Shape>,
|
||||||
|
) {
|
||||||
|
dashes_from_line(
|
||||||
|
points,
|
||||||
|
stroke.into(),
|
||||||
|
dash_lengths,
|
||||||
|
gap_lengths,
|
||||||
|
shapes,
|
||||||
|
dash_offset,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A convex polygon with a fill and optional stroke.
|
/// A convex polygon with a fill and optional stroke.
|
||||||
|
|
@ -775,12 +829,16 @@ fn points_from_line(
|
||||||
fn dashes_from_line(
|
fn dashes_from_line(
|
||||||
path: &[Pos2],
|
path: &[Pos2],
|
||||||
stroke: Stroke,
|
stroke: Stroke,
|
||||||
dash_length: f32,
|
dash_lengths: &[f32],
|
||||||
gap_length: f32,
|
gap_lengths: &[f32],
|
||||||
shapes: &mut Vec<Shape>,
|
shapes: &mut Vec<Shape>,
|
||||||
|
dash_offset: f32,
|
||||||
) {
|
) {
|
||||||
let mut position_on_segment = 0.0;
|
assert_eq!(dash_lengths.len(), gap_lengths.len());
|
||||||
|
let mut position_on_segment = dash_offset;
|
||||||
let mut drawing_dash = false;
|
let mut drawing_dash = false;
|
||||||
|
let mut step = 0;
|
||||||
|
let steps = dash_lengths.len();
|
||||||
path.windows(2).for_each(|window| {
|
path.windows(2).for_each(|window| {
|
||||||
let (start, end) = (window[0], window[1]);
|
let (start, end) = (window[0], window[1]);
|
||||||
let vector = end - start;
|
let vector = end - start;
|
||||||
|
|
@ -792,11 +850,16 @@ fn dashes_from_line(
|
||||||
if drawing_dash {
|
if drawing_dash {
|
||||||
// This is the end point.
|
// This is the end point.
|
||||||
shapes.push(Shape::line_segment([start_point, new_point], stroke));
|
shapes.push(Shape::line_segment([start_point, new_point], stroke));
|
||||||
position_on_segment += gap_length;
|
position_on_segment += gap_lengths[step];
|
||||||
|
// Increment step counter
|
||||||
|
step += 1;
|
||||||
|
if step >= steps {
|
||||||
|
step = 0;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Start a new dash.
|
// Start a new dash.
|
||||||
start_point = new_point;
|
start_point = new_point;
|
||||||
position_on_segment += dash_length;
|
position_on_segment += dash_lengths[step];
|
||||||
}
|
}
|
||||||
drawing_dash = !drawing_dash;
|
drawing_dash = !drawing_dash;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue