diff --git a/AUTHORS b/AUTHORS index 0b087b1e..4ddeb67b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,3 +17,4 @@ Dematos Pierre Adam (https://github.com/PierreAdam) eXpl0it3r (https://github.com/eXpl0it3r) Zax37 (https://github.com/Zax37) +Steven Christy (https://github.com/StevenChristy) diff --git a/CHANGELOG b/CHANGELOG index 493574c9..bfbebf07 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,14 @@ Changelog for SFGUI, http://sfgui.sfml-dev.de/ +0.4.0-dev + +Enhancements: + - HandleEvent now returns true/false to indicate whether or not an event is + handled. This allows the gui to trap events and prevent them from being + processed further by the application. + - Disabling a container now disables all child controls allowing them to + render as disabled. + 0.3.0 Fixes: diff --git a/examples/CustomWidget.cpp b/examples/CustomWidget.cpp index 3e34cc44..e83ca3b4 100644 --- a/examples/CustomWidget.cpp +++ b/examples/CustomWidget.cpp @@ -196,17 +196,19 @@ class MyCustomWidget : public sfg::Widget { } // This handler handles mouse button events - void HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override { + bool HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override { + bool bHandled = false; if( !IsMouseInWidget() ) { if( GetState() == State::ACTIVE ) { SetState( State::NORMAL ); } - return; + return bHandled; } if( button == sf::Mouse::Left ) { if( press ) { + bHandled = true; SetLabel( sf::String( "Mouse Left Press: " + std::to_string( x ) + "," + std::to_string( y ) ) ); SetState( State::ACTIVE ); } @@ -214,6 +216,7 @@ class MyCustomWidget : public sfg::Widget { SetState( State::PRELIGHT ); } } + return bHandled; } sf::String m_label; diff --git a/include/SFGUI/Button.hpp b/include/SFGUI/Button.hpp index f2ed9c8a..42cdc7e0 100644 --- a/include/SFGUI/Button.hpp +++ b/include/SFGUI/Button.hpp @@ -65,7 +65,7 @@ class SFGUI_API Button : public Bin { private: void HandleMouseEnter( int x, int y ) override; void HandleMouseLeave( int x, int y ) override; - void HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; + bool HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; void AllocateChild(); sf::String m_label; diff --git a/include/SFGUI/ComboBox.hpp b/include/SFGUI/ComboBox.hpp index 8bae67f6..f5317c40 100644 --- a/include/SFGUI/ComboBox.hpp +++ b/include/SFGUI/ComboBox.hpp @@ -136,7 +136,7 @@ class SFGUI_API ComboBox : public Bin { void HandleMouseEnter( int x, int y ) override; void HandleMouseLeave( int x, int y ) override; void HandleMouseMoveEvent( int x, int y ) override; - void HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; + bool HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; void HandleStateChange( State old_state ) override; void HandleUpdate( float seconds ) override; void ChangeStartEntry(); diff --git a/include/SFGUI/Container.hpp b/include/SFGUI/Container.hpp index 42eea30e..0061bc47 100644 --- a/include/SFGUI/Container.hpp +++ b/include/SFGUI/Container.hpp @@ -46,7 +46,11 @@ class SFGUI_API Container : public Widget { void Refresh() override; - void HandleEvent( const sf::Event& event ) override; + /** Handle event. + * @param event SFML event. + * @return true if event is handled. + */ + bool HandleEvent( const sf::Event& event ) override; /** Used to inform parent that a child has been invalidated * @param child Widget that was invalidated. @@ -84,6 +88,10 @@ class SFGUI_API Container : public Widget { /** Handle viewport change. */ void HandleViewportUpdate() override; + + /** Handle state change. + */ + void HandleStateChange(State old_state) override; private: WidgetsList m_children; diff --git a/include/SFGUI/Desktop.hpp b/include/SFGUI/Desktop.hpp index b7f4f81c..7a84b544 100644 --- a/include/SFGUI/Desktop.hpp +++ b/include/SFGUI/Desktop.hpp @@ -59,8 +59,9 @@ class SFGUI_API Desktop { /** Handle event. * @param event SFML event. + * @return true if event is handled. */ - void HandleEvent( const sf::Event& event ); + bool HandleEvent( const sf::Event& event ); /** Add widget. * The added widget will be the new top widget. diff --git a/include/SFGUI/Entry.hpp b/include/SFGUI/Entry.hpp index 6223607c..e3213e18 100644 --- a/include/SFGUI/Entry.hpp +++ b/include/SFGUI/Entry.hpp @@ -103,10 +103,10 @@ class SFGUI_API Entry : public Widget { std::unique_ptr InvalidateImpl() const override; sf::Vector2f CalculateRequisition() override; - void HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; + bool HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; void HandleUpdate( float seconds ) override; - void HandleTextEvent( sf::Uint32 character ) override; - void HandleKeyEvent( sf::Keyboard::Key key, bool press ) override; + bool HandleTextEvent( sf::Uint32 character ) override; + bool HandleKeyEvent( sf::Keyboard::Key key, bool press ) override; void HandleSizeChange() override; void HandleFocusChange( Widget::Ptr focused_widget ) override; diff --git a/include/SFGUI/Notebook.hpp b/include/SFGUI/Notebook.hpp index c547930d..8a177ae1 100644 --- a/include/SFGUI/Notebook.hpp +++ b/include/SFGUI/Notebook.hpp @@ -189,7 +189,7 @@ class SFGUI_API Notebook : public Container { typedef std::deque ChildrenList; void HandleMouseMoveEvent( int x, int y ) override; - void HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; + bool HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; bool HandleAdd( Widget::Ptr child ) override; void HandleRemove( Widget::Ptr child ) override; void HandleSizeChange() override; diff --git a/include/SFGUI/Scale.hpp b/include/SFGUI/Scale.hpp index 422b4b4d..5753d7e2 100644 --- a/include/SFGUI/Scale.hpp +++ b/include/SFGUI/Scale.hpp @@ -44,7 +44,7 @@ class SFGUI_API Scale : public Range { */ Scale( Orientation orientation = Orientation::HORIZONTAL ); - void HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; + bool HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; void HandleMouseMoveEvent( int x, int y ) override; std::unique_ptr m_drag_offset; diff --git a/include/SFGUI/Scrollbar.hpp b/include/SFGUI/Scrollbar.hpp index 71b84e8a..db50ab95 100644 --- a/include/SFGUI/Scrollbar.hpp +++ b/include/SFGUI/Scrollbar.hpp @@ -54,7 +54,7 @@ class SFGUI_API Scrollbar : public Range { */ Scrollbar( Orientation orientation = Orientation::HORIZONTAL ); - void HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; + bool HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; void HandleMouseMoveEvent( int x, int y ) override; void HandleUpdate( float seconds ) override; diff --git a/include/SFGUI/SpinButton.hpp b/include/SFGUI/SpinButton.hpp index 5bb0a5fc..22f3b05b 100644 --- a/include/SFGUI/SpinButton.hpp +++ b/include/SFGUI/SpinButton.hpp @@ -110,10 +110,10 @@ class SFGUI_API SpinButton : public Entry { void UpdateTextFromAdjustment(); void UpdateAdjustmentFromText(); - void HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; + bool HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) override; void HandleUpdate( float seconds ) override; - void HandleTextEvent( sf::Uint32 character ) override; - void HandleKeyEvent( sf::Keyboard::Key key, bool press ) override; + bool HandleTextEvent( sf::Uint32 character ) override; + bool HandleKeyEvent( sf::Keyboard::Key key, bool press ) override; void HandleSizeChange() override; void HandleFocusChange( Widget::Ptr focused_widget ) override; diff --git a/include/SFGUI/Viewport.hpp b/include/SFGUI/Viewport.hpp index a4b5cce9..14109209 100644 --- a/include/SFGUI/Viewport.hpp +++ b/include/SFGUI/Viewport.hpp @@ -56,7 +56,7 @@ class SFGUI_API Viewport : public Bin { * Handle an SFML event and fire proper signals. * @return true when event has been processed (eaten). */ - void HandleEvent( const sf::Event& event ) override; + bool HandleEvent( const sf::Event& event ) override; const std::string& GetName() const override; diff --git a/include/SFGUI/Widget.hpp b/include/SFGUI/Widget.hpp index 6d6c4bcf..a2944ef7 100644 --- a/include/SFGUI/Widget.hpp +++ b/include/SFGUI/Widget.hpp @@ -35,7 +35,8 @@ class SFGUI_API Widget : public Object, public std::enable_shared_from_this::min() ) || ( y == std::numeric_limits::min() ) ) { - return; + return bHandled; } if( GetState() == State::ACTIVE ) { @@ -288,7 +289,7 @@ void ComboBox::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int ReleaseModal(); m_scrollbar->SetActiveWidget(); - m_scrollbar->HandleEvent( event ); + bHandled = m_scrollbar->HandleEvent( event ); SetActiveWidget(); GrabModal(); @@ -297,12 +298,12 @@ void ComboBox::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int scrollbar_allocation.top += GetAllocation().top; if( scrollbar_allocation.contains( static_cast( x ), static_cast( y ) ) ) { - return; + return bHandled; } } if( !press || ( button != sf::Mouse::Left ) ) { - return; + return bHandled; } auto emit_select = false; @@ -327,7 +328,7 @@ void ComboBox::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int GetSignals().Emit( OnSelect ); } - return; + return bHandled; } if( press && ( button == sf::Mouse::Left ) && IsMouseInWidget() ) { @@ -337,7 +338,9 @@ void ComboBox::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int Invalidate(); GetSignals().Emit( OnOpen ); + bHandled = true; } + return bHandled; } sf::Vector2f ComboBox::CalculateRequisition() { diff --git a/src/SFGUI/Container.cpp b/src/SFGUI/Container.cpp index 9150edde..af9f4a14 100644 --- a/src/SFGUI/Container.cpp +++ b/src/SFGUI/Container.cpp @@ -8,6 +8,8 @@ void Container::Add( Widget::Ptr widget ) { if( HandleAdd( widget ) ) { widget->SetParent( shared_from_this() ); RequestResize(); + if ( GetState() == State::INSENSITIVE || GetState() == State::PARENT_INSENSITIVE ) + widget->SetState(State::PARENT_INSENSITIVE); } } @@ -15,6 +17,9 @@ void Container::Remove( Widget::Ptr widget ) { WidgetsList::iterator iter( std::find( m_children.begin(), m_children.end(), widget ) ); if( iter != m_children.end() ) { + if ( GetState() == State::PARENT_INSENSITIVE ) + widget->SetState(State::NORMAL); + m_children.erase( iter ); widget->SetParent( Widget::Ptr() ); HandleRemove( widget ); @@ -51,10 +56,11 @@ void Container::Refresh() { Widget::Refresh(); } -void Container::HandleEvent( const sf::Event& event ) { +bool Container::HandleEvent( const sf::Event& event ) { + bool bHandled = false; // Ignore event when widget is not visible. if( !IsGloballyVisible() ) { - return; + return bHandled; } // Create a copy of the event and transform mouse coordinates to local @@ -76,11 +82,12 @@ void Container::HandleEvent( const sf::Event& event ) { // Pass event to children. for( const auto& child : m_children ) { - child->HandleEvent( local_event ); + bHandled = child->HandleEvent( local_event ) || bHandled; } // Process event for own widget. - Widget::HandleEvent( event ); + bHandled = Widget::HandleEvent( event ) || bHandled; + return bHandled; } bool Container::HandleAdd( Widget::Ptr child ) { @@ -148,4 +155,30 @@ void Container::HandleViewportUpdate() { Widget::HandleViewportUpdate(); } +void Container::HandleStateChange( State old_state ) { + State state = GetState(); + + Widget::HandleStateChange(old_state); + + if ( state == State::INSENSITIVE || state == State::PARENT_INSENSITIVE ) { + // Unless we were previously something like it. + if ( (old_state == State::INSENSITIVE || old_state == State::PARENT_INSENSITIVE) ) + return; + + for( const auto& child : m_children ) { + if ( child->GetState() != State::PARENT_INSENSITIVE && child->GetState() != State::INSENSITIVE ) + child->SetState( State::PARENT_INSENSITIVE ); + } + } + else if ( (old_state == State::INSENSITIVE || old_state == State::PARENT_INSENSITIVE) ) + { + for( const auto& child : m_children ) { + if ( child->GetState() == State::PARENT_INSENSITIVE ) + child->SetState( State::NORMAL ); + } + } +} + + + } diff --git a/src/SFGUI/Desktop.cpp b/src/SFGUI/Desktop.cpp index ddd1b01b..48c7d374 100644 --- a/src/SFGUI/Desktop.cpp +++ b/src/SFGUI/Desktop.cpp @@ -20,7 +20,8 @@ void Desktop::Update( float seconds ) { Context::Deactivate(); } -void Desktop::HandleEvent( const sf::Event& event ) { +bool Desktop::HandleEvent( const sf::Event& event ) { + bool bHandled = false; // Activate context. Context::Activate( m_context ); @@ -46,7 +47,7 @@ void Desktop::HandleEvent( const sf::Event& event ) { Widget::Ptr widget( m_children[static_cast( index )] ); // Skip widget if not visible or is insensitive. - if( !widget->IsLocallyVisible() || widget->GetState() == Widget::State::INSENSITIVE ) { + if( !widget->IsLocallyVisible() || !widget->IsEnabled() ) { continue; } @@ -83,7 +84,7 @@ void Desktop::HandleEvent( const sf::Event& event ) { last_receiver = widget; } - widget->HandleEvent( event ); + bHandled = widget->HandleEvent( event ); if( check_inside && is_inside ) { if( index < static_cast( m_children.size() ) && widget == m_children[static_cast( index )] ) { @@ -91,10 +92,13 @@ void Desktop::HandleEvent( const sf::Event& event ) { } break; } + if ( bHandled ) + break; } // Restore previous context. Context::Deactivate(); + return bHandled; } void Desktop::Add( std::shared_ptr widget ) { diff --git a/src/SFGUI/Engines/BREW.cpp b/src/SFGUI/Engines/BREW.cpp index a221c1ed..21bff251 100644 --- a/src/SFGUI/Engines/BREW.cpp +++ b/src/SFGUI/Engines/BREW.cpp @@ -28,6 +28,7 @@ void BREW::ResetProperties() { SetProperty( "*", "BorderWidth", 1.f ); SetProperty( "*", "Padding", 5.f ); SetProperty( "*", "Thickness", 2.f ); + SetProperty( "*:INSENSITIVE", "Color", sf::Color( 0x96, 0x9b, 0x94 ) ); // Window-specific. SetProperty( "Window", "Gap", 10.f ); diff --git a/src/SFGUI/Entry.cpp b/src/SFGUI/Entry.cpp index a1153843..1a06d0bb 100644 --- a/src/SFGUI/Entry.cpp +++ b/src/SFGUI/Entry.cpp @@ -159,27 +159,32 @@ void Entry::MoveCursor( int delta ) { } } -void Entry::HandleTextEvent( sf::Uint32 character ) { +bool Entry::HandleTextEvent( sf::Uint32 character ) { + bool bHandled = character > 0x1f && character != 0x7f; if( m_max_length > 0 && static_cast( m_string.getSize() ) >= m_max_length ) { - return; + return bHandled; } - if( character > 0x1f && character != 0x7f ) { + if( bHandled ) { // not a control character m_string.insert( static_cast( m_cursor_position ), character ); MoveCursor( 1 ); GetSignals().Emit( OnTextChanged ); } + + return bHandled; } -void Entry::HandleKeyEvent( sf::Keyboard::Key key, bool press ) { +bool Entry::HandleKeyEvent( sf::Keyboard::Key key, bool press ) { + bool bHandled = false; if( !press || !HasFocus() ) { - return; + return bHandled; } switch( key ) { case sf::Keyboard::BackSpace: { // backspace + bHandled = true; if( ( m_string.getSize() > 0 ) && ( m_cursor_position > 0 ) ) { m_string.erase( static_cast( m_cursor_position - 1 ) ); @@ -203,6 +208,7 @@ void Entry::HandleKeyEvent( sf::Keyboard::Key key, bool press ) { } } break; case sf::Keyboard::Delete: { + bHandled = true; if( ( m_string.getSize() > 0 ) && ( m_cursor_position < static_cast( m_string.getSize() ) ) ) { m_string.erase( static_cast( m_cursor_position ) ); @@ -225,25 +231,31 @@ void Entry::HandleKeyEvent( sf::Keyboard::Key key, bool press ) { } } break; case sf::Keyboard::Home: { + bHandled = true; if( m_string.getSize() > 0 ) { m_visible_offset = 0; SetCursorPosition( 0 ); } } break; case sf::Keyboard::End: { + bHandled = true; if( m_string.getSize() > 0 ) { m_visible_offset = 0; SetCursorPosition( static_cast( m_string.getSize() ) ); } } break; case sf::Keyboard::Left: { + bHandled = true; MoveCursor( -1 ); } break; case sf::Keyboard::Right: { + bHandled = true; MoveCursor( 1 ); } break; default: break; } + + return bHandled; } void Entry::HandleMouseEnter( int /*x*/, int /*y*/ ) { @@ -258,18 +270,21 @@ void Entry::HandleMouseLeave( int /*x*/, int /*y*/ ) { } } -void Entry::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int /*y*/ ) { +bool Entry::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int /*y*/ ) { + bool bHandled = false; if( !press || !IsMouseInWidget() ) { - return; + return bHandled; } if( button != sf::Mouse::Left ) { // TODO: Maybe some more support for right clicking in the future. - return; + return bHandled; } + bHandled = true; GrabFocus(); SetCursorPosition( GetPositionFromMouseX( x ) ); + return bHandled; } void Entry::HandleUpdate( float seconds ) { diff --git a/src/SFGUI/Notebook.cpp b/src/SFGUI/Notebook.cpp index 8e742c4a..3ef771a5 100644 --- a/src/SFGUI/Notebook.cpp +++ b/src/SFGUI/Notebook.cpp @@ -428,9 +428,10 @@ void Notebook::HandleMouseMoveEvent( int x, int y ) { } } -void Notebook::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int /*x*/, int /*y*/ ) { +bool Notebook::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int /*x*/, int /*y*/ ) { + bool bHandled = false; if( ( button != sf::Mouse::Left ) ) { - return; + return bHandled; } float scroll_speed( Context::Get().GetEngine().GetProperty( "ScrollSpeed", shared_from_this() ) ); @@ -441,25 +442,29 @@ void Notebook::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int Invalidate(); if( m_forward_scroll_prelight && press ) { + bHandled = true; m_scrolling_forward = true; m_elapsed_time = ( 1.f / scroll_speed ); - return; + return bHandled; } else if( m_backward_scroll_prelight && press ) { + bHandled = true; m_scrolling_backward = true; m_elapsed_time = ( 1.f / scroll_speed ); - return; + return bHandled; } if( !press ) { - return; + return bHandled; } if( m_prelight_tab < 0 ) { - return; + return bHandled; } + bHandled = true; SetCurrentPage( m_prelight_tab ); + return bHandled; } bool Notebook::HandleAdd( Widget::Ptr child ) { diff --git a/src/SFGUI/Scale.cpp b/src/SFGUI/Scale.cpp index f0ee7f6e..2be15993 100644 --- a/src/SFGUI/Scale.cpp +++ b/src/SFGUI/Scale.cpp @@ -64,9 +64,10 @@ sf::Vector2f Scale::CalculateRequisition() { return sf::Vector2f( slider_width, slider_length * 2.f ); } -void Scale::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) { +bool Scale::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) { + bool bHandled = false; if( button != sf::Mouse::Left ) { - return; + return bHandled; } if( m_drag_offset ) { @@ -75,10 +76,12 @@ void Scale::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, } if( !GetAllocation().contains( static_cast( x ), static_cast( y ) ) ) { - return; + return bHandled; } if( press ) { + bHandled = true; + if( !GetSliderRect().contains( static_cast( x ) - GetAllocation().left, static_cast( y ) - GetAllocation().top ) ) { Adjustment::Ptr adjustment( GetAdjustment() ); @@ -121,6 +124,7 @@ void Scale::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, static_cast( y ) - ( GetAllocation().top + GetSliderRect().top + GetSliderRect().height / 2.f ) ) ); } + return bHandled; } void Scale::HandleMouseMoveEvent( int x, int y ) { diff --git a/src/SFGUI/Scrollbar.cpp b/src/SFGUI/Scrollbar.cpp index 4122dc39..707847f7 100644 --- a/src/SFGUI/Scrollbar.cpp +++ b/src/SFGUI/Scrollbar.cpp @@ -92,9 +92,9 @@ sf::Vector2f Scrollbar::CalculateRequisition() { return sf::Vector2f( mimimum_slider_length, mimimum_slider_length ); } -void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) { +bool Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) { if( button != sf::Mouse::Left ) { - return; + return false; } if( press ) { @@ -114,7 +114,7 @@ void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, in m_slider_click_offset = static_cast( y ) + GetAllocation().top - slider_mid; } - return; + return true; } if( GetOrientation() == Orientation::HORIZONTAL ) { @@ -129,7 +129,7 @@ void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, in m_elapsed_time = 0.f; m_repeat_wait = true; Invalidate(); - return; + return true; } if( increase_stepper_rect.contains( static_cast( x ), static_cast( y ) ) ) { @@ -138,7 +138,7 @@ void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, in m_elapsed_time = 0.f; m_repeat_wait = true; Invalidate(); - return; + return true; } } else { @@ -153,7 +153,7 @@ void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, in m_elapsed_time = 0.f; m_repeat_wait = true; Invalidate(); - return; + return true; } if( increase_stepper_rect.contains( static_cast( x ), static_cast( y ) ) ) { @@ -162,7 +162,7 @@ void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, in m_elapsed_time = 0.f; m_repeat_wait = true; Invalidate(); - return; + return true; } } @@ -177,7 +177,7 @@ void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, in m_elapsed_time = 0.f; m_repeat_wait = true; Invalidate(); - return; + return true; } else { m_page_increasing = x; @@ -185,7 +185,7 @@ void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, in m_elapsed_time = 0.f; m_repeat_wait = true; Invalidate(); - return; + return true; } } } @@ -197,7 +197,7 @@ void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, in m_elapsed_time = 0.f; m_repeat_wait = true; Invalidate(); - return; + return true; } else { m_page_increasing = y; @@ -205,7 +205,7 @@ void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, in m_elapsed_time = 0.f; m_repeat_wait = true; Invalidate(); - return; + return true; } } } @@ -220,8 +220,9 @@ void Scrollbar::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, in m_slider_click_offset = 0.f; Invalidate(); - return; } + + return false; } void Scrollbar::HandleMouseMoveEvent( int x, int y ) { diff --git a/src/SFGUI/Selector.cpp b/src/SFGUI/Selector.cpp index 0799271d..43d1b4d5 100644 --- a/src/SFGUI/Selector.cpp +++ b/src/SFGUI/Selector.cpp @@ -163,7 +163,9 @@ std::string Selector::BuildString() const { case Widget::State::INSENSITIVE: str += "INSENSITIVE"; break; - + case Widget::State::PARENT_INSENSITIVE: + str += "INSENSITIVE"; + break; default: str += "UNKNOWN"; break; @@ -194,7 +196,7 @@ bool Selector::Matches( Widget::PtrConst widget ) const { ( ( m_widget.empty() || !m_widget.compare("*") || m_widget == widget->GetName() ) && // ( m_id.empty() || m_id == widget->GetId() ) && // Selector and widget match ( m_class.empty() || m_class == widget->GetClass() ) && // - ( !m_state || *m_state == widget->GetState() ) ) ) { // + ( !m_state || *m_state == widget->GetState() || (*m_state == Widget::State::INSENSITIVE && widget->GetState() == Widget::State::PARENT_INSENSITIVE) ) ) ) { // // Current stage is a pass... // Differentiate between different hierarchy types diff --git a/src/SFGUI/SpinButton.cpp b/src/SFGUI/SpinButton.cpp index 4b48117d..6210628f 100644 --- a/src/SFGUI/SpinButton.cpp +++ b/src/SFGUI/SpinButton.cpp @@ -72,12 +72,12 @@ bool SpinButton::IsIncreaseStepperPressed() const { return m_increase_pressed; } -void SpinButton::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) { +bool SpinButton::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) { float border_width( Context::Get().GetEngine().GetProperty( "BorderWidth", shared_from_this() ) ); float stepper_aspect_ratio( Context::Get().GetEngine().GetProperty( "StepperAspectRatio", shared_from_this() ) ); if( button != sf::Mouse::Left ) { - return; + return false; } auto stepper_height = ( GetAllocation().height / 2.f ) - border_width; @@ -101,7 +101,7 @@ void SpinButton::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, i m_repeat_wait = true; Invalidate(); - return; + return true; } // Bottom stepper. @@ -117,7 +117,7 @@ void SpinButton::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, i m_repeat_wait = true; Invalidate(); - return; + return true; } } else { @@ -129,7 +129,7 @@ void SpinButton::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, i m_increase_pressed = false; } - Entry::HandleMouseButtonEvent( button, press, x, y ); + return Entry::HandleMouseButtonEvent( button, press, x, y ); } void SpinButton::HandleUpdate( float seconds ) { @@ -166,33 +166,33 @@ void SpinButton::HandleUpdate( float seconds ) { } } -void SpinButton::HandleTextEvent( sf::Uint32 character ) { +bool SpinButton::HandleTextEvent( sf::Uint32 character ) { if( isdigit( static_cast( character ) ) ) { - Entry::HandleTextEvent( character ); - return; + return Entry::HandleTextEvent( character ); } if( ( character == '.' ) && ( GetText().find( "." ) == sf::String::InvalidPos ) ) { - Entry::HandleTextEvent( character ); - return; + return Entry::HandleTextEvent( character ); } if( ( character == '-' ) && ( GetText().find( "-" ) == sf::String::InvalidPos ) && ( GetCursorPosition() == 0 ) ) { - Entry::HandleTextEvent( character ); - return; + return Entry::HandleTextEvent( character ); } + return false; } -void SpinButton::HandleKeyEvent( sf::Keyboard::Key key, bool press ) { - Entry::HandleKeyEvent( key, press ); +bool SpinButton::HandleKeyEvent( sf::Keyboard::Key key, bool press ) { + bool bHandled = Entry::HandleKeyEvent( key, press ); if( !press || !HasFocus() ) { - return; + return bHandled; } if( key == sf::Keyboard::Return ) { + bHandled = true; GrabFocus( Widget::Ptr() ); } + return bHandled; } void SpinButton::HandleSizeChange() { diff --git a/src/SFGUI/Viewport.cpp b/src/SFGUI/Viewport.cpp index 45958f7b..1e95b1bb 100644 --- a/src/SFGUI/Viewport.cpp +++ b/src/SFGUI/Viewport.cpp @@ -70,10 +70,11 @@ void Viewport::HandleAbsolutePositionChange() { Container::HandleAbsolutePositionChange(); } -void Viewport::HandleEvent( const sf::Event& event ) { +bool Viewport::HandleEvent( const sf::Event& event ) { + bool bHandled = false; // Ignore event when widget is not visible. if( !IsGloballyVisible() ) { - return; + return bHandled; } // Pass event to child @@ -92,7 +93,7 @@ void Viewport::HandleEvent( const sf::Event& event ) { altered_event.mouseButton.x += static_cast( offset_x ); altered_event.mouseButton.y += static_cast( offset_y ); - GetChild()->HandleEvent( altered_event ); + bHandled = GetChild()->HandleEvent( altered_event ); } break; case sf::Event::MouseLeft: { // Nice hack to cause scrolledwindow children to get out of @@ -100,7 +101,7 @@ void Viewport::HandleEvent( const sf::Event& event ) { sf::Event altered_event( event ); altered_event.mouseMove.x = -1; altered_event.mouseMove.y = -1; - GetChild()->HandleEvent( altered_event ); + bHandled = GetChild()->HandleEvent( altered_event ); } break; case sf::Event::MouseMoved: { // All MouseMove events sf::Event altered_event( event ); @@ -114,7 +115,7 @@ void Viewport::HandleEvent( const sf::Event& event ) { altered_event.mouseMove.x += static_cast( offset_x ); altered_event.mouseMove.y += static_cast( offset_y ); } - GetChild()->HandleEvent( altered_event ); + bHandled = GetChild()->HandleEvent( altered_event ); } break; case sf::Event::MouseWheelMoved: { // All MouseWheel events if( !GetAllocation().contains( static_cast( event.mouseWheel.x ), static_cast( event.mouseWheel.y ) ) ) { @@ -125,13 +126,14 @@ void Viewport::HandleEvent( const sf::Event& event ) { altered_event.mouseWheel.x += static_cast( offset_x ); altered_event.mouseWheel.y += static_cast( offset_y ); - GetChild()->HandleEvent( altered_event ); + bHandled = GetChild()->HandleEvent( altered_event ); } break; default: { // Pass event unaltered if it is a non-mouse event - GetChild()->HandleEvent( event ); + bHandled = GetChild()->HandleEvent( event ); } break; } } + return bHandled; } sf::Vector2f Viewport::GetAbsolutePosition() const { diff --git a/src/SFGUI/Widget.cpp b/src/SFGUI/Widget.cpp index 3a25ca2e..215bd64c 100644 --- a/src/SFGUI/Widget.cpp +++ b/src/SFGUI/Widget.cpp @@ -287,24 +287,25 @@ void Widget::SetPosition( const sf::Vector2f& position ) { } } -void Widget::HandleEvent( const sf::Event& event ) { +bool Widget::HandleEvent( const sf::Event& event ) { + bool bHandled = false; if( !IsGloballyVisible() ) { - return; + return bHandled; } // Ignore the event if widget is insensitive - if ( GetState() == State::INSENSITIVE ) { - return; + if ( !IsEnabled() ) { + return bHandled; } // Ignore the event if another widget is active. if( !IsActiveWidget() && !IsActiveWidget( PtrConst() ) ) { - return; + return bHandled; } // Ignore the event if another widget is modal. if( HasModal() && !IsModal() ) { - return; + return bHandled; } // Set widget active in context. @@ -380,10 +381,11 @@ void Widget::HandleEvent( const sf::Event& event ) { case sf::Event::MouseButtonPressed: if( !IsMouseButtonDown() && IsMouseInWidget() ) { + bHandled = true; SetMouseButtonDown( event.mouseButton.button ); } - HandleMouseButtonEvent( event.mouseButton.button, true, event.mouseButton.x, event.mouseButton.y ); + bHandled = HandleMouseButtonEvent( event.mouseButton.button, true, event.mouseButton.x, event.mouseButton.y ) || bHandled; if( IsMouseInWidget() ) { if( event.mouseButton.button == sf::Mouse::Left ) { @@ -403,6 +405,7 @@ void Widget::HandleEvent( const sf::Event& event ) { // When released inside the widget, the event can be considered a click. if( IsMouseInWidget() ) { + bHandled = true; HandleMouseClick( event.mouseButton.button, event.mouseButton.x, event.mouseButton.y ); if( event.mouseButton.button == sf::Mouse::Left ) { @@ -414,7 +417,7 @@ void Widget::HandleEvent( const sf::Event& event ) { } } - HandleMouseButtonEvent( event.mouseButton.button, false, event.mouseButton.x, event.mouseButton.y ); + bHandled = HandleMouseButtonEvent( event.mouseButton.button, false, event.mouseButton.x, event.mouseButton.y ) || bHandled; if( emit_left_click ) { GetSignals().Emit( OnLeftClick ); @@ -437,7 +440,7 @@ void Widget::HandleEvent( const sf::Event& event ) { case sf::Event::KeyPressed: if( HasFocus() ) { // TODO: Delegate event too when widget's not active? - HandleKeyEvent( event.key.code, true ); + bHandled = HandleKeyEvent( event.key.code, true ); GetSignals().Emit( OnKeyPress ); } @@ -446,7 +449,7 @@ void Widget::HandleEvent( const sf::Event& event ) { case sf::Event::KeyReleased: if( HasFocus() ) { // TODO: Delegate event too when widget's not active? - HandleKeyEvent( event.key.code, false ); + bHandled = HandleKeyEvent( event.key.code, false ); GetSignals().Emit( OnKeyRelease ); } break; @@ -454,7 +457,7 @@ void Widget::HandleEvent( const sf::Event& event ) { case sf::Event::TextEntered: if( HasFocus() ) { // TODO: Delegate event too when widget's not active? - HandleTextEvent( event.text.unicode ); + bHandled = HandleTextEvent( event.text.unicode ); GetSignals().Emit( OnText ); } break; @@ -467,6 +470,7 @@ void Widget::HandleEvent( const sf::Event& event ) { SetState( State::NORMAL ); throw; } + return bHandled; } void Widget::SetState( State state ) { @@ -563,6 +567,18 @@ void Widget::Show( bool show ) { RequestResize(); } +bool Widget::IsEnabled() const { + return GetState() != State::INSENSITIVE && GetState() != State::PARENT_INSENSITIVE; +} + +void Widget::Enable( bool enable ) { + State cur_state = GetState(); + if ( enable && cur_state == State::INSENSITIVE ) + SetState(State::NORMAL); + else if ( !enable && cur_state != State::PARENT_INSENSITIVE && cur_state != State::INSENSITIVE ) + SetState(State::INSENSITIVE); +} + const sf::Vector2f& Widget::GetRequisition() const { return m_requisition; } @@ -748,10 +764,13 @@ Widget::WidgetsList Widget::GetWidgetsByClass( const std::string& class_name ) { void Widget::HandleMouseMoveEvent( int /*x*/, int /*y*/ ) { } -void Widget::HandleMouseButtonEvent( sf::Mouse::Button /*button*/, bool /*press*/, int /*x*/, int /*y*/ ) { +bool Widget::HandleMouseButtonEvent( sf::Mouse::Button /*button*/, bool /*press*/, int /*x*/, int /*y*/ ) { + return false; } -void Widget::HandleKeyEvent( sf::Keyboard::Key /*key*/, bool /*press*/ ) { + +bool Widget::HandleKeyEvent( sf::Keyboard::Key /*key*/, bool /*press*/ ) { + return false; } void Widget::HandlePositionChange() { @@ -764,7 +783,8 @@ void Widget::HandleStateChange( State /*old_state*/ ) { Invalidate(); } -void Widget::HandleTextEvent( sf::Uint32 /*character*/ ) { +bool Widget::HandleTextEvent( sf::Uint32 /*character*/ ) { + return false; } void Widget::HandleMouseEnter( int /*x*/, int /*y*/ ) { diff --git a/src/SFGUI/Window.cpp b/src/SFGUI/Window.cpp index 31974bf5..4cdb4e68 100644 --- a/src/SFGUI/Window.cpp +++ b/src/SFGUI/Window.cpp @@ -130,15 +130,16 @@ const std::string& Window::GetName() const { return name; } -void Window::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) { +bool Window::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x, int y ) { + bool bHandled = false; if( button != sf::Mouse::Left ) { - return; + return bHandled; } if( !press ) { m_dragging = false; m_resizing = false; - return; + return bHandled; } unsigned int title_font_size( Context::Get().GetEngine().GetProperty( "FontSize", shared_from_this() ) ); @@ -157,6 +158,7 @@ void Window::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x ); if( area.contains( static_cast( x ), static_cast( y ) ) ) { + bHandled = true; if( HasStyle( TITLEBAR ) && !m_dragging ) { if( HasStyle( CLOSE ) ) { auto close_height( Context::Get().GetEngine().GetProperty( "CloseHeight", shared_from_this() ) ); @@ -193,6 +195,7 @@ void Window::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x area.height = handle_size; if( area.contains( static_cast( x ), static_cast( y ) ) ) { + bHandled = true; m_dragging = false; m_resizing = true; @@ -202,7 +205,7 @@ void Window::HandleMouseButtonEvent( sf::Mouse::Button button, bool press, int x ); } } - + return bHandled; } void Window::HandleMouseMoveEvent( int x, int y ) {