void Container::HandleEvent( const sf::Event& event ) { // Ignore event when widget is not visible. if( !IsGloballyVisible() ) { return; } // Create a copy of the event and transform mouse coordinates to local // coordinates if event is a mouse event. sf::Event local_event( event ); if( local_event.type == sf::Event::MouseMoved ) { local_event.mouseMove.x -= static_cast<int>( GetAllocation().left ); local_event.mouseMove.y -= static_cast<int>( GetAllocation().top ); } if( local_event.type == sf::Event::MouseButtonPressed || local_event.type == sf::Event::MouseButtonReleased ) { local_event.mouseButton.x -= static_cast<int>( GetAllocation().left ); local_event.mouseButton.y -= static_cast<int>( GetAllocation().top ); } std::size_t children_size = m_children.size(); // Pass event to children. for( std::size_t index = 0; index < children_size; ++index ) { m_children[index]->HandleEvent( local_event ); } // Process event for own widget. Widget::HandleEvent( event ); }
void Widget::Show( bool show ) { if( show == IsLocallyVisible() ) { return; } auto old_global_visibility = IsGloballyVisible(); // Flip the visible bit since we know show != IsLocallyVisible() m_visible = !m_visible; HandleLocalVisibilityChange(); if( old_global_visibility != IsGloballyVisible() ) { HandleGlobalVisibilityChange(); } RequestResize(); }
void Widget::HandleGlobalVisibilityChange() { if( GetState() == PRELIGHT ) { SetState( NORMAL ); } if( m_drawable ) { m_drawable->Show( IsGloballyVisible() ); } }
void Widget::HandleGlobalVisibilityChange() { auto state = GetState(); if( ( state == State::PRELIGHT ) || ( state == State::ACTIVE ) ) { SetState( State::NORMAL ); } if( m_drawable ) { m_drawable->Show( IsGloballyVisible() ); } }
void Widget::Update( float seconds ) { if( m_invalidated ) { m_invalidated = false; m_parent_notified = false; m_drawable = InvalidateImpl(); if( m_drawable ) { m_drawable->SetPosition( GetAbsolutePosition() ); m_drawable->SetLevel( m_hierarchy_level ); m_drawable->SetZOrder( m_z_order ); m_drawable->Show( IsGloballyVisible() ); // We don't want to propagate container viewports for Canvases, // they have their own special viewport for drawing. if( m_drawable->GetPrimitives().empty() || !m_drawable->GetPrimitives()[0]->GetCustomDrawCallback() ) { m_drawable->SetViewport( m_viewport ); } } } HandleUpdate( seconds ); }
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; } }
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; } }