void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge ) { MODULE* module = GetBoard()->m_Modules; SaveCopyInUndoList( module, UR_CHANGED ); if( aEdge == NULL ) { for( BOARD_ITEM *item = module->GraphicalItemsList(); item; item = item->Next() ) { aEdge = dyn_cast<EDGE_MODULE*>( item ); if( aEdge ) aEdge->SetWidth( GetDesignSettings().GetLineThickness( aEdge->GetLayer() ) ); } } else { aEdge->SetWidth( GetDesignSettings().GetLineThickness( aEdge->GetLayer() ) ); } OnModify(); module->CalculateBoundingBox(); module->SetLastEditTime(); }
void FOOTPRINT_EDIT_FRAME::Edit_Edge_Width( EDGE_MODULE* aEdge ) { MODULE* module = GetBoard()->m_Modules; SaveCopyInUndoList( module, UR_MODEDIT ); if( aEdge == NULL ) { aEdge = (EDGE_MODULE*) (BOARD_ITEM*) module->m_Drawings; for( ; aEdge != NULL; aEdge = aEdge->Next() ) { if( aEdge->Type() != PCB_MODULE_EDGE_T ) continue; aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth ); } } else { aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth ); } OnModify(); module->CalculateBoundingBox(); module->m_LastEdit_Time = time( NULL ); }
MODULE* PCB_BASE_FRAME::Create_1_Module( const wxString& aModuleName ) { MODULE* module; wxString moduleName; wxPoint newpos; moduleName = aModuleName; // Ask for the new module reference if( moduleName.IsEmpty() ) { wxTextEntryDialog dlg( this, FMT_MOD_REF, FMT_MOD_CREATE, moduleName ); if( dlg.ShowModal() != wxID_OK ) return NULL; //Aborted by user moduleName = dlg.GetValue(); } moduleName.Trim( true ); moduleName.Trim( false ); if( moduleName.IsEmpty( ) ) { DisplayInfoMessage( this, FMT_NO_REF_ABORTED ); return NULL; } // Creates the new module and add it to the head of the linked list of modules module = new MODULE( GetBoard() ); GetBoard()->Add( module ); // Update parameters: position, timestamp ... newpos = GetScreen()->GetCrossHairPosition(); module->SetPosition( newpos ); module->SetLastEditTime(); // Update its name in lib module->m_LibRef = moduleName; // Update reference: module->m_Reference->m_Text = moduleName; module->m_Reference->SetThickness( GetDesignSettings().m_ModuleTextWidth ); module->m_Reference->SetSize( GetDesignSettings().m_ModuleTextSize ); // Set the value field to a default value module->m_Value->m_Text = wxT( "VAL**" ); module->m_Value->SetThickness( GetDesignSettings().m_ModuleTextWidth ); module->m_Value->SetSize( GetDesignSettings().m_ModuleTextSize ); module->SetPosition( wxPoint( 0, 0 ) ); SetMsgPanel( module ); return module; }
wxSize D_PAD::GetSolderPasteMargin() const { // The pad inherits the margin only to calculate a default shape, // therefore only if it is also a copper layer. // Pads defined only on mask layers (and perhaps on other tech layers) use the shape // defined by the pad settings only bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any(); if( !isOnCopperLayer ) return wxSize( 0, 0 ); int margin = m_LocalSolderPasteMargin; double mratio = m_LocalSolderPasteMarginRatio; MODULE* module = GetParent(); if( module ) { if( margin == 0 ) margin = module->GetLocalSolderPasteMargin(); auto brd = GetBoard(); if( margin == 0 && brd ) { margin = brd->GetDesignSettings().m_SolderPasteMargin; } if( mratio == 0.0 ) mratio = module->GetLocalSolderPasteMarginRatio(); if( mratio == 0.0 && brd ) { mratio = brd->GetDesignSettings().m_SolderPasteMarginRatio; } } wxSize pad_margin; pad_margin.x = margin + KiROUND( m_Size.x * mratio ); pad_margin.y = margin + KiROUND( m_Size.y * mratio ); // ensure mask have a size always >= 0 if( pad_margin.x < -m_Size.x / 2 ) pad_margin.x = -m_Size.x / 2; if( pad_margin.y < -m_Size.y / 2 ) pad_margin.y = -m_Size.y / 2; return pad_margin; }
void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet( SHAPE_POLY_SET& aCornerBuffer, int aError ) const { if( GetFilledPolysList().IsEmpty() ) return; // add filled areas polygons aCornerBuffer.Append( m_FilledPolysList ); auto board = GetBoard(); int maxError = ARC_HIGH_DEF; if( board ) maxError = board->GetDesignSettings().m_MaxError; // add filled areas outlines, which are drawn with thick lines for( int i = 0; i < m_FilledPolysList.OutlineCount(); i++ ) { const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( i ); for( int j = 0; j < path.PointCount(); j++ ) { const VECTOR2I& a = path.CPoint( j ); const VECTOR2I& b = path.CPoint( j + 1 ); TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ), wxPoint( b.x, b.y ), maxError, GetMinThickness() ); } } }
/* Initialize the drawing of a segment of type other than trace. */ DRAWSEGMENT* PCB_EDIT_FRAME::Begin_DrawSegment( DRAWSEGMENT* Segment, STROKE_T shape, wxDC* DC ) { int lineWidth; DRAWSEGMENT* DrawItem; lineWidth = GetDesignSettings().GetLineThickness( GetActiveLayer() ); if( Segment == NULL ) // Create new segment. { SetCurItem( Segment = new DRAWSEGMENT( GetBoard() ) ); Segment->SetFlags( IS_NEW ); Segment->SetLayer( GetActiveLayer() ); Segment->SetWidth( lineWidth ); Segment->SetShape( shape ); Segment->SetAngle( 900 ); Segment->SetStart( GetCrossHairPosition() ); Segment->SetEnd( GetCrossHairPosition() ); m_canvas->SetMouseCapture( DrawSegment, Abort_EditEdge ); } else { // The ending point coordinate Segment->m_End was updated by the function // DrawSegment() called on a move mouse event during the segment creation if( Segment->GetStart() != Segment->GetEnd() ) { if( Segment->GetShape() == S_SEGMENT ) { SaveCopyInUndoList( Segment, UR_NEW ); GetBoard()->Add( Segment ); OnModify(); Segment->ClearFlags(); Segment->Draw( m_canvas, DC, GR_OR ); DrawItem = Segment; SetCurItem( Segment = new DRAWSEGMENT( GetBoard() ) ); Segment->SetFlags( IS_NEW ); Segment->SetLayer( DrawItem->GetLayer() ); Segment->SetWidth( lineWidth ); Segment->SetShape( DrawItem->GetShape() ); Segment->SetType( DrawItem->GetType() ); Segment->SetAngle( DrawItem->GetAngle() ); Segment->SetStart( DrawItem->GetEnd() ); Segment->SetEnd( DrawItem->GetEnd() ); DrawSegment( m_canvas, DC, wxDefaultPosition, false ); } else { End_Edge( Segment, DC ); Segment = NULL; } } } return Segment; }
void PCB_EDIT_FRAME::OnUpdateSelectTrackWidth( wxUpdateUIEvent& aEvent ) { if( aEvent.GetId() == ID_AUX_TOOLBAR_PCB_TRACK_WIDTH ) { if( m_SelTrackWidthBox->GetSelection() != (int) GetDesignSettings().GetTrackWidthIndex() ) m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() ); } else { bool check = ( ( ( ID_POPUP_PCB_SELECT_WIDTH1 + (int) GetDesignSettings().GetTrackWidthIndex() ) == aEvent.GetId() ) && !GetDesignSettings().m_UseConnectedTrackWidth && !GetDesignSettings().UseCustomTrackViaSize() ); aEvent.Check( check ); } }
/* Add a new pad to aModule. */ void PCB_BASE_FRAME::AddPad( MODULE* aModule, bool draw ) { m_Pcb->m_Status_Pcb = 0; aModule->SetLastEditTime(); D_PAD* pad = new D_PAD( aModule ); // Add the new pad to end of the module pad list. aModule->Pads().PushBack( pad ); // Update the pad properties, // and keep NETINFO_LIST::ORPHANED as net info // which is the default when nets cannot be handled. Import_Pad_Settings( pad, false ); pad->SetPosition( GetCrossHairPosition() ); // Set the relative pad position // ( pad position for module orient, 0, and relative to the module position) wxPoint pos0 = pad->GetPosition() - aModule->GetPosition(); RotatePoint( &pos0, -aModule->GetOrientation() ); pad->SetPos0( pos0 ); /* NPTH pads take empty pad number (since they can't be connected), * other pads get incremented from the last one edited */ wxString padName; if( pad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED ) { padName = GetNextPadName( GetDesignSettings() .m_Pad_Master.GetPadName() ); } pad->SetPadName( padName ); GetDesignSettings().m_Pad_Master.SetPadName( padName ); aModule->CalculateBoundingBox(); SetMsgPanel( pad ); if( draw ) m_canvas->RefreshDrawingRect( aModule->GetBoundingBox() ); }
void PCB_EDIT_FRAME::OnUpdateSelectViaSize( wxUpdateUIEvent& aEvent ) { wxString msg; if( aEvent.GetId() == ID_AUX_TOOLBAR_PCB_VIA_SIZE ) { if( m_SelViaSizeBox->GetSelection() != (int) GetDesignSettings().GetViaSizeIndex() ) m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() ); } else { bool check = ( ( ( ID_POPUP_PCB_SELECT_VIASIZE1 + (int) GetDesignSettings().GetViaSizeIndex() ) == aEvent.GetId() ) && !GetDesignSettings().m_UseConnectedTrackWidth && !GetDesignSettings().UseCustomTrackViaSize() ); aEvent.Check( check ); } }
void PCB_BASE_FRAME::ResetTextSize( BOARD_ITEM* aItem, wxDC* aDC ) { wxSize newSize; int newThickness; if( aItem->Type() == PCB_TEXT_T ) { newSize = GetDesignSettings().m_PcbTextSize; newThickness = GetDesignSettings().m_PcbTextWidth; TEXTE_PCB* text = static_cast<TEXTE_PCB*>( aItem ); // Exit if there's nothing to do if( text->GetTextSize() == newSize && text->GetThickness() == newThickness ) return; SaveCopyInUndoList( text, UR_CHANGED ); text->SetTextSize( newSize ); text->SetThickness( newThickness ); } else if( aItem->Type() == PCB_MODULE_TEXT_T ) { newSize = GetDesignSettings().m_ModuleTextSize; newThickness = GetDesignSettings().m_ModuleTextWidth; TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( aItem ); // Exit if there's nothing to do if( text->GetTextSize() == newSize && text->GetThickness() == newThickness ) return; SaveCopyInUndoList( text->GetParent(), UR_CHANGED ); text->SetTextSize( newSize ); text->SetThickness( newThickness ); } else return; if( aDC ) m_canvas->Refresh(); OnModify(); }
bool PCB_EDIT_FRAME::SetCurrentNetClass( const wxString& aNetClassName ) { bool change = GetDesignSettings().SetCurrentNetClass( aNetClassName ); if( change ) { ReCreateAuxiliaryToolbar(); } return change; }
/* * Exports the current pad settings to board design settings. */ void PCB_BASE_FRAME::Export_Pad_Settings( D_PAD* aPad ) { if( aPad == NULL ) return; SetMsgPanel( aPad ); D_PAD& masterPad = GetDesignSettings().m_Pad_Master; masterPad.ImportSettingsFromMaster( *aPad ); }
/* Imports the board design settings to aPad * - The position, names, and keys are not modifed. */ void PCB_BASE_FRAME::Import_Pad_Settings( D_PAD* aPad, bool aDraw ) { if( aDraw ) { aPad->SetFlags( DO_NOT_DRAW ); m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() ); aPad->ClearFlags( DO_NOT_DRAW ); } D_PAD& mp = GetDesignSettings().m_Pad_Master; aPad->SetShape( mp.GetShape() ); aPad->SetLayerSet( mp.GetLayerSet() ); aPad->SetAttribute( mp.GetAttribute() ); aPad->SetOrientation( mp.GetOrientation() + aPad->GetParent()->GetOrientation() ); aPad->SetSize( mp.GetSize() ); aPad->SetDelta( wxSize( 0, 0 ) ); aPad->SetOffset( mp.GetOffset() ); aPad->SetDrillSize( mp.GetDrillSize() ); aPad->SetDrillShape( mp.GetDrillShape() ); switch( mp.GetShape() ) { case PAD_TRAPEZOID: aPad->SetDelta( mp.GetDelta() ); break; case PAD_CIRCLE: // ensure size.y == size.x aPad->SetSize( wxSize( aPad->GetSize().x, aPad->GetSize().x ) ); break; default: ; } switch( mp.GetAttribute() ) { case PAD_SMD: case PAD_CONN: aPad->SetDrillSize( wxSize( 0, 0 ) ); aPad->SetOffset( wxPoint( 0, 0 ) ); break; default: ; } if( aDraw ) m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() ); aPad->GetParent()->SetLastEditTime(); OnModify(); }
void FOOTPRINT_EDIT_FRAME::Enter_Edge_Width( EDGE_MODULE* aEdge ) { wxString buffer; buffer = StringFromValue( g_UserUnit, GetDesignSettings().m_ModuleSegmentWidth ); wxTextEntryDialog dlg( this, _( "New Width:" ), _( "Edge Width" ), buffer ); if( dlg.ShowModal() != wxID_OK ) return; // canceled by user buffer = dlg.GetValue( ); GetDesignSettings().m_ModuleSegmentWidth = ValueFromString( g_UserUnit, buffer ); if( aEdge ) { MODULE* module = GetBoard()->m_Modules; aEdge->SetWidth( GetDesignSettings().m_ModuleSegmentWidth ); module->CalculateBoundingBox(); OnModify(); } }
void PCB_EDIT_FRAME::updateViaSizeSelectBox() { if( m_SelViaSizeBox == NULL ) return; wxString msg; m_SelViaSizeBox->Clear(); bool mmFirst = g_UserUnit != INCHES; for( unsigned ii = 0; ii < GetDesignSettings().m_ViasDimensionsList.size(); ii++ ) { int diam = GetDesignSettings().m_ViasDimensionsList[ii].m_Diameter; double valueMils = To_User_Unit( INCHES, diam ) * 1000; double value_mm = To_User_Unit( MILLIMETRES, diam ); if( mmFirst ) msg.Printf( _( "Via: %.2f mm (%.1f mils)" ), value_mm, valueMils ); else msg.Printf( _( "Via: %.1f mils (%.2f mm)" ), valueMils, value_mm ); int hole = GetDesignSettings().m_ViasDimensionsList[ii].m_Drill; if( hole ) { msg << wxT("/ "); wxString hole_str; valueMils = To_User_Unit( INCHES, hole ) * 1000; value_mm = To_User_Unit( MILLIMETRES, hole ); if( mmFirst ) hole_str.Printf( _( "%.2f mm (%.1f mils)" ), value_mm, valueMils ); else hole_str.Printf( _( "%.1f mils (%.2f mm)" ), valueMils, value_mm ); msg += hole_str; } // Mark the netclass via size value (the first in list) if( ii == 0 ) msg << wxT( " *" ); m_SelViaSizeBox->Append( msg ); } if( GetDesignSettings().GetViaSizeIndex() >= GetDesignSettings().m_ViasDimensionsList.size() ) GetDesignSettings().SetViaSizeIndex( 0 ); m_SelViaSizeBox->SetSelection( GetDesignSettings().GetViaSizeIndex() ); }
void FOOTPRINT_EDIT_FRAME::LoadSettings( wxConfigBase* aCfg ) { PCB_BASE_FRAME::LoadSettings( aCfg ); wxConfigLoadSetups( aCfg, GetConfigurationSettings() ); // Ensure some params are valid BOARD_DESIGN_SETTINGS& settings = GetDesignSettings(); // Usually, graphic items are drawn on F_SilkS or F_Fab layer // Force these layers if not default if( ( settings.m_RefDefaultlayer != F_SilkS ) && ( settings.m_RefDefaultlayer != F_Fab ) ) settings.m_RefDefaultlayer = F_SilkS; if( ( settings.m_ValueDefaultlayer != F_SilkS ) && ( settings.m_ValueDefaultlayer != F_Fab ) ) settings.m_ValueDefaultlayer = F_Fab; }
PCB_TARGET* PCB_EDIT_FRAME::CreateTarget( wxDC* DC ) { PCB_TARGET* target = new PCB_TARGET( GetBoard() ); target->SetFlags( IS_NEW ); GetBoard()->Add( target ); target->SetLayer( Edge_Cuts ); target->SetWidth( GetDesignSettings().m_EdgeSegmentWidth ); target->SetSize( MireDefaultSize ); target->SetPosition( GetCrossHairPosition() ); PlaceTarget( target, DC ); return target; }
bool PCB_EDIT_FRAME::IsMicroViaAcceptable() { int copperlayercnt = GetBoard()->GetCopperLayerCount( ); LAYER_ID currLayer = GetActiveLayer(); if( !GetDesignSettings().m_MicroViasAllowed ) return false; // Obvious.. if( copperlayercnt < 4 ) return false; // Only on multilayer boards.. if( ( currLayer == B_Cu ) || ( currLayer == F_Cu ) || ( currLayer == copperlayercnt - 2 ) || ( currLayer == In1_Cu ) ) return true; return false; }
bool PCB_EDIT_FRAME::IsMicroViaAcceptable( void ) { int copperlayercnt = GetBoard()->GetCopperLayerCount( ); LAYER_NUM currLayer = getActiveLayer(); if( !GetDesignSettings().m_MicroViasAllowed ) return false; // Obvious.. if( copperlayercnt < 4 ) return false; // Only on multilayer boards.. if( ( currLayer == LAYER_N_BACK ) || ( currLayer == LAYER_N_FRONT ) || ( currLayer == copperlayercnt - 2 ) || ( currLayer == LAYER_N_2 ) ) return true; return false; }
/* * Imports the board design settings to aPad * - The position, names, and keys are not modifed. * The parameters are expected to be correct (i.e. settings are valid) */ void PCB_BASE_FRAME::Import_Pad_Settings( D_PAD* aPad, bool aDraw ) { if( aDraw ) { aPad->SetFlags( DO_NOT_DRAW ); m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() ); aPad->ClearFlags( DO_NOT_DRAW ); } const D_PAD& mp = GetDesignSettings().m_Pad_Master; aPad->ImportSettingsFromMaster( mp ); if( aDraw ) m_canvas->RefreshDrawingRect( aPad->GetBoundingBox() ); aPad->GetParent()->SetLastEditTime(); OnModify(); }
void PCB_EDIT_FRAME::Begin_Self( wxDC* DC ) { if( s_inductor_pattern.m_Flag ) { m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); m_canvas->SetMouseCapture( NULL, NULL ); wxString errorMessage; // Prepare parameters for inductor // s_inductor_pattern.m_Start is already initialized, // when s_inductor_pattern.m_Flag == false s_inductor_pattern.m_Width = GetDesignSettings().GetCurrentTrackWidth(); s_inductor_pattern.m_End = GetCrossHairPosition(); MODULE* footprint = CreateMicrowaveInductor( this, errorMessage ); if( footprint ) { SetMsgPanel( footprint ); footprint->Draw( m_canvas, DC, GR_OR ); } else if( !errorMessage.IsEmpty() ) DisplayError( this, errorMessage ); return; } s_inductor_pattern.m_Start = GetCrossHairPosition(); s_inductor_pattern.m_End = s_inductor_pattern.m_Start; s_inductor_pattern.m_Flag = true; // Update the initial coordinates. GetScreen()->m_O_Curseur = GetCrossHairPosition(); UpdateStatusBar(); m_canvas->SetMouseCapture( ShowBoundingBoxMicroWaveInductor, Exit_Self ); m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); }
/* Merge all basic shapes, converted to a polygon in one polygon, * return true if OK, false in there is more than one polygon * in aMergedPolygon */ bool D_PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon ) { auto board = GetBoard(); int maxError = ARC_HIGH_DEF; if( board ) maxError = board->GetDesignSettings().m_MaxError; // if aMergedPolygon == NULL, use m_customShapeAsPolygon as target if( !aMergedPolygon ) aMergedPolygon = &m_customShapeAsPolygon; aMergedPolygon->RemoveAllContours(); // Add the anchor pad shape in aMergedPolygon, others in aux_polyset: // The anchor pad is always at 0,0 switch( GetAnchorPadShape() ) { default: case PAD_SHAPE_CIRCLE: TransformCircleToPolygon( *aMergedPolygon, wxPoint( 0, 0 ), GetSize().x / 2, maxError ); break; case PAD_SHAPE_RECT: { SHAPE_RECT rect( -GetSize().x / 2, -GetSize().y / 2, GetSize().x, GetSize().y ); aMergedPolygon->AddOutline( rect.Outline() ); break; } } if( !buildCustomPadPolygon( aMergedPolygon, maxError ) ) return false; m_boundingRadius = -1; // The current bouding radius is no more valid. return aMergedPolygon->OutlineCount() <= 1; }
MODULE* PCB_EDIT_FRAME::CreateMuWaveBaseFootprint( const wxString& aValue, int aTextSize, int aPadCount ) { MODULE* module = CreateNewModule( aValue ); if( aTextSize > 0 ) { module->Reference().SetSize( wxSize( aTextSize, aTextSize ) ); module->Reference().SetThickness( aTextSize/5 ); module->Value().SetSize( wxSize( aTextSize, aTextSize ) ); module->Value().SetThickness( aTextSize/5 ); } // Create 2 pads used in gaps and stubs. The gap is between these 2 pads // the stub is the pad 2 wxString Line; int pad_num = 1; while( aPadCount-- ) { D_PAD* pad = new D_PAD( module ); module->Pads().PushFront( pad ); int tw = GetDesignSettings().GetCurrentTrackWidth(); pad->SetSize( wxSize( tw, tw ) ); pad->SetPosition( module->GetPosition() ); pad->SetShape( PAD_SHAPE_RECT ); pad->SetAttribute( PAD_ATTRIB_SMD ); pad->SetLayerSet( F_Cu ); Line.Printf( wxT( "%d" ), pad_num ); pad->SetPadName( Line ); pad_num++; } return module; }
/* Exports the current pad settings to board design settings. */ void PCB_BASE_FRAME::Export_Pad_Settings( D_PAD* aPad ) { if( aPad == NULL ) return; SetMsgPanel( aPad ); D_PAD& mp = GetDesignSettings().m_Pad_Master; mp.SetShape( aPad->GetShape() ); mp.SetAttribute( aPad->GetAttribute() ); mp.SetLayerSet( aPad->GetLayerSet() ); mp.SetOrientation( aPad->GetOrientation() - aPad->GetParent()->GetOrientation() ); mp.SetSize( aPad->GetSize() ); mp.SetDelta( aPad->GetDelta() ); mp.SetOffset( aPad->GetOffset() ); mp.SetDrillSize( aPad->GetDrillSize() ); mp.SetDrillShape( aPad->GetDrillShape() ); }
/* * FOOTPRINT_EDIT_FRAME::Function DlgGlobalChange_PadSettings * Function to change pad caracteristics for the given footprint * or alls footprints which look like the given footprint * Options are set by the opened dialog. * aPad is the pattern. The given footprint is the parent of this pad */ void FOOTPRINT_EDIT_FRAME::DlgGlobalChange_PadSettings( D_PAD* aPad ) { int diag; if( aPad == NULL ) aPad = &GetDesignSettings().m_Pad_Master; MODULE* module = aPad->GetParent(); if( module == NULL ) { DisplayError( this, wxT( "Global_Import_Pad_Settings() Error: NULL module" ) ); return; } SetMsgPanel( module ); { DIALOG_GLOBAL_PADS_EDITION dlg( this, aPad ); dlg.m_buttonIdModules->Enable( false ); diag = dlg.ShowModal(); } if( diag == -1 ) return; bool edit_Same_Modules = false; if( diag == 1 ) edit_Same_Modules = true; GlobalChange_PadSettings( aPad, edit_Same_Modules, DIALOG_GLOBAL_PADS_EDITION::m_Pad_Shape_Filter, DIALOG_GLOBAL_PADS_EDITION::m_Pad_Orient_Filter, DIALOG_GLOBAL_PADS_EDITION::m_Pad_Layer_Filter, true, false ); }
/* Add a new graphical text to the active module (footprint) * Note there always are 2 mandatory texts: reference and value. * New texts have the member TEXTE_MODULE.GetType() set to TEXT_is_DIVERS */ TEXTE_MODULE* FOOTPRINT_EDIT_FRAME::CreateTextModule( MODULE* aModule, wxDC* aDC ) { TEXTE_MODULE* text = new TEXTE_MODULE( aModule ); text->SetFlags( IS_NEW ); GetDesignSettings().m_ModuleTextWidth = Clamp_Text_PenSize( GetDesignSettings().m_ModuleTextWidth, std::min( GetDesignSettings().m_ModuleTextSize.x, GetDesignSettings().m_ModuleTextSize.y ), true ); text->SetTextSize( GetDesignSettings().m_ModuleTextSize ); text->SetThickness( GetDesignSettings().m_ModuleTextWidth ); text->SetPosition( GetCrossHairPosition() ); if( LSET::AllTechMask().test( GetActiveLayer() ) ) // i.e. a possible layer for a text text->SetLayer( GetActiveLayer() ); InstallTextModOptionsFrame( text, NULL ); m_canvas->MoveCursorToCrossHair(); if( text->GetText().IsEmpty() ) { delete text; return NULL; } // Add the new text object to the beginning of the footprint draw list. if( aModule ) aModule->GraphicalItems().PushFront( text ); text->ClearFlags(); if( aDC ) text->Draw( m_canvas, aDC, GR_OR ); SetMsgPanel( text ); return text; }
void PCB_EDIT_FRAME::updateTraceWidthSelectBox() { if( m_SelTrackWidthBox == NULL ) return; wxString msg; bool mmFirst = g_UserUnit != INCHES; m_SelTrackWidthBox->Clear(); for( unsigned ii = 0; ii < GetDesignSettings().m_TrackWidthList.size(); ii++ ) { int size = GetDesignSettings().m_TrackWidthList[ii]; double valueMils = To_User_Unit( INCHES, size ) * 1000; double value_mm = To_User_Unit( MILLIMETRES, size ); if( mmFirst ) msg.Printf( _( "Track: %.3f mm (%.2f mils)" ), value_mm, valueMils ); else msg.Printf( _( "Track: %.2f mils (%.3f mm)" ), valueMils, value_mm ); // Mark the netclass track width value (the first in list) if( ii == 0 ) msg << wxT( " *" ); m_SelTrackWidthBox->Append( msg ); } if( GetDesignSettings().GetTrackWidthIndex() >= GetDesignSettings().m_TrackWidthList.size() ) GetDesignSettings().SetTrackWidthIndex( 0 ); m_SelTrackWidthBox->SetSelection( GetDesignSettings().GetTrackWidthIndex() ); }
void PCB_BASE_FRAME::ResetModuleTextSizes( const wxString & aFilter, bool aRef, bool aValue, bool aOthers ) { BOARD_COMMIT commit( this ); int modTextWidth = GetDesignSettings().m_ModuleTextWidth; const wxSize& modTextSize = GetDesignSettings().m_ModuleTextSize; bool modified = false; // Change fields of footprints with fpid matching the filter for( MODULE* module = GetBoard()->m_Modules; module; module = module->Next() ) { if( !aFilter.IsEmpty() ) { if( ! WildCompareString( aFilter, FROM_UTF8( module->GetFPID().Format().c_str() ), false ) ) continue; } if( aRef ) { TEXTE_MODULE* item = &module->Reference(); if( item->GetTextSize() != GetDesignSettings().m_ModuleTextSize || item->GetThickness() != GetDesignSettings().m_ModuleTextWidth ) { commit.Modify( item ); item->SetThickness( modTextWidth ); item->SetTextSize( modTextSize ); modified = true; } } if( aValue ) { TEXTE_MODULE* item = &module->Value(); if( item->GetTextSize() != GetDesignSettings().m_ModuleTextSize || item->GetThickness() != GetDesignSettings().m_ModuleTextWidth ) { commit.Modify( item ); item->SetThickness( modTextWidth ); item->SetTextSize( modTextSize ); modified = true; } } if( aOthers ) { // Go through all other module text fields for( BOARD_ITEM* boardItem = module->GraphicalItemsList(); boardItem; boardItem = boardItem->Next() ) { if( boardItem->Type() == PCB_MODULE_TEXT_T ) { TEXTE_MODULE* item = static_cast<TEXTE_MODULE*>( boardItem ); if( item->GetTextSize() != GetDesignSettings().m_ModuleTextSize || item->GetThickness() != GetDesignSettings().m_ModuleTextWidth ) { commit.Modify( item ); item->SetThickness( modTextWidth ); item->SetTextSize( modTextSize ); modified = true; } } } } } if( modified ) { commit.Push( "Reset module text size" ); GetCanvas()->Refresh(); } }
bool PCB_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotkeyCode, const wxPoint& aPosition, EDA_ITEM* aItem ) { if( aHotkeyCode == 0 ) return false; bool itemCurrentlyEdited = GetCurItem() && GetCurItem()->GetFlags(); MODULE* module = NULL; int evt_type = 0; //Used to post a wxCommandEvent on demand PCB_SCREEN* screen = GetScreen(); auto displ_opts = (PCB_DISPLAY_OPTIONS*)GetDisplayOptions(); /* Convert lower to upper case * (the usual toupper function has problem with non ascii codes like function keys */ if( (aHotkeyCode >= 'a') && (aHotkeyCode <= 'z') ) aHotkeyCode += 'A' - 'a'; EDA_HOTKEY* HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, common_Hotkey_List ); if( HK_Descr == NULL ) HK_Descr = GetDescriptorFromHotkey( aHotkeyCode, board_edit_Hotkey_List ); if( HK_Descr == NULL ) return false; int hk_id = HK_Descr->m_Idcommand; // Create a wxCommandEvent that will be posted in some hot keys functions wxCommandEvent cmd( wxEVT_COMMAND_MENU_SELECTED ); cmd.SetEventObject( this ); LAYER_NUM ll; switch( hk_id ) { default: case HK_NOT_FOUND: return false; case HK_LEFT_CLICK: OnLeftClick( aDC, aPosition ); break; case HK_LEFT_DCLICK: // Simulate a double left click: generate 2 events OnLeftClick( aDC, aPosition ); OnLeftDClick( aDC, aPosition ); break; case HK_SWITCH_TRACK_WIDTH_TO_NEXT: if( GetCanvas()->IsMouseCaptured() ) GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false ); if( GetDesignSettings().GetTrackWidthIndex() < GetDesignSettings().m_TrackWidthList.size() - 1 ) GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().GetTrackWidthIndex() + 1 ); else GetDesignSettings().SetTrackWidthIndex( 0 ); if( GetCanvas()->IsMouseCaptured() ) GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false ); break; case HK_SWITCH_TRACK_WIDTH_TO_PREVIOUS: if( GetCanvas()->IsMouseCaptured() ) GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false ); if( GetDesignSettings().GetTrackWidthIndex() <= 0 ) GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().m_TrackWidthList.size() -1 ); else GetDesignSettings().SetTrackWidthIndex( GetDesignSettings().GetTrackWidthIndex() - 1 ); if( GetCanvas()->IsMouseCaptured() ) GetCanvas()->CallMouseCapture( aDC, wxDefaultPosition, false ); break; case HK_SWITCH_GRID_TO_FASTGRID1: SetFastGrid1(); break; case HK_SWITCH_GRID_TO_FASTGRID2: SetFastGrid2(); break; case HK_SWITCH_GRID_TO_NEXT: evt_type = ID_POPUP_GRID_NEXT; break; case HK_SWITCH_GRID_TO_PREVIOUS: evt_type = ID_POPUP_GRID_PREV; break; case HK_SWITCH_LAYER_TO_PREVIOUS: ll = GetActiveLayer(); if( !IsCopperLayer( ll ) ) break; if( ll == F_Cu ) ll = B_Cu; else if( ll == B_Cu ) ll = ToLAYER_ID( GetBoard()->GetCopperLayerCount() - 2 ); else ll = ll - 1; SwitchLayer( aDC, ToLAYER_ID( ll ) ); break; case HK_SWITCH_LAYER_TO_NEXT: ll = GetActiveLayer(); if( !IsCopperLayer( ll ) ) break; if( ll == B_Cu ) ll = F_Cu; else if( ++ll >= GetBoard()->GetCopperLayerCount() - 1 ) ll = B_Cu; SwitchLayer( aDC, ToLAYER_ID( ll ) ); break; case HK_SWITCH_LAYER_TO_COMPONENT: SwitchLayer( aDC, F_Cu ); break; case HK_SWITCH_LAYER_TO_COPPER: SwitchLayer( aDC, B_Cu ); break; case HK_SWITCH_LAYER_TO_INNER1: SwitchLayer( aDC, In1_Cu ); break; case HK_SWITCH_LAYER_TO_INNER2: SwitchLayer( aDC, In2_Cu ); break; case HK_SWITCH_LAYER_TO_INNER3: SwitchLayer( aDC, In3_Cu ); break; case HK_SWITCH_LAYER_TO_INNER4: SwitchLayer( aDC, In4_Cu ); break; case HK_SWITCH_LAYER_TO_INNER5: SwitchLayer( aDC, In5_Cu ); break; case HK_SWITCH_LAYER_TO_INNER6: SwitchLayer( aDC, In6_Cu ); break; case HK_HELP: // Display Current hotkey list DisplayHotkeyList( this, g_Board_Editor_Hotkeys_Descr ); break; case HK_PREFERENCES: evt_type = wxID_PREFERENCES; break; case HK_ZOOM_IN: evt_type = ID_KEY_ZOOM_IN; break; case HK_ZOOM_OUT: evt_type = ID_KEY_ZOOM_OUT; break; case HK_ZOOM_REDRAW: evt_type = ID_ZOOM_REDRAW; break; case HK_ZOOM_AUTO: evt_type = ID_ZOOM_PAGE; break; case HK_ZOOM_CENTER: evt_type = ID_POPUP_ZOOM_CENTER; break; case HK_ZOOM_SELECTION: evt_type = ID_ZOOM_SELECTION; break; case HK_ADD_MODULE: evt_type = ID_PCB_MODULE_BUTT; break; case HK_UNDO: case HK_REDO: if( !itemCurrentlyEdited ) { wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, HK_Descr->m_IdMenuEvent ); wxPostEvent( this, event ); } break; case HK_RESET_LOCAL_COORD: // Set the relative coord GetScreen()->m_O_Curseur = GetCrossHairPosition(); break; case HK_SET_GRID_ORIGIN: PCBNEW_CONTROL::SetGridOrigin( GetGalCanvas()->GetView(), this, new KIGFX::ORIGIN_VIEWITEM( GetGridOrigin(), UR_TRANSIENT ), GetCrossHairPosition() ); m_canvas->Refresh(); break; case HK_RESET_GRID_ORIGIN: PCBNEW_CONTROL::SetGridOrigin( GetGalCanvas()->GetView(), this, new KIGFX::ORIGIN_VIEWITEM( GetGridOrigin(), UR_TRANSIENT ), wxPoint( 0, 0 ) ); m_canvas->Refresh(); break; case HK_SWITCH_UNITS: evt_type = (GetUserUnits() == INCHES) ? ID_TB_OPTIONS_SELECT_UNIT_MM : ID_TB_OPTIONS_SELECT_UNIT_INCH; break; case HK_SWITCH_TRACK_DISPLAY_MODE: displ_opts->m_DisplayPcbTrackFill = !displ_opts->m_DisplayPcbTrackFill; m_canvas->Refresh(); break; case HK_DELETE: OnHotkeyDeleteItem( aDC ); break; case HK_BACK_SPACE: if( IsCopperLayer( GetActiveLayer() ) ) { if( !itemCurrentlyEdited ) { // no track is currently being edited - select a segment and remove it. // @todo: possibly? pass the HK command code to PcbGeneralLocateAndDisplay() // so it can restrict its search to specific item types. BOARD_ITEM * item = PcbGeneralLocateAndDisplay(); // don't let backspace delete modules!! if( item && item->IsTrack() ) { Delete_Segment( aDC, (TRACK*) item ); SetCurItem( NULL ); } OnModify(); } else if( GetCurItem()->IsTrack() ) { // then an element is being edited - remove the last segment. // simple lines for debugger: TRACK* track = (TRACK*) GetCurItem(); track = Delete_Segment( aDC, track ); SetCurItem( track ); OnModify(); } } break; case HK_GET_AND_MOVE_FOOTPRINT: if( !itemCurrentlyEdited ) evt_type = ID_POPUP_PCB_GET_AND_MOVE_MODULE_REQUEST; break; case HK_FIND_ITEM: if( !itemCurrentlyEdited ) evt_type = ID_FIND_ITEMS; break; case HK_OPEN: if( !itemCurrentlyEdited ) evt_type = ID_LOAD_FILE ; break; case HK_SAVE: if( !itemCurrentlyEdited ) evt_type = ID_SAVE_BOARD; break; case HK_ADD_MICROVIA: // Place a micro via if a track is in progress if( GetToolId() != ID_TRACK_BUTT ) return true; if( !itemCurrentlyEdited ) // no track in progress: nothing to do break; if( GetCurItem()->Type() != PCB_TRACE_T ) // Should not occur return true; if( !GetCurItem()->IsNew() ) return true; // place micro via and switch layer if( IsMicroViaAcceptable() ) evt_type = ID_POPUP_PCB_PLACE_MICROVIA; break; case HK_ADD_BLIND_BURIED_VIA: case HK_ADD_THROUGH_VIA: // Switch to alternate layer and Place a via if a track is in progress if( GetBoard()->GetDesignSettings().m_BlindBuriedViaAllowed && hk_id == HK_ADD_BLIND_BURIED_VIA ) GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_BLIND_BURIED; else GetBoard()->GetDesignSettings().m_CurrentViaType = VIA_THROUGH; if( !itemCurrentlyEdited ) // no track in progress: switch layer only { Other_Layer_Route( NULL, aDC ); if( displ_opts->m_ContrastModeDisplay ) m_canvas->Refresh(); break; } if( GetToolId() != ID_TRACK_BUTT ) return true; if( GetCurItem()->Type() != PCB_TRACE_T ) return true; if( !GetCurItem()->IsNew() ) return true; evt_type = hk_id == HK_ADD_BLIND_BURIED_VIA ? ID_POPUP_PCB_PLACE_BLIND_BURIED_VIA : ID_POPUP_PCB_PLACE_THROUGH_VIA; break; case HK_SEL_LAYER_AND_ADD_THROUGH_VIA: case HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA: if( GetCurItem() == NULL || !GetCurItem()->IsNew() || GetCurItem()->Type() != PCB_TRACE_T ) break; evt_type = hk_id == HK_SEL_LAYER_AND_ADD_BLIND_BURIED_VIA ? ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA : ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_THROUGH_VIA; break; case HK_SWITCH_TRACK_POSTURE: /* change the position of initial segment when creating new tracks * switch from _/ to -\ . */ evt_type = ID_POPUP_PCB_SWITCH_TRACK_POSTURE ; break; case HK_DRAG_TRACK_KEEP_SLOPE: OnHotkeyMoveItem( HK_DRAG_TRACK_KEEP_SLOPE ); break; case HK_PLACE_ITEM: OnHotkeyPlaceItem( aDC ); break; case HK_ADD_NEW_TRACK: // Start new track, if possible OnHotkeyBeginRoute( aDC ); break; case HK_EDIT_ITEM: // Edit board item OnHotkeyEditItem( HK_EDIT_ITEM ); break; case HK_EDIT_MODULE_WITH_MODEDIT: // Edit module with module editor OnHotkeyEditItem( HK_EDIT_MODULE_WITH_MODEDIT ); break; case HK_LOCK_UNLOCK_FOOTPRINT: // toggle module "MODULE_is_LOCKED" status: // get any module, locked or not locked and toggle its locked status if( !itemCurrentlyEdited ) { wxPoint pos = RefPos( true ); module = GetBoard()->GetFootprint( pos, screen->m_Active_Layer, true ); } else if( GetCurItem()->Type() == PCB_MODULE_T ) { module = (MODULE*) GetCurItem(); } if( module ) { SetCurItem( module ); module->SetLocked( !module->IsLocked() ); OnModify(); SetMsgPanel( module ); } break; case HK_DRAG_ITEM: // Start drag module or track segment OnHotkeyMoveItem( HK_DRAG_ITEM ); break; case HK_MOVE_ITEM: // Start move item OnHotkeyMoveItem( HK_MOVE_ITEM ); break; case HK_COPY_ITEM: evt_type = OnHotkeyCopyItem(); break; case HK_ROTATE_ITEM: // Rotation OnHotkeyRotateItem( HK_ROTATE_ITEM ); break; case HK_FLIP_ITEM: OnHotkeyFlipItem( HK_FLIP_ITEM ); break; case HK_MOVE_ITEM_EXACT: case HK_DUPLICATE_ITEM: case HK_DUPLICATE_ITEM_AND_INCREMENT: case HK_CREATE_ARRAY: OnHotkeyDuplicateOrArrayItem( HK_Descr->m_Idcommand ); break; case HK_SWITCH_HIGHCONTRAST_MODE: // switch to high contrast mode and refresh the canvas displ_opts->m_ContrastModeDisplay = !displ_opts->m_ContrastModeDisplay; m_canvas->Refresh(); break; case HK_CANVAS_CAIRO: evt_type = ID_MENU_CANVAS_CAIRO; break; case HK_CANVAS_OPENGL: evt_type = ID_MENU_CANVAS_OPENGL; break; case HK_CANVAS_LEGACY: evt_type = ID_MENU_CANVAS_LEGACY; break; case HK_ZONE_FILL_OR_REFILL: evt_type = ID_POPUP_PCB_FILL_ALL_ZONES; break; case HK_ZONE_REMOVE_FILLED: evt_type = ID_POPUP_PCB_REMOVE_FILLED_AREAS_IN_ALL_ZONES; break; } if( evt_type != 0 ) { wxCommandEvent evt( wxEVT_COMMAND_MENU_SELECTED ); evt.SetEventObject( this ); evt.SetId( evt_type ); GetEventHandler()->ProcessEvent( evt ); } return true; }
/** * Function SetTrackSegmentWidth * Modify one track segment width or one via diameter and drill (using DRC control). * Basic routine used by other routines when editing tracks or vias * @param aTrackItem = the track segment or via to modify * @param aItemsListPicker = the list picker to use for an undo command (can be NULL) * @param aUseNetclassValue = true to use NetClass value, false to use BOARD::m_designSettings value * @return true if done, false if no not change (because DRC error) */ bool PCB_EDIT_FRAME::SetTrackSegmentWidth( TRACK* aTrackItem, PICKED_ITEMS_LIST* aItemsListPicker, bool aUseNetclassValue ) { int initial_width, new_width; int initial_drill = -1,new_drill = -1; bool change_ok = false; NETINFO_ITEM* net = NULL; if( aUseNetclassValue ) net = aTrackItem->GetNet(); initial_width = aTrackItem->GetWidth(); if( net ) new_width = net->GetTrackWidth(); else new_width = GetDesignSettings().GetCurrentTrackWidth(); if( aTrackItem->Type() == PCB_VIA_T ) { const VIA *via = static_cast<const VIA *>( aTrackItem ); if( !via->IsDrillDefault() ) initial_drill = via->GetDrillValue(); if( net ) { new_width = net->GetViaSize(); } else { new_width = GetDesignSettings().GetCurrentViaSize(); new_drill = GetDesignSettings().GetCurrentViaDrill(); } if( via->GetViaType() == VIA_MICROVIA ) { if( net ) new_width = net->GetMicroViaSize(); else new_width = GetDesignSettings().GetCurrentMicroViaSize(); } } aTrackItem->SetWidth( new_width ); // make a DRC test because the new size is bigger than the old size if( initial_width < new_width ) { int diagdrc = OK_DRC; if( g_Drc_On ) diagdrc = m_drc->Drc( aTrackItem, GetBoard()->m_Track ); if( diagdrc == OK_DRC ) change_ok = true; } else if( initial_width > new_width ) { change_ok = true; } else if( (aTrackItem->Type() == PCB_VIA_T) && (initial_drill != new_drill) ) { // if new width == initial_width: do nothing, unless a via has its drill value changed change_ok = true; } if( change_ok ) { OnModify(); if( aItemsListPicker ) { aTrackItem->SetWidth( initial_width ); ITEM_PICKER picker( aTrackItem, UR_CHANGED ); picker.SetLink( aTrackItem->Clone() ); aItemsListPicker->PushItem( picker ); aTrackItem->SetWidth( new_width ); if( aTrackItem->Type() == PCB_VIA_T ) { // Set new drill value. Note: currently microvias have only a default drill value VIA *via = static_cast<VIA *>( aTrackItem ); if( new_drill > 0 ) via->SetDrill( new_drill ); else via->SetDrillDefault(); } } } else { aTrackItem->SetWidth( initial_width ); } return change_ok; }