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

Toggling a CollapsingHeader in a ComboBox closes the whole ComboBox #335

Open
LeagueRaINi opened this issue Apr 25, 2021 · 10 comments
Open
Labels
design Some architectual design work needed

Comments

@LeagueRaINi
Copy link

LeagueRaINi commented Apr 25, 2021

Describe the bug
Putting a CollapsingHeader inside a ComboBox closes the ComboBox whenever you try to toggle the CollapsingHeader

To Reproduce
Steps to reproduce the behavior:

  1. Create a ComboBox
  2. Put a CollapsingHeader inside
  3. Toggle the CollapsingHeader
egui::ComboBox::from_label("Version")
    .width(150.0)
    .selected_text(selected_version)
    .show_ui(ui, |ui| {
        egui::CollapsingHeader::new("Dev")
            .default_open(true)
            .show(ui, |ui| {
                for version in versions.iter() {
                    ui.selectable_value(&mut selected_version, &version, *version);
                }
            });
    });

Expected behavior
The CollapsingHeader should be able to open/close without the ComboBox closing

Screenshots

System
OS: Windows10 20H2

@LeagueRaINi LeagueRaINi added the bug Something is broken label Apr 25, 2021
@vihdzp
Copy link
Contributor

vihdzp commented May 5, 2021

This also happens in menu bars, which is quite annoying to say the least.

@emilk emilk added design Some architectual design work needed and removed bug Something is broken labels May 8, 2021
@emilk
Copy link
Owner

emilk commented May 8, 2021

Clicking anything in a combobox closes it. Right now comboboxes are more like fold-out menus which are agnostic to their content. The most common contents is SelectableItem, i.e. a list of choices. When making a choice, the combo box closes because clicking anywhere closes the combobox.

So how do we fix it? We could not close the combobox when the user click inside of it, but that would also be annoying ("BUG: combo boxes don't close once I made a selection!").

So we want it to close when the user clicks some (most?) types of widgets, but not others (CollapsingHeader, maybe more?). But then how should that information be propagated within egui? Should some magic flag be set when a click is considered "significant"? seems a bit ugly :/

Perhaps comboboxes shouldn't be this general. Perhaps the user should provide a list of items, rather than providing an |ui| { … } content lambda. The advantage of that would be easily allowing things like filtering, and selection with arrows. The downside with that would be that one could not put collapsing headers within a combo box. Are collapsing headers within a combo box really a good idea anyway? Is there precedence?

@vihdzp
Copy link
Contributor

vihdzp commented May 9, 2021

I'd be fine with some widgets closing the menus but not others. I can't see any reason anyone would want a nested CollapsingHeader to actually close the parent one.

@msklywenn
Copy link

Instead of "significant", what about a "used" flag set when some widget "uses" the event? The following widgets could read that used flag and act or not anyway. In this case, the click would close the combobox only if the click was not used by some inner widget.

@vihdzp
Copy link
Contributor

vihdzp commented May 24, 2021

After scouring for a while through the source code, I have a concrete proposal that expands on @msklywenn's idea. We could add a used attribute to the Ui type itself. We would add a chaining operator .used(self, bool) so that a user can manually set this attribute. And to avoid issues like this propping up, we could figure out reasonable defaults for every Widget (buttons are used, menus are not, etc.).

The value of this attribute would then be propagated through Response, and would be read by a ComboBox or a Menu to determine whether to close due to the Response returned by its controls.

If this seems like a reasonable proposal, then I'd be happy to help implement it.

@vihdzp
Copy link
Contributor

vihdzp commented Jun 26, 2021

So... what about this? Is my proposal a good idea? Are there any other ways we could get around this?

@emilk
Copy link
Owner

emilk commented Sep 30, 2021

Perhaps this could be solved by re-implementing comboboxes using #543

@mankinskin
Copy link
Contributor

Just tried it, seems like it works 👍
collapsible_in_contextmenu

@mankinskin
Copy link
Contributor

Should be very easy to use this for the ComboBox menu.. but that would mean we need to manually call ui.close_menu() to close the menu. Maybe this kind of defeats the purpose of ComboBox as opposed to a regular egui::menu? Maybe except for the arrow icon?

@mankinskin
Copy link
Contributor

mankinskin commented Oct 1, 2021

@vihdzp @msklywenn I also used a propagation system like this to cascade the close command through the menu hierarchy. You have to call a function though when you want the menu to close. But I could imagine widgets triggering this internally when some flag is set. you just need a Ui from the menu hierarchy, which has a handle to its parent menu and can close it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
design Some architectual design work needed
Projects
None yet
Development

No branches or pull requests

5 participants