[emath] Use const values for Vec2::ZERO, Rect::EVERYTHING etc

This commit is contained in:
Emil Ernerfeldt 2021-02-05 09:49:21 +01:00
parent 10e86b055d
commit 2d9d06dbff
20 changed files with 118 additions and 71 deletions

View file

@ -139,7 +139,7 @@ impl Area {
let state = ctx.memory().areas.get(id).cloned(); let state = ctx.memory().areas.get(id).cloned();
let mut state = state.unwrap_or_else(|| State { let mut state = state.unwrap_or_else(|| State {
pos: default_pos.unwrap_or_else(|| automatic_area_position(ctx)), pos: default_pos.unwrap_or_else(|| automatic_area_position(ctx)),
size: Vec2::zero(), size: Vec2::ZERO,
interactable, interactable,
}); });
state.pos = new_pos.unwrap_or(state.pos); state.pos = new_pos.unwrap_or(state.pos);
@ -198,7 +198,7 @@ impl Prepared {
} }
pub(crate) fn content_ui(&self, ctx: &CtxRef) -> Ui { pub(crate) fn content_ui(&self, ctx: &CtxRef) -> Ui {
let max_rect = Rect::from_min_size(self.state.pos, Vec2::infinity()); let max_rect = Rect::from_min_size(self.state.pos, Vec2::INFINITY);
let shadow_radius = ctx.style().visuals.window_shadow.extrusion; // hacky let shadow_radius = ctx.style().visuals.window_shadow.extrusion; // hacky
let mut clip_rect = max_rect let mut clip_rect = max_rect
.expand(ctx.style().visuals.clip_rect_margin) .expand(ctx.style().visuals.clip_rect_margin)
@ -241,7 +241,7 @@ impl Prepared {
}; };
let move_response = ctx.interact( let move_response = ctx.interact(
Rect::everything(), Rect::EVERYTHING,
ctx.style().spacing.item_spacing, ctx.style().spacing.item_spacing,
layer_id, layer_id,
interact_id, interact_id,

View file

@ -37,7 +37,7 @@ pub fn show_tooltip(ctx: &CtxRef, add_contents: impl FnOnce(&mut Ui)) {
let id = Id::tooltip(); let id = Id::tooltip();
let response = show_tooltip_area(ctx, id, window_pos, add_contents); let response = show_tooltip_area(ctx, id, window_pos, add_contents);
let tooltip_rect = tooltip_rect.unwrap_or_else(Rect::nothing); let tooltip_rect = tooltip_rect.unwrap_or(Rect::NOTHING);
ctx.frame_state().tooltip_rect = Some(tooltip_rect.union(response.rect)); ctx.frame_state().tooltip_rect = Some(tooltip_rect.union(response.rect));
} }
@ -114,7 +114,7 @@ pub fn popup_below_widget(
let frame = Frame::popup(ui.style()); let frame = Frame::popup(ui.style());
let frame_margin = frame.margin; let frame_margin = frame.margin;
frame.show(ui, |ui| { frame.show(ui, |ui| {
ui.with_layout(Layout::top_down_justified(Align::left()), |ui| { ui.with_layout(Layout::top_down_justified(Align::LEFT), |ui| {
ui.set_width(widget_response.rect.width() - 2.0 * frame_margin.x); ui.set_width(widget_response.rect.width() - 2.0 * frame_margin.x);
add_contents(ui) add_contents(ui)
}); });

View file

@ -124,7 +124,7 @@ impl Resize {
/// Not manually resizable, just takes the size of its contents. /// Not manually resizable, just takes the size of its contents.
/// Text will not wrap, but will instead make your window width expand. /// Text will not wrap, but will instead make your window width expand.
pub fn auto_sized(self) -> Self { pub fn auto_sized(self) -> Self {
self.min_size(Vec2::zero()) self.min_size(Vec2::ZERO)
.default_size(Vec2::splat(f32::INFINITY)) .default_size(Vec2::splat(f32::INFINITY))
.resizable(false) .resizable(false)
} }

View file

@ -19,9 +19,9 @@ pub(crate) struct State {
impl Default for State { impl Default for State {
fn default() -> Self { fn default() -> Self {
Self { Self {
offset: Vec2::zero(), offset: Vec2::ZERO,
show_scroll: false, show_scroll: false,
vel: Vec2::zero(), vel: Vec2::ZERO,
scroll_start_offset_from_top: None, scroll_start_offset_from_top: None,
} }
} }
@ -222,7 +222,7 @@ impl Prepared {
let friction = friction_coeff * dt; let friction = friction_coeff * dt;
if friction > state.vel.length() || state.vel.length() < stop_speed { if friction > state.vel.length() || state.vel.length() < stop_speed {
state.vel = Vec2::zero(); state.vel = Vec2::ZERO;
} else { } else {
state.vel -= friction * state.vel.normalized(); state.vel -= friction * state.vel.normalized();
// Offset has an inverted coordinate system compared to // Offset has an inverted coordinate system compared to
@ -244,7 +244,7 @@ impl Prepared {
if scrolling_up || scrolling_down { if scrolling_up || scrolling_down {
state.offset.y -= scroll_delta.y; state.offset.y -= scroll_delta.y;
// Clear scroll delta so no parent scroll will use it. // Clear scroll delta so no parent scroll will use it.
frame_state.scroll_delta = Vec2::zero(); frame_state.scroll_delta = Vec2::ZERO;
} }
} }
@ -310,7 +310,7 @@ impl Prepared {
state.offset.y = state.offset.y.min(max_offset); state.offset.y = state.offset.y.min(max_offset);
#[allow(clippy::float_cmp)] #[allow(clippy::float_cmp)]
if state.offset.y != unbounded_offset_y { if state.offset.y != unbounded_offset_y {
state.vel = Vec2::zero(); state.vel = Vec2::ZERO;
} }
// Avoid frame-delay by calculating a new handle rect: // Avoid frame-delay by calculating a new handle rect:

View file

@ -705,7 +705,7 @@ fn show_title_bar(
title_label, title_label,
title_galley, title_galley,
min_rect, min_rect,
rect: Rect::invalid(), // Will be filled in later rect: Rect::NAN, // Will be filled in later
} }
}); });

View file

@ -51,11 +51,11 @@ impl Default for FrameState {
fn default() -> Self { fn default() -> Self {
Self { Self {
used_ids: Default::default(), used_ids: Default::default(),
available_rect: Rect::invalid(), available_rect: Rect::NAN,
unused_rect: Rect::invalid(), unused_rect: Rect::NAN,
used_by_panels: Rect::invalid(), used_by_panels: Rect::NAN,
tooltip_rect: None, tooltip_rect: None,
scroll_delta: Vec2::zero(), scroll_delta: Vec2::ZERO,
scroll_target: None, scroll_target: None,
} }
} }
@ -76,7 +76,7 @@ impl FrameState {
used_ids.clear(); used_ids.clear();
*available_rect = input.screen_rect(); *available_rect = input.screen_rect();
*unused_rect = input.screen_rect(); *unused_rect = input.screen_rect();
*used_by_panels = Rect::nothing(); *used_by_panels = Rect::NOTHING;
*tooltip_rect = None; *tooltip_rect = None;
*scroll_delta = input.scroll_delta; *scroll_delta = input.scroll_delta;
*scroll_target = None; *scroll_target = None;
@ -118,7 +118,7 @@ impl FrameState {
pub(crate) fn allocate_central_panel(&mut self, panel_rect: Rect) { pub(crate) fn allocate_central_panel(&mut self, panel_rect: Rect) {
// Note: we do not shrink `available_rect`, because // Note: we do not shrink `available_rect`, because
// we allow windows to cover the CentralPanel. // we allow windows to cover the CentralPanel.
self.unused_rect = Rect::nothing(); // Nothing left unused after this self.unused_rect = Rect::NOTHING; // Nothing left unused after this
self.used_by_panels = self.used_by_panels.union(panel_rect); self.used_by_panels = self.used_by_panels.union(panel_rect);
} }
} }

View file

@ -49,7 +49,7 @@ impl Default for RawInput {
fn default() -> Self { fn default() -> Self {
#![allow(deprecated)] // for screen_size #![allow(deprecated)] // for screen_size
Self { Self {
scroll_delta: Vec2::zero(), scroll_delta: Vec2::ZERO,
screen_size: Default::default(), screen_size: Default::default(),
screen_rect: None, screen_rect: None,
pixels_per_point: None, pixels_per_point: None,

View file

@ -8,7 +8,7 @@ pub fn easy_mark(ui: &mut Ui, easy_mark: &str) {
pub fn easy_mark_it<'em>(ui: &mut Ui, items: impl Iterator<Item = easy_mark::Item<'em>>) { pub fn easy_mark_it<'em>(ui: &mut Ui, items: impl Iterator<Item = easy_mark::Item<'em>>) {
ui.horizontal_wrapped(|ui| { ui.horizontal_wrapped(|ui| {
ui.spacing_mut().item_spacing = Vec2::zero(); ui.spacing_mut().item_spacing = Vec2::ZERO;
for item in items { for item in items {
item_ui(ui, item); item_ui(ui, item);
} }

View file

@ -114,7 +114,7 @@ impl InputState {
} }
pub fn wants_repaint(&self) -> bool { pub fn wants_repaint(&self) -> bool {
self.pointer.wants_repaint() || self.scroll_delta != Vec2::zero() || !self.events.is_empty() self.pointer.wants_repaint() || self.scroll_delta != Vec2::ZERO || !self.events.is_empty()
} }
/// Was the given key pressed this frame? /// Was the given key pressed this frame?
@ -259,8 +259,8 @@ impl Default for PointerState {
Self { Self {
latest_pos: None, latest_pos: None,
interact_pos: None, interact_pos: None,
delta: Vec2::zero(), delta: Vec2::ZERO,
velocity: Vec2::zero(), velocity: Vec2::ZERO,
pos_history: History::new(1000, 0.1), pos_history: History::new(1000, 0.1),
down: Default::default(), down: Default::default(),
press_origin: None, press_origin: None,
@ -357,7 +357,7 @@ impl PointerState {
self.delta = if let (Some(old_pos), Some(new_pos)) = (old_pos, self.latest_pos) { self.delta = if let (Some(old_pos), Some(new_pos)) = (old_pos, self.latest_pos) {
new_pos - old_pos new_pos - old_pos
} else { } else {
Vec2::zero() Vec2::ZERO
}; };
if let Some(pos) = self.latest_pos { if let Some(pos) = self.latest_pos {
@ -380,7 +380,7 @@ impl PointerState {
} }
fn wants_repaint(&self) -> bool { fn wants_repaint(&self) -> bool {
!self.pointer_events.is_empty() || self.delta != Vec2::zero() !self.pointer_events.is_empty() || self.delta != Vec2::ZERO
} }
/// How much the pointer moved compared to last frame, in points. /// How much the pointer moved compared to last frame, in points.
@ -429,7 +429,7 @@ impl PointerState {
/// Is the pointer currently moving? /// Is the pointer currently moving?
/// This is smoothed so a few frames of stillness is required before this returns `true`. /// This is smoothed so a few frames of stillness is required before this returns `true`.
pub fn is_moving(&self) -> bool { pub fn is_moving(&self) -> bool {
self.velocity != Vec2::zero() self.velocity != Vec2::ZERO
} }
/// Was any pointer button pressed (`!down -> down`) this frame? /// Was any pointer button pressed (`!down -> down`) this frame?

View file

@ -133,7 +133,7 @@ impl Default for Layout {
Self { Self {
main_dir: Direction::TopDown, main_dir: Direction::TopDown,
main_wrap: false, main_wrap: false,
cross_align: Align::left(), cross_align: Align::LEFT,
cross_justify: false, cross_justify: false,
} }
} }
@ -253,7 +253,7 @@ impl Layout {
fn horizontal_align(&self) -> Align { fn horizontal_align(&self) -> Align {
match self.main_dir { match self.main_dir {
// Direction::LeftToRight => Align::left(), // Direction::LeftToRight => Align::LEFT,
// Direction::RightToLeft => Align::right(), // Direction::RightToLeft => Align::right(),
Direction::LeftToRight | Direction::RightToLeft => Align::Center, // looks better to e.g. center text within a button Direction::LeftToRight | Direction::RightToLeft => Align::Center, // looks better to e.g. center text within a button
@ -263,8 +263,8 @@ impl Layout {
fn vertical_align(&self) -> Align { fn vertical_align(&self) -> Align {
match self.main_dir { match self.main_dir {
// Direction::TopDown => Align::top(), // Direction::TopDown => Align::TOP,
// Direction::BottomUp => Align::bottom(), // Direction::BottomUp => Align::BOTTOM,
Direction::TopDown | Direction::BottomUp => Align::Center, // looks better to e.g. center text within a button Direction::TopDown | Direction::BottomUp => Align::Center, // looks better to e.g. center text within a button
Direction::LeftToRight | Direction::RightToLeft => self.cross_align, Direction::LeftToRight | Direction::RightToLeft => self.cross_align,
@ -300,7 +300,7 @@ impl Layout {
pub(crate) fn region_from_max_rect(&self, max_rect: Rect) -> Region { pub(crate) fn region_from_max_rect(&self, max_rect: Rect) -> Region {
let cursor = self.initial_cursor(max_rect); let cursor = self.initial_cursor(max_rect);
let min_rect = Rect::from_min_size(cursor, Vec2::zero()); let min_rect = Rect::from_min_size(cursor, Vec2::ZERO);
Region { Region {
min_rect, min_rect,
max_rect, max_rect,

View file

@ -111,7 +111,7 @@ fn menu_impl<'c>(
style.visuals.widgets.inactive.bg_fill = Color32::TRANSPARENT; style.visuals.widgets.inactive.bg_fill = Color32::TRANSPARENT;
style.visuals.widgets.inactive.bg_stroke = Stroke::none(); style.visuals.widgets.inactive.bg_stroke = Stroke::none();
ui.set_style(style); ui.set_style(style);
ui.with_layout(Layout::top_down_justified(Align::left()), add_contents); ui.with_layout(Layout::top_down_justified(Align::LEFT), add_contents);
}) })
}); });

View file

@ -127,7 +127,7 @@ impl Placer {
self.layout.advance_cursor(&mut self.region.cursor, amount); self.layout.advance_cursor(&mut self.region.cursor, amount);
self.region self.region
.expand_to_include_rect(Rect::from_min_size(self.cursor(), Vec2::zero())); .expand_to_include_rect(Rect::from_min_size(self.cursor(), Vec2::ZERO));
} }
/// Advance cursor after a widget was added to a specific rectangle /// Advance cursor after a widget was added to a specific rectangle

View file

@ -625,7 +625,7 @@ impl Ui {
/// } /// }
/// ///
/// if scroll_bottom { /// if scroll_bottom {
/// ui.scroll_to_cursor(Align::bottom()); /// ui.scroll_to_cursor(Align::BOTTOM);
/// } /// }
/// }); /// });
/// ``` /// ```
@ -1223,7 +1223,7 @@ impl Ui {
pos2(pos.x + column_width, self.max_rect().right_bottom().y), pos2(pos.x + column_width, self.max_rect().right_bottom().y),
); );
let mut column_ui = let mut column_ui =
self.child_ui(child_rect, Layout::top_down_justified(Align::left())); self.child_ui(child_rect, Layout::top_down_justified(Align::LEFT));
column_ui.set_width(column_width); column_ui.set_width(column_width);
column_ui column_ui
}) })

View file

@ -90,7 +90,7 @@ impl super::View for Scrolling {
let (current_scroll, max_scroll) = scroll_area.show(ui, |ui| { let (current_scroll, max_scroll) = scroll_area.show(ui, |ui| {
if scroll_top { if scroll_top {
ui.scroll_to_cursor(Align::top()); ui.scroll_to_cursor(Align::TOP);
} }
ui.vertical(|ui| { ui.vertical(|ui| {
for item in 1..=50 { for item in 1..=50 {
@ -104,7 +104,7 @@ impl super::View for Scrolling {
}); });
if scroll_bottom { if scroll_bottom {
ui.scroll_to_cursor(Align::bottom()); ui.scroll_to_cursor(Align::BOTTOM);
} }
let margin = ui.visuals().clip_rect_margin; let margin = ui.visuals().clip_rect_margin;

View file

@ -19,20 +19,29 @@ pub enum Align {
impl Align { impl Align {
/// Convenience for [`Self::Min`] /// Convenience for [`Self::Min`]
pub fn left() -> Self { pub const LEFT: Self = Self::Min;
Self::Min
}
/// Convenience for [`Self::Max`] /// Convenience for [`Self::Max`]
pub fn right() -> Self { pub const RIGHT: Self = Self::Max;
Self::Max
}
/// Convenience for [`Self::Min`] /// Convenience for [`Self::Min`]
pub fn top() -> Self { pub const TOP: Self = Self::Min;
Self::Min
}
/// Convenience for [`Self::Max`] /// Convenience for [`Self::Max`]
pub const BOTTOM: Self = Self::Max;
#[deprecated = "Use Self::LEFT"]
pub fn left() -> Self {
Self::LEFT
}
#[deprecated = "Use Self::RIGHT"]
pub fn right() -> Self {
Self::RIGHT
}
#[deprecated = "Use Self::TOP"]
pub fn top() -> Self {
Self::TOP
}
#[deprecated = "Use Self::BOTTOM"]
pub fn bottom() -> Self { pub fn bottom() -> Self {
Self::Max Self::BOTTOM
} }
/// Convert `Min => 0.0`, `Center => 0.5` or `Max => 1.0`. /// Convert `Min => 0.0`, `Center => 0.5` or `Max => 1.0`.

View file

@ -82,8 +82,11 @@ impl Pos2 {
/// The zero position, the origin. /// The zero position, the origin.
/// The top left corner in a GUI. /// The top left corner in a GUI.
/// Same as `Pos2::default()`. /// Same as `Pos2::default()`.
pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
#[deprecated = "Use Pos2::ZERO instead"]
pub const fn zero() -> Self { pub const fn zero() -> Self {
Self { x: 0.0, y: 0.0 } Self::ZERO
} }
pub const fn new(x: f32, y: f32) -> Self { pub const fn new(x: f32, y: f32) -> Self {

View file

@ -1,3 +1,4 @@
use std::f32::INFINITY;
use std::ops::RangeInclusive; use std::ops::RangeInclusive;
use crate::*; use crate::*;
@ -13,7 +14,37 @@ pub struct Rect {
} }
impl Rect { impl Rect {
/// Infinite rectangle that contains everything /// Infinite rectangle that contains everything.
pub const EVERYTHING: Self = Self {
min: pos2(-INFINITY, -INFINITY),
max: pos2(INFINITY, INFINITY),
};
/// The inverse of [`Self::EVERYTHING`]: streches from positive infinity to negative infinity.
/// Contains no points.
///
/// This is useful as the seed for boulding bounding boxes.
///
/// # Example:
/// ```
/// # use emath::*;
/// let mut rect = Rect::NOTHING;
/// rect.extend_with(pos2(2.0, 1.0));
/// rect.extend_with(pos2(0.0, 3.0));
/// assert_eq!(rect, Rect::from_min_max(pos2(0.0, 1.0), pos2(2.0, 3.0)))
/// ```
pub const NOTHING: Self = Self {
min: pos2(INFINITY, INFINITY),
max: pos2(-INFINITY, -INFINITY),
};
/// An invalid `Rect` filled with [`f32::NAN`];
pub const NAN: Self = Self {
min: pos2(f32::NAN, f32::NAN),
max: pos2(-f32::NAN, -f32::NAN),
};
#[deprecated = "Use Rect::EVERYTHING"]
pub fn everything() -> Self { pub fn everything() -> Self {
let inf = f32::INFINITY; let inf = f32::INFINITY;
Self { Self {
@ -22,6 +53,7 @@ impl Rect {
} }
} }
#[deprecated = "Use Rect::NOTHING"]
pub fn nothing() -> Self { pub fn nothing() -> Self {
let inf = f32::INFINITY; let inf = f32::INFINITY;
Self { Self {
@ -30,15 +62,12 @@ impl Rect {
} }
} }
/// invalid, NAN filled Rect. #[deprecated = "Use Rect::NAN"]
pub fn invalid() -> Self { pub fn invalid() -> Self {
Self { Self::NAN
min: pos2(f32::NAN, f32::NAN),
max: pos2(f32::NAN, f32::NAN),
}
} }
pub fn from_min_max(min: Pos2, max: Pos2) -> Self { pub const fn from_min_max(min: Pos2, max: Pos2) -> Self {
Rect { min, max } Rect { min, max }
} }

View file

@ -28,8 +28,12 @@ impl Default for Rot2 {
} }
impl Rot2 { impl Rot2 {
/// The identity rotation: nothing rotates
pub const IDENTITY: Self = Self { s: 0.0, c: 1.0 };
#[deprecated = "Use Rot2::IDENTITY"]
pub fn identity() -> Self { pub fn identity() -> Self {
Self { s: 0.0, c: 1.0 } Self::IDENTITY
} }
/// A 𝞃/4 = 90° rotation means rotating the X axis to the Y axis. /// A 𝞃/4 = 90° rotation means rotating the X axis to the Y axis.

View file

@ -81,23 +81,25 @@ impl Vec2 {
pub const X: Vec2 = Vec2 { x: 1.0, y: 0.0 }; pub const X: Vec2 = Vec2 { x: 1.0, y: 0.0 };
pub const Y: Vec2 = Vec2 { x: 0.0, y: 1.0 }; pub const Y: Vec2 = Vec2 { x: 0.0, y: 1.0 };
pub const ZERO: Self = Self { x: 0.0, y: 0.0 };
pub const INFINITY: Self = Self::splat(f32::INFINITY);
#[deprecated = "Use Vec2::ZERO instead"]
pub fn zero() -> Self { pub fn zero() -> Self {
Self { x: 0.0, y: 0.0 } Self::ZERO
} }
#[deprecated = "Use Vec2::INFINITY instead"]
pub fn infinity() -> Self { pub fn infinity() -> Self {
Self { Self::INFINITY
x: f32::INFINITY,
y: f32::INFINITY,
}
} }
pub fn new(x: f32, y: f32) -> Self { pub const fn new(x: f32, y: f32) -> Self {
Self { x, y } Self { x, y }
} }
pub fn splat(v: impl Into<f32>) -> Self { /// Set both `x` and `y` to the same value.
let v: f32 = v.into(); pub const fn splat(v: f32) -> Self {
Self { x: v, y: v } Self { x: v, y: v }
} }

View file

@ -81,9 +81,9 @@ impl Path {
let mut n1 = (points[i + 1] - points[i]).normalized().rot90(); let mut n1 = (points[i + 1] - points[i]).normalized().rot90();
// Handle duplicated points (but not triplicated...): // Handle duplicated points (but not triplicated...):
if n0 == Vec2::zero() { if n0 == Vec2::ZERO {
n0 = n1; n0 = n1;
} else if n1 == Vec2::zero() { } else if n1 == Vec2::ZERO {
n1 = n0; n1 = n0;
} }
@ -121,9 +121,9 @@ impl Path {
let mut n1 = (points[(i + 1) % n] - points[i]).normalized().rot90(); let mut n1 = (points[(i + 1) % n] - points[i]).normalized().rot90();
// Handle duplicated points (but not triplicated...): // Handle duplicated points (but not triplicated...):
if n0 == Vec2::zero() { if n0 == Vec2::ZERO {
n0 = n1; n0 = n1;
} else if n1 == Vec2::zero() { } else if n1 == Vec2::ZERO {
n1 = n0; n1 = n0;
} }
@ -461,7 +461,7 @@ impl Tessellator {
pub fn from_options(options: TessellationOptions) -> Self { pub fn from_options(options: TessellationOptions) -> Self {
Self { Self {
options, options,
clip_rect: Rect::everything(), clip_rect: Rect::EVERYTHING,
scratchpad_points: Default::default(), scratchpad_points: Default::default(),
scratchpad_path: Default::default(), scratchpad_path: Default::default(),
} }
@ -744,7 +744,7 @@ pub fn tessellate_shapes(
if options.debug_paint_clip_rects { if options.debug_paint_clip_rects {
for ClippedMesh(clip_rect, mesh) in &mut clipped_meshes { for ClippedMesh(clip_rect, mesh) in &mut clipped_meshes {
tessellator.clip_rect = Rect::everything(); tessellator.clip_rect = Rect::EVERYTHING;
tessellator.tessellate_shape( tessellator.tessellate_shape(
fonts, fonts,
Shape::Rect { Shape::Rect {
@ -760,7 +760,7 @@ pub fn tessellate_shapes(
if options.debug_ignore_clip_rects { if options.debug_ignore_clip_rects {
for ClippedMesh(clip_rect, _) in &mut clipped_meshes { for ClippedMesh(clip_rect, _) in &mut clipped_meshes {
*clip_rect = Rect::everything(); *clip_rect = Rect::EVERYTHING;
} }
} }