220 lines
6.6 KiB
C++
220 lines
6.6 KiB
C++
/*********************************/
|
|
/* functions used to drag tracks */
|
|
/*********************************/
|
|
|
|
/* Fichier dragsegm.cpp */
|
|
|
|
#include "fctsys.h"
|
|
#include "common.h"
|
|
#include "class_drawpanel.h"
|
|
#include "pcbnew.h"
|
|
|
|
#include "drag.h"
|
|
|
|
/* a list of DRAG_SEGM items used to move or drag tracks */
|
|
std::vector<DRAG_SEGM> g_DragSegmentList;
|
|
|
|
/* helper class to handle a list of track segments to drag or move
|
|
*/
|
|
DRAG_SEGM::DRAG_SEGM( TRACK* segm )
|
|
{
|
|
m_Segm = segm;
|
|
m_StartInitialValue = m_Segm->m_Start;
|
|
m_EndInitialValue = m_Segm->m_End;
|
|
m_Pad_Start = m_Pad_End = NULL;
|
|
m_Flag = 0;
|
|
}
|
|
|
|
|
|
/*******************************************************************/
|
|
void Dessine_Segments_Dragges( WinEDA_DrawPanel* panel, wxDC* DC )
|
|
/*******************************************************************/
|
|
/* Redraw the list of segments starting in g_DragSegmentList, while moving a footprint */
|
|
{
|
|
D_PAD* pt_pad;
|
|
TRACK* Track;
|
|
|
|
if( g_DragSegmentList.size() == 0 )
|
|
return;
|
|
|
|
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
|
|
{
|
|
wxPoint pos;
|
|
Track = g_DragSegmentList[ii].m_Segm;
|
|
Track->Draw( panel, DC, GR_XOR ); // erase from screen at old position
|
|
|
|
pt_pad = g_DragSegmentList[ii].m_Pad_Start;
|
|
if( pt_pad )
|
|
{
|
|
pos = pt_pad->m_Pos - g_Offset_Module;
|
|
Track->m_Start = pos;
|
|
}
|
|
|
|
pt_pad = g_DragSegmentList[ii].m_Pad_End;
|
|
if( pt_pad )
|
|
{
|
|
pos = pt_pad->m_Pos - g_Offset_Module;
|
|
Track->m_End = pos;
|
|
}
|
|
|
|
Track->Draw( panel, DC, GR_XOR );
|
|
}
|
|
}
|
|
|
|
|
|
/*************************************************************************/
|
|
void Build_Drag_Liste( WinEDA_DrawPanel* panel, wxDC* DC, MODULE* Module )
|
|
/*************************************************************************/
|
|
/** Build the list of track segments connected to pads of a given module
|
|
* by populate the std::vector<DRAG_SEGM> g_DragSegmentList
|
|
* For each selected track segment set the EDIT flag
|
|
* and redraw them in EDIT mode (sketch mode)
|
|
*/
|
|
{
|
|
D_PAD* pt_pad;
|
|
|
|
pt_pad = Module->m_Pads;
|
|
for( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Next() )
|
|
{
|
|
Build_1_Pad_SegmentsToDrag( panel, DC, pt_pad );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/**********************************************************************************/
|
|
void Build_1_Pad_SegmentsToDrag( WinEDA_DrawPanel* panel, wxDC* DC, D_PAD* PtPad )
|
|
/**********************************************************************************/
|
|
/** Build the list of track segments connected to a given pad
|
|
* by populate the std::vector<DRAG_SEGM> g_DragSegmentList
|
|
* For each selected track segment set the EDIT flag
|
|
* and redraw them in EDIT mode (sketch mode)
|
|
* Net codes must be OK.
|
|
*/
|
|
{
|
|
TRACK* Track;
|
|
int net_code = PtPad->GetNet();
|
|
int MasqueLayer;
|
|
wxPoint pos;
|
|
BOARD* pcb = ( (WinEDA_BasePcbFrame*)( panel->GetParent() ) )->GetBoard();
|
|
|
|
Track = pcb->m_Track->GetStartNetCode( net_code );
|
|
|
|
pos = PtPad->m_Pos;
|
|
MasqueLayer = PtPad->m_Masque_Layer;
|
|
for( ; Track; Track = Track->Next() )
|
|
{
|
|
if( Track->GetNet() != net_code )
|
|
break;
|
|
|
|
if( ( MasqueLayer & Track->ReturnMaskLayer() ) == 0 )
|
|
continue;
|
|
|
|
if( pos == Track->m_Start )
|
|
{
|
|
AddSegmentToDragList( panel, DC, STARTPOINT, Track );
|
|
g_DragSegmentList.back().m_Pad_Start = PtPad;
|
|
}
|
|
|
|
if( pos == Track->m_End )
|
|
{
|
|
AddSegmentToDragList( panel, DC, ENDPOINT, Track );
|
|
g_DragSegmentList.back().m_Pad_End = PtPad;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************/
|
|
void AddSegmentToDragList( WinEDA_DrawPanel* panel, wxDC* DC,
|
|
int flag, TRACK* Track )
|
|
/******************************************************************/
|
|
/* Add the segment"Track" to the drag list, and erase it from screen
|
|
* flag = STARTPOINT (if the point to drag is the start point of Track) or ENDPOINT
|
|
*/
|
|
{
|
|
DRAG_SEGM wrapper( Track );
|
|
|
|
if( (flag & STARTPOINT) )
|
|
wrapper.m_Flag |= 1;
|
|
|
|
if( (flag & ENDPOINT) )
|
|
wrapper.m_Flag |= 2;
|
|
|
|
Track->Draw( panel, DC, GR_XOR );
|
|
Track->SetState( EDIT, ON );
|
|
|
|
if( (flag & STARTPOINT) )
|
|
Track->m_Flags |= STARTPOINT;
|
|
|
|
if( (flag & ENDPOINT) )
|
|
Track->m_Flags |= ENDPOINT;
|
|
|
|
Track->Draw( panel, DC, GR_XOR );
|
|
g_DragSegmentList.push_back( wrapper );
|
|
}
|
|
|
|
|
|
/**********************************************************************************/
|
|
void Collect_TrackSegmentsToDrag( WinEDA_DrawPanel* panel, wxDC* DC,
|
|
wxPoint& aRefPos, int MasqueLayer, int net_code )
|
|
/**********************************************************************************/
|
|
|
|
/* Build the list of tracks connected to the ref point
|
|
* Net codes must be OK.
|
|
* @param aRefPos = reference point of connection
|
|
*/
|
|
{
|
|
BOARD* pcb = ( (WinEDA_BasePcbFrame*)( panel->GetParent() ) )->GetBoard();
|
|
|
|
TRACK* track = pcb->m_Track->GetStartNetCode( net_code );
|
|
|
|
for( ; track; track = track->Next() )
|
|
{
|
|
if( track->GetNet() != net_code ) // Bad net, not connected
|
|
break;
|
|
|
|
if( ( MasqueLayer & track->ReturnMaskLayer() ) == 0 )
|
|
continue; // Cannot be connected, not on the same layer
|
|
|
|
if( track->m_Flags & IS_DRAGGED )
|
|
continue; // already put in list
|
|
|
|
int flag = 0;
|
|
|
|
if( (track->m_Start == aRefPos) && ((track->m_Flags & STARTPOINT) == 0) )
|
|
flag |= STARTPOINT;
|
|
|
|
if( track->m_End == aRefPos && ((track->m_Flags & ENDPOINT) == 0) )
|
|
flag |= ENDPOINT;
|
|
|
|
// Note: vias will be flagged with both STARTPOINT and ENDPOINT
|
|
// and must not be entered twice.
|
|
if( flag )
|
|
{
|
|
AddSegmentToDragList( panel, DC, flag, track );
|
|
// If a connected via is found at location aRefPos,
|
|
// collect also tracks connected by this via.
|
|
if( track->Type() == TYPE_VIA )
|
|
Collect_TrackSegmentsToDrag( panel, DC, aRefPos,
|
|
track->ReturnMaskLayer(),
|
|
net_code );
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/** function EraseDragList
|
|
* clear the .m_Flags of all track segments found in g_DragSegmentList
|
|
* and clear the list.
|
|
* the memory is not freed and will be reused when creating a new list
|
|
*/
|
|
void EraseDragList()
|
|
{
|
|
for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ )
|
|
g_DragSegmentList[ii].m_Segm->m_Flags = 0;
|
|
|
|
g_DragSegmentList.clear();
|
|
}
|