GRID_HELPER: Keep edited items out of snap
Distinguish between the snap-from and snap-to items. Previously, we used the SELECTED or DRAGGED flags but the flagging arcitecture was inherently fragile. This specifies items directly that should not be used as snap targets. Fixes: lp:1802795 * https://bugs.launchpad.net/kicad/+bug/1802795
This commit is contained in:
parent
b35b1bb644
commit
940353afde
|
@ -366,6 +366,16 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
controls->SetAutoPan( true );
|
||||
|
||||
auto curr_item = static_cast<BOARD_ITEM*>( selection.Front() );
|
||||
std::vector<BOARD_ITEM*> sel_items;
|
||||
|
||||
for( auto it : selection )
|
||||
{
|
||||
auto item = dynamic_cast<BOARD_ITEM*>( it );
|
||||
|
||||
if( item )
|
||||
sel_items.push_back( item );
|
||||
}
|
||||
|
||||
bool restore_state = false;
|
||||
VECTOR2I totalMovement;
|
||||
GRID_HELPER grid( editFrame );
|
||||
|
@ -385,7 +395,8 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
if( m_dragging && evt->Category() == TC_MOUSE )
|
||||
{
|
||||
m_cursor = grid.BestSnapAnchor( controls->GetMousePosition(), item_layers );
|
||||
m_cursor = grid.BestSnapAnchor( controls->GetMousePosition(),
|
||||
item_layers, sel_items );
|
||||
controls->ForceCursorPosition(true, m_cursor );
|
||||
VECTOR2I movement( m_cursor - prevPos );
|
||||
selection.SetReferencePoint( m_cursor );
|
||||
|
@ -438,15 +449,6 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
}
|
||||
|
||||
for( auto item : selection )
|
||||
{
|
||||
item->SetFlags( IS_DRAGGED ); //todo: flags structure rework
|
||||
|
||||
if( auto module = dyn_cast<MODULE*>( item ) )
|
||||
module->RunOnChildren( [&] ( BOARD_ITEM* bitem )
|
||||
{ bitem->SetFlags( IS_DRAGGED ); } );
|
||||
}
|
||||
|
||||
editFrame->UndoRedoBlock( true );
|
||||
m_cursor = controls->GetCursorPosition();
|
||||
|
||||
|
@ -567,15 +569,6 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
if( unselect || restore_state )
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
||||
for( auto item : selection )
|
||||
{
|
||||
item->ClearFlags( IS_DRAGGED ); //todo: flags structure rework
|
||||
|
||||
if( auto module = dyn_cast<MODULE*>( item ) )
|
||||
module->RunOnChildren( [&] ( BOARD_ITEM* bitem )
|
||||
{ bitem->SetFlags( IS_DRAGGED ); } );
|
||||
}
|
||||
|
||||
if( restore_state )
|
||||
m_commit->Revert();
|
||||
else
|
||||
|
|
|
@ -226,7 +226,8 @@ VECTOR2I GRID_HELPER::BestDragOrigin( const VECTOR2I &aMousePos, BOARD_ITEM* aIt
|
|||
}
|
||||
|
||||
|
||||
std::set<BOARD_ITEM*> GRID_HELPER::queryVisible( const BOX2I& aArea ) const
|
||||
std::set<BOARD_ITEM*> GRID_HELPER::queryVisible( const BOX2I& aArea,
|
||||
const std::vector<BOARD_ITEM*> aSkip ) const
|
||||
{
|
||||
std::set<BOARD_ITEM*> items;
|
||||
std::vector<KIGFX::VIEW::LAYER_ITEM_PAIR> selectedItems;
|
||||
|
@ -241,14 +242,15 @@ std::set<BOARD_ITEM*> GRID_HELPER::queryVisible( const BOX2I& aArea ) const
|
|||
BOARD_ITEM* item = static_cast<BOARD_ITEM*>( it.first );
|
||||
|
||||
// The item must be visible and on an active layer
|
||||
// It cannot be moving as a moving item is being snapped _from_
|
||||
// rather than considered a potential target
|
||||
if( view->IsVisible( item )
|
||||
&& ( !isHighContrast || activeLayers.count( it.second ) )
|
||||
&& !item->IsDragging() )
|
||||
&& ( !isHighContrast || activeLayers.count( it.second ) ) )
|
||||
items.insert ( item );
|
||||
}
|
||||
|
||||
|
||||
for( auto ii : aSkip )
|
||||
items.erase( ii );
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
|
@ -256,17 +258,22 @@ std::set<BOARD_ITEM*> GRID_HELPER::queryVisible( const BOX2I& aArea ) const
|
|||
VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aDraggedItem )
|
||||
{
|
||||
LSET layers;
|
||||
std::vector<BOARD_ITEM*> item;
|
||||
|
||||
if( aDraggedItem )
|
||||
{
|
||||
layers = aDraggedItem->GetLayerSet();
|
||||
item.push_back( aDraggedItem );
|
||||
}
|
||||
else
|
||||
layers = LSET::AllLayersMask();
|
||||
|
||||
return BestSnapAnchor( aOrigin, layers );
|
||||
return BestSnapAnchor( aOrigin, layers, item );
|
||||
}
|
||||
|
||||
|
||||
VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers )
|
||||
VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers,
|
||||
const std::vector<BOARD_ITEM*> aSkip )
|
||||
{
|
||||
double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale();
|
||||
int snapRange = (int) ( m_snapSize / worldScale );
|
||||
|
@ -275,7 +282,7 @@ VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLaye
|
|||
|
||||
clearAnchors();
|
||||
|
||||
for( BOARD_ITEM* item : queryVisible( bb ) )
|
||||
for( BOARD_ITEM* item : queryVisible( bb, aSkip ) )
|
||||
{
|
||||
computeAnchors( item, aOrigin );
|
||||
}
|
||||
|
|
|
@ -57,7 +57,8 @@ public:
|
|||
|
||||
VECTOR2I BestDragOrigin( const VECTOR2I& aMousePos, BOARD_ITEM* aItem );
|
||||
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aDraggedItem );
|
||||
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers );
|
||||
VECTOR2I BestSnapAnchor( const VECTOR2I& aOrigin, const LSET& aLayers,
|
||||
const std::vector<BOARD_ITEM*> aSkip = {} );
|
||||
|
||||
void SetSnap( bool aSnap )
|
||||
{
|
||||
|
@ -94,7 +95,8 @@ private:
|
|||
|
||||
std::vector<ANCHOR> m_anchors;
|
||||
|
||||
std::set<BOARD_ITEM*> queryVisible( const BOX2I& aArea ) const;
|
||||
std::set<BOARD_ITEM*> queryVisible( const BOX2I& aArea,
|
||||
const std::vector<BOARD_ITEM*> aSkip ) const;
|
||||
|
||||
void addAnchor( const VECTOR2I& aPos, int aFlags = CORNER | SNAPPABLE, BOARD_ITEM* aItem = NULL )
|
||||
{
|
||||
|
|
|
@ -364,7 +364,8 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
//TODO: unify the constraints to solve simultaneously instead of sequentially
|
||||
m_editedPoint->SetPosition( grid.BestSnapAnchor( evt->Position(), snapLayers ) );
|
||||
m_editedPoint->SetPosition( grid.BestSnapAnchor( evt->Position(),
|
||||
snapLayers, { item } ) );
|
||||
bool enableAltConstraint = !!evt->Modifier( MD_CTRL );
|
||||
|
||||
if( enableAltConstraint != (bool) m_altConstraint ) // alternative constraint
|
||||
|
@ -375,7 +376,8 @@ int POINT_EDITOR::OnSelectionChange( const TOOL_EVENT& aEvent )
|
|||
else
|
||||
m_editedPoint->ApplyConstraint();
|
||||
|
||||
m_editedPoint->SetPosition( grid.BestSnapAnchor( m_editedPoint->GetPosition(), snapLayers ) );
|
||||
m_editedPoint->SetPosition( grid.BestSnapAnchor( m_editedPoint->GetPosition(),
|
||||
snapLayers, { item } ) );
|
||||
|
||||
updateItem();
|
||||
updatePoints();
|
||||
|
|
Loading…
Reference in New Issue