Double use of widget ID with context menu on draggable area
Describe the bug
I have an Area that is moveable by dragging it, and has a context menu. As soon as it's moved from the starting position, I get a big "Double use of widget ID" warning. This might very well be me doing something wrong, but I don't see what or how I can avoid it. The ID it's complaining about is not the ID of the area, but the ID of the response.
To Reproduce
use eframe::egui::{self, Area, Color32, Frame, Id, Pos2, Vec2};
fn main() -> eframe::Result {
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]),
..Default::default()
};
let mut pos = Pos2::new(40., 40.);
eframe::run_simple_native("My egui App", options, move |ctx, _frame| {
egui::CentralPanel::default().show(ctx, |ui| {
let area = Area::new(Id::new("area"));
let area_response = area.current_pos(pos).show(ui.ctx(), |ui| {
let frame = Frame::default().fill(Color32::from_rgb(70, 70, 70)); // The frame is just to see better, it's not necessary to reproduce the problem
frame.show(ui, |ui| {
ui.allocate_space(Vec2::new(100., 100.));
});
});
if area_response.response.dragged() {
let delta = ui.ctx().input(|i| i.pointer.delta());
pos[0] += delta.x;
pos[1] += delta.y;
}
area_response.response.context_menu(|_ui| {});
});
})
}
Click and drag the gray area a bit.
Expected behavior No warning.
Screenshots
Desktop (please complete the following information):
OS: Linux. Reproduced under egui 2dac4a4f (current master).
I'm not sure why it tries to use the same ID in this case, as the code that handles that is fairly complex and changing all the time, but for the record you can avoid this problem by putting the context menu inside the Area's UI:
use eframe::egui::{self, Area, Color32, Id, Pos2, Sense};
fn main() -> eframe::Result {
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([320.0, 240.0]),
..Default::default()
};
let mut pos = Pos2::new(40., 40.);
eframe::run_simple_native("My egui App", options, move |ctx, _frame| {
egui::CentralPanel::default().show(ctx, |ui| {
let area = Area::new(Id::new("area"));
let area_response = area
.current_pos(pos)
.show(ui.ctx(), |ui| {
ui.allocate_response([100.0; 2].into(), Sense::hover())
.context_menu(|ui| {
ui.menu_button("Menu", |ui| {
ui.button("Button1");
ui.button("Button2");
});
});
ui.painter().rect_filled(ui.min_rect(), 0.0, Color32::RED);
})
.response;
if area_response.dragged() {
pos += area_response.drag_delta();
}
});
})
}
https://github.com/user-attachments/assets/1f756b7c-059d-4c21-bf1d-18ac22293e47
That works, thanks!