From 86d1c0e40ae3510e2085dfda74398e2fa61a673e Mon Sep 17 00:00:00 2001 From: lucasmerlin Date: Wed, 9 Jul 2025 14:55:13 +0200 Subject: [PATCH] Implement `BitOr` and `BitOrAssign` for `Rect` --- crates/egui/src/containers/area.rs | 2 +- crates/egui/src/containers/tooltip.rs | 2 +- crates/egui/src/debug_text.rs | 4 ++-- crates/egui/src/layout.rs | 4 ++-- crates/egui/src/pass_state.rs | 10 +++++----- .../src/text_selection/label_text_selection.rs | 2 +- crates/egui_demo_lib/src/demo/scrolling.rs | 2 +- crates/emath/src/rect.rs | 17 +++++++++++++++++ crates/epaint/src/shapes/shape.rs | 2 +- crates/epaint/src/text/text_layout.rs | 2 +- 10 files changed, 32 insertions(+), 15 deletions(-) diff --git a/crates/egui/src/containers/area.rs b/crates/egui/src/containers/area.rs index 5ae4a4b30..d3d2a7228 100644 --- a/crates/egui/src/containers/area.rs +++ b/crates/egui/src/containers/area.rs @@ -705,7 +705,7 @@ fn automatic_area_position(ctx: &Context, layer_id: LayerId) -> Pos2 { let current_column_bb = column_bbs.last_mut().unwrap(); if rect.left() < current_column_bb.right() { // same column - *current_column_bb = current_column_bb.union(rect); + *current_column_bb |= rect; } else { // new column column_bbs.push(rect); diff --git a/crates/egui/src/containers/tooltip.rs b/crates/egui/src/containers/tooltip.rs index 2060c61cf..99bc95d5c 100644 --- a/crates/egui/src/containers/tooltip.rs +++ b/crates/egui/src/containers/tooltip.rs @@ -163,7 +163,7 @@ impl Tooltip<'_> { // The popup might not be shown on at_pointer if there is no pointer. if let Some(response) = &response { state.tooltip_count += 1; - state.bounding_rect = state.bounding_rect.union(response.response.rect); + state.bounding_rect |= response.response.rect; response .response .ctx diff --git a/crates/egui/src/debug_text.rs b/crates/egui/src/debug_text.rs index f487e795f..2cd1a2755 100644 --- a/crates/egui/src/debug_text.rs +++ b/crates/egui/src/debug_text.rs @@ -102,7 +102,7 @@ impl State { let location_rect = Align2::RIGHT_TOP.anchor_size(pos - 4.0 * Vec2::X, location_galley.size()); painter.galley(location_rect.min, location_galley, color); - bounding_rect = bounding_rect.union(location_rect); + bounding_rect |= location_rect; } { @@ -117,7 +117,7 @@ impl State { ); let rect = Align2::LEFT_TOP.anchor_size(pos, galley.size()); painter.galley(rect.min, galley, color); - bounding_rect = bounding_rect.union(rect); + bounding_rect |= rect; } pos.y = bounding_rect.max.y + 4.0; diff --git a/crates/egui/src/layout.rs b/crates/egui/src/layout.rs index 3064d0d87..003476be6 100644 --- a/crates/egui/src/layout.rs +++ b/crates/egui/src/layout.rs @@ -50,8 +50,8 @@ pub(crate) struct Region { impl Region { /// Expand the `min_rect` and `max_rect` of this ui to include a child at the given rect. pub fn expand_to_include_rect(&mut self, rect: Rect) { - self.min_rect = self.min_rect.union(rect); - self.max_rect = self.max_rect.union(rect); + self.min_rect |= rect; + self.max_rect |= rect; } /// Ensure we are big enough to contain the given X-coordinate. diff --git a/crates/egui/src/pass_state.rs b/crates/egui/src/pass_state.rs index 079bb4eb0..ca0d15720 100644 --- a/crates/egui/src/pass_state.rs +++ b/crates/egui/src/pass_state.rs @@ -318,7 +318,7 @@ impl PassState { ); self.available_rect.min.x = panel_rect.max.x; self.unused_rect.min.x = panel_rect.max.x; - self.used_by_panels = self.used_by_panels.union(panel_rect); + self.used_by_panels |= panel_rect; } /// Shrink `available_rect`. @@ -329,7 +329,7 @@ impl PassState { ); self.available_rect.max.x = panel_rect.min.x; self.unused_rect.max.x = panel_rect.min.x; - self.used_by_panels = self.used_by_panels.union(panel_rect); + self.used_by_panels |= panel_rect; } /// Shrink `available_rect`. @@ -340,7 +340,7 @@ impl PassState { ); self.available_rect.min.y = panel_rect.max.y; self.unused_rect.min.y = panel_rect.max.y; - self.used_by_panels = self.used_by_panels.union(panel_rect); + self.used_by_panels |= panel_rect; } /// Shrink `available_rect`. @@ -351,13 +351,13 @@ impl PassState { ); self.available_rect.max.y = panel_rect.min.y; self.unused_rect.max.y = panel_rect.min.y; - self.used_by_panels = self.used_by_panels.union(panel_rect); + self.used_by_panels |= panel_rect; } pub(crate) fn allocate_central_panel(&mut self, panel_rect: Rect) { // Note: we do not shrink `available_rect`, because // we allow windows to cover the CentralPanel. 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 |= panel_rect; } } diff --git a/crates/egui/src/text_selection/label_text_selection.rs b/crates/egui/src/text_selection/label_text_selection.rs index ffbc7ae30..8297bc429 100644 --- a/crates/egui/src/text_selection/label_text_selection.rs +++ b/crates/egui/src/text_selection/label_text_selection.rs @@ -546,7 +546,7 @@ impl LabelSelectionState { if let Some(mut cursor_range) = cursor_state.range(galley) { let galley_rect = global_from_galley * Rect::from_min_size(Pos2::ZERO, galley.size()); - self.selection_bbox_this_frame = self.selection_bbox_this_frame.union(galley_rect); + self.selection_bbox_this_frame |= galley_rect; if let Some(selection) = &self.selection { if selection.primary.widget_id == response.id { diff --git a/crates/egui_demo_lib/src/demo/scrolling.rs b/crates/egui_demo_lib/src/demo/scrolling.rs index 3e4660d3d..ca3f6e90c 100644 --- a/crates/egui_demo_lib/src/demo/scrolling.rs +++ b/crates/egui_demo_lib/src/demo/scrolling.rs @@ -222,7 +222,7 @@ fn huge_content_painter(ui: &mut egui::Ui) { font_id.clone(), ui.visuals().text_color(), ); - used_rect = used_rect.union(text_rect); + used_rect |= text_rect; } ui.allocate_rect(used_rect, Sense::hover()); // make sure it is visible! diff --git a/crates/emath/src/rect.rs b/crates/emath/src/rect.rs index 8810fe361..089e81671 100644 --- a/crates/emath/src/rect.rs +++ b/crates/emath/src/rect.rs @@ -1,6 +1,7 @@ use std::fmt; use crate::{Div, Mul, NumExt as _, Pos2, Rangef, Rot2, Vec2, lerp, pos2, vec2}; +use std::ops::{BitOr, BitOrAssign}; /// A rectangular region of space. /// @@ -776,6 +777,22 @@ impl Div for Rect { } } +impl BitOr for Rect { + type Output = Self; + + #[inline] + fn bitor(self, other: Self) -> Self { + self.union(other) + } +} + +impl BitOrAssign for Rect { + #[inline] + fn bitor_assign(&mut self, other: Self) { + *self = self.union(other); + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/epaint/src/shapes/shape.rs b/crates/epaint/src/shapes/shape.rs index 080f1794b..3cdabeadc 100644 --- a/crates/epaint/src/shapes/shape.rs +++ b/crates/epaint/src/shapes/shape.rs @@ -363,7 +363,7 @@ impl Shape { Self::Vec(shapes) => { let mut rect = Rect::NOTHING; for shape in shapes { - rect = rect.union(shape.visual_bounding_rect()); + rect |= shape.visual_bounding_rect(); } rect } diff --git a/crates/epaint/src/text/text_layout.rs b/crates/epaint/src/text/text_layout.rs index 1e0565171..8581b067f 100644 --- a/crates/epaint/src/text/text_layout.rs +++ b/crates/epaint/src/text/text_layout.rs @@ -691,7 +691,7 @@ fn galley_from_rows( let mut num_indices = 0; for placed_row in &mut rows { - rect = rect.union(placed_row.rect()); + rect |= placed_row.rect(); let row = Arc::make_mut(&mut placed_row.row); row.visuals = tessellate_row(point_scale, &job, &format_summary, row);