Fix some snarled up event processing.

See the bug for details.  It's complicated.

Fixes https://gitlab.com/kicad/code/kicad/issues/5336
This commit is contained in:
Jeff Young 2020-08-24 13:17:58 +01:00
parent dfe3270142
commit 502f2ca2ef
4 changed files with 36 additions and 27 deletions

View File

@ -319,7 +319,10 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector<BOARD_ITEM*>&
void CONNECTIVITY_DATA::ClearDynamicRatsnest()
{
m_connAlgo->ForEachAnchor( [] ( CN_ANCHOR& anchor ) { anchor.SetNoLine( false ); } );
m_connAlgo->ForEachAnchor( []( CN_ANCHOR& anchor )
{
anchor.SetNoLine( false );
} );
HideDynamicRatsnest();
}

View File

@ -334,7 +334,9 @@ int EDIT_TOOL::MoveWithReference( const TOOL_EVENT& aEvent )
}
int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
// Note: aEvent MUST NOT be const&; the source will get de-allocated if we go into the picker's
// event loop.
int EDIT_TOOL::doMoveSelection( TOOL_EVENT aEvent, bool aPickReference )
{
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
KIGFX::VIEW_CONTROLS* controls = getViewControls();
@ -353,6 +355,7 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
LSET item_layers = selection.GetSelectionLayers();
bool unselect = selection.IsHover(); // N.B. This must be saved before the re-selection below
VECTOR2I pickedReferencePoint;
// Now filter out locked pads. We cannot do this in the first RequestSelection() as we need
// the item_layers when a pad is the selection front (ie: will become curr_tiem).
@ -366,11 +369,23 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
return 0;
std::string tool = aEvent.GetCommandStr().get();
editFrame->PushTool( tool );
Activate();
controls->ShowCursor( true );
controls->SetAutoPan( true );
if( aPickReference && !pickReferencePoint( _( "Select reference point for move..." ), "", "",
pickedReferencePoint ) )
{
if( unselect )
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
editFrame->PopTool( tool );
return 0;
}
std::vector<BOARD_ITEM*> sel_items;
for( EDA_ITEM* item : selection )
@ -449,8 +464,10 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
m_toolMgr->PostEvent( EVENTS::SelectedItemsMoved );
}
else if( !m_dragging ) // Prepare to start dragging
else if( !m_dragging && !evt->IsAction( &ACTIONS::refreshPreview ) )
{
// Prepare to start dragging
if( !( evt->IsAction( &PCB_ACTIONS::move )
|| evt->IsAction( &PCB_ACTIONS::moveWithReference ) )
&& isInteractiveDragEnabled() )
@ -488,8 +505,8 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
// If moving a group, record position of all the descendants for undo
if( item->Type() == PCB_GROUP_T )
{
static_cast<PCB_GROUP*>( item )->RunOnDescendants(
[&]( BOARD_ITEM* bItem )
PCB_GROUP* group = static_cast<PCB_GROUP*>( item );
group->RunOnDescendants( [&]( BOARD_ITEM* bItem )
{
m_commit->Modify( bItem );
});
@ -535,20 +552,9 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference )
// movement vector could be computed later
if( aPickReference )
{
VECTOR2I ref;
if( pickReferencePoint( _( "Select reference point for move..." ),
"", "", ref ) )
{
selection.SetReferencePoint( ref );
controls->ForceCursorPosition( true, ref );
m_cursor = ref;
}
else
{
// Cancel before move started
break;
}
selection.SetReferencePoint( pickedReferencePoint );
controls->ForceCursorPosition( true, pickedReferencePoint );
m_cursor = pickedReferencePoint;
}
else
{

View File

@ -185,7 +185,7 @@ private:
bool isInteractiveDragEnabled() const;
bool isRouterActive() const;
int doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference = false );
int doMoveSelection( TOOL_EVENT aEvent, bool aPickReference = false );
bool pickReferencePoint( const wxString& aTooltip, const wxString& aSuccessMessage,
const wxString& aCanceledMessage, VECTOR2I& aReferencePoint );

View File

@ -386,9 +386,9 @@ int PCB_INSPECTION_TOOL::LocalRatsnestTool( const TOOL_EVENT& aEvent )
{
if( aCondition != PCBNEW_PICKER_TOOL::END_ACTIVATE )
{
for( auto mod : board->Modules() )
for( MODULE* mod : board->Modules() )
{
for( auto pad : mod->Pads() )
for( D_PAD* pad : mod->Pads() )
pad->SetLocalRatsnestVisible( opt.m_ShowGlobalRatsnest );
}
}