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  for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
220  {
221  int aRow = findLayerRow( layer );
222  bool visible = true;
224  wxString msg = GetImagesList()->GetDisplayName( layer );
225 
226  if( myframe->GetCanvas() )
227  visible = myframe->GetCanvas()->GetView()->IsLayerVisible( GERBER_DRAW_LAYER( layer ) );
228  else
229  visible = myframe->IsLayerVisible( layer );
230 
231  if( aRow >= 0 )
232  updateLayerRow( findLayerRow( layer ), msg );
233  else
234  AppendLayerRow( LAYER_WIDGET::ROW( msg, layer, color, 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  myframe->SetLayerColor( GERBER_DRAW_LAYER( aLayer ), aColor );
255 
256  KIGFX::VIEW* view = myframe->GetCanvas()->GetView();
257  auto settings = Pgm().GetSettingsManager().GetColorSettings();
258  view->GetPainter()->GetSettings()->LoadColors( settings );
259  view->UpdateLayerColor( GERBER_DRAW_LAYER( aLayer ) );
260 
261  myframe->GetCanvas()->Refresh();
262 }
263 
264 
266 {
267  // the layer change from the GERBER_LAYER_WIDGET can be denied by returning
268  // false from this function.
269  int layer = myframe->GetActiveLayer();
270 
271  myframe->SetActiveLayer( aLayer, false );
273 
274  if( layer != myframe->GetActiveLayer() )
275  {
276  if( ! OnLayerSelected() )
277  myframe->GetCanvas()->Refresh();
278  }
279 
280  return true;
281 }
282 
283 
284 void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal )
285 {
286  LSET visibleLayers = myframe->GetVisibleLayers();
287 
288  visibleLayers[ aLayer ] = isVisible;
289 
290  myframe->SetVisibleLayers( visibleLayers );
291 
292  if( isFinal )
293  myframe->GetCanvas()->Refresh();
294 }
295 
296 #include "gerbview_draw_panel_gal.h"
298 {
299  myframe->SetVisibleElementColor( aId, aColor );
300 
301  auto view = myframe->GetCanvas()->GetView();
302  COLOR_SETTINGS* settings = Pgm().GetSettingsManager().GetColorSettings();
303 
304  view->GetPainter()->GetSettings()->LoadColors( settings );
305  view->UpdateLayerColor( aId );
306  view->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
307  view->UpdateAllItems( KIGFX::COLOR );
308  myframe->GetCanvas()->Refresh();
309 }
310 
311 
312 void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
313 {
314  myframe->SetElementVisibility( aId, isEnabled );
315 
316  if( myframe->GetCanvas() )
317  {
318  if( aId == LAYER_GERBVIEW_GRID )
319  {
322  }
323  else
324  myframe->GetCanvas()->GetView()->SetLayerVisible( aId, isEnabled );
325  }
326 
327  myframe->GetCanvas()->Refresh();
328 }
329 
330 //-----</LAYER_WIDGET callbacks>------------------------------------------
331 
332 /*
333  * Virtual Function useAlternateBitmap
334  * return true if bitmaps shown in Render layer list
335  * must be alternate bitmap (when a gerber image is loaded), or false to use "normal" bitmap
336  */
338 {
339  return GetImagesList()->GetGbrImage( aRow ) != NULL;
340 }
int findLayerRow(LAYER_NUM aLayer) const
Function findLayerRow returns the row index that aLayer resides in, or -1 if not found.
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:104
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:232
GERBER_LAYER_WIDGET(GERBVIEW_FRAME *aParent, wxWindow *aFocusOwner)
Constructor.
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 update the GERBER_LAYER_...
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...
Definition: color4d.h:44
Visibility flag has changed.
Definition: view_item.h:58
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
void updateLayerRow(int aRow, const wxString &aName)
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
bool state
initial wxCheckBox state
Definition: layer_widget.h:92
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
bool IsGridVisible() const
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:332
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:160
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.
Definition: color4d.h:48
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 GetAdapter 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
int GetActiveLayer() const
Function SetActiveLayer returns the active layer.
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
void SetLayerColor(int aLayer, COLOR4D aColor)
The common library.
void SetGridVisibility(bool aVisibility)
Sets the visibility setting of the grid.
Color settings are a bit different than most of the settings objects in that there can be more than o...
void SetVisibleLayers(LSET aLayerMask)
Function SetVisibleLayers is a proxy function that calls the correspondent function in m_BoardSetting...
#define GERBER_DRAW_LAYER(x)
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)
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:99