sel_layer.cpp 11.3 KB
Newer Older
1
/* Set up the basic primitives for Layer control */
plyatov's avatar
plyatov committed
2 3 4 5

#include "fctsys.h"
#include "gr_basic.h"
#include "common.h"
6 7
#include "class_drawpanel.h"
#include "confirm.h"
plyatov's avatar
plyatov committed
8

9
#include "pcbnew.h"
charras's avatar
charras committed
10
#include "class_board_design_settings.h"
plyatov's avatar
plyatov committed
11 12 13 14
#include "protos.h"


enum layer_sel_id {
15
    ID_LAYER_SELECT_TOP = 1800,
16 17
    ID_LAYER_SELECT_BOTTOM,
    ID_LAYER_SELECT
plyatov's avatar
plyatov committed
18 19 20
};


21
class WinEDA_SelLayerFrame : public wxDialog
plyatov's avatar
plyatov committed
22 23
{
private:
24 25
    WinEDA_BasePcbFrame* m_Parent;
    wxRadioBox*          m_LayerList;
26 27
    int m_LayerId[NB_LAYERS + 1]; // One extra element for "(Deselect)"
                                  // radiobutton
plyatov's avatar
plyatov committed
28 29

public:
30 31
    // Constructor and destructor
    WinEDA_SelLayerFrame( WinEDA_BasePcbFrame* parent, int default_layer,
32
                          int min_layer, int max_layer, bool null_layer );
33
    ~WinEDA_SelLayerFrame() { };
plyatov's avatar
plyatov committed
34 35

private:
36 37
    void Sel_Layer( wxCommandEvent& event );
    void OnCancelClick( wxCommandEvent& event );
plyatov's avatar
plyatov committed
38

39
    DECLARE_EVENT_TABLE()
plyatov's avatar
plyatov committed
40
};
41

42

43
BEGIN_EVENT_TABLE( WinEDA_SelLayerFrame, wxDialog )
dickelbeck's avatar
dickelbeck committed
44 45
    EVT_BUTTON( wxID_OK, WinEDA_SelLayerFrame::Sel_Layer )
    EVT_BUTTON( wxID_CANCEL, WinEDA_SelLayerFrame::OnCancelClick )
46
    EVT_RADIOBOX( ID_LAYER_SELECT, WinEDA_SelLayerFrame::Sel_Layer )
plyatov's avatar
plyatov committed
47 48
END_EVENT_TABLE()

49

50
/** Install the dialog box for layer selection
51
 * @param default_layer = Preselection (NB_LAYERS for "(Deselect)" layer)
52
 * @param min_layer = min layer value (-1 if no min value)
53 54 55
 * @param max_layer = max layer value (-1 if no max value)
 * @param null_layer = display a "(Deselect)" radiobutton (when set to true)
 * @return new layer value (NB_LAYERS when "(Deselect)" radiobutton selected),
56
 *                         or -1 if canceled
57 58 59 60 61 62
 *
 * Providing the option to also display a "(Deselect)" radiobutton makes the
 * "Swap Layers" command (and GerbView's "Export to Pcbnew" command) more "user
 * friendly", by permitting any layer to be "deselected" immediately after its
 * corresponding radiobutton has been clicked on. (It would otherwise be
 * necessary to first cancel the "Select Layer:" dialog box (invoked after a
63 64
 * different radiobutton is clicked on) prior to then clicking on the
 * "Deselect"
65
 * button provided within the "Swap Layers:" or "Layer selection:" dialog box).
66
 */
67 68 69 70
int WinEDA_BasePcbFrame::SelectLayer( int  default_layer,
                                      int  min_layer,
                                      int  max_layer,
                                      bool null_layer )
plyatov's avatar
plyatov committed
71
{
72
    int layer;
73 74 75 76 77
    WinEDA_SelLayerFrame* frame = new WinEDA_SelLayerFrame( this,
                                                            default_layer,
                                                            min_layer,
                                                            max_layer,
                                                            null_layer );
78

79 80
    layer = frame->ShowModal();
    frame->Destroy();
81
    return layer;
plyatov's avatar
plyatov committed
82 83 84
}


85 86 87 88 89 90
/*
 * The "OK" and "Cancel" buttons are positioned (in a horizontal line)
 * beneath the "Layer" radiobox, unless that contains only one column of
 * radiobuttons, in which case they are positioned (in a vertical line)
 * to the right of that radiobox.
 */
91 92 93 94 95 96
WinEDA_SelLayerFrame::WinEDA_SelLayerFrame( WinEDA_BasePcbFrame* parent,
                                            int default_layer, int min_layer,
                                            int max_layer, bool null_layer ) :
    wxDialog( parent, -1, _( "Select Layer:" ), wxPoint( -1, -1 ),
              wxSize( 470, 250 ),
              DIALOG_STYLE )
plyatov's avatar
plyatov committed
97
{
98
    BOARD*    board = parent->GetBoard();
99
    wxButton* Button;
100
    int       ii;
101 102
    wxString  LayerList[NB_LAYERS + 1]; // One extra element for "(Deselect)"
                                        // radiobutton
103
    int       LayerCount, LayerSelect = -1;
104

105 106
    m_Parent = parent;

107
    /* Build the layer list */
108
    LayerCount = 0;
109 110
    int Masque_Layer =
        g_TabAllCopperLayerMask[g_DesignSettings.GetCopperLayerCount() - 1];
111 112 113 114
    Masque_Layer += ALL_NO_CU_LAYERS;
    for( ii = 0; ii < NB_LAYERS; ii++ )
    {
        m_LayerId[ii] = 0;
115 116

        if( g_TabOneLayerMask[ii] & Masque_Layer )
117 118 119
        {
            if( min_layer > ii )
                continue;
120

121
            if( ( max_layer >= 0 ) && ( max_layer < ii ) )
122
                break;
123

dickelbeck's avatar
dickelbeck committed
124
            LayerList[LayerCount] = board->GetLayerName( ii );
125 126
            if( ii == default_layer )
                LayerSelect = LayerCount;
127

128 129 130 131
            m_LayerId[LayerCount] = ii;
            LayerCount++;
        }
    }
132

133 134 135 136 137 138
    // When appropriate, also provide a "(Deselect)" radiobutton
    if( null_layer )
    {
        LayerList[LayerCount] = _( "(Deselect)" );
        if( NB_LAYERS == default_layer )
            LayerSelect = LayerCount;
139

140 141 142
        m_LayerId[LayerCount] = NB_LAYERS;
        LayerCount++;
    }
143

144 145 146 147 148
    m_LayerList = new wxRadioBox( this, ID_LAYER_SELECT, _( "Layer" ),
                                  wxPoint( -1, -1 ), wxSize( -1, -1 ),
                                  LayerCount, LayerList,
                                  (LayerCount < 8) ? LayerCount : 8,
                                  wxRA_SPECIFY_ROWS );
149 150 151 152

    if( LayerSelect >= 0 )
        m_LayerList->SetSelection( LayerSelect );

153 154 155 156 157
    wxBoxSizer* FrameBoxSizer = new wxBoxSizer( wxHORIZONTAL );
    SetSizer( FrameBoxSizer );
    FrameBoxSizer->Add( m_LayerList, 0, wxALIGN_TOP | wxALL, 5 );
    wxBoxSizer* ButtonBoxSizer = new wxBoxSizer( wxVERTICAL );
    FrameBoxSizer->Add( ButtonBoxSizer, 0, wxALIGN_BOTTOM | wxALL, 0 );
158

159 160
    Button = new wxButton( this, wxID_OK, _( "OK" ) );
    ButtonBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
161

162 163
    Button = new wxButton( this, wxID_CANCEL, _( "Cancel" ) );
    ButtonBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
plyatov's avatar
plyatov committed
164

165 166
    if( GetSizer() )
    {
167
        GetSizer()->SetSizeHints( this );
168
    }
plyatov's avatar
plyatov committed
169 170 171
}


172
void WinEDA_SelLayerFrame::Sel_Layer( wxCommandEvent& event )
plyatov's avatar
plyatov committed
173
{
174 175 176
    int ii = m_LayerId[m_LayerList->GetSelection()];

    EndModal( ii );
plyatov's avatar
plyatov committed
177 178
}

179

180
void WinEDA_SelLayerFrame::OnCancelClick( wxCommandEvent& event )
plyatov's avatar
plyatov committed
181
{
182
    EndModal( -1 );
plyatov's avatar
plyatov committed
183 184 185
}


186 187 188
/*********************************************/
/* Dialog for the selecting pairs of layers. */
/*********************************************/
plyatov's avatar
plyatov committed
189

190
class WinEDA_SelLayerPairFrame : public wxDialog
plyatov's avatar
plyatov committed
191 192
{
private:
193 194 195 196
    WinEDA_BasePcbFrame* m_Parent;
    wxRadioBox*          m_LayerListTOP;
    wxRadioBox*          m_LayerListBOTTOM;
    int m_LayerId[NB_COPPER_LAYERS];
plyatov's avatar
plyatov committed
197

198
public: WinEDA_SelLayerPairFrame( WinEDA_BasePcbFrame* parent );
199
    ~WinEDA_SelLayerPairFrame() { };
plyatov's avatar
plyatov committed
200 201

private:
202 203
    void OnOkClick( wxCommandEvent& event );
    void OnCancelClick( wxCommandEvent& event );
plyatov's avatar
plyatov committed
204

205
    DECLARE_EVENT_TABLE()
plyatov's avatar
plyatov committed
206
};
207 208 209


BEGIN_EVENT_TABLE( WinEDA_SelLayerPairFrame, wxDialog )
dickelbeck's avatar
dickelbeck committed
210 211
    EVT_BUTTON( wxID_OK, WinEDA_SelLayerPairFrame::OnOkClick )
    EVT_BUTTON( wxID_CANCEL, WinEDA_SelLayerPairFrame::OnCancelClick )
plyatov's avatar
plyatov committed
212 213
END_EVENT_TABLE()

214

215 216
/* Display a list of two copper layers for selection of a pair of layers
 * for auto-routing, vias ...
217
 */
218
void WinEDA_BasePcbFrame::SelectLayerPair()
plyatov's avatar
plyatov committed
219
{
220 221 222
    // Check whether more than one copper layer has been enabled for the
    // current PCB file, as Layer Pairs can only meaningfully be defined
    // within PCB files which contain at least two copper layers.
223
    if( GetBoard()->m_BoardSettings->GetCopperLayerCount() < 2 )
224 225 226
    {
        wxString InfoMsg;
        InfoMsg = _( "Less than two copper layers are being used." );
227
        InfoMsg << wxT( "\n" ) << _( "Hence layer pairs cannot be specified." );
228
        DisplayInfoMessage( this, InfoMsg );
229 230 231
        return;
    }

232 233 234
    WinEDA_SelLayerPairFrame* frame =
        new WinEDA_SelLayerPairFrame( this );

235
    int result = frame->ShowModal();
236
    frame->Destroy();
237 238
    DrawPanel->MouseToCursorSchema();
    SetToolbars();
239

dickelbeck's avatar
dickelbeck committed
240 241
    // if user changed colors and we are in high contrast mode, then redraw
    // because the PAD_SMD pads may change color.
242 243
    if( result >= 0  &&  DisplayOpt.ContrastModeDisplay )
    {
244
        DrawPanel->Refresh();
245
    }
plyatov's avatar
plyatov committed
246 247 248
}


249
WinEDA_SelLayerPairFrame::WinEDA_SelLayerPairFrame( WinEDA_BasePcbFrame* parent ) :
250
    wxDialog( parent, -1, _( "Select Layer Pair:" ), wxPoint( -1, -1 ),
251
              wxSize( 470, 250 ), DIALOG_STYLE )
plyatov's avatar
plyatov committed
252
{
253
    BOARD*    board = parent->GetBoard();
254 255 256 257 258 259 260
    wxButton* Button;
    int       ii, LayerCount;
    wxString  LayerList[NB_COPPER_LAYERS];
    int       LayerTopSelect = 0, LayerBottomSelect = 0;

    m_Parent = parent;

261
    PCB_SCREEN* screen = (PCB_SCREEN*) m_Parent->GetScreen();
262 263
    int         Masque_Layer =
        g_TabAllCopperLayerMask[g_DesignSettings.GetCopperLayerCount() - 1];
264
    Masque_Layer += ALL_NO_CU_LAYERS;
265

266 267 268 269 270
    for( ii = 0, LayerCount = 0; ii < NB_COPPER_LAYERS; ii++ )
    {
        m_LayerId[ii] = 0;
        if( (g_TabOneLayerMask[ii] & Masque_Layer) )
        {
dickelbeck's avatar
dickelbeck committed
271
            LayerList[LayerCount] = board->GetLayerName( ii );
272 273 274 275 276 277 278 279 280
            if( ii == screen->m_Route_Layer_TOP )
                LayerTopSelect = LayerCount;
            if( ii == screen->m_Route_Layer_BOTTOM )
                LayerBottomSelect = LayerCount;
            m_LayerId[LayerCount] = ii;
            LayerCount++;
        }
    }

281 282 283 284 285 286
    m_LayerListTOP = new wxRadioBox( this, ID_LAYER_SELECT_TOP,
                                     _( "Top Layer" ),
                                     wxPoint( -1, -1 ), wxSize( -1, -1 ),
                                     LayerCount, LayerList,
                                     (LayerCount < 8) ? LayerCount : 8,
                                     wxRA_SPECIFY_ROWS );
287 288
    m_LayerListTOP->SetSelection( LayerTopSelect );

289 290 291 292 293 294
    m_LayerListBOTTOM = new wxRadioBox( this, ID_LAYER_SELECT_BOTTOM,
                                        _( "Bottom Layer" ),
                                        wxPoint( -1, -1 ), wxSize( -1, -1 ),
                                        LayerCount, LayerList,
                                        (LayerCount < 8) ? LayerCount : 8,
                                        wxRA_SPECIFY_ROWS );
295 296
    m_LayerListBOTTOM->SetSelection( LayerBottomSelect );

297 298
    wxBoxSizer* FrameBoxSizer = new wxBoxSizer( wxVERTICAL );
    SetSizer( FrameBoxSizer );
299

300 301
    wxBoxSizer* RadioBoxSizer = new wxBoxSizer( wxHORIZONTAL );
    FrameBoxSizer->Add( RadioBoxSizer, 0, wxALIGN_LEFT | wxALL, 0 );
302

303 304
    wxBoxSizer* ButtonBoxSizer = new wxBoxSizer( wxHORIZONTAL );
    FrameBoxSizer->Add( ButtonBoxSizer, 0, wxALIGN_RIGHT | wxALL, 0 );
305

306 307
    RadioBoxSizer->Add( m_LayerListTOP, 0, wxALIGN_TOP | wxALL, 5 );
    RadioBoxSizer->Add( m_LayerListBOTTOM, 0, wxALIGN_TOP | wxALL, 5 );
308

309 310
    Button = new wxButton( this, wxID_OK, _( "OK" ) );
    ButtonBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
plyatov's avatar
plyatov committed
311

312 313
    Button = new wxButton( this, wxID_CANCEL, _( "Cancel" ) );
    ButtonBoxSizer->Add( Button, 0, wxGROW | wxALL, 5 );
314 315 316

    if( GetSizer() )
    {
317
        GetSizer()->SetSizeHints( this );
318
    }
plyatov's avatar
plyatov committed
319 320 321
}


322
void WinEDA_SelLayerPairFrame::OnOkClick( wxCommandEvent& event )
plyatov's avatar
plyatov committed
323
{
324 325
    // select the same layer for top and bottom is allowed (normal in some
    // boards)
326
    // but could be a mistake. So display an info message
327
    if( m_LayerId[m_LayerListTOP->GetSelection()]
328 329 330
        == m_LayerId[m_LayerListBOTTOM->GetSelection()] )
        DisplayInfoMessage( this,
                            _( "Warning: The Top Layer and Bottom Layer are same." ) );
331

332
    PCB_SCREEN* screen = (PCB_SCREEN*) m_Parent->GetScreen();
plyatov's avatar
plyatov committed
333

334
    screen->m_Route_Layer_TOP    = m_LayerId[m_LayerListTOP->GetSelection()];
335 336
    screen->m_Route_Layer_BOTTOM =
        m_LayerId[m_LayerListBOTTOM->GetSelection()];
337

338
    EndModal( 0 );
plyatov's avatar
plyatov committed
339 340
}

341

342
void WinEDA_SelLayerPairFrame::OnCancelClick( wxCommandEvent& event )
plyatov's avatar
plyatov committed
343
{
344
    EndModal( -1 );
plyatov's avatar
plyatov committed
345
}