diff options
Diffstat (limited to 'pcbnew/sel_layer.cpp')
-rw-r--r-- | pcbnew/sel_layer.cpp | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/pcbnew/sel_layer.cpp b/pcbnew/sel_layer.cpp new file mode 100644 index 0000000..b32b032 --- /dev/null +++ b/pcbnew/sel_layer.cpp @@ -0,0 +1,429 @@ +/** + * @file sel_layer.cpp + * @brief dialogs for one layer selection and a layer pair selection. + */ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 1992-2013 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 <fctsys.h> +#include <common.h> +#include <class_drawpanel.h> +#include <confirm.h> +#include <wxBasePcbFrame.h> +#include <class_layer_box_selector.h> +#include <class_board.h> +#include <dialogs/dialog_layer_selection_base.h> + + +/* classes to display a layer list using a wxGrid. + */ +class PCB_LAYER_SELECTOR: public LAYER_SELECTOR +{ +public: + PCB_LAYER_SELECTOR( BOARD* aBrd ) : + LAYER_SELECTOR() + { + m_brd = aBrd; + } + +protected: + BOARD* m_brd; + + // Returns true if the layer id is enabled (i.e. is it should be displayed) + bool IsLayerEnabled( LAYER_NUM aLayer ) const + { + return m_brd->IsLayerEnabled( LAYER_ID( aLayer ) ); + } + + // Returns a color index from the layer id + // Virtual function + EDA_COLOR_T GetLayerColor( LAYER_NUM aLayer ) const + { + return m_brd->GetLayerColor( ToLAYER_ID( aLayer ) ); + } + + // Returns the name of the layer id + wxString GetLayerName( LAYER_NUM aLayer ) const // overrides LAYER_SELECTOR + { + return m_brd->GetLayerName( ToLAYER_ID( aLayer ) ); + } +}; + + +/* + * This class 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 +{ + LAYER_ID m_layerSelected; + LSET m_notAllowedLayersMask; + + std::vector<LAYER_ID> m_layersIdLeftColumn; + std::vector<LAYER_ID> m_layersIdRightColumn; + +public: + PCB_ONE_LAYER_SELECTOR( wxWindow* aParent, BOARD * aBrd, + LAYER_ID aDefaultLayer, + LSET aNotAllowedLayersMask ); + + LAYER_NUM GetLayerSelection() { return m_layerSelected; } + +private: + // Event handlers + void OnLeftGridCellClick( wxGridEvent& event ); + void OnRightGridCellClick( wxGridEvent& event ); + + void buildList(); +}; + + +PCB_ONE_LAYER_SELECTOR::PCB_ONE_LAYER_SELECTOR( wxWindow* aParent, + BOARD* aBrd, LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask ) + : PCB_LAYER_SELECTOR( aBrd ), DIALOG_LAYER_SELECTION_BASE( aParent ) +{ + m_layerSelected = aDefaultLayer; + m_notAllowedLayersMask = aNotAllowedLayersMask; + buildList(); + Layout(); + GetSizer()->SetSizeHints( this ); + SetFocus(); +} + + +// Build the layers list +// Column position by function: +#define SELECT_COLNUM 0 +#define COLOR_COLNUM 1 +#define LAYERNAME_COLNUM 2 + +void PCB_ONE_LAYER_SELECTOR::buildList() +{ + // Hide layerid column which is used only to know the layer id + // not to be shown in dialogs + m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 ); + m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 ); + + int left_row = 0; + int right_row = 0; + wxString layername; + + for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq ) + { + LAYER_ID layerid = *ui_seq; + + if( m_notAllowedLayersMask[layerid] ) + continue; + + wxColour color = MakeColour( GetLayerColor( layerid ) ); + layername = GetLayerName( layerid ); + + if( IsCopperLayer( layerid ) ) + { + if( left_row ) + m_leftGridLayers->AppendRows( 1 ); + + m_leftGridLayers->SetCellBackgroundColour ( left_row, COLOR_COLNUM, + color ); + m_leftGridLayers->SetCellValue( left_row, LAYERNAME_COLNUM, + layername ); + + if( m_layerSelected == layerid ) + { + m_leftGridLayers->SetCellValue( left_row, SELECT_COLNUM, + wxT("X") ); + m_leftGridLayers->SetCellBackgroundColour ( left_row, SELECT_COLNUM, + color ); + m_leftGridLayers->SetGridCursor( left_row, LAYERNAME_COLNUM ); + } + + m_layersIdLeftColumn.push_back( layerid ); + left_row++; + } + else + { + if( right_row ) + m_rightGridLayers->AppendRows( 1 ); + + m_rightGridLayers->SetCellBackgroundColour ( right_row, COLOR_COLNUM, + color ); + m_rightGridLayers->SetCellValue( right_row, LAYERNAME_COLNUM, + layername ); + + if( m_layerSelected == layerid ) + { + m_rightGridLayers->SetCellValue( right_row, SELECT_COLNUM, + wxT("X") ); + m_rightGridLayers->SetCellBackgroundColour ( right_row, SELECT_COLNUM, + color ); + m_rightGridLayers->SetGridCursor( right_row, LAYERNAME_COLNUM ); + } + + m_layersIdRightColumn.push_back( layerid ); + right_row++; + } + } + + // Show only populated lists: + if( left_row <= 0 ) + m_leftGridLayers->Show( false ); + + if( right_row <= 0 ) + m_rightGridLayers->Show( false ); + + m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM); + m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM); + m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM); + m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM); +} + + +void PCB_ONE_LAYER_SELECTOR::OnLeftGridCellClick( wxGridEvent& event ) +{ + m_layerSelected = m_layersIdLeftColumn[ event.GetRow() ]; + m_leftGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM ); + EndModal( 1 ); +} + + +void PCB_ONE_LAYER_SELECTOR::OnRightGridCellClick( wxGridEvent& event ) +{ + m_layerSelected = m_layersIdRightColumn[ event.GetRow() ]; + m_rightGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM ); + EndModal( 2 ); +} + + +LAYER_ID PCB_BASE_FRAME::SelectLayer( LAYER_ID aDefaultLayer, + LSET aNotAllowedLayersMask, wxPoint aDlgPosition ) +{ + PCB_ONE_LAYER_SELECTOR dlg( this, GetBoard(), aDefaultLayer, aNotAllowedLayersMask ); + + if( aDlgPosition != wxDefaultPosition ) + { + wxSize dlgSize = dlg.GetSize(); + aDlgPosition.x -= dlgSize.x/2; + aDlgPosition.y -= dlgSize.y/2; + dlg.SetPosition( aDlgPosition ); + } + + dlg.ShowModal(); + + LAYER_ID layer = ToLAYER_ID( dlg.GetLayerSelection() ); + return layer; +} + + +/** + * Class SELECT_COPPER_LAYERS_PAIR_DIALOG + * displays a double 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 +{ +private: + LAYER_ID m_frontLayer; + LAYER_ID m_backLayer; + int m_leftRowSelected; + int m_rightRowSelected; + + std::vector<LAYER_ID> m_layersId; + +public: + SELECT_COPPER_LAYERS_PAIR_DIALOG( wxWindow* aParent, BOARD* aPcb, + LAYER_ID aFrontLayer, LAYER_ID aBackLayer ); + + void GetLayerPair( LAYER_ID& aFrontLayer, LAYER_ID& aBackLayer ) + { + aFrontLayer = m_frontLayer; + aBackLayer = m_backLayer; + } + +private: + void OnLeftGridCellClick( wxGridEvent& event ); + void OnRightGridCellClick( wxGridEvent& event ); + + void OnOkClick( wxCommandEvent& event ) + { + EndModal( wxID_OK ); + } + + void OnCancelClick( wxCommandEvent& event ) + { + EndModal( wxID_CANCEL ); + } + + void buildList(); + void SetGridCursor( wxGrid* aGrid, int aRow, bool aEnable ); +}; + + +void PCB_BASE_FRAME::SelectCopperLayerPair() +{ + PCB_SCREEN* screen = GetScreen(); + + SELECT_COPPER_LAYERS_PAIR_DIALOG dlg( this, GetBoard(), + screen->m_Route_Layer_TOP, + screen->m_Route_Layer_BOTTOM ); + + if( dlg.ShowModal() == wxID_OK ) + { + dlg.GetLayerPair( screen->m_Route_Layer_TOP, screen->m_Route_Layer_BOTTOM ); + + // 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 ) + DisplayInfoMessage( this, + _( "Warning: The Top Layer and Bottom Layer are same." ) ); + } + + m_canvas->MoveCursorToCrossHair(); +} + + +SELECT_COPPER_LAYERS_PAIR_DIALOG::SELECT_COPPER_LAYERS_PAIR_DIALOG( + wxWindow* aParent, BOARD * aPcb, LAYER_ID aFrontLayer, LAYER_ID aBackLayer) : + PCB_LAYER_SELECTOR( aPcb ), + DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE( aParent ) +{ + m_frontLayer = aFrontLayer; + m_backLayer = aBackLayer; + m_leftRowSelected = 0; + m_rightRowSelected = 0; + buildList(); + SetFocus(); + GetSizer()->SetSizeHints( this ); + Center(); +} + + +void SELECT_COPPER_LAYERS_PAIR_DIALOG::buildList() +{ + m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 ); + m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 ); + + // Select a not show cell, to avoid a wrong cell selection for user + + int row = 0; + wxString layername; + + for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder(); ui_seq; ++ui_seq ) + { + LAYER_ID layerid = *ui_seq; + + if( !IsCopperLayer( layerid ) ) + break; + + wxColour color = MakeColour( GetLayerColor( layerid ) ); + + layername = 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 ) + { + SetGridCursor( m_leftGridLayers, row, true ); + 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 ) + { + SetGridCursor( m_rightGridLayers, row, true ); + m_rightRowSelected = row; + } + + row++; + } + + m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM); + m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM); + m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM); + m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM); +} + + +void SELECT_COPPER_LAYERS_PAIR_DIALOG::SetGridCursor( wxGrid* aGrid, int aRow, + bool aEnable ) +{ + if( aEnable ) + { + LAYER_ID layerid = m_layersId[aRow]; + wxColour color = MakeColour( GetLayerColor( layerid ) ); + aGrid->SetCellValue( aRow, SELECT_COLNUM, wxT("X") ); + aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM, color ); + aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM ); + } + else + { + aGrid->SetCellValue( aRow, SELECT_COLNUM, wxEmptyString ); + aGrid->SetCellBackgroundColour( aRow, SELECT_COLNUM, + aGrid->GetDefaultCellBackgroundColour() ); + aGrid->SetGridCursor( aRow, LAYERNAME_COLNUM ); + } +} + + +void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnLeftGridCellClick( wxGridEvent& event ) +{ + int row = event.GetRow(); + LAYER_ID layer = m_layersId[row]; + + if( m_frontLayer == layer ) + return; + + SetGridCursor( m_leftGridLayers, m_leftRowSelected, false ); + m_frontLayer = layer; + m_leftRowSelected = row; + SetGridCursor( m_leftGridLayers, m_leftRowSelected, true ); +} + + +void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnRightGridCellClick( wxGridEvent& event ) +{ + int row = event.GetRow(); + LAYER_ID layer = m_layersId[row]; + + if( m_backLayer == layer ) + return; + + SetGridCursor( m_rightGridLayers, m_rightRowSelected, false ); + m_backLayer = layer; + m_rightRowSelected = row; + SetGridCursor( m_rightGridLayers, m_rightRowSelected, true ); +} |