Beispiel #1
0
void Widget::HandleEvent( const sf::Event& event ) {
	if( !IsGloballyVisible() ) {
		return;
	}

	// Ignore the event if widget is insensitive
	if ( GetState() == State::INSENSITIVE ) {
		return;
	}

	// Ignore the event if another widget is active.
	if( !IsActiveWidget() && !IsActiveWidget( PtrConst() ) ) {
		return;
	}

	// Ignore the event if another widget is modal.
	if( HasModal() && !IsModal() ) {
		return;
	}

	// Set widget active in context.
	Context::Get().SetActiveWidget( shared_from_this() );

	auto parent = m_parent.lock();

	auto emit_leave = false;
	auto emit_enter = false;
	auto emit_move = false;
	auto emit_left_click = false;
	auto emit_right_click = false;

	try {
		switch( event.type ) {
			case sf::Event::MouseLeft:
				if( IsMouseInWidget() ) {
					SetMouseInWidget( false );

					HandleMouseLeave( std::numeric_limits<int>::min(), std::numeric_limits<int>::min() );

					emit_leave = true;
				}

				HandleMouseMoveEvent( std::numeric_limits<int>::min(), std::numeric_limits<int>::min() );

				SetMouseButtonDown();
				HandleMouseButtonEvent( sf::Mouse::Left, false, std::numeric_limits<int>::min(), std::numeric_limits<int>::min() );
				HandleMouseButtonEvent( sf::Mouse::Right, false, std::numeric_limits<int>::min(), std::numeric_limits<int>::min() );

				if( emit_leave ) {
					GetSignals().Emit( OnMouseLeave );
				}

				break;

			case sf::Event::MouseMoved:
				// Check if pointer inside of widget's allocation.
				if( GetAllocation().contains( static_cast<float>( event.mouseMove.x ), static_cast<float>( event.mouseMove.y ) ) ) {
					// Check for enter event.
					if( !IsMouseInWidget() ) {
						SetMouseInWidget( true );

						emit_enter = true;

						HandleMouseEnter( event.mouseMove.x, event.mouseMove.y );
					}

					emit_move = true;
				}
				else if( IsMouseInWidget() ) { // Check for leave event.
					SetMouseInWidget( false );

					emit_leave = true;

					HandleMouseLeave( event.mouseMove.x, event.mouseMove.y );
				}

				HandleMouseMoveEvent( event.mouseMove.x, event.mouseMove.y );

				if( emit_move ) {
					if( emit_enter ) {
						GetSignals().Emit( OnMouseEnter );
					}

					GetSignals().Emit( OnMouseMove );
				}
				else if( emit_leave ) {
					GetSignals().Emit( OnMouseLeave );
				}

				break;

			case sf::Event::MouseButtonPressed:
				if( !IsMouseButtonDown() && IsMouseInWidget() ) {
					SetMouseButtonDown( event.mouseButton.button );
				}

				HandleMouseButtonEvent( event.mouseButton.button, true, event.mouseButton.x, event.mouseButton.y );

				if( IsMouseInWidget() ) {
					if( event.mouseButton.button == sf::Mouse::Left ) {
						GetSignals().Emit( OnMouseLeftPress );
					}
					else if( event.mouseButton.button == sf::Mouse::Right ) {
						GetSignals().Emit( OnMouseRightPress );
					}
				}

				break;

			case sf::Event::MouseButtonReleased:
				// Only process as a click when mouse button has been pressed inside the widget before.
				if( IsMouseButtonDown( event.mouseButton.button ) ) {
					SetMouseButtonDown();

					// When released inside the widget, the event can be considered a click.
					if( IsMouseInWidget() ) {
						HandleMouseClick( event.mouseButton.button, event.mouseButton.x, event.mouseButton.y );

						if( event.mouseButton.button == sf::Mouse::Left ) {
							emit_left_click = true;
						}
						else if( event.mouseButton.button == sf::Mouse::Right ) {
							emit_right_click = true;
						}
					}
				}

				HandleMouseButtonEvent( event.mouseButton.button, false, event.mouseButton.x, event.mouseButton.y );

				if( emit_left_click ) {
					GetSignals().Emit( OnLeftClick );
				}
				else if( emit_right_click ) {
					GetSignals().Emit( OnRightClick );
				}

				if( IsMouseInWidget() ) {
					if( event.mouseButton.button == sf::Mouse::Left ) {
						GetSignals().Emit( OnMouseLeftRelease );
					}
					else if( event.mouseButton.button == sf::Mouse::Right ) {
						GetSignals().Emit( OnMouseRightRelease );
					}
				}

				break;

			case sf::Event::KeyPressed:
				if( HasFocus() ) {
					// TODO: Delegate event too when widget's not active?
					HandleKeyEvent( event.key.code, true );
					GetSignals().Emit( OnKeyPress );
				}

				break;

			case sf::Event::KeyReleased:
				if( HasFocus() ) {
					// TODO: Delegate event too when widget's not active?
					HandleKeyEvent( event.key.code, false );
					GetSignals().Emit( OnKeyRelease );
				}
				break;

			case sf::Event::TextEntered:
				if( HasFocus() ) {
					// TODO: Delegate event too when widget's not active?
					HandleTextEvent( event.text.unicode );
					GetSignals().Emit( OnText );
				}
				break;

			default:
				break;
		}
	}
	catch( ... ) {
		SetState( State::NORMAL );
		throw;
	}
}
Beispiel #2
0
bool Widget::IsActiveWidget() const {
	return IsActiveWidget( shared_from_this() );
}
Beispiel #3
0
void Widget::HandleEvent( const sf::Event& event ) {
	if( !IsGloballyVisible() ) {
		return;
	}

	// Ignore the event if widget is insensitive
	if ( GetState() == INSENSITIVE ) {
		return;
	}

	// Ignore the event if another widget is active.
	if( !IsActiveWidget() && !IsActiveWidget( PtrConst() ) ) {
		return;
	}

	// Ignore the event if another widget is modal.
	if( HasModal() && !IsModal() ) {
		return;
	}

	// Set widget active in context.
	Context::Get().SetActiveWidget( shared_from_this() );

	Container::Ptr parent( m_parent.lock() );

	switch( event.type ) {
		case sf::Event::MouseMoved:
			// Check if pointer inside of widget's allocation.
			if( GetAllocation().contains( static_cast<float>( event.mouseMove.x ), static_cast<float>( event.mouseMove.y ) ) ) {
				// Check for enter event.
				if( !IsMouseInWidget() ) {
					// Flip the mouse_in bit.
					m_bitfield ^= static_cast<unsigned char>( 0x10 );

					GetSignals().Emit( OnMouseEnter );
					HandleMouseEnter( event.mouseMove.x, event.mouseMove.y );
				}

				GetSignals().Emit( OnMouseMove );
			}
			else if( IsMouseInWidget() ) { // Check for leave event.
				// Flip the mouse_in bit.
				m_bitfield ^= static_cast<unsigned char>( 0x10 );

				GetSignals().Emit( OnMouseLeave );
				HandleMouseLeave( event.mouseMove.x, event.mouseMove.y );
			}

			HandleMouseMoveEvent( event.mouseMove.x, event.mouseMove.y );
			break;

		case sf::Event::MouseButtonPressed:
			if( ( ( m_bitfield & static_cast<unsigned char>( 0xe0 ) ) == static_cast<unsigned char>( 0xe0 ) ) && IsMouseInWidget() ) {
				// Clear the mouse_button_down bits to 0s.
				m_bitfield &= static_cast<unsigned char>( 0x1f );

				// Set the mouse_button_down bits.
				m_bitfield |= static_cast<unsigned char>( event.mouseButton.button << 5 );
			}

			HandleMouseButtonEvent( event.mouseButton.button, true, event.mouseButton.x, event.mouseButton.y );

			if( IsMouseInWidget() ) {
				if( event.mouseButton.button == sf::Mouse::Left ) {
					GetSignals().Emit( OnMouseLeftPress );
				}
				else if( event.mouseButton.button == sf::Mouse::Right ) {
					GetSignals().Emit( OnMouseRightPress );
				}
			}

			break;

		case sf::Event::MouseButtonReleased:
			// Only process as a click when mouse button has been pressed inside the widget before.
			if( ( ( m_bitfield & 0xe0 ) >> 5 ) == event.mouseButton.button ) {
				// Set the mouse_button_down bits to 111 (none).
				m_bitfield |= static_cast<unsigned char>( 0xe0 );

				// When released inside the widget, the event can be considered a click.
				if( IsMouseInWidget() ) {
					HandleMouseClick( event.mouseButton.button, event.mouseButton.x, event.mouseButton.y );

					if( event.mouseButton.button == sf::Mouse::Left ) {
						GetSignals().Emit( OnLeftClick );
					}
					else if( event.mouseButton.button == sf::Mouse::Right ) {
						GetSignals().Emit( OnRightClick );
					}
				}
			}

			HandleMouseButtonEvent( event.mouseButton.button, false, event.mouseButton.x, event.mouseButton.y );

			if( IsMouseInWidget() ) {
				if( event.mouseButton.button == sf::Mouse::Left ) {
					GetSignals().Emit( OnMouseLeftRelease );
				}
				else if( event.mouseButton.button == sf::Mouse::Right ) {
					GetSignals().Emit( OnMouseRightRelease );
				}
			}

			break;

		case sf::Event::KeyPressed:
			if( HasFocus() ) {
				// TODO: Delegate event too when widget's not active?
				HandleKeyEvent( event.key.code, true );
				GetSignals().Emit( OnKeyPress );
			}

			break;

		case sf::Event::KeyReleased:
			if( HasFocus() ) {
				// TODO: Delegate event too when widget's not active?
				HandleKeyEvent( event.key.code, false );
				GetSignals().Emit( OnKeyRelease );
			}
			break;

		case sf::Event::TextEntered:
			if( HasFocus() ) {
				// TODO: Delegate event too when widget's not active?
				HandleTextEvent( event.text.unicode );
				GetSignals().Emit( OnText );
			}
			break;

		default:
			break;
	}
}