Give each menu `Area` an id distinct from the id of what was clicked (#4114)
* Closes https://github.com/emilk/egui/issues/4113 Previously the `Id` of the menu `Area` was using the same id as the thing that was clicked (i.e. the button opening menu), which lead to id clashes
This commit is contained in:
parent
e8af6f38fc
commit
86d7f296ae
|
|
@ -39,13 +39,14 @@ impl BarState {
|
|||
}
|
||||
|
||||
/// Show a menu at pointer if primary-clicked response.
|
||||
///
|
||||
/// Should be called from [`Context`] on a [`Response`]
|
||||
pub fn bar_menu<R>(
|
||||
&mut self,
|
||||
response: &Response,
|
||||
add_contents: impl FnOnce(&mut Ui) -> R,
|
||||
) -> Option<InnerResponse<R>> {
|
||||
MenuRoot::stationary_click_interaction(response, &mut self.open_menu, response.id);
|
||||
MenuRoot::stationary_click_interaction(response, &mut self.open_menu);
|
||||
self.open_menu.show(response, add_contents)
|
||||
}
|
||||
|
||||
|
|
@ -134,7 +135,7 @@ pub(crate) fn submenu_button<R>(
|
|||
/// wrapper for the contents of every menu.
|
||||
pub(crate) fn menu_ui<'c, R>(
|
||||
ctx: &Context,
|
||||
menu_id: impl Into<Id>,
|
||||
menu_id: Id,
|
||||
menu_state_arc: &Arc<RwLock<MenuState>>,
|
||||
add_contents: impl FnOnce(&mut Ui) -> R + 'c,
|
||||
) -> InnerResponse<R> {
|
||||
|
|
@ -144,7 +145,7 @@ pub(crate) fn menu_ui<'c, R>(
|
|||
menu_state.rect.min
|
||||
};
|
||||
|
||||
let area = Area::new(menu_id)
|
||||
let area = Area::new(menu_id.with("__menu"))
|
||||
.order(Order::Foreground)
|
||||
.fixed_pos(pos)
|
||||
.constrain_to(ctx.screen_rect())
|
||||
|
|
@ -222,7 +223,7 @@ pub(crate) fn context_menu(
|
|||
let menu_id = Id::new(CONTEXT_MENU_ID_STR);
|
||||
let mut bar_state = BarState::load(&response.ctx, menu_id);
|
||||
|
||||
MenuRoot::context_click_interaction(response, &mut bar_state, response.id);
|
||||
MenuRoot::context_click_interaction(response, &mut bar_state);
|
||||
let inner_response = bar_state.show(response, add_contents);
|
||||
|
||||
bar_state.store(&response.ctx, menu_id);
|
||||
|
|
@ -237,6 +238,7 @@ pub(crate) struct MenuRootManager {
|
|||
|
||||
impl MenuRootManager {
|
||||
/// Show a menu at pointer if right-clicked response.
|
||||
///
|
||||
/// Should be called from [`Context`] on a [`Response`]
|
||||
pub fn show<R>(
|
||||
&mut self,
|
||||
|
|
@ -308,11 +310,9 @@ impl MenuRoot {
|
|||
/// Interaction with a stationary menu, i.e. fixed in another Ui.
|
||||
///
|
||||
/// Responds to primary clicks.
|
||||
fn stationary_interaction(
|
||||
response: &Response,
|
||||
root: &mut MenuRootManager,
|
||||
id: Id,
|
||||
) -> MenuResponse {
|
||||
fn stationary_interaction(response: &Response, root: &mut MenuRootManager) -> MenuResponse {
|
||||
let id = response.id;
|
||||
|
||||
if (response.clicked() && root.is_menu_open(id))
|
||||
|| response.ctx.input(|i| i.key_pressed(Key::Escape))
|
||||
{
|
||||
|
|
@ -357,8 +357,8 @@ impl MenuRoot {
|
|||
MenuResponse::Stay
|
||||
}
|
||||
|
||||
/// Interaction with a context menu (secondary clicks).
|
||||
fn context_interaction(response: &Response, root: &mut Option<Self>, id: Id) -> MenuResponse {
|
||||
/// Interaction with a context menu (secondary click).
|
||||
fn context_interaction(response: &Response, root: &mut Option<Self>) -> MenuResponse {
|
||||
let response = response.interact(Sense::click());
|
||||
response.ctx.input(|input| {
|
||||
let pointer = &input.pointer;
|
||||
|
|
@ -371,7 +371,7 @@ impl MenuRoot {
|
|||
}
|
||||
if !in_old_menu {
|
||||
if response.hovered() && response.secondary_clicked() {
|
||||
return MenuResponse::Create(pos, id);
|
||||
return MenuResponse::Create(pos, response.id);
|
||||
} else if (response.hovered() && pointer.primary_down()) || destroy {
|
||||
return MenuResponse::Close;
|
||||
}
|
||||
|
|
@ -392,14 +392,14 @@ impl MenuRoot {
|
|||
}
|
||||
|
||||
/// Respond to secondary (right) clicks.
|
||||
pub fn context_click_interaction(response: &Response, root: &mut MenuRootManager, id: Id) {
|
||||
let menu_response = Self::context_interaction(response, root, id);
|
||||
pub fn context_click_interaction(response: &Response, root: &mut MenuRootManager) {
|
||||
let menu_response = Self::context_interaction(response, root);
|
||||
Self::handle_menu_response(root, menu_response);
|
||||
}
|
||||
|
||||
// Responds to primary clicks.
|
||||
pub fn stationary_click_interaction(response: &Response, root: &mut MenuRootManager, id: Id) {
|
||||
let menu_response = Self::stationary_interaction(response, root, id);
|
||||
pub fn stationary_click_interaction(response: &Response, root: &mut MenuRootManager) {
|
||||
let menu_response = Self::stationary_interaction(response, root);
|
||||
Self::handle_menu_response(root, menu_response);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -105,17 +105,17 @@ impl WidgetRects {
|
|||
// e.g. calling `response.interact(…)` to add more interaction.
|
||||
let (idx_in_layer, existing) = entry.get_mut();
|
||||
|
||||
egui_assert!(
|
||||
existing.layer_id == widget_rect.layer_id,
|
||||
"Widget changed layer_id during the frame"
|
||||
);
|
||||
|
||||
// Update it:
|
||||
existing.rect = widget_rect.rect; // last wins
|
||||
existing.interact_rect = widget_rect.interact_rect; // last wins
|
||||
existing.sense |= widget_rect.sense;
|
||||
existing.enabled |= widget_rect.enabled;
|
||||
|
||||
egui_assert!(
|
||||
existing.layer_id == widget_rect.layer_id,
|
||||
"Widget changed layer_id during the frame"
|
||||
);
|
||||
|
||||
if existing.layer_id == widget_rect.layer_id {
|
||||
layer_widgets[*idx_in_layer] = *existing;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue