diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index 7be37ffcae..06aba33cb3 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -556,6 +556,7 @@ set( COMMON_SRCS hotkeys_basic.cpp kiface_base.cpp kiway_player.cpp + layer_presentation.cpp lib_table_grid_tricks.cpp lib_tree_model.cpp lib_tree_model_adapter.cpp diff --git a/common/layer_presentation.cpp b/common/layer_presentation.cpp new file mode 100644 index 0000000000..0f2a9bc2aa --- /dev/null +++ b/common/layer_presentation.cpp @@ -0,0 +1,171 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "layer_presentation.h" + +#include <wx/bitmap.h> +#include <wx/dcmemory.h> + +#include <gal/color4d.h> + + +using namespace KIGFX; + + +void LAYER_PRESENTATION::DrawColorSwatch( wxBitmap& aLayerbmp, const COLOR4D& aBackground, + const COLOR4D& aColor ) +{ + wxMemoryDC bmpDC; + wxBrush brush; + + // Prepare Bitmap + bmpDC.SelectObject( aLayerbmp ); + + brush.SetStyle( wxBRUSHSTYLE_SOLID ); + + if( aBackground != COLOR4D::UNSPECIFIED ) + { + brush.SetColour( aBackground.WithAlpha( 1.0 ).ToColour() ); + bmpDC.SetBrush( brush ); + bmpDC.DrawRectangle( 0, 0, aLayerbmp.GetWidth(), aLayerbmp.GetHeight() ); + } + + brush.SetColour( aColor.ToColour() ); + bmpDC.SetBrush( brush ); + bmpDC.DrawRectangle( 0, 0, aLayerbmp.GetWidth(), aLayerbmp.GetHeight() ); + + bmpDC.SetBrush( *wxTRANSPARENT_BRUSH ); + bmpDC.SetPen( *wxBLACK_PEN ); + bmpDC.DrawRectangle( 0, 0, aLayerbmp.GetWidth(), aLayerbmp.GetHeight() ); +} + + +void LAYER_PRESENTATION::DrawColorSwatch( wxBitmap& aLayerbmp, int aLayer ) const +{ + const COLOR4D bgColor = getLayerColor( LAYER_PCB_BACKGROUND ); + const COLOR4D color = getLayerColor( aLayer ); + + DrawColorSwatch( aLayerbmp, bgColor, color ); +} + + +static constexpr unsigned BM_LAYERICON_SIZE = 24; +static const char s_BitmapLayerIcon[BM_LAYERICON_SIZE][BM_LAYERICON_SIZE] = { + // 0 = draw pixel with white + // 1 = draw pixel with black + // 2 = draw pixel with top layer from router pair + // 3 = draw pixel with bottom layer from router pair + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, + { 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, +}; + +static COLOR4D ICON_WHITE{ 0.86, 0.86, 0.86, 1.0 }; +static COLOR4D ICON_BLACK{ 0.28, 0.28, 0.28, 1.0 }; + + +std::unique_ptr<wxBitmap> LAYER_PRESENTATION::CreateLayerPairIcon( const COLOR4D& aBgColor, const COLOR4D& aTopColor, + const COLOR4D& aBottomColor, int aScale ) +{ + auto layerPairBitmap = std::make_unique<wxBitmap>( BM_LAYERICON_SIZE, BM_LAYERICON_SIZE ); + + // Draw the icon, with colors according to the router's layer pair + wxMemoryDC iconDC; + iconDC.SelectObject( *layerPairBitmap ); + wxBrush brush; + wxPen pen; + int buttonColor = -1; + + brush.SetStyle( wxBRUSHSTYLE_SOLID ); + brush.SetColour( aBgColor.WithAlpha( 1.0 ).ToColour() ); + iconDC.SetBrush( brush ); + iconDC.DrawRectangle( 0, 0, BM_LAYERICON_SIZE, BM_LAYERICON_SIZE ); + + for( unsigned ii = 0; ii < BM_LAYERICON_SIZE; ii++ ) + { + for( unsigned jj = 0; jj < BM_LAYERICON_SIZE; jj++ ) + { + if( s_BitmapLayerIcon[ii][jj] != buttonColor ) + { + switch( s_BitmapLayerIcon[ii][jj] ) + { + default: + case 0: pen.SetColour( ICON_WHITE.ToColour() ); break; + case 1: pen.SetColour( ICON_BLACK.ToColour() ); break; + case 2: pen.SetColour( aTopColor.ToColour() ); break; + case 3: pen.SetColour( aBottomColor.ToColour() ); break; + } + + buttonColor = s_BitmapLayerIcon[ii][jj]; + iconDC.SetPen( pen ); + } + + iconDC.DrawPoint( jj, ii ); + } + } + + // Deselect the bitmap from the DC in order to delete the MemoryDC safely without + // deleting the bitmap + iconDC.SelectObject( wxNullBitmap ); + + // Scale the bitmap + wxImage image = layerPairBitmap->ConvertToImage(); + + // "NEAREST" causes less mixing of colors + image.Rescale( aScale * image.GetWidth() / 4, aScale * image.GetHeight() / 4, + wxIMAGE_QUALITY_NEAREST ); + + return std::make_unique<wxBitmap>( image ); +} + + +std::unique_ptr<wxBitmap> LAYER_PRESENTATION::CreateLayerPairIcon( const LAYER_PAIR& aPair, + int aScale ) const +{ + const COLOR4D bgColor = getLayerColor( LAYER_PCB_BACKGROUND ); + const COLOR4D topColor = getLayerColor( aPair.GetLayerA() ); + const COLOR4D bottomColor = getLayerColor( aPair.GetLayerB() ); + + return CreateLayerPairIcon( bgColor, topColor, bottomColor, aScale ); +} \ No newline at end of file diff --git a/common/widgets/layer_box_selector.cpp b/common/widgets/layer_box_selector.cpp index d99a07c618..b7450522e9 100644 --- a/common/widgets/layer_box_selector.cpp +++ b/common/widgets/layer_box_selector.cpp @@ -47,34 +47,6 @@ bool LAYER_SELECTOR::SetLayersHotkeys( bool value ) } -void LAYER_SELECTOR::DrawColorSwatch( wxBitmap& aLayerbmp, const COLOR4D& aBackground, - const COLOR4D& aColor ) -{ - wxMemoryDC bmpDC; - wxBrush brush; - - // Prepare Bitmap - bmpDC.SelectObject( aLayerbmp ); - - brush.SetStyle( wxBRUSHSTYLE_SOLID ); - - if( aBackground != COLOR4D::UNSPECIFIED ) - { - brush.SetColour( aBackground.WithAlpha( 1.0 ).ToColour() ); - bmpDC.SetBrush( brush ); - bmpDC.DrawRectangle( 0, 0, aLayerbmp.GetWidth(), aLayerbmp.GetHeight() ); - } - - brush.SetColour( aColor.ToColour() ); - bmpDC.SetBrush( brush ); - bmpDC.DrawRectangle( 0, 0, aLayerbmp.GetWidth(), aLayerbmp.GetHeight() ); - - bmpDC.SetBrush( *wxTRANSPARENT_BRUSH ); - bmpDC.SetPen( *wxBLACK_PEN ); - bmpDC.DrawRectangle( 0, 0, aLayerbmp.GetWidth(), aLayerbmp.GetHeight() ); -} - - LAYER_BOX_SELECTOR::LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, int n, const wxString choices[] ) : wxBitmapComboBox( parent, id, wxEmptyString, pos, size, n, choices, wxCB_READONLY ), diff --git a/gerbview/widgets/gbr_layer_box_selector.cpp b/gerbview/widgets/gbr_layer_box_selector.cpp index 89471c7231..f4ea864b7c 100644 --- a/gerbview/widgets/gbr_layer_box_selector.cpp +++ b/gerbview/widgets/gbr_layer_box_selector.cpp @@ -23,6 +23,10 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "gbr_layer_box_selector.h" + +#include <layer_presentation.h> + #include <gerbview_frame.h> #include <gerber_file_image_list.h> @@ -30,7 +34,44 @@ #include <dpi_scaling_common.h> #endif -#include "gbr_layer_box_selector.h" + +/** + * Gerbview-specific implementation of the LAYER_PRESENTATION interface. + */ +class GBR_LAYER_PRESENTATION : public LAYER_PRESENTATION +{ +public: + GBR_LAYER_PRESENTATION( GERBVIEW_FRAME& aFrame ) : m_frame( aFrame ) {} + + // Returns a color index from the layer id + COLOR4D getLayerColor( int aLayer ) const override + { + return m_frame.GetLayerColor( GERBER_DRAW_LAYER( aLayer ) ); + } + + // Returns the name of the layer id + wxString getLayerName( int aLayer ) const override + { + GERBER_FILE_IMAGE_LIST& images = GERBER_FILE_IMAGE_LIST::GetImagesList(); + wxString name = images.GetDisplayName( aLayer ); + + return name; + } + +private: + GERBVIEW_FRAME& m_frame; +}; + + +GBR_LAYER_BOX_SELECTOR::GBR_LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id, const wxPoint& pos, + const wxSize& size, int n, + const wxString choices[] ) : + LAYER_BOX_SELECTOR( parent, id, pos, size, n, choices ), + m_layerPresentation( std::make_unique<GBR_LAYER_PRESENTATION>( + static_cast<GERBVIEW_FRAME&>( *parent->GetParent() ) ) ) +{ + m_layerhotkeys = false; +} void GBR_LAYER_BOX_SELECTOR::Resync() { @@ -57,14 +98,14 @@ void GBR_LAYER_BOX_SELECTOR::Resync() { wxBitmap bmp( size * scale, size * scale ); - DrawColorSwatch( bmp, getLayerColor( LAYER_PCB_BACKGROUND ), getLayerColor( layerid ) ); + m_layerPresentation->DrawColorSwatch( bmp, layerid ); bmp.SetScaleFactor( scale ); bitmaps.push_back( bmp ); } - Append( getLayerName( layerid ), wxBitmapBundle::FromBitmaps( bitmaps ), - (void*) (intptr_t) layerid ); + Append( m_layerPresentation->getLayerName( layerid ), + wxBitmapBundle::FromBitmaps( bitmaps ), (void*) (intptr_t) layerid ); } // Ensure the size of the widget is enough to show the text and the icon @@ -88,22 +129,3 @@ void GBR_LAYER_BOX_SELECTOR::Resync() Thaw(); } - - -// Returns a color index from the layer id -COLOR4D GBR_LAYER_BOX_SELECTOR::getLayerColor( int aLayer ) const -{ - GERBVIEW_FRAME* frame = (GERBVIEW_FRAME*) GetParent()->GetParent(); - - return frame->GetLayerColor( GERBER_DRAW_LAYER( aLayer ) ); -} - - -// Returns the name of the layer id -wxString GBR_LAYER_BOX_SELECTOR::getLayerName( int aLayer ) const -{ - GERBER_FILE_IMAGE_LIST& images = GERBER_FILE_IMAGE_LIST::GetImagesList(); - wxString name = images.GetDisplayName( aLayer ); - - return name; -} diff --git a/gerbview/widgets/gbr_layer_box_selector.h b/gerbview/widgets/gbr_layer_box_selector.h index 44dbba6a39..b1d2474a11 100644 --- a/gerbview/widgets/gbr_layer_box_selector.h +++ b/gerbview/widgets/gbr_layer_box_selector.h @@ -23,35 +23,30 @@ */ #ifndef GBR_LAYER_BOX_SELECTOR_H -#define GBR_LAYER_BOX_SELECTOR_H 1 +#define GBR_LAYER_BOX_SELECTOR_H + +#include <memory> #include <widgets/layer_box_selector.h> +class LAYER_PRESENTATION; // class to display a layer list in GerbView. class GBR_LAYER_BOX_SELECTOR : public LAYER_BOX_SELECTOR { public: - GBR_LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - int n = 0, const wxString choices[] = nullptr ) : - LAYER_BOX_SELECTOR( parent, id, pos, size, n, choices ) - { - m_layerhotkeys = false; - } + GBR_LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id, const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, int n = 0, + const wxString choices[] = nullptr ); // Reload the Layers names and bitmaps void Resync() override; - // Return a color index from the layer id - COLOR4D getLayerColor( int aLayer ) const override; - // Return true if the layer id is enabled (i.e. is it should be displayed) bool isLayerEnabled( int aLayer ) const override { return true; } - // Return the name of the layer id - wxString getLayerName( int aLayer ) const override; +private: + std::unique_ptr<LAYER_PRESENTATION> m_layerPresentation; }; #endif //GBR_LAYER_BOX_SELECTOR_H diff --git a/include/layer_presentation.h b/include/layer_presentation.h new file mode 100644 index 0000000000..9dc208152c --- /dev/null +++ b/include/layer_presentation.h @@ -0,0 +1,73 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef LAYER_PRESENTATION_H +#define LAYER_PRESENTATION_H + +#include <gal/color4d.h> +#include <layer_ids.h> +#include <layer_pairs.h> + +class wxBitmap; + +using KIGFX::COLOR4D; + +/** + * Base class for an object that can provide information about + * presenting layers (colours, etc). + */ +class LAYER_PRESENTATION +{ +public: + // Return a color index from the layer id + virtual COLOR4D getLayerColor( int aLayer ) const = 0; + + // Return the name of the layer id + virtual wxString getLayerName( int aLayer ) const = 0; + + // Fill the layer bitmap aLayerbmp with the layer color + static void DrawColorSwatch( wxBitmap& aLayerbmp, const COLOR4D& aBackground, + const COLOR4D& aColor ); + + /** + * Fill the layer bitmap aLayerbmp with the layer color + * for the layer ID. + */ + void DrawColorSwatch( wxBitmap& aLayerbmp, int aLayer ) const; + + /** + * Create a layer pair "side-by-side swatch" icon + */ + static std::unique_ptr<wxBitmap> CreateLayerPairIcon( const KIGFX::COLOR4D& aBgColor, + const KIGFX::COLOR4D& aTopColor, + const KIGFX::COLOR4D& aBottomColor, + int aScale ); + + /** + * Create a layer pair "side-by-side swatch" icon for the given + * layer pair with the style of this presentation. + */ + std::unique_ptr<wxBitmap> CreateLayerPairIcon( const LAYER_PAIR& aPair, int aScale ) const; +}; + +#endif // LAYER_PRESENTATION_H \ No newline at end of file diff --git a/include/widgets/layer_box_selector.h b/include/widgets/layer_box_selector.h index e275bd1bcc..2f1849ff01 100644 --- a/include/widgets/layer_box_selector.h +++ b/include/widgets/layer_box_selector.h @@ -26,10 +26,7 @@ #define LAYER_BOX_SELECTOR_H #include <wx/bmpcbox.h> -#include <gal/color4d.h> -#include <layer_ids.h> -using KIGFX::COLOR4D; /** * Base class to build a layer list. @@ -43,17 +40,7 @@ public: bool SetLayersHotkeys( bool value ); - // Fill the layer bitmap aLayerbmp with the layer color - static void DrawColorSwatch( wxBitmap& aLayerbmp, const COLOR4D& aBackground, - const COLOR4D& aColor ); - protected: - // Return a color index from the layer id - virtual COLOR4D getLayerColor( int aLayer ) const = 0; - - // Return the name of the layer id - virtual wxString getLayerName( int aLayer ) const = 0; - // Return true if the layer id is enabled (i.e. is it should be displayed) virtual bool isLayerEnabled( int aLayer ) const = 0; diff --git a/pcbnew/board_stackup_manager/panel_board_stackup.cpp b/pcbnew/board_stackup_manager/panel_board_stackup.cpp index 9e96dc1b58..ef7d0022ad 100644 --- a/pcbnew/board_stackup_manager/panel_board_stackup.cpp +++ b/pcbnew/board_stackup_manager/panel_board_stackup.cpp @@ -26,6 +26,7 @@ #include <pcb_edit_frame.h> #include <board.h> #include <board_design_settings.h> +#include <layer_presentation.h> #include <dialogs/dialog_color_picker.h> #include <widgets/paged_dialog.h> #include <widgets/layer_box_selector.h> @@ -684,7 +685,7 @@ void PANEL_SETUP_BOARD_STACKUP::synchronizeWithBoard( bool aFullSync ) { bm_combo->SetString( selected, item->GetColor( sub_item ) ); wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y ); - LAYER_SELECTOR::DrawColorSwatch( layerbmp, COLOR4D(), custom_color ); + LAYER_PRESENTATION::DrawColorSwatch( layerbmp, COLOR4D(), custom_color ); bm_combo->SetItemBitmap( selected, layerbmp ); } } @@ -1404,7 +1405,7 @@ void PANEL_SETUP_BOARD_STACKUP::onColorSelected( wxCommandEvent& event ) combo->SetString( idx, color.ToHexString() ); wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y ); - LAYER_SELECTOR::DrawColorSwatch( layerbmp, COLOR4D( 0, 0, 0, 0 ), color ); + LAYER_PRESENTATION::DrawColorSwatch( layerbmp, COLOR4D( 0, 0, 0, 0 ), color ); combo->SetItemBitmap( combo->GetCount() - 1, layerbmp ); combo->SetSelection( idx ); @@ -1654,7 +1655,7 @@ wxBitmapComboBox* PANEL_SETUP_BOARD_STACKUP::createColorBox( BOARD_STACKUP_ITEM* } wxBitmap layerbmp( m_colorSwatchesSize.x, m_colorSwatchesSize.y ); - LAYER_SELECTOR::DrawColorSwatch( layerbmp, COLOR4D( 0, 0, 0, 0 ), curr_color ); + LAYER_PRESENTATION::DrawColorSwatch( layerbmp, COLOR4D( 0, 0, 0, 0 ), curr_color ); combo->Append( label, layerbmp ); } diff --git a/pcbnew/grid_layer_box_helpers.cpp b/pcbnew/grid_layer_box_helpers.cpp index 57cfd5c278..30ee18ad34 100644 --- a/pcbnew/grid_layer_box_helpers.cpp +++ b/pcbnew/grid_layer_box_helpers.cpp @@ -22,17 +22,20 @@ */ #include <grid_layer_box_helpers.h> + +#include <wx/textctrl.h> + #include <pgm_base.h> #include <settings/settings_manager.h> #include <settings/color_settings.h> #include <footprint_editor_settings.h> #include <board.h> +#include <layer_presentation.h> #include <lset.h> #include <pcb_edit_frame.h> #include <pcb_layer_box_selector.h> #include <settings/color_settings.h> #include <widgets/layer_box_selector.h> -#include <wx/textctrl.h> //-------- Custom wxGridCellRenderers -------------------------------------------------- @@ -76,9 +79,9 @@ void GRID_CELL_LAYER_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& int size = KiROUND( 14 * aDC.GetContentScaleFactor() ); wxBitmap bitmap( size, size ); - LAYER_SELECTOR::DrawColorSwatch( bitmap, - cs->GetColor( ToLAYER_ID( LAYER_PCB_BACKGROUND ) ), - cs->GetColor( ToLAYER_ID( value ) ) ); + LAYER_PRESENTATION::DrawColorSwatch( bitmap, + cs->GetColor( ToLAYER_ID( LAYER_PCB_BACKGROUND ) ), + cs->GetColor( ToLAYER_ID( value ) ) ); aDC.DrawBitmap( bitmap, rect.GetLeft() + 4, rect.GetTop() + ( rect.GetHeight() - bitmap.GetHeight() ) / 2, true ); diff --git a/pcbnew/pcb_layer_box_selector.cpp b/pcbnew/pcb_layer_box_selector.cpp index fd17b07292..ac831a0598 100644 --- a/pcbnew/pcb_layer_box_selector.cpp +++ b/pcbnew/pcb_layer_box_selector.cpp @@ -23,19 +23,35 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ -#include <pgm_base.h> -#include <settings/settings_manager.h> -#include <footprint_editor_settings.h> -#include <pcb_edit_frame.h> -#include <layer_ids.h> -#include <settings/color_settings.h> +#include "pcb_layer_box_selector.h" + #include <board.h> -#include <pcb_layer_box_selector.h> +#include <layer_ids.h> +#include <pcb_edit_frame.h> +#include <pcb_layer_presentation.h> +#include <settings/color_settings.h> #include <tools/pcb_actions.h> #include <dpi_scaling_common.h> -// class to display a layer list in a wxBitmapComboBox. +PCB_LAYER_BOX_SELECTOR::PCB_LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id, + const wxString& value, const wxPoint& pos, + const wxSize& size, int n, const wxString choices[], + int style ) : + LAYER_BOX_SELECTOR( parent, id, pos, size, n, choices ), m_boardFrame( nullptr ), + m_showNotEnabledBrdlayers( false ), + m_layerPresentation( std::make_unique<PCB_LAYER_PRESENTATION>( + nullptr ) ) // The parent isn't awlays the frame +{ +} + + +void PCB_LAYER_BOX_SELECTOR::SetBoardFrame( PCB_BASE_FRAME* aFrame ) +{ + m_boardFrame = aFrame; + m_layerPresentation->SetBoardFrame( m_boardFrame ); +} + // Reload the Layers void PCB_LAYER_BOX_SELECTOR::Resync() @@ -64,13 +80,13 @@ void PCB_LAYER_BOX_SELECTOR::Resync() { wxBitmap bmp( size * scale, size * scale ); - DrawColorSwatch( bmp, getLayerColor( LAYER_PCB_BACKGROUND ), getLayerColor( layerid ) ); + m_layerPresentation->DrawColorSwatch( bmp, layerid ); bmp.SetScaleFactor( scale ); bitmaps.push_back( bmp ); } - wxString layername = getLayerName( layerid ) + layerstatus; + wxString layername = m_layerPresentation->getLayerName( layerid ) + layerstatus; if( m_layerhotkeys ) { @@ -122,31 +138,3 @@ LSET PCB_LAYER_BOX_SELECTOR::getEnabledLayers() const else return footprintEditorLayers; } - - -// Returns a color index from the layer id -COLOR4D PCB_LAYER_BOX_SELECTOR::getLayerColor( int aLayer ) const -{ - if( m_boardFrame ) - { - return m_boardFrame->GetColorSettings()->GetColor( aLayer ); - } - else - { - SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager(); - FOOTPRINT_EDITOR_SETTINGS* settings = mgr.GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>(); - COLOR_SETTINGS* current = mgr.GetColorSettings( settings->m_ColorTheme ); - - return current->GetColor( aLayer ); - } -} - - -// Returns the name of the layer id -wxString PCB_LAYER_BOX_SELECTOR::getLayerName( int aLayer ) const -{ - if( m_boardFrame ) - return m_boardFrame->GetBoard()->GetLayerName( ToLAYER_ID( aLayer ) ); - else - return BOARD::GetStandardLayerName( ToLAYER_ID( aLayer ) ); -} diff --git a/pcbnew/pcb_layer_box_selector.h b/pcbnew/pcb_layer_box_selector.h index e9ce2c9b7c..0c58828cb7 100644 --- a/pcbnew/pcb_layer_box_selector.h +++ b/pcbnew/pcb_layer_box_selector.h @@ -25,10 +25,14 @@ #ifndef PCB_LAYER_BOX_SELECTOR_H #define PCB_LAYER_BOX_SELECTOR_H +#include <memory> + #include <lset.h> #include <widgets/layer_box_selector.h> class PCB_BASE_FRAME; +class PCB_LAYER_PRESENTATION; + /** * Class to display a pcb layer list in a wxBitmapComboBox. @@ -39,21 +43,15 @@ public: // If you are thinking the constructor is a bit curious, just remember it is automatically // generated when used in wxFormBuilder files, and so must have the same signature as the // wxBitmapComboBox constructor. In particular, value and style are not used by this class. - PCB_LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id, - const wxString& value = wxEmptyString, + PCB_LAYER_BOX_SELECTOR( wxWindow* parent, wxWindowID id, const wxString& value = wxEmptyString, const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - int n = 0, const wxString choices[] = nullptr, int style = 0 ) : - LAYER_BOX_SELECTOR( parent, id, pos, size, n, choices ) - { - m_boardFrame = nullptr; - m_showNotEnabledBrdlayers = false; - } + const wxSize& size = wxDefaultSize, int n = 0, + const wxString choices[] = nullptr, int style = 0 ); // SetBoardFrame should be called after creating a PCB_LAYER_BOX_SELECTOR. It is not passed // through the constructor because it must have the same signature as wxBitmapComboBox for // use with wxFormBuilder. - void SetBoardFrame( PCB_BASE_FRAME* aFrame ) { m_boardFrame = aFrame; }; + void SetBoardFrame( PCB_BASE_FRAME* aFrame ); // SetLayerSet allows disabling some layers, which are not shown in list void SetNotAllowedLayerSet( LSET aMask ) { m_layerMaskDisable = aMask; } @@ -70,15 +68,9 @@ public: void ShowNonActivatedLayers( bool aShow ) { m_showNotEnabledBrdlayers = aShow; } private: - // Returns a color index from the layer id - COLOR4D getLayerColor( int aLayer ) const override; - // Returns true if the layer id is enabled (i.e. if it should be displayed) bool isLayerEnabled( int aLayer ) const override; - // Returns the name of the layer id - wxString getLayerName( int aLayer ) const override; - LSET getEnabledLayers() const; PCB_BASE_FRAME* m_boardFrame; @@ -89,6 +81,8 @@ private: // (with not activated layers flagged) wxString m_undefinedLayerName; // if not empty add an item with this name which sets // the layer to UNDEFINED_LAYER + + std::unique_ptr<PCB_LAYER_PRESENTATION> m_layerPresentation; }; #endif // PCB_LAYER_BOX_SELECTOR_H diff --git a/pcbnew/pcb_layer_presentation.h b/pcbnew/pcb_layer_presentation.h new file mode 100644 index 0000000000..4b39de422d --- /dev/null +++ b/pcbnew/pcb_layer_presentation.h @@ -0,0 +1,53 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef PCB_LAYER_PRESENTATION_H +#define PCB_LAYER_PRESENTATION_H + +#include <layer_presentation.h> + +class PCB_BASE_FRAME; + +/** + * Class that manages the presentation of PCB layers in a PCB frame. + */ +class PCB_LAYER_PRESENTATION : public LAYER_PRESENTATION +{ +public: + PCB_LAYER_PRESENTATION( PCB_BASE_FRAME* aFrame ); + + COLOR4D getLayerColor( int aLayer ) const override; + + wxString getLayerName( int aLayer ) const override; + + /** + * Annoying post-ctor initialization (for when PCB_LAYER_BOX_SELECTOR doesn't + * have access to the PCB_BASE_FRAME at construction time). + */ + void SetBoardFrame( PCB_BASE_FRAME* aFrame ) { m_boardFrame = aFrame; } + +private: + PCB_BASE_FRAME* m_boardFrame; +}; + +#endif // PCB_LAYER_PRESENTATION_H \ No newline at end of file diff --git a/pcbnew/sel_layer.cpp b/pcbnew/sel_layer.cpp index 48ca2e1774..ff9946af35 100644 --- a/pcbnew/sel_layer.cpp +++ b/pcbnew/sel_layer.cpp @@ -26,11 +26,14 @@ #include <kiplatform/ui.h> #include <confirm.h> #include <lset.h> -#include <pcb_base_frame.h> -#include <widgets/layer_box_selector.h> #include <board.h> +#include <pgm_base.h> +#include <pcb_base_frame.h> +#include <pcb_layer_presentation.h> +#include <footprint_editor_settings.h> #include <dialogs/dialog_layer_selection_base.h> #include <router/router_tool.h> +#include <settings/settings_manager.h> #include <settings/color_settings.h> #include <tools/pcb_actions.h> @@ -40,45 +43,40 @@ #define LAYERNAME_COLNUM 2 #define LAYER_HK_COLUMN 3 -/* - * Display a layer list using a wxGrid. - */ -class PCB_LAYER_SELECTOR: public LAYER_SELECTOR + +PCB_LAYER_PRESENTATION::PCB_LAYER_PRESENTATION( PCB_BASE_FRAME* aFrame ) : m_boardFrame( aFrame ) { -public: - PCB_LAYER_SELECTOR( PCB_BASE_FRAME* aFrame ) : - LAYER_SELECTOR() - { - m_frame = aFrame; - } +} -protected: - PCB_BASE_FRAME* m_frame; - - ///< @return true if the layer id is enabled (i.e. is it should be displayed). - bool isLayerEnabled( int aLayer ) const override +COLOR4D PCB_LAYER_PRESENTATION::getLayerColor( int aLayer ) const +{ + if( m_boardFrame ) { - return m_frame->GetBoard()->IsLayerEnabled( PCB_LAYER_ID( aLayer ) ); + return m_boardFrame->GetColorSettings()->GetColor( aLayer ); } - - // Return the color index from the layer ID. - COLOR4D getLayerColor( int aLayer ) const override + else { - return m_frame->GetColorSettings()->GetColor( aLayer ); - } + SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager(); + FOOTPRINT_EDITOR_SETTINGS* settings = mgr.GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>(); + COLOR_SETTINGS* current = mgr.GetColorSettings( settings->m_ColorTheme ); - // Return the name of the layer ID. - wxString getLayerName( int aLayer ) const override - { - return m_frame->GetBoard()->GetLayerName( ToLAYER_ID( aLayer ) ); + return current->GetColor( aLayer ); } -}; +} + +wxString PCB_LAYER_PRESENTATION::getLayerName( int aLayer ) const +{ + if( m_boardFrame ) + return m_boardFrame->GetBoard()->GetLayerName( ToLAYER_ID( aLayer ) ); + else + return BOARD::GetStandardLayerName( ToLAYER_ID( aLayer ) ); +} /** * Display a PCB layers list in a dialog to select one layer from this list. */ -class PCB_ONE_LAYER_SELECTOR : public PCB_LAYER_SELECTOR, public DIALOG_LAYER_SELECTION_BASE +class PCB_ONE_LAYER_SELECTOR : public DIALOG_LAYER_SELECTION_BASE { public: PCB_ONE_LAYER_SELECTOR( PCB_BASE_FRAME* aParent, BOARD * aBrd, PCB_LAYER_ID aDefaultLayer, @@ -104,6 +102,7 @@ private: void buildList(); + PCB_LAYER_PRESENTATION m_layerPresentation; PCB_LAYER_ID m_layerSelected; LSET m_notAllowedLayersMask; BOARD* m_brd; @@ -114,10 +113,8 @@ private: PCB_ONE_LAYER_SELECTOR::PCB_ONE_LAYER_SELECTOR( PCB_BASE_FRAME* aParent, BOARD* aBrd, PCB_LAYER_ID aDefaultLayer, - LSET aNotAllowedLayersMask, - bool aHideCheckBoxes ) : - PCB_LAYER_SELECTOR( aParent ), - DIALOG_LAYER_SELECTION_BASE( aParent ) + LSET aNotAllowedLayersMask, bool aHideCheckBoxes ) : + DIALOG_LAYER_SELECTION_BASE( aParent ), m_layerPresentation( aParent ) { m_useCalculatedSize = true; @@ -198,7 +195,7 @@ void PCB_ONE_LAYER_SELECTOR::onCharHook( wxKeyEvent& event ) void PCB_ONE_LAYER_SELECTOR::buildList() { - wxColour bg = getLayerColor( LAYER_PCB_BACKGROUND ).ToColour(); + wxColour bg = m_layerPresentation.getLayerColor( LAYER_PCB_BACKGROUND ).ToColour(); int left_row = 0; int right_row = 0; wxString layername; @@ -208,12 +205,12 @@ void PCB_ONE_LAYER_SELECTOR::buildList() if( m_notAllowedLayersMask[layerid] ) continue; - wxColour fg = getLayerColor( layerid ).ToColour(); + wxColour fg = m_layerPresentation.getLayerColor( layerid ).ToColour(); wxColour color( wxColour::AlphaBlend( fg.Red(), bg.Red(), fg.Alpha() / 255.0 ), wxColour::AlphaBlend( fg.Green(), bg.Green(), fg.Alpha() / 255.0 ), wxColour::AlphaBlend( fg.Blue(), bg.Blue(), fg.Alpha() / 255.0 ) ); - layername = wxT( " " ) + getLayerName( layerid ); + layername = wxT( " " ) + m_layerPresentation.getLayerName( layerid ); if( IsCopperLayer( layerid ) ) { @@ -304,8 +301,7 @@ PCB_LAYER_ID PCB_BASE_FRAME::SelectOneLayer( PCB_LAYER_ID aDefaultLayer, LSET aN /** * Display a pair PCB copper layers list in a dialog to select a layer pair from these lists. */ -class SELECT_COPPER_LAYERS_PAIR_DIALOG: public PCB_LAYER_SELECTOR, - public DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE +class SELECT_COPPER_LAYERS_PAIR_DIALOG : public DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE { public: SELECT_COPPER_LAYERS_PAIR_DIALOG( PCB_BASE_FRAME* aParent, BOARD* aPcb, @@ -323,11 +319,12 @@ private: void buildList(); - BOARD* m_brd; - PCB_LAYER_ID m_frontLayer; - PCB_LAYER_ID m_backLayer; - int m_leftRowSelected; - int m_rightRowSelected; + PCB_LAYER_PRESENTATION m_layerPresentation; + BOARD* m_brd; + PCB_LAYER_ID m_frontLayer; + PCB_LAYER_ID m_backLayer; + int m_leftRowSelected; + int m_rightRowSelected; std::vector<PCB_LAYER_ID> m_layersId; }; @@ -354,10 +351,11 @@ int ROUTER_TOOL::SelectCopperLayerPair( const TOOL_EVENT& aEvent ) } -SELECT_COPPER_LAYERS_PAIR_DIALOG::SELECT_COPPER_LAYERS_PAIR_DIALOG( - PCB_BASE_FRAME* aParent, BOARD * aPcb, PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer) : - PCB_LAYER_SELECTOR( aParent ), - DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE( aParent ) +SELECT_COPPER_LAYERS_PAIR_DIALOG::SELECT_COPPER_LAYERS_PAIR_DIALOG( PCB_BASE_FRAME* aParent, + BOARD* aPcb, + PCB_LAYER_ID aFrontLayer, + PCB_LAYER_ID aBackLayer ) : + DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE( aParent ), m_layerPresentation( aParent ) { m_frontLayer = aFrontLayer; m_backLayer = aBackLayer; @@ -380,7 +378,7 @@ SELECT_COPPER_LAYERS_PAIR_DIALOG::SELECT_COPPER_LAYERS_PAIR_DIALOG( void SELECT_COPPER_LAYERS_PAIR_DIALOG::buildList() { - wxColour bg = getLayerColor( LAYER_PCB_BACKGROUND ).ToColour(); + wxColour bg = m_layerPresentation.getLayerColor( LAYER_PCB_BACKGROUND ).ToColour(); int row = 0; wxString layername; @@ -389,12 +387,12 @@ void SELECT_COPPER_LAYERS_PAIR_DIALOG::buildList() if( !IsCopperLayer( layerid ) ) continue; - wxColour fg = getLayerColor( layerid ).ToColour(); + wxColour fg = m_layerPresentation.getLayerColor( layerid ).ToColour(); wxColour color( wxColour::AlphaBlend( fg.Red(), bg.Red(), fg.Alpha() / 255.0 ), wxColour::AlphaBlend( fg.Green(), bg.Green(), fg.Alpha() / 255.0 ), wxColour::AlphaBlend( fg.Blue(), bg.Blue(), fg.Alpha() / 255.0 ) ); - layername = wxT( " " ) + getLayerName( layerid ); + layername = wxT( " " ) + m_layerPresentation.getLayerName( layerid ); if( row ) m_leftGridLayers->AppendRows( 1 ); diff --git a/pcbnew/toolbars_pcb_editor.cpp b/pcbnew/toolbars_pcb_editor.cpp index db50672647..ee816bd853 100644 --- a/pcbnew/toolbars_pcb_editor.cpp +++ b/pcbnew/toolbars_pcb_editor.cpp @@ -33,6 +33,7 @@ #include <board_design_settings.h> #include <kiface_base.h> #include <kiplatform/ui.h> +#include <layer_presentation.h> #include <macros.h> #include <pcb_edit_frame.h> #include <pcb_layer_box_selector.h> @@ -49,12 +50,12 @@ #include <tools/pcb_actions.h> #include <tools/pcb_selection_tool.h> #include <widgets/appearance_controls.h> +#include <widgets/layer_box_selector.h> #include <widgets/pcb_properties_panel.h> #include <widgets/net_inspector_panel.h> #include <widgets/pcb_search_pane.h> #include <widgets/wx_aui_utils.h> #include <wx/wupdlock.h> -#include <wx/dcmemory.h> #include <wx/combobox.h> #include "../scripting/python_scripting.h" @@ -63,46 +64,9 @@ /* Data to build the layer pair indicator button */ static std::unique_ptr<wxBitmap> LayerPairBitmap; -#define BM_LAYERICON_SIZE 24 -static const char s_BitmapLayerIcon[BM_LAYERICON_SIZE][BM_LAYERICON_SIZE] = -{ - // 0 = draw pixel with white - // 1 = draw pixel with black - // 2 = draw pixel with top layer from router pair - // 3 = draw pixel with bottom layer from router pair - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, - { 2, 2, 2, 2, 2, 0, 1, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }, -}; - -static COLOR4D ICON_WHITE { 0.86, 0.86, 0.86, 1.0 }; -static COLOR4D ICON_BLACK { 0.28, 0.28, 0.28, 1.0 }; - void PCB_EDIT_FRAME::PrepareLayerIndicator( bool aForceRebuild ) { - int ii, jj; COLOR4D top_color, bottom_color, background_color; bool change = aForceRebuild; @@ -140,56 +104,9 @@ void PCB_EDIT_FRAME::PrepareLayerIndicator( bool aForceRebuild ) if( change || !LayerPairBitmap ) { - LayerPairBitmap = std::make_unique<wxBitmap>( 24, 24 ); - - // Draw the icon, with colors according to the router's layer pair - wxMemoryDC iconDC; - iconDC.SelectObject( *LayerPairBitmap ); - wxBrush brush; - wxPen pen; - int buttonColor = -1; - - brush.SetStyle( wxBRUSHSTYLE_SOLID ); - brush.SetColour( background_color.WithAlpha(1.0).ToColour() ); - iconDC.SetBrush( brush ); - iconDC.DrawRectangle( 0, 0, BM_LAYERICON_SIZE, BM_LAYERICON_SIZE ); - - for( ii = 0; ii < BM_LAYERICON_SIZE; ii++ ) - { - for( jj = 0; jj < BM_LAYERICON_SIZE; jj++ ) - { - if( s_BitmapLayerIcon[ii][jj] != buttonColor ) - { - switch( s_BitmapLayerIcon[ii][jj] ) - { - default: - case 0: pen.SetColour( ICON_WHITE.ToColour() ); break; - case 1: pen.SetColour( ICON_BLACK.ToColour() ); break; - case 2: pen.SetColour( top_color.ToColour() ); break; - case 3: pen.SetColour( bottom_color.ToColour() ); break; - } - - buttonColor = s_BitmapLayerIcon[ii][jj]; - iconDC.SetPen( pen ); - } - - iconDC.DrawPoint( jj, ii ); - } - } - - // Deselect the bitmap from the DC in order to delete the MemoryDC safely without - // deleting the bitmap - iconDC.SelectObject( wxNullBitmap ); - - // Scale the bitmap const int scale = ( requested_scale <= 0 ) ? KiIconScale( this ) : requested_scale; - wxImage image = LayerPairBitmap->ConvertToImage(); - - // "NEAREST" causes less mixing of colors - image.Rescale( scale * image.GetWidth() / 4, scale * image.GetHeight() / 4, - wxIMAGE_QUALITY_NEAREST ); - - LayerPairBitmap = std::make_unique<wxBitmap>( image ); + LayerPairBitmap = LAYER_PRESENTATION::CreateLayerPairIcon( background_color, top_color, + bottom_color, scale ); if( m_auxiliaryToolBar ) {