Add "move exact" and "duplicate" tools to pcbnew

This commit is contained in:
John Beard
2015-02-12 03:22:24 +00:00
parent 74e83e924a
commit 4f3672da4d
53 changed files with 3165 additions and 148 deletions
+99 -3
View File
@@ -53,14 +53,19 @@
#include <class_dimension.h>
#include <class_edge_mod.h>
#include <dialogs/dialog_move_exact.h>
#define BLOCK_COLOR BROWN
// Functions defined here, but used also in other files
// These 2 functions are used in modedit to rotate or mirror the whole footprint
// so they are called with force_all = true
// These 3 functions are used in modedit to rotate, mirror or move the
// whole footprint so they are called with force_all = true
void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all = false );
void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
const wxPoint& translation, double rotation,
bool force_all = false );
// Local functions:
static void DrawMovingBlockOutlines( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
@@ -166,6 +171,26 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
break;
case BLOCK_MOVE_EXACT:
itemsCount = MarkItemsInBloc( currentModule, GetScreen()->m_BlockLocate );
if( itemsCount )
{
wxPoint translation;
double rotation = 0;
DIALOG_MOVE_EXACT dialog( this, translation, rotation );
int ret = dialog.ShowModal();
if( ret == DIALOG_MOVE_EXACT::MOVE_OK )
{
SaveCopyInUndoList( currentModule, UR_MODEDIT );
const wxPoint blockCentre = GetScreen()->m_BlockLocate.Centre();
MoveMarkedItemsExactly( currentModule, blockCentre, translation, rotation );
}
}
break;
case BLOCK_PRESELECT_MOVE: // Move with preselection list
nextcmd = true;
m_canvas->SetMouseCaptureCallback( DrawMovingBlockOutlines );
@@ -194,7 +219,6 @@ bool FOOTPRINT_EDIT_FRAME::HandleBlockEnd( wxDC* DC )
RotateMarkedItems( currentModule, GetScreen()->m_BlockLocate.Centre() );
break;
case BLOCK_MIRROR_X:
case BLOCK_MIRROR_Y:
case BLOCK_FLIP: // mirror
@@ -706,6 +730,78 @@ void ClearMarkItems( MODULE* module )
}
void MoveMarkedItemsExactly( MODULE* module, const wxPoint& centre,
const wxPoint& translation,
double rotation, bool force_all )
{
if( module == NULL )
return;
if( module->Reference().IsSelected() || force_all )
{
module->Reference().RotateTransformWithModule( centre, rotation );
module->Reference().MoveTransformWithModule( translation );
}
if( module->Value().IsSelected() || force_all )
{
module->Value().RotateTransformWithModule( centre, rotation );
module->Value().MoveTransformWithModule( translation );
}
D_PAD* pad = module->Pads();
for( ; pad != NULL; pad = pad->Next() )
{
if( !pad->IsSelected() && !force_all )
continue;
// rotate about centre point,
wxPoint newPos = pad->GetPosition();
RotatePoint( &newPos, centre, rotation );
// shift and update
newPos += translation;
pad->SetPosition( newPos );
pad->SetPos0( newPos );
// finally apply rotation to the pad itself
pad->Rotate( newPos, rotation );
}
EDA_ITEM* item = module->GraphicalItems();
for( ; item != NULL; item = item->Next() )
{
if( !item->IsSelected() && !force_all )
continue;
switch( item->Type() )
{
case PCB_MODULE_TEXT_T:
{
TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
text->RotateTransformWithModule( centre, rotation );
text->MoveTransformWithModule( translation );
break;
}
case PCB_MODULE_EDGE_T:
{
EDGE_MODULE* em = static_cast<EDGE_MODULE*>( item );
em->Rotate( centre, rotation );
em->Move( translation );
break;
}
default:
;
}
}
ClearMarkItems( module );
}
/* Mark items inside rect.
* Items are inside rect when an end point is inside rect
*/