sel_layer.cpp 13 KB
Newer Older
1 2
/**
 * @file sel_layer.cpp
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 * @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
27
 */
plyatov's avatar
plyatov committed
28

29

30 31 32 33 34
#include <fctsys.h>
#include <common.h>
#include <class_drawpanel.h>
#include <confirm.h>
#include <wxBasePcbFrame.h>
35
#include <class_layer_box_selector.h>
36
#include <class_board.h>
37
#include <dialogs/dialog_layer_selection_base.h>
plyatov's avatar
plyatov committed
38 39


40 41 42
/* classes to display a layer list using a wxGrid.
 */
class PCB_LAYER_SELECTOR: public LAYER_SELECTOR
plyatov's avatar
plyatov committed
43 44
{
public:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
45 46
    PCB_LAYER_SELECTOR( BOARD* aBrd ) :
        LAYER_SELECTOR()
47 48 49
    {
        m_brd = aBrd;
    }
50

51
protected:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
52 53
    BOARD*  m_brd;

54 55 56
    // Returns true if the layer id is enabled (i.e. is it should be displayed)
    bool IsLayerEnabled( LAYER_NUM aLayer ) const
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
57
        return m_brd->IsLayerEnabled( LAYER_ID( aLayer ) );
58
    }
plyatov's avatar
plyatov committed
59

60 61 62 63
    // Returns a color index from the layer id
    // Virtual function
    EDA_COLOR_T GetLayerColor( LAYER_NUM aLayer ) const
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
64
        return m_brd->GetLayerColor( ToLAYER_ID( aLayer ) );
65
    }
66

67
    // Returns the name of the layer id
Dick Hollenbeck's avatar
Dick Hollenbeck committed
68
    wxString GetLayerName( LAYER_NUM aLayer ) const      // overrides LAYER_SELECTOR
69
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
70
        return m_brd->GetLayerName( ToLAYER_ID( aLayer ) );
71 72
    }
};
plyatov's avatar
plyatov committed
73

Dick Hollenbeck's avatar
Dick Hollenbeck committed
74

75
/*
76
 * This class display a pcb layers list in a dialog,
77
 * to select one layer from this list
78
 */
79 80
class PCB_ONE_LAYER_SELECTOR : public PCB_LAYER_SELECTOR,
                               public DIALOG_LAYER_SELECTION_BASE
plyatov's avatar
plyatov committed
81
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
82 83 84 85 86
    LAYER_ID    m_layerSelected;
    LSET        m_notAllowedLayersMask;

    std::vector<LAYER_ID> m_layersIdLeftColumn;
    std::vector<LAYER_ID> m_layersIdRightColumn;
87

88 89
public:
    PCB_ONE_LAYER_SELECTOR( wxWindow* aParent, BOARD * aBrd,
Dick Hollenbeck's avatar
Dick Hollenbeck committed
90 91
                        LAYER_ID aDefaultLayer,
                        LSET aNotAllowedLayersMask );
92

Dick Hollenbeck's avatar
Dick Hollenbeck committed
93
    LAYER_NUM GetLayerSelection()   { return m_layerSelected; }
94

95 96
private:
    // Event handlers
97 98
    void OnLeftGridCellClick( wxGridEvent& event );
    void OnRightGridCellClick( wxGridEvent& event );
99

Dick Hollenbeck's avatar
Dick Hollenbeck committed
100
    void buildList();
101
};
102

Dick Hollenbeck's avatar
Dick Hollenbeck committed
103

104
PCB_ONE_LAYER_SELECTOR::PCB_ONE_LAYER_SELECTOR( wxWindow* aParent,
Dick Hollenbeck's avatar
Dick Hollenbeck committed
105
        BOARD* aBrd, LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask )
106 107
    : PCB_LAYER_SELECTOR( aBrd ), DIALOG_LAYER_SELECTION_BASE( aParent )
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
108
    m_layerSelected = aDefaultLayer;
109
    m_notAllowedLayersMask = aNotAllowedLayersMask;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
110
    buildList();
111
    Layout();
Dick Hollenbeck's avatar
Dick Hollenbeck committed
112
    GetSizer()->SetSizeHints( this );
113 114 115
    SetFocus();
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
116

117 118
// Build the layers list
// Column position by function:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
119 120 121
#define SELECT_COLNUM       0
#define COLOR_COLNUM        1
#define LAYERNAME_COLNUM    2
122

Dick Hollenbeck's avatar
Dick Hollenbeck committed
123
void PCB_ONE_LAYER_SELECTOR::buildList()
124
{
125 126
    // Hide layerid column which is used only to know the layer id
    // not to be shown in dialogs
127 128 129
    m_leftGridLayers->SetColSize( COLOR_COLNUM, 20 );
    m_rightGridLayers->SetColSize( COLOR_COLNUM, 20 );

Dick Hollenbeck's avatar
Dick Hollenbeck committed
130 131 132
    int         left_row = 0;
    int         right_row = 0;
    wxString    layername;
133

Dick Hollenbeck's avatar
Dick Hollenbeck committed
134 135 136
    for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder();  ui_seq;  ++ui_seq )
    {
        LAYER_ID  layerid = *ui_seq;
137

Dick Hollenbeck's avatar
Dick Hollenbeck committed
138
        if( m_notAllowedLayersMask[layerid] )
139
            continue;
140

141 142
        wxColour color = MakeColour( GetLayerColor( layerid ) );
        layername = GetLayerName( layerid );
143

Dick Hollenbeck's avatar
Dick Hollenbeck committed
144
        if( IsCopperLayer( layerid ) )
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
        {
            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 );
160
                m_leftGridLayers->SetGridCursor( left_row, LAYERNAME_COLNUM );
161 162
            }

163
            m_layersIdLeftColumn.push_back( layerid );
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
            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 );
182
                m_rightGridLayers->SetGridCursor( right_row, LAYERNAME_COLNUM );
183 184
            }

185
            m_layersIdRightColumn.push_back( layerid );
186 187 188
            right_row++;
        }
    }
plyatov's avatar
plyatov committed
189

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

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

197 198 199 200
    m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
    m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
    m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM);
    m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
plyatov's avatar
plyatov committed
201 202
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
203

204
void PCB_ONE_LAYER_SELECTOR::OnLeftGridCellClick( wxGridEvent& event )
plyatov's avatar
plyatov committed
205
{
206
    m_layerSelected = m_layersIdLeftColumn[ event.GetRow() ];
207
    m_leftGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM );
208
    EndModal( 1 );
plyatov's avatar
plyatov committed
209 210
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
211

212
void PCB_ONE_LAYER_SELECTOR::OnRightGridCellClick( wxGridEvent& event )
plyatov's avatar
plyatov committed
213
{
214
    m_layerSelected = m_layersIdRightColumn[ event.GetRow() ];
215
    m_rightGridLayers->SetGridCursor( event.GetRow(), LAYERNAME_COLNUM );
216
    EndModal( 2 );
plyatov's avatar
plyatov committed
217 218
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
219 220 221

LAYER_ID PCB_BASE_FRAME::SelectLayer( LAYER_ID aDefaultLayer,
        LSET aNotAllowedLayersMask, wxPoint aDlgPosition )
222
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
223 224
    PCB_ONE_LAYER_SELECTOR dlg( this, GetBoard(), aDefaultLayer, aNotAllowedLayersMask );

225 226 227 228 229 230 231
    if( aDlgPosition != wxDefaultPosition )
    {
        wxSize dlgSize = dlg.GetSize();
        aDlgPosition.x -= dlgSize.x/2;
        aDlgPosition.y -= dlgSize.y/2;
        dlg.SetPosition( aDlgPosition );
    }
Dick Hollenbeck's avatar
Dick Hollenbeck committed
232

233
    dlg.ShowModal();
Dick Hollenbeck's avatar
Dick Hollenbeck committed
234

Dick Hollenbeck's avatar
Dick Hollenbeck committed
235
    LAYER_ID layer = ToLAYER_ID( dlg.GetLayerSelection() );
236 237
    return layer;
}
plyatov's avatar
plyatov committed
238 239


Dick Hollenbeck's avatar
Dick Hollenbeck committed
240 241 242
/**
 * Class SELECT_COPPER_LAYERS_PAIR_DIALOG
 * displays a double pcb copper layers list in a dialog,
243
 * to select a layer pair from these lists
244 245 246
 */
class SELECT_COPPER_LAYERS_PAIR_DIALOG: public PCB_LAYER_SELECTOR,
                                        public DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE
plyatov's avatar
plyatov committed
247 248
{
private:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
249 250 251 252 253 254
    LAYER_ID    m_frontLayer;
    LAYER_ID    m_backLayer;
    int         m_leftRowSelected;
    int         m_rightRowSelected;

    std::vector<LAYER_ID> m_layersId;
255 256

public:
Dick Hollenbeck's avatar
Dick Hollenbeck committed
257 258
    SELECT_COPPER_LAYERS_PAIR_DIALOG( wxWindow* aParent, BOARD* aPcb,
                                      LAYER_ID aFrontLayer, LAYER_ID aBackLayer );
plyatov's avatar
plyatov committed
259

Dick Hollenbeck's avatar
Dick Hollenbeck committed
260
    void GetLayerPair( LAYER_ID& aFrontLayer, LAYER_ID& aBackLayer )
261 262 263 264
    {
        aFrontLayer = m_frontLayer;
        aBackLayer = m_backLayer;
    }
plyatov's avatar
plyatov committed
265 266

private:
267 268
    void OnLeftGridCellClick( wxGridEvent& event );
    void OnRightGridCellClick( wxGridEvent& event );
plyatov's avatar
plyatov committed
269

270 271 272 273
    void OnOkClick( wxCommandEvent& event )
    {
        EndModal( wxID_OK );
    }
274

275 276 277 278
    void OnCancelClick( wxCommandEvent& event )
    {
        EndModal( wxID_CANCEL );
    }
279

Dick Hollenbeck's avatar
Dick Hollenbeck committed
280
    void buildList();
281
    void SetGridCursor( wxGrid* aGrid, int aRow, bool aEnable );
282
};
283

Dick Hollenbeck's avatar
Dick Hollenbeck committed
284

285
void PCB_BASE_FRAME::SelectCopperLayerPair()
plyatov's avatar
plyatov committed
286
{
287
    PCB_SCREEN* screen = GetScreen();
Dick Hollenbeck's avatar
Dick Hollenbeck committed
288

289 290 291 292 293
    SELECT_COPPER_LAYERS_PAIR_DIALOG dlg( this, GetBoard(),
                                         screen->m_Route_Layer_TOP,
                                         screen->m_Route_Layer_BOTTOM );

    if( dlg.ShowModal() == wxID_OK )
294
    {
295
        dlg.GetLayerPair( screen->m_Route_Layer_TOP, screen->m_Route_Layer_BOTTOM );
296

297 298 299 300 301 302
        // 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." ) );
    }
303

304
    m_canvas->MoveCursorToCrossHair();
plyatov's avatar
plyatov committed
305 306
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
307 308 309

SELECT_COPPER_LAYERS_PAIR_DIALOG::SELECT_COPPER_LAYERS_PAIR_DIALOG(
        wxWindow* aParent, BOARD * aPcb, LAYER_ID aFrontLayer, LAYER_ID aBackLayer) :
310 311
    PCB_LAYER_SELECTOR( aPcb ),
    DIALOG_COPPER_LAYER_PAIR_SELECTION_BASE( aParent )
plyatov's avatar
plyatov committed
312
{
313 314 315 316
    m_frontLayer = aFrontLayer;
    m_backLayer = aBackLayer;
    m_leftRowSelected = 0;
    m_rightRowSelected = 0;
Dick Hollenbeck's avatar
Dick Hollenbeck committed
317
    buildList();
318 319 320 321
    SetFocus();
    GetSizer()->SetSizeHints( this );
    Center();
}
322

Dick Hollenbeck's avatar
Dick Hollenbeck committed
323 324

void SELECT_COPPER_LAYERS_PAIR_DIALOG::buildList()
325 326 327 328 329 330
{
    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

Dick Hollenbeck's avatar
Dick Hollenbeck committed
331 332
    int         row = 0;
    wxString    layername;
333

Dick Hollenbeck's avatar
Dick Hollenbeck committed
334
    for( LSEQ ui_seq = m_brd->GetEnabledLayers().UIOrder();  ui_seq;  ++ui_seq )
335
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
336
        LAYER_ID  layerid = *ui_seq;
337

Dick Hollenbeck's avatar
Dick Hollenbeck committed
338 339
        if( !IsCopperLayer( layerid ) )
            break;
340

341
        wxColour color = MakeColour( GetLayerColor( layerid ) );
Dick Hollenbeck's avatar
Dick Hollenbeck committed
342

343
        layername = GetLayerName( layerid );
344

345 346
        if( row )
            m_leftGridLayers->AppendRows( 1 );
347

Dick Hollenbeck's avatar
Dick Hollenbeck committed
348 349
        m_leftGridLayers->SetCellBackgroundColour( row, COLOR_COLNUM, color );
        m_leftGridLayers->SetCellValue( row, LAYERNAME_COLNUM, layername );
350
        m_layersId.push_back( layerid );
351

352 353
        if( m_frontLayer == layerid )
        {
354
            SetGridCursor( m_leftGridLayers, row, true );
355
            m_leftRowSelected = row;
356 357
        }

358 359 360 361 362 363
        if( row )
            m_rightGridLayers->AppendRows( 1 );
        m_rightGridLayers->SetCellBackgroundColour ( row, COLOR_COLNUM,
                                                     color );
        m_rightGridLayers->SetCellValue( row, LAYERNAME_COLNUM,
                                         layername );
364

365 366
        if( m_backLayer == layerid )
        {
367
            SetGridCursor( m_rightGridLayers, row, true );
368 369
            m_rightRowSelected = row;
        }
370

371 372
        row++;
    }
373

374 375 376 377 378
    m_leftGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
    m_rightGridLayers->AutoSizeColumn(LAYERNAME_COLNUM);
    m_leftGridLayers->AutoSizeColumn(SELECT_COLNUM);
    m_rightGridLayers->AutoSizeColumn(SELECT_COLNUM);
}
379

Dick Hollenbeck's avatar
Dick Hollenbeck committed
380

381 382 383 384 385
void SELECT_COPPER_LAYERS_PAIR_DIALOG::SetGridCursor( wxGrid* aGrid, int aRow,
                                                      bool aEnable )
{
    if( aEnable )
    {
Dick Hollenbeck's avatar
Dick Hollenbeck committed
386
        LAYER_ID  layerid = m_layersId[aRow];
387 388 389 390 391 392 393 394 395 396 397 398 399 400
        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 );
    }
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
401

402
void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnLeftGridCellClick( wxGridEvent& event )
403
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
404 405
    int         row = event.GetRow();
    LAYER_ID    layer = m_layersId[row];
406

407 408
    if( m_frontLayer == layer )
        return;
409

410
    SetGridCursor( m_leftGridLayers, m_leftRowSelected, false );
411 412
    m_frontLayer = layer;
    m_leftRowSelected = row;
413
    SetGridCursor( m_leftGridLayers, m_leftRowSelected, true );
plyatov's avatar
plyatov committed
414 415
}

Dick Hollenbeck's avatar
Dick Hollenbeck committed
416

417
void SELECT_COPPER_LAYERS_PAIR_DIALOG::OnRightGridCellClick( wxGridEvent& event )
plyatov's avatar
plyatov committed
418
{
Dick Hollenbeck's avatar
Dick Hollenbeck committed
419 420
    int         row = event.GetRow();
    LAYER_ID    layer = m_layersId[row];
plyatov's avatar
plyatov committed
421

Dick Hollenbeck's avatar
Dick Hollenbeck committed
422
    if( m_backLayer == layer )
423
        return;
424

425
    SetGridCursor( m_rightGridLayers, m_rightRowSelected, false );
426 427
    m_backLayer = layer;
    m_rightRowSelected = row;
428
    SetGridCursor( m_rightGridLayers, m_rightRowSelected, true );
plyatov's avatar
plyatov committed
429
}