zgui
zgui copied to clipboard
[BUG] Click goes "through" menu elements
Describe the bug When clicking on a listbox, combobox, multicombobox, the thing under the list appearing get triggered too, here is a gif to understand me better. https://i.imgur.com/9ECDCqa.gifv
To Reproduce Steps to reproduce the behavior:
- Make a combobox, listbox.
- Put a interactive element under (checkbox, another combobox, listbox)
- Click
Expected behavior Only the opened element should get triggered.
Screenshots See the gif ^
Thanks for reporting that, but this issue seems to be more advanced and it can take more time to investigate source of this behavior and whole blocking system. Already added it to TODO.
Thanks for reporting that, but this issue seems to be more advanced and it can take more time to investigate source of this behavior and whole blocking system. Already added it to TODO.
As always, thanks for the quick answer and good luck
In order to fix this issue, you’ll need to disable input with your inputsystem interfaces when the menu is open. I assume that there is ways to make this already implemented in zgui, but for now this is the way I do it.
In order to fix this issue, you’ll need to disable input with your inputsystem interfaces when the menu is open. I assume that there is ways to make this already implemented in zgui, but for now this is the way I do it.
Oh okay, thanks for the reply :)
Small correction. The issue that I explained how to fix is different, my mistake I am on my phone and it decided not to show the gif. However for your issue, I’m pretty sure zxvnme is planning on looking into control priority at some point
Thanks for reporting that, but this issue seems to be more advanced and it can take more time to investigate source of this behavior and whole blocking system. Already added it to TODO.
It's rather quite simple. This is how I do it:
/**
* @brief Invoked when the user clicks somewhere on the element's surface.
* @return true, if the input was consumed.
* @return false, if the input wasn't consumed.
*/
bool OnPress() override {
for( const auto& element : m_elements ) {
// Release currently focused element
// if we aren't pressing with our mouse
if( m_focused_element && !g_mouse->Pressing() ) {
m_focused_element->OnRelease();
m_focused_element->m_state &= ~kState_Focused;
m_focused_element = nullptr;
}
// Handle mouse events specifically based on element type
// i.e. listbox has a scroll event which can turn focus on
auto mouse_event = g_mouse->Pressing();
if( element->m_type & kType_Listbox )
mouse_event |= ( g_mouse->m_scroll != kScroll_None );
// There is currently no focused element
// and the current element isn't being pressed on,
// so we can just skip any focus callback logic
if( !m_focused_element && !( element->Hovered() && mouse_event ) )
continue;
// Handle the @ref OnPress callback of the newly focused element only once
if( !m_focused_element ) {
m_focused_element = element;
m_focused_element->m_state |= kState_Focused;
return m_focused_element->OnPress();
}
// Handle the slider @ref m_focused_element @ref OnPress event continuously,
// even when out of clickable area
auto has_slider = ( m_focused_element->m_type & kType_Slider || m_focused_element->m_type & kType_Listbox );
if( m_focused_element && has_slider )
return m_focused_element->OnPress();
}
return false;
}
The above posted code is obviously for an OOP-style menu. You should call this code in your groupbox/window element mouse click handler. There should be only one m_focused_element object per application instance.
Based on the returned state, you can also figure out which window has consumed the input.
Thanks for reporting that, but this issue seems to be more advanced and it can take more time to investigate source of this behavior and whole blocking system. Already added it to TODO.
It's rather quite simple. This is how I do it:
/** * @brief Invoked when the user clicks somewhere on the element's surface. * @return true, if the input was consumed. * @return false, if the input wasn't consumed. */ bool OnPress() override { for( const auto& element : m_elements ) { // Release currently focused element // if we aren't pressing with our mouse if( m_focused_element && !g_mouse->Pressing() ) { m_focused_element->OnRelease(); m_focused_element->m_state &= ~kState_Focused; m_focused_element = nullptr; } // Handle mouse events specifically based on element type // i.e. listbox has a scroll event which can turn focus on auto mouse_event = g_mouse->Pressing(); if( element->m_type & kType_Listbox ) mouse_event |= ( g_mouse->m_scroll != kScroll_None ); // There is currently no focused element // and the current element isn't being pressed on, // so we can just skip any focus callback logic if( !m_focused_element && !( element->Hovered() && mouse_event ) ) continue; // Handle the @ref OnPress callback of the newly focused element only once if( !m_focused_element ) { m_focused_element = element; m_focused_element->m_state |= kState_Focused; return m_focused_element->OnPress(); } // Handle the slider @ref m_focused_element @ref OnPress event continuously, // even when out of clickable area auto has_slider = ( m_focused_element->m_type & kType_Slider || m_focused_element->m_type & kType_Listbox ); if( m_focused_element && has_slider ) return m_focused_element->OnPress(); } return false; }
The above posted code is obviously for an OOP-style menu. You should call this code in your groupbox/window element mouse click handler. There should be only one m_focused_element object per application instance.
Based on the returned state, you can also figure out which window has consumed the input.
you can make a pull request btw