[refactor] introduce NumExt with at_least and at_most
`x.min(maxumim)` can be confusing but `x.at_most(maximum)` is very clear
This commit is contained in:
parent
5856cded95
commit
85a67ab15e
12 changed files with 83 additions and 22 deletions
2
TODO.md
2
TODO.md
|
@ -68,7 +68,7 @@ TODO-list for the Egui project. If you looking for something to do, look here.
|
||||||
* [ ] Thin circles look bad
|
* [ ] Thin circles look bad
|
||||||
* [ ] Allow adding multiple tooltips to the same widget, showing them all one after the other.
|
* [ ] Allow adding multiple tooltips to the same widget, showing them all one after the other.
|
||||||
* Math
|
* Math
|
||||||
* [ ] Change `width.min(max_width)` to `width.at_most(max_width)`
|
* [x] Change `width.min(max_width)` to `width.at_most(max_width)`
|
||||||
* Id
|
* Id
|
||||||
* struct TempId(u64); struct StateId(u64);
|
* struct TempId(u64); struct StateId(u64);
|
||||||
* `TempId` is count-based. Only good for interaction. Can't be used for storing state.
|
* `TempId` is count-based. Only good for interaction. Can't be used for storing state.
|
||||||
|
|
|
@ -191,7 +191,9 @@ impl CollapsingHeader {
|
||||||
desired_width,
|
desired_width,
|
||||||
galley.size.y + 2.0 * ui.style().spacing.button_padding.y,
|
galley.size.y + 2.0 * ui.style().spacing.button_padding.y,
|
||||||
);
|
);
|
||||||
desired_size.y = desired_size.y.max(ui.style().spacing.clickable_diameter);
|
desired_size.y = desired_size
|
||||||
|
.y
|
||||||
|
.at_least(ui.style().spacing.clickable_diameter);
|
||||||
let rect = ui.allocate_space(desired_size);
|
let rect = ui.allocate_space(desired_size);
|
||||||
let rect = rect.expand2(ui.style().spacing.button_expand);
|
let rect = rect.expand2(ui.style().spacing.button_expand);
|
||||||
|
|
||||||
|
|
|
@ -140,7 +140,10 @@ impl Resize {
|
||||||
let mut state = ui.memory().resize.get(&id).cloned().unwrap_or_else(|| {
|
let mut state = ui.memory().resize.get(&id).cloned().unwrap_or_else(|| {
|
||||||
ui.ctx().request_repaint(); // counter frame delay
|
ui.ctx().request_repaint(); // counter frame delay
|
||||||
|
|
||||||
let default_size = self.default_size.max(self.min_size);
|
let default_size = self
|
||||||
|
.default_size
|
||||||
|
.at_least(self.min_size)
|
||||||
|
.at_most(self.max_size);
|
||||||
|
|
||||||
State {
|
State {
|
||||||
desired_size: default_size,
|
desired_size: default_size,
|
||||||
|
@ -149,8 +152,10 @@ impl Resize {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
state.desired_size = state.desired_size.max(self.min_size);
|
state.desired_size = state
|
||||||
state.desired_size = state.desired_size.min(self.max_size);
|
.desired_size
|
||||||
|
.at_least(self.min_size)
|
||||||
|
.at_most(self.max_size);
|
||||||
|
|
||||||
let position = ui.available().min;
|
let position = ui.available().min;
|
||||||
|
|
||||||
|
@ -174,8 +179,10 @@ impl Resize {
|
||||||
if let Some(requested_size) = state.requested_size.take() {
|
if let Some(requested_size) = state.requested_size.take() {
|
||||||
state.desired_size = requested_size;
|
state.desired_size = requested_size;
|
||||||
}
|
}
|
||||||
state.desired_size = state.desired_size.max(self.min_size);
|
state.desired_size = state
|
||||||
state.desired_size = state.desired_size.min(self.max_size);
|
.desired_size
|
||||||
|
.at_least(self.min_size)
|
||||||
|
.at_most(self.max_size);
|
||||||
|
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ impl ScrollArea {
|
||||||
|
|
||||||
let outer_size = vec2(
|
let outer_size = vec2(
|
||||||
ui.available().width(),
|
ui.available().width(),
|
||||||
ui.available().height().min(max_height),
|
ui.available().height().at_most(max_height),
|
||||||
);
|
);
|
||||||
|
|
||||||
let inner_size = outer_size - vec2(current_scroll_bar_width, 0.0);
|
let inner_size = outer_size - vec2(current_scroll_bar_width, 0.0);
|
||||||
|
|
|
@ -255,7 +255,7 @@ impl<'open> Window<'open> {
|
||||||
&mut collapsing,
|
&mut collapsing,
|
||||||
collapsible,
|
collapsible,
|
||||||
);
|
);
|
||||||
resize.min_size.x = resize.min_size.x.max(title_bar.rect.width()); // Prevent making window smaller than title bar width
|
resize.min_size.x = resize.min_size.x.at_least(title_bar.rect.width()); // Prevent making window smaller than title bar width
|
||||||
|
|
||||||
let content_rect = collapsing
|
let content_rect = collapsing
|
||||||
.add_contents(&mut frame.content_ui, collapsing_id, |ui| {
|
.add_contents(&mut frame.content_ui, collapsing_id, |ui| {
|
||||||
|
|
|
@ -36,8 +36,8 @@ impl Texture {
|
||||||
let v = remap_clamp(pos.y, rect.range_y(), 0.0..=tex_h);
|
let v = remap_clamp(pos.y, rect.range_y(), 0.0..=tex_h);
|
||||||
|
|
||||||
let texel_radius = 32.0;
|
let texel_radius = 32.0;
|
||||||
let u = u.max(texel_radius).min(tex_w - texel_radius);
|
let u = u.at_least(texel_radius).at_most(tex_w - texel_radius);
|
||||||
let v = v.max(texel_radius).min(tex_h - texel_radius);
|
let v = v.at_least(texel_radius).at_most(tex_h - texel_radius);
|
||||||
|
|
||||||
let uv_rect = Rect::from_min_max(
|
let uv_rect = Rect::from_min_max(
|
||||||
pos2((u - texel_radius) / tex_w, (v - texel_radius) / tex_h),
|
pos2((u - texel_radius) / tex_w, (v - texel_radius) / tex_h),
|
||||||
|
|
|
@ -180,3 +180,49 @@ fn test_remap() {
|
||||||
assert_eq!(remap_clamp(1.0, 1.0..=0.0, 16.0..=0.0), 16.0);
|
assert_eq!(remap_clamp(1.0, 1.0..=0.0, 16.0..=0.0), 16.0);
|
||||||
assert_eq!(remap_clamp(0.5, 1.0..=0.0, 16.0..=0.0), 8.0);
|
assert_eq!(remap_clamp(0.5, 1.0..=0.0, 16.0..=0.0), 8.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub trait NumExt {
|
||||||
|
/// More readable version of `self.max(lower_limit)`
|
||||||
|
fn at_least(self, lower_limit: Self) -> Self;
|
||||||
|
|
||||||
|
/// More readable version of `self.min(upper_limit)`
|
||||||
|
fn at_most(self, upper_limit: Self) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NumExt for f32 {
|
||||||
|
/// More readable version of `self.max(lower_limit)`
|
||||||
|
fn at_least(self, lower_limit: Self) -> Self {
|
||||||
|
self.max(lower_limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// More readable version of `self.min(upper_limit)`
|
||||||
|
fn at_most(self, upper_limit: Self) -> Self {
|
||||||
|
self.min(upper_limit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NumExt for Vec2 {
|
||||||
|
/// More readable version of `self.max(lower_limit)`
|
||||||
|
fn at_least(self, lower_limit: Self) -> Self {
|
||||||
|
self.max(lower_limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// More readable version of `self.min(upper_limit)`
|
||||||
|
fn at_most(self, upper_limit: Self) -> Self {
|
||||||
|
self.min(upper_limit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NumExt for Pos2 {
|
||||||
|
/// More readable version of `self.max(lower_limit)`
|
||||||
|
fn at_least(self, lower_limit: Self) -> Self {
|
||||||
|
self.max(lower_limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// More readable version of `self.min(upper_limit)`
|
||||||
|
fn at_most(self, upper_limit: Self) -> Self {
|
||||||
|
self.min(upper_limit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -710,8 +710,8 @@ fn tessellate_paint_command(
|
||||||
if !rect.is_empty() {
|
if !rect.is_empty() {
|
||||||
// It is common to (sometimes accidentally) create an infinitely sized rectangle.
|
// It is common to (sometimes accidentally) create an infinitely sized rectangle.
|
||||||
// Make sure we can handle that:
|
// Make sure we can handle that:
|
||||||
rect.min = rect.min.max(pos2(-1e7, -1e7));
|
rect.min = rect.min.at_least(pos2(-1e7, -1e7));
|
||||||
rect.max = rect.max.min(pos2(1e7, 1e7));
|
rect.max = rect.max.at_most(pos2(1e7, 1e7));
|
||||||
|
|
||||||
path::rounded_rectangle(scratchpad_points, rect, corner_radius);
|
path::rounded_rectangle(scratchpad_points, rect, corner_radius);
|
||||||
path.add_line_loop(scratchpad_points);
|
path.add_line_loop(scratchpad_points);
|
||||||
|
|
|
@ -197,7 +197,7 @@ impl Ui {
|
||||||
/// You won't be able to shrink it beyond its current child bounds.
|
/// You won't be able to shrink it beyond its current child bounds.
|
||||||
pub fn set_desired_width(&mut self, width: f32) {
|
pub fn set_desired_width(&mut self, width: f32) {
|
||||||
let min_width = self.child_bounds.max.x - self.top_left().x;
|
let min_width = self.child_bounds.max.x - self.top_left().x;
|
||||||
let width = width.max(min_width);
|
let width = width.at_least(min_width);
|
||||||
self.desired_rect.max.x = self.top_left().x + width;
|
self.desired_rect.max.x = self.top_left().x + width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ impl Ui {
|
||||||
/// You won't be able to shrink it beyond its current child bounds.
|
/// You won't be able to shrink it beyond its current child bounds.
|
||||||
pub fn set_desired_height(&mut self, height: f32) {
|
pub fn set_desired_height(&mut self, height: f32) {
|
||||||
let min_height = self.child_bounds.max.y - self.top_left().y;
|
let min_height = self.child_bounds.max.y - self.top_left().y;
|
||||||
let height = height.max(min_height);
|
let height = height.at_least(min_height);
|
||||||
self.desired_rect.max.y = self.top_left().y + height;
|
self.desired_rect.max.y = self.top_left().y + height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,7 +584,7 @@ impl Ui {
|
||||||
/// After `add_contents` is called the contents of `bounding_size`
|
/// After `add_contents` is called the contents of `bounding_size`
|
||||||
/// will decide how much space will be used in the parent ui.
|
/// will decide how much space will be used in the parent ui.
|
||||||
pub fn add_custom_contents(&mut self, size: Vec2, add_contents: impl FnOnce(&mut Ui)) -> Rect {
|
pub fn add_custom_contents(&mut self, size: Vec2, add_contents: impl FnOnce(&mut Ui)) -> Rect {
|
||||||
let size = size.min(self.available().size());
|
let size = size.at_most(self.available().size());
|
||||||
let child_rect = Rect::from_min_size(self.cursor, size);
|
let child_rect = Rect::from_min_size(self.cursor, size);
|
||||||
let mut child_ui = self.child_ui(child_rect);
|
let mut child_ui = self.child_ui(child_rect);
|
||||||
add_contents(&mut child_ui);
|
add_contents(&mut child_ui);
|
||||||
|
|
|
@ -64,7 +64,7 @@ fn color_button(ui: &mut Ui, color: Srgba) -> Response {
|
||||||
background_checkers(ui.painter(), rect);
|
background_checkers(ui.painter(), rect);
|
||||||
ui.painter().add(PaintCmd::Rect {
|
ui.painter().add(PaintCmd::Rect {
|
||||||
rect,
|
rect,
|
||||||
corner_radius: visuals.corner_radius.min(2.0),
|
corner_radius: visuals.corner_radius.at_most(2.0),
|
||||||
fill: color,
|
fill: color,
|
||||||
stroke: visuals.fg_stroke,
|
stroke: visuals.fg_stroke,
|
||||||
});
|
});
|
||||||
|
|
|
@ -292,7 +292,9 @@ impl Widget for Button {
|
||||||
let font = &ui.fonts()[text_style];
|
let font = &ui.fonts()[text_style];
|
||||||
let galley = font.layout_multiline(text, ui.available().width());
|
let galley = font.layout_multiline(text, ui.available().width());
|
||||||
let mut desired_size = galley.size + 2.0 * ui.style().spacing.button_padding;
|
let mut desired_size = galley.size + 2.0 * ui.style().spacing.button_padding;
|
||||||
desired_size.y = desired_size.y.max(ui.style().spacing.clickable_diameter);
|
desired_size.y = desired_size
|
||||||
|
.y
|
||||||
|
.at_least(ui.style().spacing.clickable_diameter);
|
||||||
let rect = ui.allocate_space(desired_size);
|
let rect = ui.allocate_space(desired_size);
|
||||||
let rect = rect.expand2(ui.style().spacing.button_expand);
|
let rect = rect.expand2(ui.style().spacing.button_expand);
|
||||||
|
|
||||||
|
@ -355,7 +357,9 @@ impl<'a> Widget for Checkbox<'a> {
|
||||||
let button_padding = ui.style().spacing.button_padding;
|
let button_padding = ui.style().spacing.button_padding;
|
||||||
let mut desired_size =
|
let mut desired_size =
|
||||||
button_padding + vec2(icon_width, 0.0) + galley.size + button_padding;
|
button_padding + vec2(icon_width, 0.0) + galley.size + button_padding;
|
||||||
desired_size.y = desired_size.y.max(ui.style().spacing.clickable_diameter);
|
desired_size.y = desired_size
|
||||||
|
.y
|
||||||
|
.at_least(ui.style().spacing.clickable_diameter);
|
||||||
let rect = ui.allocate_space(desired_size);
|
let rect = ui.allocate_space(desired_size);
|
||||||
|
|
||||||
let response = ui.interact(rect, id, Sense::click());
|
let response = ui.interact(rect, id, Sense::click());
|
||||||
|
@ -437,7 +441,9 @@ impl Widget for RadioButton {
|
||||||
let button_padding = ui.style().spacing.button_padding;
|
let button_padding = ui.style().spacing.button_padding;
|
||||||
let mut desired_size =
|
let mut desired_size =
|
||||||
button_padding + vec2(icon_width, 0.0) + galley.size + button_padding;
|
button_padding + vec2(icon_width, 0.0) + galley.size + button_padding;
|
||||||
desired_size.y = desired_size.y.max(ui.style().spacing.clickable_diameter);
|
desired_size.y = desired_size
|
||||||
|
.y
|
||||||
|
.at_least(ui.style().spacing.clickable_diameter);
|
||||||
let rect = ui.allocate_space(desired_size);
|
let rect = ui.allocate_space(desired_size);
|
||||||
|
|
||||||
let response = ui.interact(rect, id, Sense::click());
|
let response = ui.interact(rect, id, Sense::click());
|
||||||
|
@ -633,7 +639,7 @@ impl<'a> Widget for DragValue<'a> {
|
||||||
} = self;
|
} = self;
|
||||||
let value = get(&mut value_function);
|
let value = get(&mut value_function);
|
||||||
let aim_rad = ui.input().physical_pixel_size(); // ui.input().aim_radius(); // TODO
|
let aim_rad = ui.input().physical_pixel_size(); // ui.input().aim_radius(); // TODO
|
||||||
let precision = (aim_rad / speed.abs()).log10().ceil().max(0.0) as usize;
|
let precision = (aim_rad / speed.abs()).log10().ceil().at_least(0.0) as usize;
|
||||||
let value_text = format_with_minimum_precision(value as f32, precision); // TODO: full precision
|
let value_text = format_with_minimum_precision(value as f32, precision); // TODO: full precision
|
||||||
|
|
||||||
let kb_edit_id = ui.make_position_id().with("edit");
|
let kb_edit_id = ui.make_position_id().with("edit");
|
||||||
|
|
|
@ -272,7 +272,7 @@ impl<'a> Widget for Slider<'a> {
|
||||||
let font = &ui.fonts()[text_style];
|
let font = &ui.fonts()[text_style];
|
||||||
let height = font
|
let height = font
|
||||||
.line_spacing()
|
.line_spacing()
|
||||||
.max(ui.style().spacing.clickable_diameter);
|
.at_least(ui.style().spacing.clickable_diameter);
|
||||||
|
|
||||||
if let Some(text) = &self.text {
|
if let Some(text) = &self.text {
|
||||||
self.id = self.id.or_else(|| Some(ui.make_unique_child_id(text)));
|
self.id = self.id.or_else(|| Some(ui.make_unique_child_id(text)));
|
||||||
|
|
Loading…
Reference in a new issue