/*********************************/ /* 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 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 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 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(); }