Beispiel #1
0
void PCB_TEXT::AddToBoard()
{
    // Simple, not the best, but acceptable text positioning.
    m_name.textPositionX    = m_positionX;
    m_name.textPositionY    = m_positionY;
    CorrectTextPosition( &m_name, m_rotation );

    TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board );
    m_board->Add( pcbtxt, ADD_APPEND );

    pcbtxt->SetText( m_name.text );

    pcbtxt->SetSize( wxSize( KiROUND( m_name.textHeight / 2 ),
                             KiROUND( m_name.textHeight / 1.1 ) ) );

    pcbtxt->SetThickness( m_name.textstrokeWidth );
    pcbtxt->SetOrientation( m_rotation );

    pcbtxt->SetPosition( wxPoint( m_name.correctedPositionX, m_name.correctedPositionY ) );

    pcbtxt->SetMirrored( m_name.mirror );
    pcbtxt->SetTimeStamp( 0 );

    pcbtxt->SetLayer( m_KiCadLayer );
}
void PCB_TEXT::AddToBoard()
{
    m_name.textPositionX = m_positionX;
    m_name.textPositionY = m_positionY;
    m_name.textRotation = m_rotation;

    TEXTE_PCB* pcbtxt = new TEXTE_PCB( m_board );
    m_board->Add( pcbtxt, ADD_APPEND );

    pcbtxt->SetText( m_name.text );

    SetTextSizeFromStrokeFontHeight( pcbtxt, m_name.textHeight );

    pcbtxt->SetThickness( m_name.textstrokeWidth );
    pcbtxt->SetOrientation( m_name.textRotation );

    SetTextJustify( pcbtxt, m_name.justify );
    pcbtxt->SetTextPosition( wxPoint( m_name.textPositionX,
                                      m_name.textPositionY ) );

    pcbtxt->SetMirrored( m_name.mirror );
    pcbtxt->SetTimeStamp( 0 );

    pcbtxt->SetLayer( m_KiCadLayer );
}
// Move  PCB text following the cursor.
static void Move_Texte_Pcb( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosition,
                            bool aErase )
{
    TEXTE_PCB* TextePcb = (TEXTE_PCB*) aPanel->GetScreen()->GetCurItem();

    if( TextePcb == NULL )
        return;

    if( aErase )
        TextePcb->Draw( aPanel, aDC, GR_XOR );

    TextePcb->SetTextPosition( aPanel->GetParent()->GetCrossHairPosition() );

    TextePcb->Draw( aPanel, aDC, GR_XOR );
}
/*
 * Abort current text edit progress.
 * If a text is selected, its initial coord are regenerated
 */
void Abort_Edit_Pcb_Text( EDA_DRAW_PANEL* Panel, wxDC* DC )
{
    TEXTE_PCB* TextePcb = (TEXTE_PCB*) Panel->GetScreen()->GetCurItem();
    ( (PCB_EDIT_FRAME*) Panel->GetParent() )->SetCurItem( NULL );

    Panel->SetMouseCapture( NULL, NULL );

    if( TextePcb == NULL )  // Should not occur
        return;

#ifndef USE_WX_OVERLAY
    TextePcb->Draw( Panel, DC, GR_XOR );
#endif

    if( TextePcb->IsNew() )  // If new: remove it
    {
        TextePcb->DeleteStructure();
        return;
    }


    TextePcb->SwapData( &s_TextCopy );
    TextePcb->ClearFlags();
#ifndef USE_WX_OVERLAY
    TextePcb->Draw( Panel, DC, GR_OR );
#else
    Panel->Refresh();
#endif
}
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();
}
/*
 *  Place the current text being moving
 */
void PCB_EDIT_FRAME::Place_Texte_Pcb( TEXTE_PCB* TextePcb, wxDC* DC )
{
    m_canvas->SetMouseCapture( NULL, NULL );
    SetCurItem( NULL );

    if( TextePcb == NULL )
        return;

    TextePcb->Draw( m_canvas, DC, GR_OR );
    OnModify();

    if( TextePcb->IsNew() )  // If new: prepare undo command
    {
        SaveCopyInUndoList( TextePcb, UR_NEW );
        TextePcb->ClearFlags();
        return;
    }

    if( TextePcb->IsMoving() ) // If moved only
    {
        SaveCopyInUndoList( TextePcb, UR_MOVED,
                            TextePcb->GetTextPosition() - s_TextCopy.GetTextPosition() );
    }
    else
    {
        // Restore initial params
        TextePcb->SwapData( &s_TextCopy );
        // Prepare undo command
        SaveCopyInUndoList( TextePcb, UR_CHANGED );
        // Restore current params
        TextePcb->SwapData( &s_TextCopy );
    }

    TextePcb->ClearFlags();
#ifdef USE_WX_OVERLAY
    m_canvas->Refresh();
#endif
}
void PCB_EDIT_FRAME::StartMoveTextePcb( TEXTE_PCB* aTextePcb, wxDC* aDC, bool aErase )
{
    if( aTextePcb == NULL )
        return;

    // if it is an existing item: prepare a copy to undo/abort command
    if( !aTextePcb->IsNew() )
        s_TextCopy.Copy( aTextePcb );

    aTextePcb->SetFlags( IS_MOVED );
    SetMsgPanel( aTextePcb );

#ifdef USE_WX_OVERLAY
    m_canvas->Refresh();
#endif

    SetCrossHairPosition( aTextePcb->GetTextPosition() );
    m_canvas->MoveCursorToCrossHair();

    m_canvas->SetMouseCapture( Move_Texte_Pcb, Abort_Edit_Pcb_Text );
    SetCurItem( aTextePcb );
    m_canvas->CallMouseCapture( aDC, wxDefaultPosition, aErase );
}
TEXTE_PCB* PCB_EDIT_FRAME::CreateTextePcb( wxDC* aDC, TEXTE_PCB* aText )
{
    TEXTE_PCB* textePcb = new TEXTE_PCB( GetBoard() );

    if( aText )
    {
        textePcb->Copy( aText );
        GetBoard()->Add( textePcb );
        textePcb->SetFlags( IS_NEW );
        if( aDC )
            StartMoveTextePcb( textePcb, aDC, false ); // Don't erase aText when copying
    }
    else
    {
        GetBoard()->Add( textePcb );
        textePcb->SetFlags( IS_NEW );
        LAYER_NUM layer = ( (PCB_SCREEN*) GetScreen() )->m_Active_Layer;
        textePcb->SetLayer( layer );

        // Set the mirrored option for layers on the BACK side of the board
        if( layer == LAYER_N_BACK || layer == SILKSCREEN_N_BACK ||
            layer == SOLDERPASTE_N_BACK || layer == SOLDERMASK_N_BACK ||
            layer == ADHESIVE_N_BACK
            )
            textePcb->SetMirrored( true );

        textePcb->SetSize( GetBoard()->GetDesignSettings().m_PcbTextSize );
        textePcb->SetTextPosition( GetCrossHairPosition() );
        textePcb->SetThickness( GetBoard()->GetDesignSettings().m_PcbTextWidth );

        InstallTextPCBOptionsFrame( textePcb, aDC );

        if( textePcb->GetText().IsEmpty() )
        {
            textePcb->DeleteStructure();
            textePcb = NULL;
        }
        else if( aDC )
        {
            StartMoveTextePcb( textePcb, aDC );
        }
    }

    return textePcb;
}
void DRC::testTexts()
{
    std::vector<wxPoint> textShape;      // a buffer to store the text shape (set of segments)
    std::vector<D_PAD*> padList = m_pcb->GetPads();

    // Test text areas for vias, tracks and pads inside text areas
    for( BOARD_ITEM* item = m_pcb->m_Drawings; item; item = item->Next() )
    {
        // Drc test only items on copper layers
        if( ! IsCopperLayer( item->GetLayer() ) )
            continue;

        // only texts on copper layers are tested
        if( item->Type() !=  PCB_TEXT_T )
            continue;

        textShape.clear();

        // So far the bounding box makes up the text-area
        TEXTE_PCB* text = (TEXTE_PCB*) item;
        text->TransformTextShapeToSegmentList( textShape );

        if( textShape.size() == 0 )     // Should not happen (empty text?)
            continue;

        for( TRACK* track = m_pcb->m_Track; track != NULL; track = track->Next() )
        {
            if( ! track->IsOnLayer( item->GetLayer() ) )
                    continue;

            // Test the distance between each segment and the current track/via
            int min_dist = ( track->GetWidth() + text->GetThickness() ) /2 +
                           track->GetClearance(NULL);

            if( track->Type() == PCB_TRACE_T )
            {
                SEG segref( track->GetStart(), track->GetEnd() );

                // Error condition: Distance between text segment and track segment is
                // smaller than the clearance of the segment
                for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
                {
                    SEG segtest( textShape[jj], textShape[jj+1] );
                    int dist = segref.Distance( segtest );

                    if( dist < min_dist )
                    {
                        addMarkerToPcb( fillMarker( track, text,
                                                    DRCE_TRACK_INSIDE_TEXT,
                                                    m_currentMarker ) );
                        m_currentMarker = nullptr;
                        break;
                    }
                }
            }
            else if( track->Type() == PCB_VIA_T )
            {
                // Error condition: Distance between text segment and via is
                // smaller than the clearance of the via
                for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
                {
                    SEG segtest( textShape[jj], textShape[jj+1] );

                    if( segtest.PointCloserThan( track->GetPosition(), min_dist ) )
                    {
                        addMarkerToPcb( fillMarker( track, text,
                                                    DRCE_VIA_INSIDE_TEXT, m_currentMarker ) );
                        m_currentMarker = nullptr;
                        break;
                    }
                }
            }
        }

        // Test pads
        for( unsigned ii = 0; ii < padList.size(); ii++ )
        {
            D_PAD* pad = padList[ii];

            if( ! pad->IsOnLayer( item->GetLayer() ) )
                    continue;

            wxPoint shape_pos = pad->ShapePos();

            for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
            {
                /* In order to make some calculations more easier or faster,
                 * pads and tracks coordinates will be made relative
                 * to the segment origin
                 */
                wxPoint origin = textShape[jj];  // origin will be the origin of other coordinates
                m_segmEnd = textShape[jj+1] - origin;
                wxPoint delta = m_segmEnd;
                m_segmAngle = 0;

                // for a non horizontal or vertical segment Compute the segment angle
                // in tenths of degrees and its length
                if( delta.x || delta.y )    // delta.x == delta.y == 0 for vias
                {
                    // Compute the segment angle in 0,1 degrees
                    m_segmAngle = ArcTangente( delta.y, delta.x );

                    // Compute the segment length: we build an equivalent rotated segment,
                    // this segment is horizontal, therefore dx = length
                    RotatePoint( &delta, m_segmAngle );    // delta.x = length, delta.y = 0
                }

                m_segmLength = delta.x;
                m_padToTestPos = shape_pos - origin;

                if( !checkClearanceSegmToPad( pad, text->GetThickness(),
                                              pad->GetClearance(NULL) ) )
                {
                    addMarkerToPcb( fillMarker( pad, text,
                                                DRCE_PAD_INSIDE_TEXT, m_currentMarker ) );
                    m_currentMarker = nullptr;
                    break;
                }
            }
        }
    }
}
Beispiel #10
0
/* Initialise les cellules du board a la valeur HOLE et VIA_IMPOSSIBLE
	selon les marges d'isolement
	les elements de net_code = net_code ne seront pas places comme occupe
	mais en VIA_IMPOSSIBLE uniquement
	Pour Routage 1 seule face:
		le plan BOTTOM est utilise
		et Route_Layer_BOTTOM = Route_Layer_TOP

	Selon les bits = 1 du parametre flag:
		si FORCE_PADS : tous les pads seront places meme ceux de meme net_code
*/
void PlaceCells(BOARD * Pcb, int net_code, int flag)
{
int ii;
LISTE_PAD* ptr;
TRACK * pt_segm;
TEXTE_PCB * PtText;
DRAWSEGMENT * DrawSegm;
EDA_BaseStruct * PtStruct;
int ux0 = 0 , uy0 = 0, ux1, uy1, dx, dy;
int marge, via_marge;
int masque_layer;

	marge = g_DesignSettings.m_TrackClearence + (g_DesignSettings.m_CurrentTrackWidth /2);
	via_marge = g_DesignSettings.m_TrackClearence + (g_DesignSettings.m_CurrentViaSize /2);

	/////////////////////////////////////
	// Placement des PADS sur le board //
	/////////////////////////////////////
	ptr = (LISTE_PAD*)Pcb->m_Pads; ii = Pcb->m_NbPads;
	for( ; ii > 0 ; ii-- , ptr++)
		{
		if( (net_code != (*ptr)->m_NetCode ) || (flag & FORCE_PADS) )
			{
			Place_1_Pad_Board(Pcb, *ptr, HOLE, marge, WRITE_CELL);
			}
		Place_1_Pad_Board(Pcb, *ptr, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL);
		}

	///////////////////////////////////////////////
	// Placement des elements de modules sur PCB //
	///////////////////////////////////////////////
	PtStruct = Pcb->m_Modules;
	for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
		{
		EDA_BaseStruct * PtModStruct = ((MODULE*)PtStruct)->m_Drawings;
		for( ;PtModStruct != NULL; PtModStruct = PtModStruct->Pnext )
			{
			switch( PtModStruct->m_StructType )
				{
				case TYPEEDGEMODULE:
					{
					TRACK * TmpSegm = new TRACK(NULL);
					TmpSegm->m_Layer = ((EDGE_MODULE *) PtModStruct)->m_Layer;
					if(TmpSegm->m_Layer == EDGE_N) TmpSegm->m_Layer = -1;

					TmpSegm->m_Start = ((EDGE_MODULE *) PtModStruct)->m_Start;
					TmpSegm->m_End = ((EDGE_MODULE *) PtModStruct)->m_End;
					TmpSegm->m_Shape = ((EDGE_MODULE *) PtModStruct)->m_Shape;
					TmpSegm->m_Width = ((EDGE_MODULE *) PtModStruct)->m_Width;
					TmpSegm->m_Param = ((EDGE_MODULE *) PtModStruct)->m_Angle;
					TmpSegm->m_NetCode = -1;

					TraceSegmentPcb(Pcb, TmpSegm, HOLE, marge,WRITE_CELL );
					TraceSegmentPcb(Pcb, TmpSegm, VIA_IMPOSSIBLE, via_marge,
									WRITE_OR_CELL );
					delete TmpSegm;
					break;
					}

				default: break;
				}
			}
		}

	////////////////////////////////////////////
	// Placement des contours et segments PCB //
	////////////////////////////////////////////
	PtStruct = Pcb->m_Drawings;
	for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
		{
		switch( PtStruct->m_StructType)
			{
			case TYPEDRAWSEGMENT:
				{
				int type_cell = HOLE;
				TRACK * TmpSegm = new TRACK(NULL);
				DrawSegm = (DRAWSEGMENT *) PtStruct;
				TmpSegm->m_Layer = DrawSegm->m_Layer;
				if(DrawSegm->m_Layer == EDGE_N)
					{
					TmpSegm->m_Layer = -1;
					type_cell |= CELL_is_EDGE;
					}

				TmpSegm->m_Start = DrawSegm->m_Start;
				TmpSegm->m_End = DrawSegm->m_End;
				TmpSegm->m_Shape = DrawSegm->m_Shape;
				TmpSegm->m_Width = DrawSegm->m_Width;
				TmpSegm->m_Param = DrawSegm->m_Angle;
				TmpSegm->m_NetCode = -1;

				TraceSegmentPcb(Pcb, TmpSegm, type_cell, marge,WRITE_CELL );
//				TraceSegmentPcb(Pcb, TmpSegm, VIA_IMPOSSIBLE, via_marge,WRITE_OR_CELL );
				delete TmpSegm;
				break;
				}

			case TYPETEXTE:
				PtText = (TEXTE_PCB*) PtStruct;
				if(PtText->GetLength() == 0 ) break;
				ux0 = PtText->m_Pos.x; uy0 = PtText->m_Pos.y;

				dx = PtText->Pitch()* PtText->GetLength();
				dy = PtText->m_Size.y + PtText->m_Width;

				/* Calcul du rectangle d'encadrement */
				dx /= 2; dy /= 2; /* dx et dy = demi dimensionx X et Y */
				ux1 = ux0 + dx; uy1 = uy0 + dy;
				ux0 -= dx; uy0 -= dy;

				masque_layer = g_TabOneLayerMask[PtText->m_Layer];

				TraceFilledRectangle(Pcb, ux0-marge, uy0-marge, ux1+marge, uy1+marge,
								(int)(PtText->m_Orient),
								masque_layer, HOLE, WRITE_CELL);
				TraceFilledRectangle(Pcb, ux0-via_marge, uy0-via_marge,
								ux1+via_marge, uy1+via_marge,
								(int)(PtText->m_Orient),
								masque_layer, VIA_IMPOSSIBLE, WRITE_OR_CELL);
				break;

			default: break;
			}
		}

	/* Placement des PISTES */
	pt_segm = Pcb->m_Track;
	for( ; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext)
		{
		if(net_code == pt_segm->m_NetCode) continue;
		TraceSegmentPcb(Pcb, pt_segm, HOLE, marge, WRITE_CELL );
		TraceSegmentPcb(Pcb, pt_segm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
		}

	/* Placement des ZONES */
	pt_segm = (TRACK*) Pcb->m_Zone;
	for( ; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext)
		{
		if(net_code == pt_segm->m_NetCode) continue;
		TraceSegmentPcb(Pcb, pt_segm, HOLE, marge, WRITE_CELL );
		TraceSegmentPcb(Pcb, pt_segm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
		}
}
Beispiel #11
0
/**
 * 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 );
    }
}
int DRAWING_TOOL::placeTextPcb()
{
    TEXTE_PCB* text = NULL;

    assert( !m_editModules );

    // 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 );
     // do not capture or auto-pan until we start placing some text

    Activate();
    m_frame->SetToolID( ID_PCB_ADD_TEXT_BUTT, wxCURSOR_PENCIL, _( "Add text" ) );

    // Main loop: keep receiving events
    while( OPT_TOOL_EVENT evt = Wait() )
    {
        VECTOR2I cursorPos = m_controls->GetCursorPosition();

        if( evt->IsCancel() || evt->IsActivate() )
        {
            if( text )
            {
                // Delete the old text and have another try
                m_board->Delete( text );        // it was already added by CreateTextPcb()
                text = NULL;

                preview.Clear();
                preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
                m_controls->SetAutoPan( false );
                m_controls->CaptureCursor( false );
                m_controls->ShowCursor( true );
            }
            else
                break;

            if( evt->IsActivate() )  // now finish unconditionally
                break;
        }

        else if( text && evt->Category() == TC_COMMAND )
        {
            if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
            {
                text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() );
                preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            }
            else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
            {
                text->Flip( text->GetPosition() );
                preview.ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            }
        }

        else if( evt->IsClick( BUT_LEFT ) )
        {
            if( !text )
            {
                // Init the new item attributes
                text = static_cast<PCB_EDIT_FRAME*>( m_frame )->CreateTextePcb( NULL );

                if( text == NULL )
                    continue;

                m_controls->CaptureCursor( true );
                m_controls->SetAutoPan( true );
                preview.Add( text );
            }
            else
            {
                assert( text->GetText().Length() > 0 );
                assert( text->GetSize().x > 0 && text->GetSize().y > 0 );

                text->ClearFlags();
                m_view->Add( text );
                // m_board->Add( text );        // it is already added by CreateTextePcb()
                text->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );

                m_frame->OnModify();
                m_frame->SaveCopyInUndoList( text, UR_NEW );

                preview.Remove( text );
                m_controls->CaptureCursor( false );
                m_controls->SetAutoPan( false );

                text = NULL;
            }
        }

        else if( text && evt->IsMotion() )
        {
            text->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );

            // Show a preview of the item
            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 );

    m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );

    return 0;
}
Beispiel #13
0
int DRAWING_TOOL::PlaceDXF( const TOOL_EVENT& aEvent )
{
    if( !m_frame->GetModel() )
        return 0;

    DIALOG_DXF_IMPORT dlg( m_frame );
    int dlgResult = dlg.ShowModal();

    const std::list<BOARD_ITEM*>& list = dlg.GetImportedItems();

    if( dlgResult != wxID_OK || list.empty() )
        return 0;

    VECTOR2I cursorPos = m_controls->GetCursorPosition();
    VECTOR2I delta = cursorPos - list.front()->GetPosition();

    // Add a VIEW_GROUP that serves as a preview for the new item
    SELECTION preview( m_view );
    BOARD_COMMIT commit( m_frame );

    // Build the undo list & add items to the current view
    for( auto item : list )
    {
        assert( item->Type() == PCB_LINE_T || item->Type() == PCB_TEXT_T );

        preview.Add( item );
    }

    BOARD_ITEM* firstItem = preview.Front();
    m_view->Add( &preview );

    m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
    m_controls->ShowCursor( true );
    m_controls->SetSnapping( true );

    SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::DXF );

    Activate();

    // Main loop: keep receiving events
    while( OPT_TOOL_EVENT evt = Wait() )
    {
        cursorPos = m_controls->GetCursorPosition();

        if( evt->IsMotion() )
        {
            delta = cursorPos - firstItem->GetPosition();

            for( auto item : preview )
                item->Move( wxPoint( delta.x, delta.y ) );

            m_view->Update( &preview );
        }

        else if( evt->Category() == TC_COMMAND )
        {
            // TODO it should be handled by EDIT_TOOL, so add items and select?
            if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
            {
                for( auto item : preview )
                    item->Rotate( wxPoint( cursorPos.x, cursorPos.y ),
                                 m_frame->GetRotationAngle() );

                m_view->Update( &preview );
            }
            else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
            {
                for( auto item : preview )
                    item->Flip( wxPoint( cursorPos.x, cursorPos.y ) );

                m_view->Update( &preview );
            }
            else if( evt->IsCancel() || evt->IsActivate() )
            {
                preview.FreeItems();
                break;
            }
        }

        else if ( evt->IsClick( BUT_RIGHT ) )
        {
            showContextMenu();
        }

        else if( evt->IsClick( BUT_LEFT ) )
        {
            // Place the drawing
            BOARD_ITEM_CONTAINER* parent = m_frame->GetModel();

            for( auto item : preview )
            {
                if( m_editModules )
                {
                    // Modules use different types for the same things,
                    // so we need to convert imported items to appropriate classes.
                    BOARD_ITEM* converted = NULL;

                    switch( item->Type() )
                    {
                    case PCB_TEXT_T:
                    {
                        TEXTE_PCB* text = static_cast<TEXTE_PCB*>( item );
                        TEXTE_MODULE* textMod = new TEXTE_MODULE( (MODULE*) parent );
                        // Assignment operator also copies the item PCB_TEXT_T type,
                        // so it cannot be added to a module which handles PCB_MODULE_TEXT_T
                        textMod->SetPosition( text->GetPosition() );
                        textMod->SetText( text->GetText() );
                        textMod->SetSize( text->GetSize() );
                        textMod->SetThickness( text->GetThickness() );
                        textMod->SetOrientation( text->GetOrientation() );
                        textMod->SetTextPosition( text->GetTextPosition() );
                        textMod->SetSize( text->GetSize() );
                        textMod->SetMirrored( text->IsMirrored() );
                        textMod->SetAttributes( text->GetAttributes() );
                        textMod->SetItalic( text->IsItalic() );
                        textMod->SetBold( text->IsBold() );
                        textMod->SetHorizJustify( text->GetHorizJustify() );
                        textMod->SetVertJustify( text->GetVertJustify() );
                        textMod->SetMultilineAllowed( text->IsMultilineAllowed() );
                        converted = textMod;
                        break;
                    }

                    case PCB_LINE_T:
                    {
                        DRAWSEGMENT* seg = static_cast<DRAWSEGMENT*>( item );
                        EDGE_MODULE* modSeg = new EDGE_MODULE( (MODULE*) parent );

                        // Assignment operator also copies the item PCB_LINE_T type,
                        // so it cannot be added to a module which handles PCB_MODULE_EDGE_T
                        modSeg->SetWidth( seg->GetWidth() );
                        modSeg->SetStart( seg->GetStart() );
                        modSeg->SetEnd( seg->GetEnd() );
                        modSeg->SetAngle( seg->GetAngle() );
                        modSeg->SetShape( seg->GetShape() );
                        modSeg->SetType( seg->GetType() );
                        modSeg->SetBezControl1( seg->GetBezControl1() );
                        modSeg->SetBezControl2( seg->GetBezControl2() );
                        modSeg->SetBezierPoints( seg->GetBezierPoints() );
                        modSeg->SetPolyPoints( seg->GetPolyPoints() );
                        converted = modSeg;
                        break;
                    }

                    default:
                        assert( false );
                        break;
                    }

                    if( converted )
                        converted->SetLayer( item->GetLayer() );

                    delete item;
                    item = converted;
                }

                if( item )
                    commit.Add( item );
            }

            commit.Push( _( "Place a DXF drawing" ) );
            break;
        }
    }

    preview.Clear();

    m_controls->ShowCursor( false );
    m_controls->SetSnapping( false );
    m_controls->SetAutoPan( false );
    m_controls->CaptureCursor( false );
    m_view->Remove( &preview );

    return 0;
}
Beispiel #14
0
int DRAWING_TOOL::PlaceText( const TOOL_EVENT& aEvent )
{
    BOARD_ITEM* text = NULL;
    const BOARD_DESIGN_SETTINGS& dsnSettings = m_frame->GetDesignSettings();
    BOARD_COMMIT commit( m_frame );

    // Add a VIEW_GROUP that serves as a preview for the new item
    SELECTION preview( m_view );
    m_view->Add( &preview );

    m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );
    m_controls->ShowCursor( true );
    m_controls->SetSnapping( true );
    // do not capture or auto-pan until we start placing some text

    SCOPED_DRAW_MODE scopedDrawMode( m_mode, MODE::TEXT );

    Activate();
    m_frame->SetToolID( m_editModules ? ID_MODEDIT_TEXT_TOOL : ID_PCB_ADD_TEXT_BUTT,
                        wxCURSOR_PENCIL, _( "Add text" ) );

    // Main loop: keep receiving events
    while( OPT_TOOL_EVENT evt = Wait() )
    {
        VECTOR2I cursorPos = m_controls->GetCursorPosition();

        if( evt->IsCancel() || evt->IsActivate() )
        {
            if( text )
            {
                // Delete the old text and have another try
                delete text;
                text = NULL;

                preview.Clear();

                m_controls->SetAutoPan( false );
                m_controls->CaptureCursor( false );
                m_controls->ShowCursor( true );
            }
            else
                break;

            if( evt->IsActivate() )  // now finish unconditionally
                break;
        }

        else if( text && evt->Category() == TC_COMMAND )
        {
            if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
            {
                text->Rotate( text->GetPosition(), m_frame->GetRotationAngle() );
                m_view->Update( &preview );
            }
            // TODO rotate CCW
            else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
            {
                text->Flip( text->GetPosition() );
                m_view->Update( &preview );
            }
        }

        else if ( evt->IsClick( BUT_RIGHT ) )
        {
            showContextMenu();
        }

        else if( evt->IsClick( BUT_LEFT ) )
        {
            if( !text )
            {
                // Init the new item attributes
                if( m_editModules )
                {
                    TEXTE_MODULE* textMod = new TEXTE_MODULE( (MODULE*) m_frame->GetModel() );

                    textMod->SetLayer( m_frame->GetActiveLayer() );
                    textMod->SetSize( dsnSettings.m_ModuleTextSize );
                    textMod->SetThickness( dsnSettings.m_ModuleTextWidth );
                    textMod->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );

                    DialogEditModuleText textDialog( m_frame, textMod, NULL );
                    bool placing;

                    RunMainStack( [&]() {
                        placing = textDialog.ShowModal() && ( textMod->GetText().Length() > 0 );
                    } );

                    if( placing )
                        text = textMod;
                    else
                        delete textMod;
                }
                else
                {
                    TEXTE_PCB* textPcb = new TEXTE_PCB( m_frame->GetModel() );
                    // TODO we have to set IS_NEW, otherwise InstallTextPCB.. creates an undo entry :| LEGACY_CLEANUP
                    textPcb->SetFlags( IS_NEW );

                    LAYER_ID layer = m_frame->GetActiveLayer();
                    textPcb->SetLayer( layer );

                    // Set the mirrored option for layers on the BACK side of the board
                    if( IsBackLayer( layer ) )
                        textPcb->SetMirrored( true );

                    textPcb->SetSize( dsnSettings.m_PcbTextSize );
                    textPcb->SetThickness( dsnSettings.m_PcbTextWidth );
                    textPcb->SetTextPosition( wxPoint( cursorPos.x, cursorPos.y ) );

                    RunMainStack( [&]() {
                        getEditFrame<PCB_EDIT_FRAME>()->InstallTextPCBOptionsFrame( textPcb, NULL );
                    } );

                    if( textPcb->GetText().IsEmpty() )
                        delete textPcb;
                    else
                        text = textPcb;
                }

                if( text == NULL )
                    continue;

                m_controls->CaptureCursor( true );
                m_controls->SetAutoPan( true );
                //m_controls->ShowCursor( false );

                preview.Add( text );
            }
            else
            {
                //assert( text->GetText().Length() > 0 );
                //assert( text->GetSize().x > 0 && text->GetSize().y > 0 );

                text->ClearFlags();
                preview.Remove( text );

                commit.Add( text );
                commit.Push( _( "Place a text" ) );

                m_controls->CaptureCursor( false );
                m_controls->SetAutoPan( false );
                m_controls->ShowCursor( true );

                text = NULL;
            }
        }

        else if( text && evt->IsMotion() )
        {
            text->SetPosition( wxPoint( cursorPos.x, cursorPos.y ) );

            // Show a preview of the item
            m_view->Update( &preview );
        }
    }

    m_controls->ShowCursor( false );
    m_controls->SetSnapping( false );
    m_controls->SetAutoPan( false );
    m_controls->CaptureCursor( false );

    m_view->Remove( &preview );
    m_frame->SetToolID( ID_NO_TOOL_SELECTED, wxCURSOR_DEFAULT, wxEmptyString );

    return 0;

}