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;
}
Beispiel #2
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 );
    }
}
Beispiel #3
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;
}
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 #5
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;

}