Add "move exact" and "duplicate" tools to pcbnew
This commit is contained in:
@@ -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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user