// Redraw the moved node according to the mouse cursor position static void Show_MoveNode( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase ) { auto displ_opts = (PCB_DISPLAY_OPTIONS*) aPanel->GetDisplayOptions(); wxPoint moveVector; int tmp = displ_opts->m_DisplayPcbTrackFill; GR_DRAWMODE draw_mode = GR_XOR | GR_HIGHLIGHT; displ_opts->m_DisplayPcbTrackFill = false; #ifndef USE_WX_OVERLAY aErase = true; #else aErase = false; #endif // set the new track coordinates wxPoint Pos = aPanel->GetParent()->GetCrossHairPosition(); moveVector = Pos - s_LastPos; s_LastPos = Pos; TRACK *track = NULL; for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ ) { track = g_DragSegmentList[ii].m_Track; if( aErase ) track->Draw( aPanel, aDC, draw_mode ); if( track->GetFlags() & STARTPOINT ) track->SetStart( track->GetStart() + moveVector ); if( track->GetFlags() & ENDPOINT ) track->SetEnd( track->GetEnd() + moveVector ); if( track->Type() == PCB_VIA_T ) track->SetEnd( track->GetStart() ); track->Draw( aPanel, aDC, draw_mode ); } displ_opts->m_DisplayPcbTrackFill = tmp; // Display track length if( track ) { PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent(); frame->SetMsgPanel( track ); } }
void PNS_KICAD_IFACE::AddItem( PNS::ITEM* aItem ) { BOARD_CONNECTED_ITEM* newBI = NULL; switch( aItem->Kind() ) { case PNS::ITEM::SEGMENT_T: { PNS::SEGMENT* seg = static_cast<PNS::SEGMENT*>( aItem ); TRACK* track = new TRACK( m_board ); const SEG& s = seg->Seg(); track->SetStart( wxPoint( s.A.x, s.A.y ) ); track->SetEnd( wxPoint( s.B.x, s.B.y ) ); track->SetWidth( seg->Width() ); track->SetLayer( ToLAYER_ID( seg->Layers().Start() ) ); track->SetNetCode( seg->Net() > 0 ? seg->Net() : 0 ); newBI = track; break; } case PNS::ITEM::VIA_T: { VIA* via_board = new VIA( m_board ); PNS::VIA* via = static_cast<PNS::VIA*>( aItem ); via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) ); via_board->SetWidth( via->Diameter() ); via_board->SetDrill( via->Drill() ); via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 ); via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair() via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ), ToLAYER_ID( via->Layers().End() ) ); newBI = via_board; break; } default: break; } if( newBI ) { aItem->SetParent( newBI ); newBI->ClearFlags(); m_commit->Add( newBI ); } }
TRACK* SPECCTRA_DB::makeTRACK( PATH* aPath, int aPointIndex, int aNetcode ) throw( IO_ERROR ) { int layerNdx = findLayerName( aPath->layer_id ); if( layerNdx == -1 ) { wxString layerName = FROM_UTF8( aPath->layer_id.c_str() ); THROW_IO_ERROR( wxString::Format( _("Session file uses invalid layer id \"%s\""), GetChars( layerName ) ) ); } TRACK* track = new TRACK( sessionBoard ); track->SetStart( mapPt( aPath->points[aPointIndex+0], routeResolution ) ); track->SetEnd( mapPt( aPath->points[aPointIndex+1], routeResolution ) ); track->SetLayer( pcbLayer2kicad[layerNdx] ); track->SetWidth( scale( aPath->aperture_width, routeResolution ) ); track->SetNetCode( aNetcode ); return track; }
/* drawing the track segment movement * > s_MovingSegmentSlope slope = moving track segment slope * > s_StartSegmentSlope slope = slope of the segment connected to the start * point of the moving segment * > s_EndSegmentSlope slope = slope of the segment connected to the end point * of the moving segment * * moved segment function : * yt=s_MovingSegmentSlope * x + s_MovingSegment_Yorg * * segment connected to moved segment's start: * y1 = s_StartSegmentSlope * x + s_StartSegment_Yorg * * segment connected to moved segment's end: * y2=s_EndSegmentSlope * x + s_EndSegment_Yorg * * first intersection point will be located at * y1=yt -> * * xi1=(s_MovingSegment_Yorg-s_StartSegment_Yorg)/(s_StartSegmentSlope-s_MovingSegmentSlope) * yi1=s_MovingSegmentSlope*xi1+s_MovingSegment_Yorg * or yi1=s_StartSegmentSlope*xi1+s_MovingSegment_Yorg * * second intersection point * y2=yt -> * * xi2=(s_MovingSegment_Yorg-s_StartSegment_Yorg)/(s_MovingSegmentSlope-s_MovingSegmentSlope) * yi2=s_MovingSegmentSlope*xi2+s_MovingSegment_Yorg * or yi1=s_EndSegmentSlope*xi2+s_MovingSegment_Yorg * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * !!!!! special attention to vertical segments because * !!!!! their slope=infinite * !!!!! intersection point will be calculated using the * !!!!! segment intersecting it * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * * Slope parameters are computed once, because they can become undetermined * when moving segments * (i.e. when a segment length is 0) and we want keep them constant */ static void Show_Drag_Track_Segment_With_Cte_Slope( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase ) { double xi1 = 0, yi1 = 0, xi2 = 0, yi2 = 0; // calculated intersection points double tx1, tx2, ty1, ty2; // temporary storage of points int dx, dy; bool update = true; TRACK* Track; TRACK* tSegmentToStart = NULL, * tSegmentToEnd = NULL; if( g_DragSegmentList.size() == 0 ) return; /* get the segments : * from last to first in list are: * the segment to move * the segment connected to its end point (if exists) * the segment connected to its start point (if exists) */ int ii = g_DragSegmentList.size() - 1; Track = g_DragSegmentList[ii].m_Track; if( Track == NULL ) return; ii--; if( ii >= 0) { if( s_EndSegmentPresent ) { // Get the segment connected to the end point tSegmentToEnd = g_DragSegmentList[ii].m_Track; ii--; } if( s_StartSegmentPresent ) { // Get the segment connected to the start point if( ii >= 0 ) tSegmentToStart = g_DragSegmentList[ii].m_Track; } } GR_DRAWMODE draw_mode = GR_XOR | GR_HIGHLIGHT; // Undraw the current moved track segments before modification #ifndef USE_WX_OVERLAY // if( erase ) { Track->Draw( aPanel, aDC, draw_mode ); if( tSegmentToStart ) tSegmentToStart->Draw( aPanel, aDC, draw_mode ); if( tSegmentToEnd ) tSegmentToEnd->Draw( aPanel, aDC, draw_mode ); } #endif // Compute the new track segment position wxPoint Pos = aPanel->GetParent()->GetCrossHairPosition(); dx = Pos.x - s_LastPos.x; dy = Pos.y - s_LastPos.y; // move the line by dx and dy tx1 = (double) ( Track->GetStart().x + dx ); ty1 = (double) ( Track->GetStart().y + dy ); tx2 = (double) ( Track->GetEnd().x + dx ); ty2 = (double) ( Track->GetEnd().y + dy ); // recalculate the segments new parameters and intersection points // only the intercept will change, segment slopes does not change // because we are moving parallel with is initial state if( !s_MovingSegmentVertical ) { s_MovingSegment_Yorg = ty1 - ( s_MovingSegmentSlope * tx1 ); } if( ( !s_EndPointVertical ) && ( !s_MovingSegmentVertical ) ) { xi2 = ( s_MovingSegment_Yorg - s_EndSegment_Yorg ) / ( s_EndSegmentSlope - s_MovingSegmentSlope ); } else { if( !s_EndPointVertical ) { xi2 = tx2; } else { //P1=P2 if( !s_EndPointHorizontal ) { xi2 = tx2 - dx; } else { update = false; } } } if( !s_MovingSegmentVertical ) { yi2 = s_MovingSegmentSlope * ( xi2 ) + s_MovingSegment_Yorg; } else { if( !s_EndPointVertical ) { yi2 = s_EndSegmentSlope * ( xi2 ) + s_EndSegment_Yorg; } else { if( !s_EndPointHorizontal ) { update = false; } else { yi2 = s_MovingSegmentSlope * ( xi2 ) + s_MovingSegment_Yorg; } } } if( ( !s_StartPointVertical ) && ( !s_MovingSegmentVertical ) ) { xi1 = ( s_MovingSegment_Yorg - s_StartSegment_Yorg ) / ( s_StartSegmentSlope - s_MovingSegmentSlope ); } else { if( !s_StartPointVertical ) { xi1 = tx1; } else { //P1=P2 if( !s_StartPointHorizontal ) { xi1 = tx1 - dx; } else { if( !s_StartPointHorizontal ) { update = false; } } } } if( !s_MovingSegmentVertical ) { yi1 = s_MovingSegmentSlope * ( xi1 ) + s_MovingSegment_Yorg; } else { if( !s_StartPointVertical ) { yi1 = s_StartSegmentSlope * ( xi1 ) + s_StartSegment_Yorg; } else { if( !s_StartPointHorizontal ) { update = false; } else { yi2 = s_MovingSegmentSlope * ( xi1 ) + s_MovingSegment_Yorg; } } } // update the segment coordinates (if possible) if( tSegmentToStart == NULL ) { xi1 = tx1; yi1 = ty1; } if( tSegmentToEnd == NULL ) { xi2 = tx2; yi2 = ty2; } if( update ) { s_LastPos = Pos; Track->SetStart( wxPoint( KiROUND( xi1 ), KiROUND( yi1 ) ) ); Track->SetEnd( wxPoint( KiROUND( xi2 ), KiROUND( yi2 ) ) ); if( tSegmentToEnd ) { if( tSegmentToEnd->GetFlags() & STARTPOINT ) tSegmentToEnd->SetStart( Track->GetEnd() ); else tSegmentToEnd->SetEnd( Track->GetEnd() ); } if( tSegmentToStart ) { if( tSegmentToStart->GetFlags() & STARTPOINT ) tSegmentToStart->SetStart( Track->GetStart() ); else tSegmentToStart->SetEnd( Track->GetStart() ); } } Track->Draw( aPanel, aDC, draw_mode ); if( tSegmentToStart ) tSegmentToStart->Draw( aPanel, aDC, draw_mode ); if( tSegmentToEnd ) tSegmentToEnd->Draw( aPanel, aDC, draw_mode ); // Display track length PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent(); frame->SetMsgPanel( Track ); }
bool PCB_EDIT_FRAME::Other_Layer_Route( TRACK* aTrack, wxDC* DC ) { unsigned itmp; if( aTrack == NULL ) { if( GetActiveLayer() != GetScreen()->m_Route_Layer_TOP ) SetActiveLayer( GetScreen()->m_Route_Layer_TOP ); else SetActiveLayer( GetScreen()->m_Route_Layer_BOTTOM ); UpdateStatusBar(); return true; } // Avoid more than one via on the current location: if( GetBoard()->GetViaByPosition( g_CurrentTrackSegment->GetEnd(), g_CurrentTrackSegment->GetLayer() ) ) return false; for( TRACK* segm = g_FirstTrackSegment; segm; segm = segm->Next() ) { if( segm->Type() == PCB_VIA_T && g_CurrentTrackSegment->GetEnd() == segm->GetStart() ) return false; } // Is the current segment Ok (no DRC error) ? if( g_Drc_On ) { if( BAD_DRC==m_drc->Drc( g_CurrentTrackSegment, GetBoard()->m_Track ) ) // DRC error, the change layer is not made return false; // Handle 2 segments. if( g_TwoSegmentTrackBuild && g_CurrentTrackSegment->Back() ) { if( BAD_DRC == m_drc->Drc( g_CurrentTrackSegment->Back(), GetBoard()->m_Track ) ) return false; } } /* Save current state before placing a via. * If the via cannot be placed this current state will be reused */ itmp = g_CurrentTrackList.GetCount(); Begin_Route( g_CurrentTrackSegment, DC ); m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // create the via VIA* via = new VIA( GetBoard() ); via->SetFlags( IS_NEW ); via->SetViaType( GetDesignSettings().m_CurrentViaType ); via->SetNetCode( GetBoard()->GetHighLightNetCode() ); via->SetPosition( g_CurrentTrackSegment->GetEnd() ); // for microvias, the size and hole will be changed later. via->SetWidth( GetDesignSettings().GetCurrentViaSize()); via->SetDrill( GetDesignSettings().GetCurrentViaDrill() ); // Usual via is from copper to component. // layer pair is B_Cu and F_Cu. via->SetLayerPair( B_Cu, F_Cu ); LAYER_ID first_layer = GetActiveLayer(); LAYER_ID last_layer; // prepare switch to new active layer: if( first_layer != GetScreen()->m_Route_Layer_TOP ) last_layer = GetScreen()->m_Route_Layer_TOP; else last_layer = GetScreen()->m_Route_Layer_BOTTOM; // Adjust the actual via layer pair switch( via->GetViaType() ) { case VIA_BLIND_BURIED: via->SetLayerPair( first_layer, last_layer ); break; case VIA_MICROVIA: // from external to the near neighbor inner layer { LAYER_ID last_inner_layer = ToLAYER_ID( ( GetBoard()->GetCopperLayerCount() - 2 ) ); if( first_layer == B_Cu ) last_layer = last_inner_layer; else if( first_layer == F_Cu ) last_layer = In1_Cu; else if( first_layer == last_inner_layer ) last_layer = B_Cu; else if( first_layer == In1_Cu ) last_layer = F_Cu; // else error: will be removed later via->SetLayerPair( first_layer, last_layer ); // Update diameter and hole size, which where set previously // for normal vias NETINFO_ITEM* net = via->GetNet(); via->SetWidth( net->GetMicroViaSize() ); via->SetDrill( net->GetMicroViaDrillSize() ); } break; default: break; } if( g_Drc_On && BAD_DRC == m_drc->Drc( via, GetBoard()->m_Track ) ) { // DRC fault: the Via cannot be placed here ... delete via; m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); // delete the track(s) added in Begin_Route() while( g_CurrentTrackList.GetCount() > itmp ) { Delete_Segment( DC, g_CurrentTrackSegment ); } SetCurItem( g_CurrentTrackSegment, false ); // Refresh DRC diag, erased by previous calls if( m_drc->GetCurrentMarker() ) SetMsgPanel( m_drc->GetCurrentMarker() ); return false; } SetActiveLayer( last_layer ); TRACK* lastNonVia = g_CurrentTrackSegment; /* A new via was created. It was Ok. */ g_CurrentTrackList.PushBack( via ); /* The via is now in linked list and we need a new track segment * after the via, starting at via location. * it will become the new current segment (from via to the mouse cursor) */ TRACK* track = (TRACK*)lastNonVia->Clone(); /* the above creates a new segment from the last entered segment, with the * current width, flags, netcode, etc... values. * layer, start and end point are not correct, * and will be modified next */ // set the layer to the new value track->SetLayer( GetActiveLayer() ); /* the start point is the via position and the end point is the cursor * which also is on the via (will change when moving mouse) */ track->SetEnd( via->GetStart() ); track->SetStart( via->GetStart() ); g_CurrentTrackList.PushBack( track ); if( g_TwoSegmentTrackBuild ) { // Create a second segment (we must have 2 track segments to adjust) g_CurrentTrackList.PushBack( (TRACK*)g_CurrentTrackSegment->Clone() ); } m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); SetMsgPanel( via ); UpdateStatusBar(); return true; }
bool DIALOG_TRACK_VIA_PROPERTIES::Apply( COMMIT& aCommit ) { if( !check() ) return false; bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED; bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED; for( auto item : m_items ) { aCommit.Modify( item ); switch( item->Type() ) { case PCB_TRACE_T: { assert( m_tracks ); TRACK* t = static_cast<TRACK*>( item ); if( m_trackStartX.Valid() || m_trackStartY.Valid() ) { wxPoint start = t->GetStart(); if( m_trackStartX.Valid() ) start.x = m_trackStartX.GetValue(); if( m_trackStartY.Valid() ) start.y = m_trackStartY.GetValue(); t->SetStart( start ); } if( m_trackEndX.Valid() || m_trackEndY.Valid() ) { wxPoint end = t->GetEnd(); if( m_trackEndX.Valid() ) end.x = m_trackEndX.GetValue(); if( m_trackEndY.Valid() ) end.y = m_trackEndY.GetValue(); t->SetEnd( end ); } if( m_trackNetclass->IsChecked() ) { t->SetWidth( t->GetNetClass()->GetTrackWidth() ); } else if( m_trackWidth.Valid() ) { t->SetWidth( m_trackWidth.GetValue() ); } LAYER_NUM layer = m_TrackLayerCtrl->GetLayerSelection(); if( layer != UNDEFINED_LAYER ) t->SetLayer( (LAYER_ID) layer ); if( changeLock ) t->SetLocked( setLock ); break; } case PCB_VIA_T: { assert( m_vias ); VIA* v = static_cast<VIA*>( item ); if( m_viaX.Valid() || m_viaY.Valid() ) { wxPoint pos = v->GetPosition(); if( m_viaX.Valid() ) pos.x = m_viaX.GetValue(); if( m_viaY.Valid() ) pos.y = m_viaY.GetValue(); v->SetPosition( pos ); } if( m_viaNetclass->IsChecked() ) { switch( v->GetViaType() ) { default: wxFAIL_MSG("Unhandled via type"); // fall through case VIA_THROUGH: case VIA_BLIND_BURIED: v->SetWidth( v->GetNetClass()->GetViaDiameter() ); v->SetDrill( v->GetNetClass()->GetViaDrill() ); break; case VIA_MICROVIA: v->SetWidth( v->GetNetClass()->GetuViaDiameter() ); v->SetDrill( v->GetNetClass()->GetuViaDrill() ); break; } } else { if( m_viaDiameter.Valid() ) v->SetWidth( m_viaDiameter.GetValue() ); if( m_viaDrill.Valid() ) v->SetDrill( m_viaDrill.GetValue() ); } if( changeLock ) v->SetLocked( setLock ); break; } default: assert( false ); break; } } return true; }
/* Insert the new track created in the list of tracks. * amend the points of beginning and end of the track so that they are * connected * Center on pads even if they are off grid. */ static void AddNewTrace( PCB_EDIT_FRAME* pcbframe, wxDC* DC ) { if( g_FirstTrackSegment == NULL ) return; int dx0, dy0, dx1, dy1; int marge, via_marge; EDA_DRAW_PANEL* panel = pcbframe->GetCanvas(); PCB_SCREEN* screen = pcbframe->GetScreen(); marge = s_Clearance + ( pcbframe->GetDesignSettings().GetCurrentTrackWidth() / 2 ); via_marge = s_Clearance + ( pcbframe->GetDesignSettings().GetCurrentViaSize() / 2 ); dx1 = g_CurrentTrackSegment->GetEnd().x - g_CurrentTrackSegment->GetStart().x; dy1 = g_CurrentTrackSegment->GetEnd().y - g_CurrentTrackSegment->GetStart().y; // Place on center of pad if off grid. dx0 = pt_cur_ch->m_PadStart->GetPosition().x - g_CurrentTrackSegment->GetStart().x; dy0 = pt_cur_ch->m_PadStart->GetPosition().y - g_CurrentTrackSegment->GetStart().y; // If aligned, change the origin point. if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) ) { g_CurrentTrackSegment->SetEnd( pt_cur_ch->m_PadStart->GetPosition() ); } else { TRACK* newTrack = (TRACK*)g_CurrentTrackSegment->Clone(); newTrack->SetEnd( pt_cur_ch->m_PadStart->GetPosition() ); newTrack->SetStart( g_CurrentTrackSegment->GetEnd() ); g_CurrentTrackList.PushBack( newTrack ); } g_FirstTrackSegment->start = pcbframe->GetBoard()->GetPad( g_FirstTrackSegment, ENDPOINT_START ); if( g_FirstTrackSegment->start ) g_FirstTrackSegment->SetState( BEGIN_ONPAD, true ); g_CurrentTrackSegment->end = pcbframe->GetBoard()->GetPad( g_CurrentTrackSegment, ENDPOINT_END ); if( g_CurrentTrackSegment->end ) g_CurrentTrackSegment->SetState( END_ONPAD, true ); // Out the new track on the matrix board for( TRACK* track = g_FirstTrackSegment; track; track = track->Next() ) { TraceSegmentPcb( track, HOLE, marge, WRITE_CELL ); TraceSegmentPcb( track, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL ); } // Insert new segments in real board int netcode = g_FirstTrackSegment->GetNetCode(); TRACK* firstTrack = g_FirstTrackSegment; int newCount = g_CurrentTrackList.GetCount(); // Put entire new current segment list in BOARD TRACK* track; TRACK* insertBeforeMe = g_CurrentTrackSegment->GetBestInsertPoint( pcbframe->GetBoard() ); while( ( track = g_CurrentTrackList.PopFront() ) != NULL ) { ITEM_PICKER picker( track, UR_NEW ); s_ItemsListPicker.PushItem( picker ); pcbframe->GetBoard()->m_Track.Insert( track, insertBeforeMe ); } DrawTraces( panel, DC, firstTrack, newCount, GR_OR ); pcbframe->TestNetConnection( DC, netcode ); screen->SetModify(); }
/* This function is used by Retrace and read the autorouting matrix data cells to create * the real track on the physical board */ static void OrCell_Trace( BOARD* pcb, int col, int row, int side, int orient, int current_net_code ) { if( orient == HOLE ) // placement of a via { VIA *newVia = new VIA( pcb ); g_CurrentTrackList.PushBack( newVia ); g_CurrentTrackSegment->SetState( TRACK_AR, true ); g_CurrentTrackSegment->SetLayer( F_Cu ); g_CurrentTrackSegment->SetStart(wxPoint( pcb->GetBoundingBox().GetX() + ( RoutingMatrix.m_GridRouting * row ), pcb->GetBoundingBox().GetY() + ( RoutingMatrix.m_GridRouting * col ))); g_CurrentTrackSegment->SetEnd( g_CurrentTrackSegment->GetStart() ); g_CurrentTrackSegment->SetWidth( pcb->GetDesignSettings().GetCurrentViaSize() ); newVia->SetViaType( pcb->GetDesignSettings().m_CurrentViaType ); g_CurrentTrackSegment->SetNetCode( current_net_code ); } else // placement of a standard segment { TRACK *newTrack = new TRACK( pcb ); int dx0, dy0, dx1, dy1; g_CurrentTrackList.PushBack( newTrack ); g_CurrentTrackSegment->SetLayer( g_Route_Layer_BOTTOM ); if( side == TOP ) g_CurrentTrackSegment->SetLayer( g_Route_Layer_TOP ); g_CurrentTrackSegment->SetState( TRACK_AR, true ); g_CurrentTrackSegment->SetEnd( wxPoint( pcb->GetBoundingBox().GetX() + ( RoutingMatrix.m_GridRouting * row ), pcb->GetBoundingBox().GetY() + ( RoutingMatrix.m_GridRouting * col ))); g_CurrentTrackSegment->SetNetCode( current_net_code ); if( g_CurrentTrackSegment->Back() == NULL ) // Start trace. { g_CurrentTrackSegment->SetStart( wxPoint( segm_fX, segm_fY ) ); // Placement on the center of the pad if outside grid. dx1 = g_CurrentTrackSegment->GetEnd().x - g_CurrentTrackSegment->GetStart().x; dy1 = g_CurrentTrackSegment->GetEnd().y - g_CurrentTrackSegment->GetStart().y; dx0 = pt_cur_ch->m_PadEnd->GetPosition().x - g_CurrentTrackSegment->GetStart().x; dy0 = pt_cur_ch->m_PadEnd->GetPosition().y - g_CurrentTrackSegment->GetStart().y; // If aligned, change the origin point. if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) ) { g_CurrentTrackSegment->SetStart( pt_cur_ch->m_PadEnd->GetPosition() ); } else // Creation of a supplemental segment { g_CurrentTrackSegment->SetStart( pt_cur_ch->m_PadEnd->GetPosition() ); newTrack = (TRACK*)g_CurrentTrackSegment->Clone(); newTrack->SetStart( g_CurrentTrackSegment->GetEnd()); g_CurrentTrackList.PushBack( newTrack ); } } else { if( g_CurrentTrackSegment->Back() ) { g_CurrentTrackSegment->SetStart( g_CurrentTrackSegment->Back()->GetEnd() ); } } g_CurrentTrackSegment->SetWidth( pcb->GetDesignSettings().GetCurrentTrackWidth() ); if( g_CurrentTrackSegment->GetStart() != g_CurrentTrackSegment->GetEnd() ) { // Reduce aligned segments by one. TRACK* oldTrack = g_CurrentTrackSegment->Back(); if( oldTrack && oldTrack->Type() != PCB_VIA_T ) { dx1 = g_CurrentTrackSegment->GetEnd().x - g_CurrentTrackSegment->GetStart().x; dy1 = g_CurrentTrackSegment->GetEnd().y - g_CurrentTrackSegment->GetStart().y; dx0 = oldTrack->GetEnd().x - oldTrack->GetStart().x; dy0 = oldTrack->GetEnd().y - oldTrack->GetStart().y; if( abs( dx0 * dy1 ) == abs( dx1 * dy0 ) ) { oldTrack->SetEnd( g_CurrentTrackSegment->GetEnd() ); delete g_CurrentTrackList.PopBack(); } } } } }
void BOARD_ITEM::SwapData( BOARD_ITEM* aImage ) { if( aImage == NULL ) { return; } EDA_ITEM * pnext = Next(); EDA_ITEM * pback = Back(); switch( Type() ) { case PCB_MODULE_T: { MODULE* tmp = (MODULE*) aImage->Clone(); ( (MODULE*) aImage )->Copy( (MODULE*) this ); ( (MODULE*) this )->Copy( tmp ); delete tmp; } break; case PCB_ZONE_AREA_T: { ZONE_CONTAINER* tmp = (ZONE_CONTAINER*) aImage->Clone(); ( (ZONE_CONTAINER*) aImage )->Copy( (ZONE_CONTAINER*) this ); ( (ZONE_CONTAINER*) this )->Copy( tmp ); delete tmp; } break; case PCB_LINE_T: std::swap( *((DRAWSEGMENT*)this), *((DRAWSEGMENT*)aImage) ); break; case PCB_TRACE_T: case PCB_VIA_T: { TRACK* track = (TRACK*) this; TRACK* image = (TRACK*) aImage; EXCHG(track->m_Layer, image->m_Layer ); // swap start, end, width and shape for track and image. wxPoint exchp = track->GetStart(); track->SetStart( image->GetStart() ); image->SetStart( exchp ); exchp = track->GetEnd(); track->SetEnd( image->GetEnd() ); image->SetEnd( exchp ); int atmp = track->GetWidth(); track->SetWidth( image->GetWidth() ); image->SetWidth( atmp ); if( Type() == PCB_VIA_T ) { VIA *via = static_cast<VIA*>( this ); VIA *viaimage = static_cast<VIA*>( aImage ); VIATYPE_T viatmp = via->GetViaType(); via->SetViaType( viaimage->GetViaType() ); viaimage->SetViaType( viatmp ); int drilltmp = via->GetDrillValue(); if( via->IsDrillDefault() ) drilltmp = -1; int itmp = viaimage->GetDrillValue(); if( viaimage->IsDrillDefault() ) itmp = -1; EXCHG(itmp, drilltmp ); if( drilltmp > 0 ) via->SetDrill( drilltmp ); else via->SetDrillDefault(); if( itmp > 0 ) viaimage->SetDrill( itmp ); else viaimage->SetDrillDefault(); } } break; case PCB_TEXT_T: std::swap( *((TEXTE_PCB*)this), *((TEXTE_PCB*)aImage) ); break; case PCB_TARGET_T: std::swap( *((PCB_TARGET*)this), *((PCB_TARGET*)aImage) ); break; case PCB_DIMENSION_T: std::swap( *((DIMENSION*)this), *((DIMENSION*)aImage) ); break; case PCB_ZONE_T: default: wxLogMessage( wxT( "SwapData() error: unexpected type %d" ), Type() ); break; } if( pnext != Next() || pback != Back() ) { Pnext = pnext; Pback = pback; #ifdef DEBUG wxLogMessage( wxT( "SwapData Error: %s Pnext or Pback pointers modified" ), GetClass().GetData() ); #endif } }
void BOARD_ITEM::SwapData( BOARD_ITEM* aImage ) { if( aImage == NULL ) return; // Remark: to create images of edited items to undo, we are using Clone method // which can duplication of items foe copy, but does not clone all members // mainly pointers in chain and time stamp, which is set to new, unique value. // So we have to use the current values of these parameters. EDA_ITEM * pnext = Next(); EDA_ITEM * pback = Back(); DHEAD* mylist = m_List; time_t timestamp = GetTimeStamp(); switch( Type() ) { case PCB_MODULE_T: { MODULE* tmp = (MODULE*) aImage->Clone(); ( (MODULE*) aImage )->Copy( (MODULE*) this ); ( (MODULE*) this )->Copy( tmp ); delete tmp; } break; case PCB_ZONE_AREA_T: { ZONE_CONTAINER* tmp = (ZONE_CONTAINER*) aImage->Clone(); ( (ZONE_CONTAINER*) aImage )->Copy( (ZONE_CONTAINER*) this ); ( (ZONE_CONTAINER*) this )->Copy( tmp ); delete tmp; } break; case PCB_LINE_T: std::swap( *((DRAWSEGMENT*)this), *((DRAWSEGMENT*)aImage) ); break; case PCB_TRACE_T: case PCB_VIA_T: { TRACK* track = (TRACK*) this; TRACK* image = (TRACK*) aImage; std::swap(track->m_Layer, image->m_Layer ); // swap start, end, width and shape for track and image. wxPoint exchp = track->GetStart(); track->SetStart( image->GetStart() ); image->SetStart( exchp ); exchp = track->GetEnd(); track->SetEnd( image->GetEnd() ); image->SetEnd( exchp ); int atmp = track->GetWidth(); track->SetWidth( image->GetWidth() ); image->SetWidth( atmp ); if( Type() == PCB_VIA_T ) { VIA *via = static_cast<VIA*>( this ); VIA *viaimage = static_cast<VIA*>( aImage ); VIATYPE_T viatmp = via->GetViaType(); via->SetViaType( viaimage->GetViaType() ); viaimage->SetViaType( viatmp ); int drilltmp = via->GetDrillValue(); if( via->IsDrillDefault() ) drilltmp = -1; int itmp = viaimage->GetDrillValue(); if( viaimage->IsDrillDefault() ) itmp = -1; std::swap(itmp, drilltmp ); if( drilltmp > 0 ) via->SetDrill( drilltmp ); else via->SetDrillDefault(); if( itmp > 0 ) viaimage->SetDrill( itmp ); else viaimage->SetDrillDefault(); } } break; case PCB_TEXT_T: std::swap( *((TEXTE_PCB*)this), *((TEXTE_PCB*)aImage) ); break; case PCB_TARGET_T: std::swap( *((PCB_TARGET*)this), *((PCB_TARGET*)aImage) ); break; case PCB_DIMENSION_T: std::swap( *((DIMENSION*)this), *((DIMENSION*)aImage) ); break; case PCB_ZONE_T: default: wxLogMessage( wxT( "SwapData() error: unexpected type %d" ), Type() ); break; } // Restore pointers and time stamp, to be sure they are not broken Pnext = pnext; Pback = pback; m_List = mylist; SetTimeStamp( timestamp ); }
void PNS_ROUTER::CommitRouting( PNS_NODE* aNode ) { PNS_NODE::ITEM_VECTOR removed, added; aNode->GetUpdatedItems( removed, added ); for( unsigned int i = 0; i < removed.size(); i++ ) { BOARD_CONNECTED_ITEM* parent = removed[i]->Parent(); if( parent ) { m_view->Remove( parent ); m_board->Remove( parent ); m_undoBuffer.PushItem( ITEM_PICKER( parent, UR_DELETED ) ); } } for( PNS_ITEM* item : added ) { BOARD_CONNECTED_ITEM* newBI = NULL; switch( item->Kind() ) { case PNS_ITEM::SEGMENT: { PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item ); TRACK* track = new TRACK( m_board ); const SEG& s = seg->Seg(); track->SetStart( wxPoint( s.A.x, s.A.y ) ); track->SetEnd( wxPoint( s.B.x, s.B.y ) ); track->SetWidth( seg->Width() ); track->SetLayer( ToLAYER_ID( seg->Layers().Start() ) ); track->SetNetCode( seg->Net() > 0 ? seg->Net() : 0 ); newBI = track; break; } case PNS_ITEM::VIA: { VIA* via_board = new VIA( m_board ); PNS_VIA* via = static_cast<PNS_VIA*>( item ); via_board->SetPosition( wxPoint( via->Pos().x, via->Pos().y ) ); via_board->SetWidth( via->Diameter() ); via_board->SetDrill( via->Drill() ); via_board->SetNetCode( via->Net() > 0 ? via->Net() : 0 ); via_board->SetViaType( via->ViaType() ); // MUST be before SetLayerPair() via_board->SetLayerPair( ToLAYER_ID( via->Layers().Start() ), ToLAYER_ID( via->Layers().End() ) ); newBI = via_board; break; } default: break; } if( newBI ) { item->SetParent( newBI ); newBI->ClearFlags(); m_view->Add( newBI ); m_board->Add( newBI ); m_undoBuffer.PushItem( ITEM_PICKER( newBI, UR_NEW ) ); newBI->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } } m_board->GetRatsnest()->Recalculate(); m_world->Commit( aNode ); }
bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow() { auto connectivity = m_frame->GetBoard()->GetConnectivity(); int newNetCode = m_netSelector->GetSelectedNetcode(); std::vector<D_PAD*> changingPads; if ( !m_netSelector->IsIndeterminate() ) { std::set<D_PAD*> connectedPads; for( auto& item : m_items ) { const KICAD_T ourTypes[] = { PCB_TRACE_T, PCB_PAD_T, PCB_VIA_T, PCB_MODULE_T, EOT }; auto connectedItems = connectivity->GetConnectedItems( static_cast<BOARD_CONNECTED_ITEM*>( item ), ourTypes, true ); for ( auto citem : connectedItems ) { if( citem->Type() == PCB_PAD_T ) { connectedPads.insert( static_cast<D_PAD*>( citem ) ); } } } for( D_PAD* pad : connectedPads ) { if( pad->GetNetCode() != newNetCode ) changingPads.push_back( pad ); } } // Run validations: if( changingPads.size() ) { if( !confirmPadChange( changingPads ) ) return false; } if( m_vias ) { if( !m_viaDiameter.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) || !m_viaDrill.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) ) return false; if( m_ViaDiameterCtrl->IsEnabled() && !m_viaDiameter.IsIndeterminate() && m_ViaDrillCtrl->IsEnabled() && !m_viaDrill.IsIndeterminate() && m_viaDiameter.GetValue() <= m_viaDrill.GetValue() ) { DisplayError( GetParent(), _( "Via drill size must be smaller than via diameter" ) ); m_ViaDrillCtrl->SelectAll(); m_ViaDrillCtrl->SetFocus(); return false; } if( m_ViaStartLayer->GetLayerSelection() != UNDEFINED_LAYER && m_ViaStartLayer->GetLayerSelection() == m_ViaEndLayer->GetLayerSelection() ) { DisplayError( GetParent(), _( "Via start layer and end layer cannot be the same" ) ); return false; } } if( m_tracks ) { if( !m_trackWidth.Validate( GEOMETRY_MIN_SIZE, INT_MAX ) ) return false; } // If we survived that, then save the changes: bool changeLock = m_lockedCbox->Get3StateValue() != wxCHK_UNDETERMINED; bool setLock = m_lockedCbox->Get3StateValue() == wxCHK_CHECKED; for( auto item : m_items ) { m_commit.Modify( item ); switch( item->Type() ) { case PCB_TRACE_T: { wxASSERT( m_tracks ); TRACK* t = static_cast<TRACK*>( item ); if( !m_trackStartX.IsIndeterminate() ) t->SetStart( wxPoint( m_trackStartX.GetValue(), t->GetStart().y ) ); if( !m_trackStartY.IsIndeterminate() ) t->SetStart( wxPoint( t->GetStart().x, m_trackStartY.GetValue() ) ); if( !m_trackEndX.IsIndeterminate() ) t->SetEnd( wxPoint( m_trackEndX.GetValue(), t->GetEnd().y ) ); if( !m_trackEndY.IsIndeterminate() ) t->SetEnd( wxPoint( t->GetEnd().x, m_trackEndY.GetValue() ) ); if( m_trackNetclass->IsChecked() ) t->SetWidth( t->GetNetClass()->GetTrackWidth() ); else if( !m_trackWidth.IsIndeterminate() ) t->SetWidth( m_trackWidth.GetValue() ); LAYER_NUM layer = m_TrackLayerCtrl->GetLayerSelection(); if( layer != UNDEFINED_LAYER ) t->SetLayer( (PCB_LAYER_ID) layer ); if( changeLock ) t->SetLocked( setLock ); if ( !m_netSelector->IsIndeterminate() ) t->SetNetCode( m_netSelector->GetSelectedNetcode() ); break; } case PCB_VIA_T: { wxASSERT( m_vias ); VIA* v = static_cast<VIA*>( item ); if( !m_viaX.IsIndeterminate() ) v->SetPosition( wxPoint( m_viaX.GetValue(), v->GetPosition().y ) ); if( !m_viaY.IsIndeterminate() ) v->SetPosition( wxPoint( v->GetPosition().x, m_viaY.GetValue() ) ); if( m_ViaTypeChoice->GetSelection() != 3) { switch( m_ViaTypeChoice->GetSelection() ) { default: case 0: v->SetViaType( VIA_THROUGH ); v->SanitizeLayers(); break; case 1: v->SetViaType( VIA_MICROVIA ); break; case 2: v->SetViaType( VIA_BLIND_BURIED ); break; } } auto startLayer = static_cast<PCB_LAYER_ID>( m_ViaStartLayer->GetLayerSelection() ); auto endLayer = static_cast<PCB_LAYER_ID>( m_ViaEndLayer->GetLayerSelection() ); if (startLayer != UNDEFINED_LAYER ) v->SetTopLayer( startLayer ); if (endLayer != UNDEFINED_LAYER ) v->SetBottomLayer( endLayer ); v->SanitizeLayers(); if( m_viaNetclass->IsChecked() ) { switch( v->GetViaType() ) { default: wxFAIL_MSG("Unhandled via type"); // fall through case VIA_THROUGH: case VIA_BLIND_BURIED: v->SetWidth( v->GetNetClass()->GetViaDiameter() ); v->SetDrill( v->GetNetClass()->GetViaDrill() ); break; case VIA_MICROVIA: v->SetWidth( v->GetNetClass()->GetuViaDiameter() ); v->SetDrill( v->GetNetClass()->GetuViaDrill() ); break; } } else { if( !m_viaDiameter.IsIndeterminate() ) v->SetWidth( m_viaDiameter.GetValue() ); if( !m_viaDrill.IsIndeterminate() ) v->SetDrill( m_viaDrill.GetValue() ); } if ( !m_netSelector->IsIndeterminate() ) v->SetNetCode( m_netSelector->GetSelectedNetcode() ); if( changeLock ) v->SetLocked( setLock ); break; } default: wxASSERT( false ); break; } } if ( !m_netSelector->IsIndeterminate() ) { // Commit::Push() will rebuild connectivitiy propagating nets from connected pads // outwards. We therefore have to update the connected pads in order for the net // change to "stick". for( D_PAD* pad : changingPads ) { m_commit.Modify( pad ); pad->SetNetCode( m_netSelector->GetSelectedNetcode() ); } } m_commit.Push( _( "Edit track/via properties" ) ); return true; }
bool DIALOG_TRACK_VIA_PROPERTIES::Apply() { if( !check() ) return false; for( int i = 0; i < m_items.Size(); ++i ) { BOARD_ITEM* item = m_items.Item<BOARD_ITEM>( i ); switch( item->Type() ) { case PCB_TRACE_T: { assert( m_tracks ); TRACK* t = static_cast<TRACK*>( item ); if( m_trackStartX.Valid() || m_trackStartY.Valid() ) { wxPoint start = t->GetStart(); if( m_trackStartX.Valid() ) start.x = m_trackStartX.GetValue(); if( m_trackStartY.Valid() ) start.y = m_trackStartY.GetValue(); t->SetStart( start ); } if( m_trackEndX.Valid() || m_trackEndY.Valid() ) { wxPoint end = t->GetEnd(); if( m_trackEndX.Valid() ) end.x = m_trackEndX.GetValue(); if( m_trackEndY.Valid() ) end.y = m_trackEndY.GetValue(); t->SetEnd( end ); } if( m_trackNetclass->IsChecked() ) { t->SetWidth( t->GetNetClass()->GetTrackWidth() ); } else if( m_trackWidth.Valid() ) { t->SetWidth( m_trackWidth.GetValue() ); } LAYER_NUM layer = m_TrackLayerCtrl->GetLayerSelection(); if( layer != UNDEFINED_LAYER ) t->SetLayer( (LAYER_ID) layer ); break; } case PCB_VIA_T: { assert( m_vias ); VIA* v = static_cast<VIA*>( item ); if( m_viaX.Valid() || m_viaY.Valid() ) { wxPoint pos = v->GetPosition(); if( m_viaX.Valid() ) pos.x = m_viaX.GetValue(); if( m_viaY.Valid() ) pos.y = m_viaY.GetValue(); v->SetPosition( pos ); } if( m_viaNetclass->IsChecked() ) { v->SetWidth( v->GetNetClass()->GetViaDiameter() ); v->SetDrill( v->GetNetClass()->GetViaDrill() ); } else { if( m_viaDiameter.Valid() ) v->SetWidth( m_viaDiameter.GetValue() ); if( m_viaDrill.Valid() ) v->SetDrill( m_viaDrill.GetValue() ); } break; } default: assert( false ); break; } } return true; }
/* function to handle key press events */ void handleKeyPress( SDL_keysym *keysym ) { VERTEX tvec1, tvec2, fr, fl, bl, br, camray, selvert; QUATERNION trot; BEZIER * lastbez; BEZIER * colbez; ROADSTRIP * tempstrip; BEZIER patch; bool l; int i; string tstr; //else if (timefactor == 0 && !menu.InMenu()) timefactor = 0; // else timefactor = 1.0; // else { switch ( keysym->sym ) { case SDLK_ESCAPE: /* ESC key was pressed */ Quit( 0 ); //menu.MainMenu(); break; /*case SDLK_F7: tvec1 = tvec1.rotate(0,0,6.21652); cout << tvec1[0] << "," << tvec1[1] << endl; tvec2.Set(44.464,-126.8737,0); trot.Rotate(6.21652, 0, 0, 1); tvec2 = trot.RotateVec(tvec2); tvec2.DebugPrint(); break;*/ /*case SDLK_F7: if (timefactor != 100.0f) timefactor = 100.0f; else timefactor = 1.0f; break;*/ /*case SDLK_PAGEUP: //tmpvert = cam.GetVelocity(); cam.MoveRelative(0.0f, 0.0f, -2.0f); //cam.Update(); //cam.LoadVelocityIdentity(); break; case SDLK_PAGEDOWN: //tmpvert = cam.GetVelocity(); cam.MoveRelative(0.0f, 0.0f, 2.0f); //cam.Update(); //cam.LoadVelocityIdentity(); break;*/ case SDLK_BACKSPACE: if (activestrip != NULL) { if (activestrip->DeleteLastPatch()) { if (activestrip->NumPatches() == 0) { mq1.AddMessage("Deleted patch and empty road"); track.Delete(activestrip); activestrip = NULL; editordata.numbezinput = 0; } else { mq1.AddMessage("Deleted patch"); lastbez = activestrip->GetLastPatch(); if (lastbez != NULL) { editordata.bezinput[0] = lastbez->points[0][0]; editordata.bezinput[1] = lastbez->points[0][1]; editordata.bezinput[2] = lastbez->points[0][2]; editordata.bezinput[3] = lastbez->points[0][3]; } else editordata.numbezinput = 0; } } else mq1.AddMessage("Can't delete patch: no patches on this road"); } else { mq1.AddMessage("Can't delete patch: no road selected"); } break; case 'h': editordata.helppage++; break; case 'd': if (activestrip != NULL) { track.Delete(activestrip); mq1.AddMessage("Deleted road."); } else { mq1.AddMessage("Can't delete road: no road selected."); } activestrip = NULL; editordata.numbezinput = 0; break; case 'n': //create a new road mq1.AddMessage("Ready to create new road, add patches."); activestrip = NULL; editordata.numbezinput = 0; break; case 's': mq1.AddMessage("Saved to file"); track.Write(editordata.activetrack); break; case 'l': track.SetStart(cam.position.ScaleR(-1)); track.SetStartOrientation(cam.dir.ReturnConjugate()); mq1.AddMessage("Added start location"); break; case 'k': track.RemoveStart(); track.RemoveStartOrientation(); mq1.AddMessage("Removed start location"); break; case 'r': //mq1.AddMessage("Saved to file"); tvec1.zero(); tvec1.z = -1; tvec2 = cam.dir.ReturnConjugate().RotateVec(tvec1); l = track.Collide(cam.position.ScaleR(-1.0), tvec2, tvec1, true, activestrip, colbez); if (!l) { mq1.AddMessage("Can't select road: no road found under cursor"); } break; case 'a': AutoTrace(); break; case 'f': for (i = 0; i < 25; i++) { AutoTrace(); } break; case 'i': camray.z = -1; camray = cam.dir.ReturnConjugate().RotateVec(camray); if (objects.FindClosestVert(cam.position.ScaleR(-1.0), camray, selvert, tstr)) cout << tstr << endl; break; case '-': track.ClearLapSequence(); mq1.AddMessage("All lap sequence markers cleared"); break; case 'e': //mq1.AddMessage("Saved to file"); tvec1.zero(); tvec1.z = -1; tvec2 = cam.dir.ReturnConjugate().RotateVec(tvec1); l = track.Collide(cam.position.ScaleR(-1.0), tvec2, tvec1, true, tempstrip, colbez); if (!l) { mq1.AddMessage("Can't create lap sequence marker: no road found under cursor"); } else { track.AddLapSequence(colbez); } break; case '2': mq1.AddMessage("Two-vertex selection mode"); vertmode = TWOVERTS; break; case '3': mq1.AddMessage("Three-vertex selection mode"); vertmode = THREEVERTS; break; case '4': mq1.AddMessage("Four-vertex selection mode"); vertmode = FOURVERTS; break; //case SDLK_F11: //SDL_WM_ToggleFullScreen( surface ); //ChangeDisplay(1280,1024,32,true); //menu.DisplayMenu();//DisplaySelect(); //break; //case SDLK_F12: //menu.MainMenu(); //break; default: keyman.OneTime(keysym->sym); break; } } return; }
// 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->SetStart( Pad_OldPos ); if( g_DragSegmentList[ii].m_Pad_End ) Track->SetEnd( 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->SetStart( aPad->GetPosition() ); if( g_DragSegmentList[ii].m_Pad_End ) Track->SetEnd( 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 ); }
/** * Function SwapData * Used in undo / redo command: * swap data between Item and a copy * swapped data is data modified by edition, mainly sizes and texts * so ONLY FEW values are swapped * @param aItem = the item * @param aImage = a copy of the item */ void SwapData( BOARD_ITEM* aItem, BOARD_ITEM* aImage ) { if( aItem == NULL || aImage == NULL ) { wxMessageBox( wxT( "SwapData error: NULL pointer" ) ); return; } // Swap layers: if( aItem->Type() != PCB_MODULE_T && aItem->Type() != PCB_ZONE_AREA_T ) { // These items have a global swap function. int layer, layerimg; layer = aItem->GetLayer(); layerimg = aImage->GetLayer(); aItem->SetLayer( layerimg ); aImage->SetLayer( layer ); } switch( aItem->Type() ) { case PCB_MODULE_T: { MODULE* tmp = (MODULE*) aImage->Clone(); ( (MODULE*) aImage )->Copy( (MODULE*) aItem ); ( (MODULE*) aItem )->Copy( tmp ); delete tmp; } break; case PCB_ZONE_AREA_T: { ZONE_CONTAINER* tmp = (ZONE_CONTAINER*) aImage->Clone(); ( (ZONE_CONTAINER*) aImage )->Copy( (ZONE_CONTAINER*) aItem ); ( (ZONE_CONTAINER*) aItem )->Copy( tmp ); delete tmp; } break; case PCB_LINE_T: #if 0 EXCHG( ( (DRAWSEGMENT*) aItem )->m_Start, ( (DRAWSEGMENT*) aImage )->m_Start ); EXCHG( ( (DRAWSEGMENT*) aItem )->m_End, ( (DRAWSEGMENT*) aImage )->m_End ); EXCHG( ( (DRAWSEGMENT*) aItem )->m_Width, ( (DRAWSEGMENT*) aImage )->m_Width ); EXCHG( ( (DRAWSEGMENT*) aItem )->m_Shape, ( (DRAWSEGMENT*) aImage )->m_Shape ); #else { DRAWSEGMENT tmp = *(DRAWSEGMENT*) aImage; *aImage = *aItem; *aItem = tmp; } #endif break; case PCB_TRACE_T: case PCB_VIA_T: { TRACK* track = (TRACK*) aItem; TRACK* image = (TRACK*) aImage; // swap start, end, width and shape for track and image. wxPoint exchp = track->GetStart(); track->SetStart( image->GetStart() ); image->SetStart( exchp ); exchp = track->GetEnd(); track->SetEnd( image->GetEnd() ); image->SetEnd( exchp ); int atmp = track->GetWidth(); track->SetWidth( image->GetWidth() ); image->SetWidth( atmp ); atmp = track->GetShape(); track->SetShape( image->GetShape() ); image->SetShape( atmp ); atmp = track->GetDrillValue(); if( track->IsDrillDefault() ) atmp = -1; int itmp = image->GetDrillValue(); if( image->IsDrillDefault() ) itmp = -1; EXCHG(itmp, atmp ); if( atmp > 0 ) track->SetDrill( atmp ); else track->SetDrillDefault(); if( itmp > 0 ) image->SetDrill( itmp ); else image->SetDrillDefault(); } break; case PCB_TEXT_T: EXCHG( ( (TEXTE_PCB*) aItem )->m_Mirror, ( (TEXTE_PCB*) aImage )->m_Mirror ); EXCHG( ( (TEXTE_PCB*) aItem )->m_Size, ( (TEXTE_PCB*) aImage )->m_Size ); EXCHG( ( (TEXTE_PCB*) aItem )->m_Pos, ( (TEXTE_PCB*) aImage )->m_Pos ); EXCHG( ( (TEXTE_PCB*) aItem )->m_Thickness, ( (TEXTE_PCB*) aImage )->m_Thickness ); EXCHG( ( (TEXTE_PCB*) aItem )->m_Orient, ( (TEXTE_PCB*) aImage )->m_Orient ); EXCHG( ( (TEXTE_PCB*) aItem )->m_Text, ( (TEXTE_PCB*) aImage )->m_Text ); EXCHG( ( (TEXTE_PCB*) aItem )->m_Italic, ( (TEXTE_PCB*) aImage )->m_Italic ); EXCHG( ( (TEXTE_PCB*) aItem )->m_Bold, ( (TEXTE_PCB*) aImage )->m_Bold ); EXCHG( ( (TEXTE_PCB*) aItem )->m_HJustify, ( (TEXTE_PCB*) aImage )->m_HJustify ); EXCHG( ( (TEXTE_PCB*) aItem )->m_VJustify, ( (TEXTE_PCB*) aImage )->m_VJustify ); break; case PCB_TARGET_T: ( (PCB_TARGET*) aItem )->Exchg( (PCB_TARGET*) aImage ); break; case PCB_DIMENSION_T: { wxString txt = ( (DIMENSION*) aItem )->GetText(); ( (DIMENSION*) aItem )->SetText( ( (DIMENSION*) aImage )->GetText() ); ( (DIMENSION*) aImage )->SetText( txt ); EXCHG( ( (DIMENSION*) aItem )->m_Width, ( (DIMENSION*) aImage )->m_Width ); EXCHG( ( (DIMENSION*) aItem )->m_Text.m_Size, ( (DIMENSION*) aImage )->m_Text.m_Size ); EXCHG( ( (DIMENSION*) aItem )->m_Text.m_Pos, ( (DIMENSION*) aImage )->m_Text.m_Pos ); EXCHG( ( (DIMENSION*) aItem )->m_Text.m_Thickness, ( (DIMENSION*) aImage )->m_Text.m_Thickness ); EXCHG( ( (DIMENSION*) aItem )->m_Text.m_Mirror, ( (DIMENSION*) aImage )->m_Text.m_Mirror ); } break; case PCB_ZONE_T: default: wxMessageBox( wxT( "SwapData() error: unexpected type" ) ); break; } }