Skip to content

Commit 82df857

Browse files
committed
Keep track of submenu index in parent context menu
this improves the Id's generated for submenus, as they will depend on the index in their parent, rather than their position. This avoids recreating an Id for the same conceptual submenu, only drawn at a different position.
1 parent 648dc33 commit 82df857

File tree

1 file changed

+21
-10
lines changed

1 file changed

+21
-10
lines changed

egui/src/context_menu.rs

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,16 @@ pub struct MenuEntry {
144144
text: String,
145145
icon: String,
146146
state: EntryState,
147+
index: usize,
147148
}
148149
impl MenuEntry {
149150
#[allow(clippy::needless_pass_by_value)]
150-
fn new(text: impl ToString, icon: impl ToString, state: EntryState) -> Self {
151+
fn new(text: impl ToString, icon: impl ToString, state: EntryState, index: usize) -> Self {
151152
Self {
152153
text: text.to_string(),
153154
icon: icon.to_string(),
154155
state,
156+
index,
155157
}
156158
}
157159
#[allow(clippy::needless_pass_by_value)]
@@ -167,7 +169,8 @@ impl MenuEntry {
167169
let MenuEntry {
168170
text,
169171
icon,
170-
state
172+
state,
173+
..
171174
} = self;
172175

173176
let text_style = TextStyle::Button;
@@ -223,14 +226,14 @@ pub struct SubMenu<'a> {
223226
}
224227
impl<'a> SubMenu<'a> {
225228
#[allow(clippy::needless_pass_by_value)]
226-
fn new(text: impl ToString, parent_state: &'a mut MenuState) -> Self {
229+
fn new(text: impl ToString, parent_state: &'a mut MenuState, index: usize) -> Self {
227230
Self {
228-
entry: MenuEntry::new(text, "⏵", EntryState::Active),
231+
entry: MenuEntry::new(text, "⏵", EntryState::Active, index),
229232
parent_state,
230233
}
231234
}
232235
pub fn show(self, ui: &mut Ui, add_contents: impl FnOnce(&mut Ui, &mut MenuState)) -> Response {
233-
let sub_id = ui.id().with(format!("{:?}", ui.placer.cursor().min));
236+
let sub_id = ui.id().with(self.entry.index);
234237
let button = self.entry.show_with_state(ui, EntryState::submenu(self.parent_state, sub_id));
235238
self.parent_state
236239
.submenu_button_interaction(ui, sub_id, &button);
@@ -244,29 +247,36 @@ pub struct MenuState {
244247
sub_menu: Option<(Id, Box<MenuState>)>,
245248
rect: Rect,
246249
response: MenuResponse,
250+
entry_count: usize,
247251
}
248252
impl MenuState {
249253
/// close menu hierarchy
250254
pub fn close(&mut self) {
251255
self.response = MenuResponse::Close;
252256
}
253257
/// create a menu item
254-
pub fn item(&self, text: impl ToString) -> MenuEntry {
255-
MenuEntry::new(text, "", EntryState::entry(self))
258+
pub fn item(&mut self, text: impl ToString) -> MenuEntry {
259+
MenuEntry::new(text, "", EntryState::entry(self), self.next_entry_index())
256260
}
257261
/// create a menu item with an icon
258-
pub fn item_with_icon(&self, text: impl ToString, icon: impl ToString) -> MenuEntry {
259-
MenuEntry::new(text, icon, EntryState::entry(self))
262+
pub fn item_with_icon(&mut self, text: impl ToString, icon: impl ToString) -> MenuEntry {
263+
MenuEntry::new(text, icon, EntryState::entry(self), self.next_entry_index())
264+
}
265+
fn next_entry_index(&mut self) -> usize {
266+
self.entry_count += 1;
267+
self.entry_count-1
260268
}
261269
/// create a sub-menu
262270
pub fn submenu(&'_ mut self, text: impl ToString) -> SubMenu<'_> {
263-
SubMenu::new(text, self)
271+
let index = self.next_entry_index();
272+
SubMenu::new(text, self, index)
264273
}
265274
fn new(position: Pos2) -> Self {
266275
Self {
267276
rect: Rect::from_min_size(position, Vec2::ZERO),
268277
sub_menu: None,
269278
response: MenuResponse::Stay,
279+
entry_count: 0,
270280
}
271281
}
272282
/// sense button interaction opening and closing submenu
@@ -303,6 +313,7 @@ impl MenuState {
303313
id: Id,
304314
add_contents: impl FnOnce(&mut Ui, &mut MenuState),
305315
) -> Response {
316+
self.entry_count = 0;
306317
crate::menu::menu_ui(
307318
ctx,
308319
id,

0 commit comments

Comments
 (0)