Commit b762f6aa authored by stambaughw's avatar stambaughw
Browse files

Component library editor improvements.

* Eliminate external direct manipulation of component draw item pointer.
* Add draw item remove, add, and locate methods to library component object.
* Remove redundant locate pin, field, and draw item code.
* Fix add new pin drawing bug that left initial pin draw in place.
* Improved best zoom calculations for small components.
* Library component bounding box calculation now includes fields.
* Removed unnecessary header file "libcmp.h".
* Fixed potential locate draw item bug in library editor hot key handler.
parent d1e137d6
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -13,7 +13,6 @@

#include "program.h"
#include "general.h"
#include "libcmp.h"
#include "protos.h"

/* Constructor and destructor for SCH_ITEM */
+11 −15
Original line number Diff line number Diff line
@@ -861,51 +861,47 @@ static LIB_DRAW_ITEM* GetNextPinPosition( SCH_COMPONENT* aDrawLibItem,
 */
{
    LIB_COMPONENT* Entry;
    static LIB_DRAW_ITEM* NextItem;
    static LibDrawPin* NextPin;
    static int Multi, convert, TransMat[2][2];
    LIB_DRAW_ITEM* DEntry;
    int orient;
    LibDrawPin* Pin;
    static wxPoint CmpPosition;

    if( aDrawLibItem )
    {
        NextItem = NULL;
        NextPin = NULL;
        Entry = CMP_LIBRARY::FindLibraryComponent( aDrawLibItem->m_ChipName );

        if( Entry == NULL )
            return NULL;

        DEntry      = Entry->m_Drawings;
        Pin         = Entry->GetNextPin();
        Multi       = aDrawLibItem->m_Multi;
        convert     = aDrawLibItem->m_Convert;
        CmpPosition = aDrawLibItem->m_Pos;
        memcpy( TransMat, aDrawLibItem->m_Transform, sizeof(TransMat) );
    }
    else
        DEntry = NextItem;
        Pin = NextPin;

    for( ; DEntry != NULL; DEntry = DEntry->Next() )
    for( ; Pin != NULL; NextPin = Entry->GetNextPin( Pin ) )
    {
        wxASSERT( Pin->Type() == COMPONENT_PIN_DRAW_TYPE );

        /* Elimination des elements non relatifs a l'unite */
        if( Multi && DEntry->m_Unit && (DEntry->m_Unit != Multi) )
            continue;
        if( convert && DEntry->m_Convert && (DEntry->m_Convert != convert) )
        if( Multi && Pin->m_Unit && ( Pin->m_Unit != Multi ) )
            continue;
        if( DEntry->Type() != COMPONENT_PIN_DRAW_TYPE )
        if( convert && Pin->m_Convert && ( Pin->m_Convert != convert ) )
            continue;

        Pin = (LibDrawPin*) DEntry;

        /* Calcul de l'orientation reelle de la Pin */
        orient = Pin->ReturnPinDrawOrient( TransMat );

        /* Calcul de la position du point de reference */
        aPosition = TransformCoordinate( TransMat, Pin->m_Pos ) + CmpPosition;
        NextItem  = DEntry->Next();
        return DEntry;
        return Pin;
    }

    NextItem = NULL;
    NextPin = NULL;
    return NULL;
}
+14 −95
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@

static void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC,
                                     bool erase );
static void MirrorMarkedItems( LIB_COMPONENT* LibEntry, wxPoint offset );


/*
@@ -77,6 +76,7 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
{
    int ItemCount = 0;
    int MustDoPlace = 0;
    wxPoint pt;

    if( GetScreen()->m_BlockLocate.GetCount() )
    {
@@ -147,7 +147,9 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
                                              g_EditPinByPinIsOn );
        if( ItemCount )
            SaveCopyInUndoList( m_component );
        MirrorMarkedItems( m_component, GetScreen()->m_BlockLocate.Centre() );
        pt = GetScreen()->m_BlockLocate.Centre();
        pt.y *= -1;
        m_component->MirrorSelectedItemsH( pt );
        break;

    case BLOCK_ZOOM:     /* Window Zoom */
@@ -191,7 +193,7 @@ int WinEDA_LibeditFrame::HandleBlockEnd( wxDC* DC )
void WinEDA_LibeditFrame::HandleBlockPlace( wxDC* DC )
{
    bool err = FALSE;
    wxPoint offset;
    wxPoint pt;

    if( DrawPanel->ManageCurseur == NULL )
    {
@@ -212,18 +214,18 @@ void WinEDA_LibeditFrame::HandleBlockPlace( wxDC* DC )
    case BLOCK_PRESELECT_MOVE:      /* Move with preselection list*/
        GetScreen()->m_BlockLocate.ClearItemsList();
        SaveCopyInUndoList( m_component );
        offset = GetScreen()->m_BlockLocate.m_MoveVector;
        offset.y *= -1;
        m_component->MoveSelectedItems( offset );
        pt = GetScreen()->m_BlockLocate.m_MoveVector;
        pt.y *= -1;
        m_component->MoveSelectedItems( pt );
        DrawPanel->Refresh( TRUE );
        break;

    case BLOCK_COPY:     /* Copy */
        GetScreen()->m_BlockLocate.ClearItemsList();
        SaveCopyInUndoList( m_component );
        offset = GetScreen()->m_BlockLocate.m_MoveVector;
        offset.y *= -1;
        m_component->CopySelectedItems( offset );
        pt = GetScreen()->m_BlockLocate.m_MoveVector;
        pt.y *= -1;
        m_component->CopySelectedItems( pt );
        break;

    case BLOCK_PASTE:     /* Paste (recopie du dernier bloc sauve */
@@ -232,7 +234,9 @@ void WinEDA_LibeditFrame::HandleBlockPlace( wxDC* DC )

    case BLOCK_MIRROR_Y:      /* Invert by popup menu, from block move */
        SaveCopyInUndoList( m_component );
        MirrorMarkedItems( m_component, GetScreen()->m_BlockLocate.Centre() );
        pt = GetScreen()->m_BlockLocate.Centre();
        pt.y *= -1;
        m_component->MirrorSelectedItemsH( pt );
        break;

    case BLOCK_ZOOM:        // Handled by HandleBlockEnd
@@ -305,88 +309,3 @@ void DrawMovingBlockOutlines( WinEDA_DrawPanel* panel, wxDC* DC, bool erase )
                     g_XorMode, -1, DefaultTransformMatrix,
                     true, true, true );
}


/*
 * Mirror marked items, refer to a Vertical axis at position offset
 */
void MirrorMarkedItems( LIB_COMPONENT* LibEntry, wxPoint offset )
{
#define SETMIRROR( z ) (z) -= offset.x; (z) = -(z); (z) += offset.x;
    LIB_DRAW_ITEM* item;

    if( LibEntry == NULL )
        return;

    offset.y = -offset.y;  // Y axis for lib items is Down to Up: reverse y offset value
    item = LibEntry->m_Drawings;
    for( ; item != NULL; item = item->Next() )
    {
        if( item->m_Selected == 0 )
            continue;

        switch( item->Type() )
        {
        case COMPONENT_PIN_DRAW_TYPE:
            SETMIRROR( ( (LibDrawPin*) item )->m_Pos.x );

            switch( ( (LibDrawPin*) item )->m_Orient )
            {
            case PIN_RIGHT:
                ( (LibDrawPin*) item )->m_Orient = PIN_LEFT;
                break;

            case PIN_LEFT:
                ( (LibDrawPin*) item )->m_Orient = PIN_RIGHT;
                break;

            case PIN_UP:
            case PIN_DOWN:
                break;
            }

            break;

        case COMPONENT_ARC_DRAW_TYPE:
        {
            SETMIRROR( ( (LibDrawArc*) item )->m_Pos.x );
            SETMIRROR( ( (LibDrawArc*) item )->m_ArcStart.x );
            SETMIRROR( ( (LibDrawArc*) item )->m_ArcEnd.x );
            EXCHG( ( (LibDrawArc*) item )->m_ArcStart,
                   ( (LibDrawArc*) item )->m_ArcEnd );
            break;
        }

        case COMPONENT_CIRCLE_DRAW_TYPE:
            SETMIRROR( ( (LibDrawCircle*) item )->m_Pos.x );
            break;

        case COMPONENT_RECT_DRAW_TYPE:
            SETMIRROR( ( (LibDrawSquare*) item )->m_Pos.x );
            SETMIRROR( ( (LibDrawSquare*) item )->m_End.x );
            break;

        case COMPONENT_POLYLINE_DRAW_TYPE:
        {
            unsigned ii, imax = ( (LibDrawPolyline*) item )->GetCornerCount();
            for( ii = 0; ii < imax; ii ++ )
            {
                SETMIRROR( ( (LibDrawPolyline*) item )->m_PolyPoints[ii].x );
            }
        }
            break;

        case COMPONENT_LINE_DRAW_TYPE:
            break;

        case COMPONENT_GRAPHIC_TEXT_DRAW_TYPE:
            SETMIRROR( ( (LibDrawText*) item )->m_Pos.x );
            break;

        default:
            break;
        }

        item->m_Flags = item->m_Selected = 0;
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -226,6 +226,14 @@ void LibDrawText::DoMove( const wxPoint& newPosition )
}


void LibDrawText::DoMirrorHorizontal( const wxPoint& center )
{
    m_Pos.x -= center.x;
    m_Pos.x *= -1;
    m_Pos.x += center.x;
}


/** Function GetPenSize
 * @return the size of the "pen" that be used to draw or plot this item
 */
+177 −26
Original line number Diff line number Diff line
@@ -326,7 +326,6 @@ LIB_COMPONENT::LIB_COMPONENT( const LIB_COMPONENT& component,
    LibDrawField*  oldField;
    LibDrawField*  newField;


    m_Prefix              = component.m_Prefix;
    m_AliasList           = component.m_AliasList;
    m_FootprintList       = component.m_FootprintList;
@@ -336,6 +335,7 @@ LIB_COMPONENT::LIB_COMPONENT( const LIB_COMPONENT& component,
    m_DrawPinNum          = component.m_DrawPinNum;
    m_DrawPinName         = component.m_DrawPinName;
    m_LastDate            = component.m_LastDate;
    m_Drawings            = NULL;

    m_Prefix.SetParent( this );

@@ -505,6 +505,8 @@ void LIB_COMPONENT::RemoveDrawItem( LIB_DRAW_ITEM* item,
        item->Draw( panel, dc, wxPoint( 0, 0 ), -1, g_XorMode, NULL,
                    DefaultTransformMatrix );

    if( item->Type() != COMPONENT_FIELD_DRAW_TYPE )
    {
        if( m_Drawings == item )
        {
            m_Drawings = item->Next();
@@ -524,6 +526,63 @@ void LIB_COMPONENT::RemoveDrawItem( LIB_DRAW_ITEM* item,
            prevItem = prevItem->Next();
        }
    }
    else
    {
        LibDrawField* field;

        for( field = m_Fields; field != NULL; field = field->Next() )
        {
            if( field == item )
            {
                m_Fields.Remove( field );
                delete field;
                break;
            }
        }
    }
}


void LIB_COMPONENT::AddDrawItem( LIB_DRAW_ITEM* item )
{
    wxASSERT( item != NULL );

    if( m_Drawings == NULL )
    {
        m_Drawings = item;
        item->SetNext( NULL );
        return;
    }

    LIB_DRAW_ITEM* i = m_Drawings;

    while(  i->Next() != NULL )
        i = i->Next();

    i->SetNext( item );
    item->SetNext( NULL );
    SortDrawItems();
}


LIB_DRAW_ITEM* LIB_COMPONENT::GetNextDrawItem( LIB_DRAW_ITEM* item,
                                               KICAD_T type )
{
    if( type == TYPE_NOT_INIT )
        return ( item == NULL ) ? m_Drawings : item->Next();

    LIB_DRAW_ITEM* i = ( item == NULL ) ? m_Drawings : item->Next();

    while( i != NULL )
    {
        if( i->Type() == type )
            return i;

        i = i->Next();
    }

    return i;
}


/**
@@ -940,7 +999,7 @@ void LIB_COMPONENT::SortDrawItems()

    if( Entry == NULL )
        return; /* Pas d'alias pour ce composant */
    /* calcul du nombre d'items */

    for( nbitems = 0; Entry != NULL; Entry = Entry->Next() )
        nbitems++;

@@ -978,23 +1037,25 @@ void LIB_COMPONENT::SortDrawItems()
/**********************************************************************/
EDA_Rect LIB_COMPONENT::GetBoundaryBox( int Unit, int Convert )
{
    LIB_DRAW_ITEM* DrawEntry;
    LIB_DRAW_ITEM* item;
    EDA_Rect       bBox( wxPoint( 0, 0 ), wxSize( 0, 0 ) );

    for( DrawEntry = m_Drawings; DrawEntry != NULL;
         DrawEntry = DrawEntry->Next() )
    for( item = m_Drawings; item != NULL; item = item->Next() )
    {
        if( DrawEntry->m_Unit > 0 )  // The item is non common to units
            if( ( m_UnitCount > 1 ) && ( Unit > 0 )
                && ( Unit != DrawEntry->m_Unit ) )
        if( ( item->m_Unit > 0 )
            && ( ( m_UnitCount > 1 ) && ( Unit > 0 )
                 && ( Unit != item->m_Unit ) ) )
            continue;
        if( DrawEntry->m_Convert > 0 )  // The item is not common to all convert
            if( ( Convert > 0 ) && ( Convert != DrawEntry->m_Convert ) )
        if( item->m_Convert > 0
            && ( ( Convert > 0 ) && ( Convert != item->m_Convert ) ) )
            continue;

        bBox.Merge( DrawEntry->GetBoundingBox() );
        bBox.Merge( item->GetBoundingBox() );
    }

    bBox.Merge( m_Name.GetBoundingBox() );
    bBox.Merge( m_Prefix.GetBoundingBox() );

    return bBox;
}

@@ -1172,6 +1233,22 @@ bool LIB_COMPONENT::HasConversion() const
}


void LIB_COMPONENT::ClearStatus( void )
{
    LIB_DRAW_ITEM* item;
    LibDrawField* field;

    for( item = m_Drawings; item != NULL; item = item->Next() )
        item->m_Flags = 0;

    m_Name.m_Flags = 0;
    m_Prefix.m_Flags = 0;

    for( field = m_Fields.GetFirst(); field != NULL; field = field->Next() )
        field->m_Flags = 0;
}


int LIB_COMPONENT::SelectItems( EDA_Rect& rect, int unit, int convert,
                                bool editPinByPin )
{
@@ -1318,3 +1395,77 @@ void LIB_COMPONENT::CopySelectedItems( const wxPoint& offset )
    MoveSelectedItems( offset );
    SortDrawItems();
}

void LIB_COMPONENT::MirrorSelectedItemsH( const wxPoint& center )
{
    LIB_DRAW_ITEM* item;
    LibDrawField*  field;

    for( item = m_Drawings; item != NULL; item = item->Next() )
    {
        if( item->m_Selected == 0 )
            continue;

        item->SetOffset( center );
        item->m_Flags = item->m_Selected = 0;
    }

    if( m_Name.m_Selected )
    {
        m_Name.SetOffset( center );
        m_Name.m_Flags = m_Name.m_Selected = 0;
    }

    if( m_Prefix.m_Selected )
    {
        m_Prefix.SetOffset( center );
        m_Prefix.m_Flags = m_Prefix.m_Selected = 0;
    }

    for( field = m_Fields.GetFirst(); field != NULL; field = field->Next() )
    {
        if( field->m_Selected )
        {
            field->SetOffset( center );
            field->m_Flags = field->m_Selected = 0;
        }
    }

    SortDrawItems();
}


LIB_DRAW_ITEM* LIB_COMPONENT::LocateDrawItem( int unit, int convert,
                                              KICAD_T type, const wxPoint& pt )
{
    LIB_DRAW_ITEM* item;
    LibDrawField*  field;

    for( item = m_Drawings; item != NULL; item = item->Next() )
    {
        if( ( unit && item->m_Unit && ( unit != item->m_Unit) )
            || ( convert && item->m_Convert && ( convert != item->m_Convert ) )
            || ( ( item->Type() != type ) && ( type != TYPE_NOT_INIT ) ) )
            continue;

        if( item->HitTest( pt ) )
            return item;
    }

    if( type == COMPONENT_FIELD_DRAW_TYPE || type == TYPE_NOT_INIT )
    {
        if( m_Name.HitTest( pt ) )
            return &m_Name;
        if( m_Prefix.HitTest( pt ) )
            return &m_Prefix;

        for( field = m_Fields.GetFirst(); field != NULL; field = field->Next() )
        {
            if( field->HitTest( pt ) )
                return field;
        }
    }


    return NULL;
}
Loading