kicad/pcbnew/move-drag_pads.cpp

209 lines
5.0 KiB
C++

/**
* @file move-drag_pads.cpp
* @brief Edit footprint pads.
*/
#include <fctsys.h>
#include <gr_basic.h>
#include <common.h>
#include <class_drawpanel.h>
#include <trigo.h>
#include <block_commande.h>
#include <wxBasePcbFrame.h>
#include <pcbcommon.h>
#include <class_board.h>
#include <class_module.h>
#include <pcbnew.h>
#include <drag.h>
static D_PAD* s_CurrentSelectedPad;
static wxPoint Pad_OldPos;
/* Cancel move pad command.
*/
static void Abort_Move_Pad( EDA_DRAW_PANEL* Panel, wxDC* DC )
{
D_PAD* pad = s_CurrentSelectedPad;
Panel->SetMouseCapture( NULL, NULL );
if( pad == NULL )
return;
pad->Draw( Panel, DC, GR_XOR );
pad->ClearFlags();
pad->SetPosition( Pad_OldPos );
pad->Draw( Panel, DC, GR_XOR );
// Pad move in progress: restore origin of dragged tracks, if any.
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{
TRACK* Track = g_DragSegmentList[ii].m_Track;
Track->Draw( Panel, DC, GR_XOR );
Track->SetState( IN_EDIT, OFF );
g_DragSegmentList[ii].RestoreInitialValues();
Track->Draw( Panel, DC, GR_OR );
}
EraseDragList();
s_CurrentSelectedPad = NULL;
}
/* Draw in drag mode when moving a pad.
*/
static void Show_Pad_Move( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
bool aErase )
{
TRACK* Track;
BASE_SCREEN* screen = aPanel->GetScreen();
D_PAD* pad = s_CurrentSelectedPad;
if( pad == NULL ) // Should not occur
return;
if( aErase )
pad->Draw( aPanel, aDC, GR_XOR );
pad->SetPosition( screen->GetCrossHairPosition() );
pad->Draw( aPanel, aDC, GR_XOR );
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{
Track = g_DragSegmentList[ii].m_Track;
if( aErase )
Track->Draw( aPanel, aDC, GR_XOR );
g_DragSegmentList[ii].SetTrackEndsCoordinates( wxPoint(0, 0) );
Track->Draw( aPanel, aDC, GR_XOR );
}
}
// Function to initialize the "move pad" command
void PCB_BASE_FRAME::StartMovePad( D_PAD* aPad, wxDC* aDC, bool aDragConnectedTracks )
{
if( aPad == NULL )
return;
s_CurrentSelectedPad = aPad;
Pad_OldPos = aPad->GetPosition();
aPad->DisplayInfo( this );
m_canvas->SetMouseCapture( Show_Pad_Move, Abort_Move_Pad );
// Draw the pad, in SKETCH mode
aPad->Draw( m_canvas, aDC, GR_XOR );
aPad->SetFlags( IS_MOVED );
aPad->Draw( m_canvas, aDC, GR_XOR );
EraseDragList();
// Build the list of track segments to drag if the command is a drag pad
if( aDragConnectedTracks )
{
DRAG_LIST drglist( GetBoard() );
drglist.BuildDragListe( aPad );
UndrawAndMarkSegmentsToDrag( m_canvas, aDC );
}
}
// Routine to place a moved pad.
void PCB_BASE_FRAME::PlacePad( D_PAD* aPad, wxDC* DC )
{
int dX, dY;
TRACK* Track;
if( aPad == NULL )
return;
MODULE* module = aPad->GetParent();
ITEM_PICKER picker( NULL, UR_CHANGED );
PICKED_ITEMS_LIST pickList;
// Save dragged track segments in undo list
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{
Track = g_DragSegmentList[ii].m_Track;
// Set the old state
if( g_DragSegmentList[ii].m_Pad_Start )
Track->m_Start = Pad_OldPos;
if( g_DragSegmentList[ii].m_Pad_End )
Track->m_End = Pad_OldPos;
picker.SetItem( Track );
pickList.PushItem( picker );
}
// Save old module and old items values
wxPoint pad_curr_position = aPad->GetPosition();
aPad->SetPosition( Pad_OldPos );
if( g_DragSegmentList.size() == 0 )
SaveCopyInUndoList( module, UR_CHANGED );
else
{
picker.SetItem( module );
pickList.PushItem( picker );
SaveCopyInUndoList( pickList, UR_CHANGED );
}
aPad->SetPosition( pad_curr_position );
aPad->Draw( m_canvas, DC, GR_XOR );
// Redraw dragged track segments
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
{
Track = g_DragSegmentList[ii].m_Track;
// Set the new state
if( g_DragSegmentList[ii].m_Pad_Start )
Track->m_Start = aPad->GetPosition();
if( g_DragSegmentList[ii].m_Pad_End )
Track->m_End = aPad->GetPosition();
Track->SetState( IN_EDIT, OFF );
if( DC )
Track->Draw( m_canvas, DC, GR_OR );
}
// Compute local coordinates (i.e refer to module position and for module orient = 0)
dX = aPad->GetPosition().x - Pad_OldPos.x;
dY = aPad->GetPosition().y - Pad_OldPos.y;
RotatePoint( &dX, &dY, -module->GetOrientation() );
aPad->SetX0( dX + aPad->GetPos0().x );
aPad->SetY0( dY + aPad->GetPos0().y );
aPad->ClearFlags();
if( DC )
aPad->Draw( m_canvas, DC, GR_OR );
module->CalculateBoundingBox();
module->SetLastEditTime();
EraseDragList();
OnModify();
m_canvas->SetMouseCapture( NULL, NULL );
m_Pcb->m_Status_Pcb &= ~( LISTE_RATSNEST_ITEM_OK | CONNEXION_OK );
}