void GERBVIEW_FRAME::Block_Move( wxDC* DC ) { wxPoint delta; wxPoint oldpos; oldpos = GetCrossHairPosition(); m_canvas->SetMouseCaptureCallback( NULL ); SetCrossHairPosition( oldpos ); m_canvas->MoveCursorToCrossHair(); GetScreen()->SetModify(); GetScreen()->m_BlockLocate.Normalize(); /* Calculate displacement vectors. */ delta = GetScreen()->m_BlockLocate.GetMoveVector(); /* Move items in block */ for( GERBER_DRAW_ITEM* item = GetItemsList(); item; item = item->Next() ) { GERBER_DRAW_ITEM* gerb_item = (GERBER_DRAW_ITEM*) item; if( gerb_item->HitTest( GetScreen()->m_BlockLocate ) ) gerb_item->MoveAB( delta ); } m_canvas->Refresh( true ); }
/** * Function StepAndRepeatItem * Gerber format has a command Step an Repeat * This function must be called when reading a gerber file and * after creating a new gerber item that must be repeated * (i.e when m_XRepeatCount or m_YRepeatCount are > 1) * @param aItem = the item to repeat */ void GERBER_FILE_IMAGE::StepAndRepeatItem( const GERBER_DRAW_ITEM& aItem ) { if( GetLayerParams().m_XRepeatCount < 2 && GetLayerParams().m_YRepeatCount < 2 ) return; // Nothing to repeat // Duplicate item: for( int ii = 0; ii < GetLayerParams().m_XRepeatCount; ii++ ) { for( int jj = 0; jj < GetLayerParams().m_YRepeatCount; jj++ ) { // the first gerber item already exists (this is the template) // create duplicate only if ii or jj > 0 if( jj == 0 && ii == 0 ) continue; GERBER_DRAW_ITEM* dupItem = new GERBER_DRAW_ITEM( aItem ); wxPoint move_vector; move_vector.x = scaletoIU( ii * GetLayerParams().m_StepForRepeat.x, GetLayerParams().m_StepForRepeatMetric ); move_vector.y = scaletoIU( jj * GetLayerParams().m_StepForRepeat.y, GetLayerParams().m_StepForRepeatMetric ); dupItem->MoveXY( move_vector ); m_Drawings.Append( dupItem ); } } }
// Copy constructor GERBER_DRAW_ITEM::GERBER_DRAW_ITEM( const GERBER_DRAW_ITEM& aSource ) : EDA_ITEM( aSource ) { m_imageParams = aSource.m_imageParams; m_Shape = aSource.m_Shape; m_Flags = aSource.m_Flags; SetTimeStamp( aSource.m_TimeStamp ); SetStatus( aSource.GetStatus() ); m_Start = aSource.m_Start; m_End = aSource.m_End; m_Size = aSource.m_Size; m_Layer = aSource.m_Layer; m_Shape = aSource.m_Shape; m_Flashed = aSource.m_Flashed; m_DCode = aSource.m_DCode; m_PolyCorners = aSource.m_PolyCorners; m_UnitsMetric = aSource.m_UnitsMetric; m_LayerNegative = aSource.m_LayerNegative; m_swapAxis = aSource.m_swapAxis; m_mirrorA = aSource.m_mirrorA; m_mirrorB = aSource.m_mirrorB; m_layerOffset = aSource.m_layerOffset; m_drawScale = aSource.m_drawScale; m_lyrRotation = aSource.m_lyrRotation; }
/* Function HasNegativeItems * return true if at least one item must be drawn in background color * used to optimize screen refresh */ bool GERBER_FILE_IMAGE::HasNegativeItems() { if( m_hasNegativeItems < 0 ) // negative items are not yet searched: find them if any { if( m_ImageNegative ) // A negative layer is expected having always negative objects. m_hasNegativeItems = 1; else { m_hasNegativeItems = 0; for( GERBER_DRAW_ITEM* item = GetItemsList(); item; item = item->Next() ) { if( item->GetLayer() != m_GraphicLayer ) continue; if( item->HasNegativeItems() ) { m_hasNegativeItems = 1; break; } } } } return m_hasNegativeItems == 1; }
void GERBVIEW_FRAME::Erase_Current_Layer( bool query ) { int layer = getActiveLayer(); wxString msg; msg.Printf( _( "Clear layer %d?" ), layer + 1 ); if( query && !IsOK( this, msg ) ) return; SetCurItem( NULL ); GERBER_DRAW_ITEM* item = GetLayout()->m_Drawings; GERBER_DRAW_ITEM * next; for( ; item; item = next ) { next = item->Next(); if( item->GetLayer() != layer ) continue; item->DeleteStructure(); } if( g_GERBER_List[layer] ) { g_GERBER_List[layer]->InitToolTable(); g_GERBER_List[layer]->ResetDefaultValues(); } GetScreen()->SetModify(); m_canvas->Refresh(); m_LayersManager->UpdateLayerIcons(); syncLayerBox(); }
bool GERBVIEW_FRAME::Read_EXCELLON_File( const wxString& aFullFileName ) { wxString msg; int layerId = GetActiveLayer(); // current layer used in GerbView GERBER_FILE_IMAGE_LIST* images = GetGerberLayout()->GetImagesList(); auto gerber_layer = images->GetGbrImage( layerId ); auto drill_layer = dynamic_cast<EXCELLON_IMAGE*>( gerber_layer ); if( gerber_layer && !drill_layer ) { // The active layer contains old gerber data we have to clear Erase_Current_DrawLayer( false ); } if( drill_layer == nullptr ) { drill_layer = new EXCELLON_IMAGE( layerId ); layerId = images->AddGbrImage( drill_layer, layerId ); } if( layerId < 0 ) { DisplayError( this, _( "No room to load file" ) ); return false; } // Read the Excellon drill file: bool success = drill_layer->LoadFile( aFullFileName ); if( !success ) { msg.Printf( _( "File %s not found" ), GetChars( aFullFileName ) ); DisplayError( this, msg ); return false; } // Display errors list if( drill_layer->GetMessages().size() > 0 ) { HTML_MESSAGE_BOX dlg( this, _( "Error reading EXCELLON drill file" ) ); dlg.ListSet( drill_layer->GetMessages() ); dlg.ShowModal(); } if( success ) { EDA_DRAW_PANEL_GAL* canvas = GetGalCanvas(); if( canvas ) { KIGFX::VIEW* view = canvas->GetView(); for( GERBER_DRAW_ITEM* item = drill_layer->GetItemsList(); item; item = item->Next() ) { view->Add( (KIGFX::VIEW_ITEM*) item ); } } } return success; }
/* Prepare the right-click pullup menu. * The menu already has a list of zoom commands. */ bool GERBVIEW_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* aPopMenu ) { GERBER_DRAW_ITEM* currItem = (GERBER_DRAW_ITEM*) GetScreen()->GetCurItem(); wxString msg; bool BlockActive = !GetScreen()->m_BlockLocate.IsIdle(); bool busy = currItem && currItem->GetFlags(); // Do not initiate a start block validation on menu. m_canvas->SetCanStartBlock( -1 ); // Simple location of elements where possible. if( !busy ) { currItem = Locate( aPosition, CURSEUR_OFF_GRILLE ); busy = currItem && currItem->GetFlags(); } // If command in progress, end command. if( GetToolId() != ID_NO_TOOL_SELECTED ) { if( busy ) AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); else AddMenuItem( aPopMenu, ID_POPUP_CLOSE_CURRENT_TOOL, _( "End Tool" ), KiBitmap( cursor_xpm ) ); aPopMenu->AppendSeparator(); } else { if( busy || BlockActive ) { if( BlockActive ) { AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel Block" ), KiBitmap( cancel_xpm ) ); aPopMenu->AppendSeparator(); AddMenuItem( aPopMenu, ID_POPUP_PLACE_BLOCK, _( "Place Block" ), KiBitmap( checked_ok_xpm ) ); } else { AddMenuItem( aPopMenu, ID_POPUP_CANCEL_CURRENT_COMMAND, _( "Cancel" ), KiBitmap( cancel_xpm ) ); } aPopMenu->AppendSeparator(); } } if( BlockActive ) return true; if( currItem ) { GetScreen()->SetCurItem( currItem ); bool add_separator = false; // Now, display a context menu // to allow highlighting items which share the same attributes // as the selected item (net attributes and aperture attributes) const GBR_NETLIST_METADATA& net_attr = currItem->GetNetAttributes(); if( ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_PAD ) || ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_CMP ) ) { AddMenuItem( aPopMenu, ID_HIGHLIGHT_CMP_ITEMS, wxString::Format( _( "Highlight items of component '%s'" ), GetChars( net_attr.m_Cmpref ) ), KiBitmap( file_footprint_xpm ) ); add_separator = true; } if( ( net_attr.m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_NET ) ) { AddMenuItem( aPopMenu, ID_HIGHLIGHT_NET_ITEMS, wxString::Format( _( "Highlight items of net '%s'" ), GetChars( net_attr.m_Netname ) ), KiBitmap( general_ratsnest_xpm ) ); add_separator = true; } D_CODE* apertDescr = currItem->GetDcodeDescr(); if( !apertDescr->m_AperFunction.IsEmpty() ) { AddMenuItem( aPopMenu, ID_HIGHLIGHT_APER_ATTRIBUTE_ITEMS, wxString::Format( _( "Highlight aperture type '%s'" ), GetChars( apertDescr->m_AperFunction ) ), KiBitmap( flag_xpm ) ); add_separator = true; } if( add_separator ) aPopMenu->AppendSeparator(); } AddMenuItem( aPopMenu, ID_HIGHLIGHT_REMOVE_ALL, _( "Clear highlight" ), KiBitmap( gerbview_clear_layers_xpm ) ); aPopMenu->AppendSeparator(); return true; }