Skip to content

Commit

Permalink
Fix: Menu popups and tooltips don't respect layer transforms (emilk#4708
Browse files Browse the repository at this point in the history
)

The menu buttons, combo box menus, and tooltips don't take layer
transforms into account when placing their popups, resulting in popups
being placed in the wrong location.

This PR makes the popups take layer transforms into account,
transforming the positions before displaying them on screen. I
implemented this fix for menu buttons, combo boxes, and tooltips; let me
know if there's anything I missed.
Scaling of the popups is purposefully ignored for now. Personally, I
think popup scaling isn't necessary but if it is required I can
implement it (also it would require doing more invasive things to the
code and I want to keep this as simple as possible.)

Before the fix: (with a modified version of the "Pan Zoom" web demo)
<video
src=https://github.com/emilk/egui/assets/104604363/a2d79757-c410-4815-8159-b64d6bd668ee>

After:
<video
src=https://github.com/emilk/egui/assets/104604363/48f8b1d1-d30f-44bf-961f-f10b85964a92>

The frame delay seems to be unavoidable unless we can move the popups
_after_ the layer transform is set (or apply the transforms to the popup
during painting). I think this would be better implemented once the
menu/popup/tooltip unification is done (emilk#4669).
  • Loading branch information
Creative0708 authored and hacknus committed Oct 30, 2024
1 parent db3a181 commit bc01619
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
8 changes: 7 additions & 1 deletion crates/egui/src/containers/popup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,10 +302,16 @@ pub fn popup_above_or_below_widget<R>(
add_contents: impl FnOnce(&mut Ui) -> R,
) -> Option<R> {
if parent_ui.memory(|mem| mem.is_popup_open(popup_id)) {
let (pos, pivot) = match above_or_below {
let (mut pos, pivot) = match above_or_below {
AboveOrBelow::Above => (widget_response.rect.left_top(), Align2::LEFT_BOTTOM),
AboveOrBelow::Below => (widget_response.rect.left_bottom(), Align2::LEFT_TOP),
};
if let Some(transform) = parent_ui
.ctx()
.memory(|m| m.layer_transforms.get(&parent_ui.layer_id()).copied())
{
pos = transform * pos;
}

let frame = Frame::popup(parent_ui.style());
let frame_margin = frame.total_margin();
Expand Down
7 changes: 7 additions & 0 deletions crates/egui/src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,13 @@ impl MenuRoot {
}
}

if let Some(transform) = button
.ctx
.memory(|m| m.layer_transforms.get(&button.layer_id).copied())
{
pos = transform * pos;
}

return MenuResponse::Create(pos, id);
} else if button
.ctx
Expand Down
9 changes: 8 additions & 1 deletion crates/egui/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,14 @@ impl Response {
///
/// This can be used to give attention to a widget during a tutorial.
pub fn show_tooltip_ui(&self, add_contents: impl FnOnce(&mut Ui)) {
crate::containers::show_tooltip_for(&self.ctx, self.id, &self.rect, add_contents);
let mut rect = self.rect;
if let Some(transform) = self
.ctx
.memory(|m| m.layer_transforms.get(&self.layer_id).copied())
{
rect = transform * rect;
}
crate::containers::show_tooltip_for(&self.ctx, self.id, &rect, add_contents);
}

/// Always show this tooltip, even if disabled and the user isn't hovering it.
Expand Down

0 comments on commit bc01619

Please sign in to comment.