SecondHalfGames / yakui

yakui is a declarative Rust UI library for games
Apache License 2.0
222 stars 18 forks source link

Widgets don't respond to mouse buttons until after mouse motion #109

Open Ralith opened 8 months ago

Ralith commented 8 months ago

If you click a button that causes another button to be spawned under the mouse, further clicks won't trigger the new button until the mouse has moved.

kulkalkul commented 4 months ago

I have a similar case, so sharing a reproducable example here instead of opening another issue, so maybe it helps.

#[derive(Copy, Clone, Eq, PartialEq)]
enum BuildingMenu {
    Nothing,
    Station,
    Facilities,
}

impl BuildingMenu {
    fn name(self) -> &'static str {
        match self {
            BuildingMenu::Nothing => "",
            BuildingMenu::Station => "Station",
            BuildingMenu::Facilities => "Facilities",
        }
    }
}

pub fn update_ui() {
    let active_menu = use_state(|| BuildingMenu::Nothing);

    let mut main_col = List::column();
    main_col.main_axis_alignment = MainAxisAlignment::End;
    main_col.cross_axis_alignment = CrossAxisAlignment::Center;
    main_col.show(|| {
        pad(Pad::horizontal(50.), || {

            // column I'll be talking about
            column(|| {
                if active_menu.get() != BuildingMenu::Nothing {
                    label(active_menu.get().name());
                }

                // row I'll be talking about
                row(|| {
                    building_menu(BuildingMenu::Station, &active_menu);
                    building_menu(BuildingMenu::Facilities, &active_menu);
                });
            });
        });
    });
}

fn building_menu(menu: BuildingMenu, active_menu: &Response<StateResponse<BuildingMenu>>) {
    let name = menu.name();
    if button(name).clicked {
        if active_menu.get() == menu {
            active_menu.set(BuildingMenu::Nothing)
        } else {
            active_menu.set(menu);
        }
    }
}

I've put two comments there for the column and row I'll be talking about. So, if active_menu branch is run inside column as first element, second click doesn't work until I move the mouse. If I swap the row with active_menu branch, it works. When it is inside the row like so:

row(|| {
    building_menu(BuildingMenu::Station, &active_menu);
    building_menu(BuildingMenu::Facilities, &active_menu);
    if active_menu.get() != BuildingMenu::Nothing {
        label(active_menu.get().name());
    }
});

Also works. I assume this is because layout is recalculated?