Commit 014905e7 authored by Maciej Suminski's avatar Maciej Suminski
Browse files

bugfix: pad enumerator skips pads if mouse cursor is moved too fast (GAL module editor).

parent de03accd
Loading
Loading
Loading
Loading
+58 −24
Original line number Original line Diff line number Diff line
/*
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 *
 * Copyright (C) 2014 CERN
 * Copyright (C) 2014-2015 CERN
 * @author Maciej Suminski <maciej.suminski@cern.ch>
 * @author Maciej Suminski <maciej.suminski@cern.ch>
 *
 *
 * This program is free software; you can redistribute it and/or
 * This program is free software; you can redistribute it and/or
@@ -195,7 +195,7 @@ int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent )
    guide.SetIgnoreModulesVals( true );
    guide.SetIgnoreModulesVals( true );
    guide.SetIgnoreModulesRefs( true );
    guide.SetIgnoreModulesRefs( true );


    // Create a set containing all pads (to avoid double adding to a list)
    // Create a set containing all pads (to avoid double adding to the list)
    for( D_PAD* p = module->Pads(); p; p = p->Next() )
    for( D_PAD* p = module->Pads(); p; p = p->Next() )
        allPads.insert( p );
        allPads.insert( p );


@@ -217,23 +217,56 @@ int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent )


    m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
    m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
    m_controls->ShowCursor( true );
    m_controls->ShowCursor( true );
    VECTOR2I oldCursorPos = m_controls->GetCursorPosition();
    std::list<D_PAD*> selectedPads;


    while( OPT_TOOL_EVENT evt = Wait() )
    while( OPT_TOOL_EVENT evt = Wait() )
    {
    {
        if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
        if( evt->IsDrag( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
        {
        {
            // Add pads to the list according to the selection order
            selectedPads.clear();
            VECTOR2I cursorPos = m_controls->GetCursorPosition();
            VECTOR2I cursorPos = m_controls->GetCursorPosition();


            if( evt->IsClick( BUT_LEFT ) )
            {
                oldCursorPos = m_controls->GetCursorPosition();
                collector.Empty();
                collector.Empty();
                collector.Collect( m_board, types, wxPoint( cursorPos.x, cursorPos.y ), guide );
                collector.Collect( m_board, types, wxPoint( cursorPos.x, cursorPos.y ), guide );


                for( int i = 0; i < collector.GetCount(); ++i )
                for( int i = 0; i < collector.GetCount(); ++i )
                {
                {
                    if( collector[i]->Type() == PCB_PAD_T )
                    if( collector[i]->Type() == PCB_PAD_T )
                        selectedPads.push_back( static_cast<D_PAD*>( collector[i] ) );
                }
            }
            else //evt->IsDrag( BUT_LEFT )
            {
                // wxWidgets deliver mouse move events not frequently enough, resulting in skipping
                // pads if the user moves cursor too fast. To solve it, create a line that approximates
                // the mouse move and select items intersecting with the line.
                int distance = ( cursorPos - oldCursorPos ).EuclideanNorm();
                int segments = distance / 100000 + 1;
                const wxPoint LINE_STEP( ( cursorPos - oldCursorPos ).x / segments,
                                         ( cursorPos - oldCursorPos ).y / segments );

                collector.Empty();
                for( int j = 0; j < segments; ++j ) {
                    collector.Collect( m_board, types,
                                       wxPoint( oldCursorPos.x, oldCursorPos.y ) + j * LINE_STEP,
                                       guide );

                    for( int i = 0; i < collector.GetCount(); ++i )
                    {
                    {
                    D_PAD* pad = static_cast<D_PAD*>( collector[i] );
                        if( collector[i]->Type() == PCB_PAD_T )
                            selectedPads.push_back( static_cast<D_PAD*>( collector[i] ) );
                    }
                }

                selectedPads.unique();
            }


            BOOST_FOREACH( D_PAD* pad, selectedPads )
            {
                std::set<D_PAD*>::iterator it = allPads.find( pad );
                std::set<D_PAD*>::iterator it = allPads.find( pad );


                // Add the pad to the list, if it was not selected previously..
                // Add the pad to the list, if it was not selected previously..
@@ -252,7 +285,8 @@ int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent )
                    pad->ClearSelected();
                    pad->ClearSelected();
                }
                }
            }
            }
            }

            oldCursorPos = cursorPos;
        }
        }


        else if( ( evt->IsKeyPressed() && evt->KeyCode() == WXK_RETURN ) ||
        else if( ( evt->IsKeyPressed() && evt->KeyCode() == WXK_RETURN ) ||