Skip to content
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

⚠️ Improved menu based on egui::Popup #5716

Merged
merged 39 commits into from
Mar 3, 2025
Merged

Conversation

lucasmerlin
Copy link
Collaborator

@lucasmerlin lucasmerlin commented Feb 13, 2025

Continuation of #5713

Silently breaking changes:

  • Menus now close on click by default, this is configurable via PopupCloseBehavior

Additional additions:

  • Button::right_text
  • StyleModifier

This is a rewrite of the egui menus, with the following goals:

  • submenu buttons should work everywhere, in a popup, context menu, area, in some random Ui
  • remove the menu state from Ui
  • should work just like the previous menu
  • proper support for keyboard navigation
    • It's better now but requires further work to be perfect
  • support PopupCloseBehavior

Copy link

Preview available at https://egui-pr-preview.github.io/pr/5716-lucaspopup-based-menu
Note that it might take a couple seconds for the update to show up after the preview_build workflow has completed.

@lucasmerlin lucasmerlin marked this pull request as draft February 13, 2025 20:46
@lucasmerlin lucasmerlin force-pushed the lucas/popup-based-menu branch from e6cf98d to 0109e35 Compare February 18, 2025 15:09
@lucasmerlin lucasmerlin force-pushed the lucas/popup-based-menu branch from 0109e35 to b9c1a1f Compare February 19, 2025 17:21
@lucasmerlin lucasmerlin added feature New feature or request egui labels Feb 20, 2025
@lucasmerlin lucasmerlin changed the title Improved menu based on egui::Popup ⚠️ Improved menu based on egui::Popup Feb 20, 2025
# Conflicts:
#	crates/egui/src/containers/popup.rs
#	crates/egui/src/containers/window.rs
#	crates/egui/src/response.rs
#	crates/egui/src/ui.rs
#	crates/egui/src/ui_builder.rs
#	crates/egui_demo_lib/src/demo/context_menu.rs
#	crates/egui_demo_lib/src/demo/demo_app_windows.rs
#	crates/egui_demo_lib/src/demo/popups.rs
@@ -374,6 +374,7 @@ fn combo_box_dyn<'c, R>(

let inner = Popup::menu(&button_response)
.id(popup_id)
.style(None)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we set the menu styles for the ComboBox? I'm overwriting this here since this is how it was before, but I think the menu styles would look nice here

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question 🤔 If so I think we save it for another PR

Comment on lines +243 to +246
ui.hyperlink_to(
egui::RichText::new("🦋").size(font_size),
"https://bsky.app/profile/ernerfeldt.bsky.social",
);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like there is no butterfly in egui :(

Screenshot 2025-02-20 at 19 04 02

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You just have to wait for🐛...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought this would be a fun way to display the options, but it seems like the readability suffers a bit. Should I change it?

@emilk
Copy link
Owner

emilk commented Feb 21, 2025

Menus now close on click by default, this is configurable via PopupCloseBehavior

What happens if you also call ui.close(); (or the old ui.close_menu()) in a buttons on-click handler inside a menu? Does that close the egui::Window that the menu is in?

@lucasmerlin
Copy link
Collaborator Author

Add reset button to demo

@lucasmerlin
Copy link
Collaborator Author

Add some note that ui.close doesnt bubble up across areas

Copy link
Owner

@emilk emilk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the default behavior is CloseOnClick, then we can remove the calls to ui.close() from

fn file_menu_button(ui: &mut Ui) {
let organize_shortcut =
egui::KeyboardShortcut::new(Modifiers::CTRL | Modifiers::SHIFT, egui::Key::O);
let reset_shortcut =
egui::KeyboardShortcut::new(Modifiers::CTRL | Modifiers::SHIFT, egui::Key::R);
// NOTE: we must check the shortcuts OUTSIDE of the actual "File" menu,
// or else they would only be checked if the "File" menu was actually open!
if ui.input_mut(|i| i.consume_shortcut(&organize_shortcut)) {
ui.ctx().memory_mut(|mem| mem.reset_areas());
}
if ui.input_mut(|i| i.consume_shortcut(&reset_shortcut)) {
ui.ctx().memory_mut(|mem| *mem = Default::default());
}
ui.menu_button("File", |ui| {
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Extend);
// On the web the browser controls the zoom
#[cfg(not(target_arch = "wasm32"))]
{
egui::gui_zoom::zoom_menu_buttons(ui);
ui.weak(format!(
"Current zoom: {:.0}%",
100.0 * ui.ctx().zoom_factor()
))
.on_hover_text("The UI zoom level, on top of the operating system's default value");
ui.separator();
}
if ui
.add(
egui::Button::new("Organize Windows")
.shortcut_text(ui.ctx().format_shortcut(&organize_shortcut)),
)
.clicked()
{
ui.ctx().memory_mut(|mem| mem.reset_areas());
ui.close();
}
if ui
.add(
egui::Button::new("Reset egui memory")
.shortcut_text(ui.ctx().format_shortcut(&reset_shortcut)),
)
.on_hover_text("Forget scroll, positions, sizes etc")
.clicked()
{
ui.ctx().memory_mut(|mem| *mem = Default::default());
ui.close();
}
});
}

@@ -374,6 +374,7 @@ fn combo_box_dyn<'c, R>(

let inner = Popup::menu(&button_response)
.id(popup_id)
.style(None)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question 🤔 If so I think we save it for another PR

Comment on lines +193 to +195
/// Show some text on the right side of the button.
#[inline]
pub fn right_text(mut self, right_text: impl Into<WidgetText>) -> Self {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this was broken out to its own PR it would get its own entry in the changelog 🤷

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioned it in the PR description, hopefully that is enough to remember to add this to the changelog during the release

@lucasmerlin lucasmerlin force-pushed the lucas/popup-based-menu branch from 8c9b953 to a312478 Compare February 28, 2025 10:07
@crumblingstatue
Copy link
Contributor

⚠️ Breaking: This technically breaks popup dialogs nested inside menus, for example a color edit button
image

Since they use the same popup mechanism, and there can only be one popup, they will close the menu (and likely themselves in the process).

I don't know if this should be counted as a regression, or never supported in the first place, but a decision should be made regarding this, before merging this PR.

@lucasmerlin
Copy link
Collaborator Author

@crumblingstatue good catch. I want to support opening multiple/nested popups which should fix this. But I'll implement that in a separate PR, since this one is already so big.

@lucasmerlin lucasmerlin merged commit cd22517 into master Mar 3, 2025
46 checks passed
@lucasmerlin lucasmerlin deleted the lucas/popup-based-menu branch March 3, 2025 13:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
egui feature New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unify menus with tooltips/popups
4 participants