1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 14:20:04 -04:00

Use u8 in Rounding, and introduce Roundingf (#5563)

* Part of https://github.com/emilk/egui/issues/4019

As part of the work on adding a custom `Border` to everything, I want to
make sure that the size of `RectShape`, `Frame` and the future `Border`
is kept small (for performance reasons).

This PR changes the storage of the corner radius of rectangles from four
`f32` (one for each corner) into four `u8`. This mean the corner radius
can only be an integer in the range 0-255 (in ui points). This should be
enough for most people.

If you want to manipulate rounding using `f32`, there is a new
`Roundingf` to fill that niche.
This commit is contained in:
Emil Ernerfeldt
2025-01-02 14:29:50 +01:00
committed by GitHub
parent 3ffe1ed774
commit 249f8bcb93
13 changed files with 508 additions and 242 deletions

View File

@@ -8,7 +8,9 @@ use crate::{
TextStyle, Ui, UiKind, Vec2b, WidgetInfo, WidgetRect, WidgetText, WidgetType,
};
use emath::GuiRounding as _;
use epaint::{emath, pos2, vec2, Galley, Pos2, Rect, RectShape, Rounding, Shape, Stroke, Vec2};
use epaint::{
emath, pos2, vec2, Galley, Pos2, Rect, RectShape, Rounding, Roundingf, Shape, Stroke, Vec2,
};
use super::scroll_area::ScrollBarVisibility;
use super::{area, resize, Area, Frame, Resize, ScrollArea};
@@ -486,8 +488,9 @@ impl<'open> Window<'open> {
let style = ctx.style();
let spacing = window_margin.top + window_margin.bottom;
let height = ctx.fonts(|f| title.font_height(f, &style)) + spacing;
window_frame.rounding.ne = window_frame.rounding.ne.clamp(0.0, height / 2.0);
window_frame.rounding.nw = window_frame.rounding.nw.clamp(0.0, height / 2.0);
let half_height = (height / 2.0).round() as _;
window_frame.rounding.ne = window_frame.rounding.ne.clamp(0, half_height);
window_frame.rounding.nw = window_frame.rounding.nw.clamp(0, half_height);
(height, spacing)
} else {
(0.0, 0.0)
@@ -603,8 +606,8 @@ impl<'open> Window<'open> {
let mut round = window_frame.rounding;
if !is_collapsed {
round.se = 0.0;
round.sw = 0.0;
round.se = 0;
round.sw = 0;
}
area_content_ui.painter().set(
@@ -682,6 +685,7 @@ fn paint_resize_corner(
};
// Adjust the corner offset to accommodate for window rounding
let radius = radius as f32;
let offset =
((2.0_f32.sqrt() * (1.0 + radius) - radius) * 45.0_f32.to_radians().cos()).max(2.0);
@@ -1022,7 +1026,7 @@ fn paint_frame_interaction(ui: &Ui, rect: Rect, interaction: ResizeInteraction)
bottom = interaction.bottom.hover;
}
let rounding = ui.visuals().window_rounding;
let rounding = Roundingf::from(ui.visuals().window_rounding);
let Rect { min, max } = rect;
let mut points = Vec::new();

View File

@@ -1291,7 +1291,7 @@ impl Visuals {
warn_fg_color: Color32::from_rgb(255, 143, 0), // orange
error_fg_color: Color32::from_rgb(255, 0, 0), // red
window_rounding: Rounding::same(6.0),
window_rounding: Rounding::same(6),
window_shadow: Shadow {
offset: vec2(10.0, 20.0),
blur: 15.0,
@@ -1302,7 +1302,7 @@ impl Visuals {
window_stroke: Stroke::new(1.0, Color32::from_gray(60)),
window_highlight_topmost: true,
menu_rounding: Rounding::same(6.0),
menu_rounding: Rounding::same(6),
panel_fill: Color32::from_gray(27),
@@ -1412,7 +1412,7 @@ impl Widgets {
bg_fill: Color32::from_gray(27),
bg_stroke: Stroke::new(1.0, Color32::from_gray(60)), // separators, indentation lines
fg_stroke: Stroke::new(1.0, Color32::from_gray(140)), // normal text color
rounding: Rounding::same(2.0),
rounding: Rounding::same(2),
expansion: 0.0,
},
inactive: WidgetVisuals {
@@ -1420,7 +1420,7 @@ impl Widgets {
bg_fill: Color32::from_gray(60), // checkbox background
bg_stroke: Default::default(),
fg_stroke: Stroke::new(1.0, Color32::from_gray(180)), // button text
rounding: Rounding::same(2.0),
rounding: Rounding::same(2),
expansion: 0.0,
},
hovered: WidgetVisuals {
@@ -1428,7 +1428,7 @@ impl Widgets {
bg_fill: Color32::from_gray(70),
bg_stroke: Stroke::new(1.0, Color32::from_gray(150)), // e.g. hover over window edge or button
fg_stroke: Stroke::new(1.5, Color32::from_gray(240)),
rounding: Rounding::same(3.0),
rounding: Rounding::same(3),
expansion: 1.0,
},
active: WidgetVisuals {
@@ -1436,7 +1436,7 @@ impl Widgets {
bg_fill: Color32::from_gray(55),
bg_stroke: Stroke::new(1.0, Color32::WHITE),
fg_stroke: Stroke::new(2.0, Color32::WHITE),
rounding: Rounding::same(2.0),
rounding: Rounding::same(2),
expansion: 1.0,
},
open: WidgetVisuals {
@@ -1444,7 +1444,7 @@ impl Widgets {
bg_fill: Color32::from_gray(27),
bg_stroke: Stroke::new(1.0, Color32::from_gray(60)),
fg_stroke: Stroke::new(1.0, Color32::from_gray(210)),
rounding: Rounding::same(2.0),
rounding: Rounding::same(2),
expansion: 0.0,
},
}
@@ -1457,7 +1457,7 @@ impl Widgets {
bg_fill: Color32::from_gray(248),
bg_stroke: Stroke::new(1.0, Color32::from_gray(190)), // separators, indentation lines
fg_stroke: Stroke::new(1.0, Color32::from_gray(80)), // normal text color
rounding: Rounding::same(2.0),
rounding: Rounding::same(2),
expansion: 0.0,
},
inactive: WidgetVisuals {
@@ -1465,7 +1465,7 @@ impl Widgets {
bg_fill: Color32::from_gray(230), // checkbox background
bg_stroke: Default::default(),
fg_stroke: Stroke::new(1.0, Color32::from_gray(60)), // button text
rounding: Rounding::same(2.0),
rounding: Rounding::same(2),
expansion: 0.0,
},
hovered: WidgetVisuals {
@@ -1473,7 +1473,7 @@ impl Widgets {
bg_fill: Color32::from_gray(220),
bg_stroke: Stroke::new(1.0, Color32::from_gray(105)), // e.g. hover over window edge or button
fg_stroke: Stroke::new(1.5, Color32::BLACK),
rounding: Rounding::same(3.0),
rounding: Rounding::same(3),
expansion: 1.0,
},
active: WidgetVisuals {
@@ -1481,7 +1481,7 @@ impl Widgets {
bg_fill: Color32::from_gray(165),
bg_stroke: Stroke::new(1.0, Color32::BLACK),
fg_stroke: Stroke::new(2.0, Color32::BLACK),
rounding: Rounding::same(2.0),
rounding: Rounding::same(2),
expansion: 1.0,
},
open: WidgetVisuals {
@@ -1489,7 +1489,7 @@ impl Widgets {
bg_fill: Color32::from_gray(220),
bg_stroke: Stroke::new(1.0, Color32::from_gray(160)),
fg_stroke: Stroke::new(1.0, Color32::BLACK),
rounding: Rounding::same(2.0),
rounding: Rounding::same(2),
expansion: 0.0,
},
}
@@ -2420,9 +2420,16 @@ impl Widget for &mut Rounding {
// Apply the checkbox:
if same {
*self = Rounding::same((self.nw + self.ne + self.sw + self.se) / 4.0);
} else if self.is_same() {
self.se *= 1.00001; // prevent collapsing into sameness
*self = Rounding::from(self.average());
} else {
// Make sure we aren't same:
if self.is_same() {
if self.average() == 0.0 {
self.se = 1;
} else {
self.se -= 1;
}
}
}
response

View File

@@ -99,7 +99,7 @@ fn color_button(ui: &mut Ui, color: Color32, open: bool) -> Response {
show_color_at(ui.painter(), color, rect);
let rounding = visuals.rounding.at_most(2.0); // Can't do more rounding because the background grid doesn't do any rounding
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
}

View File

@@ -138,7 +138,8 @@ impl Widget for ProgressBar {
let rounding = rounding.unwrap_or_else(|| corner_radius.into());
ui.painter()
.rect(outer_rect, rounding, visuals.extreme_bg_color, Stroke::NONE);
let min_width = 2.0 * rounding.sw.at_least(rounding.nw).at_most(corner_radius);
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);
let inner_rect =
Rect::from_min_size(outer_rect.min, vec2(filled_width, outer_rect.height()));

View File

@@ -780,10 +780,10 @@ impl<'a> Slider<'a> {
// The trailing rect has to be drawn differently depending on the orientation.
match self.orientation {
SliderOrientation::Horizontal => {
trailing_rail_rect.max.x = center.x + rounding.nw;
trailing_rail_rect.max.x = center.x + rounding.nw as f32;
}
SliderOrientation::Vertical => {
trailing_rail_rect.min.y = center.y - rounding.se;
trailing_rail_rect.min.y = center.y - rounding.se as f32;
}
};