From edf13bdfd0beaef7602f19a31355a334c12804cd Mon Sep 17 00:00:00 2001 From: John Beard Date: Wed, 24 Jul 2024 13:28:46 +0800 Subject: [PATCH] Add a layer pair preset list This will later be used for a quick switcher UI. This commit adds the data structures, set-up UI and project file persistance. Relates-To: https://gitlab.com/kicad/code/kicad/-/issues/15227 --- common/project/board_project_settings.cpp | 64 + common/project/project_file.cpp | 2 + include/project/board_project_settings.h | 79 + include/project/project_file.h | 2 + pcbnew/CMakeLists.txt | 1 + .../dialogs/dialog_layer_selection_base.cpp | 71 +- .../dialogs/dialog_layer_selection_base.fbp | 1540 ++++++++++------- pcbnew/dialogs/dialog_layer_selection_base.h | 19 +- pcbnew/layer_pairs.cpp | 127 ++ pcbnew/layer_pairs.h | 96 + pcbnew/pcb_base_edit_frame.cpp | 1 + pcbnew/pcb_base_edit_frame.h | 11 +- pcbnew/pcb_edit_frame.cpp | 30 + pcbnew/pcb_layer_presentation.h | 3 + pcbnew/sel_layer.cpp | 614 +++++-- pcbnew/toolbars_pcb_editor.cpp | 11 - 16 files changed, 1852 insertions(+), 819 deletions(-) create mode 100644 pcbnew/layer_pairs.cpp create mode 100644 pcbnew/layer_pairs.h diff --git a/common/project/board_project_settings.cpp b/common/project/board_project_settings.cpp index 2355988fc6..72bd98908d 100644 --- a/common/project/board_project_settings.cpp +++ b/common/project/board_project_settings.cpp @@ -305,3 +305,67 @@ void PARAM_VIEWPORT3D::jsonToViewports( const nlohmann::json& aJson ) } } } + + +PARAM_LAYER_PAIRS::PARAM_LAYER_PAIRS( const std::string& aPath, + std::vector& aLayerPairInfos ) : + PARAM_LAMBDA( aPath, + std::bind( &PARAM_LAYER_PAIRS::layerPairsToJson, this ), + std::bind( &PARAM_LAYER_PAIRS::jsonToLayerPairs, this, _1 ), + {} ), + m_layerPairInfos( aLayerPairInfos ) +{ +} + + +nlohmann::json PARAM_LAYER_PAIRS::layerPairsToJson() +{ + nlohmann::json ret = nlohmann::json::array(); + + for( const LAYER_PAIR_INFO& pairInfo : m_layerPairInfos ) + { + const LAYER_PAIR& pair = pairInfo.GetLayerPair(); + nlohmann::json js = { + { "topLayer", pair.GetLayerA() }, + { "bottomLayer", pair.GetLayerB() }, + { "enabled", pairInfo.IsEnabled() }, + }; + + if( pairInfo.GetName().has_value() ) + { + js["name"] = pairInfo.GetName().value(); + } + + ret.push_back( std::move( js ) ); + } + + return ret; +} + + +void PARAM_LAYER_PAIRS::jsonToLayerPairs( const nlohmann::json& aJson ) +{ + if( aJson.empty() || !aJson.is_array() ) + return; + + m_layerPairInfos.clear(); + + for( const nlohmann::json& pairJson : aJson ) + { + if( pairJson.contains( "topLayer" ) && pairJson.contains( "bottomLayer" ) ) + { + LAYER_PAIR pair( pairJson.at( "topLayer" ).get(), + pairJson.at( "bottomLayer" ).get() ); + + bool enabled = true; + if( pairJson.contains( "enabled" ) ) + enabled = pairJson.at( "enabled" ).get(); + + std::optional name; + if( pairJson.contains( "name" ) ) + name = pairJson.at( "name" ).get(); + + m_layerPairInfos.emplace_back( LAYER_PAIR_INFO( pair, enabled, std::move( name ) ) ); + } + } +} \ No newline at end of file diff --git a/common/project/project_file.cpp b/common/project/project_file.cpp index 90f05bb2ed..fe5323cbde 100644 --- a/common/project/project_file.cpp +++ b/common/project/project_file.cpp @@ -124,6 +124,8 @@ PROJECT_FILE::PROJECT_FILE( const wxString& aFullPath ) : m_params.emplace_back( new PARAM_VIEWPORT3D( "board.3dviewports", &m_Viewports3D ) ); + m_params.emplace_back( new PARAM_LAYER_PAIRS( "board.layer_pairs", m_LayerPairInfos ) ); + m_params.emplace_back( new PARAM( "board.ipc2581.internal_id", &m_IP2581Bom.id, wxEmptyString ) ); diff --git a/include/project/board_project_settings.h b/include/project/board_project_settings.h index b51fadd0eb..0020f2534a 100644 --- a/include/project/board_project_settings.h +++ b/include/project/board_project_settings.h @@ -258,6 +258,85 @@ private: std::vector* m_viewports; }; + +class KICOMMON_API LAYER_PAIR +{ +public: + LAYER_PAIR() : + m_layerA( UNDEFINED_LAYER ), m_layerB( UNDEFINED_LAYER ) + { + } + + LAYER_PAIR( PCB_LAYER_ID a, PCB_LAYER_ID b ) : + m_layerA( a ), m_layerB( b ) + { + } + + PCB_LAYER_ID GetLayerA() const { return m_layerA; } + PCB_LAYER_ID GetLayerB() const { return m_layerB; } + + void SetLayerA( PCB_LAYER_ID aLayer ) { m_layerA = aLayer; } + void SetLayerB( PCB_LAYER_ID aLayer ) { m_layerB = aLayer; } + + /** + * @return true if the two layer pairs have the same layers, regardless of order + */ + bool HasSameLayers( const LAYER_PAIR& aOther ) const + { + return ( m_layerA == aOther.m_layerA && m_layerB == aOther.m_layerB ) + || ( m_layerA == aOther.m_layerB && m_layerB == aOther.m_layerA ); + } + + bool operator<=> ( const LAYER_PAIR& aOther ) const = default; + +private: + PCB_LAYER_ID m_layerA; + PCB_LAYER_ID m_layerB; +}; + + +/** + * All information about a layer pair as stored in the layer pair store. + */ +class KICOMMON_API LAYER_PAIR_INFO +{ +public: + LAYER_PAIR_INFO( LAYER_PAIR aPair, bool aEnabled, std::optional aName ) : + m_pair( std::move( aPair ) ), m_enabled( aEnabled), m_name( std::move( aName ) ) + { + } + + const LAYER_PAIR& GetLayerPair() const { return m_pair; } + + const std::optional& GetName() const { return m_name; } + + void SetName( const wxString& aNewName ) { m_name = aNewName; } + void UnsetName() { m_name = std::nullopt; } + + bool IsEnabled() const { return m_enabled; } + void SetEnabled( bool aNewEnabled ) { m_enabled = aNewEnabled; } + +private: + LAYER_PAIR m_pair; + bool m_enabled = true; + std::optional m_name; +}; + + +class KICOMMON_API PARAM_LAYER_PAIRS : public PARAM_LAMBDA +{ +public: + PARAM_LAYER_PAIRS( const std::string& aPath, std::vector& m_layerPairInfos ); + +private: + nlohmann::json layerPairsToJson(); + + void jsonToLayerPairs( const nlohmann::json& aJson ); + + std::vector& m_layerPairInfos; +}; + + /** * Persisted state for the net inspector panel */ diff --git a/include/project/project_file.h b/include/project/project_file.h index 9041b42acc..7b5371ef31 100644 --- a/include/project/project_file.h +++ b/include/project/project_file.h @@ -31,6 +31,7 @@ class BOARD_DESIGN_SETTINGS; class ERC_SETTINGS; class NET_SETTINGS; +class LAYER_PAIR_SETTINGS; class SCHEMATIC_SETTINGS; class TEMPLATES; @@ -176,6 +177,7 @@ public: std::vector m_LayerPresets; /// List of stored layer presets std::vector m_Viewports; /// List of stored viewports (pos + zoom) std::vector m_Viewports3D; /// List of stored 3D viewports (view matrixes) + std::vector m_LayerPairInfos; /// Layer pair list for the board struct IP2581_BOM m_IP2581Bom; /// IPC-2581 BOM settings diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index d1db8c32e0..9c1bb0a325 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -328,6 +328,7 @@ set( PCBNEW_CLASS_SRCS grid_layer_box_helpers.cpp grid_layer_box_helpers.h initpcb.cpp + layer_pairs.cpp load_select_footprint.cpp menubar_footprint_editor.cpp menubar_pcb_editor.cpp diff --git a/pcbnew/dialogs/dialog_layer_selection_base.cpp b/pcbnew/dialogs/dialog_layer_selection_base.cpp index ed8ad4f229..074e3e411f 100644 --- a/pcbnew/dialogs/dialog_layer_selection_base.cpp +++ b/pcbnew/dialogs/dialog_layer_selection_base.cpp @@ -1,10 +1,12 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) +// C++ code generated with wxFormBuilder (version 4.1.0-0-g733bf3d) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! /////////////////////////////////////////////////////////////////////////// +#include "widgets/wx_grid.h" + #include "dialog_layer_selection_base.h" /////////////////////////////////////////////////////////////////////////// @@ -14,7 +16,7 @@ DIALOG_LAYER_SELECTION_BASE::DIALOG_LAYER_SELECTION_BASE( wxWindow* parent, wxWi this->SetSizeHints( wxDefaultSize, wxDefaultSize ); wxBoxSizer* bSizerMain; - bSizerMain = new wxBoxSizer( wxVERTICAL ); + bSizerMain = new wxBoxSizer( wxHORIZONTAL ); wxBoxSizer* bSizerUpper; bSizerUpper = new wxBoxSizer( wxHORIZONTAL ); @@ -153,7 +155,7 @@ DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE bSizerLeft->Add( m_leftGridLayers, 0, wxALL|wxEXPAND, 5 ); - bSizerUpper->Add( bSizerLeft, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + bSizerUpper->Add( bSizerLeft, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); wxBoxSizer* bSizerRight; bSizerRight = new wxBoxSizer( wxVERTICAL ); @@ -192,7 +194,59 @@ DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE bSizerRight->Add( m_rightGridLayers, 0, wxALL|wxEXPAND, 5 ); - bSizerUpper->Add( bSizerRight, 1, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + bSizerUpper->Add( bSizerRight, 0, wxEXPAND|wxRIGHT|wxLEFT, 5 ); + + wxBoxSizer* bSizer7; + bSizer7 = new wxBoxSizer( wxVERTICAL ); + + m_addToPresetsButton = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + bSizer7->Add( m_addToPresetsButton, 0, wxALL, 5 ); + + + bSizerUpper->Add( bSizer7, 0, wxALIGN_CENTER_VERTICAL, 5 ); + + wxStaticBoxSizer* m_presetsSizer; + m_presetsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Copper layer pair presets") ), wxVERTICAL ); + + m_presetsGrid = new WX_GRID( m_presetsSizer->GetStaticBox(), ID_LEFT_LIST, wxDefaultPosition, wxDefaultSize, 0 ); + + // Grid + m_presetsGrid->CreateGrid( 0, 4 ); + m_presetsGrid->EnableEditing( true ); + m_presetsGrid->EnableGridLines( true ); + m_presetsGrid->EnableDragGridSize( false ); + m_presetsGrid->SetMargins( 5, 3 ); + + // Columns + m_presetsGrid->SetColSize( 0, 60 ); + m_presetsGrid->SetColSize( 1, 24 ); + m_presetsGrid->SetColSize( 2, 100 ); + m_presetsGrid->SetColSize( 3, 200 ); + m_presetsGrid->EnableDragColMove( false ); + m_presetsGrid->EnableDragColSize( false ); + m_presetsGrid->SetColLabelValue( 0, _("Enabled") ); + m_presetsGrid->SetColLabelValue( 1, wxEmptyString ); + m_presetsGrid->SetColLabelValue( 2, _("Layers") ); + m_presetsGrid->SetColLabelValue( 3, _("Label") ); + m_presetsGrid->SetColLabelSize( wxGRID_AUTOSIZE ); + m_presetsGrid->SetColLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); + + // Rows + m_presetsGrid->EnableDragRowSize( false ); + m_presetsGrid->SetRowLabelSize( 0 ); + m_presetsGrid->SetRowLabelAlignment( wxALIGN_CENTER, wxALIGN_CENTER ); + + // Label Appearance + + // Cell Defaults + m_presetsGrid->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_CENTER ); + m_presetsSizer->Add( m_presetsGrid, 1, wxALL|wxEXPAND, 0 ); + + m_deleteRowButton = new wxBitmapButton( m_presetsSizer->GetStaticBox(), wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 ); + m_presetsSizer->Add( m_deleteRowButton, 0, wxALL, 5 ); + + + bSizerUpper->Add( m_presetsSizer, 1, wxEXPAND, 5 ); bSizerMain->Add( bSizerUpper, 1, wxALL|wxEXPAND, 5 ); @@ -209,19 +263,10 @@ DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE this->SetSizer( bSizerMain ); this->Layout(); - bSizerMain->Fit( this ); this->Centre( wxBOTH ); - - // Connect Events - m_leftGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnLeftGridCellClick ), NULL, this ); - m_rightGridLayers->Connect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnRightGridCellClick ), NULL, this ); } DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::~DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE() { - // Disconnect Events - m_leftGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnLeftGridCellClick ), NULL, this ); - m_rightGridLayers->Disconnect( wxEVT_GRID_CELL_LEFT_CLICK, wxGridEventHandler( DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE::OnRightGridCellClick ), NULL, this ); - } diff --git a/pcbnew/dialogs/dialog_layer_selection_base.fbp b/pcbnew/dialogs/dialog_layer_selection_base.fbp index a1a5105016..c213b36b2e 100644 --- a/pcbnew/dialogs/dialog_layer_selection_base.fbp +++ b/pcbnew/dialogs/dialog_layer_selection_base.fbp @@ -1,644 +1,912 @@ - + - - - - C++ - 1 - source_name - 0 - 0 - res - UTF-8 - connect - dialog_layer_selection_base - 1000 - none - - - 1 - dialog_layer_selection_base - - . - - 1 - 1 - 1 - 1 - UI - 0 - 0 - 0 - - 0 - wxAUI_MGR_DEFAULT - - wxBOTH - - 1 - 1 - impl_virtual - - - - 0 - wxID_ANY - + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + dialog_layer_selection_base + 1000 + none + + + 1 + dialog_layer_selection_base + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + 0 + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 0 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_LAYER_SELECTION_BASE + + -1,-1 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + DIALOG_SHIM; dialog_shim.h; forward_declare + Select Layer + + 0 + + + + OnMouseMove + + + bSizerMain + wxHORIZONTAL + none + + 10 + wxEXPAND|wxALL + 1 + - DIALOG_LAYER_SELECTION_BASE - - -1,-1 - wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER - DIALOG_SHIM; dialog_shim.h; forward_declare - Select Layer - - 0 - - - - OnMouseMove - - - bSizerMain - wxVERTICAL - none - - 10 - wxEXPAND|wxALL - 1 - - - bSizerUpper - wxHORIZONTAL - none - - 5 - wxALL|wxEXPAND - 1 - - 1 - 1 - 1 - 1 - - - - - 0 - 0 - - - - 1 - - - wxALIGN_LEFT - - wxALIGN_CENTER - 0 - 1 - wxALIGN_CENTER - 0 - - wxALIGN_CENTER - 3 - 24,20,72 - - 1 - 0 - Dock - 0 - Left - 0 - 0 - 0 - 0 - 0 - 1 - - 1 - - - 0 - 0 - 0 - ID_LEFT_LIST - - - - 3 - 5 - - 0 - - - 0 - -1,-1 - 1 - m_leftGridLayers - 1 - - - protected - 1 - - Resizable - wxALIGN_CENTER - 0 - - wxALIGN_CENTER - - 1 - 1 - - - 0 - - - - - OnLeftGridCellClick - OnLeftButtonReleased - - - - 5 - wxALL|wxEXPAND - 1 - - 1 - 1 - 1 - 1 - - - - - 0 - 0 - - - - 1 - - - wxALIGN_LEFT - - wxALIGN_CENTER - 0 - 1 - wxALIGN_CENTER - 0 - - wxALIGN_CENTER - 3 - 24,20,72 - - 1 - 0 - Dock - 0 - Left - 0 - 0 - 0 - 0 - 0 - 1 - - 1 - - - 0 - 0 - 0 - ID_RIGHT_LIST - - - - 3 - 5 - - 0 - - - 0 - - 1 - m_rightGridLayers - 1 - - - protected - 1 - - Resizable - wxALIGN_CENTER - 0 - - wxALIGN_CENTER - - 1 - 1 - - - 0 - - - - - OnRightGridCellClick - OnLeftButtonReleased - - - - + bSizerUpper + wxHORIZONTAL + none + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + 0 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_CENTER + 0 + 1 + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + 3 + 24,20,72 + + 1 + 0 + Dock + 0 + Left + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + 1 + + + 0 + 0 + 0 + ID_LEFT_LIST + + + + 3 + 5 + + 0 + + + 0 + -1,-1 + 1 + m_leftGridLayers + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + + 1 + 1 + + + 0 + + + + + OnLeftGridCellClick + OnLeftButtonReleased + - - - 0 - wxAUI_MGR_DEFAULT - - wxBOTH - - 1 - 1 - impl_virtual - - - - 0 - wxID_ANY - - - DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE - - -1,-1 - wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER - DIALOG_SHIM; dialog_shim.h; forward_declare - Select Copper Layer Pair - - 0 - - - - + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + 0 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_CENTER + 0 + 1 + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + 3 + 24,20,72 + + 1 + 0 + Dock + 0 + Left + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + 1 + + + 0 + 0 + 0 + ID_RIGHT_LIST + + + + 3 + 5 + + 0 + + + 0 - bSizerMain - wxVERTICAL - none - - 5 - wxALL|wxEXPAND - 1 - - - bSizerUpper - wxHORIZONTAL - none - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 1 - - - bSizerLeft - wxVERTICAL - none - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Top/Front layer: - 0 - - 0 - - - 0 - - 1 - m_staticTextTopLayer - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - 0 - 0 - - - - 1 - - - wxALIGN_LEFT - - wxALIGN_CENTER - 0 - 1 - wxALIGN_CENTER - 0 - - wxALIGN_CENTER - 3 - 24,20,72 - - 1 - 0 - Dock - 0 - Left - 0 - 0 - 0 - 0 - 0 - 1 - - 1 - - - 0 - 0 - 0 - ID_LEFT_LIST - - - - 3 - 3 - - 0 - - - 0 - - 1 - m_leftGridLayers - 1 - - - protected - 1 - - Resizable - wxALIGN_CENTER - 0 - - wxALIGN_CENTER - - 1 - 1 - - - 0 - - - - - OnLeftGridCellClick - - - - - - 5 - wxEXPAND|wxRIGHT|wxLEFT - 1 - - - bSizerRight - wxVERTICAL - none - - 5 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Bottom/Back layer: - 0 - - 0 - - - 0 - - 1 - m_staticTextBottomLayer - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - - - - - -1 - - - - 5 - wxALL|wxEXPAND - 0 - - 1 - 1 - 1 - 1 - - - - - 0 - 0 - - - - 1 - - - wxALIGN_LEFT - - wxALIGN_CENTER - 0 - 1 - wxALIGN_CENTER - 0 - - wxALIGN_CENTER - 3 - 24,20,72 - - 1 - 0 - Dock - 0 - Left - 0 - 0 - 0 - 0 - 0 - 1 - - 1 - - - 0 - 0 - 0 - ID_RIGHT_LIST - - - - 3 - 3 - - 0 - - - 0 - -1,-1 - 1 - m_rightGridLayers - 1 - - - protected - 1 - - Resizable - wxALIGN_CENTER - 0 - - wxALIGN_CENTER - - 1 - 1 - - - 0 - - - - - OnRightGridCellClick - - - - - - - - 5 - wxBOTTOM|wxEXPAND|wxLEFT|wxTOP - 0 - - 0 - 1 - 0 - 0 - 0 - 1 - 0 - 0 - - m_sdbSizer - protected - - + 1 + m_rightGridLayers + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + + 1 + 1 + + + 0 + + + + + OnRightGridCellClick + OnLeftButtonReleased + + + + + 0 + wxAUI_MGR_DEFAULT + + wxBOTH + + 1 + 0 + 1 + impl_virtual + + + + 0 + wxID_ANY + + + DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE + + 744,217 + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER + DIALOG_SHIM; dialog_shim.h; forward_declare + Select Copper Layer Pair + + 0 + + + + + + bSizerMain + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 1 + + + bSizerUpper + wxHORIZONTAL + none + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + + bSizerLeft + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Top/Front layer: + 0 + + 0 + + + 0 + + 1 + m_staticTextTopLayer + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_CENTER + 0 + 1 + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + 3 + 24,20,72 + + 1 + 0 + Dock + 0 + Left + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + 1 + + + 0 + 0 + 0 + ID_LEFT_LIST + + + + 3 + 3 + + 0 + + + 0 + + 1 + m_leftGridLayers + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + + 1 + 1 + + + 0 + + + + + + + + + + 5 + wxEXPAND|wxRIGHT|wxLEFT + 0 + + + bSizerRight + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 0 + 1 + + 1 + + 0 + 0 + wxID_ANY + Bottom/Back layer: + 0 + + 0 + + + 0 + + 1 + m_staticTextBottomLayer + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_CENTER + 0 + 1 + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + 3 + 24,20,72 + + 1 + 0 + Dock + 0 + Left + 0 + 0 + 0 + 0 + 0 + 0 + 1 + + 1 + + + 0 + 0 + 0 + ID_RIGHT_LIST + + + + 3 + 3 + + 0 + + + 0 + -1,-1 + 1 + m_rightGridLayers + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + + 1 + 1 + + + 0 + + + + + + + + + + 5 + wxALIGN_CENTER_VERTICAL + 0 + + + bSizer7 + wxVERTICAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 0 + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + m_addToPresetsButton + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + 5 + wxEXPAND + 1 + + wxID_ANY + Copper layer pair presets + + m_presetsSizer + wxVERTICAL + 1 + none + + 0 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + 0 + 0 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_CENTER + 0 + 1 + wxALIGN_CENTER + wxGRID_AUTOSIZE + "Enabled" "" "Layers" "Label" + wxALIGN_CENTER + 4 + 60,24,100,200 + + 1 + 0 + Dock + 0 + Left + 0 + 0 + 0 + 0 + 0 + 1 + 1 + + 1 + + + 1 + 0 + 0 + ID_LEFT_LIST + + + + 3 + 5 + + 0 + + + 0 + -1,-1 + 1 + m_presetsGrid + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTER + 0 + + wxALIGN_CENTER + + 0 + 1 + + WX_GRID; widgets/wx_grid.h; forward_declare + 0 + + + + + + + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + 0 + + + + + 1 + 0 + 1 + + 1 + + 0 + 0 + + Dock + 0 + Left + 0 + 1 + + 1 + + + 0 + 0 + wxID_ANY + MyButton + + 0 + + 0 + + + 0 + + 1 + m_deleteRowButton + 1 + + + protected + 1 + + + + Resizable + 1 + + + ; ; forward_declare + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + 5 + wxBOTTOM|wxEXPAND|wxLEFT|wxTOP + 0 + + 0 + 1 + 0 + 0 + 0 + 1 + 0 + 0 + + m_sdbSizer + protected + + + + + diff --git a/pcbnew/dialogs/dialog_layer_selection_base.h b/pcbnew/dialogs/dialog_layer_selection_base.h index 63b10cbf8e..0f078f0572 100644 --- a/pcbnew/dialogs/dialog_layer_selection_base.h +++ b/pcbnew/dialogs/dialog_layer_selection_base.h @@ -1,5 +1,5 @@ /////////////////////////////////////////////////////////////////////////// -// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b) +// C++ code generated with wxFormBuilder (version 4.1.0-0-g733bf3d) // http://www.wxformbuilder.org/ // // PLEASE DO *NOT* EDIT THIS FILE! @@ -10,6 +10,8 @@ #include #include #include +class WX_GRID; + #include "dialog_shim.h" #include #include @@ -20,7 +22,12 @@ #include #include #include +#include +#include +#include +#include #include +#include /////////////////////////////////////////////////////////////////////////// @@ -65,18 +72,16 @@ class DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE : public DIALOG_SHIM wxGrid* m_leftGridLayers; wxStaticText* m_staticTextBottomLayer; wxGrid* m_rightGridLayers; + wxBitmapButton* m_addToPresetsButton; + WX_GRID* m_presetsGrid; + wxBitmapButton* m_deleteRowButton; wxStdDialogButtonSizer* m_sdbSizer; wxButton* m_sdbSizerOK; wxButton* m_sdbSizerCancel; - // Virtual event handlers, override them in your derived class - virtual void OnLeftGridCellClick( wxGridEvent& event ) { event.Skip(); } - virtual void OnRightGridCellClick( wxGridEvent& event ) { event.Skip(); } - - public: - DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select Copper Layer Pair"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); + DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Select Copper Layer Pair"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 744,217 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER ); ~DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE(); diff --git a/pcbnew/layer_pairs.cpp b/pcbnew/layer_pairs.cpp new file mode 100644 index 0000000000..dc9c9b531b --- /dev/null +++ b/pcbnew/layer_pairs.cpp @@ -0,0 +1,127 @@ +/* + * 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_pairs.h" + +wxDEFINE_EVENT( PCB_LAYER_PAIR_PRESETS_CHANGED, wxCommandEvent ); +wxDEFINE_EVENT( PCB_CURRENT_LAYER_PAIR_CHANGED, wxCommandEvent ); + + +LAYER_PAIR_SETTINGS::LAYER_PAIR_SETTINGS( const LAYER_PAIR_SETTINGS& aOther ) +{ + m_pairs = aOther.m_pairs; + m_currentPair = aOther.m_currentPair; +} + + +bool LAYER_PAIR_SETTINGS::addLayerPairInternal( LAYER_PAIR_INFO aPairInfo ) +{ + const LAYER_PAIR& newPair = aPairInfo.GetLayerPair(); + const auto pairMatcher = [&]( const LAYER_PAIR_INFO& aExistingPair ) + { + return newPair.HasSameLayers( aExistingPair.GetLayerPair() ); + }; + + const bool alreadyExists = std::any_of( m_pairs.begin(), m_pairs.end(), pairMatcher ); + + if( alreadyExists ) + { + return false; + } + + m_pairs.push_back( std::move( aPairInfo ) ); + return true; +} + + +bool LAYER_PAIR_SETTINGS::AddLayerPair( LAYER_PAIR_INFO aPair ) +{ + bool ret = addLayerPairInternal( std::move( aPair ) ); + + wxCommandEvent* evt = new wxCommandEvent( PCB_LAYER_PAIR_PRESETS_CHANGED, wxID_ANY ); + QueueEvent( evt ); + return ret; +} + + +bool LAYER_PAIR_SETTINGS::removeLayerPairInternal( const LAYER_PAIR& aPair ) +{ + const auto pairMatcher = [&aPair]( const LAYER_PAIR_INFO& aPairInfo ) + { + return aPairInfo.GetLayerPair().HasSameLayers( aPair ); + }; + + const auto pairToRemoveIt = std::find_if( m_pairs.begin(), m_pairs.end(), pairMatcher ); + + if( pairToRemoveIt == m_pairs.end() ) + { + return false; + } + + m_pairs.erase( pairToRemoveIt ); + return true; +} + + +bool LAYER_PAIR_SETTINGS::RemoveLayerPair( const LAYER_PAIR& aPair ) +{ + bool ret = removeLayerPairInternal( aPair ); + + wxCommandEvent* evt = new wxCommandEvent( PCB_LAYER_PAIR_PRESETS_CHANGED, wxID_ANY ); + QueueEvent( evt ); + return ret; +} + + +std::span LAYER_PAIR_SETTINGS::GetLayerPairs() const +{ + return m_pairs; +} + +std::span LAYER_PAIR_SETTINGS::GetLayerPairs() +{ + return m_pairs; +} + +void LAYER_PAIR_SETTINGS::SetLayerPairs( std::span aPairs ) +{ + // Replace all pairs with the given list + m_pairs.clear(); + for( const LAYER_PAIR_INFO& pair : aPairs ) + { + // Skip dupes and other + addLayerPairInternal( pair ); + } + + { + wxCommandEvent* evt = new wxCommandEvent( PCB_LAYER_PAIR_PRESETS_CHANGED, wxID_ANY ); + QueueEvent( evt ); + } +} + +void LAYER_PAIR_SETTINGS::SetCurrentLayerPair( const LAYER_PAIR& aPair ) +{ + m_currentPair = aPair; + wxCommandEvent* evt = new wxCommandEvent( PCB_CURRENT_LAYER_PAIR_CHANGED, wxID_ANY ); + QueueEvent( evt ); +} diff --git a/pcbnew/layer_pairs.h b/pcbnew/layer_pairs.h new file mode 100644 index 0000000000..3324c9b8ef --- /dev/null +++ b/pcbnew/layer_pairs.h @@ -0,0 +1,96 @@ +/* + * 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_PAIRS_H +#define LAYER_PAIRS_H + +#include +#include +#include +#include +#include + +#include + +#include + + +class wxBitmap; + +wxDECLARE_EVENT( PCB_LAYER_PAIR_PRESETS_CHANGED, wxCommandEvent ); +wxDECLARE_EVENT( PCB_CURRENT_LAYER_PAIR_CHANGED, wxCommandEvent ); + +/** + * Management class for layer pairs in a PCB + */ +class LAYER_PAIR_SETTINGS: public wxEvtHandler +{ +public: + /** + * Construct a new layer pair manager. + */ + LAYER_PAIR_SETTINGS() : + m_currentPair( F_Cu, B_Cu ) + { + } + + LAYER_PAIR_SETTINGS( const LAYER_PAIR_SETTINGS& aOther ); + + bool AddLayerPair( LAYER_PAIR_INFO aPair ); + + /** + * Remove the matching layer pair from the store, if present. + */ + bool RemoveLayerPair( const LAYER_PAIR& aPair ); + + /** + * Returns a span of all stored layer pairs. + */ + std::span GetLayerPairs() const; + std::span GetLayerPairs(); + + /** + * Replace the stored layer pairs with the given list. + * + * The same conditions are maintained as for AddLayerPair + */ + void SetLayerPairs( std::span aPairs ); + + const LAYER_PAIR& GetCurrentLayerPair() const { return m_currentPair; } + + /** + * Set the "active" layer pair. This doesn't have to be a preset pair. + */ + void SetCurrentLayerPair( const LAYER_PAIR& aPair ); + +private: + bool addLayerPairInternal( LAYER_PAIR_INFO aPair ); + bool removeLayerPairInternal( const LAYER_PAIR& aPair ); + + // Ordered store of all preset layer pairs + std::vector m_pairs; + + LAYER_PAIR m_currentPair; +}; + +#endif // LAYER_PAIRS_H \ No newline at end of file diff --git a/pcbnew/pcb_base_edit_frame.cpp b/pcbnew/pcb_base_edit_frame.cpp index 98636425df..ffecbfc151 100644 --- a/pcbnew/pcb_base_edit_frame.cpp +++ b/pcbnew/pcb_base_edit_frame.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include diff --git a/pcbnew/pcb_base_edit_frame.h b/pcbnew/pcb_base_edit_frame.h index 7347297401..aebe8073d8 100644 --- a/pcbnew/pcb_base_edit_frame.h +++ b/pcbnew/pcb_base_edit_frame.h @@ -30,6 +30,7 @@ #include class APPEARANCE_CONTROLS; +class LAYER_PAIR_SETTINGS; class BOARD_ITEM_CONTAINER; class PANEL_SELECTION_FILTER; class PCB_TEXTBOX; @@ -220,6 +221,11 @@ public: APPEARANCE_CONTROLS* GetAppearancePanel() { return m_appearancePanel; } + /** + * Acess to the layer pair settings controller of the board, if available + */ + LAYER_PAIR_SETTINGS* GetLayerPairSettings() { return m_layerPairSettings.get(); } + void ToggleProperties() override; void GetContextualTextVars( BOARD_ITEM* aSourceItem, const wxString& aCrossRef, @@ -252,8 +258,9 @@ protected: protected: bool m_undoRedoBlocked; - PANEL_SELECTION_FILTER* m_selectionFilterPanel; - APPEARANCE_CONTROLS* m_appearancePanel; + PANEL_SELECTION_FILTER* m_selectionFilterPanel; + APPEARANCE_CONTROLS* m_appearancePanel; + std::unique_ptr m_layerPairSettings; wxAuiNotebook* m_tabbedPanel; /// Panel with Layers and Object Inspector tabs diff --git a/pcbnew/pcb_edit_frame.cpp b/pcbnew/pcb_edit_frame.cpp index c87e89b878..3859d59379 100644 --- a/pcbnew/pcb_edit_frame.cpp +++ b/pcbnew/pcb_edit_frame.cpp @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -395,6 +396,30 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) : m_appearancePanel->SetTabIndex( settings->m_AuiPanels.appearance_panel_tab ); } + { + m_layerPairSettings = std::make_unique(); + + m_layerPairSettings->Bind( PCB_LAYER_PAIR_PRESETS_CHANGED, [&]( wxCommandEvent& aEvt ) + { + // Update the project file list + std::span newPairInfos = m_layerPairSettings->GetLayerPairs(); + Prj().GetProjectFile().m_LayerPairInfos = + std::vector{ newPairInfos.begin(), newPairInfos.end() }; + }); + + m_layerPairSettings->Bind( PCB_CURRENT_LAYER_PAIR_CHANGED, [&]( wxCommandEvent& aEvt ) + { + const LAYER_PAIR& layerPair = m_layerPairSettings->GetCurrentLayerPair(); + PCB_SCREEN& screen = *GetScreen(); + + screen.m_Route_Layer_TOP = layerPair.GetLayerA(); + screen.m_Route_Layer_BOTTOM = layerPair.GetLayerB(); + + // Update the toolbar icon + PrepareLayerIndicator(); + }); + } + GetToolManager()->PostAction( ACTIONS::zoomFitScreen ); // This is used temporarily to fix a client size issue on GTK that causes zoom to fit @@ -1574,6 +1599,11 @@ void PCB_EDIT_FRAME::onBoardLoaded() if( GetBoard()->GetDesignSettings().IsLayerEnabled( localSettings.m_ActiveLayer ) ) SetActiveLayer( localSettings.m_ActiveLayer ); + PROJECT_FILE& projectFile = Prj().GetProjectFile(); + + m_layerPairSettings->SetLayerPairs( projectFile.m_LayerPairInfos ); + m_layerPairSettings->SetCurrentLayerPair( LAYER_PAIR{ F_Cu, B_Cu } ); + // Updates any auto dimensions and the auxiliary toolbar tracks/via sizes unitsChangeRefresh(); diff --git a/pcbnew/pcb_layer_presentation.h b/pcbnew/pcb_layer_presentation.h index 4b39de422d..675fb14b91 100644 --- a/pcbnew/pcb_layer_presentation.h +++ b/pcbnew/pcb_layer_presentation.h @@ -24,6 +24,7 @@ #ifndef PCB_LAYER_PRESENTATION_H #define PCB_LAYER_PRESENTATION_H +#include #include class PCB_BASE_FRAME; @@ -40,6 +41,8 @@ public: wxString getLayerName( int aLayer ) const override; + LSEQ getOrderedEnabledLayers() const; + /** * Annoying post-ctor initialization (for when PCB_LAYER_BOX_SELECTOR doesn't * have access to the PCB_BASE_FRAME at construction time). diff --git a/pcbnew/sel_layer.cpp b/pcbnew/sel_layer.cpp index ff9946af35..de6526ce4c 100644 --- a/pcbnew/sel_layer.cpp +++ b/pcbnew/sel_layer.cpp @@ -22,26 +22,36 @@ * with this program. If not, see . */ +#include #include #include #include #include #include +#include #include #include #include +#include #include +#include #include #include #include #include +#include +#include +#include +#include +#include + // Column position by function: -#define SELECT_COLNUM 0 -#define COLOR_COLNUM 1 -#define LAYERNAME_COLNUM 2 -#define LAYER_HK_COLUMN 3 +#define SELECT_COLNUM 0 +#define COLOR_COLNUM 1 +#define LAYERNAME_COLNUM 2 +#define LAYER_HK_COLUMN 3 PCB_LAYER_PRESENTATION::PCB_LAYER_PRESENTATION( PCB_BASE_FRAME* aFrame ) : m_boardFrame( aFrame ) @@ -72,6 +82,11 @@ wxString PCB_LAYER_PRESENTATION::getLayerName( int aLayer ) const return BOARD::GetStandardLayerName( ToLAYER_ID( aLayer ) ); } +LSEQ PCB_LAYER_PRESENTATION::getOrderedEnabledLayers() const +{ + return m_boardFrame->GetBoard()->GetEnabledLayers().UIOrder(); +} + /** * Display a PCB layers list in a dialog to select one layer from this list. @@ -79,11 +94,11 @@ wxString PCB_LAYER_PRESENTATION::getLayerName( int aLayer ) const 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, + PCB_ONE_LAYER_SELECTOR( PCB_BASE_FRAME* aParent, PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask, bool aHideCheckBoxes = false ); ~PCB_ONE_LAYER_SELECTOR(); - int GetLayerSelection() { return m_layerSelected; } + int GetLayerSelection() { return m_layerSelected; } private: // Event handlers @@ -111,8 +126,7 @@ private: }; -PCB_ONE_LAYER_SELECTOR::PCB_ONE_LAYER_SELECTOR( PCB_BASE_FRAME* aParent, BOARD* aBrd, - PCB_LAYER_ID aDefaultLayer, +PCB_ONE_LAYER_SELECTOR::PCB_ONE_LAYER_SELECTOR( PCB_BASE_FRAME* aParent, PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask, bool aHideCheckBoxes ) : DIALOG_LAYER_SELECTION_BASE( aParent ), m_layerPresentation( aParent ) { @@ -120,7 +134,6 @@ PCB_ONE_LAYER_SELECTOR::PCB_ONE_LAYER_SELECTOR( PCB_BASE_FRAME* aParent, BOARD* m_layerSelected = aDefaultLayer; m_notAllowedLayersMask = aNotAllowedLayersMask; - m_brd = aBrd; m_leftGridLayers->SetCellHighlightPenWidth( 0 ); m_rightGridLayers->SetCellHighlightPenWidth( 0 ); @@ -167,7 +180,7 @@ void PCB_ONE_LAYER_SELECTOR::OnMouseMove( wxUpdateUIEvent& aEvent ) if( row != wxNOT_FOUND && row < static_cast( m_layersIdLeftColumn.size() ) ) { - m_layerSelected = m_layersIdLeftColumn[ row ]; + m_layerSelected = m_layersIdLeftColumn[row]; m_leftGridLayers->SelectBlock( row, LAYERNAME_COLNUM, row, LAYER_HK_COLUMN ); return; } @@ -180,8 +193,8 @@ void PCB_ONE_LAYER_SELECTOR::OnMouseMove( wxUpdateUIEvent& aEvent ) if( row == wxNOT_FOUND || row >= static_cast( m_layersIdRightColumn.size() ) ) return; - m_layerSelected = m_layersIdRightColumn[ row ]; - m_rightGridLayers->SelectBlock( row, LAYERNAME_COLNUM, row, LAYERNAME_COLNUM); + m_layerSelected = m_layersIdRightColumn[row]; + m_rightGridLayers->SelectBlock( row, LAYERNAME_COLNUM, row, LAYERNAME_COLNUM ); } } @@ -200,7 +213,7 @@ void PCB_ONE_LAYER_SELECTOR::buildList() int right_row = 0; wxString layername; - for( PCB_LAYER_ID layerid : m_brd->GetEnabledLayers().UIOrder() ) + for( PCB_LAYER_ID layerid : m_layerPresentation.getOrderedEnabledLayers() ) { if( m_notAllowedLayersMask[layerid] ) continue; @@ -217,7 +230,7 @@ void PCB_ONE_LAYER_SELECTOR::buildList() if( left_row ) m_leftGridLayers->AppendRows( 1 ); - m_leftGridLayers->SetCellBackgroundColour ( left_row, COLOR_COLNUM, color ); + m_leftGridLayers->SetCellBackgroundColour( left_row, COLOR_COLNUM, color ); m_leftGridLayers->SetCellValue( left_row, LAYERNAME_COLNUM, layername ); m_leftGridLayers->SetCellValue( left_row, LAYER_HK_COLUMN, getLayerHotKey( layerid ) ); @@ -258,7 +271,7 @@ void PCB_ONE_LAYER_SELECTOR::buildList() void PCB_ONE_LAYER_SELECTOR::OnLeftGridCellClick( wxGridEvent& event ) { - m_layerSelected = m_layersIdLeftColumn[ event.GetRow() ]; + m_layerSelected = m_layersIdLeftColumn[event.GetRow()]; if( IsQuasiModal() ) EndQuasiModal( 1 ); @@ -269,7 +282,7 @@ void PCB_ONE_LAYER_SELECTOR::OnLeftGridCellClick( wxGridEvent& event ) void PCB_ONE_LAYER_SELECTOR::OnRightGridCellClick( wxGridEvent& event ) { - m_layerSelected = m_layersIdRightColumn[ event.GetRow() ]; + m_layerSelected = m_layersIdRightColumn[event.GetRow()]; if( IsQuasiModal() ) EndQuasiModal( 2 ); @@ -281,13 +294,13 @@ void PCB_ONE_LAYER_SELECTOR::OnRightGridCellClick( wxGridEvent& event ) PCB_LAYER_ID PCB_BASE_FRAME::SelectOneLayer( PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask, wxPoint aDlgPosition ) { - PCB_ONE_LAYER_SELECTOR dlg( this, GetBoard(), aDefaultLayer, aNotAllowedLayersMask, true ); + PCB_ONE_LAYER_SELECTOR dlg( this, aDefaultLayer, aNotAllowedLayersMask, true ); if( aDlgPosition != wxDefaultPosition ) { wxSize dlgSize = dlg.GetSize(); - aDlgPosition.x -= dlgSize.x/2; - aDlgPosition.y -= dlgSize.y/2; + aDlgPosition.x -= dlgSize.x / 2; + aDlgPosition.y -= dlgSize.y / 2; dlg.SetPosition( aDlgPosition ); } @@ -298,162 +311,463 @@ PCB_LAYER_ID PCB_BASE_FRAME::SelectOneLayer( PCB_LAYER_ID aDefaultLayer, LSET aN } +/** + * Class that manages the UI for the copper layer pair presets list + * based on an injected layer pair store. + */ +class COPPER_LAYERS_PAIR_PRESETS_UI +{ + enum class COLNUMS + { + ENABLED, + SWATCH, + LAYERNAMES, + USERNAME, + }; + +public: + COPPER_LAYERS_PAIR_PRESETS_UI( WX_GRID& aGrid, PCB_LAYER_PRESENTATION& aPresentation, + LAYER_PAIR_SETTINGS& aLayerPairSettings ) : + m_layerPresentation( aPresentation ), m_grid( aGrid ), + m_layerPairSettings( aLayerPairSettings ) + { + wxASSERT_MSG( m_grid.GetNumberRows() == 0, "Grid should be empty at controller start" ); + + configureGrid(); + fillGridFromStore(); + + m_grid.Bind( wxEVT_GRID_CELL_CHANGED, + [this]( wxGridEvent& aEvent ) + { + const int col = aEvent.GetCol(); + const int row = aEvent.GetRow(); + if( col == (int) COLNUMS::USERNAME ) + { + onUserNameChanged( row, m_grid.GetCellValue( row, col ) ); + } + else if( col == (int) COLNUMS::ENABLED ) + { + onEnableChanged( row, m_grid.GetCellValue( row, col ) == wxS( "1" ) ); + } + } ); + + m_grid.Bind( wxEVT_GRID_CELL_LEFT_DCLICK, + [&]( wxGridEvent& aEvent ) + { + const int row = aEvent.GetRow(); + const int col = aEvent.GetCol(); + + if( col == (int) COLNUMS::LAYERNAMES || col == (int) COLNUMS::SWATCH ) + { + onPairActivated( row ); + } + } ); + + m_autosizer = + std::make_unique( m_grid, + WX_GRID_AUTOSIZER::COL_MIN_WIDTHS{ + { (int) COLNUMS::LAYERNAMES, 72 }, + { (int) COLNUMS::USERNAME, 72 }, + }, + (int) COLNUMS::USERNAME ); + } + + void OnLayerPairAdded( const LAYER_PAIR& aLayerPair ) + { + LAYER_PAIR_INFO layerPairInfo{ aLayerPair, true, std::nullopt }; + + const bool added = m_layerPairSettings.AddLayerPair( std::move( layerPairInfo ) ); + + if( added ) + { + m_grid.AppendRows( 1 ); + fillRowFromLayerPair( m_grid.GetNumberRows() - 1, layerPairInfo ); + } + } + + void OnDeleteSelectedLayerPairs() + { + int row = m_grid.GetGridCursorRow(); + + const LAYER_PAIR_INFO& layerPairInfo = m_layerPairSettings.GetLayerPairs()[row]; + const bool removed = m_layerPairSettings.RemoveLayerPair( layerPairInfo.GetLayerPair() ); + + if( removed ) + { + m_grid.DeleteRows( row ); + } + } + +private: + void configureGrid() + { + m_grid.UseNativeColHeader( true ); + + m_grid.SetCellHighlightPenWidth( 0 ); + m_grid.SetColFormatBool( (int) COLNUMS::ENABLED ); + + m_grid.SetSelectionMode( wxGrid::wxGridSelectionModes::wxGridSelectRows ); + + m_grid.AutoSizeColumn( (int) COLNUMS::USERNAME ); + } + + void fillGridFromStore() + { + std::span storePairs = m_layerPairSettings.GetLayerPairs(); + + m_grid.AppendRows( storePairs.size() ); + + int row = 0; + for( const LAYER_PAIR_INFO& layerPairInfo : storePairs ) + { + fillRowFromLayerPair( row, layerPairInfo ); + row++; + } + } + + wxString constructLayerPairLabel( const LAYER_PAIR& aLayerPair ) + { + const wxString layerAName = m_layerPresentation.getLayerName( aLayerPair.GetLayerA() ); + const wxString layerBName = m_layerPresentation.getLayerName( aLayerPair.GetLayerB() ); + return layerAName + wxT( " / " ) + layerBName; + } + + void fillRowFromLayerPair( int aRow, const LAYER_PAIR_INFO& aLayerPairInfo ) + { + wxASSERT_MSG( aRow < m_grid.GetNumberRows(), "Row index out of bounds" ); + + const LAYER_PAIR& layerPair = aLayerPairInfo.GetLayerPair(); + + const wxString layerNames = constructLayerPairLabel( layerPair ); + + m_grid.SetCellValue( aRow, (int) COLNUMS::LAYERNAMES, layerNames ); + + const std::optional userName = aLayerPairInfo.GetName(); + if( userName ) + { + m_grid.SetCellValue( aRow, (int) COLNUMS::USERNAME, *userName ); + } + + m_grid.SetCellValue( aRow, (int) COLNUMS::ENABLED, + aLayerPairInfo.IsEnabled() ? wxT( "1" ) : wxT( "0" ) ); + + // Set the color swatch + std::unique_ptr& swatch = m_swatches.emplace_back( + m_layerPresentation.CreateLayerPairIcon( layerPair, KiIconScale( &m_grid ) ) ); + + m_grid.SetCellRenderer( aRow, (int) COLNUMS::SWATCH, + new GRID_CELL_ICON_RENDERER( *swatch ) ); + + m_grid.SetReadOnly( aRow, (int) COLNUMS::SWATCH ); + m_grid.SetReadOnly( aRow, (int) COLNUMS::LAYERNAMES ); + } + + void onUserNameChanged( int aRow, const wxString& aNewValue ) + { + LAYER_PAIR_INFO& changedPair = m_layerPairSettings.GetLayerPairs()[aRow]; + changedPair.SetName( aNewValue ); + } + + void onEnableChanged( int aRow, bool aNewValue ) + { + LAYER_PAIR_INFO& changedPair = m_layerPairSettings.GetLayerPairs()[aRow]; + changedPair.SetEnabled( aNewValue ); + } + + void onPairActivated( int aRow ) + { + const LAYER_PAIR_INFO& layerPairInfo = m_layerPairSettings.GetLayerPairs()[aRow]; + const LAYER_PAIR& layerPair = layerPairInfo.GetLayerPair(); + + m_layerPairSettings.SetCurrentLayerPair( layerPair ); + } + + LAYER_PRESENTATION& m_layerPresentation; + WX_GRID& m_grid; + LAYER_PAIR_SETTINGS& m_layerPairSettings; + + // Lifetime managment of the swatches + std::vector> m_swatches; + + std::unique_ptr m_autosizer; +}; + + +/** + * Class that manages the UI for the copper layer pair selection + * (left and right grids). + */ +class COPPER_LAYERS_PAIR_SELECTION_UI +{ + enum class CU_LAYER_COLNUMS + { + SELECT = 0, + COLOR = 1, + LAYERNAME = 2, + }; + +public: + COPPER_LAYERS_PAIR_SELECTION_UI( wxGrid& aLeftGrid, wxGrid& aRightGrid, + PCB_LAYER_PRESENTATION& aPresentation, + LAYER_PAIR_SETTINGS& aLayerPairSettings ) : + m_layerPresentation( aPresentation ), m_layerPairSettings( aLayerPairSettings ), + m_leftGrid( aLeftGrid ), m_rightGrid( aRightGrid ) + { + configureGrid( m_leftGrid ); + configureGrid( m_rightGrid ); + + for( const PCB_LAYER_ID& layerId : m_layerPresentation.getOrderedEnabledLayers() ) + { + if( IsCopperLayer( layerId ) ) + { + m_layersId.push_back( layerId ); + } + } + + fillLayerGrid( m_leftGrid ); + fillLayerGrid( m_rightGrid ); + + m_leftGrid.Bind( wxEVT_GRID_CELL_LEFT_CLICK, + [this]( wxGridEvent& aEvent ) + { + onLeftGridRowSelected( aEvent.GetRow() ); + } ); + + m_rightGrid.Bind( wxEVT_GRID_CELL_LEFT_CLICK, + [this]( wxGridEvent& aEvent ) + { + onRightGridRowSelected( aEvent.GetRow() ); + } ); + + m_layerPairSettings.Bind( PCB_CURRENT_LAYER_PAIR_CHANGED, + [this]( wxCommandEvent& aEvent ) + { + const LAYER_PAIR& newPair = + m_layerPairSettings.GetCurrentLayerPair(); + setCurrentSelection( rowForLayer( newPair.GetLayerA() ), + rowForLayer( newPair.GetLayerB() ) ); + } ); + } + +private: + void configureGrid( wxGrid& aGrid ) + { + aGrid.SetCellHighlightPenWidth( 0 ); + aGrid.SetColFormatBool( (int) CU_LAYER_COLNUMS::SELECT ); + } + + void fillLayerGrid( wxGrid& aGrid ) + { + const wxColour bg = m_layerPresentation.getLayerColor( LAYER_PCB_BACKGROUND ).ToColour(); + + aGrid.AppendRows( m_layersId.size() - 1 ); + + int row = 0; + for( const PCB_LAYER_ID& layerId : m_layersId ) + { + const wxColour fg = m_layerPresentation.getLayerColor( layerId ).ToColour(); + const 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 ) ); + + const wxString layerName = wxT( " " ) + m_layerPresentation.getLayerName( layerId ); + + aGrid.SetCellBackgroundColour( row, (int) CU_LAYER_COLNUMS::COLOR, color ); + aGrid.SetCellValue( row, (int) CU_LAYER_COLNUMS::LAYERNAME, layerName ); + + row++; + }; + + // Now fix min grid layer name column size (it also sets a minimal size) + aGrid.AutoSizeColumn( (int) CU_LAYER_COLNUMS::LAYERNAME ); + } + + PCB_LAYER_ID layerForRow( int aRow ) { return m_layersId.at( aRow ); } + + int rowForLayer( PCB_LAYER_ID aLayerId ) + { + for( unsigned i = 0; i < m_layersId.size(); ++i ) + { + if( m_layersId[i] == aLayerId ) + { + return i; + } + } + + wxASSERT_MSG( false, wxString::Format( "Unknown layer in grid: %d", aLayerId ) ); + return 0; + } + + void onLeftGridRowSelected( int aRow ) + { + LAYER_PAIR newPair{ + layerForRow( aRow ), + layerForRow( m_rightCurrRow ), + }; + setCurrentSelection( aRow, m_rightCurrRow ); + m_layerPairSettings.SetCurrentLayerPair( newPair ); + } + + void onRightGridRowSelected( int aRow ) + { + LAYER_PAIR newPair{ + layerForRow( m_leftCurrRow ), + layerForRow( aRow ), + }; + setCurrentSelection( m_leftCurrRow, aRow ); + m_layerPairSettings.SetCurrentLayerPair( newPair ); + } + + /** + * Set the current layer selection. + * + * The layer pair must be copper layers that the selector this class + * was constructed with knows about. + */ + void setCurrentSelection( int aLeftRow, int aRightRow ) + { + const auto selectGridRow = [this]( wxGrid& aGrid, int aRow, bool aSelect ) + { + // At start, there is no old row + if( aRow < 0 ) + { + return; + } + const wxString val = aSelect ? wxT( "1" ) : wxEmptyString; + aGrid.SetCellValue( aRow, (int) CU_LAYER_COLNUMS::SELECT, val ); + aGrid.SetGridCursor( aRow, (int) CU_LAYER_COLNUMS::COLOR ); + }; + + if( m_leftCurrRow != aLeftRow ) + { + selectGridRow( m_leftGrid, m_leftCurrRow, false ); + selectGridRow( m_leftGrid, aLeftRow, true ); + m_leftCurrRow = aLeftRow; + } + + if( m_rightCurrRow != aRightRow ) + { + selectGridRow( m_rightGrid, m_rightCurrRow, false ); + selectGridRow( m_rightGrid, aRightRow, true ); + m_rightCurrRow = aRightRow; + } + } + + PCB_LAYER_PRESENTATION& m_layerPresentation; + LAYER_PAIR_SETTINGS& m_layerPairSettings; + std::vector m_layersId; + wxGrid& m_leftGrid; + wxGrid& m_rightGrid; + + int m_leftCurrRow = -1; + int m_rightCurrRow = -1; +}; + + /** * Display a pair PCB copper layers list in a dialog to select a layer pair from these lists. + * + * This is a higher level class that mostly glues together other controller classes and UI + * elements. */ 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, - PCB_LAYER_ID aFrontLayer, PCB_LAYER_ID aBackLayer ); - - void GetLayerPair( PCB_LAYER_ID& aFrontLayer, PCB_LAYER_ID& aBackLayer ) + SELECT_COPPER_LAYERS_PAIR_DIALOG( PCB_BASE_FRAME& aParent, + LAYER_PAIR_SETTINGS& aBoardSettings ) : + DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE( &aParent ), + m_boardPairSettings( aBoardSettings ), m_dialogPairSettings( aBoardSettings ), + m_layerPresentation( &aParent ), + m_pairSelectionController( *m_leftGridLayers, *m_rightGridLayers, m_layerPresentation, + m_dialogPairSettings ), + m_presetsGridController( *m_presetsGrid, m_layerPresentation, m_dialogPairSettings ) { - aFrontLayer = m_frontLayer; - aBackLayer = m_backLayer; + m_addToPresetsButton->SetBitmap( KiBitmapBundle( BITMAPS::right ) ); + m_deleteRowButton->SetBitmap( KiBitmapBundle( BITMAPS::trash ) ); + + m_addToPresetsButton->Bind( wxEVT_BUTTON, + [this]( wxCommandEvent& aEvent ) + { + const LAYER_PAIR newPair = + m_dialogPairSettings.GetCurrentLayerPair(); + m_presetsGridController.OnLayerPairAdded( newPair ); + } ); + + m_deleteRowButton->Bind( wxEVT_BUTTON, + [this]( wxCommandEvent& aEvent ) + { + m_presetsGridController.OnDeleteSelectedLayerPairs(); + } ); + + SetFocus(); + + GetSizer()->SetSizeHints( this ); + Center(); + } + + bool TransferDataToWindow() override + { + m_presetsGrid->Freeze(); + m_leftGridLayers->Freeze(); + m_rightGridLayers->Freeze(); + + m_dialogPairSettings.SetCurrentLayerPair( m_boardPairSettings.GetCurrentLayerPair() ); + + m_rightGridLayers->Thaw(); + m_leftGridLayers->Thaw(); + m_presetsGrid->Thaw(); + return true; + } + + bool TransferDataFromWindow() override + { + // Pull out the dialog's stored pairs + std::span storePairs = m_dialogPairSettings.GetLayerPairs(); + + m_boardPairSettings.SetLayerPairs( storePairs ); + m_boardPairSettings.SetCurrentLayerPair( m_dialogPairSettings.GetCurrentLayerPair() ); + + return true; } private: - void OnLeftGridCellClick( wxGridEvent& event ) override; - void OnRightGridCellClick( wxGridEvent& event ) override; - - void buildList(); - + // The BOARD's pair store to be updated + LAYER_PAIR_SETTINGS& m_boardPairSettings; + // A local copy while we modify it + LAYER_PAIR_SETTINGS m_dialogPairSettings; + // Information about the layer presentation (colors, etc) 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 m_layersId; + // UI controllers + COPPER_LAYERS_PAIR_SELECTION_UI m_pairSelectionController; + COPPER_LAYERS_PAIR_PRESETS_UI m_presetsGridController; }; int ROUTER_TOOL::SelectCopperLayerPair( const TOOL_EVENT& aEvent ) { - PCB_SCREEN* screen = frame()->GetScreen(); + LAYER_PAIR_SETTINGS* const boardSettings = frame()->GetLayerPairSettings(); - SELECT_COPPER_LAYERS_PAIR_DIALOG dlg( frame(), frame()->GetBoard(), screen->m_Route_Layer_TOP, - screen->m_Route_Layer_BOTTOM ); + if( !boardSettings ) + { + // Should only be used for suitable frame types with layer pairs + wxASSERT_MSG( false, "Could not access layer pair settings" ); + return 0; + } + + SELECT_COPPER_LAYERS_PAIR_DIALOG dlg( *frame(), *boardSettings ); if( dlg.ShowModal() == wxID_OK ) { - dlg.GetLayerPair( screen->m_Route_Layer_TOP, screen->m_Route_Layer_BOTTOM ); + const LAYER_PAIR layerPair = boardSettings->GetCurrentLayerPair(); // select the same layer for both layers is allowed (normal in some boards) // but could be a mistake. So display an info message - if( screen->m_Route_Layer_TOP == screen->m_Route_Layer_BOTTOM ) + if( layerPair.GetLayerA() == layerPair.GetLayerB() ) + { DisplayInfoMessage( frame(), _( "Warning: top and bottom layers are same." ) ); + } } return 0; } - - -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; - m_leftRowSelected = 0; - m_rightRowSelected = 0; - m_brd = aPcb; - - m_leftGridLayers->SetCellHighlightPenWidth( 0 ); - m_rightGridLayers->SetCellHighlightPenWidth( 0 ); - m_leftGridLayers->SetColFormatBool( SELECT_COLNUM ); - m_rightGridLayers->SetColFormatBool( SELECT_COLNUM ); - buildList(); - - SetFocus(); - - GetSizer()->SetSizeHints( this ); - Center(); -} - - -void SELECT_COPPER_LAYERS_PAIR_DIALOG::buildList() -{ - wxColour bg = m_layerPresentation.getLayerColor( LAYER_PCB_BACKGROUND ).ToColour(); - int row = 0; - wxString layername; - - for( PCB_LAYER_ID layerid : m_brd->GetEnabledLayers().UIOrder() ) - { - if( !IsCopperLayer( layerid ) ) - continue; - - 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( " " ) + m_layerPresentation.getLayerName( layerid ); - - if( row ) - m_leftGridLayers->AppendRows( 1 ); - - m_leftGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color ); - m_leftGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername ); - m_layersId.push_back( layerid ); - - if( m_frontLayer == layerid ) - { - m_leftGridLayers->SetCellValue( row, SELECT_COLNUM, wxT( "1" ) ); - m_leftGridLayers->SetGridCursor( row, COLOR_COLNUM ); - m_leftRowSelected = row; - } - - if( row ) - m_rightGridLayers->AppendRows( 1 ); - - m_rightGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color ); - m_rightGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername ); - - if( m_backLayer == layerid ) - { - m_rightGridLayers->SetCellValue( row, SELECT_COLNUM, wxT( "1" ) ); - m_rightRowSelected = row; - } - - row++; - } - - // Now fix min grid layer name column size (it also sets a minimal size) - m_leftGridLayers->AutoSizeColumn( LAYERNAME_COLNUM ); - m_rightGridLayers->AutoSizeColumn( LAYERNAME_COLNUM ); -} - - -void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnLeftGridCellClick( wxGridEvent& event ) -{ - int row = event.GetRow(); - PCB_LAYER_ID layer = m_layersId[row]; - - if( m_frontLayer == layer ) - return; - - m_leftGridLayers->SetCellValue( m_leftRowSelected, SELECT_COLNUM, wxEmptyString ); - m_frontLayer = layer; - m_leftRowSelected = row; - m_leftGridLayers->SetCellValue( m_leftRowSelected, SELECT_COLNUM, wxT( "1" ) ); -} - - -void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnRightGridCellClick( wxGridEvent& event ) -{ - int row = event.GetRow(); - PCB_LAYER_ID layer = m_layersId[row]; - - if( m_backLayer == layer ) - return; - - m_rightGridLayers->SetCellValue( m_rightRowSelected, SELECT_COLNUM, wxEmptyString ); - m_backLayer = layer; - m_rightRowSelected = row; - m_rightGridLayers->SetCellValue( m_rightRowSelected, SELECT_COLNUM, wxT( "1" ) ); -} diff --git a/pcbnew/toolbars_pcb_editor.cpp b/pcbnew/toolbars_pcb_editor.cpp index ee816bd853..7d444964e0 100644 --- a/pcbnew/toolbars_pcb_editor.cpp +++ b/pcbnew/toolbars_pcb_editor.cpp @@ -440,17 +440,6 @@ void PCB_EDIT_FRAME::ReCreateAuxiliaryToolbar() m_auxiliaryToolBar = new ACTION_TOOLBAR( this, ID_AUX_TOOLBAR, wxDefaultPosition, wxDefaultSize, KICAD_AUI_TB_STYLE | wxAUI_TB_HORZ_LAYOUT ); - - // The layer indicator is special, so we register a callback directly that will - // regenerate the bitmap instead of using the conditions system. - auto layerIndicatorUpdate = - [this] ( wxUpdateUIEvent& ) - { - PrepareLayerIndicator(); - }; - - Bind( wxEVT_UPDATE_UI, layerIndicatorUpdate, PCB_ACTIONS::selectLayerPair.GetUIId() ); - m_auxiliaryToolBar->SetAuiManager( &m_auimgr ); }