emilk / emilk/egui

Ability to pass data / control state of `context_menu`

Open
#4,162 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Rust
Stars
30.6k
Forks
2.1k
Avg merge
1d 9h
Merged PRs (30d)
72

Description

Current API relied on response.rect. When we want to show menu, we associate it with response, e.g. menu call `context_interaction` to get menu events(create, close, stay) **internally**. All this stuff is private and couldnt be accessed outside egui.

This behavior dont work if we want to track entity user clicked inside response.rect in our own.

When I have `map, diagram, timeline` - **there is no way to know exact point was clicked on menu creation**.

I have my own fork with workaround inside:
It is `context_menu` function

```
let menu_response = egui::menu::MenuRoot::context_interaction(response, root, id);
```
added code is here. we just inject some `inter-frame-object`
```
let my_state = match &menu_response {
egui::menu::MenuResponse::Create(_, _) => {
my_state.store()
}
_ => MyState::load()
};

```
and pass `my_state` to the render function
```
bar_state.show(response, |ui| my_context_menu_render(ui, my_state));
```

But it requires **a lot** of doing `pub(crate) -> pub` replacements.

Then I forked `menu.rs`, but it couldnt work because `ui.set_menu_state` is private as well.

1. So my naive API, just to check out the idea, may be something like:
```
response
.menu_clicked(|my_state, menu_response|
if menu_response == 'create'{ my_state = row_id}
if menu_response == 'close'{ clean_resources() }
true
)
.show_menu(|ui, my_state| {...})
```
2. Much easier API would be
```
resp.context_menu(|ui, menu_handle|{
menu_handle. is_just_created() ?
menu_handle. some_handle_i_could_associate the data() ?
menu_handle. is_about_to_close() ?
})
```
Btw, looks like currently we have `ui.close_menu()` as this `menu_handle` germ.

3. Probably, simplest and most useful API would to just make `ui.menu_state.response` public.

so I could do
```
resp.context_menu(|ui|{
if ui.menu_state.response == 'create'{
memory.save_my_data()
}
})
```

(but currently show is earlier that setting the response)

4. Make `context_menu` and all related stuff `public` to allow everybody inline it on his own function and add some logic. Current implementation is very easy to do this, except private visibility.

personally I like №4

PS: `MenuResponse::Create(**pos**, id)` is not enough, because map could be scrolled after menu was created. we need ability to user make his own associated data.

Contributor guide

Open the contributing guide

Research direction

Start by reading the context_menu function and menu.rs, especially MenuRoot::context_interaction, MenuResponse, and ui.set_menu_state. Compare the proposed callback, menu-handle, public menu_state.response, and public-API approaches with the current lifecycle. Done means an agreed API lets callers associate their own data with menu creation and observe relevant menu events without maintaining a fork.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.