8000 Fix tooltips sometimes changing position each frame by emilk · Pull Request #7304 · emilk/egui · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
8000

Fix tooltips sometimes changing position each frame #7304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 7, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/egui/src/containers/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,7 @@ impl<'a> Popup<'a> {
self.gap,
expected_popup_size,
)
.unwrap_or_default()
}

/// Show the popup.
Expand Down
8 changes: 7 additions & 1 deletion crates/emath/src/align.rs
8000
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl Align {
// ----------------------------------------------------------------------------

/// Two-dimension alignment, e.g. [`Align2::LEFT_TOP`].
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Align2(pub [Align; 2]);

Expand Down Expand Up @@ -298,3 +298,9 @@ impl std::ops::IndexMut<usize> for Align2 {
pub fn center_size_in_rect(size: Vec2, frame: Rect) -> Rect {
Align2::CENTER_CENTER.align_size_within_rect(size, frame)
}

impl std::fmt::Debug for Align2 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Align2({:?}, {:?})", self.x(), self.y())
}
}
55 changes: 22 additions & 33 deletions crates/emath/src/rect_align.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use crate::{Align2, Pos2, Rect, Vec2};
///
/// There are helper constants for the 12 common menu positions:
/// ```text
/// ┌───────────┐ ┌────────┐ ┌─────────┐
/// │ TOP_START │ │ TOP │ │ TOP_END │
/// └───────────┘ └────────┘ └─────────┘
/// ┌───────────┐ ┌────────┐ ┌─────────┐
/// │ TOP_START │ │ TOP │ │ TOP_END │
/// └───────────┘ └────────┘ └─────────┘
/// ┌──────────┐ ┌────────────────────────────────────┐ ┌───────────┐
/// │LEFT_START│ │ │ │RIGHT_START│
/// └──────────┘ │ │ └───────────┘
Expand All @@ -19,9 +19,9 @@ use crate::{Align2, Pos2, Rect, Vec2};
/// ┌──────────┐ │ │ ┌───────────┐
/// │ LEFT_END │ │ │ │ RIGHT_END │
/// └──────────┘ └────────────────────────────────────┘ └───────────┘
/// ┌────────────┐ ┌──────┐ ┌──────────┐
/// │BOTTOM_START│ │BOTTOM│ │BOTTOM_END│
/// └────────────┘ └──────┘ └──────────┘
/// ┌────────────┐ ┌──────┐ ┌──────────┐
/// │BOTTOM_START│ │BOTTOM│ │BOTTOM_END│
/// └────────────┘ └──────┘ └──────────┘
/// ```
// There is no `new` function on purpose, since writing out `parent` and `child` is more
// reasonable.
Expand Down Expand Up @@ -235,45 +235,34 @@ impl RectAlign {
[self.flip_x(), self.flip_y(), self.flip()]
}

/// Look for the [`RectAlign`] that fits best in the available space.
/// Look for the first alternative [`RectAlign`] that allows the child rect to fit
/// inside the `screen_rect`.
///
/// If no alternative fits, the first is returned.
/// If no alternatives are given, `None` is returned.
///
/// See also:
/// - [`RectAlign::symmetries`] to calculate alternatives
/// - [`RectAlign::MENU_ALIGNS`] for the 12 common menu positions
pub fn find_best_align(
mut values_to_try: impl Iterator<Item = Self>,
available_space: Rect,
values_to_try: impl Iterator<Item = Self>,
screen_rect: Rect,
parent_rect: Rect,
gap: f32,
size: Vec2,
) -> Self {
let area = size.x * size.y;

let blocked_area = |pos: Self| {
let rect = pos.align_rect(&parent_rect, size, gap);
area - available_space.intersect(rect).area()
};
expected_size: Vec2,
) -> Option<Self> {
let mut first_choice = None;

let first = values_to_try.next().unwrap_or_default();

if blocked_area(first) == 0.0 {
return first;
}
for align in values_to_try {
first_choice = first_choice.or(Some(align)); // Remember the first alternative

let mut best_area = blocked_area(first);
let mut best = first;
let suggested_popup_rect = align.align_rect(&parent_rect, expected_size, gap);

for align in values_to_try {
let blocked = blocked_area(align);
if blocked == 0.0 {
return align;
}
if blocked < best_area {
best = align;
best_area = blocked;
if screen_rect.contains_rect(suggested_popup_rect) {
return Some(align);
}
}

best
first_choice
}
}
Loading
0