From db457f52fae92f489863af52ded5c95615f3c5ed Mon Sep 17 00:00:00 2001 From: John Beard <john.j.beard@gmail.com> Date: Wed, 24 Jul 2024 13:32:21 +0800 Subject: [PATCH] Move layer presentation logic to a separate class The separates it from the LAYER_SELECTOR class - deciding what color a layer is (say) is separate to managing the actual selection of the layer. For example, sel_layer.cpp only needs the presentation logic. This also makes it eaiser to compose rather than inherit. Additonally, break out the layer pair swatch function to this class. This will also be needed by the layer pair manager UI. Relates-To: https://gitlab.com/kicad/code/kicad/-/issues/15227 --- common/CMakeLists.txt | 1 + common/layer_presentation.cpp | 171 ++++++++++++++++++ common/widgets/layer_box_selector.cpp | 28 --- gerbview/widgets/gbr_layer_box_selector.cpp | 68 ++++--- gerbview/widgets/gbr_layer_box_selector.h | 23 +-- include/layer_presentation.h | 73 ++++++++ include/widgets/layer_box_selector.h | 13 -- .../panel_board_stackup.cpp | 7 +- pcbnew/grid_layer_box_helpers.cpp | 11 +- pcbnew/pcb_layer_box_selector.cpp | 64 +++---- pcbnew/pcb_layer_box_selector.h | 26 +-- pcbnew/pcb_layer_presentation.h | 53 ++++++ pcbnew/sel_layer.cpp | 98 +++++----- pcbnew/toolbars_pcb_editor.cpp | 91 +--------- 14 files changed, 451 insertions(+), 276 deletions(-) create mode 100644 common/layer_presentation.cpp create mode 100644 include/layer_presentation.h create mode 100644 pcbnew/pcb_layer_presentation.h 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 ) {