void PCB_EDIT_FRAME::Block_Flip() { #define INVERT( pos ) (pos) = center.y - ( (pos) - center.y ) wxPoint memo; wxPoint center; // Position of the axis for inversion of all elements OnModify(); PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems(); itemsList->m_Status = UR_FLIPPED; memo = GetCrossHairPosition(); center = GetScreen()->m_BlockLocate.Centre(); for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii ); wxASSERT( item ); itemsList->SetPickedItemStatus( UR_FLIPPED, ii ); item->Flip( center ); switch( item->Type() ) { case PCB_MODULE_T: item->ClearFlags(); m_Pcb->m_Status_Pcb = 0; break; // Move and rotate the track segments case PCB_TRACE_T: // a track segment (segment on a copper layer) case PCB_VIA_T: // a via (like track segment on a copper layer) m_Pcb->m_Status_Pcb = 0; break; case PCB_ZONE_AREA_T: case PCB_LINE_T: case PCB_TEXT_T: case PCB_TARGET_T: case PCB_DIMENSION_T: break; // This item is not put in undo list case PCB_ZONE_T: // SEG_ZONE items are now deprecated itemsList->RemovePicker( ii ); ii--; break; default: wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Flip( ) error: unexpected type" ) ); break; } } SaveCopyInUndoList( *itemsList, UR_FLIPPED, center ); Compile_Ratsnest( NULL, true ); m_canvas->Refresh( true ); }
void PCB_EDIT_FRAME::Block_Delete() { OnModify(); SetCurItem( NULL ); PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems(); itemsList->m_Status = UR_DELETED; // unlink items and clear flags for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii ); itemsList->SetPickedItemStatus( UR_DELETED, ii ); GetBoard()->GetConnectivity()->Remove( item ); switch( item->Type() ) { case PCB_MODULE_T: { MODULE* module = (MODULE*) item; module->ClearFlags(); module->UnLink(); m_Pcb->m_Status_Pcb = 0; } break; case PCB_ZONE_AREA_T: // a zone area m_Pcb->Remove( item ); break; case PCB_LINE_T: // a segment not on copper layers case PCB_TEXT_T: // a text on a layer case PCB_TRACE_T: // a track segment (segment on a copper layer) case PCB_VIA_T: // a via (like track segment on a copper layer) case PCB_DIMENSION_T: // a dimension (graphic item) case PCB_TARGET_T: // a target (graphic item) item->UnLink(); break; // These items are deleted, but not put in undo list case PCB_MARKER_T: // a marker used to show something case PCB_ZONE_T: // SEG_ZONE items are now deprecated item->UnLink(); itemsList->RemovePicker( ii ); ii--; item->DeleteStructure(); break; default: wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Delete( ) error: unexpected type" ) ); break; } } SaveCopyInUndoList( *itemsList, UR_DELETED ); Compile_Ratsnest( NULL, true ); m_canvas->Refresh( true ); }
void PCB_EDIT_FRAME::Block_Rotate() { wxPoint oldpos; wxPoint centre; // rotation cent-re for the rotation transform int rotAngle = 900; // rotation angle in 0.1 deg. oldpos = GetScreen()->GetCrossHairPosition(); centre = GetScreen()->m_BlockLocate.Centre(); OnModify(); PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.m_ItemsSelection; itemsList->m_Status = UR_ROTATED; for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii ); wxASSERT( item ); itemsList->SetPickedItemStatus( UR_ROTATED, ii ); item->Rotate( centre, rotAngle ); switch( item->Type() ) { case PCB_MODULE_T: ( (MODULE*) item )->ClearFlags(); m_Pcb->m_Status_Pcb = 0; break; /* Move and rotate the track segments */ case PCB_TRACE_T: // a track segment (segment on a copper layer) case PCB_VIA_T: // a via (like track segment on a copper layer) m_Pcb->m_Status_Pcb = 0; break; case PCB_ZONE_AREA_T: case PCB_LINE_T: case PCB_TEXT_T: case PCB_TARGET_T: case PCB_DIMENSION_T: break; // This item is not put in undo list case PCB_ZONE_T: // SEG_ZONE items are now deprecated itemsList->RemovePicker( ii ); ii--; break; default: wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Rotate( ) error: unexpected type" ) ); break; } } SaveCopyInUndoList( *itemsList, UR_ROTATED, centre ); Compile_Ratsnest( NULL, true ); m_canvas->Refresh( true ); }
void PCB_EDIT_FRAME::Block_Move() { OnModify(); wxPoint MoveVector = GetScreen()->m_BlockLocate.GetMoveVector(); PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems(); itemsList->m_Status = UR_MOVED; for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii ); itemsList->SetPickedItemStatus( UR_MOVED, ii ); item->Move( MoveVector ); GetBoard()->GetConnectivity()->Update( item ); item->ClearFlags( IS_MOVED ); switch( item->Type() ) { case PCB_MODULE_T: m_Pcb->m_Status_Pcb = 0; item->ClearFlags(); break; // Move track segments case PCB_TRACE_T: // a track segment (segment on a copper layer) case PCB_VIA_T: // a via (like a track segment on a copper layer) m_Pcb->m_Status_Pcb = 0; break; case PCB_ZONE_AREA_T: case PCB_LINE_T: case PCB_TEXT_T: case PCB_TARGET_T: case PCB_DIMENSION_T: break; // This item is not put in undo list case PCB_ZONE_T: // SEG_ZONE items are now deprecated itemsList->RemovePicker( ii ); ii--; break; default: wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Move( ) error: unexpected type" ) ); break; } } SaveCopyInUndoList( *itemsList, UR_MOVED, MoveVector ); Compile_Ratsnest( NULL, true ); m_canvas->Refresh( true ); }
/** * Function UpdateCopyOfZonesList * check a pick list to remove zones identical to their copies * and set the type of operation in picker (UR_DELETED, UR_CHANGED) * if an item is deleted, the initial values are retrievered, * because they can have changed in edition * @param aPickList = the main pick list * @param aAuxiliaryList = the list of deleted or added (new created) items after calculations * @param aPcb = the Board * * aAuxiliaryList is a list of pickers updated by zone algorithms: * This list contains zones which were added or deleted during the zones combine process * aPickList :is a list of zones that can be modified (changed or deleted, or not modified) * Typically, this is the list of existing zones on the layer of the edited zone, * before any change. * >> if the picked zone is not changed, it is removed from list * >> if the picked zone was deleted (i.e. not found in board list), the picker is modified: * its status becomes UR_DELETED * the aAuxiliaryList corresponding picker is removed (if not found : set an error) * >> if the picked zone was flagged as UR_NEW, and was after deleted , * perhaps combined with an other zone (i.e. not found in board list): * the picker is removed * the zone itself if really deleted * the aAuxiliaryList corresponding picker is removed (if not found : set an error) * After aPickList is cleaned, the aAuxiliaryList is read * All pickers flagged UR_NEW are moved to aPickList * (the corresponding zones are zone that were created by the zone normalize and combine process, * mainly when adding cutout areas, or creating self intersecting contours) * All pickers flagged UR_DELETED are removed, and the coresponding zones actually deleted * (the corresponding zones are new zone that were created by the zone normalize process, * when creating self intersecting contours, and after combined with an existing zone. * At the end of the update process the aAuxiliaryList must be void, * because all pickers created by the combine process * must have been removed (removed for new and deleted zones, or moved in aPickList.) * If not an error is set. */ void UpdateCopyOfZonesList( PICKED_ITEMS_LIST& aPickList, PICKED_ITEMS_LIST& aAuxiliaryList, BOARD* aPcb ) { for( unsigned kk = 0; kk < aPickList.GetCount(); kk++ ) { UNDO_REDO_T status = aPickList.GetPickedItemStatus( kk ); ZONE_CONTAINER* ref = (ZONE_CONTAINER*) aPickList.GetPickedItem( kk ); for( unsigned ii = 0; ; ii++ ) // analyse the main picked list { ZONE_CONTAINER* zone = aPcb->GetArea( ii ); if( zone == NULL ) { /* End of list: the stored item is not found: * it must be in aDeletedList: * search it and restore initial values * or * if flagged UR_NEW: remove it definitively */ if( status == UR_NEW ) { delete ref; ref = NULL; aPickList.RemovePicker( kk ); kk--; } else { ZONE_CONTAINER* zcopy = (ZONE_CONTAINER*) aPickList.GetPickedItemLink( kk ); aPickList.SetPickedItemStatus( UR_DELETED, kk ); wxASSERT_MSG( zcopy != NULL, wxT( "UpdateCopyOfZonesList() error: link = NULL" ) ); ref->Copy( zcopy ); // the copy was deleted; the link does not exists now. aPickList.SetPickedItemLink( NULL, kk ); delete zcopy; } // Remove this item from aAuxiliaryList, mainly for tests purpose bool notfound = true; for( unsigned nn = 0; nn < aAuxiliaryList.GetCount(); nn++ ) { if( ref != NULL && aAuxiliaryList.GetPickedItem( nn ) == ref ) { aAuxiliaryList.RemovePicker( nn ); notfound = false; break; } } wxASSERT_MSG( notfound != true, wxT( "UpdateCopyOfZonesList() error: item not found in " "aAuxiliaryList" ) ); break; } if( zone == ref ) // picked zone found { if( aPickList.GetPickedItemStatus( kk ) != UR_NEW ) { ZONE_CONTAINER* zcopy = (ZONE_CONTAINER*) aPickList.GetPickedItemLink( kk ); if( zone->IsSame( *zcopy ) ) // Remove picked, because no changes { delete zcopy; // Delete copy aPickList.RemovePicker( kk ); kk--; } } break; } } } // Add new zones in main pick list, and remove pickers from Auxiliary List for( unsigned ii = 0; ii < aAuxiliaryList.GetCount(); ) { if( aAuxiliaryList.GetPickedItemStatus( ii ) == UR_NEW ) { ITEM_PICKER picker = aAuxiliaryList.GetItemWrapper( ii ); aPickList.PushItem( picker ); aAuxiliaryList.RemovePicker( ii ); } else if( aAuxiliaryList.GetPickedItemStatus( ii ) == UR_DELETED ) { delete aAuxiliaryList.GetPickedItemLink( ii ); aAuxiliaryList.RemovePicker( ii ); } else ii++; } // Should not occur: wxASSERT_MSG( aAuxiliaryList.GetCount() == 0, wxT( "UpdateCopyOfZonesList() error: aAuxiliaryList not empty." ) ); }
void PCB_EDIT_FRAME::Block_Rotate() { wxPoint centre; // rotation cent-re for the rotation transform int rotAngle = m_rotationAngle; // rotation angle in 0.1 deg. centre = GetScreen()->m_BlockLocate.Centre(); OnModify(); PICKED_ITEMS_LIST* itemsList = &GetScreen()->m_BlockLocate.GetItems(); itemsList->m_Status = UR_CHANGED; for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii ); wxASSERT( item ); itemsList->SetPickedItemStatus( UR_CHANGED, ii ); switch( item->Type() ) { case PCB_MODULE_T: ( (MODULE*) item )->ClearFlags(); m_Pcb->m_Status_Pcb = 0; break; // Move and rotate the track segments case PCB_TRACE_T: // a track segment (segment on a copper layer) case PCB_VIA_T: // a via (like track segment on a copper layer) m_Pcb->m_Status_Pcb = 0; break; case PCB_ZONE_AREA_T: case PCB_LINE_T: case PCB_TEXT_T: case PCB_TARGET_T: case PCB_DIMENSION_T: break; // This item is not put in undo list case PCB_ZONE_T: // SEG_ZONE items are now deprecated itemsList->RemovePicker( ii ); ii--; break; default: wxMessageBox( wxT( "PCB_EDIT_FRAME::Block_Rotate( ) error: unexpected type" ) ); break; } } // Save all the block items in there current state before applying the rotation. SaveCopyInUndoList( *itemsList, UR_CHANGED, centre ); // Now perform the rotation. for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii ); wxASSERT( item ); item->Rotate( centre, rotAngle ); GetBoard()->GetConnectivity()->Update( item ); } Compile_Ratsnest( NULL, true ); m_canvas->Refresh( true ); }