pcbnew/copy&paste: multiple improvements:
- fixed netcode propagation bug - factored out EDIT_TOOL::m_offset, now selection offset is stored in SELECTION class - added VECTOR2I-based Move/Flip/Rotate methods in BOARD_ITEM
This commit is contained in:
parent
f573a2e685
commit
5731000135
|
@ -244,6 +244,11 @@ public:
|
|||
wxMessageBox( wxT( "virtual BOARD_ITEM::Move used, should not occur" ), GetClass() );
|
||||
}
|
||||
|
||||
void Move( const VECTOR2I& aMoveVector )
|
||||
{
|
||||
Move( wxPoint( aMoveVector.x, aMoveVector.y ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Rotate
|
||||
* Rotate this object.
|
||||
|
@ -255,6 +260,12 @@ public:
|
|||
wxMessageBox( wxT( "virtual BOARD_ITEM::Rotate used, should not occur" ), GetClass() );
|
||||
}
|
||||
|
||||
void Rotate( const VECTOR2I& aRotCentre, double aAngle )
|
||||
{
|
||||
Rotate( wxPoint( aRotCentre.x, aRotCentre.y ), aAngle );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Function Flip
|
||||
* Flip this object, i.e. change the board side for this object
|
||||
|
@ -265,6 +276,11 @@ public:
|
|||
wxMessageBox( wxT( "virtual BOARD_ITEM::Flip used, should not occur" ), GetClass() );
|
||||
}
|
||||
|
||||
void Flip( const VECTOR2I& aCentre )
|
||||
{
|
||||
Flip( wxPoint( aCentre.x, aCentre.y ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetBoard
|
||||
* returns the BOARD in which this BOARD_ITEM resides, or NULL if none.
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include <functional>
|
||||
using namespace std::placeholders;
|
||||
|
||||
#include "pcb_draw_panel_gal.h"
|
||||
|
||||
BOARD_COMMIT::BOARD_COMMIT( PCB_TOOL* aTool )
|
||||
{
|
||||
m_toolMgr = aTool->GetManager();
|
||||
|
@ -218,7 +220,6 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry )
|
|||
if( !( changeFlags & CHT_DONE ) )
|
||||
board->Remove( boardItem );
|
||||
|
||||
//ratsnest->Remove( boardItem ); // currently done by BOARD::Remove()
|
||||
break;
|
||||
|
||||
case PCB_MODULE_T:
|
||||
|
@ -282,7 +283,11 @@ void BOARD_COMMIT::Push( const wxString& aMessage, bool aCreateUndoEntry )
|
|||
toolMgr->PostEvent( { TC_MESSAGE, TA_MODEL_CHANGE, AS_GLOBAL } );
|
||||
|
||||
if ( !m_editModules )
|
||||
{
|
||||
auto panel = static_cast<PCB_DRAW_PANEL_GAL *>( frame->GetGalCanvas() );
|
||||
connectivity->RecalculateRatsnest();
|
||||
panel->RedrawRatsnest();
|
||||
}
|
||||
|
||||
frame->OnModify();
|
||||
frame->UpdateMsgPanel();
|
||||
|
|
|
@ -103,7 +103,6 @@ BOARD::BOARD() :
|
|||
|
||||
// Initialize ratsnest
|
||||
m_connectivity.reset( new CONNECTIVITY_DATA() );
|
||||
m_connectivity->Build( this );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ CONNECTIVITY_DATA::~CONNECTIVITY_DATA()
|
|||
|
||||
bool CONNECTIVITY_DATA::Add( BOARD_ITEM* aItem )
|
||||
{
|
||||
printf("add %p type %d\n", aItem, aItem->Type() );
|
||||
m_connAlgo->Add( aItem );
|
||||
return true;
|
||||
}
|
||||
|
@ -72,7 +71,6 @@ void CONNECTIVITY_DATA::Build( BOARD* aBoard )
|
|||
{
|
||||
m_connAlgo.reset( new CN_CONNECTIVITY_ALGO );
|
||||
m_connAlgo->Build( aBoard );
|
||||
|
||||
RecalculateRatsnest();
|
||||
}
|
||||
|
||||
|
@ -194,12 +192,15 @@ void CONNECTIVITY_DATA::BlockRatsnestItems( const std::vector<BOARD_ITEM*>& aIte
|
|||
|
||||
for( auto item : citems )
|
||||
{
|
||||
auto& entry = m_connAlgo->ItemEntry( item );
|
||||
|
||||
for( auto cnItem : entry.GetItems() )
|
||||
if ( m_connAlgo->ItemExists( item ) )
|
||||
{
|
||||
for( auto anchor : cnItem->Anchors() )
|
||||
anchor->SetNoLine( true );
|
||||
auto& entry = m_connAlgo->ItemEntry( item );
|
||||
|
||||
for( auto cnItem : entry.GetItems() )
|
||||
{
|
||||
for( auto anchor : cnItem->Anchors() )
|
||||
anchor->SetNoLine( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -220,7 +220,6 @@ void CN_CONNECTIVITY_ALGO::markItemNetAsDirty( const BOARD_ITEM* aItem )
|
|||
|
||||
bool CN_CONNECTIVITY_ALGO::Add( BOARD_ITEM* aItem )
|
||||
{
|
||||
printf("%p add %p\n", this, aItem );
|
||||
markItemNetAsDirty ( aItem );
|
||||
|
||||
switch( aItem->Type() )
|
||||
|
@ -287,8 +286,6 @@ bool CN_CONNECTIVITY_ALGO::Add( BOARD_ITEM* aItem )
|
|||
return false;
|
||||
}
|
||||
|
||||
printf("post-dirty %d\n", isDirty()?1:0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -592,15 +589,11 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST
|
|||
CN_ITEM* head = nullptr;
|
||||
CLUSTERS clusters;
|
||||
|
||||
printf("searchcl isdirty %d\n", isDirty() ? 1: 0);
|
||||
|
||||
if( isDirty() )
|
||||
searchConnections( includeZones );
|
||||
|
||||
printf("%p: search\n", this);
|
||||
auto addToSearchList = [&head, withinAnyNet, aSingleNet, aTypes] ( CN_ITEM *aItem )
|
||||
{
|
||||
printf("ASL %p %d %d\n", aItem, aItem->Net(), aItem->Parent()->Type() );
|
||||
if( withinAnyNet && aItem->Net() <= 0 )
|
||||
return;
|
||||
|
||||
|
@ -755,12 +748,7 @@ void CN_CONNECTIVITY_ALGO::propagateConnections()
|
|||
{
|
||||
for( auto cluster : m_connClusters )
|
||||
{
|
||||
if( cluster->IsConflicting() )
|
||||
{
|
||||
|
||||
printf( "Conflicting nets in cluster %p\n", cluster.get() );
|
||||
}
|
||||
else if( cluster->IsOrphaned() )
|
||||
if( cluster->IsOrphaned() )
|
||||
{
|
||||
wxLogTrace( "CN", "Skipping orphaned cluster %p [net: %s]\n", cluster.get(),
|
||||
(const char*) cluster->OriginNetName().c_str() );
|
||||
|
@ -770,10 +758,8 @@ void CN_CONNECTIVITY_ALGO::propagateConnections()
|
|||
// normal cluster: just propagate from the pads
|
||||
int n_changed = 0;
|
||||
|
||||
printf("propagate %d\n", cluster->OriginNet() );
|
||||
for( auto item : *cluster )
|
||||
{
|
||||
printf("item %p net %d type %d\n", item, item->Parent()->GetNetCode(), item->Parent()->Type() );
|
||||
if( item->CanChangeNet() )
|
||||
{
|
||||
if( item->Valid() && item->Parent()->GetNetCode() != cluster->OriginNet() )
|
||||
|
|
|
@ -830,6 +830,11 @@ public:
|
|||
CN_CONNECTIVITY_ALGO();
|
||||
~CN_CONNECTIVITY_ALGO();
|
||||
|
||||
bool ItemExists( const BOARD_CONNECTED_ITEM* aItem )
|
||||
{
|
||||
return m_itemMap.find( aItem ) != m_itemMap.end();
|
||||
}
|
||||
|
||||
ITEM_MAP_ENTRY& ItemEntry( const BOARD_CONNECTED_ITEM* aItem )
|
||||
{
|
||||
return m_itemMap[ aItem ];
|
||||
|
|
|
@ -315,9 +315,6 @@ bool EDIT_TOOL::Init()
|
|||
menu.AddItem( PCB_ACTIONS::exchangeFootprints,
|
||||
singleModuleCondition );
|
||||
|
||||
m_offset.x = 0;
|
||||
m_offset.y = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -415,20 +412,18 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
if( m_dragging && evt->Category() == TC_MOUSE )
|
||||
{
|
||||
m_cursor = grid.BestSnapAnchor( evt->Position(), curr_item );
|
||||
|
||||
controls->ForceCursorPosition( true, m_cursor );
|
||||
|
||||
VECTOR2I movement( m_cursor - prevPos );// - curr_item->GetPosition();
|
||||
VECTOR2I movement( m_cursor - prevPos );
|
||||
selection.SetReferencePoint(m_cursor);
|
||||
|
||||
totalMovement += movement;
|
||||
prevPos = m_cursor;
|
||||
auto delta = movement + m_offset;
|
||||
|
||||
// Drag items to the current cursor position
|
||||
for( auto item : selection )
|
||||
static_cast<BOARD_ITEM*>( item )->Move( wxPoint( delta.x, delta.y ) );
|
||||
static_cast<BOARD_ITEM*>( item )->Move( movement );
|
||||
|
||||
m_offset = VECTOR2I(0, 0);
|
||||
}
|
||||
else if( !m_dragging ) // Prepare to start dragging
|
||||
{
|
||||
|
@ -452,23 +447,21 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
m_commit->Modify( item );
|
||||
|
||||
m_cursor = controls->GetCursorPosition();
|
||||
m_offset = VECTOR2I(0, 0);
|
||||
|
||||
auto refPoint = VECTOR2I( curr_item->GetPosition() );
|
||||
updateModificationPoint( selection );
|
||||
|
||||
if ( selection.HasReferencePoint() )
|
||||
{
|
||||
// start moving with the reference point attached to the cursor
|
||||
refPoint = selection.GetReferencePoint();
|
||||
grid.SetAuxAxes( false );
|
||||
|
||||
auto delta = m_cursor - selection.GetReferencePoint();
|
||||
|
||||
// Drag items to the current cursor position
|
||||
for( auto item : selection )
|
||||
static_cast<BOARD_ITEM*>( item )->Move( wxPoint( delta.x, delta.y ) );
|
||||
static_cast<BOARD_ITEM*>( item )->Move( delta );
|
||||
|
||||
selection.ClearReferencePoint();
|
||||
selection.SetReferencePoint( m_cursor );
|
||||
}
|
||||
else if( selection.Size() == 1 )
|
||||
{
|
||||
|
@ -508,8 +501,6 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
// Dispatch TOOL_ACTIONs
|
||||
else if( evt->Category() == TC_COMMAND )
|
||||
{
|
||||
wxPoint modPoint = getModificationPoint( selection );
|
||||
|
||||
if( evt->IsAction( &PCB_ACTIONS::remove ) )
|
||||
{
|
||||
// exit the loop, as there is no further processing for removed items
|
||||
|
@ -546,13 +537,6 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
//MoveExact( aEvent );
|
||||
break; // exit the loop - we move exactly, so we have finished moving
|
||||
}
|
||||
|
||||
// TODO check if the following can be removed
|
||||
if( m_dragging && !selection.Empty() )
|
||||
{
|
||||
// Update dragging offset (distance between cursor and the first dragged item)
|
||||
m_offset = static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() - modPoint;
|
||||
}
|
||||
}
|
||||
|
||||
else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
|
||||
|
@ -570,8 +554,6 @@ int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
|
|||
controls->SetAutoPan( false );
|
||||
|
||||
m_dragging = false;
|
||||
m_offset.x = 0;
|
||||
m_offset.y = 0;
|
||||
|
||||
if( unselect || restore )
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
|
||||
|
@ -679,7 +661,7 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
|
||||
|
||||
const auto& selection = m_selectionTool->RequestSelection();
|
||||
auto& selection = m_selectionTool->RequestSelection();
|
||||
|
||||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
@ -687,18 +669,15 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent )
|
|||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
||||
wxPoint modPoint = getModificationPoint( selection );
|
||||
updateModificationPoint( selection );
|
||||
const int rotateAngle = TOOL_EVT_UTILS::GetEventRotationAngle( *editFrame, aEvent );
|
||||
|
||||
for( auto item : selection )
|
||||
{
|
||||
m_commit->Modify( item );
|
||||
static_cast<BOARD_ITEM*>( item )->Rotate( modPoint, rotateAngle );
|
||||
static_cast<BOARD_ITEM*>( item )->Rotate( selection.GetReferencePoint(), rotateAngle );
|
||||
}
|
||||
|
||||
// Update the dragging point offset
|
||||
m_offset = static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() - modPoint;
|
||||
|
||||
if( !m_dragging )
|
||||
m_commit->Push( _( "Rotate" ) );
|
||||
|
||||
|
@ -751,7 +730,7 @@ static void mirrorPadX( D_PAD& aPad, const wxPoint& aMirrorPoint )
|
|||
|
||||
int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const auto& selection = m_selectionTool->RequestSelection();
|
||||
auto& selection = m_selectionTool->RequestSelection();
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
@ -759,7 +738,9 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
wxPoint mirrorPoint = getModificationPoint( selection );
|
||||
updateModificationPoint( selection );
|
||||
auto refPoint = selection.GetReferencePoint();
|
||||
wxPoint mirrorPoint( refPoint.x, refPoint.y );
|
||||
|
||||
for( auto item : selection )
|
||||
{
|
||||
|
@ -820,7 +801,7 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent )
|
|||
|
||||
int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
const auto& selection = m_selectionTool->RequestSelection();
|
||||
auto& selection = m_selectionTool->RequestSelection();
|
||||
|
||||
if( m_selectionTool->CheckLock() == SELECTION_LOCKED )
|
||||
return 0;
|
||||
|
@ -828,7 +809,8 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
|||
if( selection.Empty() )
|
||||
return 0;
|
||||
|
||||
wxPoint modPoint = getModificationPoint( selection );
|
||||
updateModificationPoint( selection );
|
||||
auto modPoint = selection.GetReferencePoint();
|
||||
|
||||
for( auto item : selection )
|
||||
{
|
||||
|
@ -836,9 +818,6 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent )
|
|||
static_cast<BOARD_ITEM*>( item )->Flip( modPoint );
|
||||
}
|
||||
|
||||
// Update the dragging point offset
|
||||
m_offset = static_cast<BOARD_ITEM*>( selection.Front() )->GetPosition() - modPoint;
|
||||
|
||||
if( !m_dragging )
|
||||
m_commit->Push( _( "Flip" ) );
|
||||
|
||||
|
@ -1256,13 +1235,16 @@ void EDIT_TOOL::setTransitions()
|
|||
}
|
||||
|
||||
|
||||
wxPoint EDIT_TOOL::getModificationPoint( const SELECTION& aSelection )
|
||||
bool EDIT_TOOL::updateModificationPoint( SELECTION& aSelection )
|
||||
{
|
||||
if ( aSelection.HasReferencePoint() )
|
||||
return false;
|
||||
|
||||
if( aSelection.Size() == 1 )
|
||||
{
|
||||
auto item = static_cast<BOARD_ITEM*>( aSelection.Front() );
|
||||
auto pos = item->GetPosition();
|
||||
return wxPoint( pos.x - m_offset.x, pos.y - m_offset.y );
|
||||
aSelection.SetReferencePoint( VECTOR2I( pos.x, pos.y ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1271,8 +1253,10 @@ wxPoint EDIT_TOOL::getModificationPoint( const SELECTION& aSelection )
|
|||
if( m_toolMgr->GetCurrentToolId() != m_toolId )
|
||||
m_cursor = getViewControls()->GetCursorPosition();
|
||||
|
||||
return wxPoint( m_cursor.x, m_cursor.y );
|
||||
aSelection.SetReferencePoint( m_cursor );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -168,9 +168,6 @@ private:
|
|||
///> Flag determining if anything is being dragged right now
|
||||
bool m_dragging;
|
||||
|
||||
///> Offset from the dragged item's center (anchor)
|
||||
VECTOR2I m_offset;
|
||||
|
||||
///> Last cursor position (needed for getModificationPoint() to avoid changes
|
||||
///> of edit reference point).
|
||||
VECTOR2I m_cursor;
|
||||
|
@ -178,6 +175,7 @@ private:
|
|||
///> Returns the right modification point (e.g. for rotation), depending on the number of
|
||||
///> selected items.
|
||||
wxPoint getModificationPoint( const SELECTION& aSelection );
|
||||
bool updateModificationPoint( SELECTION& aSelection );
|
||||
|
||||
int editFootprintInFpEditor( const TOOL_EVENT& aEvent );
|
||||
|
||||
|
|
|
@ -1161,13 +1161,10 @@ int PCB_EDITOR_CONTROL::ShowLocalRatsnest( const TOOL_EVENT& aEvent )
|
|||
|
||||
int PCB_EDITOR_CONTROL::UpdateSelectionRatsnest( const TOOL_EVENT& aEvent )
|
||||
{
|
||||
return 0;
|
||||
auto selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
auto& selection = selectionTool->GetSelection();
|
||||
auto connectivity = getModel<BOARD>()->GetConnectivity();
|
||||
|
||||
printf("UpdSelRat!\n");
|
||||
|
||||
if( selection.Empty() )
|
||||
{
|
||||
connectivity->ClearDynamicRatsnest();
|
||||
|
@ -1219,7 +1216,8 @@ void PCB_EDITOR_CONTROL::calculateSelectionRatsnest()
|
|||
{
|
||||
auto selectionTool = m_toolMgr->GetTool<SELECTION_TOOL>();
|
||||
auto& selection = selectionTool->GetSelection();
|
||||
auto connectivity = getModel<BOARD>()->GetConnectivity();
|
||||
auto connectivity = board()->GetConnectivity();
|
||||
|
||||
std::vector<BOARD_ITEM*> items;
|
||||
items.reserve( selection.Size() );
|
||||
|
||||
|
|
|
@ -741,17 +741,16 @@ int PCBNEW_CONTROL::PasteItemsFromClipboard( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
CLIPBOARD_IO pi;
|
||||
BOARD tmpBoard;
|
||||
|
||||
pi.SetBoard( &tmpBoard );
|
||||
BOARD_ITEM* clipItem = pi.Parse();
|
||||
|
||||
tmpBoard.ClearAllNetCodes();
|
||||
|
||||
if(!clipItem )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( clipItem->Type() == PCB_T )
|
||||
static_cast<BOARD*>(clipItem)->ClearAllNetCodes();
|
||||
|
||||
bool editModules = m_editModules || frame()->IsType( FRAME_PCB_MODULE_EDITOR );
|
||||
|
||||
// The clipboard can contain two different things, an entire kicad_pcb
|
||||
|
@ -877,18 +876,11 @@ int PCBNEW_CONTROL::placeBoardItems( std::vector<BOARD_ITEM*>& aItems )
|
|||
item->SetSelected();
|
||||
selection.Add( item );
|
||||
editTool->GetCurrentCommit()->Add( item );
|
||||
printf("pb-add %p\n", item );
|
||||
}
|
||||
|
||||
selection.SetReferencePoint( VECTOR2I( 0, 0 ) );
|
||||
|
||||
printf("SSSS\n");
|
||||
|
||||
m_toolMgr->ProcessEvent( SELECTION_TOOL::SelectedEvent );
|
||||
|
||||
|
||||
printf("Begin-PLACE\n");
|
||||
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::move, true );
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -353,6 +353,7 @@ SELECTION& SELECTION_TOOL::RequestSelection( int aFlags )
|
|||
{
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectionCursor, true, 0 );
|
||||
m_selection.SetIsHover( true );
|
||||
m_selection.ClearReferencePoint();
|
||||
}
|
||||
|
||||
// Be careful with iterators: items can be removed from list
|
||||
|
@ -421,6 +422,8 @@ bool SELECTION_TOOL::selectPoint( const VECTOR2I& aWhere, bool aOnDrag )
|
|||
collector.Remove( i );
|
||||
}
|
||||
|
||||
m_selection.ClearReferencePoint();
|
||||
|
||||
switch( collector.GetCount() )
|
||||
{
|
||||
case 0:
|
||||
|
@ -589,6 +592,9 @@ bool SELECTION_TOOL::selectMultiple()
|
|||
m_multiple = false; // Multiple selection mode is inactive
|
||||
getViewControls()->SetAutoPan( false );
|
||||
|
||||
if ( !cancelled )
|
||||
m_selection.ClearReferencePoint();
|
||||
|
||||
return cancelled;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue