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>
39 
40 
41 /*
42  * Class GERBER_LAYER_WIDGET
43  * is here to implement the abtract functions of LAYER_WIDGET so they
44  * may be tied into the GERBVIEW_FRAME's data and so we can add a popup
45  * menu which is specific to Pcbnew's needs.
46  */
47 
48 
49 GERBER_LAYER_WIDGET::GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFocusOwner ) :
50  LAYER_WIDGET( aParent, aFocusOwner ),
51  myframe( aParent )
52 {
54 
55  ReFillRender();
56 
57  // Update default tabs labels for GerbView
59 
60  //-----<Popup menu>-------------------------------------------------
61  // handle the popup menu over the layer window.
62  m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN,
63  wxMouseEventHandler( GERBER_LAYER_WIDGET::onRightDownLayers ), NULL, this );
64 
65  // since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
66  // and not m_LayerScrolledWindow->Connect()
68  wxEVT_COMMAND_MENU_SELECTED,
69  wxCommandEventHandler( GERBER_LAYER_WIDGET::onPopupSelection ), NULL, this );
70 }
71 
73 {
75 }
76 
77 
79 {
80  m_notebook->SetPageText(0, _("Layers") );
81  m_notebook->SetPageText(1, _("Items") );
82 }
83 
89 {
91 
92  // Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
93  // is changed before appending to the LAYER_WIDGET. This is an automatic variable
94  // not a static variable, change the color & state after copying from code to renderRows
95  // on the stack.
96  LAYER_WIDGET::ROW renderRows[6] = {
97 
98 #define RR LAYER_WIDGET::ROW // Render Row abreviation to reduce source width
99 
100  // text id color tooltip checked
101  RR( _( "DCodes" ), LAYER_DCODES, WHITE, _( "Show DCodes identification" ) ),
102  RR( _( "Negative Objects" ), LAYER_NEGATIVE_OBJECTS, DARKGRAY, _( "Show negative objects in this color" ) ),
103  RR(),
104  RR( _( "Grid" ), LAYER_GERBVIEW_GRID, WHITE, _( "Show the (x,y) grid dots" ) ),
105  RR( _( "Worksheet" ), LAYER_WORKSHEET, DARKRED, _( "Show worksheet") ),
106  RR( _( "Background" ), LAYER_PCB_BACKGROUND, BLACK, _( "PCB Background" ), true, false )
107  };
108 
109  for( unsigned row=0; row<arrayDim(renderRows); ++row )
110  {
111  if( renderRows[row].color != COLOR4D::UNSPECIFIED ) // does this row show a color?
112  renderRows[row].color = myframe->GetVisibleElementColor( renderRows[row].id );
113 
114  if( renderRows[row].id ) // if not the separator
115  renderRows[row].state = myframe->IsElementVisible( renderRows[row].id );
116  }
117 
118  AppendRenderRows( renderRows, arrayDim(renderRows) );
119 }
120 
121 
123 {
124  // Remember: menu text is capitalized (see our rules_for_capitalization_in_Kicad_UI.txt)
125  AddMenuItem( aMenu, ID_SHOW_ALL_LAYERS, _( "Show All Layers" ),
126  KiBitmap( show_all_layers_xpm ) );
127 
129  _( "Hide All Layers But Active" ),
130  KiBitmap( select_w_layer_xpm ) );
131 
133  _( "Always Hide All Layers But Active" ),
134  KiBitmap( select_w_layer_xpm ) );
135 
136  AddMenuItem( aMenu, ID_SHOW_NO_LAYERS, _( "Hide All Layers" ),
137  KiBitmap( show_no_layers_xpm ) );
138 
139  aMenu->AppendSeparator();
140  AddMenuItem( aMenu, ID_SORT_GBR_LAYERS, _( "Sort Layers if X2 Mode" ),
141  KiBitmap( reload_xpm ) );
142 }
143 
144 
145 void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
146 {
147  wxMenu menu;
148 
149  AddRightClickMenuItems( &menu );
150  PopupMenu( &menu );
151 
152  passOnFocus();
153 }
154 
155 void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
156 {
157  int rowCount;
158  int menuId = event.GetId();
159  bool visible = (menuId == ID_SHOW_ALL_LAYERS) ? true : false;
160  LSET visibleLayers;
161  bool force_active_layer_visible;
162 
163  switch( menuId )
164  {
165  case ID_SHOW_ALL_LAYERS:
166  case ID_SHOW_NO_LAYERS:
169  // Set the display layers options. Sorting layers has no effect to these options
171  force_active_layer_visible = ( menuId == ID_SHOW_NO_LAYERS_BUT_ACTIVE ||
173 
174  // Update icons and check boxes
175  rowCount = GetLayerRowCount();
176 
177  for( int row = 0; row < rowCount; ++row )
178  {
179  wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
180  int layer = getDecodedId( cb->GetId() );
181  bool loc_visible = visible;
182 
183  if( force_active_layer_visible && (layer == myframe->GetActiveLayer() ) )
184  loc_visible = true;
185 
186  cb->SetValue( loc_visible );
187  visibleLayers[ row ] = loc_visible;
188  }
189 
190  myframe->SetVisibleLayers( visibleLayers );
191  myframe->GetCanvas()->Refresh();
192  break;
193 
194  case ID_SORT_GBR_LAYERS:
196  break;
197  }
198 }
199 
201 {
203  return false;
204 
205  // postprocess after active layer selection
206  // ensure active layer visible
207  wxCommandEvent event;
209  onPopupSelection( event );
210  return true;
211 }
212 
213 
215 {
216  Freeze();
217 
218  ClearLayerRows();
219 
220  for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
221  {
222  wxString msg = GetImagesList()->GetDisplayName( layer );
223 
224  bool visible = true;
225 
226  if( myframe->GetCanvas() )
227  visible = myframe->GetCanvas()->GetView()->IsLayerVisible( GERBER_DRAW_LAYER( layer ) );
228  else
229  visible = myframe->IsLayerVisible( layer );
230 
231  AppendLayerRow( LAYER_WIDGET::ROW( msg, layer,
233  wxEmptyString, visible, true ) );
234  }
235 
236  UpdateLayouts();
237  Thaw();
238 }
239 
240 //-----<LAYER_WIDGET callbacks>-------------------------------------------
241 
243 {
244  AddRightClickMenuItems( &aMenu );
245 }
246 
247 
249 {
250  // NOTE: Active layer in GerbView is stored as 0-indexed, but layer color is
251  // stored according to the GERBER_DRAW_LAYER() offset.
252 
253  myframe->SetLayerColor( GERBER_DRAW_LAYER( aLayer ), aColor );
255 
256  KIGFX::VIEW* view = myframe->GetCanvas()->GetView();
258  view->UpdateLayerColor( GERBER_DRAW_LAYER( aLayer ) );
259 
260  myframe->GetCanvas()->Refresh();
261 }
262 
263 
265 {
266  // the layer change from the GERBER_LAYER_WIDGET can be denied by returning
267  // false from this function.
268  int layer = myframe->GetActiveLayer();
269 
270  myframe->SetActiveLayer( aLayer, false );
272 
273  if( layer != myframe->GetActiveLayer() )
274  {
275  if( ! OnLayerSelected() )
276  myframe->GetCanvas()->Refresh();
277  }
278 
279  return true;
280 }
281 
282 
283 void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal )
284 {
285  LSET visibleLayers = myframe->GetVisibleLayers();
286 
287  visibleLayers[ aLayer ] = isVisible;
288 
289  myframe->SetVisibleLayers( visibleLayers );
290 
291  if( isFinal )
292  myframe->GetCanvas()->Refresh();
293 }
294 
295 
297 {
298  myframe->SetVisibleElementColor( aId, aColor );
299 
300  auto view = myframe->GetCanvas()->GetView();
301 
303  view->UpdateLayerColor( aId );
304 
305  view->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
306  view->UpdateAllItems( KIGFX::COLOR );
307  myframe->GetCanvas()->Refresh();
308 }
309 
310 
311 void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
312 {
313  myframe->SetElementVisibility( aId, isEnabled );
314 
315  if( myframe->GetCanvas() )
316  {
317  if( aId == LAYER_GERBVIEW_GRID )
318  {
321  }
322  else
323  myframe->GetCanvas()->GetView()->SetLayerVisible( aId, isEnabled );
324  }
325 
326  myframe->GetCanvas()->Refresh();
327 }
328 
329 //-----</LAYER_WIDGET callbacks>------------------------------------------
330 
331 /*
332  * Virtual Function useAlternateBitmap
333  * return true if bitmaps shown in Render layer list
334  * must be alternate bitmap (when a gerber image is loaded), or false to use "normal" bitmap
335  */
337 {
338  return GetImagesList()->GetGbrImage( aRow ) != NULL;
339 }
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.
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:251
GERBER_LAYER_WIDGET(GERBVIEW_FRAME *aParent, wxWindow *aFocusOwner)
Constructor.
virtual bool IsGridVisible() const
void UpdateLayouts()
GERBVIEW_FRAME * myframe
int color
Definition: DXF_plotter.cpp:62
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.
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:79
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.
Class LSET is a set of PCB_LAYER_IDs.
#define GERBER_DRAWLAYERS_COUNT
GERBER_FILE_IMAGE * GetGbrImage(int aIdx)
void MarkTargetDirty(int aTarget)
Function MarkTargetDirty() Sets or clears target 'dirty' flag.
Definition: view.h:585
virtual void ImportLegacyColors(const COLORS_DESIGN_SETTINGS *aSettings)
Function ImportLegacyColors Loads a list of color settings for layers.
Definition: painter.h:67
COLORS_DESIGN_SETTINGS * m_colorsSettings
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...
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
#define _(s)
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...
Class LAYER_WIDGET is abstract and is used to manage a list of layers, with the notion of a "current"...
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
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.
Class VIEW.
Definition: view.h:61
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.
bool IsLayerVisible(int aLayer) const
Function IsLayerVisible() Returns information about visibility of a particular layer.
Definition: view.h:416
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39