1
0
mirror of https://github.com/emilk/egui.git synced 2026-06-28 07:23:13 -04:00

Require a StrokeKind when painting rectangles with strokes (#5648)

This is a breaking change, requiring users to think about wether the
stroke is inside/centered/outside the rect.

When in doubt, add `egui::StrokeKind::Inside` to the function call.
This commit is contained in:
Emil Ernerfeldt
2025-01-29 15:52:49 +01:00
committed by GitHub
parent 8d2c8c203c
commit 525d435a84
35 changed files with 184 additions and 73 deletions

View File

@@ -16,10 +16,8 @@ pub struct RectShape {
/// The thickness and color of the outline.
///
/// The stroke extends _outside_ the edge of [`Self::rect`],
/// i.e. using [`crate::StrokeKind::Outside`].
///
/// This means the [`Self::visual_bounding_rect`] is `rect.size() + 2.0 * stroke.width`.
/// Whether or not the stroke is inside or outside the edge of [`Self::rect`],
/// is controlled by [`Self::stroke_kind`].
pub stroke: Stroke,
/// Is the stroke on the inside, outside, or centered on the rectangle?
@@ -62,20 +60,21 @@ fn rect_shape_size() {
}
impl RectShape {
/// The stroke extends _outside_ the [`Rect`].
/// See also [`Self::filled`] and [`Self::stroke`].
#[inline]
pub fn new(
rect: Rect,
rounding: impl Into<Rounding>,
fill_color: impl Into<Color32>,
stroke: impl Into<Stroke>,
stroke_kind: StrokeKind,
) -> Self {
Self {
rect,
rounding: rounding.into(),
fill: fill_color.into(),
stroke: stroke.into(),
stroke_kind: StrokeKind::Outside,
stroke_kind,
round_to_pixels: None,
blur_width: 0.0,
brush: Default::default(),
@@ -88,14 +87,24 @@ impl RectShape {
rounding: impl Into<Rounding>,
fill_color: impl Into<Color32>,
) -> Self {
Self::new(rect, rounding, fill_color, Stroke::NONE)
Self::new(
rect,
rounding,
fill_color,
Stroke::NONE,
StrokeKind::Outside, // doesn't matter
)
}
/// The stroke extends _outside_ the [`Rect`].
#[inline]
pub fn stroke(rect: Rect, rounding: impl Into<Rounding>, stroke: impl Into<Stroke>) -> Self {
pub fn stroke(
rect: Rect,
rounding: impl Into<Rounding>,
stroke: impl Into<Stroke>,
stroke_kind: StrokeKind,
) -> Self {
let fill = Color32::TRANSPARENT;
Self::new(rect, rounding, fill, stroke)
Self::new(rect, rounding, fill, stroke, stroke_kind)
}
/// Set if the stroke is on the inside, outside, or centered on the rectangle.
@@ -146,8 +155,12 @@ impl RectShape {
if self.fill == Color32::TRANSPARENT && self.stroke.is_empty() {
Rect::NOTHING
} else {
let Stroke { width, .. } = self.stroke; // Make sure we remember to update this if we change `stroke` to `PathStroke`
self.rect.expand(width + self.blur_width / 2.0)
let expand = match self.stroke_kind {
StrokeKind::Inside => 0.0,
StrokeKind::Middle => self.stroke.width / 2.0,
StrokeKind::Outside => self.stroke.width,
};
self.rect.expand(expand + self.blur_width / 2.0)
}
}

View File

@@ -7,7 +7,7 @@ use emath::{pos2, Align2, Pos2, Rangef, Rect, TSTransform, Vec2};
use crate::{
stroke::PathStroke,
text::{FontId, Fonts, Galley},
Color32, Mesh, Rounding, Stroke, TextureId,
Color32, Mesh, Rounding, Stroke, StrokeKind, TextureId,
};
use super::{
@@ -275,6 +275,7 @@ impl Shape {
Self::Ellipse(EllipseShape::stroke(center, radius, stroke))
}
/// See also [`Self::rect_stroke`].
#[inline]
pub fn rect_filled(
rect: Rect,
@@ -284,14 +285,15 @@ impl Shape {
Self::Rect(RectShape::filled(rect, rounding, fill_color))
}
/// The stroke extends _outside_ the [`Rect`].
/// See also [`Self::rect_filled`].
#[inline]
pub fn rect_stroke(
rect: Rect,
rounding: impl Into<Rounding>,
stroke: impl Into<Stroke>,
stroke_kind: StrokeKind,
) -> Self {
Self::Rect(RectShape::stroke(rect, rounding, stroke))
Self::Rect(RectShape::stroke(rect, rounding, stroke, stroke_kind))
}
#[allow(clippy::needless_pass_by_value)]

View File

@@ -1400,7 +1400,7 @@ impl Tessellator {
if self.options.debug_paint_text_rects {
let rect = text_shape.galley.rect.translate(text_shape.pos.to_vec2());
self.tessellate_rect(
&RectShape::stroke(rect.expand(0.5), 2.0, (0.5, Color32::GREEN)),
&RectShape::stroke(rect, 2.0, (0.5, Color32::GREEN), StrokeKind::Outside),
out,
);
}
@@ -2189,7 +2189,12 @@ impl Tessellator {
.flat_map(|clipped_primitive| {
let mut clip_rect_mesh = Mesh::default();
self.tessellate_shape(
Shape::rect_stroke(clipped_primitive.clip_rect, 0.0, stroke),
Shape::rect_stroke(
clipped_primitive.clip_rect,
0.0,
stroke,
StrokeKind::Outside,
),
&mut clip_rect_mesh,
);