Пример #1
0
void EDA_DRAW_FRAME::LoadSettings( wxConfigBase* aCfg )
{
    EDA_BASE_FRAME::LoadSettings( aCfg );

    wxString baseCfgName = ConfigBaseName();

    bool btmp;
    if( aCfg->Read( baseCfgName + ShowGridEntryKeyword, &btmp ) )
        SetGridVisibility( btmp );

    // Read grid color:
    COLOR4D wtmp = COLOR4D::UNSPECIFIED;

    if( wtmp.SetFromWxString( aCfg->Read(
                baseCfgName + GridColorEntryKeyword, wxT( "NONE" ) ) ) )
        SetGridColor( wtmp );

    aCfg->Read( baseCfgName + LastGridSizeIdKeyword, &m_LastGridSizeId, 0L );

    // m_LastGridSizeId is an offset, expected to be >= 0
    if( m_LastGridSizeId < 0 )
        m_LastGridSizeId = 0;

    m_UndoRedoCountMax = aCfg->Read( baseCfgName + MaxUndoItemsEntry,
            long( DEFAULT_MAX_UNDO_ITEMS ) );

    aCfg->Read( baseCfgName + FirstRunShownKeyword, &m_firstRunDialogSetting, 0L );

    m_galDisplayOptions->ReadConfig( aCfg, baseCfgName + GalDisplayOptionsKeyword );
}
Пример #2
0
void LIB_VIEW_FRAME::LoadSettings( wxConfigBase* aCfg )
{
    EDA_DRAW_FRAME::LoadSettings( aCfg );

    // Fetch grid settings from Symbol Editor
    wxString symbolEditor = LIB_EDIT_FRAME_NAME;
    bool     btmp;
    COLOR4D  wtmp;

    if( aCfg->Read( symbolEditor + ShowGridEntryKeyword, &btmp ) )
        SetGridVisibility( btmp );

    if( wtmp.SetFromWxString( aCfg->Read( symbolEditor + GridColorEntryKeyword, wxT( "NONE" ) ) ) )
        SetGridColor( wtmp );

    // Grid shape, etc.
    GetGalDisplayOptions().ReadAppConfig( *aCfg, symbolEditor );

    aCfg->Read( LIBLIST_WIDTH_KEY, &m_libListWidth, 150 );
    aCfg->Read( CMPLIST_WIDTH_KEY, &m_cmpListWidth, 150 );
    m_showPinElectricalTypeName = aCfg->Read( CMPVIEW_SHOW_PINELECTRICALTYPE_KEY, true );

    // Set parameters to a reasonable value.
    if( m_libListWidth > m_FrameSize.x/2 )
        m_libListWidth = m_FrameSize.x/2;

    if( m_cmpListWidth > m_FrameSize.x/2 )
        m_cmpListWidth = m_FrameSize.x/2;
}
void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
{
    aGal->SetIsStroke( true );
    aGal->SetIsFill( false );
    aGal->SetLineWidth( 1.0 );
    RENDER_SETTINGS* rs = m_view->GetPainter()->GetSettings();
    COLOR4D color = rs->GetColor( NULL, ITEM_GAL_LAYER( RATSNEST_VISIBLE ) );
    int highlightedNet = rs->GetHighlightNetCode();

    for( int i = 1; i < m_data->GetNetCount(); ++i )
    {
        RN_NET& net = m_data->GetNet( i );

        if( !net.IsVisible() )
            continue;

        // Set brighter color for the temporary ratsnest
        aGal->SetStrokeColor( color.Brightened( 0.8 ) );

        // Draw the "dynamic" ratsnest (i.e. for objects that may be currently being moved)
        BOOST_FOREACH( const RN_NODE_PTR& node, net.GetSimpleNodes() )
        {
            RN_NODE_PTR dest = net.GetClosestNode( node, WITHOUT_FLAG() &&
                                                         DIFFERENT_TAG( RN_NODE::TAG_UNCONNECTED ) );

            if( dest )
            {
                VECTOR2D origin( node->GetX(), node->GetY() );
                VECTOR2D end( dest->GetX(), dest->GetY() );

                aGal->DrawLine( origin, end );

                // Avoid duplicate destinations for ratsnest lines by storing already used nodes
                net.AddBlockedNode( dest );
            }
        }

        // Draw the "static" ratsnest
        if( i != highlightedNet )
            aGal->SetStrokeColor( color );  // using the default ratsnest color for not highlighted

        const std::vector<RN_EDGE_MST_PTR>* edges = net.GetUnconnected();

        if( edges == NULL )
            continue;

        BOOST_FOREACH( const RN_EDGE_MST_PTR& edge, *edges )
        {
            const RN_NODE_PTR& sourceNode = edge->GetSourceNode();
            const RN_NODE_PTR& targetNode = edge->GetTargetNode();
            VECTOR2D source( sourceNode->GetX(), sourceNode->GetY() );
            VECTOR2D target( targetNode->GetX(), targetNode->GetY() );

            aGal->DrawLine( source, target );
        }
    }
}
void SELECT_COPPER_LAYERS_PAIR_DIALOG::buildList()
{
    m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 );
    m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 );

    // Select a not show cell, to avoid a wrong cell selection for user

    int         row = 0;
    wxString    layername;

    for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder();  ui_seq;  ++ui_seq )
    {
        LAYER_ID  layerid = *ui_seq;

        if( !IsCopperLayer( layerid ) )
            break;

        COLOR4D color = GetLayerColor( layerid );

        layername = GetLayerName( layerid );

        if( row )
            m_leftGridLayers->AppendRows( 1 );

        m_leftGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color.ToColour() );
        m_leftGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername );
        m_layersId.push_back( layerid );

        if( m_frontLayer == layerid )
        {
            SetGridCursor( m_leftGridLayers, row, true );
            m_leftRowSelected = row;
        }

        if( row )
            m_rightGridLayers->AppendRows( 1 );
        m_rightGridLayers->SetCellBackgroundColour ( row, COLOR_COLNUM,
                                                     color.ToColour() );
        m_rightGridLayers->SetCellValue( row, LAYERNAME_COLNUM,
                                         layername );

        if( m_backLayer == layerid )
        {
            SetGridCursor( m_rightGridLayers, row, true );
            m_rightRowSelected = row;
        }

        row++;
    }

    m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
    m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
    m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM);
    m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
}
Пример #5
0
void PCB_RENDER_SETTINGS::ImportLegacyColors( const COLORS_DESIGN_SETTINGS* aSettings )
{
    // Init board layers colors:
    for( int i = 0; i < PCB_LAYER_ID_COUNT; i++ )
    {
        m_layerColors[i] = aSettings->GetLayerColor( i );

        // Guard: if the alpah channel is too small, the layer is not visible.
        // clamp it to 0.2
        if( m_layerColors[i].a < 0.2 )
            m_layerColors[i].a = 0.2;
    }

    // Init specific graphic layers colors:
    for( int i = GAL_LAYER_ID_START; i < GAL_LAYER_ID_END; i++ )
        m_layerColors[i] = aSettings->GetItemColor( i );

    // Default colors for specific layers (not really board layers).
    m_layerColors[LAYER_VIAS_HOLES]         = COLOR4D( 0.5, 0.4, 0.0, 0.8 );
    m_layerColors[LAYER_PADS_PLATEDHOLES]   = aSettings->GetItemColor( LAYER_PCB_BACKGROUND );
    m_layerColors[LAYER_PADS_NETNAMES]      = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
    m_layerColors[LAYER_PAD_FR_NETNAMES]    = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
    m_layerColors[LAYER_PAD_BK_NETNAMES]    = COLOR4D( 1.0, 1.0, 1.0, 0.9 );
    m_layerColors[LAYER_DRC]                = COLOR4D( 1.0, 0.0, 0.0, 0.8 );

    // LAYER_PADS_TH, LAYER_NON_PLATEDHOLES, LAYER_ANCHOR ,LAYER_RATSNEST,
    // LAYER_VIA_THROUGH, LAYER_VIA_BBLIND, LAYER_VIA_MICROVIA
    // are initialized from aSettings

    // These colors are not actually used. Set just in case...
    m_layerColors[LAYER_MOD_TEXT_FR] = m_layerColors[F_SilkS];
    m_layerColors[LAYER_MOD_TEXT_BK] = m_layerColors[B_SilkS];

    // Netnames for copper layers
    for( LSEQ cu = LSET::AllCuMask().CuStack();  cu;  ++cu )
    {
        const COLOR4D lightLabel( 0.8, 0.8, 0.8, 0.7 );
        const COLOR4D darkLabel = lightLabel.Inverted();
        PCB_LAYER_ID layer = *cu;

        if( m_layerColors[layer].GetBrightness() > 0.5 )
            m_layerColors[GetNetnameLayer( layer )] = darkLabel;
        else
            m_layerColors[GetNetnameLayer( layer )] = lightLabel;
    }

    SetBackgroundColor ( aSettings->GetItemColor( LAYER_PCB_BACKGROUND ) );

    update();
}
void DrawGraphicHaloText( EDA_RECT* aClipBox, wxDC * aDC,
                          const wxPoint &aPos,
                          const COLOR4D aBgColor,
                          COLOR4D aColor1,
                          COLOR4D aColor2,
                          const wxString &aText,
                          double aOrient,
                          const wxSize &aSize,
                          enum EDA_TEXT_HJUSTIFY_T aH_justify,
                          enum EDA_TEXT_VJUSTIFY_T aV_justify,
                          int aWidth, bool aItalic, bool aBold,
                          void (*aCallback)( int x0, int y0, int xf, int yf ),
                          PLOTTER * aPlotter )
{
    // Swap color if contrast would be better
    // TODO: Maybe calculate contrast some way other than brightness
    if( aBgColor.GetBrightness() > 0.5 )
    {
        COLOR4D c = aColor1;
        aColor1 = aColor2;
        aColor2 = c;
    }

    // Draw the background
    DrawGraphicText( aClipBox, aDC, aPos, aColor1, aText, aOrient, aSize,
                     aH_justify, aV_justify, aWidth, aItalic, aBold,
                     aCallback, aPlotter );

    // Draw the text
    DrawGraphicText( aClipBox, aDC, aPos, aColor2, aText, aOrient, aSize,
                     aH_justify, aV_justify, aWidth/4, aItalic, aBold,
                     aCallback, aPlotter );
}
void WIDGET_EESCHEMA_COLOR_CONFIG::SetColor( wxCommandEvent& event )
{
    wxBitmapButton* button = (wxBitmapButton*) event.GetEventObject();

    wxCHECK_RET( button != NULL, wxT( "Color button event object is NULL." ) );

    COLORBUTTON* colorButton = (COLORBUTTON*) button->GetClientData();

    wxCHECK_RET( colorButton != NULL, wxT( "Client data not set for color button." ) );

    wxColourData colourData;
    colourData.SetColour( currentColors[ colorButton->m_Layer ].ToColour() );
    wxColourDialog *dialog = new wxColourDialog( this, &colourData );

    COLOR4D newColor = COLOR4D::UNSPECIFIED;

    if( dialog->ShowModal() == wxID_OK )
    {
        newColor = COLOR4D( dialog->GetColourData().GetColour() );
    }

    if( newColor == COLOR4D::UNSPECIFIED || currentColors[ colorButton->m_Layer ] == newColor )
        return;

    currentColors[ colorButton->m_Layer ] = newColor;

    wxMemoryDC iconDC;

    wxBitmap bitmap = button->GetBitmapLabel();
    iconDC.SelectObject( bitmap );
    iconDC.SetPen( *wxBLACK_PEN );

    wxBrush  brush;
    brush.SetColour( newColor.ToColour() );
    brush.SetStyle( wxBRUSHSTYLE_SOLID );

    iconDC.SetBrush( brush );
    iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X, BUTT_SIZE_Y );
    button->SetBitmapLabel( bitmap );
    button->Refresh();

    Refresh( false );
}
void SELECT_COPPER_LAYERS_PAIR_DIALOG::SetGridCursor( wxGrid* aGrid, int aRow,
                                                      bool aEnable )
{
    if( aEnable )
    {
        LAYER_ID  layerid = m_layersId[aRow];
        COLOR4D color = GetLayerColor( layerid );
        aGrid->SetCellValue( aRow, SELECT_COLNUM, wxT("X") );
        aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM, color.ToColour() );
        aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM );
    }
    else
    {
        aGrid->SetCellValue( aRow, SELECT_COLNUM, wxEmptyString );
        aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM,
                                        aGrid->GetDefaultCellBackgroundColour() );
        aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM );
    }
}
Пример #9
0
void EDA_DRAW_FRAME::LoadSettings( wxConfigBase* aCfg )
{
    EDA_BASE_FRAME::LoadSettings( aCfg );

    wxString baseCfgName = ConfigBaseName();
    wxConfigBase* cmnCfg = Pgm().CommonSettings();

    // Read units used in dialogs and toolbars
    EDA_UNITS_T unitsTmp;

    if( aCfg->Read( baseCfgName + UserUnitsEntryKeyword, (int*) &unitsTmp ) )
        SetUserUnits( unitsTmp );
    else
        SetUserUnits( MILLIMETRES );

    // Read show/hide grid entry
    bool btmp;
    if( aCfg->Read( baseCfgName + ShowGridEntryKeyword, &btmp ) )
        SetGridVisibility( btmp );

    // Read grid color:
    COLOR4D wtmp = COLOR4D::UNSPECIFIED;

    if( wtmp.SetFromWxString( aCfg->Read( baseCfgName + GridColorEntryKeyword, wxT( "NONE" ) ) ) )
        SetGridColor( wtmp );

    aCfg->Read( baseCfgName + LastGridSizeIdKeyword, &m_LastGridSizeId, 0L );

    // m_LastGridSizeId is an offset, expected to be >= 0
    if( m_LastGridSizeId < 0 )
        m_LastGridSizeId = 0;

    m_UndoRedoCountMax = aCfg->Read( baseCfgName + MaxUndoItemsEntry,
            long( DEFAULT_MAX_UNDO_ITEMS ) );

    aCfg->Read( baseCfgName + FirstRunShownKeyword, &m_firstRunDialogSetting, 0L );

    m_galDisplayOptions.ReadConfig( *cmnCfg, *aCfg, baseCfgName, this );
}
void EDA_DRAW_PANEL::ReDraw( wxDC* DC, bool erasebg )
{
    BASE_SCREEN* Screen = GetScreen();

    if( Screen == NULL )
        return;

    COLOR4D bgColor = GetParent()->GetDrawBgColor();

    // TODO(JE): Is this correct?
    if( bgColor.GetBrightness() > 0.5 )
    {
        g_XorMode    = GR_NXOR;
        g_GhostColor = BLACK;
    }
    else
    {
        g_XorMode    = GR_XOR;
        g_GhostColor = WHITE;
    }

    GRResetPenAndBrush( DC );

    DC->SetBackground( wxBrush( bgColor.ToColour() ) );
    DC->SetBackgroundMode( wxSOLID );

    if( erasebg )
        EraseScreen( DC );

    GetParent()->RedrawActiveWindow( DC, erasebg );

    // Verfies that the clipping is working correctly.  If these two sets of numbers are
    // not the same or really close.  The clipping algorithms are broken.
    wxLogTrace( kicadTraceCoords,
                wxT( "Clip box: (%d, %d, %d, %d), Draw extents (%d, %d, %d, %d)" ),
                m_ClipBox.GetX(), m_ClipBox.GetY(), m_ClipBox.GetRight(), m_ClipBox.GetBottom(),
                DC->MinX(), DC->MinY(), DC->MaxX(), DC->MaxY() );
}
void EDA_DRAW_PANEL::DrawCrossHair( wxDC* aDC, COLOR4D aColor )
{
    if( m_cursorLevel != 0 || aDC == NULL || !m_showCrossHair )
        return;

    wxPoint cursor = GetParent()->GetCrossHairPosition();

#ifdef USE_WX_GRAPHICS_CONTEXT
    // Normally cursor color is set to white, so when it is xored with white
    // background, it is painted black effectively. wxGraphicsContext does not have
    // xor operation, so we need to invert the color manually.
    aColor.Invert();
#else
    GRSetDrawMode( aDC, GR_XOR );
#endif

    if( GetParent()->GetGalDisplayOptions().m_fullscreenCursor )
    {
        wxSize  clientSize = GetClientSize();

        // Y axis
        wxPoint lineStart( cursor.x, aDC->DeviceToLogicalY( 0 ) );
        wxPoint lineEnd(   cursor.x, aDC->DeviceToLogicalY( clientSize.y ) );

        GRLine( &m_ClipBox, aDC, lineStart, lineEnd, 0, aColor );

        // X axis
        lineStart = wxPoint( aDC->DeviceToLogicalX( 0 ), cursor.y );
        lineEnd   = wxPoint( aDC->DeviceToLogicalX( clientSize.x ), cursor.y );

        GRLine( &m_ClipBox, aDC, lineStart, lineEnd, 0, aColor );
    }
    else
    {
        int len = aDC->DeviceToLogicalXRel( CURSOR_SIZE );

        GRLine( &m_ClipBox, aDC, cursor.x - len, cursor.y,
                cursor.x + len, cursor.y, 0, aColor );
        GRLine( &m_ClipBox, aDC, cursor.x, cursor.y - len,
                cursor.x, cursor.y + len, 0, aColor );
    }
}
Пример #12
0
    EDA_COLOR_T COLOR4D::GetNearestLegacyColor( const COLOR4D &aColor )
    {
        // Cache layer implemented here, because all callers are using wxColour
        static std::map< unsigned int, unsigned int > nearestCache;
        static double hues[NBCOLORS];
        static double values[NBCOLORS];

        unsigned int colorInt = aColor.ToU32();

        auto search = nearestCache.find( colorInt );

        if( search != nearestCache.end() )
            return static_cast<EDA_COLOR_T>( search->second );

        // First use ColorFindNearest to check for exact matches
        EDA_COLOR_T nearest = ColorFindNearest( aColor.r * 255.0, aColor.g * 255.0, aColor.b * 255.0 );

        if( COLOR4D( nearest ) == aColor )
        {
            nearestCache.insert( std::pair< unsigned int, unsigned int >(
                                 colorInt, static_cast<unsigned int>( nearest ) ) );
            return nearest;
        }

        // If not, use hue and value to match.
        // Hue will be NAN for grayscale colors.
        // The legacy color palette is a grid across hue and value.
        // We can exploit that to find a good match -- hue is most apparent to the user.
        // So, first we determine the closest hue match, and then the closest value from that
        // "grid row" in the legacy palette.

        double h, s, v;
        aColor.ToHSV( h, s, v );

        double minDist = 360.0;
        double legacyHue = 0.0;

        if( std::isnan( h ) )
        {
            legacyHue = NAN;
        }
        else
        {
            for( EDA_COLOR_T candidate = ::BLACK;
                    candidate < NBCOLORS; candidate = NextColor( candidate ) )
            {
                double ch;

                if( hues[candidate] == 0.0 && values[candidate] == 0.0 )
                {
                    COLOR4D candidate4d( candidate );
                    double cs, cv;

                    candidate4d.ToHSV( ch, cs, cv );

                    values[candidate] = cv;
                    // Set the hue to non-zero for black so that we won't do this more than once
                    hues[candidate] = ( cv == 0.0 ) ? 1.0 : ch;
                }
                else
                {
                    ch = hues[candidate];
                }

                if( fabs( ch - h ) < minDist )
                {
                    minDist = fabs( ch - h );
                    legacyHue = ch;
                }
            }
        }

        // Now we have the desired hue; let's find the nearest value
        minDist = 1.0;
        for( EDA_COLOR_T candidate = ::BLACK;
                candidate < NBCOLORS; candidate = NextColor( candidate ) )
        {
            // If the target hue is NAN, we didn't extract the value for any colors above
            if( std::isnan( legacyHue ) )
            {
                double ch, cs, cv;
                COLOR4D candidate4d( candidate );
                candidate4d.ToHSV( ch, cs, cv );
                values[candidate] = cv;
                hues[candidate] = ( cv == 0.0 ) ? 1.0 : ch;
            }

            if( ( std::isnan( legacyHue ) != std::isnan( hues[candidate] ) ) || hues[candidate] != legacyHue )
                continue;

            if( fabs( values[candidate] - v ) < minDist )
            {
                minDist = fabs( values[candidate] - v );
                nearest = candidate;
            }
        }

        nearestCache.insert( std::pair< unsigned int, unsigned int >(
                             colorInt, static_cast<unsigned int>( nearest ) ) );

        return nearest;
    }
void WIDGET_EESCHEMA_COLOR_CONFIG::CreateControls()
{
    wxStaticText*   label;
    int             buttonId = 1800;

    m_mainBoxSizer = new wxBoxSizer( wxHORIZONTAL );
    SetSizer( m_mainBoxSizer );

    BUTTONINDEX* groups = buttonGroups;
    wxBoxSizer* columnBoxSizer = NULL;

    while( groups->m_Buttons != NULL )
    {
        COLORBUTTON* buttons = groups->m_Buttons;

        columnBoxSizer = new wxBoxSizer( wxVERTICAL );
        m_mainBoxSizer->Add( columnBoxSizer, 1, wxALIGN_TOP | wxLEFT | wxTOP, 5 );
        wxBoxSizer* rowBoxSizer = new wxBoxSizer( wxHORIZONTAL );
        columnBoxSizer->Add( rowBoxSizer, 0, wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );

        // Add a text string to identify the column of color select buttons.
        label = new wxStaticText( this, wxID_ANY, groups->m_Name );

        // Make the column label font bold.
        wxFont font( label->GetFont() );
        font.SetWeight( wxFONTWEIGHT_BOLD );
        label->SetFont( font );

        rowBoxSizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );

        while( buttons->m_Layer >= 0 )
        {
            rowBoxSizer = new wxBoxSizer( wxHORIZONTAL );
            columnBoxSizer->Add( rowBoxSizer, 0, wxGROW | wxALL, 0 );

            COLOR4D color = GetLayerColor( LAYERSCH_ID( buttons->m_Layer ) );
            currentColors[ buttons->m_Layer ] = color;

            wxMemoryDC iconDC;
            wxBitmap   bitmap( BUTT_SIZE_X, BUTT_SIZE_Y );

            iconDC.SelectObject( bitmap );
            iconDC.SetPen( *wxBLACK_PEN );

            wxBrush brush;
            brush.SetColour( color.ToColour() );
            brush.SetStyle( wxBRUSHSTYLE_SOLID );
            iconDC.SetBrush( brush );
            iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X, BUTT_SIZE_Y );

            wxBitmapButton* bitmapButton = new wxBitmapButton(
                                    this, buttonId, bitmap, wxDefaultPosition,
                                    wxSize( BUTT_SIZE_X+8, BUTT_SIZE_Y+6 ) );
            bitmapButton->SetClientData( (void*) buttons );

            rowBoxSizer->Add( bitmapButton, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 );

            label = new wxStaticText( this, wxID_ANY, wxGetTranslation( buttons->m_Name ) );
            rowBoxSizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 );
            buttonId += 1;
            buttons++;
        }

        groups++;
    }

    COLOR4D bgColor = GetDrawFrame()->GetDrawBgColor();
    wxMemoryDC iconDC;
    wxBitmap   bitmap( BUTT_SIZE_X, BUTT_SIZE_Y );

    iconDC.SelectObject( bitmap );
    iconDC.SetPen( *wxBLACK_PEN );

    wxBrush brush;
    brush.SetColour( bgColor.ToColour() );
    brush.SetStyle( wxBRUSHSTYLE_SOLID );
    iconDC.SetBrush( brush );
    iconDC.DrawRectangle( 0, 0, BUTT_SIZE_X, BUTT_SIZE_Y );

    buttonId++;
    wxBitmapButton* selBgColorBtn = new wxBitmapButton(
                            this, buttonId, bitmap, wxDefaultPosition,
                            wxSize( BUTT_SIZE_X + 8, BUTT_SIZE_Y + 6 ) );
    selBgColorBtn->SetClientData( (void*) &bgColorButton );

    Connect( 1800, buttonId, wxEVT_COMMAND_BUTTON_CLICKED,
             wxCommandEventHandler( WIDGET_EESCHEMA_COLOR_CONFIG::SetColor ) );

    wxStaticText* bgColorLabel = new wxStaticText( this, wxID_ANY, _( "Background Color" ) );
    wxFont font( bgColorLabel->GetFont() );
    font.SetWeight( wxFONTWEIGHT_BOLD );
    bgColorLabel->SetFont( font );

    if( columnBoxSizer )
    {
        // Add a spacer to improve appearance.
        columnBoxSizer->AddSpacer( 5 );
        columnBoxSizer->Add( bgColorLabel, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );
        columnBoxSizer->Add( selBgColorBtn, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 );
    }

    currentColors[ LAYER_BACKGROUND ] = bgColor;

    // Dialog now needs to be resized, but the associated command is found elsewhere.
}
void GERBER_DRAW_ITEM::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, GR_DRAWMODE aDrawMode,
                             const wxPoint& aOffset, GBR_DISPLAY_OPTIONS* aDrawOptions )
{
    // used when a D_CODE is not found. default D_CODE to draw a flashed item
    static D_CODE dummyD_CODE( 0 );
    bool          isFilled;
    int           radius;
    int           halfPenWidth;
    static bool   show_err;
    D_CODE*       d_codeDescr = GetDcodeDescr();

    if( d_codeDescr == NULL )
        d_codeDescr = &dummyD_CODE;

    COLOR4D color = m_GerberImageFile->GetPositiveDrawColor();

    if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
        color.SetToLegacyHighlightColor();

    /* isDark is true if flash is positive and should use a drawing
     *   color other than the background color, else use the background color
     *   when drawing so that an erasure happens.
     */
    bool isDark = !(m_LayerNegative ^ m_GerberImageFile->m_ImageNegative);

    if( !isDark )
    {
        // draw in background color ("negative" color)
        color = aDrawOptions->m_NegativeDrawColor;
    }

    GRSetDrawMode( aDC, aDrawMode );

    isFilled = aDrawOptions->m_DisplayLinesFill;

    switch( m_Shape )
    {
    case GBR_POLYGON:
        isFilled = aDrawOptions->m_DisplayPolygonsFill;

        if( !isDark )
            isFilled = true;

        DrawGbrPoly( aPanel->GetClipBox(), aDC, color, aOffset, isFilled );
        break;

    case GBR_CIRCLE:
        radius = KiROUND( GetLineLength( m_Start, m_End ) );

        halfPenWidth = m_Size.x >> 1;

        if( !isFilled )
        {
            // draw the border of the pen's path using two circles, each as narrow as possible
            GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
                      radius - halfPenWidth, 0, color );
            GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
                      radius + halfPenWidth, 0, color );
        }
        else    // Filled mode
        {
            GRCircle( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
                      radius, m_Size.x, color );
        }
        break;

    case GBR_ARC:
        // Currently, arcs plotted with a rectangular aperture are not supported.
        // a round pen only is expected.

#if 0   // for arc debug only
        GRLine( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
                GetABPosition( m_ArcCentre ), 0, color );
        GRLine( aPanel->GetClipBox(), aDC, GetABPosition( m_End ),
                GetABPosition( m_ArcCentre ), 0, color );
#endif

        if( !isFilled )
        {
            GRArc1( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
                    GetABPosition( m_End ), GetABPosition( m_ArcCentre ),
                    0, color );
        }
        else
        {
            GRArc1( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
                    GetABPosition( m_End ), GetABPosition( m_ArcCentre ),
                    m_Size.x, color );
        }

        break;

    case GBR_SPOT_CIRCLE:
    case GBR_SPOT_RECT:
    case GBR_SPOT_OVAL:
    case GBR_SPOT_POLY:
    case GBR_SPOT_MACRO:
        isFilled = aDrawOptions->m_DisplayFlashedItemsFill;
        d_codeDescr->DrawFlashedShape( this, aPanel->GetClipBox(), aDC, color,
                                       m_Start, isFilled );
        break;

    case GBR_SEGMENT:
        /* Plot a line from m_Start to m_End.
         * Usually, a round pen is used, but some gerber files use a rectangular pen
         * In fact, any aperture can be used to plot a line.
         * currently: only a square pen is handled (I believe using a polygon gives a strange plot).
         */
        if( d_codeDescr->m_Shape == APT_RECT )
        {
            if( m_Polygon.OutlineCount() == 0 )
                ConvertSegmentToPolygon();

            DrawGbrPoly( aPanel->GetClipBox(), aDC, color, aOffset, isFilled );
        }
        else
        {
            if( !isFilled )
            {
                    GRCSegm( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
                             GetABPosition( m_End ), m_Size.x, color );
            }
            else
            {
                GRFilledSegment( aPanel->GetClipBox(), aDC, GetABPosition( m_Start ),
                                 GetABPosition( m_End ), m_Size.x, color );
            }
        }

        break;

    default:
        if( !show_err )
        {
            wxMessageBox( wxT( "Trace_Segment() type error" ) );
            show_err = true;
        }

        break;
    }
}
void ZONE_CONTAINER::DrawFilledArea( EDA_DRAW_PANEL* panel,
                                     wxDC* DC, GR_DRAWMODE aDrawMode, const wxPoint& offset )
{
    static std::vector <wxPoint> CornersBuffer;
    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();

    // outline_mode is false to show filled polys,
    // and true to show polygons outlines only (test and debug purposes)
    bool outline_mode = displ_opts->m_DisplayZonesMode == 2 ? true : false;

    if( DC == NULL )
        return;

    if( displ_opts->m_DisplayZonesMode == 1 )     // Do not show filled areas
        return;

    if( m_FilledPolysList.IsEmpty() )  // Nothing to draw
        return;

    BOARD*      brd = GetBoard();
    LAYER_ID    curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
    COLOR4D     color = brd->GetLayerColor( m_Layer );

    if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
        return;

    GRSetDrawMode( DC, aDrawMode );

    if( displ_opts->m_ContrastModeDisplay )
    {
        if( !IsOnLayer( curr_layer ) )
            color = COLOR4D( DARKDARKGRAY );
    }

    if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
        color.SetToLegacyHighlightColor();

    color.a = 0.588;


    for ( int ic = 0; ic < m_FilledPolysList.OutlineCount(); ic++ )
    {
        const SHAPE_LINE_CHAIN& path = m_FilledPolysList.COutline( ic );

        CornersBuffer.clear();

        wxPoint p0;

        for( int j = 0; j < path.PointCount(); j++ )
        {
            const VECTOR2I& corner = path.CPoint( j );

            wxPoint coord( corner.x + offset.x, corner.y + offset.y );

            if( j == 0 )
                p0 = coord;

            CornersBuffer.push_back( coord );
        }

        CornersBuffer.push_back( p0 );

        // Draw outlines:
        if( ( m_ZoneMinThickness > 1 ) || outline_mode )
        {
            int ilim = CornersBuffer.size() - 1;

            for( int is = 0, ie = ilim; is <= ilim; ie = is, is++ )
            {
                int x0 = CornersBuffer[is].x;
                int y0 = CornersBuffer[is].y;
                int x1 = CornersBuffer[ie].x;
                int y1 = CornersBuffer[ie].y;

                // Draw only basic outlines, not extra segments.
                if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
                    GRCSegm( panel->GetClipBox(), DC,
                             x0, y0, x1, y1,
                             m_ZoneMinThickness, color );
                else
                    GRFillCSegm( panel->GetClipBox(), DC,
                                 x0, y0, x1, y1, m_ZoneMinThickness, color );
            }
        }

        // Draw areas:
        if( m_FillMode == 0 && !outline_mode )
            GRPoly( panel->GetClipBox(), DC, CornersBuffer.size(), &CornersBuffer[0],
                    true, 0, color, color );
    }

    if( m_FillMode == 1  && !outline_mode )     // filled with segments
    {
        for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
        {
            wxPoint start = m_FillSegmList[ic].m_Start + offset;
            wxPoint end   = m_FillSegmList[ic].m_End + offset;

            if( !displ_opts->m_DisplayPcbTrackFill || GetState( FORCE_SKETCH ) )
                GRCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
                         m_ZoneMinThickness, color );
            else
                GRFillCSegm( panel->GetClipBox(), DC, start.x, start.y, end.x, end.y,
                             m_ZoneMinThickness, color );
        }
    }
}
Пример #16
0
void VIA::Draw( EDA_DRAW_PANEL* panel, wxDC* aDC, GR_DRAWMODE aDrawMode, const wxPoint& aOffset )
{
    wxCHECK_RET( panel != NULL, wxT( "VIA::Draw panel cannot be NULL." ) );

    int radius;
    PCB_LAYER_ID curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;

    int fillvia = 0;
    PCB_BASE_FRAME* frame  = (PCB_BASE_FRAME*) panel->GetParent();
    PCB_SCREEN*     screen = frame->GetScreen();
    auto displ_opts = (PCB_DISPLAY_OPTIONS*)( frame->GetDisplayOptions() );

    if( displ_opts->m_DisplayViaFill == FILLED )
        fillvia = 1;

    GRSetDrawMode( aDC, aDrawMode );

    BOARD * brd =  GetBoard();
    COLOR4D color = frame->Settings().Colors().GetItemColor( LAYER_VIAS + GetViaType() );

    if( brd->IsElementVisible( LAYER_VIAS + GetViaType() ) == false
        && !( aDrawMode & GR_HIGHLIGHT ) )
       return;

    // Only draw the via if at least one of the layers it crosses is being displayed
    if( !( brd->GetVisibleLayers() & GetLayerSet() ).any() )
        return;

    if( displ_opts->m_ContrastModeDisplay )
    {
        if( !IsOnLayer( curr_layer ) )
            color = COLOR4D( DARKDARKGRAY );
    }

    if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
        color.SetToLegacyHighlightColor();

    color.a = 0.588;


    radius = m_Width >> 1;
    // for small via size on screen (radius < 4 pixels) draw a simplified shape

    int radius_in_pixels = aDC->LogicalToDeviceXRel( radius );

    bool fast_draw = false;

    // Vias are drawn as a filled circle or a double circle. The hole will be drawn later
    int drill_radius = GetDrillValue() / 2;

    int inner_radius = radius - aDC->DeviceToLogicalXRel( 2 );

    if( radius_in_pixels < MIN_VIA_DRAW_SIZE )
    {
        fast_draw = true;
        fillvia = false;
    }

    if( fillvia )
    {
        GRFilledCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius, color );
    }
    else
    {
        GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius, 0, color );

        if ( fast_draw )
            return;

        GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, inner_radius, 0, color );
    }

    if( fillvia )
    {
        bool blackpenstate = false;

        if( screen->m_IsPrinting )
        {
            blackpenstate = GetGRForceBlackPenState();
            GRForceBlackPen( false );
            color = WHITE;
        }
        else
        {
            color = BLACK;     // or DARKGRAY;
        }

        if( (aDrawMode & GR_XOR) == 0)
            GRSetDrawMode( aDC, GR_COPY );

        // Draw hole if the radius is > 1pixel.
        if( aDC->LogicalToDeviceXRel( drill_radius ) > 1 )
            GRFilledCircle( panel->GetClipBox(), aDC, m_Start.x + aOffset.x,
                            m_Start.y + aOffset.y, drill_radius, 0, color, color );

        if( screen->m_IsPrinting )
            GRForceBlackPen( blackpenstate );
    }
    else
    {
        if( drill_radius < inner_radius )         // We can show the via hole
            GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, drill_radius, 0, color );
    }

    if( ShowClearance( displ_opts, this ) )
    {
        GRCircle( panel->GetClipBox(), aDC, m_Start + aOffset, radius + GetClearance(), 0, color );
    }

    // for Micro Vias, draw a partial cross : X on component layer, or + on copper layer
    // (so we can see 2 superimposed microvias ):
    if( GetViaType() == VIA_MICROVIA )
    {
        int ax, ay, bx, by;

        if( IsOnLayer( B_Cu ) )
        {
            ax = radius; ay = 0;
            bx = drill_radius; by = 0;
        }
        else
        {
            ax = ay = (radius * 707) / 1000;
            bx = by = (drill_radius * 707) / 1000;
        }

        // lines '|' or '\'
        GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax,
                m_Start.y + aOffset.y - ay,
                m_Start.x + aOffset.x - bx,
                m_Start.y + aOffset.y - by, 0, color );
        GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x + bx,
                m_Start.y + aOffset.y + by,
                m_Start.x + aOffset.x + ax,
                m_Start.y + aOffset.y + ay, 0, color );

        // lines - or '/'
        GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x + ay,
                m_Start.y + aOffset.y - ax,
                m_Start.x + aOffset.x + by,
                m_Start.y + aOffset.y - bx, 0, color );
        GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - by,
                m_Start.y + aOffset.y + bx,
                m_Start.x + aOffset.x - ay,
                m_Start.y + aOffset.y + ax, 0, color );
    }

    // for Buried Vias, draw a partial line : orient depending on layer pair
    // (so we can see superimposed buried vias ):
    if( GetViaType() == VIA_BLIND_BURIED )
    {
        int ax = 0, ay = radius, bx = 0, by = drill_radius;
        PCB_LAYER_ID layer_top, layer_bottom;

        LayerPair( &layer_top, &layer_bottom );

        // lines for the top layer
        RotatePoint( &ax, &ay, layer_top * 3600.0 / brd->GetCopperLayerCount( ) );
        RotatePoint( &bx, &by, layer_top * 3600.0 / brd->GetCopperLayerCount( ) );
        GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax,
                m_Start.y + aOffset.y - ay,
                m_Start.x + aOffset.x - bx,
                m_Start.y + aOffset.y - by, 0, color );

        // lines for the bottom layer
        ax = 0; ay = radius; bx = 0; by = drill_radius;
        RotatePoint( &ax, &ay, layer_bottom * 3600.0 / brd->GetCopperLayerCount( ) );
        RotatePoint( &bx, &by, layer_bottom * 3600.0 / brd->GetCopperLayerCount( ) );
        GRLine( panel->GetClipBox(), aDC, m_Start.x + aOffset.x - ax,
                m_Start.y + aOffset.y - ay,
                m_Start.x + aOffset.x - bx,
                m_Start.y + aOffset.y - by, 0, color );
    }

    // Display the short netname:
    if( GetNetCode() == NETINFO_LIST::UNCONNECTED )
        return;

    if( displ_opts->m_DisplayNetNamesMode == 0 || displ_opts->m_DisplayNetNamesMode == 1 )
        return;

    NETINFO_ITEM* net = GetNet();

    if( net == NULL )
        return;

    int len = net->GetShortNetname().Len();

    if( len > 0 )
    {
        // calculate a good size for the text
        int tsize = m_Width / len;

        if( aDC->LogicalToDeviceXRel( tsize ) >= MIN_TEXT_SIZE )
        {
            tsize = (tsize * 7) / 10;        // small reduction to give a better look, inside via

            if( (aDrawMode & GR_XOR) == 0 )
                GRSetDrawMode( aDC, GR_COPY );

            EDA_RECT* clipbox = panel->GetClipBox();
            DrawGraphicHaloText( clipbox, aDC, m_Start,
                                 color, WHITE, BLACK, net->GetShortNetname(), 0,
                                 wxSize( tsize, tsize ),
                                 GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_VJUSTIFY_CENTER,
                                 tsize / 7, false, false );
        }
    }
}
void ZONE_CONTAINER::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, GR_DRAWMODE aDrawMode,
                           const wxPoint& offset )
{
    if( !DC )
        return;

    wxPoint     seg_start, seg_end;
    LAYER_ID    curr_layer = ( (PCB_SCREEN*) panel->GetScreen() )->m_Active_Layer;
    BOARD*      brd   = GetBoard();

    COLOR4D     color = brd->GetLayerColor( m_Layer );

    if( brd->IsLayerVisible( m_Layer ) == false && !( aDrawMode & GR_HIGHLIGHT ) )
        return;

    GRSetDrawMode( DC, aDrawMode );
    DISPLAY_OPTIONS* displ_opts = (DISPLAY_OPTIONS*)panel->GetDisplayOptions();

    if( displ_opts->m_ContrastModeDisplay )
    {
        if( !IsOnLayer( curr_layer ) )
            color = COLOR4D( DARKDARKGRAY );
    }

    if( ( aDrawMode & GR_HIGHLIGHT ) && !( aDrawMode & GR_AND ) )
        color.SetToLegacyHighlightColor();

    color.a = 0.588;

    // draw the lines
    int i_start_contour = 0;
    std::vector<wxPoint> lines;
    lines.reserve( (GetNumCorners() * 2) + 2 );

    for( int ic = 0; ic < GetNumCorners(); ic++ )
    {
        seg_start = GetCornerPosition( ic ) + offset;

        if( !m_Poly->m_CornersList.IsEndContour( ic ) && ic < GetNumCorners() - 1 )
        {
            seg_end = GetCornerPosition( ic + 1 ) + offset;
        }
        else
        {
            seg_end = GetCornerPosition( i_start_contour ) + offset;
            i_start_contour = ic + 1;
        }

        lines.push_back( seg_start );
        lines.push_back( seg_end );
    }

    GRLineArray( panel->GetClipBox(), DC, lines, 0, color );

    // draw hatches
    lines.clear();
    lines.reserve( (m_Poly->m_HatchLines.size() * 2) + 2 );

    for( unsigned ic = 0; ic < m_Poly->m_HatchLines.size(); ic++ )
    {
        seg_start = m_Poly->m_HatchLines[ic].m_Start + offset;
        seg_end   = m_Poly->m_HatchLines[ic].m_End + offset;
        lines.push_back( seg_start );
        lines.push_back( seg_end );
    }

    GRLineArray( panel->GetClipBox(), DC, lines, 0, color );
}
Пример #18
0
void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
{
    VECTOR2D    size;
    VECTOR2D    position( aPad->GetPosition() );
    PAD_SHAPE_T shape;
    double      m, n;
    double      orientation = aPad->GetOrientation();
    wxString buffer;

    // Draw description layer
    if( IsNetnameLayer( aLayer ) )
    {
        // Is anything that we can display enabled?
        if( m_pcbSettings.m_netNamesOnPads || m_pcbSettings.m_padNumbers )
        {
            // Min char count to calculate string size
            const int MIN_CHAR_COUNT = 3;

            bool displayNetname = ( m_pcbSettings.m_netNamesOnPads &&
                                    !aPad->GetNetname().empty() );
            VECTOR2D padsize = VECTOR2D( aPad->GetSize() );
            double maxSize = PCB_RENDER_SETTINGS::MAX_FONT_SIZE;
            double size = padsize.y;

            // Keep the size ratio for the font, but make it smaller
            if( padsize.x < padsize.y )
            {
                orientation += 900.0;
                size = padsize.x;
                EXCHG( padsize.x, padsize.y );
            }
            else if( padsize.x == padsize.y )
            {
                // If the text is displayed on a symmetrical pad, do not rotate it
                orientation = 0.0;
            }

            // Font size limits
            if( size > maxSize )
                size = maxSize;

            m_gal->Save();
            m_gal->Translate( position );

            // do not display descriptions upside down
            NORMALIZE_ANGLE_90( orientation );
            m_gal->Rotate( -orientation * M_PI / 1800.0 );

            // Default font settings
            m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER );
            m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_CENTER );
            m_gal->SetBold( false );
            m_gal->SetItalic( false );
            m_gal->SetMirrored( false );

            // Set a proper color for the label
            const COLOR4D& color  = m_pcbSettings.GetColor( aPad, aPad->GetLayer() );
            COLOR4D labelColor = m_pcbSettings.GetColor( NULL, aLayer );

            if( color.GetBrightness() > 0.5 )
                m_gal->SetStrokeColor( labelColor.Inverted() );
            else
                m_gal->SetStrokeColor( labelColor );

            VECTOR2D textpos( 0.0, 0.0);

            // Divide the space, to display both pad numbers and netnames
            // and set the Y text position to display 2 lines
            if( displayNetname && m_pcbSettings.m_padNumbers )
            {
                size = size / 2.0;
                textpos.y = size / 2.0;
            }

            if( displayNetname )
            {
                // calculate the size of net name text:
                double tsize = padsize.x / aPad->GetShortNetname().Length();
                tsize = std::min( tsize, size );
                // Use a smaller text size to handle interline, pen size..
                tsize *= 0.7;
                VECTOR2D namesize( tsize, tsize );
                m_gal->SetGlyphSize( namesize );
                m_gal->SetLineWidth( namesize.x / 12.0 );
                m_gal->StrokeText( aPad->GetShortNetname(), textpos, 0.0 );
            }

            if( m_pcbSettings.m_padNumbers )
            {
                textpos.y = -textpos.y;
                aPad->StringPadName( buffer );
                int len = buffer.Length();
                double tsize = padsize.x / std::max( len, MIN_CHAR_COUNT );
                tsize = std::min( tsize, size );
                // Use a smaller text size to handle interline, pen size..
                tsize *= 0.7;
                tsize = std::min( tsize, size );
                VECTOR2D numsize( tsize, tsize );

                m_gal->SetGlyphSize( numsize );
                m_gal->SetLineWidth( numsize.x / 12.0 );
                m_gal->StrokeText( aPad->GetPadName(), textpos, 0.0 );
            }

            m_gal->Restore();
        }
        return;
    }

    // Pad drawing
    const COLOR4D& color = m_pcbSettings.GetColor( aPad, aLayer );
    if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] )
    {
        // Outline mode
        m_gal->SetIsFill( false );
        m_gal->SetIsStroke( true );
        m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
        m_gal->SetStrokeColor( color );
    }
    else
    {
        // Filled mode
        m_gal->SetIsFill( true );
        m_gal->SetIsStroke( false );
        m_gal->SetFillColor( color );
    }

    m_gal->Save();
    m_gal->Translate( VECTOR2D( aPad->GetPosition() ) );
    m_gal->Rotate( -aPad->GetOrientation() * M_PI / 1800.0 );

    // Choose drawing settings depending on if we are drawing a pad itself or a hole
    if( aLayer == ITEM_GAL_LAYER( PADS_HOLES_VISIBLE ) )
    {
        // Drawing hole: has same shape as PAD_CIRCLE or PAD_OVAL
        size  = VECTOR2D( aPad->GetDrillSize() ) / 2.0;
        shape = aPad->GetDrillShape() == PAD_DRILL_OBLONG ? PAD_OVAL : PAD_CIRCLE;
    }
    else if( aLayer == SOLDERMASK_N_FRONT || aLayer == SOLDERMASK_N_BACK )
    {
        // Drawing soldermask
        int soldermaskMargin = aPad->GetSolderMaskMargin();

        m_gal->Translate( VECTOR2D( aPad->GetOffset() ) );
        size  = VECTOR2D( aPad->GetSize().x / 2.0 + soldermaskMargin,
                          aPad->GetSize().y / 2.0 + soldermaskMargin );
        shape = aPad->GetShape();
    }
    else if( aLayer == SOLDERPASTE_N_FRONT || aLayer == SOLDERPASTE_N_BACK )
    {
        // Drawing solderpaste
        int solderpasteMargin = aPad->GetLocalSolderPasteMargin();

        m_gal->Translate( VECTOR2D( aPad->GetOffset() ) );
        size  = VECTOR2D( aPad->GetSize().x / 2.0 + solderpasteMargin,
                          aPad->GetSize().y / 2.0 + solderpasteMargin );
        shape = aPad->GetShape();
    }
    else
    {
        // Drawing every kind of pad
        m_gal->Translate( VECTOR2D( aPad->GetOffset() ) );
        size  = VECTOR2D( aPad->GetSize() ) / 2.0;
        shape = aPad->GetShape();
    }

    switch( shape )
    {
    case PAD_OVAL:
        if( size.y >= size.x )
        {
            m = ( size.y - size.x );
            n = size.x;

            if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] )
            {
                // Outline mode
                m_gal->DrawArc( VECTOR2D( 0, -m ), n, -M_PI, 0 );
                m_gal->DrawArc( VECTOR2D( 0, m ),  n, M_PI, 0 );
                m_gal->DrawLine( VECTOR2D( -n, -m ), VECTOR2D( -n, m ) );
                m_gal->DrawLine( VECTOR2D( n, -m ),  VECTOR2D( n, m ) );
            }
            else
            {
                // Filled mode
                m_gal->DrawCircle( VECTOR2D( 0, -m ), n );
                m_gal->DrawCircle( VECTOR2D( 0, m ),  n );
                m_gal->DrawRectangle( VECTOR2D( -n, -m ), VECTOR2D( n, m ) );
            }
        }
        else
        {
            m = ( size.x - size.y );
            n = size.y;

            if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] )
            {
                // Outline mode
                m_gal->DrawArc( VECTOR2D( -m, 0 ), n, M_PI / 2, 3 * M_PI / 2 );
                m_gal->DrawArc( VECTOR2D( m, 0 ),  n, M_PI / 2, -M_PI / 2 );
                m_gal->DrawLine( VECTOR2D( -m, -n ), VECTOR2D( m, -n ) );
                m_gal->DrawLine( VECTOR2D( -m, n ),  VECTOR2D( m, n ) );
            }
            else
            {
                // Filled mode
                m_gal->DrawCircle( VECTOR2D( -m, 0 ), n );
                m_gal->DrawCircle( VECTOR2D( m, 0 ),  n );
                m_gal->DrawRectangle( VECTOR2D( -m, -n ), VECTOR2D( m, n ) );
            }
        }
        break;

    case PAD_RECT:
        m_gal->DrawRectangle( VECTOR2D( -size.x, -size.y ), VECTOR2D( size.x, size.y ) );
        break;

    case PAD_TRAPEZOID:
    {
        std::deque<VECTOR2D> pointList;
        wxPoint corners[4];

        VECTOR2D padSize = VECTOR2D( aPad->GetSize().x, aPad->GetSize().y ) / 2;
        VECTOR2D deltaPadSize = size - padSize; // = solder[Paste/Mask]Margin or 0

        aPad->BuildPadPolygon( corners, wxSize( deltaPadSize.x, deltaPadSize.y ), 0.0 );
        pointList.push_back( VECTOR2D( corners[0] ) );
        pointList.push_back( VECTOR2D( corners[1] ) );
        pointList.push_back( VECTOR2D( corners[2] ) );
        pointList.push_back( VECTOR2D( corners[3] ) );

        if( m_pcbSettings.m_sketchMode[PADS_VISIBLE] )
        {
            // Add the beginning point to close the outline
            pointList.push_back( pointList.front() );
            m_gal->DrawPolyline( pointList );
        }
        else
        {
            m_gal->DrawPolygon( pointList );
        }
    }
    break;

    case PAD_CIRCLE:
        m_gal->DrawCircle( VECTOR2D( 0.0, 0.0 ), size.x );
        break;
    }

    m_gal->Restore();
}
Пример #19
0
void PCB_PAINTER::draw( const TRACK* aTrack, int aLayer )
{
    VECTOR2D start( aTrack->GetStart() );
    VECTOR2D end( aTrack->GetEnd() );
    int      width = aTrack->GetWidth();

    if( m_pcbSettings.m_netNamesOnTracks && IsNetnameLayer( aLayer ) )
    {
        // If there is a net name - display it on the track
        if( aTrack->GetNetCode() > NETINFO_LIST::UNCONNECTED )
        {
            VECTOR2D line = ( end - start );
            double length = line.EuclideanNorm();

            // Check if the track is long enough to have a netname displayed
            if( length < 10 * width )
                return;

            const wxString& netName = aTrack->GetShortNetname();
            VECTOR2D textPosition = start + line / 2.0;     // center of the track
            double textOrientation = -atan( line.y / line.x );
            double textSize = std::min( static_cast<double>( width ), length / netName.length() );

            // Set a proper color for the label
            const COLOR4D& color = m_pcbSettings.GetColor( aTrack, aTrack->GetLayer() );
            COLOR4D labelColor = m_pcbSettings.GetColor( NULL, aLayer );

            if( color.GetBrightness() > 0.5 )
                m_gal->SetStrokeColor( labelColor.Inverted() );
            else
                m_gal->SetStrokeColor( labelColor );

            m_gal->SetLineWidth( width / 10.0 );
            m_gal->SetBold( false );
            m_gal->SetItalic( false );
            m_gal->SetMirrored( false );
            m_gal->SetGlyphSize( VECTOR2D( textSize * 0.7, textSize * 0.7 ) );
            m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER );
            m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_CENTER );
            m_gal->StrokeText( netName, textPosition, textOrientation );
        }
    }
    else if( IsCopperLayer( aLayer ) )
    {
        // Draw a regular track
        const COLOR4D& color = m_pcbSettings.GetColor( aTrack, aLayer );
        m_gal->SetStrokeColor( color );
        m_gal->SetIsStroke( true );

        if( m_pcbSettings.m_sketchMode[TRACKS_VISIBLE] )
        {
            // Outline mode
            m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
            m_gal->SetIsFill( false );
        }
        else
        {
            // Filled mode
            m_gal->SetFillColor( color );
            m_gal->SetIsFill( true );
        }
        m_gal->DrawSegment( start, end, width );
    }
}
void WIDGET_EESCHEMA_COLOR_CONFIG::CreateControls()
{
    wxStaticText*   label;
    int             buttonId = 1800;

    m_mainBoxSizer = new wxBoxSizer( wxHORIZONTAL );
    SetSizer( m_mainBoxSizer );

    BUTTONINDEX* groups = buttonGroups;
    wxBoxSizer* columnBoxSizer = NULL;

    while( groups->m_Buttons != NULL )
    {
        COLORBUTTON* buttons = groups->m_Buttons;

        columnBoxSizer = new wxBoxSizer( wxVERTICAL );
        m_mainBoxSizer->Add( columnBoxSizer, 1, wxALIGN_TOP | wxLEFT, 5 );
        wxBoxSizer* rowBoxSizer = new wxBoxSizer( wxHORIZONTAL );
        columnBoxSizer->Add( rowBoxSizer, 0, wxGROW | wxLEFT | wxRIGHT | wxBOTTOM, 5 );

        // Add a text string to identify the column of color select buttons.
        label = new wxStaticText( this, wxID_ANY, groups->m_Name );

        // Make the column label font bold.
        wxFont font( label->GetFont() );
        font.SetWeight( wxFONTWEIGHT_BOLD );
        label->SetFont( font );

        rowBoxSizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5 );

        while( buttons->m_Layer >= 0 )
        {
            rowBoxSizer = new wxBoxSizer( wxHORIZONTAL );
            columnBoxSizer->Add( rowBoxSizer, 0, wxGROW | wxALL, 0 );

            COLOR4D color = GetLayerColor( SCH_LAYER_ID( buttons->m_Layer ) );
            currentColors[ buttons->m_Layer ] = color;

            wxMemoryDC iconDC;
            wxBitmap   bitmap( m_butt_size_pix );

            iconDC.SelectObject( bitmap );
            iconDC.SetPen( *wxBLACK_PEN );

            wxBrush brush;
            brush.SetColour( color.ToColour() );
            brush.SetStyle( wxBRUSHSTYLE_SOLID );
            iconDC.SetBrush( brush );
            iconDC.DrawRectangle( 0, 0, m_butt_size_pix.x, m_butt_size_pix.y );

            wxBitmapButton* bitmapButton = new wxBitmapButton(
                                    this, buttonId, bitmap, wxDefaultPosition,
                                    m_butt_size_pix + m_butt_border_pix + wxSize( 1, 1 ) );
            bitmapButton->SetClientData( (void*) buttons );

            rowBoxSizer->Add( bitmapButton, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 );

            label = new wxStaticText( this, wxID_ANY, wxGetTranslation( buttons->m_Name ) );
            rowBoxSizer->Add( label, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxBOTTOM, 5 );
            buttonId += 1;
            buttons++;
        }

        groups++;
    }

    Connect( 1800, buttonId, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIDGET_EESCHEMA_COLOR_CONFIG::SetColor ) );

    // Dialog now needs to be resized, but the associated command is found elsewhere.
}
void PCB_ONE_LAYER_SELECTOR::buildList()
{
    // Hide layerid column which is used only to know the layer id
    // not to be shown in dialogs
    m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 );
    m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 );

    int         left_row = 0;
    int         right_row = 0;
    wxString    layername;

    for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder();  ui_seq;  ++ui_seq )
    {
        LAYER_ID  layerid = *ui_seq;

        if( m_notAllowedLayersMask[layerid] )
            continue;

        COLOR4D color = GetLayerColor( layerid );
        layername = GetLayerName( layerid );

        if( IsCopperLayer( layerid ) )
        {
            if( left_row )
                m_leftGridLayers->AppendRows( 1 );

            m_leftGridLayers->SetCellBackgroundColour ( left_row, COLOR_COLNUM,
                                                        color.ToColour() );
            m_leftGridLayers->SetCellValue( left_row, LAYERNAME_COLNUM,
                                            layername );

            if( m_layerSelected == layerid )
            {
                m_leftGridLayers->SetCellValue( left_row, SELECT_COLNUM,
                                                wxT("X") );
                m_leftGridLayers->SetCellBackgroundColour ( left_row, SELECT_COLNUM,
                                                        color.ToColour() );
                m_leftGridLayers->SetGridCursor( left_row, LAYERNAME_COLNUM );
            }

            m_layersIdLeftColumn.push_back( layerid );
            left_row++;
        }
        else
        {
            if( right_row )
                m_rightGridLayers->AppendRows( 1 );

            m_rightGridLayers->SetCellBackgroundColour ( right_row, COLOR_COLNUM,
                                                         color.ToColour() );
            m_rightGridLayers->SetCellValue( right_row, LAYERNAME_COLNUM,
                                             layername );

            if( m_layerSelected == layerid )
            {
                m_rightGridLayers->SetCellValue( right_row, SELECT_COLNUM,
                                                 wxT("X") );
                m_rightGridLayers->SetCellBackgroundColour ( right_row, SELECT_COLNUM,
                                                         color.ToColour() );
                m_rightGridLayers->SetGridCursor( right_row, LAYERNAME_COLNUM );
            }

            m_layersIdRightColumn.push_back( layerid );
            right_row++;
        }
    }

    // Show only populated lists:
    if( left_row <= 0 )
        m_leftGridLayers->Show( false );

    if( right_row <= 0 )
        m_rightGridLayers->Show( false );

    m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
    m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
    m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM);
    m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
}