static void Move_Segment(WinEDA_DrawPanel * panel, wxDC * DC, bool erase) /************************************************************************/ /* redessin du contour du Segment Edge lors des deplacements de la souris */ { BASE_SCREEN * screen = panel->GetScreen(); EDGE_MODULE * Edge = (EDGE_MODULE * ) screen->m_CurrentItem; if( Edge == NULL ) return; MODULE * Module = (MODULE*) Edge->m_Parent; screen->Trace_Curseur(panel, DC); if( erase ) { Edge->Draw(panel, DC, MoveVector, GR_XOR); } MoveVector.x = -(screen->m_Curseur.x - CursorInitialPosition.x); MoveVector.y = -(screen->m_Curseur.y - CursorInitialPosition.y); Edge->Draw(panel, DC, MoveVector, GR_XOR); screen->Trace_Curseur(panel, DC); Module->Set_Rectangle_Encadrement(); }
static void Exit_EditEdge_Module(WinEDA_DrawFrame * frame, wxDC * DC) /******************************************************************/ { EDGE_MODULE * Edge = (EDGE_MODULE * ) frame->GetScreen()->m_CurrentItem; if( Edge && (Edge->m_StructType == TYPEEDGEMODULE) ) /* error si non */ { if (Edge->m_Flags & IS_NEW) /* effacement du nouveau contour */ { MODULE * Module = (MODULE *) Edge->m_Parent; Edge->Draw(frame->DrawPanel, DC, MoveVector, GR_XOR); DeleteStructure(Edge); Module->Set_Rectangle_Encadrement(); } else { Edge->Draw(frame->DrawPanel, DC, MoveVector, GR_XOR); Edge->m_Flags = 0; Edge->Draw(frame->DrawPanel, DC, wxPoint(0, 0), GR_OR); } } frame->GetScreen()->ManageCurseur = NULL; frame->GetScreen()->ForceCloseManageCurseur = NULL; frame->GetScreen()->m_CurrentItem = NULL; }
static void ShowEdgeModule(WinEDA_DrawPanel * panel, wxDC * DC, bool erase) /************************************************************************/ /* Affiche le segment Edge Module en cours de trace */ { BASE_SCREEN * screen = panel->GetScreen(); EDGE_MODULE * Edge = (EDGE_MODULE * ) screen->m_CurrentItem; if( Edge == NULL ) return; MODULE * Module = (MODULE*) Edge->m_Parent; screen->Trace_Curseur(panel, DC); // if( erase ) { Edge->Draw(panel, DC, wxPoint(0, 0), GR_XOR); } Edge->m_End = screen->m_Curseur; /* Mise a jour des coord relatives */ Edge->m_End0.x = Edge->m_End.x - Module->m_Pos.x; Edge->m_End0.y = Edge->m_End.y - Module->m_Pos.y ; RotatePoint((int*)&Edge->m_End0.x, (int*)&Edge->m_End0.y, - Module->m_Orient); Edge->Draw(panel, DC, wxPoint(0, 0), GR_XOR); screen->Trace_Curseur(panel, DC); Module->Set_Rectangle_Encadrement(); }
void MODULE::MoveAnchorPosition( const wxPoint& aMoveVector ) { /* Move the reference point of the footprint * the footprints elements (pads, outlines, edges .. ) are moved * but: * - the footprint position is not modified. * - the relative (local) coordinates of these items are modified */ wxPoint footprintPos = GetPosition(); /* Update the relative coordinates: * The coordinates are relative to the anchor point. * Calculate deltaX and deltaY from the anchor. */ wxPoint moveVector = aMoveVector; RotatePoint( &moveVector, -GetOrientation() ); // Update of the reference and value. m_Reference->SetPos0( m_Reference->GetPos0() + moveVector ); m_Reference->SetDrawCoord(); m_Value->SetPos0( m_Value->GetPos0() + moveVector ); m_Value->SetDrawCoord(); // Update the pad local coordinates. for( D_PAD* pad = Pads(); pad; pad = pad->Next() ) { pad->SetPos0( pad->GetPos0() + moveVector ); pad->SetPosition( pad->GetPos0() + footprintPos ); } // Update the draw element coordinates. for( EDA_ITEM* item = GraphicalItems(); item; item = item->Next() ) { switch( item->Type() ) { case PCB_MODULE_EDGE_T: { EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item ); edge->m_Start0 += moveVector; edge->m_End0 += moveVector; edge->SetDrawCoord(); break; } case PCB_MODULE_TEXT_T: { TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item ); text->SetPos0( text->GetPos0() + moveVector ); text->SetDrawCoord(); break; } default: break; } } CalculateBoundingBox(); }
int DRAWING_TOOL::DrawLine( const TOOL_EVENT& aEvent ) { boost::optional<VECTOR2D> startingPoint; if( m_editModules ) { m_frame->SetToolID( ID_MODEDIT_LINE_TOOL, wxCURSOR_PENCIL, _( "Add graphic line" ) ); EDGE_MODULE* line = new EDGE_MODULE( m_board->m_Modules ); while( drawSegment( S_SEGMENT, reinterpret_cast<DRAWSEGMENT*&>( line ), startingPoint ) ) { if( line ) { m_frame->OnModify(); m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT ); line->SetParent( m_board->m_Modules ); line->SetLocalCoord(); m_board->m_Modules->GraphicalItems().PushFront( line ); startingPoint = line->GetEnd(); } else { startingPoint = boost::none; } line = new EDGE_MODULE( m_board->m_Modules ); } } else // !m_editModules case { m_frame->SetToolID( ID_PCB_ADD_LINE_BUTT, wxCURSOR_PENCIL, _( "Add graphic line" ) ); DRAWSEGMENT* line = new DRAWSEGMENT; while( drawSegment( S_SEGMENT, line, startingPoint ) ) { if( line ) { m_board->Add( line ); m_frame->OnModify(); m_frame->SaveCopyInUndoList( line, UR_NEW ); startingPoint = line->GetEnd(); } else { startingPoint = boost::none; } line = new DRAWSEGMENT; } } m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; }
/* Redraw the current graphic item during its creation * Use this function to show a new outline, in begin command */ static void ShowNewEdgeModule( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase ) { BASE_SCREEN* screen = aPanel->GetScreen(); EDGE_MODULE* edge = (EDGE_MODULE*) screen->GetCurItem(); if( edge == NULL ) return; MODULE* module = (MODULE*) edge->GetParent(); // if( erase ) { edge->Draw( aPanel, aDC, GR_XOR ); } edge->SetEnd( aPanel->GetParent()->GetCrossHairPosition() ); // Update relative coordinate. edge->SetEnd0( edge->GetEnd() - module->GetPosition() ); wxPoint pt( edge->GetEnd0() ); RotatePoint( &pt, -module->GetOrientation() ); edge->SetEnd0( pt ); edge->Draw( aPanel, aDC, GR_XOR ); module->CalculateBoundingBox(); }
/* abort function in moving outline. */ static void Abort_Move_ModuleOutline( EDA_DRAW_PANEL* Panel, wxDC* DC ) { EDGE_MODULE* edge = (EDGE_MODULE*) Panel->GetScreen()->GetCurItem(); Panel->SetMouseCapture( NULL, NULL ); if( edge && ( edge->Type() == PCB_MODULE_EDGE_T ) ) { if( edge->IsNew() ) // On aborting, delete new outline. { MODULE* module = (MODULE*) edge->GetParent(); edge->Draw( Panel, DC, GR_XOR, MoveVector ); edge->DeleteStructure(); module->CalculateBoundingBox(); } else // On aborting, move existing outline to its initial position. { edge->Draw( Panel, DC, GR_XOR, MoveVector ); edge->ClearFlags(); edge->Draw( Panel, DC, GR_OR ); } } Panel->GetScreen()->SetCurItem( NULL ); }
void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::OnOkClick( wxCommandEvent& event ) /*******************************************************************/ /* Copy values in text control to the item parameters */ { LAYER_NUM layer = m_LayerSelectionCtrl->GetLayerSelection(); if( IsCopperLayer( layer ) ) { /* an edge is put on a copper layer: this it is very dangerous. a * confirmation is requested */ if( !IsOK( NULL, _( "The graphic item will be on a copper layer. This is very dangerous. Are you sure?" ) ) ) return; } m_parent->SaveCopyInUndoList( m_module, UR_MODEDIT ); m_module->SetLastEditTime(); wxString msg; wxPoint coord; msg = m_Center_StartXCtrl->GetValue(); coord.x = ValueFromString( g_UserUnit, msg ); msg = m_Center_StartYCtrl->GetValue(); coord.y = ValueFromString( g_UserUnit, msg ); m_item->SetStart( coord ); m_item->SetStart0( coord ); msg = m_EndX_Radius_Ctrl->GetValue(); coord.x = ValueFromString( g_UserUnit, msg ); msg = m_EndY_Ctrl->GetValue(); coord.y = ValueFromString( g_UserUnit, msg ); m_item->SetEnd( coord ); m_item->SetEnd0( coord ); msg = m_ThicknessCtrl->GetValue(); m_item->SetWidth( ValueFromString( g_UserUnit, msg ) ); msg = m_DefaultThicknessCtrl->GetValue(); int thickness = ValueFromString( g_UserUnit, msg ); m_brdSettings.m_ModuleSegmentWidth = thickness; m_parent->SetDesignSettings( m_brdSettings ); m_item->SetLayer( layer ); if( m_item->GetShape() == S_ARC ) { double angle; m_Angle_Ctrl->GetValue().ToDouble( &angle ); NORMALIZE_ANGLE_360(angle); m_item->SetAngle( angle ); } m_parent->OnModify(); m_parent->SetMsgPanel( m_item ); Close( true ); }
/* Move marked items, at new position = old position + offset */ void MoveMarkedItems( MODULE* module, wxPoint offset ) { EDA_ITEM* item; if( module == NULL ) return; if( module->Reference().IsSelected() ) module->Reference().Move( offset ); if( module->Value().IsSelected() ) module->Value().Move( offset ); D_PAD* pad = module->Pads(); for( ; pad != NULL; pad = pad->Next() ) { if( !pad->IsSelected() ) continue; pad->SetPosition( pad->GetPosition() + offset ); pad->SetPos0( pad->GetPos0() + offset ); } item = module->GraphicalItems(); for( ; item != NULL; item = item->Next() ) { if( !item->IsSelected() ) continue; switch( item->Type() ) { case PCB_MODULE_TEXT_T: static_cast<TEXTE_MODULE*>( item )->Move( offset ); break; case PCB_MODULE_EDGE_T: { EDGE_MODULE* em = (EDGE_MODULE*) item; em->SetStart( em->GetStart() + offset ); em->SetEnd( em->GetEnd() + offset ); em->SetStart0( em->GetStart0() + offset ); em->SetEnd0( em->GetEnd0() + offset ); } break; default: ; } } ClearMarkItems( module ); }
// Plot footprints graphic items (outlines) void BRDITEMS_PLOTTER::Plot_Edges_Modules() { for( MODULE* module = m_board->m_Modules; module; module = module->Next() ) { for( BOARD_ITEM* item = module->GraphicalItems().GetFirst(); item; item = item->Next() ) { EDGE_MODULE* edge = dyn_cast<EDGE_MODULE*>( item ); if( !edge || !m_layerMask[edge->GetLayer()] ) continue; Plot_1_EdgeModule( edge ); } } }
bool DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::TransferDataFromWindow() { if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataFromWindow() ) return false; LAYER_NUM layer = m_LayerSelectionCtrl->GetLayerSelection(); if( IsCopperLayer( layer ) ) { /* an edge is put on a copper layer: this it is very dangerous. a * confirmation is requested */ if( !IsOK( NULL, _( "The graphic item will be on a copper layer. This is very dangerous. Are you sure?" ) ) ) return false;; } m_parent->SaveCopyInUndoList( m_module, UR_MODEDIT ); m_module->SetLastEditTime(); wxString msg; wxPoint coord; msg = m_Center_StartXCtrl->GetValue(); coord.x = ValueFromString( g_UserUnit, msg ); msg = m_Center_StartYCtrl->GetValue(); coord.y = ValueFromString( g_UserUnit, msg ); m_item->SetStart( coord ); m_item->SetStart0( coord ); msg = m_EndX_Radius_Ctrl->GetValue(); coord.x = ValueFromString( g_UserUnit, msg ); msg = m_EndY_Ctrl->GetValue(); coord.y = ValueFromString( g_UserUnit, msg ); m_item->SetEnd( coord ); m_item->SetEnd0( coord ); msg = m_ThicknessCtrl->GetValue(); m_item->SetWidth( ValueFromString( g_UserUnit, msg ) ); msg = m_DefaultThicknessCtrl->GetValue(); int thickness = ValueFromString( g_UserUnit, msg ); m_brdSettings.m_ModuleSegmentWidth = thickness; m_parent->SetDesignSettings( m_brdSettings ); m_item->SetLayer( ToLAYER_ID( layer ) ); if( m_item->GetShape() == S_ARC ) { m_item->SetAngle( m_AngleValue * 10.0 ); } m_parent->OnModify(); m_parent->SetMsgPanel( m_item ); return true; }
/* Move marked items, at new position = old position + offset */ void MoveMarkedItems( MODULE* module, wxPoint offset ) { EDA_ITEM* item; if( module == NULL ) return; D_PAD* pad = module->Pads(); for( ; pad != NULL; pad = pad->Next() ) { if( !pad->IsSelected() ) continue; pad->SetPosition( pad->GetPosition() + offset ); pad->SetPos0( pad->GetPos0() + offset ); } item = module->GraphicalItems(); for( ; item != NULL; item = item->Next() ) { if( !item->IsSelected() ) continue; switch( item->Type() ) { case PCB_MODULE_TEXT_T: { TEXTE_MODULE* tm = (TEXTE_MODULE*) item; tm->Offset( offset ); tm->SetPos0( tm->GetPos0() + offset ); } break; case PCB_MODULE_EDGE_T: { EDGE_MODULE* em = (EDGE_MODULE*) item; em->SetStart( em->GetStart() + offset ); em->SetEnd( em->GetEnd() + offset ); em->SetStart0( em->GetStart0() + offset ); em->SetEnd0( em->GetEnd0() + offset ); } break; default: ; } item->ClearFlags(); } }
int DRAWING_TOOL::DrawCircle( const TOOL_EVENT& aEvent ) { if( m_editModules ) { m_frame->SetToolID( ID_MODEDIT_CIRCLE_TOOL, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); EDGE_MODULE* circle = new EDGE_MODULE( m_board->m_Modules ); while( drawSegment( S_CIRCLE, reinterpret_cast<DRAWSEGMENT*&>( circle ) ) ) { if( circle ) { m_frame->OnModify(); m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT ); circle->SetParent( m_board->m_Modules ); circle->SetLocalCoord(); m_board->m_Modules->GraphicalItems().PushFront( circle ); } circle = new EDGE_MODULE( m_board->m_Modules ); } } else // !m_editModules case { m_frame->SetToolID( ID_PCB_CIRCLE_BUTT, wxCURSOR_PENCIL, _( "Add graphic circle" ) ); DRAWSEGMENT* circle = new DRAWSEGMENT; while( drawSegment( S_CIRCLE, circle ) ) { if( circle ) { m_board->Add( circle ); m_frame->OnModify(); m_frame->SaveCopyInUndoList( circle, UR_NEW ); } circle = new DRAWSEGMENT; } } m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; }
int DRAWING_TOOL::DrawArc( const TOOL_EVENT& aEvent ) { if( m_editModules ) { m_frame->SetToolID( ID_MODEDIT_ARC_TOOL, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); EDGE_MODULE* arc = new EDGE_MODULE( m_board->m_Modules ); while( drawArc( reinterpret_cast<DRAWSEGMENT*&>( arc ) ) ) { if( arc ) { m_frame->OnModify(); m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT ); arc->SetParent( m_board->m_Modules ); arc->SetLocalCoord(); m_board->m_Modules->GraphicalItems().PushFront( arc ); } arc = new EDGE_MODULE( m_board->m_Modules ); } } else // !m_editModules case { m_frame->SetToolID( ID_PCB_ARC_BUTT, wxCURSOR_PENCIL, _( "Add graphic arc" ) ); DRAWSEGMENT* arc = new DRAWSEGMENT; while( drawArc( arc ) ) { if( arc ) { m_board->Add( arc ); m_frame->OnModify(); m_frame->SaveCopyInUndoList( arc, UR_NEW ); } arc = new DRAWSEGMENT; } } m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString ); return 0; }
void MODULE::SetOrientation( double newangle ) { double angleChange = newangle - m_Orient; // change in rotation wxPoint pt; NORMALIZE_ANGLE_POS( newangle ); m_Orient = newangle; for( D_PAD* pad = m_Pads; pad; pad = pad->Next() ) { pt = pad->GetPos0(); pad->SetOrientation( pad->GetOrientation() + angleChange ); RotatePoint( &pt, m_Orient ); pad->SetPosition( GetPosition() + pt ); } // Update of the reference and value. m_Reference->SetDrawCoord(); m_Value->SetDrawCoord(); // Displace contours and text of the footprint. for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() ) { if( item->Type() == PCB_MODULE_EDGE_T ) { EDGE_MODULE* edge = (EDGE_MODULE*) item; edge->SetDrawCoord(); } else if( item->Type() == PCB_MODULE_TEXT_T ) { TEXTE_MODULE* text = (TEXTE_MODULE*) item; text->SetDrawCoord(); } } CalculateBoundingBox(); }
/* Redraw the current moved graphic item when mouse is moving * Use this function to show an existing outline, in move command */ static void ShowCurrentOutlineWhileMoving( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition, bool aErase ) { BASE_SCREEN* screen = aPanel->GetScreen(); EDGE_MODULE* edge = (EDGE_MODULE*) screen->GetCurItem(); if( edge == NULL ) return; MODULE* module = (MODULE*) edge->GetParent(); if( aErase ) { edge->Draw( aPanel, aDC, GR_XOR, MoveVector ); } MoveVector = -(aPanel->GetParent()->GetCrossHairPosition() - CursorInitialPosition); edge->Draw( aPanel, aDC, GR_XOR, MoveVector ); module->CalculateBoundingBox(); }
void PCB_POLYGON::AddToModule( MODULE* aModule ) { if( IsNonCopperLayer( m_KiCadLayer ) ) { EDGE_MODULE* dwg = new EDGE_MODULE( aModule, S_POLYGON ); aModule->GraphicalItemsList().PushBack( dwg ); dwg->SetWidth( 0 ); dwg->SetLayer( m_KiCadLayer ); auto outline = new std::vector<wxPoint>; for( auto point : m_outline ) outline->push_back( wxPoint( point->x, point->y ) ); dwg->SetPolyPoints( *outline ); dwg->SetStart0( *outline->begin() ); dwg->SetEnd0( outline->back() ); dwg->SetDrawCoord(); delete( outline ); } }
/** Rotate marked items, refer to a rotation point at position offset * Note: because this function is used in global transform, * if force_all is true, all items will be rotated */ void RotateMarkedItems( MODULE* module, wxPoint offset, bool force_all ) { #define ROTATE( z ) RotatePoint( (&z), offset, 900 ) if( module == NULL ) return; for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { if( !pad->IsSelected() && !force_all ) continue; wxPoint pos = pad->GetPosition(); ROTATE( pos ); pad->SetPosition( pos ); pad->SetPos0( pad->GetPosition() ); pad->SetOrientation( pad->GetOrientation() + 900 ); } for( EDA_ITEM* item = module->GraphicalItems(); item; item = item->Next() ) { if( !item->IsSelected() && !force_all) continue; switch( item->Type() ) { case PCB_MODULE_EDGE_T: { EDGE_MODULE* em = (EDGE_MODULE*) item; wxPoint tmp = em->GetStart(); ROTATE( tmp ); em->SetStart( tmp ); em->SetStart0( tmp ); tmp = em->GetEnd(); ROTATE( tmp ); em->SetEnd( tmp ); em->SetEnd0( tmp ); } break; case PCB_MODULE_TEXT_T: { TEXTE_MODULE* tm = (TEXTE_MODULE*) item; wxPoint pos = tm->GetTextPosition(); ROTATE( pos ); tm->SetTextPosition( pos ); tm->SetPos0( tm->GetTextPosition() ); tm->SetOrientation( tm->GetOrientation() + 900 ); } break; default: ; } item->ClearFlags(); } }
MODULE* MWAVE::CreateMicrowaveInductor( INDUCTOR_PATTERN& inductorPattern, PCB_EDIT_FRAME* aPcbFrame, wxString& aErrorMessage ) { /* Build a microwave inductor footprint. * - Length Mself.lng * - Extremities Mself.m_Start and Mself.m_End * We must determine: * Mself.nbrin = number of segments perpendicular to the direction * (The coil nbrin will demicercles + 1 + 2 1 / 4 circle) * Mself.lbrin = length of a strand * Mself.radius = radius of rounded parts of the coil * Mself.delta = segments extremities connection between him and the coil even * * The equations are * Mself.m_Size.x = 2 * Mself.radius + Mself.lbrin * Mself.m_Size.y * Mself.delta = 2 + 2 * Mself.nbrin * Mself.radius * Mself.lng = 2 * Mself.delta / / connections to the coil + (Mself.nbrin-2) * Mself.lbrin / / length of the strands except 1st and last + (Mself.nbrin 1) * (PI * Mself.radius) / / length of rounded * Mself.lbrin + / 2 - Melf.radius * 2) / / length of 1st and last bit * * The constraints are: * Nbrin >= 2 * Mself.radius < Mself.m_Size.x * Mself.m_Size.y = Mself.radius * 4 + 2 * Mself.raccord * Mself.lbrin> Mself.radius * 2 * * The calculation is conducted in the following way: * Initially: * Nbrin = 2 * Radius = 4 * m_Size.x (arbitrarily fixed value) * Then: * Increasing the number of segments to the desired length * (Radius decreases if necessary) */ D_PAD* pad; int ll; wxString msg; auto pt = inductorPattern.m_End - inductorPattern.m_Start; int min_len = KiROUND( EuclideanNorm( pt ) ); inductorPattern.m_length = min_len; // Enter the desired length. msg = StringFromValue( g_UserUnit, inductorPattern.m_length ); wxTextEntryDialog dlg( nullptr, wxEmptyString, _( "Length of Trace:" ), msg ); if( dlg.ShowModal() != wxID_OK ) return nullptr; // canceled by user msg = dlg.GetValue(); inductorPattern.m_length = ValueFromString( g_UserUnit, msg ); // Control values (ii = minimum length) if( inductorPattern.m_length < min_len ) { aErrorMessage = _( "Requested length < minimum length" ); return nullptr; } // Calculate the elements. std::vector <wxPoint> buffer; ll = BuildCornersList_S_Shape( buffer, inductorPattern.m_Start, inductorPattern.m_End, inductorPattern.m_length, inductorPattern.m_Width ); if( !ll ) { aErrorMessage = _( "Requested length too large" ); return nullptr; } // Generate footprint. the value is also used as footprint name. msg = "L"; wxTextEntryDialog cmpdlg( nullptr, wxEmptyString, _( "Component Value:" ), msg ); cmpdlg.SetTextValidator( FILE_NAME_CHAR_VALIDATOR( &msg ) ); if( ( cmpdlg.ShowModal() != wxID_OK ) || msg.IsEmpty() ) return nullptr; // Aborted by user MODULE* module = aPcbFrame->CreateNewModule( msg ); // here the module is already in the BOARD, CreateNewModule() does that. module->SetFPID( LIB_ID( wxString( "mw_inductor" ) ) ); module->SetAttributes( MOD_VIRTUAL | MOD_CMS ); module->ClearFlags(); module->SetPosition( inductorPattern.m_End ); // Generate segments for( unsigned jj = 1; jj < buffer.size(); jj++ ) { EDGE_MODULE* PtSegm; PtSegm = new EDGE_MODULE( module ); PtSegm->SetStart( buffer[jj - 1] ); PtSegm->SetEnd( buffer[jj] ); PtSegm->SetWidth( inductorPattern.m_Width ); PtSegm->SetLayer( module->GetLayer() ); PtSegm->SetShape( S_SEGMENT ); PtSegm->SetStart0( PtSegm->GetStart() - module->GetPosition() ); PtSegm->SetEnd0( PtSegm->GetEnd() - module->GetPosition() ); module->GraphicalItemsList().PushBack( PtSegm ); } // Place a pad on each end of coil. pad = new D_PAD( module ); module->PadsList().PushFront( pad ); pad->SetName( "1" ); pad->SetPosition( inductorPattern.m_End ); pad->SetPos0( pad->GetPosition() - module->GetPosition() ); pad->SetSize( wxSize( inductorPattern.m_Width, inductorPattern.m_Width ) ); pad->SetLayerSet( LSET( module->GetLayer() ) ); pad->SetAttribute( PAD_ATTRIB_SMD ); pad->SetShape( PAD_SHAPE_CIRCLE ); D_PAD* newpad = new D_PAD( *pad ); module->PadsList().Insert( newpad, pad->Next() ); pad = newpad; pad->SetName( "2" ); pad->SetPosition( inductorPattern.m_Start ); pad->SetPos0( pad->GetPosition() - module->GetPosition() ); // Modify text positions. wxPoint refPos( ( inductorPattern.m_Start.x + inductorPattern.m_End.x ) / 2, ( inductorPattern.m_Start.y + inductorPattern.m_End.y ) / 2 ); wxPoint valPos = refPos; refPos.y -= module->Reference().GetTextSize().y; module->Reference().SetPosition( refPos ); valPos.y += module->Value().GetTextSize().y; module->Value().SetPosition( valPos ); module->CalculateBoundingBox(); return module; }
void MODULE::Copy( MODULE* aModule ) { m_Pos = aModule->m_Pos; m_Layer = aModule->m_Layer; m_fpid = aModule->m_fpid; m_Attributs = aModule->m_Attributs; m_ModuleStatus = aModule->m_ModuleStatus; m_Orient = aModule->m_Orient; m_BoundaryBox = aModule->m_BoundaryBox; m_CntRot90 = aModule->m_CntRot90; m_CntRot180 = aModule->m_CntRot180; m_LastEditTime = aModule->m_LastEditTime; m_Link = aModule->m_Link; m_Path = aModule->m_Path; //is this correct behavior? SetTimeStamp( GetNewTimeStamp() ); m_LocalClearance = aModule->m_LocalClearance; m_LocalSolderMaskMargin = aModule->m_LocalSolderMaskMargin; m_LocalSolderPasteMargin = aModule->m_LocalSolderPasteMargin; m_LocalSolderPasteMarginRatio = aModule->m_LocalSolderPasteMarginRatio; m_ZoneConnection = aModule->m_ZoneConnection; m_ThermalWidth = aModule->m_ThermalWidth; m_ThermalGap = aModule->m_ThermalGap; // Copy reference and value. m_Reference->Copy( aModule->m_Reference ); m_Value->Copy( aModule->m_Value ); // Copy auxiliary data: Pads m_Pads.DeleteAll(); for( D_PAD* pad = aModule->m_Pads; pad; pad = pad->Next() ) { D_PAD* newpad = new D_PAD( this ); newpad->Copy( pad ); m_Pads.PushBack( newpad ); } // Copy auxiliary data: Drawings m_Drawings.DeleteAll(); for( BOARD_ITEM* item = aModule->m_Drawings; item; item = item->Next() ) { switch( item->Type() ) { case PCB_MODULE_TEXT_T: { TEXTE_MODULE* textm = new TEXTE_MODULE( this ); textm->Copy( static_cast<TEXTE_MODULE*>( item ) ); m_Drawings.PushBack( textm ); break; } case PCB_MODULE_EDGE_T: { EDGE_MODULE * edge; edge = new EDGE_MODULE( this ); edge->Copy( (EDGE_MODULE*) item ); m_Drawings.PushBack( edge ); break; } default: wxLogMessage( wxT( "MODULE::Copy() Internal Err: unknown type" ) ); break; } } // Copy auxiliary data: 3D_Drawings info m_3D_Drawings.DeleteAll(); // Ensure there is one (or more) item in m_3D_Drawings m_3D_Drawings.PushBack( new S3D_MASTER( this ) ); // push a void item for( S3D_MASTER* item = aModule->m_3D_Drawings; item; item = item->Next() ) { if( item->GetShape3DName().IsEmpty() ) // do not copy empty shapes. continue; S3D_MASTER* t3d = m_3D_Drawings; if( t3d && t3d->GetShape3DName().IsEmpty() ) // The first entry can { // exist, but is empty : use it. t3d->Copy( item ); } else { t3d = new S3D_MASTER( this ); t3d->Copy( item ); m_3D_Drawings.PushBack( t3d ); } } m_Doc = aModule->m_Doc; m_KeyWord = aModule->m_KeyWord; // Ensure auxiliary data is up to date CalculateBoundingBox(); }
/** Mirror marked items, refer to a Vertical axis at position offset * Note: because this function is used in global transform, * if force_all is true, all items will be mirrored */ void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all ) { #define SETMIRROR( z ) (z) -= offset.x; (z) = -(z); (z) += offset.x; wxPoint tmp; wxSize tmpz; if( module == NULL ) return; for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() ) { // Skip pads not selected, i.e. not inside the block to mirror: if( !pad->IsSelected() && !force_all ) continue; tmp = pad->GetPosition(); SETMIRROR( tmp.x ); pad->SetPosition( tmp ); pad->SetX0( pad->GetPosition().x ); tmp = pad->GetOffset(); NEGATE( tmp.x ); pad->SetOffset( tmp ); tmpz = pad->GetDelta(); NEGATE( tmpz.x ); pad->SetDelta( tmpz ); pad->SetOrientation( 1800 - pad->GetOrientation() ); } for( EDA_ITEM* item = module->GraphicalItems(); item; item = item->Next() ) { // Skip items not selected, i.e. not inside the block to mirror: if( !item->IsSelected() && !force_all ) continue; switch( item->Type() ) { case PCB_MODULE_EDGE_T: { EDGE_MODULE* em = (EDGE_MODULE*) item; tmp = em->GetStart0(); SETMIRROR( tmp.x ); em->SetStart0( tmp ); em->SetStartX( tmp.x ); tmp = em->GetEnd0(); SETMIRROR( tmp.x ); em->SetEnd0( tmp ); em->SetEndX( tmp.x ); em->SetAngle( -em->GetAngle() ); } break; case PCB_MODULE_TEXT_T: { TEXTE_MODULE* tm = (TEXTE_MODULE*) item; tmp = tm->GetTextPosition(); SETMIRROR( tmp.x ); tm->SetTextPosition( tmp ); tmp.y = tm->GetPos0().y; tm->SetPos0( tmp ); } break; default: break; } item->ClearFlags(); } }
/* generate shapes of graphic items (outlines) on layer aLayer as polygons, * and adds these polygons to aCornerBuffer * aCornerBuffer = the buffer to store polygons * aInflateValue = a value to inflate shapes * aCircleToSegmentsCount = number of segments to approximate a circle * aCorrectionFactor = the correction to apply to the circle radius * to generate the polygon. * if aCorrectionFactor = 1.0, the polygon is inside the circle * the radius of circle approximated by segments is * initial radius * aCorrectionFactor */ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( LAYER_NUM aLayer, CPOLYGONS_LIST& aCornerBuffer, int aInflateValue, int aCircleToSegmentsCount, double aCorrectionFactor ) { std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert EDGE_MODULE* outline; for( EDA_ITEM* item = GraphicalItems(); item != NULL; item = item->Next() ) { switch( item->Type() ) { case PCB_MODULE_TEXT_T: if( ((TEXTE_MODULE*)item)->GetLayer() == aLayer ) texts.push_back( (TEXTE_MODULE *) item ); break; case PCB_MODULE_EDGE_T: outline = (EDGE_MODULE*) item; if( outline->GetLayer() != aLayer ) break; switch( outline->GetShape() ) { case S_SEGMENT: TransformRoundedEndsSegmentToPolygon( aCornerBuffer, outline->GetStart(), outline->GetEnd(), aCircleToSegmentsCount, outline->GetWidth() ); break; case S_CIRCLE: TransformRingToPolygon( aCornerBuffer, outline->GetCenter(), outline->GetRadius(), aCircleToSegmentsCount, outline->GetWidth() ); break; case S_ARC: TransformArcToPolygon( aCornerBuffer, outline->GetCenter(), outline->GetArcStart(), outline->GetAngle(), aCircleToSegmentsCount, outline->GetWidth() ); break; case S_POLYGON: // for outline shape = S_POLYGON: // We must compute true coordinates from m_PolyPoints // which are relative to module position and module orientation = 0 for( unsigned ii = 0; ii < outline->GetPolyPoints().size(); ii++ ) { CPolyPt corner( outline->GetPolyPoints()[ii] ); RotatePoint( &corner.x, &corner.y, GetOrientation() ); corner.x += GetPosition().x; corner.y += GetPosition().y; aCornerBuffer.Append( corner ); } aCornerBuffer.CloseLastContour(); break; default: DBG( printf( "Error: Shape %d not implemented!\n", outline->GetShape() ); ) break; } break; default: break; } }
static void Print_Module( EDA_DRAW_PANEL* aPanel, wxDC* aDC, MODULE* aModule, GR_DRAWMODE aDraw_mode, LSET aMask, PRINT_PARAMETERS::DrillShapeOptT aDrillShapeOpt ) { // Print pads for( D_PAD* pad = aModule->Pads(); pad; pad = pad->Next() ) { if( !( pad->GetLayerSet() & aMask ).any() ) continue; // Manage hole according to the print drill option wxSize drill_tmp = pad->GetDrillSize(); switch( aDrillShapeOpt ) { case PRINT_PARAMETERS::NO_DRILL_SHAPE: pad->SetDrillSize( wxSize(0,0) ); break; case PRINT_PARAMETERS::SMALL_DRILL_SHAPE: { wxSize sz( std::min( SMALL_DRILL, pad->GetDrillSize().x ), std::min( SMALL_DRILL, pad->GetDrillSize().y ) ); pad->SetDrillSize( sz ); } break; case PRINT_PARAMETERS::FULL_DRILL_SHAPE: // Do nothing break; } pad->Draw( aPanel, aDC, aDraw_mode ); pad->SetDrillSize( drill_tmp ); } // Print footprint graphic shapes LSET mlayer( aModule->GetLayer() ); if( aModule->GetLayer() == B_Cu ) mlayer = LSET( B_SilkS ); else if( aModule->GetLayer() == F_Cu ) mlayer = LSET( F_SilkS ); if( ( mlayer & aMask ).any() ) { if( aModule->Reference().IsVisible() ) aModule->Reference().Draw( aPanel, aDC, aDraw_mode ); if( aModule->Value().IsVisible() ) aModule->Value().Draw( aPanel, aDC, aDraw_mode ); } for( EDA_ITEM* item = aModule->GraphicalItems(); item; item = item->Next() ) { switch( item->Type() ) { case PCB_MODULE_TEXT_T: { if( !( mlayer & aMask ).any() ) break; TEXTE_MODULE* textMod = static_cast<TEXTE_MODULE*>( item ); textMod->Draw( aPanel, aDC, aDraw_mode ); break; } case PCB_MODULE_EDGE_T: { EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( item ); if( !aMask[edge->GetLayer()] ) break; edge->Draw( aPanel, aDC, aDraw_mode ); } break; default: break; } } }
void POINT_EDITOR::addCorner( const VECTOR2I& aBreakPoint ) { EDA_ITEM* item = m_editPoints->GetParent(); const SELECTION& selection = m_selectionTool->GetSelection(); if( item->Type() == PCB_ZONE_AREA_T ) { getEditFrame<PCB_BASE_FRAME>()->OnModify(); getEditFrame<PCB_BASE_FRAME>()->SaveCopyInUndoList( selection.items, UR_CHANGED ); ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item ); CPolyLine* outline = zone->Outline(); // Handle the last segment, so other segments can be easily handled in a loop unsigned int nearestIdx = outline->GetCornersCount() - 1, nextNearestIdx = 0; SEG side( VECTOR2I( outline->GetPos( nearestIdx ) ), VECTOR2I( outline->GetPos( nextNearestIdx ) ) ); unsigned int nearestDist = side.Distance( aBreakPoint ); for( int i = 0; i < outline->GetCornersCount() - 1; ++i ) { side = SEG( VECTOR2I( outline->GetPos( i ) ), VECTOR2I( outline->GetPos( i + 1 ) ) ); unsigned int distance = side.Distance( aBreakPoint ); if( distance < nearestDist ) { nearestDist = distance; nearestIdx = i; nextNearestIdx = i + 1; } } // Find the point on the closest segment VECTOR2I sideOrigin( outline->GetPos( nearestIdx ) ); VECTOR2I sideEnd( outline->GetPos( nextNearestIdx ) ); SEG nearestSide( sideOrigin, sideEnd ); VECTOR2I nearestPoint = nearestSide.NearestPoint( aBreakPoint ); // Do not add points that have the same coordinates as ones that already belong to polygon // instead, add a point in the middle of the side if( nearestPoint == sideOrigin || nearestPoint == sideEnd ) nearestPoint = ( sideOrigin + sideEnd ) / 2; outline->InsertCorner( nearestIdx, nearestPoint.x, nearestPoint.y ); } else if( item->Type() == PCB_LINE_T || item->Type() == PCB_MODULE_EDGE_T ) { bool moduleEdge = item->Type() == PCB_MODULE_EDGE_T; PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>(); frame->OnModify(); if( moduleEdge ) frame->SaveCopyInUndoList( getModel<BOARD>()->m_Modules, UR_MODEDIT ); else frame->SaveCopyInUndoList( selection.items, UR_CHANGED ); DRAWSEGMENT* segment = static_cast<DRAWSEGMENT*>( item ); if( segment->GetShape() == S_SEGMENT ) { SEG seg( segment->GetStart(), segment->GetEnd() ); VECTOR2I nearestPoint = seg.NearestPoint( aBreakPoint ); // Move the end of the line to the break point.. segment->SetEnd( wxPoint( nearestPoint.x, nearestPoint.y ) ); // and add another one starting from the break point DRAWSEGMENT* newSegment; if( moduleEdge ) { EDGE_MODULE* edge = static_cast<EDGE_MODULE*>( segment ); assert( segment->GetParent()->Type() == PCB_MODULE_T ); newSegment = new EDGE_MODULE( *edge ); edge->SetLocalCoord(); } else { newSegment = new DRAWSEGMENT( *segment ); } newSegment->ClearSelected(); newSegment->SetStart( wxPoint( nearestPoint.x, nearestPoint.y ) ); newSegment->SetEnd( wxPoint( seg.B.x, seg.B.y ) ); if( moduleEdge ) { static_cast<EDGE_MODULE*>( newSegment )->SetLocalCoord(); getModel<BOARD>()->m_Modules->Add( newSegment ); } else { getModel<BOARD>()->Add( newSegment ); } getView()->Add( newSegment ); } } }
/* generate shapes of graphic items (outlines) on layer aLayer as polygons, * and adds these polygons to aCornerBuffer * aCornerBuffer = the buffer to store polygons * aInflateValue = a value to inflate shapes * aCircleToSegmentsCount = number of segments to approximate a circle * aCorrectionFactor = the correction to apply to the circle radius * to generate the polygon. * if aCorrectionFactor = 1.0, the polygon is inside the circle * the radius of circle approximated by segments is * initial radius * aCorrectionFactor */ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError, bool aIncludeText ) const { std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert EDGE_MODULE* outline; for( EDA_ITEM* item = GraphicalItemsList(); item != NULL; item = item->Next() ) { switch( item->Type() ) { case PCB_MODULE_TEXT_T: { TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item ); if( ( aLayer != UNDEFINED_LAYER && text->GetLayer() == aLayer ) && text->IsVisible() ) texts.push_back( text ); break; } case PCB_MODULE_EDGE_T: outline = (EDGE_MODULE*) item; if( aLayer != UNDEFINED_LAYER && outline->GetLayer() != aLayer ) break; outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, 0, aError ); break; default: break; } } if( !aIncludeText ) return; // Convert texts sur modules if( Reference().GetLayer() == aLayer && Reference().IsVisible() ) texts.push_back( &Reference() ); if( Value().GetLayer() == aLayer && Value().IsVisible() ) texts.push_back( &Value() ); prms.m_cornerBuffer = &aCornerBuffer; for( unsigned ii = 0; ii < texts.size(); ii++ ) { TEXTE_MODULE *textmod = texts[ii]; prms.m_textWidth = textmod->GetThickness() + ( 2 * aInflateValue ); prms.m_error = aError; wxSize size = textmod->GetTextSize(); if( textmod->IsMirrored() ) size.x = -size.x; DrawGraphicText( NULL, NULL, textmod->GetTextPos(), BLACK, textmod->GetShownText(), textmod->GetDrawRotation(), size, textmod->GetHorizJustify(), textmod->GetVertJustify(), textmod->GetThickness(), textmod->IsItalic(), true, addTextSegmToPoly, &prms ); } }
/** * Function PlaceCells * Initialize the matrix routing by setting obstacles for each occupied cell * a cell set to HOLE is an obstacle for tracks and vias * a cell set to VIA_IMPOSSIBLE is an obstacle for vias only. * a cell set to CELL_is_EDGE is a frontier. * Tracks and vias having the same net code as net_code are skipped * (htey do not are obstacles) * * For single-sided Routing 1: * BOTTOM side is used, and Route_Layer_BOTTOM = Route_Layer_TOP * * If flag == FORCE_PADS: all pads will be put in matrix as obstacles. */ void PlaceCells( BOARD* aPcb, int net_code, int flag ) { int ux0 = 0, uy0 = 0, ux1, uy1, dx, dy; int marge, via_marge; LAYER_MSK layerMask; // use the default NETCLASS? NETCLASS* nc = aPcb->m_NetClasses.GetDefault(); int trackWidth = nc->GetTrackWidth(); int clearance = nc->GetClearance(); int viaSize = nc->GetViaDiameter(); marge = clearance + (trackWidth / 2); via_marge = clearance + (viaSize / 2); // Place PADS on matrix routing: for( unsigned i = 0; i < aPcb->GetPadCount(); ++i ) { D_PAD* pad = aPcb->GetPad( i ); if( net_code != pad->GetNet() || (flag & FORCE_PADS) ) { ::PlacePad( pad, HOLE, marge, WRITE_CELL ); } ::PlacePad( pad, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL ); } // Place outlines of modules on matrix routing, if they are on a copper layer // or on the edge layer TRACK tmpSegm( NULL ); // A dummy track used to create segments. for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) { for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() ) { switch( item->Type() ) { case PCB_MODULE_EDGE_T: { EDGE_MODULE* edge = (EDGE_MODULE*) item; tmpSegm.SetLayer( edge->GetLayer() ); if( tmpSegm.GetLayer() == EDGE_N ) tmpSegm.SetLayer( UNDEFINED_LAYER ); tmpSegm.SetStart( edge->GetStart() ); tmpSegm.SetEnd( edge->GetEnd() ); tmpSegm.SetShape( edge->GetShape() ); tmpSegm.SetWidth( edge->GetWidth() ); tmpSegm.m_Param = edge->GetAngle(); tmpSegm.SetNet( -1 ); TraceSegmentPcb( &tmpSegm, HOLE, marge, WRITE_CELL ); TraceSegmentPcb( &tmpSegm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL ); } break; default: break; } } } // Place board outlines and texts on copper layers: for( BOARD_ITEM* item = aPcb->m_Drawings; item; item = item->Next() ) { switch( item->Type() ) { case PCB_LINE_T: { DRAWSEGMENT* DrawSegm; int type_cell = HOLE; DrawSegm = (DRAWSEGMENT*) item; tmpSegm.SetLayer( DrawSegm->GetLayer() ); if( DrawSegm->GetLayer() == EDGE_N ) { tmpSegm.SetLayer( UNDEFINED_LAYER ); type_cell |= CELL_is_EDGE; } tmpSegm.SetStart( DrawSegm->GetStart() ); tmpSegm.SetEnd( DrawSegm->GetEnd() ); tmpSegm.SetShape( DrawSegm->GetShape() ); tmpSegm.SetWidth( DrawSegm->GetWidth() ); tmpSegm.m_Param = DrawSegm->GetAngle(); tmpSegm.SetNet( -1 ); TraceSegmentPcb( &tmpSegm, type_cell, marge, WRITE_CELL ); } break; case PCB_TEXT_T: { TEXTE_PCB* PtText; PtText = (TEXTE_PCB*) item; if( PtText->GetText().Length() == 0 ) break; EDA_RECT textbox = PtText->GetTextBox( -1 ); ux0 = textbox.GetX(); uy0 = textbox.GetY(); dx = textbox.GetWidth(); dy = textbox.GetHeight(); /* Put bounding box (rectangle) on matrix */ dx /= 2; dy /= 2; ux1 = ux0 + dx; uy1 = uy0 + dy; ux0 -= dx; uy0 -= dy; layerMask = GetLayerMask( PtText->GetLayer() ); TraceFilledRectangle( ux0 - marge, uy0 - marge, ux1 + marge, uy1 + marge, PtText->GetOrientation(), layerMask, HOLE, WRITE_CELL ); TraceFilledRectangle( ux0 - via_marge, uy0 - via_marge, ux1 + via_marge, uy1 + via_marge, PtText->GetOrientation(), layerMask, VIA_IMPOSSIBLE, WRITE_OR_CELL ); } break; default: break; } } /* Put tracks and vias on matrix */ for( TRACK* track = aPcb->m_Track; track; track = track->Next() ) { if( net_code == track->GetNet() ) continue; TraceSegmentPcb( track, HOLE, marge, WRITE_CELL ); TraceSegmentPcb( track, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL ); } }
void DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::initDlg() /* Initialize messages and values in text control, * according to the item parameters values */ { SetFocus(); m_StandardButtonsSizerOK->SetDefault(); // Set unit symbol wxStaticText * texts_unit[] = { m_StartPointXUnit, m_StartPointYUnit, m_EndPointXUnit, m_EndPointYUnit, m_ThicknessTextUnit, m_DefaulThicknessTextUnit, NULL }; for( int ii = 0; ; ii++ ) { if( texts_unit[ii] == NULL ) break; texts_unit[ii]->SetLabel( GetAbbreviatedUnitsLabel() ); } wxString msg; // Change texts according to the segment shape: switch ( m_item->GetShape() ) { case S_CIRCLE: m_StartPointXLabel->SetLabel(_("Center X")); m_StartPointYLabel->SetLabel(_("Center Y")); m_EndPointXLabel->SetLabel(_("Point X")); m_EndPointYLabel->SetLabel(_("Point Y")); m_Angle_Text->Show(false); m_Angle_Ctrl->Show(false); m_AngleUnit->Show(false); break; case S_ARC: m_StartPointXLabel->SetLabel(_("Center X")); m_StartPointYLabel->SetLabel(_("Center Y")); m_EndPointXLabel->SetLabel(_("Start Point X")); m_EndPointYLabel->SetLabel(_("Start Point Y")); // Here the angle is a double, but the UI is still working // with integers msg << int( m_item->GetAngle() ); m_Angle_Ctrl->SetValue(msg); break; default: m_Angle_Text->Show(false); m_Angle_Ctrl->Show(false); m_AngleUnit->Show(false); break; } PutValueInLocalUnits( *m_Center_StartXCtrl, m_item->GetStart().x ); PutValueInLocalUnits( *m_Center_StartYCtrl, m_item->GetStart().y ); PutValueInLocalUnits( *m_EndX_Radius_Ctrl, m_item->GetEnd().x ); PutValueInLocalUnits( *m_EndY_Ctrl, m_item->GetEnd().y ); PutValueInLocalUnits( *m_ThicknessCtrl, m_item->GetWidth() ); PutValueInLocalUnits( *m_DefaultThicknessCtrl, m_brdSettings.m_ModuleSegmentWidth ); // Configure the layers list selector m_LayerSelectionCtrl->SetLayersHotkeys( false ); m_LayerSelectionCtrl->SetLayerMask( INTERNAL_CU_LAYERS|EDGE_LAYER ); m_LayerSelectionCtrl->SetBoardFrame( m_parent ); m_LayerSelectionCtrl->Resync(); if( m_LayerSelectionCtrl->SetLayerSelection( m_item->GetLayer() ) < 0 ) { wxMessageBox( _("This item has an illegal layer id.\n" "Now, forced on the front silk screen layer. Please, fix it") ); m_LayerSelectionCtrl->SetLayerSelection( SILKSCREEN_N_FRONT ); } }
bool DRAWING_TOOL::drawSegment( int aShape, DRAWSEGMENT*& aGraphic, boost::optional<VECTOR2D> aStartingPoint ) { // Only two shapes are currently supported assert( aShape == S_SEGMENT || aShape == S_CIRCLE ); DRAWSEGMENT line45; // Add a VIEW_GROUP that serves as a preview for the new item KIGFX::VIEW_GROUP preview( m_view ); m_view->Add( &preview ); m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true ); m_controls->ShowCursor( true ); m_controls->SetSnapping( true ); Activate(); bool direction45 = false; // 45 degrees only mode bool started = false; VECTOR2I cursorPos = m_controls->GetCursorPosition(); if( aStartingPoint ) { LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer; // Init the new item attributes aGraphic->SetShape( (STROKE_T) aShape ); aGraphic->SetWidth( m_lineWidth ); aGraphic->SetStart( wxPoint( aStartingPoint->x, aStartingPoint->y ) ); aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); aGraphic->SetLayer( layer ); if( aShape == S_SEGMENT ) line45 = *aGraphic; // used only for direction 45 mode with lines preview.Add( aGraphic ); m_controls->SetAutoPan( true ); m_controls->CaptureCursor( true ); started = true; } // Main loop: keep receiving events while( OPT_TOOL_EVENT evt = Wait() ) { bool updatePreview = false; // should preview be updated cursorPos = m_controls->GetCursorPosition(); // Enable 45 degrees lines only mode by holding control if( direction45 != evt->Modifier( MD_CTRL ) && started && aShape == S_SEGMENT ) { direction45 = evt->Modifier( MD_CTRL ); if( direction45 ) { preview.Add( &line45 ); make45DegLine( aGraphic, &line45 ); } else { preview.Remove( &line45 ); aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); } updatePreview = true; } if( evt->IsCancel() || evt->IsActivate() || evt->IsAction( &COMMON_ACTIONS::layerChanged ) ) { preview.Clear(); updatePreview = true; delete aGraphic; aGraphic = NULL; break; } else if( evt->IsClick( BUT_LEFT ) || evt->IsDblClick( BUT_LEFT ) ) { if( !started ) { LAYER_ID layer = m_frame->GetScreen()->m_Active_Layer; if( IsCopperLayer( layer ) ) { DisplayInfoMessage( NULL, _( "Graphic not allowed on Copper layers" ) ); } else { // Init the new item attributes aGraphic->SetShape( (STROKE_T) aShape ); m_lineWidth = getSegmentWidth( layer ); aGraphic->SetWidth( m_lineWidth ); aGraphic->SetStart( wxPoint( cursorPos.x, cursorPos.y ) ); aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); aGraphic->SetLayer( layer ); if( aShape == S_SEGMENT ) line45 = *aGraphic; // used only for direction 45 mode with lines preview.Add( aGraphic ); m_controls->SetAutoPan( true ); m_controls->CaptureCursor( true ); started = true; } } else { if( aGraphic->GetEnd() == aGraphic->GetStart() || ( evt->IsDblClick( BUT_LEFT ) && aShape == S_SEGMENT ) ) // User has clicked twice in the same spot { // a clear sign that the current drawing is finished if( direction45 ) { // Now we have to add the helper line as well if( m_editModules ) { EDGE_MODULE* l = new EDGE_MODULE( m_board->m_Modules ); // Copy coordinates, layer, etc. *static_cast<DRAWSEGMENT*>( l ) = line45; l->SetEnd( aGraphic->GetStart() ); l->SetLocalCoord(); m_frame->SaveCopyInUndoList( m_board->m_Modules, UR_MODEDIT ); m_board->m_Modules->SetLastEditTime(); m_board->m_Modules->GraphicalItems().PushFront( l ); m_view->Add( l ); l->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } else { DRAWSEGMENT* l = static_cast<DRAWSEGMENT*>( line45.Clone() ); l->SetEnd( aGraphic->GetStart() ); m_frame->SaveCopyInUndoList( l, UR_NEW ); m_board->Add( l ); m_view->Add( l ); l->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } m_frame->OnModify(); } delete aGraphic; aGraphic = NULL; } else { assert( aGraphic->GetLength() > 0 ); assert( aGraphic->GetWidth() > 0 ); m_view->Add( aGraphic ); aGraphic->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } preview.Clear(); break; } } else if( evt->IsMotion() ) { // 45 degree lines if( direction45 && aShape == S_SEGMENT ) make45DegLine( aGraphic, &line45 ); else aGraphic->SetEnd( wxPoint( cursorPos.x, cursorPos.y ) ); updatePreview = true; } else if( evt->IsAction( &COMMON_ACTIONS::incWidth ) ) { m_lineWidth += WIDTH_STEP; aGraphic->SetWidth( m_lineWidth ); updatePreview = true; } else if( evt->IsAction( &COMMON_ACTIONS::decWidth ) ) { if( m_lineWidth > (unsigned) WIDTH_STEP ) { m_lineWidth -= WIDTH_STEP; aGraphic->SetWidth( m_lineWidth ); updatePreview = true; } } if( updatePreview ) preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY ); } m_controls->ShowCursor( false ); m_controls->SetSnapping( false ); m_controls->SetAutoPan( false ); m_controls->CaptureCursor( false ); m_view->Remove( &preview ); return started; }
bool DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::TransferDataToWindow() { // Set unit symbol wxStaticText* texts_unit[] = { m_StartPointXUnit, m_StartPointYUnit, m_EndPointXUnit, m_EndPointYUnit, m_ThicknessTextUnit, m_DefaulThicknessTextUnit, }; for( size_t ii = 0; ii < DIM( texts_unit ); ii++ ) { texts_unit[ii]->SetLabel( GetAbbreviatedUnitsLabel() ); } wxString msg; // Change texts according to the segment shape: switch( m_item->GetShape() ) { case S_CIRCLE: SetTitle( _( "Circle Properties" ) ); m_StartPointXLabel->SetLabel( _( "Center X" ) ); m_StartPointYLabel->SetLabel( _( "Center Y" ) ); m_EndPointXLabel->SetLabel( _( "Point X" ) ); m_EndPointYLabel->SetLabel( _( "Point Y" ) ); m_AngleText->Show( false ); m_AngleCtrl->Show( false ); m_AngleUnit->Show( false ); break; case S_ARC: SetTitle( _( "Arc Properties" ) ); m_StartPointXLabel->SetLabel( _( "Center X" ) ); m_StartPointYLabel->SetLabel( _( "Center Y" ) ); m_EndPointXLabel->SetLabel( _( "Start Point X" ) ); m_EndPointYLabel->SetLabel( _( "Start Point Y" ) ); m_AngleValue = m_item->GetAngle() / 10.0; break; case S_SEGMENT: SetTitle( _( "Line Segment Properties" ) ); // Fall through. default: m_AngleText->Show( false ); m_AngleCtrl->Show( false ); m_AngleUnit->Show( false ); break; } PutValueInLocalUnits( *m_Center_StartXCtrl, m_item->GetStart().x ); PutValueInLocalUnits( *m_Center_StartYCtrl, m_item->GetStart().y ); PutValueInLocalUnits( *m_EndX_Radius_Ctrl, m_item->GetEnd().x ); PutValueInLocalUnits( *m_EndY_Ctrl, m_item->GetEnd().y ); PutValueInLocalUnits( *m_ThicknessCtrl, m_item->GetWidth() ); PutValueInLocalUnits( *m_DefaultThicknessCtrl, m_brdSettings.m_ModuleSegmentWidth ); // Configure the layers list selector m_LayerSelectionCtrl->SetLayersHotkeys( false ); m_LayerSelectionCtrl->SetLayerSet( LSET::InternalCuMask().set( Edge_Cuts ) ); m_LayerSelectionCtrl->SetBoardFrame( m_parent ); m_LayerSelectionCtrl->Resync(); if( m_LayerSelectionCtrl->SetLayerSelection( m_item->GetLayer() ) < 0 ) { wxMessageBox( _( "This item was on an unknown layer.\n" "It has been moved to the front silk screen layer. Please fix it." ) ); m_LayerSelectionCtrl->SetLayerSelection( F_SilkS ); } return DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::TransferDataToWindow(); }
bool DIALOG_MODEDIT_FP_BODY_ITEM_PROPERTIES::Validate() { wxArrayString error_msgs; if( !DIALOG_GRAPHIC_ITEM_PROPERTIES_BASE::Validate() ) return false; // Load the start and end points -- all types use these in the checks. int startx = ValueFromString( g_UserUnit, m_Center_StartXCtrl->GetValue() ); int starty = ValueFromString( g_UserUnit, m_Center_StartYCtrl->GetValue() ); int endx = ValueFromString( g_UserUnit, m_EndX_Radius_Ctrl->GetValue() ); int endy = ValueFromString( g_UserUnit, m_EndY_Ctrl->GetValue() ); // Type specific checks. switch( m_item->GetShape() ) { case S_ARC: // Check angle of arc. double angle; m_AngleCtrl->GetValue().ToDouble( &angle ); NORMALIZE_ANGLE_360( angle ); if( angle == 0 ) { error_msgs.Add( _( "The arc angle must be greater than zero." ) ); } // Fall through. case S_CIRCLE: // Check radius. if( (startx == endx) && (starty == endy) ) error_msgs.Add( _( "The radius must be greater than zero." ) ); break; default: // Check start and end are not the same. if( (startx == endx) && (starty == endy) ) error_msgs.Add( _( "The start and end points cannot be the same." ) ); break; } // Check the item thickness. int thickness = ValueFromString( g_UserUnit, m_ThicknessCtrl->GetValue() ); if( thickness <= 0 ) error_msgs.Add( _( "The item thickness must be greater than zero." ) ); // And the default thickness. thickness = ValueFromString( g_UserUnit, m_DefaultThicknessCtrl->GetValue() ); if( thickness <= 0 ) error_msgs.Add( _( "The default thickness must be greater than zero." ) ); if( error_msgs.GetCount() ) { HTML_MESSAGE_BOX dlg( this, _( "Error list" ) ); dlg.ListSet( error_msgs ); dlg.ShowModal(); } return error_msgs.GetCount() == 0; }