/** Abort function for drag or move track */ static void Abort_MoveTrack( EDA_DRAW_PANEL* aPanel, wxDC* aDC ) { PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) aPanel->GetParent(); BOARD * pcb = frame->GetBoard(); pcb->HighLightOFF(); pcb->PopHighLight(); frame->SetCurItem( NULL ); aPanel->SetMouseCapture( NULL, NULL ); // Undo move and redraw trace segments. for( unsigned jj=0 ; jj < g_DragSegmentList.size(); jj++ ) { TRACK* track = g_DragSegmentList[jj].m_Track; g_DragSegmentList[jj].RestoreInitialValues(); track->SetState( IN_EDIT, false ); track->ClearFlags(); } // Clear the undo picker list: s_ItemsListPicker.ClearListAndDeleteItems(); EraseDragList(); aPanel->Refresh(); }
// 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(); SetMsgPanel( aPad ); 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 ); } }
/* 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; }
// Place a dragged (or moved) track segment or via bool PCB_EDIT_FRAME::PlaceDraggedOrMovedTrackSegment( TRACK* Track, wxDC* DC ) { int errdrc; if( Track == NULL ) return false; int current_net_code = Track->GetNetCode(); // DRC control: if( g_Drc_On ) { errdrc = m_drc->Drc( Track, GetBoard()->m_Track ); if( errdrc == BAD_DRC ) return false; // Redraw the dragged segments for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ ) { errdrc = m_drc->Drc( g_DragSegmentList[ii].m_Track, GetBoard()->m_Track ); if( errdrc == BAD_DRC ) return false; } } // DRC Ok: place track segments Track->ClearFlags(); Track->SetState( IN_EDIT, false ); // Draw dragged tracks for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ ) { Track = g_DragSegmentList[ii].m_Track; Track->SetState( IN_EDIT, false ); Track->ClearFlags(); /* Test the connections modified by the move * (only pad connection must be tested, track connection will be * tested by TestNetConnection() ) */ LSET layerMask( Track->GetLayer() ); Track->start = GetBoard()->GetPadFast( Track->GetStart(), layerMask ); if( Track->start ) Track->SetState( BEGIN_ONPAD, true ); else Track->SetState( BEGIN_ONPAD, false ); Track->end = GetBoard()->GetPadFast( Track->GetEnd(), layerMask ); if( Track->end ) Track->SetState( END_ONPAD, true ); else Track->SetState( END_ONPAD, false ); } EraseDragList(); SaveCopyInUndoList( s_ItemsListPicker, UR_UNSPECIFIED ); s_ItemsListPicker.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items GetBoard()->PopHighLight(); OnModify(); m_canvas->SetMouseCapture( NULL, NULL ); if( current_net_code > 0 ) TestNetConnection( DC, current_net_code ); m_canvas->Refresh(); return true; }
void PCB_EDIT_FRAME::Start_DragTrackSegmentAndKeepSlope( TRACK* track, wxDC* DC ) { TRACK* TrackToStartPoint = NULL; TRACK* TrackToEndPoint = NULL; bool error = false; if( !track ) return; // TODO: Use clenup functions to merge collinear segments if track // is connected to a collinear segment. s_StartSegmentPresent = s_EndSegmentPresent = true; if( ( track->start == NULL ) || ( track->start->Type() == PCB_TRACE_T ) ) TrackToStartPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START, true, false ); // Test if more than one segment is connected to this point if( TrackToStartPoint ) { TrackToStartPoint->SetState( BUSY, true ); if( ( TrackToStartPoint->Type() == PCB_VIA_T ) || track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_START, true, false ) ) error = true; TrackToStartPoint->SetState( BUSY, false ); } if( ( track->end == NULL ) || ( track->end->Type() == PCB_TRACE_T ) ) TrackToEndPoint = track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END, true, false ); // Test if more than one segment is connected to this point if( TrackToEndPoint ) { TrackToEndPoint->SetState( BUSY, true ); if( (TrackToEndPoint->Type() == PCB_VIA_T) || track->GetTrack( GetBoard()->m_Track, NULL, ENDPOINT_END, true, false ) ) error = true; TrackToEndPoint->SetState( BUSY, false ); } if( error ) { DisplayError( this, _( "Unable to drag this segment: too many segments connected" ) ); return; } if( !TrackToStartPoint || ( TrackToStartPoint->Type() != PCB_TRACE_T ) ) s_StartSegmentPresent = false; if( !TrackToEndPoint || ( TrackToEndPoint->Type() != PCB_TRACE_T ) ) s_EndSegmentPresent = false; // Change high light net: the new one will be highlighted GetBoard()->PushHighLight(); if( GetBoard()->IsHighLightNetON() ) HighLight( DC ); EraseDragList(); track->SetFlags( IS_DRAGGED ); if( TrackToStartPoint ) { STATUS_FLAGS flag = STARTPOINT; if( track->GetStart() != TrackToStartPoint->GetStart() ) flag = ENDPOINT; AddSegmentToDragList( flag, TrackToStartPoint ); track->SetFlags( STARTPOINT ); } if( TrackToEndPoint ) { STATUS_FLAGS flag = STARTPOINT; if( track->GetEnd() != TrackToEndPoint->GetStart() ) flag = ENDPOINT; AddSegmentToDragList( flag, TrackToEndPoint ); track->SetFlags( ENDPOINT ); } AddSegmentToDragList( track->GetFlags(), track ); UndrawAndMarkSegmentsToDrag( m_canvas, DC ); PosInit = GetCrossHairPosition(); s_LastPos = GetCrossHairPosition(); m_canvas->SetMouseCapture( Show_Drag_Track_Segment_With_Cte_Slope, Abort_MoveTrack ); GetBoard()->SetHighLightNet( track->GetNetCode() ); GetBoard()->HighLightON(); GetBoard()->DrawHighLight( m_canvas, DC, GetBoard()->GetHighLightNetCode() ); // Prepare the Undo command ITEM_PICKER picker( NULL, UR_CHANGED ); for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ ) { TRACK* draggedtrack = g_DragSegmentList[ii].m_Track; picker.SetItem( draggedtrack); picker.SetLink ( draggedtrack->Clone() ); s_ItemsListPicker.PushItem( picker ); draggedtrack = (TRACK*) picker.GetLink(); draggedtrack->SetStatus( 0 ); draggedtrack->ClearFlags(); } if( !InitialiseDragParameters() ) { DisplayError( this, _( "Unable to drag this segment: two collinear segments" ) ); m_canvas->SetMouseCaptureCallback( NULL ); Abort_MoveTrack( m_canvas, DC ); return; } }
void PCB_EDIT_FRAME::StartMoveOneNodeOrSegment( TRACK* aTrack, wxDC* aDC, int aCommand ) { if( !aTrack ) return; EraseDragList(); // Change highlighted net: the new one will be highlighted GetBoard()->PushHighLight(); if( GetBoard()->IsHighLightNetON() ) HighLight( aDC ); PosInit = GetCrossHairPosition(); if( aTrack->Type() == PCB_VIA_T ) { aTrack->SetFlags( IS_DRAGGED | STARTPOINT | ENDPOINT ); AddSegmentToDragList( aTrack->GetFlags(), aTrack ); if( aCommand != ID_POPUP_PCB_MOVE_TRACK_SEGMENT ) { Collect_TrackSegmentsToDrag( GetBoard(), aTrack->GetStart(), aTrack->GetLayerSet(), aTrack->GetNetCode(), aTrack->GetWidth() / 2 ); } PosInit = aTrack->GetStart(); } else { STATUS_FLAGS diag = aTrack->IsPointOnEnds( GetCrossHairPosition(), -1 ); wxPoint pos; switch( aCommand ) { case ID_POPUP_PCB_MOVE_TRACK_SEGMENT: // Move segment aTrack->SetFlags( IS_DRAGGED | ENDPOINT | STARTPOINT ); AddSegmentToDragList( aTrack->GetFlags(), aTrack ); break; case ID_POPUP_PCB_DRAG_TRACK_SEGMENT: // drag a segment pos = aTrack->GetStart(); Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerSet(), aTrack->GetNetCode(), aTrack->GetWidth() / 2 ); pos = aTrack->GetEnd(); aTrack->SetFlags( IS_DRAGGED | ENDPOINT | STARTPOINT ); Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerSet(), aTrack->GetNetCode(), aTrack->GetWidth() / 2 ); break; case ID_POPUP_PCB_MOVE_TRACK_NODE: // Drag via or move node pos = (diag & STARTPOINT) ? aTrack->GetStart() : aTrack->GetEnd(); Collect_TrackSegmentsToDrag( GetBoard(), pos, aTrack->GetLayerSet(), aTrack->GetNetCode(), aTrack->GetWidth() / 2 ); PosInit = pos; break; } aTrack->SetFlags( IS_DRAGGED ); } // Prepare the Undo command ITEM_PICKER picker( aTrack, UR_CHANGED ); picker.SetLink( aTrack->Clone() ); s_ItemsListPicker.PushItem( picker ); for( unsigned ii = 0; ii < g_DragSegmentList.size(); ii++ ) { TRACK* draggedtrack = g_DragSegmentList[ii].m_Track; picker.SetItem( draggedtrack ); picker.SetLink( draggedtrack->Clone() ); s_ItemsListPicker.PushItem( picker ); draggedtrack = (TRACK*) picker.GetLink(); draggedtrack->SetStatus( 0 ); draggedtrack->ClearFlags(); } s_LastPos = PosInit; m_canvas->SetMouseCapture( Show_MoveNode, Abort_MoveTrack ); GetBoard()->SetHighLightNet( aTrack->GetNetCode() ); GetBoard()->HighLightON(); GetBoard()->DrawHighLight( m_canvas, aDC, GetBoard()->GetHighLightNetCode() ); m_canvas->CallMouseCapture( aDC, wxDefaultPosition, true ); 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->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 ); }