From 994be43782f1182b65f899cd9f79ee7360c2fdb4 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Tue, 8 Jan 2019 17:17:49 -0800 Subject: [PATCH] ratsnest: Calculate ratsnest per pad The local/dynamic ratsnest needs to calculate on a per-pad basis as the module is always listed as having a visible ratsnest. This fixes the finalized ratsnest viewed when routing as well as the show local ratsnest regression. Fixes: lp:1811010 * https://bugs.launchpad.net/kicad/+bug/1811010 --- pcbnew/ratsnest.cpp | 3 -- pcbnew/tools/edit_tool.cpp | 12 ++++++ pcbnew/tools/edit_tool.h | 8 ++++ pcbnew/tools/pcb_editor_control.cpp | 60 +++++++++++++++++++++-------- pcbnew/tools/picker_tool.cpp | 7 +++- pcbnew/tools/picker_tool.h | 1 + 6 files changed, 72 insertions(+), 19 deletions(-) diff --git a/pcbnew/ratsnest.cpp b/pcbnew/ratsnest.cpp index fddfc433e0..89944af8bc 100644 --- a/pcbnew/ratsnest.cpp +++ b/pcbnew/ratsnest.cpp @@ -192,9 +192,6 @@ static MODULE movedModule( nullptr ); void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule, wxPoint aMoveVector ) { - if( !GetBoard()->IsElementVisible( LAYER_RATSNEST ) ) - return; - auto connectivity = GetBoard()->GetConnectivity(); movedModule = *aModule; diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index 62c6ac3d27..69b156b7e4 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -1215,6 +1215,18 @@ int EDIT_TOOL::CreateArray( const TOOL_EVENT& aEvent ) } +void EDIT_TOOL::PadFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector ) +{ + for( int i = aCollector.GetCount() - 1; i >= 0; i-- ) + { + BOARD_ITEM* item = static_cast( aCollector[i] ); + + if( item->Type() != PCB_PAD_T ) + aCollector.Remove( i ); + } +} + + void EDIT_TOOL::FootprintFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector ) { for( int i = aCollector.GetCount() - 1; i >= 0; i-- ) diff --git a/pcbnew/tools/edit_tool.h b/pcbnew/tools/edit_tool.h index e3d4dcbe5d..9e77e7b295 100644 --- a/pcbnew/tools/edit_tool.h +++ b/pcbnew/tools/edit_tool.h @@ -158,6 +158,14 @@ public: */ static void FootprintFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector ); + /** + * Function PadFilter() + * + * A selection filter which prunes the selection to contain only items + * of type PCB_PAD_T + */ + static void PadFilter( const VECTOR2I&, GENERAL_COLLECTOR& aCollector ); + ///> Sets up handlers for various events. void setTransitions() override; diff --git a/pcbnew/tools/pcb_editor_control.cpp b/pcbnew/tools/pcb_editor_control.cpp index 9e386b2556..992efba64c 100644 --- a/pcbnew/tools/pcb_editor_control.cpp +++ b/pcbnew/tools/pcb_editor_control.cpp @@ -1089,17 +1089,21 @@ int PCB_EDITOR_CONTROL::HighlightNetCursor( const TOOL_EVENT& aEvent ) static bool showLocalRatsnest( TOOL_MANAGER* aToolMgr, BOARD* aBoard, const VECTOR2D& aPosition ) { auto selectionTool = aToolMgr->GetTool(); - auto modules = aBoard->Modules(); aToolMgr->RunAction( PCB_ACTIONS::selectionClear, true ); - aToolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, EDIT_TOOL::FootprintFilter ); + aToolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, EDIT_TOOL::PadFilter ); + SELECTION& selection = selectionTool->GetSelection(); - const SELECTION& selection = selectionTool->GetSelection(); + if( selection.Empty() ) + { + aToolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, EDIT_TOOL::FootprintFilter ); + selection = selectionTool->GetSelection(); + } if( selection.Empty() ) { // Clear the previous local ratsnest if we click off all items - for( auto mod : modules ) + for( auto mod : aBoard->Modules() ) { for( auto pad : mod->Pads() ) pad->SetLocalRatsnestVisible( aBoard->IsElementVisible( LAYER_RATSNEST ) ); @@ -1109,10 +1113,19 @@ static bool showLocalRatsnest( TOOL_MANAGER* aToolMgr, BOARD* aBoard, const VECT { for( auto item : selection ) { - if( auto mod = dyn_cast(item) ) + if( auto pad = dyn_cast(item) ) { - for( auto pad : mod->Pads() ) - pad->SetLocalRatsnestVisible( !pad->GetLocalRatsnestVisible() ); + pad->SetLocalRatsnestVisible( !pad->GetLocalRatsnestVisible() ); + } + else if( auto mod = dyn_cast(item) ) + { + printf("2\n"); + bool enable = !( *( mod->Pads().begin() ) )->GetLocalRatsnestVisible(); + + for( auto modpad : mod->Pads() ) + { + modpad->SetLocalRatsnestVisible( enable ); + } } } } @@ -1137,10 +1150,15 @@ int PCB_EDITOR_CONTROL::ShowLocalRatsnest( const TOOL_EVENT& aEvent ) picker->SetClickHandler( std::bind( showLocalRatsnest, m_toolMgr, board, _1 ) ); picker->SetFinalizeHandler( [ board ]( int aCondition ){ auto vis = board->IsElementVisible( LAYER_RATSNEST ); - for( auto mod : board->Modules() ) - for( auto pad : mod->Pads() ) - pad->SetLocalRatsnestVisible( vis ); + + if( aCondition != PICKER_TOOL::END_ACTIVATE ) + { + for( auto mod : board->Modules() ) + for( auto pad : mod->Pads() ) + pad->SetLocalRatsnestVisible( vis ); + } } ); + picker->SetSnapping( false ); picker->Activate(); Wait(); @@ -1155,7 +1173,7 @@ int PCB_EDITOR_CONTROL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent ) auto& selection = selectionTool->GetSelection(); auto connectivity = getModel()->GetConnectivity(); - if( selection.Empty() || !getModel()->IsElementVisible( LAYER_RATSNEST ) ) + if( selection.Empty() ) { connectivity->ClearDynamicRatsnest(); } @@ -1204,9 +1222,6 @@ void PCB_EDITOR_CONTROL::ratsnestTimer( wxTimerEvent& aEvent ) void PCB_EDITOR_CONTROL::calculateSelectionRatsnest() { - if( !board()->IsElementVisible( LAYER_RATSNEST ) ) - return; - auto selectionTool = m_toolMgr->GetTool(); auto& selection = selectionTool->GetSelection(); auto connectivity = board()->GetConnectivity(); @@ -1215,7 +1230,22 @@ void PCB_EDITOR_CONTROL::calculateSelectionRatsnest() items.reserve( selection.Size() ); for( auto item : selection ) - items.push_back( static_cast( item ) ); + { + auto board_item = static_cast( item ); + + if( board_item->Type() != PCB_MODULE_T && board_item->GetLocalRatsnestVisible() ) + { + items.push_back( board_item ); + } + else if( board_item->Type() == PCB_MODULE_T ) + { + for( auto pad : static_cast( item )->Pads() ) + { + if( pad->GetLocalRatsnestVisible() ) + items.push_back( pad ); + } + } + } connectivity->ComputeDynamicRatsnest( items ); } diff --git a/pcbnew/tools/picker_tool.cpp b/pcbnew/tools/picker_tool.cpp index e8d356fd26..2af3937911 100644 --- a/pcbnew/tools/picker_tool.cpp +++ b/pcbnew/tools/picker_tool.cpp @@ -99,7 +99,12 @@ int PICKER_TOOL::Main( const TOOL_EVENT& aEvent ) } } - finalize_state = EVT_CANCEL; + // Activating a new tool may have alternate finalization from canceling the current tool + if( evt->IsActivate() ) + finalize_state = END_ACTIVATE; + else + finalize_state = EVT_CANCEL; + break; } diff --git a/pcbnew/tools/picker_tool.h b/pcbnew/tools/picker_tool.h index 25b6ec8849..3527f6176c 100644 --- a/pcbnew/tools/picker_tool.h +++ b/pcbnew/tools/picker_tool.h @@ -46,6 +46,7 @@ public: { WAIT_CANCEL, CLICK_CANCEL, + END_ACTIVATE, EVT_CANCEL, EXCEPTION_CANCEL };