summaryrefslogtreecommitdiff
path: root/gerbview/class_gerbview_layer_widget.cpp
blob: f2108ac58a73a95f18003ede052fbbc2c58aeda6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
/*
 * This program source code file is part of KiCad, a free EDA CAD application.
 *
 * Copyright (C) 2004-2010 Jean-Pierre Charras, jp.charras at wanadoo.fr
 * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
 * Copyright (C) 2010 KiCad Developers, see change_log.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
 */


/**
 * @file class_gerbview_layer_widget.cpp
 * @brief  GerbView layers manager.
 */

#include <fctsys.h>
#include <common.h>
#include <class_drawpanel.h>
#include <pcbstruct.h>
#include <macros.h>
#include <class_gbr_layer_box_selector.h>

#include <gerbview.h>
#include <gerbview_frame.h>
#include <class_GERBER.h>
#include <layer_widget.h>
#include <class_gerbview_layer_widget.h>
#include <class_X2_gerber_attributes.h>


/*
 * Class GERBER_LAYER_WIDGET
 * is here to implement the abtract functions of LAYER_WIDGET so they
 * may be tied into the GERBVIEW_FRAME's data and so we can add a popup
 * menu which is specific to Pcbnew's needs.
 */


GERBER_LAYER_WIDGET::GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFocusOwner,
                                          int aPointSize ) :
    LAYER_WIDGET( aParent, aFocusOwner, aPointSize ),
    myframe( aParent )
{
    m_alwaysShowActiveLayer = false;

    ReFillRender();

    // Update default tabs labels for GerbView
    SetLayersManagerTabsText( );

    //-----<Popup menu>-------------------------------------------------
    // handle the popup menu over the layer window.
    m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN,
        wxMouseEventHandler( GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this );

    // since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
    // and not m_LayerScrolledWindow->Connect()
    Connect( ID_LAYER_MANAGER_START, ID_LAYER_MANAGER_END,
        wxEVT_COMMAND_MENU_SELECTED,
        wxCommandEventHandler( GERBER_LAYER_WIDGET::onPopupSelection ), NULL, this );

    // install the right click handler into each control at end of ReFill()
    // using installRightLayerClickHandler
}

/**
 * Function SetLayersManagerTabsText
 * Update the layer manager tabs labels
 * Useful when changing Language or to set labels to a non default value
 */
void GERBER_LAYER_WIDGET::SetLayersManagerTabsText( )
{
    m_notebook->SetPageText(0, _("Layer") );
    m_notebook->SetPageText(1, _("Render") );
}

/**
 * Function ReFillRender
 * Rebuild Render for instance after the config is read
 */
void GERBER_LAYER_WIDGET::ReFillRender()
{
    ClearRenderRows();

    // Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
    // is changed before appending to the LAYER_WIDGET.  This is an automatic variable
    // not a static variable, change the color & state after copying from code to renderRows
    // on the stack.
    LAYER_WIDGET::ROW renderRows[3] = {

#define RR  LAYER_WIDGET::ROW   // Render Row abreviation to reduce source width

             // text                id                      color       tooltip                 checked
        RR( _( "Grid" ),            GERBER_GRID_VISIBLE,    WHITE,      _( "Show the (x,y) grid dots" ) ),
        RR( _( "DCodes" ),          DCODES_VISIBLE,         WHITE,      _( "Show DCodes identification" ) ),
        RR( _( "Neg. Obj." ),       NEGATIVE_OBJECTS_VISIBLE,  DARKGRAY,
                                    _( "Show negative objects in this color" ) ),
    };

    for( unsigned row=0;  row<DIM(renderRows);  ++row )
    {
        if( renderRows[row].color != -1 )       // does this row show a color?
        {
            renderRows[row].color = myframe->GetVisibleElementColor(
                                    (GERBER_VISIBLE_ID)renderRows[row].id );
        }
        renderRows[row].state = myframe->IsElementVisible(
                                (GERBER_VISIBLE_ID)renderRows[row].id );
    }

    AppendRenderRows( renderRows, DIM(renderRows) );
}

void GERBER_LAYER_WIDGET::installRightLayerClickHandler()
{
    int rowCount = GetLayerRowCount();

    for( int row=0;  row<rowCount;  ++row )
    {
        for( int col=0; col<LYR_COLUMN_COUNT;  ++col )
        {
            wxWindow* w = getLayerComp( row, col );

            w->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(
                GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this );
        }
    }
}


void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
{
    wxMenu          menu;

    // Remember: menu text is capitalized (see our rules_for_capitalization_in_Kicad_UI.txt)
    menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_LAYERS,
                                 _("Show All Layers") ) );

    menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_LAYERS_BUT_ACTIVE,
                                 _( "Hide All Layers But Active" ) ) );

    menu.Append( new wxMenuItem( &menu, ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE,
                                 _( "Always Hide All Layers But Active" ) ) );

    menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_LAYERS,
                                 _( "Hide All Layers" ) ) );

    menu.AppendSeparator();
    menu.Append( new wxMenuItem( &menu, ID_SORT_GBR_LAYERS,
                                 _( "Sort Layers if X2 Mode" ) ) );
    PopupMenu( &menu );

    passOnFocus();
}

void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
{
    int  rowCount;
    int  menuId = event.GetId();
    bool visible = (menuId == ID_SHOW_ALL_LAYERS) ? true : false;
    long visibleLayers = 0;
    bool force_active_layer_visible;

    m_alwaysShowActiveLayer = ( menuId == ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE );
    force_active_layer_visible = ( menuId == ID_SHOW_NO_LAYERS_BUT_ACTIVE ||
                                   menuId == ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE );

    switch( menuId )
    {
    case ID_SHOW_ALL_LAYERS:
    case ID_SHOW_NO_LAYERS:
    case ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE:
    case ID_SHOW_NO_LAYERS_BUT_ACTIVE:
        rowCount = GetLayerRowCount();
        for( int row=0; row < rowCount; ++row )
        {
            wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
            int layer = getDecodedId( cb->GetId() );
            bool loc_visible = visible;

            if( force_active_layer_visible && (layer == myframe->getActiveLayer() ) )
                loc_visible = true;

            cb->SetValue( loc_visible );

            if( loc_visible )
                visibleLayers |= 1 << row;
            else
                visibleLayers &= ~( 1 << row );
        }

        myframe->SetVisibleLayers( visibleLayers );
        myframe->GetCanvas()->Refresh();
        break;

    case ID_SORT_GBR_LAYERS:
        g_GERBER_List.SortImagesByZOrder( myframe->GetItemsList() );
        myframe->ReFillLayerWidget();
        myframe->syncLayerBox();
        myframe->GetCanvas()->Refresh();
        break;
    }
}

bool  GERBER_LAYER_WIDGET::OnLayerSelected()
{
    if( !m_alwaysShowActiveLayer )
        return false;

    // postprocess after active layer selection
    // ensure active layer visible
    wxCommandEvent event;
    event.SetId( ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE );
    onPopupSelection( event );
    return true;
}


void GERBER_LAYER_WIDGET::ReFill()
{
    Freeze();

    ClearLayerRows();

    for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
    {
        wxString msg = g_GERBER_List.GetDisplayName( layer );

        AppendLayerRow( LAYER_WIDGET::ROW( msg, layer,
                        myframe->GetLayerColor( layer ), wxEmptyString, true ) );
    }

    Thaw();

    installRightLayerClickHandler();
}

//-----<LAYER_WIDGET callbacks>-------------------------------------------

void GERBER_LAYER_WIDGET::OnLayerColorChange( int aLayer, EDA_COLOR_T aColor )
{
    myframe->SetLayerColor( aLayer, aColor );
    myframe->m_SelLayerBox->ResyncBitmapOnly();
    myframe->GetCanvas()->Refresh();
}

bool GERBER_LAYER_WIDGET::OnLayerSelect( int aLayer )
{
    // the layer change from the GERBER_LAYER_WIDGET can be denied by returning
    // false from this function.
    int layer = myframe->getActiveLayer( );
    myframe->setActiveLayer( aLayer, false );
    myframe->syncLayerBox();

    if( layer != myframe->getActiveLayer( ) )
    {
        if( ! OnLayerSelected() )
            myframe->GetCanvas()->Refresh();
    }

    return true;
}

void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal )
{
    long visibleLayers = myframe->GetVisibleLayers();

    if( isVisible )
        visibleLayers |= 1 << aLayer;
    else
        visibleLayers &= ~( 1 << aLayer );

    myframe->SetVisibleLayers( visibleLayers );

    if( isFinal )
        myframe->GetCanvas()->Refresh();
}

void GERBER_LAYER_WIDGET::OnRenderColorChange( int aId, EDA_COLOR_T aColor )
{
    myframe->SetVisibleElementColor( (GERBER_VISIBLE_ID)aId, aColor );
    myframe->GetCanvas()->Refresh();
}

void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
{
    myframe->SetElementVisibility( (GERBER_VISIBLE_ID)aId, isEnabled );
    myframe->GetCanvas()->Refresh();
}

//-----</LAYER_WIDGET callbacks>------------------------------------------

/*
 * Virtual Function useAlternateBitmap
 * return true if bitmaps shown in Render layer list
 * must be alternate bitmaps, or false to use "normal" bitmaps
 */
bool GERBER_LAYER_WIDGET::useAlternateBitmap(int aRow)
{
    return g_GERBER_List.IsUsed( aRow );
}

/*
 * Update the layer manager icons (layers only)
 * Useful when loading a file or clearing a layer because they change
 */
void GERBER_LAYER_WIDGET::UpdateLayerIcons()
{
    int row_count = GetLayerRowCount();
    for( int row = 0; row < row_count ; row++ )
    {
        wxStaticBitmap* bm = (wxStaticBitmap*) getLayerComp( row, COLUMN_ICON_ACTIVE );
        if( bm == NULL)
            continue;

        if( row == m_CurrentRow )
            bm->SetBitmap( useAlternateBitmap(row) ? *m_RightArrowAlternateBitmap :
                           *m_RightArrowBitmap );
        else
            bm->SetBitmap( useAlternateBitmap(row) ? *m_BlankAlternateBitmap : *m_BlankBitmap );
    }
}