KiCad PCB EDA Suite
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) 2018-2019 KiCad Developers, see AUTHORS.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 #include <fctsys.h>
27 #include <common.h>
28 #include <macros.h>
29 #include <gbr_layer_box_selector.h>
30 #include <menus_helpers.h>
31 #include <gerbview.h>
32 #include <gerbview_frame.h>
33 #include <gerber_file_image_list.h>
34 #include <layer_widget.h>
35 #include <gerbview_layer_widget.h>
36 #include <view/view.h>
37 #include <gerbview_painter.h>
40 
41 
42 /*
43  * GERBER_LAYER_WIDGET
44  * is here to implement the abtract functions of LAYER_WIDGET so they
45  * may be tied into the GERBVIEW_FRAME's data and so we can add a popup
46  * menu which is specific to Pcbnew's needs.
47  */
48 
49 
50 GERBER_LAYER_WIDGET::GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFocusOwner ) :
51  LAYER_WIDGET( aParent, aFocusOwner ),
52  myframe( aParent )
53 {
55 
56  ReFillRender();
57 
58  // Update default tabs labels for GerbView
60 
61  //-----<Popup menu>-------------------------------------------------
62  // handle the popup menu over the layer window.
63  m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN,
64  wxMouseEventHandler( GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this );
65 
66  // since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
67  // and not m_LayerScrolledWindow->Connect()
69  wxEVT_COMMAND_MENU_SELECTED,
70  wxCommandEventHandler( GERBER_LAYER_WIDGET::onPopupSelection ), NULL, this );
71 }
72 
74 {
76 }
77 
78 
80 {
81  m_notebook->SetPageText(0, _("Layers") );
82  m_notebook->SetPageText(1, _("Items") );
83 }
84 
90 {
92 
93  // Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
94  // is changed before appending to the LAYER_WIDGET. This is an automatic variable
95  // not a static variable, change the color & state after copying from code to renderRows
96  // on the stack.
97  LAYER_WIDGET::ROW renderRows[6] = {
98 
99 #define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
100 
101  // text id color tooltip checked
102  RR( _( "DCodes" ), LAYER_DCODES, WHITE, _( "Show DCodes identification" ) ),
103  RR( _( "Negative Objects" ), LAYER_NEGATIVE_OBJECTS, DARKGRAY, _( "Show negative objects in this color" ) ),
104  RR(),
105  RR( _( "Grid" ), LAYER_GERBVIEW_GRID, WHITE, _( "Show the (x,y) grid dots" ) ),
106  RR( _( "Worksheet" ), LAYER_GERBVIEW_WORKSHEET, DARKRED, _( "Show worksheet") ),
107  RR( _( "Background" ), LAYER_GERBVIEW_BACKGROUND, BLACK, _( "PCB Background" ), true, false )
108  };
109 
110  for( unsigned row=0; row<arrayDim(renderRows); ++row )
111  {
112  if( renderRows[row].color != COLOR4D::UNSPECIFIED ) // does this row show a color?
113  renderRows[row].color = myframe->GetVisibleElementColor( renderRows[row].id );
114 
115  if( renderRows[row].id ) // if not the separator
116  renderRows[row].state = myframe->IsElementVisible( renderRows[row].id );
117  }
118 
119  AppendRenderRows( renderRows, arrayDim(renderRows) );
120 }
121 
122 
124 {
125  // Remember: menu text is capitalized (see our rules_for_capitalization_in_Kicad_UI.txt)
126  AddMenuItem( aMenu, ID_SHOW_ALL_LAYERS, _( "Show All Layers" ),
128 
130  _( "Hide All Layers But Active" ),
132 
134  _( "Always Hide All Layers But Active" ),
136 
137  AddMenuItem( aMenu, ID_SHOW_NO_LAYERS, _( "Hide All Layers" ),
139 
140  aMenu->AppendSeparator();
141  AddMenuItem( aMenu, ID_SORT_GBR_LAYERS, _( "Sort Layers if X2 Mode" ),
142  KiBitmap( reload_xpm ) );
143 }
144 
145 
146 void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
147 {
148  wxMenu menu;
149 
150  AddRightClickMenuItems( &menu );
151  PopupMenu( &menu );
152 
153  passOnFocus();
154 }
155 
156 void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
157 {
158  int rowCount;
159  int menuId = event.GetId();
160  bool visible = (menuId == ID_SHOW_ALL_LAYERS) ? true : false;
161  LSET visibleLayers;
162  bool force_active_layer_visible;
163 
164  switch( menuId )
165  {
166  case ID_SHOW_ALL_LAYERS:
167  case ID_SHOW_NO_LAYERS:
170  // Set the display layers options. Sorting layers has no effect to these options
172  force_active_layer_visible = ( menuId == ID_SHOW_NO_LAYERS_BUT_ACTIVE ||
174 
175  // Update icons and check boxes
176  rowCount = GetLayerRowCount();
177 
178  for( int row = 0; row < rowCount; ++row )
179  {
180  wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
181  int layer = getDecodedId( cb->GetId() );
182  bool loc_visible = visible;
183 
184  if( force_active_layer_visible && (layer == myframe->GetActiveLayer() ) )
185  loc_visible = true;
186 
187  cb->SetValue( loc_visible );
188  visibleLayers[ row ] = loc_visible;
189  }
190 
191  myframe->SetVisibleLayers( visibleLayers );
192  myframe->GetCanvas()->Refresh();
193  break;
194 
195  case ID_SORT_GBR_LAYERS:
197  break;
198  }
199 }
200 
202 {
204  return false;
205 
206  // postprocess after active layer selection
207  // ensure active layer visible
208  wxCommandEvent event;
210  onPopupSelection( event );
211  return true;
212 }
213 
214 
216 {
217  Freeze();
218 
219  ClearLayerRows();
220 
221  for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
222  {
223  wxString msg = GetImagesList()->GetDisplayName( layer );
224 
225  bool visible = true;
226 
227  if( myframe->GetCanvas() )
228  visible = myframe->GetCanvas()->GetView()->IsLayerVisible( GERBER_DRAW_LAYER( layer ) );
229  else
230  visible = myframe->IsLayerVisible( layer );
231 
232  AppendLayerRow( LAYER_WIDGET::ROW( msg, layer,
234  wxEmptyString, visible, true ) );
235  }
236 
237  UpdateLayouts();
238  Thaw();
239 }
240 
241 //-----<LAYER_WIDGET callbacks>-------------------------------------------
242 
244 {
245  AddRightClickMenuItems( &aMenu );
246 }
247 
248 
250 {
251  // NOTE: Active layer in GerbView is stored as 0-indexed, but layer color is
252  // stored according to the GERBER_DRAW_LAYER() offset.
253 
254  myframe->SetLayerColor( GERBER_DRAW_LAYER( aLayer ), aColor );
256 
257  KIGFX::VIEW* view = myframe->GetCanvas()->GetView();
258  auto settings = Pgm().GetSettingsManager().GetColorSettings();
259  view->GetPainter()->GetSettings()->LoadColors( settings );
260  view->UpdateLayerColor( GERBER_DRAW_LAYER( aLayer ) );
261 
262  myframe->GetCanvas()->Refresh();
263 }
264 
265 
267 {
268  // the layer change from the GERBER_LAYER_WIDGET can be denied by returning
269  // false from this function.
270  int layer = myframe->GetActiveLayer();
271 
272  myframe->SetActiveLayer( aLayer, false );
274 
275  if( layer != myframe->GetActiveLayer() )
276  {
277  if( ! OnLayerSelected() )
278  myframe->GetCanvas()->Refresh();
279  }
280 
281  return true;
282 }
283 
284 
285 void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal )
286 {
287  LSET visibleLayers = myframe->GetVisibleLayers();
288 
289  visibleLayers[ aLayer ] = isVisible;
290 
291  myframe->SetVisibleLayers( visibleLayers );
292 
293  if( isFinal )
294  myframe->GetCanvas()->Refresh();
295 }
296 
297 
299 {
300  myframe->SetVisibleElementColor( aId, aColor );
301 
302  auto view = myframe->GetCanvas()->GetView();
303  auto settings = Pgm().GetSettingsManager().GetColorSettings();
304 
305  view->GetPainter()->GetSettings()->LoadColors( settings );
306  view->UpdateLayerColor( aId );
307 
308  view->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
309  view->UpdateAllItems( KIGFX::COLOR );
310  myframe->GetCanvas()->Refresh();
311 }
312 
313 
314 void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
315 {
316  myframe->SetElementVisibility( aId, isEnabled );
317 
318  if( myframe->GetCanvas() )
319  {
320  if( aId == LAYER_GERBVIEW_GRID )
321  {
324  }
325  else
326  myframe->GetCanvas()->GetView()->SetLayerVisible( aId, isEnabled );
327  }
328 
329  myframe->GetCanvas()->Refresh();
330 }
331 
332 //-----</LAYER_WIDGET callbacks>------------------------------------------
333 
334 /*
335  * Virtual Function useAlternateBitmap
336  * return true if bitmaps shown in Render layer list
337  * must be alternate bitmap (when a gerber image is loaded), or false to use "normal" bitmap
338  */
340 {
341  return GetImagesList()->GetGbrImage( aRow ) != NULL;
342 }
wxAuiNotebook * m_notebook
Definition: layer_widget.h:127
void SetVisibleElementColor(int aLayerID, COLOR4D aColor)
void SortLayersByX2Attributes()
void OnLayerColorChange(int aLayer, COLOR4D aColor) override
Function OnLayerColorChange is called to notify client code about a layer color change.
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:103
Struct ROW provides all the data needed to add a row to a LAYER_WIDGET.
Definition: layer_widget.h:87
void onRightDownLayers(wxMouseEvent &event)
Function OnRightDownLayers puts up a popup menu for the layer panel.
void AddRightClickMenuItems(wxMenu *aMenu)
Function addRightClickMenuItems add menu items to a menu that should be shown when right-clicking the...
const wxString GetDisplayName(int aIdx, bool aNameOnly=false)
void syncLayerBox(bool aRebuildLayerBox=false)
Function syncLayerBox updates the currently "selected" layer within m_SelLayerBox The currently activ...
COLOR4D GetVisibleElementColor(int aLayerID)
Function GetVisibleElementColor returns the color of a gerber visible element.
LSET GetVisibleLayers() const
Function GetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmap &aImage, wxItemKind aType=wxITEM_NORMAL)
Function AddMenuItem is an inline helper function to create and insert a menu item with an icon into ...
Definition: bitmap.cpp:250
GERBER_LAYER_WIDGET(GERBVIEW_FRAME *aParent, wxWindow *aFocusOwner)
Constructor.
virtual bool IsGridVisible() const
void UpdateLayouts()
GERBVIEW_FRAME * myframe
int color
Definition: DXF_plotter.cpp:61
virtual EDA_DRAW_PANEL_GAL * GetCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
void OnLayerVisible(int aLayer, bool isVisible, bool isFinal) override
Function OnLayerVisible is called to notify client code about a layer visibility change.
void SetActiveLayer(int aLayer, bool doLayerWidgetUpdate=true)
Function SetActiveLayer will change the currently active layer to aLayer and also update the GERBER_L...
GBR_LAYER_BOX_SELECTOR * m_SelLayerBox
#define RR
GERBER_FILE_IMAGE_LIST * GetImagesList()
wxWindow * getLayerComp(int aRow, int aColumn) const
Function getLayerComp returns the component within the m_LayersFlexGridSizer at aRow and aCol or NULL...
Visibility flag has changed.
Definition: view_item.h:56
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
int GetActiveLayer()
Function SetActiveLayer returns the active layer.
void ClearRenderRows()
Function ClearRenderRows empties out the render rows.
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
Definition: colors.h:54
bool state
initial wxCheckBox state
Definition: layer_widget.h:92
void ClearLayerRows()
Function ClearLayerRows empties out the layer rows.
Auxiliary rendering target (noncached)
Definition: definitions.h:49
This file contains miscellaneous commonly used macros and functions.
const BITMAP_OPAQUE reload_xpm[1]
Definition: reload.cpp:71
void SetLayersManagerTabsText()
Function SetLayersManagerTabsText Update the layer manager tabs labels Useful when changing Language ...
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:80
COLOR4D color
COLOR4D::UNSPECIFIED if none.
Definition: layer_widget.h:91
bool OnLayerSelect(int aLayer) override
Function OnLayerSelect is called to notify client code whenever the user selects a different layer.
LSET is a set of PCB_LAYER_IDs.
#define NULL
#define GERBER_DRAWLAYERS_COUNT
const BITMAP_OPAQUE select_w_layer_xpm[1]
GERBER_FILE_IMAGE * GetGbrImage(int aIdx)
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:585
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...
const BITMAP_OPAQUE show_all_layers_xpm[1]
void OnLayerRightClick(wxMenu &aMenu) override
Function OnLayerRightClick is called to notify client code about a layer being right-clicked.
bool IsElementVisible(int aLayerID) const
Function IsElementVisible tests whether a given element category is visible.
wxScrolledWindow * m_LayerScrolledWindow
Definition: layer_widget.h:129
KIGFX::GAL * GetGAL() const
Function GetGAL() Returns a pointer to the GAL instance used in the panel.
virtual KIGFX::VIEW * GetView() const
Function GetView() Returns a pointer to the VIEW instance used in the panel.
void SetLayerVisible(int aLayer, bool aVisible=true)
Function SetLayerVisible() Controls the visibility of a particular layer.
Definition: view.h:399
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:330
static LAYER_NUM getDecodedId(int aControlId)
Function getDecodedId decodes aControlId to original un-encoded value.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=NULL) override
Update the board display after modifying it by a python script (note: it is automatically called by a...
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Definition: macros.h:108
int GetLayerRowCount() const
Function GetLayerRowCount returns the number of rows in the layer tab.
void passOnFocus()
Function passOnFocus gives away the keyboard focus up to the main parent window.
void UpdateLayerColor(int aLayer)
Function UpdateLayerColor() Applies the new coloring scheme held by RENDER_SETTINGS in case that it h...
Definition: view.cpp:777
virtual bool useAlternateBitmap(int aRow) override
Virtual Function useAlternateBitmap.
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
LAYER_WIDGET is abstract and is used to manage a list of layers, with the notion of a "current" layer...
Definition: layer_widget.h:79
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:54
#define _(s)
Definition: 3d_actions.cpp:33
COLOR4D GetLayerColor(int aLayer) const
Function GetLayerColor gets a layer color for any valid layer.
void SetLayerColor(int aLayer, COLOR4D aColor)
Function SetLayerColor changes a layer color for any valid layer.
The common library.
void SetGridVisibility(bool aVisibility)
Sets the visibility setting of the grid.
Definition: colors.h:49
void SetVisibleLayers(LSET aLayerMask)
Function SetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
#define GERBER_DRAW_LAYER(x)
Definition: colors.h:45
void ReFillRender()
Function ReFillRender Rebuild Render for instance after the config is read.
VIEW.
Definition: view.h:61
virtual void LoadColors(const COLOR_SETTINGS *aSettings)
Definition: painter.h:62
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible tests whether a given layer is visible.
bool OnLayerSelected()
Function OnLayerSelected ensure the active layer is visible, and other layers not visible when m_alwa...
void SetElementVisibility(int aLayerID, bool aNewState)
Function SetElementVisibility changes the visibility of an element category.
const BITMAP_OPAQUE show_no_layers_xpm[1]
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:416
COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:40