zgui icon indicating copy to clipboard operation
zgui copied to clipboard

[BUG] Click goes "through" menu elements

Open NaiJii opened this issue 5 years ago • 7 comments

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:

  1. Make a combobox, listbox.
  2. Put a interactive element under (checkbox, another combobox, listbox)
  3. Click

Expected behavior Only the opened element should get triggered.

Screenshots See the gif ^

NaiJii avatar Jul 24 '19 20:07 NaiJii

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.

zxvnme avatar Jul 24 '19 21:07 zxvnme

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

NaiJii avatar Jul 24 '19 21:07 NaiJii

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.

txxmo avatar Jul 24 '19 21:07 txxmo

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 :)

NaiJii avatar Jul 24 '19 21:07 NaiJii

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

txxmo avatar Jul 24 '19 21:07 txxmo

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.

microphone369 avatar Aug 14 '19 17:08 microphone369

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

smefpw avatar Aug 14 '19 22:08 smefpw