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:
parent
8d2c8c203c
commit
525d435a84
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
|
|||
|
|
@ -474,6 +474,7 @@ fn button_frame(
|
|||
visuals.rounding,
|
||||
visuals.weak_bg_fill,
|
||||
visuals.bg_stroke,
|
||||
epaint::StrokeKind::Inside,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -356,6 +356,7 @@ impl Resize {
|
|||
rect,
|
||||
3.0,
|
||||
ui.visuals().widgets.noninteractive.bg_stroke,
|
||||
epaint::StrokeKind::Inside,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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<Rounding>,
|
||||
fill_color: impl Into<Color32>,
|
||||
stroke: impl Into<Stroke>,
|
||||
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<Rounding>,
|
||||
stroke: impl Into<Stroke>,
|
||||
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()`.
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ impl Widget for Checkbox<'_> {
|
|||
visuals.rounding,
|
||||
visuals.bg_fill,
|
||||
visuals.bg_stroke,
|
||||
epaint::StrokeKind::Inside,
|
||||
));
|
||||
|
||||
if indeterminate {
|
||||
|
|
|
|||
|
|
@ -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<Rgba>) -> 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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ impl Widget for SelectableLabel {
|
|||
visuals.rounding,
|
||||
visuals.weak_bg_fill,
|
||||
visuals.bg_stroke,
|
||||
epaint::StrokeKind::Inside,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e6cc6ff64eb73ddac89ecdacd07c2176f3ab952c0db4593fccf6d11f155ec392
|
||||
size 103100
|
||||
oid sha256:2292f0f80bfd3c80055a72eb983549ac2875d36acb333732bd0a67e51b24ae4f
|
||||
size 102983
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7d8135b745cb95a7e7c7a26e73e160742f88ec177a2fa262215c4886d98ff172
|
||||
size 24403
|
||||
oid sha256:e4fef5fa8661f207bae2c58381e729cdaf77aecc8b3f178caf262dc310e3a490
|
||||
size 24206
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:64fe3ef34aaf3104931954f4a39760b99944f42da13f866622ca0222b750f6be
|
||||
size 17731
|
||||
oid sha256:6efc59cb9908533baa1a7346b359e9e21c5faf0e373dac6fa7db5476e644233d
|
||||
size 17678
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:4eed8890c6d8fa6b97639197f5d1be79a72724a70470c5e5ae4b55e3447b9b88
|
||||
size 35561
|
||||
oid sha256:d076f5365bfa87b7e61d3808b8b9b367157ea6e55ccf665720cbd2237d53793d
|
||||
size 35563
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b3dc1bf9a59007a6ad0fb66a345d6cf272bd8bdcd26b10dbf411c1280e62b6fc
|
||||
size 158285
|
||||
oid sha256:a291f3a5724aefc59ba7881f48752ccc826ca5e480741c221d195061f562ccc9
|
||||
size 158220
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:0a61ecf294d930ebbee9837611d7a75381e690348f448b1c0c8264b27f44ceb3
|
||||
size 7535
|
||||
oid sha256:64fd46da67cab2afae0ea8997a88fb43fd207e24cc3943086d978a8de717320f
|
||||
size 7542
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -478,7 +478,7 @@ fn drop_target<R>(
|
|||
|
||||
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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue