예제 #1
0
void PCB_LAYER_WIDGET::SyncLayerAlphaIndicators()
{
    int count = GetLayerRowCount();
    TOOL_MANAGER* mgr = myframe->GetToolManager();
    KIGFX::PCB_PAINTER* painter = static_cast<KIGFX::PCB_PAINTER*>( mgr->GetView()->GetPainter() );
    KIGFX::PCB_RENDER_SETTINGS* settings = painter->GetSettings();

    for( int row = 0; row < count; ++row )
    {
        // this utilizes more implementation knowledge than ideal, eventually
        // add member ROW getRow() or similar to base LAYER_WIDGET.

        wxWindow* w = getLayerComp( row, COLUMN_ICON_ACTIVE );
        PCB_LAYER_ID layerId = ToLAYER_ID( getDecodedId( w->GetId() ) );
        KIGFX::COLOR4D screenColor = settings->GetLayerColor( layerId );

        COLOR_SWATCH* swatch = static_cast<COLOR_SWATCH*>( getLayerComp( row, COLUMN_COLORBM ) );
        KIGFX::COLOR4D layerColor = swatch->GetSwatchColor();

        INDICATOR_ICON* indicator = static_cast<INDICATOR_ICON*>( getLayerComp( row, COLUMN_ALPHA_INDICATOR ) );

        if( std::abs( screenColor.a - layerColor.a ) > ALPHA_EPSILON )
        {
            if( screenColor.a < layerColor.a )
                indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::DOWN );
            else
                indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::UP );
        }
        else
            indicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF );
    }
}
예제 #2
0
void LAYER_WIDGET::SelectLayerRow( int aRow )
{
    // enable the layer tab at index 0
    m_notebook->SetSelection( 0 );

    INDICATOR_ICON* oldIndicator = (INDICATOR_ICON*) getLayerComp( m_CurrentRow, 0 );
    if( oldIndicator )
        oldIndicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::OFF );

    INDICATOR_ICON* newIndicator = (INDICATOR_ICON*) getLayerComp( aRow, 0 );
    if( newIndicator )
    {
        newIndicator->SetIndicatorState( ROW_ICON_PROVIDER::STATE::ON );

        // Make sure the desired layer row is visible.
        // It seems that as of 2.8.2, setting the focus does this.
        // I don't expect the scrolling to be needed at all because
        // the minimum window size may end up being established so that the
        // scroll bars will not be visible.
        getLayerComp( aRow, 1 )->SetFocus();
    }

    m_CurrentRow = aRow;

    // give the focus back to the app.
    passOnFocus();
}
void PCB_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
{
    int     rowCount;
    int     menuId = event.GetId();
    bool    visible;
    bool    force_active_layer_visible;

    visible = menuId == ID_SHOW_ALL_COPPERS;
    m_alwaysShowActiveCopperLayer = ( menuId == ID_ALWAYS_SHOW_NO_COPPERS_BUT_ACTIVE );
    force_active_layer_visible = ( menuId == ID_SHOW_NO_COPPERS_BUT_ACTIVE ||
                                   menuId == ID_ALWAYS_SHOW_NO_COPPERS_BUT_ACTIVE );

    switch( menuId )
    {
    case ID_SHOW_ALL_COPPERS:
    case ID_ALWAYS_SHOW_NO_COPPERS_BUT_ACTIVE:
    case ID_SHOW_NO_COPPERS_BUT_ACTIVE:
    case ID_SHOW_NO_COPPERS:
        // Search the last copper layer row index:
        int lastCu = -1;
        rowCount = GetLayerRowCount();
        for( int row = rowCount-1; row>=0; --row )
        {
            wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
            LAYER_ID    layer = ToLAYER_ID( getDecodedId( cb->GetId() ) );

            if( IsCopperLayer( layer ) )
            {
                lastCu = row;
                break;
            }
        }

        // Enable/disable the copper layers visibility:
        for( int row=0;  row<rowCount;  ++row )
        {
            wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
            LAYER_ID    layer = ToLAYER_ID( getDecodedId( cb->GetId() ) );

            if( IsCopperLayer( layer ) )
            {
                bool loc_visible = visible;

                if( force_active_layer_visible && (layer == myframe->GetActiveLayer() ) )
                    loc_visible = true;

                cb->SetValue( loc_visible );

                bool isLastCopperLayer = (row==lastCu);
                OnLayerVisible( layer, loc_visible, isLastCopperLayer );

                if( isLastCopperLayer )
                    break;
            }
        }
        break;
    }
}
void PCB_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
{
    int     rowCount;
    int     menuId = event.GetId();
    bool    visible;

    switch( menuId )
    {
    case ID_SHOW_ALL_COPPERS:
        visible = true;
        goto L_change_coppers;

    case ID_SHOW_NO_COPPERS_BUT_ACTIVE:
    case ID_SHOW_NO_COPPERS:
        visible = false;
    L_change_coppers:
        int lastCu = -1;
        rowCount = GetLayerRowCount();
        for( int row=rowCount-1;  row>=0;  --row )
        {
            wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, 3 );
            int layer = getDecodedId( cb->GetId() );
            if( IsValidCopperLayerIndex( layer ) )
            {
                lastCu = row;
                break;
            }
        }

        for( int row=0;  row<rowCount;  ++row )
        {
            wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, 3 );
            int layer = getDecodedId( cb->GetId() );

            if( IsValidCopperLayerIndex( layer ) )
            {
                bool loc_visible = visible;
                if( (menuId == ID_SHOW_NO_COPPERS_BUT_ACTIVE ) &&
                    (layer == myframe->getActiveLayer() ) )
                    loc_visible = true;

                cb->SetValue( loc_visible );

                bool isLastCopperLayer = (row==lastCu);

                OnLayerVisible( layer, loc_visible, isLastCopperLayer );

                if( isLastCopperLayer )
                    break;
            }
        }
        break;
    }
}
예제 #5
0
LAYER_NUM LAYER_WIDGET::GetSelectedLayer()
{
    wxWindow* w = getLayerComp( m_CurrentRow, 0 );
    if( w )
        return getDecodedId( w->GetId() );

    return UNDEFINED_LAYER;
}
예제 #6
0
void LAYER_WIDGET::SetLayerVisible( LAYER_NUM aLayer, bool isVisible )
{
    int row = findLayerRow( aLayer );
    if( row >= 0 )
    {
        wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
        wxASSERT( cb );
        cb->SetValue( isVisible );      // does not fire an event
    }
}
예제 #7
0
bool LAYER_WIDGET::IsLayerVisible( LAYER_NUM aLayer )
{
    int row = findLayerRow( aLayer );
    if( row >= 0 )
    {
        wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
        wxASSERT( cb );
        return cb->GetValue();
    }
    return false;
}
예제 #8
0
void LAYER_WIDGET::SetLayerColor( LAYER_NUM aLayer, COLOR4D aColor )
{
    int row = findLayerRow( aLayer );
    if( row >= 0 )
    {
        int col = 1;    // bitmap button is column 1
        auto swatch = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
        wxASSERT( swatch );

        swatch->SetSwatchColor( aColor, false );
    }
}
void PCB_LAYER_WIDGET::installRightLayerClickHandler()
{
    int rowCount = GetLayerRowCount();
    for( int row=0; row < rowCount; ++row )
    {
        for( int col=0; col<LYR_COLUMN_COUNT; ++col )
        {
            wxWindow* w = getLayerComp( row, col );

            w->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(
                PCB_LAYER_WIDGET::onRightDownLayers ), NULL, this );
        }
    }
}
예제 #10
0
COLOR4D LAYER_WIDGET::GetLayerColor( LAYER_NUM aLayer ) const
{
    int row = findLayerRow( aLayer );
    if( row >= 0 )
    {
        int col = 1;    // bitmap button is column 1
        auto swatch = static_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
        wxASSERT( swatch );

        return swatch->GetSwatchColor();
    }

    return COLOR4D::UNSPECIFIED;   // it's caller fault, gave me a bad layer
}
void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
{
    int  rowCount;
    int  menuId = event.GetId();
    bool visible = (menuId == ID_SHOW_ALL_LAYERS) ? true : false;
    long visibleLayers = 0;
    bool force_active_layer_visible;

    switch( menuId )
    {
    case ID_SHOW_ALL_LAYERS:
    case ID_SHOW_NO_LAYERS:
    case ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE:
    case ID_SHOW_NO_LAYERS_BUT_ACTIVE:
        // Set the display layers options. Sorting layers has no effect to these options
        m_alwaysShowActiveLayer = ( menuId == ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE );
        force_active_layer_visible = ( menuId == ID_SHOW_NO_LAYERS_BUT_ACTIVE ||
                                       menuId == ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE );
        // Update icons and check boxes
        rowCount = GetLayerRowCount();
        for( int row=0; row < rowCount; ++row )
        {
            wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
            int layer = getDecodedId( cb->GetId() );
            bool loc_visible = visible;

            if( force_active_layer_visible &&
                (layer == myframe->GetActiveLayer() ) )
            {
                loc_visible = true;
            }

            cb->SetValue( loc_visible );

            if( loc_visible )
                visibleLayers |= 1 << row;
            else
                visibleLayers &= ~( 1 << row );
        }

        myframe->SetVisibleLayers( visibleLayers );
        myframe->GetCanvas()->Refresh();
        break;

    case ID_SORT_GBR_LAYERS:
        myframe->SortLayersByX2Attributes();
        break;
    }
}
void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
{
    int  rowCount;
    int  menuId = event.GetId();
    bool visible = (menuId == ID_SHOW_ALL_LAYERS) ? true : false;
    long visibleLayers = 0;
    bool force_active_layer_visible;

    m_alwaysShowActiveLayer = ( menuId == ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE );
    force_active_layer_visible = ( menuId == ID_SHOW_NO_LAYERS_BUT_ACTIVE ||
                                   menuId == ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE );

    switch( menuId )
    {
    case ID_SHOW_ALL_LAYERS:
    case ID_SHOW_NO_LAYERS:
    case ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE:
    case ID_SHOW_NO_LAYERS_BUT_ACTIVE:
        rowCount = GetLayerRowCount();
        for( int row=0; row < rowCount; ++row )
        {
            wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
            int layer = getDecodedId( cb->GetId() );
            bool loc_visible = visible;

            if( force_active_layer_visible && (layer == myframe->getActiveLayer() ) )
                loc_visible = true;

            cb->SetValue( loc_visible );

            if( loc_visible )
                visibleLayers |= 1 << row;
            else
                visibleLayers &= ~( 1 << row );
        }

        myframe->SetVisibleLayers( visibleLayers );
        myframe->GetCanvas()->Refresh();
        break;

    case ID_SORT_GBR_LAYERS:
        g_GERBER_List.SortImagesByZOrder( myframe->GetItemsList() );
        myframe->ReFillLayerWidget();
        myframe->syncLayerBox( true );
        myframe->GetCanvas()->Refresh();
        break;
    }
}
예제 #13
0
int LAYER_WIDGET::findLayerRow( LAYER_NUM aLayer ) const
{
    int count = GetLayerRowCount();

    for( int row = 0; row < count; ++row )
    {
        // column 0 in the layer scroll window has a wxStaticBitmap, get its ID.
        wxWindow* w = getLayerComp( row, 0 );
        wxASSERT( w );

        if( aLayer == getDecodedId( w->GetId() ))
            return row;
    }

    return -1;
}
예제 #14
0
void LAYER_WIDGET::UpdateLayerIcons()
{
    int rowCount = GetLayerRowCount();

    for( int row = 0; row < rowCount ; row++ )
    {
        INDICATOR_ICON* indicator = (INDICATOR_ICON*) getLayerComp( row, COLUMN_ICON_ACTIVE );

        if( indicator )
        {
            auto state = ( row == m_CurrentRow ) ? ROW_ICON_PROVIDER::STATE::ON
                                                 : ROW_ICON_PROVIDER::STATE::OFF;
            indicator->SetIndicatorState( state );
        }
    }
}
/*
 * Update the layer manager icons (layers only)
 * Useful when loading a file or clearing a layer because they change
 */
void GERBER_LAYER_WIDGET::UpdateLayerIcons()
{
    int row_count = GetLayerRowCount();
    for( int row = 0; row < row_count ; row++ )
    {
        wxStaticBitmap* bm = (wxStaticBitmap*) getLayerComp( row, COLUMN_ICON_ACTIVE );
        if( bm == NULL)
            continue;

        if( row == m_CurrentRow )
            bm->SetBitmap( useAlternateBitmap(row) ? *m_RightArrowAlternateBitmap :
                           *m_RightArrowBitmap );
        else
            bm->SetBitmap( useAlternateBitmap(row) ? *m_BlankAlternateBitmap : *m_BlankBitmap );
    }
}
예제 #16
0
void LAYER_WIDGET::OnLeftDownLayers( wxMouseEvent& event )
{
    int row;
    LAYER_NUM layer;

    wxWindow* eventSource = (wxWindow*) event.GetEventObject();

    // if mouse event is coming from the m_LayerScrolledWindow and not one
    // of its children, we have to find the row manually based on y coord.
    if( eventSource == m_LayerScrolledWindow )
    {
        int y = event.GetY();

        wxArrayInt heights = m_LayersFlexGridSizer->GetRowHeights();

        int height = 0;

        int rowCount = GetLayerRowCount();
        for( row = 0;  row<rowCount;  ++row )
        {
            if( y < height + heights[row] )
                break;

            height += heights[row];
        }

        if( row >= rowCount )
            row = rowCount - 1;

        layer = getDecodedId( getLayerComp( row, 0 )->GetId() );
    }

    else
    {
        // all nested controls on a given row will have their ID encoded with
        // encodeId(), and the corresponding decoding is getDecodedId()
        int id = eventSource->GetId();
        layer  = getDecodedId( id );
        row    = findLayerRow( layer );
    }

    if( OnLayerSelect( layer ) )    // if client allows this change.
        SelectLayerRow( row );

    passOnFocus();
}
void PCB_LAYER_WIDGET::SyncLayerVisibilities()
{
    BOARD*  board = myframe->GetBoard();
    int     count = GetLayerRowCount();

    for( int row=0;  row<count;  ++row )
    {
        // this utilizes more implementation knowledge than ideal, eventually
        // add member ROW getRow() or similar to base LAYER_WIDGET.

        wxWindow* w = getLayerComp( row, COLUMN_ICON_ACTIVE );

        LAYER_ID layerId = ToLAYER_ID( getDecodedId( w->GetId() ) );

        // this does not fire a UI event
        SetLayerVisible( layerId, board->IsLayerVisible( layerId ) );
    }
}
예제 #18
0
void LAYER_WIDGET::OnRenderSwatchChanged( wxCommandEvent& aEvent )
{
    auto eventSource = static_cast<COLOR_SWATCH*>( aEvent.GetEventObject() );

    COLOR4D newColor = eventSource->GetSwatchColor();

    LAYER_NUM id = getDecodedId( eventSource->GetId() );

    if( id == LAYER_PCB_BACKGROUND )
    {
        // Update all swatch backgrounds
        int count = GetLayerRowCount();
        int row;
        int col = 1;    // bitmap button is column 1 in layers tab
        for( row = 0; row < count; ++row )
        {
            COLOR_SWATCH* swatch = dynamic_cast<COLOR_SWATCH*>( getLayerComp( row, col ) );
            if( swatch )
                swatch->SetSwatchBackground( newColor );
        }

        count = GetRenderRowCount();
        col = 0;    // bitmap button is column 0 in render tab
        for( row = 0; row < count; ++row )
        {
            COLOR_SWATCH* swatch = dynamic_cast<COLOR_SWATCH*>( getRenderComp( row, col ) );
            if( swatch )
                swatch->SetSwatchBackground( newColor );
        }
    }

    // tell the client code.
    OnRenderColorChange( id, newColor );

    passOnFocus();
}
예제 #19
0
void PCB_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
{
    int     rowCount;
    int     menuId = event.GetId();
    bool    visible;
    bool    force_active_layer_visible;

    m_alwaysShowActiveCopperLayer = ( menuId == ID_ALWAYS_SHOW_NO_COPPER_LAYERS_BUT_ACTIVE );
    force_active_layer_visible = ( menuId == ID_SHOW_NO_COPPER_LAYERS_BUT_ACTIVE ||
            menuId == ID_ALWAYS_SHOW_NO_COPPER_LAYERS_BUT_ACTIVE );

    switch( menuId )
    {
        case ID_SHOW_NO_LAYERS:
        case ID_SHOW_ALL_LAYERS:
            {
                visible = ( menuId == ID_SHOW_ALL_LAYERS );
                rowCount = GetLayerRowCount();

                for( int row=0;  row<rowCount;  ++row )
                {
                    bool isLast;
                    wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
                    PCB_LAYER_ID    layer = ToLAYER_ID( getDecodedId( cb->GetId() ) );
                    cb->SetValue( visible );

                    isLast = row == rowCount-1;

                    OnLayerVisible( layer, visible, isLast );

                    if( isLast )
                        break;
                }
                break;
            }

        case ID_SHOW_ALL_COPPER_LAYERS:
        case ID_ALWAYS_SHOW_NO_COPPER_LAYERS_BUT_ACTIVE:
        case ID_SHOW_NO_COPPER_LAYERS_BUT_ACTIVE:
        case ID_SHOW_NO_COPPER_LAYERS:
        case ID_HIDE_ALL_NON_COPPER:
        case ID_SHOW_ALL_NON_COPPER:
            {

                // Search the last copper layer row index:
                int lastCu = -1;
                rowCount = GetLayerRowCount();
                for( int row = rowCount-1; row>=0; --row )
                {
                    wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
                    PCB_LAYER_ID    layer = ToLAYER_ID( getDecodedId( cb->GetId() ) );

                    if( IsCopperLayer( layer ) )
                    {
                        lastCu = row;
                        break;
                    }
                }

                // Enable/disable the copper layers visibility:
                int startrow = 0;

                if(     ( menuId == ID_SHOW_ALL_NON_COPPER ) ||
                        ( menuId == ID_HIDE_ALL_NON_COPPER ) )
                {
                    startrow = lastCu + 1;
                }

                for( int row = startrow;  row<rowCount;  ++row )
                {
                    wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
                    PCB_LAYER_ID    layer = ToLAYER_ID( getDecodedId( cb->GetId() ) );

                    visible = ( ( menuId == ID_SHOW_ALL_COPPER_LAYERS ) || ( menuId == ID_SHOW_ALL_NON_COPPER ) );

                    if( force_active_layer_visible && (layer == myframe->GetActiveLayer() ) )
                        visible = true;

                    cb->SetValue( visible );

                    bool isLastLayer = (row == lastCu);

                    if(     ( menuId == ID_SHOW_ALL_NON_COPPER ) ||
                            ( menuId == ID_HIDE_ALL_NON_COPPER ) )
                    {
                        isLastLayer = false;
                    }
                    OnLayerVisible( layer, visible, isLastLayer );

                    if( isLastLayer )
                        break;
                }
                break;
            }

        case ID_SHOW_ALL_FRONT:
            {
                visible = false;
                rowCount = GetLayerRowCount();

                for( int row=0;  row<rowCount;  ++row )
                {
                    bool isLast;
                    wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
                    PCB_LAYER_ID    layer = ToLAYER_ID( getDecodedId( cb->GetId() ) );
                    isLast = ( row == rowCount-1 );

                    if(  layer == F_Paste || layer == F_SilkS ||
                         layer == F_Mask  || layer == F_Cu ||
                         layer == F_Fab || layer == F_CrtYd  || layer == Edge_Cuts )
                    {
                        visible = true;
                    }
                    else
                    {
                        visible = false;
                    }

                    cb->SetValue( visible );
                    OnLayerVisible( layer, visible, isLast );

                    if( isLast )
                        break;
                }
                break;
            }
        case ID_SHOW_ALL_BACK:
            {
                visible = false;
                rowCount = GetLayerRowCount();

                for( int row=0;  row<rowCount;  ++row )
                {
                    bool isLast;
                    wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
                    PCB_LAYER_ID    layer = ToLAYER_ID( getDecodedId( cb->GetId() ) );
                    isLast = ( row == rowCount-1 );

                    if( layer == B_Paste || layer == B_SilkS ||
                        layer == B_Mask  || layer == B_Cu ||
                        layer == B_Fab || layer == B_CrtYd || layer == Edge_Cuts )
                    {
                        visible = true;
                    }
                    else
                    {
                        visible = false;
                    }

                    cb->SetValue( visible );
                    OnLayerVisible( layer, visible, isLast );

                    if( isLast )
                        break;
                }
                break;
            }
    }
}
예제 #20
0
void PCB_LAYER_WIDGET::ReFill()
{
    BOARD*  brd = myframe->GetBoard();
    LSET    enabled = brd->GetEnabledLayers();

    ClearLayerRows();

    wxString dsc;

    // show all coppers first, with front on top, back on bottom, then technical layers
    for( LSEQ cu_stack = enabled.CuStack(); cu_stack; ++cu_stack )
    {
        PCB_LAYER_ID layer = *cu_stack;

        switch( layer )
        {
        case F_Cu:
            dsc = _( "Front copper layer" );
            break;

        case B_Cu:
            dsc = _( "Back copper layer" );
            break;

        default:
            dsc = _( "Inner copper layer" );
            break;
        }

        AppendLayerRow( LAYER_WIDGET::ROW(
            brd->GetLayerName( layer ), layer, myframe->Settings().Colors().GetLayerColor( layer ),
            dsc, true ) );

        if( m_fp_editor_mode && LSET::ForbiddenFootprintLayers().test( layer ) )
        {
            getLayerComp( GetLayerRowCount()-1, COLUMN_COLOR_LYRNAME )->Enable( false );
            getLayerComp( GetLayerRowCount()-1, COLUMN_COLORBM )->SetToolTip( wxEmptyString );
        }
    }

    UpdateLayouts();


    // technical layers are shown in this order:
    // Because they are static, wxGetTranslation must be explicitly
    // called for tooltips.
    static const struct {
        PCB_LAYER_ID    layerId;
        wxString    tooltip;
    } non_cu_seq[] = {
        { F_Adhes,          _( "Adhesive on board's front" ) },
        { B_Adhes,          _( "Adhesive on board's back" ) },
        { F_Paste,          _( "Solder paste on board's front" )  },
        { B_Paste,          _( "Solder paste on board's back" ) },
        { F_SilkS,          _( "Silkscreen on board's front" ) },
        { B_SilkS,          _( "Silkscreen on board's back" )  },
        { F_Mask,           _( "Solder mask on board's front" ) },
        { B_Mask,           _( "Solder mask on board's back" )  },
        { Dwgs_User,        _( "Explanatory drawings" )      },
        { Cmts_User,        _( "Explanatory comments" )         },
        { Eco1_User,        _( "User defined meaning" )         },
        { Eco2_User,        _( "User defined meaning" )         },
        { Edge_Cuts,        _( "Board's perimeter definition" ) },
        { Margin,           _( "Board's edge setback outline" ) },
        { F_CrtYd,          _( "Footprint courtyards on board's front" ) },
        { B_CrtYd,          _( "Footprint courtyards on board's back" ) },
        { F_Fab,            _( "Footprint assembly on board's front" ) },
        { B_Fab,            _( "Footprint assembly on board's back" ) }
    };

    for( unsigned i=0;  i<arrayDim( non_cu_seq );  ++i )
    {
        PCB_LAYER_ID layer = non_cu_seq[i].layerId;

        if( !enabled[layer] )
            continue;

        AppendLayerRow( LAYER_WIDGET::ROW(
            brd->GetLayerName( layer ), layer,  myframe->Settings().Colors().GetLayerColor( layer ),
            wxGetTranslation( non_cu_seq[i].tooltip ), true ) );

        if( m_fp_editor_mode && LSET::ForbiddenFootprintLayers().test( layer ) )
        {
            getLayerComp( GetLayerRowCount()-1, COLUMN_COLOR_LYRNAME )->Enable( false );
            getLayerComp( GetLayerRowCount()-1, COLUMN_COLORBM )->SetToolTip( wxEmptyString );
        }
    }
}