diff --git a/crates/egui/src/containers/collapsing_header.rs b/crates/egui/src/containers/collapsing_header.rs index c5fa812d897..4ac57d36d03 100644 --- a/crates/egui/src/containers/collapsing_header.rs +++ b/crates/egui/src/containers/collapsing_header.rs @@ -5,7 +5,7 @@ use crate::{ Response, Sense, Stroke, TextStyle, TextWrapMode, Ui, Vec2, WidgetInfo, WidgetText, WidgetType, }; use emath::GuiRounding as _; -use epaint::Shape; +use epaint::{Shape, StrokeKind}; #[derive(Clone, Copy, Debug)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] @@ -576,6 +576,7 @@ impl CollapsingHeader { visuals.rounding, visuals.weak_bg_fill, visuals.bg_stroke, + StrokeKind::Inside, )); } @@ -583,8 +584,13 @@ impl CollapsingHeader { { let rect = rect.expand(visuals.expansion); - ui.painter() - .rect(rect, visuals.rounding, visuals.bg_fill, visuals.bg_stroke); + ui.painter().rect( + rect, + visuals.rounding, + visuals.bg_fill, + visuals.bg_stroke, + StrokeKind::Inside, + ); } { diff --git a/crates/egui/src/containers/combo_box.rs b/crates/egui/src/containers/combo_box.rs index 55157294b79..d6a71c2e415 100644 --- a/crates/egui/src/containers/combo_box.rs +++ b/crates/egui/src/containers/combo_box.rs @@ -474,6 +474,7 @@ fn button_frame( visuals.rounding, visuals.weak_bg_fill, visuals.bg_stroke, + epaint::StrokeKind::Inside, ), ); } diff --git a/crates/egui/src/containers/frame.rs b/crates/egui/src/containers/frame.rs index b1bf5611907..abe1b8afe94 100644 --- a/crates/egui/src/containers/frame.rs +++ b/crates/egui/src/containers/frame.rs @@ -423,10 +423,13 @@ impl Frame { let fill_rect = self.fill_rect(content_rect); let widget_rect = self.widget_rect(content_rect); - let frame_shape = Shape::Rect( - epaint::RectShape::new(fill_rect, rounding, fill, stroke) - .with_stroke_kind(epaint::StrokeKind::Outside), - ); + let frame_shape = Shape::Rect(epaint::RectShape::new( + fill_rect, + rounding, + fill, + stroke, + epaint::StrokeKind::Outside, + )); if shadow == Default::default() { frame_shape diff --git a/crates/egui/src/containers/resize.rs b/crates/egui/src/containers/resize.rs index bbb86dfbf36..0df9a113607 100644 --- a/crates/egui/src/containers/resize.rs +++ b/crates/egui/src/containers/resize.rs @@ -356,6 +356,7 @@ impl Resize { rect, 3.0, ui.visuals().widgets.noninteractive.bg_stroke, + epaint::StrokeKind::Inside, )); } diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index e0459485d18..ea36040cbb8 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -11,7 +11,7 @@ use epaint::{ tessellator, text::{FontInsert, FontPriority, Fonts}, util::OrderedFloat, - vec2, ClippedPrimitive, ClippedShape, Color32, ImageData, ImageDelta, Pos2, Rect, + vec2, ClippedPrimitive, ClippedShape, Color32, ImageData, ImageDelta, Pos2, Rect, StrokeKind, TessellationOptions, TextureAtlas, TextureId, Vec2, }; @@ -1087,7 +1087,7 @@ impl Context { let text = format!("🔥 {text}"); let color = self.style().visuals.error_fg_color; let painter = self.debug_painter(); - painter.rect_stroke(widget_rect, 0.0, (1.0, color)); + painter.rect_stroke(widget_rect, 0.0, (1.0, color), StrokeKind::Outside); let below = widget_rect.bottom() + 32.0 < screen_rect.bottom(); diff --git a/crates/egui/src/grid.rs b/crates/egui/src/grid.rs index 102027dd8e4..1e341432caf 100644 --- a/crates/egui/src/grid.rs +++ b/crates/egui/src/grid.rs @@ -208,7 +208,12 @@ impl GridLayout { if (debug_expand_width && too_wide) || (debug_expand_height && too_high) { let painter = self.ctx.debug_painter(); - painter.rect_stroke(rect, 0.0, (1.0, Color32::LIGHT_BLUE)); + painter.rect_stroke( + rect, + 0.0, + (1.0, Color32::LIGHT_BLUE), + crate::StrokeKind::Inside, + ); let stroke = Stroke::new(2.5, Color32::from_rgb(200, 0, 0)); let paint_line_seg = |a, b| painter.line_segment([a, b], stroke); diff --git a/crates/egui/src/lib.rs b/crates/egui/src/lib.rs index ccd48e860d3..15f4faf3c36 100644 --- a/crates/egui/src/lib.rs +++ b/crates/egui/src/lib.rs @@ -465,7 +465,7 @@ pub use epaint::{ text::{FontData, FontDefinitions, FontFamily, FontId, FontTweak}, textures::{TextureFilter, TextureOptions, TextureWrapMode, TexturesDelta}, ClippedPrimitive, ColorImage, FontImage, ImageData, Margin, Mesh, PaintCallback, - PaintCallbackInfo, Rounding, Shadow, Shape, Stroke, TextureHandle, TextureId, + PaintCallbackInfo, Rounding, Shadow, Shape, Stroke, StrokeKind, TextureHandle, TextureId, }; pub mod text { diff --git a/crates/egui/src/painter.rs b/crates/egui/src/painter.rs index e30a148d979..4ed74cddba0 100644 --- a/crates/egui/src/painter.rs +++ b/crates/egui/src/painter.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use emath::GuiRounding as _; use epaint::{ text::{Fonts, Galley, LayoutJob}, - CircleShape, ClippedShape, PathStroke, RectShape, Rounding, Shape, Stroke, + CircleShape, ClippedShape, PathStroke, RectShape, Rounding, Shape, Stroke, StrokeKind, }; use crate::{ @@ -301,6 +301,7 @@ impl Painter { 0.0, color.additive().linear_multiply(0.015), (1.0, color), + StrokeKind::Outside, ); self.text( rect.min, @@ -407,15 +408,22 @@ impl Painter { }) } - /// The stroke extends _outside_ the [`Rect`]. + /// See also [`Self::rect_filled`] and [`Self::rect_stroke`]. pub fn rect( &self, rect: Rect, rounding: impl Into, fill_color: impl Into, stroke: impl Into, + stroke_kind: StrokeKind, ) -> ShapeIdx { - self.add(RectShape::new(rect, rounding, fill_color, stroke)) + self.add(RectShape::new( + rect, + rounding, + fill_color, + stroke, + stroke_kind, + )) } pub fn rect_filled( @@ -433,8 +441,9 @@ impl Painter { rect: Rect, rounding: impl Into, stroke: impl Into, + stroke_kind: StrokeKind, ) -> ShapeIdx { - self.add(RectShape::stroke(rect, rounding, stroke)) + self.add(RectShape::stroke(rect, rounding, stroke, stroke_kind)) } /// Show an arrow starting at `origin` and going in the direction of `vec`, with the length `vec.length()`. diff --git a/crates/egui/src/pass_state.rs b/crates/egui/src/pass_state.rs index 1cca5becc9c..942001c7349 100644 --- a/crates/egui/src/pass_state.rs +++ b/crates/egui/src/pass_state.rs @@ -121,7 +121,13 @@ impl DebugRect { Color32::LIGHT_BLUE }; let rect_bg_color = Color32::BLUE.gamma_multiply(0.5); - painter.rect(rect, 0.0, rect_bg_color, (1.0, rect_fg_color)); + painter.rect( + rect, + 0.0, + rect_bg_color, + (1.0, rect_fg_color), + crate::StrokeKind::Outside, + ); } if !callstack.is_empty() { @@ -157,7 +163,13 @@ impl DebugRect { text_bg_color }; let text_rect = Rect::from_min_size(text_pos, galley.size()); - painter.rect(text_rect, 0.0, text_bg_color, (1.0, text_rect_stroke_color)); + painter.rect( + text_rect, + 0.0, + text_bg_color, + (1.0, text_rect_stroke_color), + crate::StrokeKind::Middle, + ); painter.galley(text_pos, galley, text_color); if is_clicking { diff --git a/crates/egui/src/placer.rs b/crates/egui/src/placer.rs index 3490eef1064..2de822c0315 100644 --- a/crates/egui/src/placer.rs +++ b/crates/egui/src/placer.rs @@ -281,7 +281,7 @@ impl Placer { if let Some(grid) = &self.grid { let rect = grid.next_cell(self.cursor(), Vec2::splat(0.0)); - painter.rect_stroke(rect, 1.0, stroke); + painter.rect_stroke(rect, 1.0, stroke, epaint::StrokeKind::Inside); let align = Align2::CENTER_CENTER; painter.debug_text(align.pos_in_rect(&rect), align, stroke.color, text); } else { diff --git a/crates/egui/src/ui.rs b/crates/egui/src/ui.rs index 879177139bc..1fdfccdc6d9 100644 --- a/crates/egui/src/ui.rs +++ b/crates/egui/src/ui.rs @@ -1186,7 +1186,7 @@ impl Ui { /// # egui::__run_test_ui(|ui| { /// let response = ui.allocate_response(egui::vec2(100.0, 200.0), egui::Sense::click()); /// if response.clicked() { /* … */ } - /// ui.painter().rect_stroke(response.rect, 0.0, (1.0, egui::Color32::WHITE)); + /// ui.painter().rect_stroke(response.rect, 0.0, (1.0, egui::Color32::WHITE), egui::StrokeKind::Inside); /// # }); /// ``` pub fn allocate_response(&mut self, desired_size: Vec2, sense: Sense) -> Response { @@ -1253,8 +1253,12 @@ impl Ui { let debug_expand_height = self.style().debug.show_expand_height; if (debug_expand_width && too_wide) || (debug_expand_height && too_high) { - self.painter - .rect_stroke(rect, 0.0, (1.0, Color32::LIGHT_BLUE)); + self.painter.rect_stroke( + rect, + 0.0, + (1.0, Color32::LIGHT_BLUE), + crate::StrokeKind::Inside, + ); let stroke = Stroke::new(2.5, Color32::from_rgb(200, 0, 0)); let paint_line_seg = |a, b| self.painter().line_segment([a, b], stroke); diff --git a/crates/egui/src/widgets/button.rs b/crates/egui/src/widgets/button.rs index 701e89b1cb3..9e44e940e11 100644 --- a/crates/egui/src/widgets/button.rs +++ b/crates/egui/src/widgets/button.rs @@ -319,6 +319,7 @@ impl Widget for Button<'_> { frame_rounding, frame_fill, frame_stroke, + epaint::StrokeKind::Inside, ); let mut cursor_x = rect.min.x + button_padding.x; diff --git a/crates/egui/src/widgets/checkbox.rs b/crates/egui/src/widgets/checkbox.rs index 96cc3d22bf8..f54478984b2 100644 --- a/crates/egui/src/widgets/checkbox.rs +++ b/crates/egui/src/widgets/checkbox.rs @@ -107,6 +107,7 @@ impl Widget for Checkbox<'_> { visuals.rounding, visuals.bg_fill, visuals.bg_stroke, + epaint::StrokeKind::Inside, )); if indeterminate { diff --git a/crates/egui/src/widgets/color_picker.rs b/crates/egui/src/widgets/color_picker.rs index ea1b53aef9f..b56f3c4e948 100644 --- a/crates/egui/src/widgets/color_picker.rs +++ b/crates/egui/src/widgets/color_picker.rs @@ -7,7 +7,7 @@ use crate::{ }; use epaint::{ ecolor::{Color32, Hsva, HsvaGamma, Rgba}, - pos2, vec2, Mesh, Rect, Shape, Stroke, Vec2, + pos2, vec2, Mesh, Rect, Shape, Stroke, StrokeKind, Vec2, }; fn contrast_color(color: impl Into) -> Color32 { @@ -97,11 +97,16 @@ fn color_button(ui: &mut Ui, color: Color32, open: bool) -> Response { }; let rect = rect.expand(visuals.expansion); - show_color_at(ui.painter(), color, rect); + let stroke_width = 1.0; + show_color_at(ui.painter(), color, rect.shrink(stroke_width)); let rounding = visuals.rounding.at_most(2); // Can't do more rounding because the background grid doesn't do any rounding - ui.painter() - .rect_stroke(rect, rounding, (2.0, visuals.bg_fill)); // fill is intentional, because default style has no border + ui.painter().rect_stroke( + rect, + rounding, + (stroke_width, visuals.bg_fill), // Using fill for stroke is intentional, because default style has no border + StrokeKind::Inside, + ); } response @@ -139,7 +144,8 @@ fn color_slider_1d(ui: &mut Ui, value: &mut f32, color_at: impl Fn(f32) -> Color ui.painter().add(Shape::mesh(mesh)); } - ui.painter().rect_stroke(rect, 0.0, visuals.bg_stroke); // outline + ui.painter() + .rect_stroke(rect, 0.0, visuals.bg_stroke, StrokeKind::Inside); // outline { // Show where the slider is at: @@ -208,7 +214,8 @@ fn color_slider_2d( } ui.painter().add(Shape::mesh(mesh)); // fill - ui.painter().rect_stroke(rect, 0.0, visuals.bg_stroke); // outline + ui.painter() + .rect_stroke(rect, 0.0, visuals.bg_stroke, StrokeKind::Inside); // outline // Show where the slider is at: let x = lerp(rect.left()..=rect.right(), *x_value); diff --git a/crates/egui/src/widgets/image_button.rs b/crates/egui/src/widgets/image_button.rs index 3a03ab295f5..7bf55cb608d 100644 --- a/crates/egui/src/widgets/image_button.rs +++ b/crates/egui/src/widgets/image_button.rs @@ -137,8 +137,12 @@ impl Widget for ImageButton<'_> { ); // Draw frame outline: - ui.painter() - .rect_stroke(rect.expand2(expansion), rounding, stroke); + ui.painter().rect_stroke( + rect.expand2(expansion), + rounding, + stroke, + epaint::StrokeKind::Inside, + ); } widgets::image::texture_load_result_response(&self.image.source(ui.ctx()), &tlr, response) diff --git a/crates/egui/src/widgets/progress_bar.rs b/crates/egui/src/widgets/progress_bar.rs index 7f926d02b73..a8c27f5c3b3 100644 --- a/crates/egui/src/widgets/progress_bar.rs +++ b/crates/egui/src/widgets/progress_bar.rs @@ -137,7 +137,7 @@ impl Widget for ProgressBar { let corner_radius = outer_rect.height() / 2.0; let rounding = rounding.unwrap_or_else(|| corner_radius.into()); ui.painter() - .rect(outer_rect, rounding, visuals.extreme_bg_color, Stroke::NONE); + .rect_filled(outer_rect, rounding, visuals.extreme_bg_color); let min_width = 2.0 * f32::max(rounding.sw as _, rounding.nw as _).at_most(corner_radius); let filled_width = (outer_rect.width() * progress).at_least(min_width); @@ -152,13 +152,12 @@ impl Widget for ProgressBar { bright }; - ui.painter().rect( + ui.painter().rect_filled( inner_rect, rounding, Color32::from( Rgba::from(fill.unwrap_or(visuals.selection.bg_fill)) * color_factor as f32, ), - Stroke::NONE, ); if animate && !is_custom_rounding { diff --git a/crates/egui/src/widgets/selected_label.rs b/crates/egui/src/widgets/selected_label.rs index 193fee74dea..16978794b6b 100644 --- a/crates/egui/src/widgets/selected_label.rs +++ b/crates/egui/src/widgets/selected_label.rs @@ -74,6 +74,7 @@ impl Widget for SelectableLabel { visuals.rounding, visuals.weak_bg_fill, visuals.bg_stroke, + epaint::StrokeKind::Inside, ); } diff --git a/crates/egui/src/widgets/slider.rs b/crates/egui/src/widgets/slider.rs index d535a5c7541..f721ce10124 100644 --- a/crates/egui/src/widgets/slider.rs +++ b/crates/egui/src/widgets/slider.rs @@ -815,8 +815,13 @@ impl Slider<'_> { }; let v = v + Vec2::splat(visuals.expansion); let rect = Rect::from_center_size(center, 2.0 * v); - ui.painter() - .rect(rect, visuals.rounding, visuals.bg_fill, visuals.fg_stroke); + ui.painter().rect( + rect, + visuals.rounding, + visuals.bg_fill, + visuals.fg_stroke, + epaint::StrokeKind::Inside, + ); } } } diff --git a/crates/egui/src/widgets/text_edit/builder.rs b/crates/egui/src/widgets/text_edit/builder.rs index 81dd6a448a1..05a8470c178 100644 --- a/crates/egui/src/widgets/text_edit/builder.rs +++ b/crates/egui/src/widgets/text_edit/builder.rs @@ -1,7 +1,10 @@ use std::sync::Arc; use emath::{Rect, TSTransform}; -use epaint::text::{cursor::CCursor, Galley, LayoutJob}; +use epaint::{ + text::{cursor::CCursor, Galley, LayoutJob}, + StrokeKind, +}; use crate::{ epaint, @@ -442,6 +445,7 @@ impl TextEdit<'_> { visuals.rounding, background_color, ui.visuals().selection.stroke, + StrokeKind::Inside, ) } else { epaint::RectShape::new( @@ -449,6 +453,7 @@ impl TextEdit<'_> { visuals.rounding, background_color, visuals.bg_stroke, // TODO(emilk): we want to show something here, or a text-edit field doesn't "pop". + StrokeKind::Inside, ) } } else { @@ -457,6 +462,7 @@ impl TextEdit<'_> { frame_rect, visuals.rounding, visuals.bg_stroke, // TODO(emilk): we want to show something here, or a text-edit field doesn't "pop". + StrokeKind::Inside, ) }; diff --git a/crates/egui_demo_app/src/frame_history.rs b/crates/egui_demo_app/src/frame_history.rs index a6a3fbeeb3f..b1091faba88 100644 --- a/crates/egui_demo_app/src/frame_history.rs +++ b/crates/egui_demo_app/src/frame_history.rs @@ -75,6 +75,7 @@ impl FrameHistory { style.rounding, ui.visuals().extreme_bg_color, ui.style().noninteractive().bg_stroke, + egui::StrokeKind::Inside, ))); let rect = rect.shrink(4.0); diff --git a/crates/egui_demo_app/tests/snapshots/imageviewer.png b/crates/egui_demo_app/tests/snapshots/imageviewer.png index 1176b2d3304..750fa35778d 100644 --- a/crates/egui_demo_app/tests/snapshots/imageviewer.png +++ b/crates/egui_demo_app/tests/snapshots/imageviewer.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6cc6ff64eb73ddac89ecdacd07c2176f3ab952c0db4593fccf6d11f155ec392 -size 103100 +oid sha256:2292f0f80bfd3c80055a72eb983549ac2875d36acb333732bd0a67e51b24ae4f +size 102983 diff --git a/crates/egui_demo_lib/benches/benchmark.rs b/crates/egui_demo_lib/benches/benchmark.rs index d3820603d5c..cbcc4d88f46 100644 --- a/crates/egui_demo_lib/benches/benchmark.rs +++ b/crates/egui_demo_lib/benches/benchmark.rs @@ -76,7 +76,13 @@ pub fn criterion_benchmark(c: &mut Criterion) { let painter = ui.painter(); let rect = ui.max_rect(); b.iter(|| { - painter.rect(rect, 2.0, egui::Color32::RED, (1.0, egui::Color32::WHITE)); + painter.rect( + rect, + 2.0, + egui::Color32::RED, + (1.0, egui::Color32::WHITE), + egui::StrokeKind::Inside, + ); }); }); }); diff --git a/crates/egui_demo_lib/src/demo/misc_demo_window.rs b/crates/egui_demo_lib/src/demo/misc_demo_window.rs index f3edf39558a..5f1022ffcd3 100644 --- a/crates/egui_demo_lib/src/demo/misc_demo_window.rs +++ b/crates/egui_demo_lib/src/demo/misc_demo_window.rs @@ -390,6 +390,7 @@ impl BoxPainting { self.rounding, ui.visuals().text_color().gamma_multiply(0.5), Stroke::new(self.stroke_width, Color32::WHITE), + egui::StrokeKind::Inside, ); } }); diff --git a/crates/egui_demo_lib/src/demo/paint_bezier.rs b/crates/egui_demo_lib/src/demo/paint_bezier.rs index 61dc3b7e676..08e29a9ffda 100644 --- a/crates/egui_demo_lib/src/demo/paint_bezier.rs +++ b/crates/egui_demo_lib/src/demo/paint_bezier.rs @@ -1,6 +1,7 @@ -use egui::epaint::{CubicBezierShape, PathShape, QuadraticBezierShape}; use egui::{ - emath, epaint, pos2, Color32, Context, Frame, Grid, Pos2, Rect, Sense, Shape, Stroke, Ui, Vec2, + emath, + epaint::{self, CubicBezierShape, PathShape, QuadraticBezierShape}, + pos2, Color32, Context, Frame, Grid, Pos2, Rect, Sense, Shape, Stroke, StrokeKind, Ui, Vec2, Widget, Window, }; @@ -132,6 +133,7 @@ impl PaintBezier { shape.visual_bounding_rect(), 0.0, self.bounding_box_stroke, + StrokeKind::Outside, )); painter.add(shape); } @@ -143,6 +145,7 @@ impl PaintBezier { shape.visual_bounding_rect(), 0.0, self.bounding_box_stroke, + StrokeKind::Outside, )); painter.add(shape); } diff --git a/crates/egui_demo_lib/src/demo/toggle_switch.rs b/crates/egui_demo_lib/src/demo/toggle_switch.rs index ca32987ef07..9619bd2c028 100644 --- a/crates/egui_demo_lib/src/demo/toggle_switch.rs +++ b/crates/egui_demo_lib/src/demo/toggle_switch.rs @@ -56,8 +56,13 @@ pub fn toggle_ui(ui: &mut egui::Ui, on: &mut bool) -> egui::Response { // All coordinates are in absolute screen coordinates so we use `rect` to place the elements. let rect = rect.expand(visuals.expansion); let radius = 0.5 * rect.height(); - ui.painter() - .rect(rect, radius, visuals.bg_fill, visuals.bg_stroke); + ui.painter().rect( + rect, + radius, + visuals.bg_fill, + visuals.bg_stroke, + egui::StrokeKind::Inside, + ); // Paint the circle, animating it from left to right with `how_on`: let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on); let center = egui::pos2(circle_x, rect.center().y); @@ -88,8 +93,13 @@ fn toggle_ui_compact(ui: &mut egui::Ui, on: &mut bool) -> egui::Response { let visuals = ui.style().interact_selectable(&response, *on); let rect = rect.expand(visuals.expansion); let radius = 0.5 * rect.height(); - ui.painter() - .rect(rect, radius, visuals.bg_fill, visuals.bg_stroke); + ui.painter().rect( + rect, + radius, + visuals.bg_fill, + visuals.bg_stroke, + egui::StrokeKind::Inside, + ); let circle_x = egui::lerp((rect.left() + radius)..=(rect.right() - radius), how_on); let center = egui::pos2(circle_x, rect.center().y); ui.painter() diff --git a/crates/egui_demo_lib/src/rendering_test.rs b/crates/egui_demo_lib/src/rendering_test.rs index 9d4c7985f2d..d43116e0b3f 100644 --- a/crates/egui_demo_lib/src/rendering_test.rs +++ b/crates/egui_demo_lib/src/rendering_test.rs @@ -452,7 +452,12 @@ fn pixel_test_strokes(ui: &mut Ui) { Pos2::new(cursor_pixel.x, cursor_pixel.y), Vec2::splat(size as f32), ); - painter.rect_stroke(rect_points / pixels_per_point, 0.0, stroke); + painter.rect_stroke( + rect_points / pixels_per_point, + 0.0, + stroke, + egui::StrokeKind::Outside, + ); cursor_pixel.x += (1 + size) as f32 + thickness_pixels * 2.0; } } diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Frame.png b/crates/egui_demo_lib/tests/snapshots/demos/Frame.png index 8d9779b293c..689bb21536f 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Frame.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Frame.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7d8135b745cb95a7e7c7a26e73e160742f88ec177a2fa262215c4886d98ff172 -size 24403 +oid sha256:e4fef5fa8661f207bae2c58381e729cdaf77aecc8b3f178caf262dc310e3a490 +size 24206 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Painting.png b/crates/egui_demo_lib/tests/snapshots/demos/Painting.png index 2638bf08da2..2aee66f7251 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Painting.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Painting.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64fe3ef34aaf3104931954f4a39760b99944f42da13f866622ca0222b750f6be -size 17731 +oid sha256:6efc59cb9908533baa1a7346b359e9e21c5faf0e373dac6fa7db5476e644233d +size 17678 diff --git a/crates/egui_demo_lib/tests/snapshots/demos/Scene.png b/crates/egui_demo_lib/tests/snapshots/demos/Scene.png index 6f1e00fe1d2..d9f483ec17e 100644 --- a/crates/egui_demo_lib/tests/snapshots/demos/Scene.png +++ b/crates/egui_demo_lib/tests/snapshots/demos/Scene.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4eed8890c6d8fa6b97639197f5d1be79a72724a70470c5e5ae4b55e3447b9b88 -size 35561 +oid sha256:d076f5365bfa87b7e61d3808b8b9b367157ea6e55ccf665720cbd2237d53793d +size 35563 diff --git a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png index 6f06e7727f6..84e73117130 100644 --- a/crates/egui_demo_lib/tests/snapshots/widget_gallery.png +++ b/crates/egui_demo_lib/tests/snapshots/widget_gallery.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3dc1bf9a59007a6ad0fb66a345d6cf272bd8bdcd26b10dbf411c1280e62b6fc -size 158285 +oid sha256:a291f3a5724aefc59ba7881f48752ccc826ca5e480741c221d195061f562ccc9 +size 158220 diff --git a/crates/egui_kittest/tests/snapshots/combobox_opened.png b/crates/egui_kittest/tests/snapshots/combobox_opened.png index 201fc999e2e..9020c95c27f 100644 --- a/crates/egui_kittest/tests/snapshots/combobox_opened.png +++ b/crates/egui_kittest/tests/snapshots/combobox_opened.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0a61ecf294d930ebbee9837611d7a75381e690348f448b1c0c8264b27f44ceb3 -size 7535 +oid sha256:64fd46da67cab2afae0ea8997a88fb43fd207e24cc3943086d978a8de717320f +size 7542 diff --git a/crates/epaint/src/shapes/rect_shape.rs b/crates/epaint/src/shapes/rect_shape.rs index 30ab0760513..ca7ab01f161 100644 --- a/crates/epaint/src/shapes/rect_shape.rs +++ b/crates/epaint/src/shapes/rect_shape.rs @@ -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, fill_color: impl Into, stroke: impl Into, + 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, fill_color: impl Into, ) -> 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, stroke: impl Into) -> Self { + pub fn stroke( + rect: Rect, + rounding: impl Into, + stroke: impl Into, + 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) } } diff --git a/crates/epaint/src/shapes/shape.rs b/crates/epaint/src/shapes/shape.rs index 62af1b58166..2e43fc58530 100644 --- a/crates/epaint/src/shapes/shape.rs +++ b/crates/epaint/src/shapes/shape.rs @@ -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, stroke: impl Into, + 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)] diff --git a/crates/epaint/src/tessellator.rs b/crates/epaint/src/tessellator.rs index f4562e5cad0..f05d9b47a75 100644 --- a/crates/epaint/src/tessellator.rs +++ b/crates/epaint/src/tessellator.rs @@ -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, ); diff --git a/tests/test_viewports/src/main.rs b/tests/test_viewports/src/main.rs index 9d06db431e4..9cdb0b967ba 100644 --- a/tests/test_viewports/src/main.rs +++ b/tests/test_viewports/src/main.rs @@ -478,7 +478,7 @@ fn drop_target( ui.painter().set( background_id, - egui::epaint::RectShape::new(rect, style.rounding, fill, stroke), + egui::epaint::RectShape::new(rect, style.rounding, fill, stroke, egui::StrokeKind::Inside), ); egui::InnerResponse::new(ret, response)