KiCad PCB EDA Suite
class_gerbview_layer_widget.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2004-2010 Jean-Pierre Charras, jp.charras at wanadoo.fr
5  * Copyright (C) 2010 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
6  * Copyright (C) 2016 KiCad Developers, see change_log.txt for contributors.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, you may find one here:
20  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21  * or you may search the http://www.gnu.org website for the version 2 license,
22  * or you may write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24  */
25 
26 
32 #include <fctsys.h>
33 #include <common.h>
34 #include <class_drawpanel.h>
35 #include <macros.h>
37 
38 #include <gerbview.h>
39 #include <gerbview_frame.h>
41 #include <layer_widget.h>
43 
44 
45 /*
46  * Class GERBER_LAYER_WIDGET
47  * is here to implement the abtract functions of LAYER_WIDGET so they
48  * may be tied into the GERBVIEW_FRAME's data and so we can add a popup
49  * menu which is specific to Pcbnew's needs.
50  */
51 
52 
54  int aPointSize ) :
55  LAYER_WIDGET( aParent, aFocusOwner, aPointSize ),
56  myframe( aParent )
57 {
59 
60  ReFillRender();
61 
62  // Update default tabs labels for GerbView
64 
65  //-----<Popup menu>-------------------------------------------------
66  // handle the popup menu over the layer window.
67  m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN,
68  wxMouseEventHandler( GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this );
69 
70  // since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
71  // and not m_LayerScrolledWindow->Connect()
73  wxEVT_COMMAND_MENU_SELECTED,
74  wxCommandEventHandler( GERBER_LAYER_WIDGET::onPopupSelection ), NULL, this );
75 
76  // install the right click handler into each control at end of ReFill()
77  // using installRightLayerClickHandler
78 }
79 
81 {
83 }
84 
85 
87 {
88  m_notebook->SetPageText(0, _("Layer") );
89  m_notebook->SetPageText(1, _("Render") );
90 }
91 
97 {
99 
100  // Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
101  // is changed before appending to the LAYER_WIDGET. This is an automatic variable
102  // not a static variable, change the color & state after copying from code to renderRows
103  // on the stack.
104  LAYER_WIDGET::ROW renderRows[3] = {
105 
106 #define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
107 
108  // text id color tooltip checked
109  RR( _( "Grid" ), LAYER_GERBVIEW_GRID, WHITE, _( "Show the (x,y) grid dots" ) ),
110  RR( _( "DCodes" ), LAYER_DCODES, WHITE, _( "Show DCodes identification" ) ),
111  RR( _( "Neg. Obj." ), LAYER_NEGATIVE_OBJECTS, DARKGRAY,
112  _( "Show negative objects in this color" ) ),
113  };
114 
115  for( unsigned row=0; row<DIM(renderRows); ++row )
116  {
117  if( renderRows[row].color != COLOR4D::UNSPECIFIED ) // does this row show a color?
118  {
119  renderRows[row].color = myframe->GetVisibleElementColor(
120  ( GERBVIEW_LAYER_ID )renderRows[row].id );
121  }
122  renderRows[row].state = myframe->IsElementVisible(
123  ( GERBVIEW_LAYER_ID )renderRows[row].id );
124  }
125 
126  AppendRenderRows( renderRows, DIM(renderRows) );
127 }
128 
130 {
131  int rowCount = GetLayerRowCount();
132 
133  for( int row=0; row<rowCount; ++row )
134  {
135  for( int col=0; col<LYR_COLUMN_COUNT; ++col )
136  {
137  wxWindow* w = getLayerComp( row, col );
138 
139  w->Connect( wxEVT_RIGHT_DOWN, wxMouseEventHandler(
141  }
142  }
143 }
144 
145 
146 void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
147 {
148  wxMenu menu;
149 
150  // Remember: menu text is capitalized (see our rules_for_capitalization_in_Kicad_UI.txt)
151  menu.Append( new wxMenuItem( &menu, ID_SHOW_ALL_LAYERS,
152  _("Show All Layers") ) );
153 
154  menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_LAYERS_BUT_ACTIVE,
155  _( "Hide All Layers But Active" ) ) );
156 
157  menu.Append( new wxMenuItem( &menu, ID_ALWAYS_SHOW_NO_LAYERS_BUT_ACTIVE,
158  _( "Always Hide All Layers But Active" ) ) );
159 
160  menu.Append( new wxMenuItem( &menu, ID_SHOW_NO_LAYERS,
161  _( "Hide All Layers" ) ) );
162 
163  menu.AppendSeparator();
164  menu.Append( new wxMenuItem( &menu, ID_SORT_GBR_LAYERS,
165  _( "Sort Layers if X2 Mode" ) ) );
166  PopupMenu( &menu );
167 
168  passOnFocus();
169 }
170 
171 void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
172 {
173  int rowCount;
174  int menuId = event.GetId();
175  bool visible = (menuId == ID_SHOW_ALL_LAYERS) ? true : false;
176  long visibleLayers = 0;
177  bool force_active_layer_visible;
178 
180  force_active_layer_visible = ( menuId == ID_SHOW_NO_LAYERS_BUT_ACTIVE ||
182 
183  switch( menuId )
184  {
185  case ID_SHOW_ALL_LAYERS:
186  case ID_SHOW_NO_LAYERS:
189  rowCount = GetLayerRowCount();
190  for( int row=0; row < rowCount; ++row )
191  {
192  wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
193  int layer = getDecodedId( cb->GetId() );
194  bool loc_visible = visible;
195 
196  if( force_active_layer_visible && (layer == myframe->getActiveLayer() ) )
197  loc_visible = true;
198 
199  cb->SetValue( loc_visible );
200 
201  if( loc_visible )
202  visibleLayers |= 1 << row;
203  else
204  visibleLayers &= ~( 1 << row );
205  }
206 
207  myframe->SetVisibleLayers( visibleLayers );
208  myframe->GetCanvas()->Refresh();
209  break;
210 
211  case ID_SORT_GBR_LAYERS:
214  myframe->syncLayerBox( true );
215  myframe->GetCanvas()->Refresh();
216  break;
217  }
218 }
219 
221 {
223  return false;
224 
225  // postprocess after active layer selection
226  // ensure active layer visible
227  wxCommandEvent event;
229  onPopupSelection( event );
230  return true;
231 }
232 
233 
235 {
236  Freeze();
237 
238  ClearLayerRows();
239 
240  for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
241  {
242  wxString msg = GetImagesList()->GetDisplayName( layer );
243 
244  AppendLayerRow( LAYER_WIDGET::ROW( msg, layer,
245  myframe->GetLayerColor( layer ), wxEmptyString, true ) );
246  }
247 
248  Thaw();
249 
251 }
252 
253 //-----<LAYER_WIDGET callbacks>-------------------------------------------
254 
256 {
257  myframe->SetLayerColor( aLayer, aColor );
259  myframe->GetCanvas()->Refresh();
260 }
261 
263 {
264  // the layer change from the GERBER_LAYER_WIDGET can be denied by returning
265  // false from this function.
266  int layer = myframe->getActiveLayer( );
267  myframe->setActiveLayer( aLayer, false );
269 
270  if( layer != myframe->getActiveLayer( ) )
271  {
272  if( ! OnLayerSelected() )
273  myframe->GetCanvas()->Refresh();
274  }
275 
276  return true;
277 }
278 
279 void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal )
280 {
281  long visibleLayers = myframe->GetVisibleLayers();
282 
283  if( isVisible )
284  visibleLayers |= 1 << aLayer;
285  else
286  visibleLayers &= ~( 1 << aLayer );
287 
288  myframe->SetVisibleLayers( visibleLayers );
289 
290  if( isFinal )
291  myframe->GetCanvas()->Refresh();
292 }
293 
295 {
297  myframe->GetCanvas()->Refresh();
298 }
299 
300 void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
301 {
302  myframe->SetElementVisibility( (GERBVIEW_LAYER_ID) aId, isEnabled );
303  myframe->GetCanvas()->Refresh();
304 }
305 
306 //-----</LAYER_WIDGET callbacks>------------------------------------------
307 
308 /*
309  * Virtual Function useAlternateBitmap
310  * return true if bitmaps shown in Render layer list
311  * must be alternate bitmap (when a gerber i¨mage is loaded), or false to use "normal" bitmap
312  */
314 {
315  return GetImagesList()->GetGbrImage( aRow ) != NULL;
316 }
void installRightLayerClickHandler()
this is for the popup menu, the right click handler has to be installed on every child control within...
#define DIM(x)
of elements in an array
Definition: macros.h:98
wxAuiNotebook * m_notebook
Definition: layer_widget.h:109
#define LYR_COLUMN_COUNT
Layer tab column count.
Definition: layer_widget.h:47
void OnLayerColorChange(int aLayer, COLOR4D aColor) override
Function OnLayerColorChange is called to notify client code about a layer color change.
Struct ROW provides all the data needed to add a row to a LAYER_WIDGET.
Definition: layer_widget.h:84
void onRightDownLayers(wxMouseEvent &event)
Function OnRightDownLayers puts up a popup menu for the layer panel.
virtual void Refresh(bool eraseBackground=true, const wxRect *rect=NULL) override
Definition: draw_panel.cpp:326
EDA_DRAW_PANEL * GetCanvas()
Definition: draw_frame.h:299
const wxString GetDisplayName(int aIdx, bool aNameOnly=false)
void SetVisibleElementColor(GERBVIEW_LAYER_ID aItemIdVisible, COLOR4D aColor)
void syncLayerBox(bool aRebuildLayerBox=false)
Function syncLayerBox updates the currently "selected" layer within m_SelLayerBox The currently activ...
void SortImagesByZOrder()
Sort loaded images by Z order priority, if they have the X2 FileFormat info (SortImagesByZOrder updat...
void OnLayerVisible(int aLayer, bool isVisible, bool isFinal) override
Function OnLayerVisible is called to notify client code about a layer visibility change.
GBR_LAYER_BOX_SELECTOR * m_SelLayerBox
GERBER_FILE_IMAGE_LIST * GetImagesList()
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
void SetVisibleLayers(long aLayerMask)
Function SetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
void ClearRenderRows()
Function ClearRenderRows empties out the render rows.
GERBVIEW_LAYER_ID
GerbView draw layers.
bool state
initial wxCheckBox state
Definition: layer_widget.h:89
GERBER_LAYER_WIDGET(GERBVIEW_FRAME *aParent, wxWindow *aFocusOwner, int aPointSize=10)
Constructor.
void ClearLayerRows()
Function ClearLayerRows empties out the layer rows.
long GetVisibleLayers() const
Function GetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
This file contains miscellaneous commonly used macros and functions.
void SetLayersManagerTabsText()
Function SetLayersManagerTabsText Update the layer manager tabs labels Useful when changing Language ...
COLOR4D color
COLOR4D::UNSPECIFIED if none.
Definition: layer_widget.h:88
bool OnLayerSelect(int aLayer) override
Function OnLayerSelect is called to notify client code whenever the user selects a different layer...
COLOR4D GetVisibleElementColor(GERBVIEW_LAYER_ID aItemIdVisible)
Function GetVisibleElementColor returns the color of a gerber visible element.
#define GERBER_DRAWLAYERS_COUNT
GERBER_FILE_IMAGE * GetGbrImage(int aIdx)
void AppendLayerRow(const ROW &aRow)
Function AppendLayerRow appends a new row in the layer portion of the widget.
static GERBER_FILE_IMAGE_LIST & GetImagesList()
void OnRenderColorChange(int aId, COLOR4D aColor) override
Function OnRenderColorChange is called to notify client code whenever the user changes a rendering co...
wxScrolledWindow * m_LayerScrolledWindow
Definition: layer_widget.h:111
wxWindow * getLayerComp(int aRow, int aColumn) const
Function getLayerComp returns the component within the m_LayersFlexGridSizer at aRow and aCol or NULL...
#define RR
int GetLayerRowCount() const
Function GetLayerRowCount returns the number of rows in the layer tab.
void onPopupSelection(wxCommandEvent &event)
void AppendRenderRows(const ROW *aRowsArray, int aRowCount)
Function AppendRenderRows appends new rows in the render portion of the widget.
Definition: layer_widget.h:289
static LAYER_NUM getDecodedId(int aControlId)
Function getDecodedId decodes aControlId to original un-encoded value.
void setActiveLayer(int aLayer, bool doLayerWidgetUpdate=true)
Function setActiveLayer will change the currently active layer to aLayer and also update the GERBER_L...
void passOnFocus()
Function passOnFocus gives away the keyboard focus up to the main parent window.
virtual bool useAlternateBitmap(int aRow) override
Virtual Function useAlternateBitmap.
COLOR4D GetLayerColor(int aLayer) const
Function GetLayerColor gets a layer color for any valid layer.
Class LAYER_WIDGET is abstract and is used to manage a list of layers, with the notion of a "current"...
Definition: layer_widget.h:76
void OnRenderEnable(int aId, bool isEnabled) override
Function OnRenderEnable is called to notify client code whenever the user changes an rendering enable...
#define COLUMN_COLOR_LYR_CB
Definition: layer_widget.h:52
void SetElementVisibility(GERBVIEW_LAYER_ID aItemIdVisible, bool aNewState)
Function SetElementVisibility changes the visibility of an element category.
bool IsElementVisible(GERBVIEW_LAYER_ID aItemIdVisible) const
Function IsElementVisible tests whether a given element category is visible.
int getActiveLayer()
Function getActiveLayer returns the active layer.
void SetLayerColor(int aLayer, COLOR4D aColor)
Function SetLayerColor changes a layer color for any valid layer.
The common library.
Definition: colors.h:49
void ReFillRender()
Function ReFillRender Rebuild Render for instance after the config is read.
bool OnLayerSelected()
Function OnLayerSelected ensure the active layer is visible, and other layers not visible when m_alwa...
void ReFillLayerWidget()
Function ReFillLayerWidget changes out all the layers in m_Layers and may be called upon loading new ...
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39