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

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

parent de03accd
/* /*
* 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 ) ...@@ -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,42 +217,76 @@ int MODULE_TOOLS::EnumeratePads( const TOOL_EVENT& aEvent ) ...@@ -217,42 +217,76 @@ 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();
collector.Empty(); if( evt->IsClick( BUT_LEFT ) )
collector.Collect( m_board, types, wxPoint( cursorPos.x, cursorPos.y ), guide );
for( int i = 0; i < collector.GetCount(); ++i )
{ {
if( collector[i]->Type() == PCB_PAD_T ) oldCursorPos = m_controls->GetCursorPosition();
{ collector.Empty();
D_PAD* pad = static_cast<D_PAD*>( collector[i] ); collector.Collect( m_board, types, wxPoint( cursorPos.x, cursorPos.y ), guide );
std::set<D_PAD*>::iterator it = allPads.find( pad );
// Add the pad to the list, if it was not selected previously.. for( int i = 0; i < collector.GetCount(); ++i )
if( it != allPads.end() ) {
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 )
{ {
allPads.erase( it ); if( collector[i]->Type() == PCB_PAD_T )
pads.push_back( pad ); selectedPads.push_back( static_cast<D_PAD*>( collector[i] ) );
pad->SetSelected();
} }
}
// ..or remove it from the list if it was clicked selectedPads.unique();
else if( evt->IsClick( BUT_LEFT ) ) }
{
allPads.insert( pad ); BOOST_FOREACH( D_PAD* pad, selectedPads )
pads.remove( pad ); {
pad->ClearSelected(); std::set<D_PAD*>::iterator it = allPads.find( pad );
}
// Add the pad to the list, if it was not selected previously..
if( it != allPads.end() )
{
allPads.erase( it );
pads.push_back( pad );
pad->SetSelected();
}
// ..or remove it from the list if it was clicked
else if( evt->IsClick( BUT_LEFT ) )
{
allPads.insert( pad );
pads.remove( pad );
pad->ClearSelected();
} }
} }
oldCursorPos = cursorPos;
} }
else if( ( evt->IsKeyPressed() && evt->KeyCode() == WXK_RETURN ) || else if( ( evt->IsKeyPressed() && evt->KeyCode() == WXK_RETURN ) ||
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment