KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 <[email protected]>
6 * Copyright (C) 2018-2023 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 <wx/checkbox.h>
27#include <wx/filedlg.h>
28#include <bitmaps.h>
29#include <gerbview.h>
31#include <gerbview_frame.h>
33#include <core/arraydim.h>
34#include <lset.h>
35#include <view/view.h>
36#include <gerbview_painter.h>
39#include <tool/tool_manager.h>
41
42#include "layer_widget.h"
45#include "dcode_selection_box.h"
46
47
48GERBER_LAYER_WIDGET::GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFocusOwner ) :
49 LAYER_WIDGET( aParent, aFocusOwner ),
50 m_frame( aParent )
51{
53
55
56 // Update default tabs labels for GerbView
58
59 // handle the popup menu over the layer window.
60 m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN,
61 wxMouseEventHandler( GERBER_LAYER_WIDGET::onRightDownLayers ),
62 nullptr, this );
63
64 // since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
65 // and not m_LayerScrolledWindow->Connect()
66 Connect( ID_LAYER_MANAGER_START, ID_LAYER_MANAGER_END, wxEVT_COMMAND_MENU_SELECTED,
67 wxCommandEventHandler( GERBER_LAYER_WIDGET::onPopupSelection ), nullptr, this );
68}
69
70
72{
74}
75
76
78{
79 m_notebook->SetPageText( 0, _( "Layers" ) );
80 m_notebook->SetPageText( 1, _( "Items" ) );
81}
82
83
85{
86 std::vector<int>render_layers{ LAYER_DCODES, LAYER_NEGATIVE_OBJECTS, LAYER_GERBVIEW_GRID,
89
90 for( int layer: render_layers )
91 {
92 int row = findRenderRow( layer );
93
94 if( row < 0 )
95 continue;
96
98
99 if( color != COLOR4D::UNSPECIFIED )
100 aColorSettings->SetColor( layer, color );
101 }
102
103 for( int layer = GERBVIEW_LAYER_ID_START; layer < GERBVIEW_LAYER_ID_START + GERBER_DRAWLAYERS_COUNT; layer++ )
104 {
105 int row = findLayerRow( layer - GERBVIEW_LAYER_ID_START );
106
107 if( row < 0 ) // Not existing in layer list
108 continue;
109
110 COLOR4D color = GetLayerColor( row );
111
112 if( color != COLOR4D::UNSPECIFIED )
113 aColorSettings->SetColor( layer, color );
114 }
115}
116
117
119{
121
122 // Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
123 // is changed before appending to the LAYER_WIDGET. This is an automatic variable
124 // not a static variable, change the color & state after copying from code to renderRows
125 // on the stack.
126 LAYER_WIDGET::ROW renderRows[7] = {
127
128#define RR LAYER_WIDGET::ROW // Render Row abbreviation to reduce source width
129
130 RR( _( "DCodes" ), LAYER_DCODES, WHITE,
131 _( "Show DCodes identification" ) ),
132 RR( _( "Negative Objects" ), LAYER_NEGATIVE_OBJECTS, DARKGRAY,
133 _( "Show negative objects in this color" ) ),
134 RR(),
135 RR( _( "Grid" ), LAYER_GERBVIEW_GRID, WHITE,
136 _( "Show the (x,y) grid dots" ) ),
137 RR( _( "Drawing Sheet" ), LAYER_GERBVIEW_DRAWINGSHEET, DARKRED,
138 _( "Show drawing sheet border and title block") ),
139 RR( _( "Page Limits" ), LAYER_GERBVIEW_PAGE_LIMITS, WHITE,
140 _( "Show drawing sheet page limits" ) ),
141 RR( _( "Background" ), LAYER_GERBVIEW_BACKGROUND, BLACK,
142 _( "PCB Background" ), true, false )
143 };
144
145 for( unsigned row = 0; row < arrayDim( renderRows ); ++row )
146 {
147 if( renderRows[row].color != COLOR4D::UNSPECIFIED ) // does this row show a color?
148 renderRows[row].color = m_frame->GetVisibleElementColor( renderRows[row].id );
149
150 if( renderRows[row].id ) // if not the separator
151 renderRows[row].state = m_frame->IsElementVisible( renderRows[row].id );
152 }
153
154 AppendRenderRows( renderRows, arrayDim(renderRows) );
155}
156
157
159{
160 // Remember: menu text is capitalized (see our rules_for_capitalization_in_Kicad_UI.txt)
161 KIUI::AddMenuItem( aMenu, ID_SHOW_ALL_LAYERS, _( "Show All Layers" ),
162 KiBitmap( BITMAPS::show_all_layers ) );
163
164 KIUI::AddMenuItem( aMenu, ID_SHOW_NO_LAYERS_BUT_ACTIVE, _( "Hide All Layers But Active" ),
165 KiBitmap( BITMAPS::select_w_layer ) );
166
168 _( "Always Hide All Layers But Active" ),
169 KiBitmap( BITMAPS::select_w_layer ) );
170
171 KIUI::AddMenuItem( aMenu, ID_SHOW_NO_LAYERS, _( "Hide All Layers" ),
172 KiBitmap( BITMAPS::show_no_layers ) );
173
174 aMenu->AppendSeparator();
175
176 KIUI::AddMenuItem( aMenu, ID_SORT_GBR_LAYERS_X2, _( "Sort Layers if X2 Mode" ),
177 KiBitmap( BITMAPS::reload ) );
178
179 KIUI::AddMenuItem( aMenu, ID_SORT_GBR_LAYERS_FILE_EXT, _( "Sort Layers by File Extension" ),
180 KiBitmap( BITMAPS::reload ) );
181
182 aMenu->AppendSeparator();
183
185 _( "Layers Display Parameters: Offset and Rotation" ),
186 KiBitmap( BITMAPS::tools ) );
187
188 aMenu->AppendSeparator();
189
190 KIUI::AddMenuItem( aMenu, ID_LAYER_MOVE_UP, _( "Move Current Layer Up" ),
191 KiBitmap( BITMAPS::up ) );
192
193 KIUI::AddMenuItem( aMenu, ID_LAYER_MOVE_DOWN, _( "Move Current Layer Down" ),
194 KiBitmap( BITMAPS::down ) );
195
196 KIUI::AddMenuItem( aMenu, ID_LAYER_DELETE, _( "Clear Current Layer..." ),
197 KiBitmap( BITMAPS::delete_gerber ) );
198}
199
200
201void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
202{
203 wxMenu menu;
204
205 AddRightClickMenuItems( &menu );
206 PopupMenu( &menu );
207
208 passOnFocus();
209}
210
211
212void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
213{
214 int layer;
215 int rowCount;
216 int menuId = event.GetId();
217 bool visible = (menuId == ID_SHOW_ALL_LAYERS) ? true : false;
218 LSET visibleLayers;
219 bool force_active_layer_visible;
220
221 switch( menuId )
222 {
227 // Set the display layers options. Sorting layers has no effect to these options
229 force_active_layer_visible = ( menuId == ID_SHOW_NO_LAYERS_BUT_ACTIVE ||
231
232 // Update icons and check boxes
233 rowCount = GetLayerRowCount();
234
235 for( int row = 0; row < rowCount; ++row )
236 {
237 wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
238 layer = getDecodedId( cb->GetId() );
239 bool loc_visible = visible;
240
241 if( force_active_layer_visible && (layer == m_frame->GetActiveLayer() ) )
242 loc_visible = true;
243
244 cb->SetValue( loc_visible );
245 visibleLayers[ row ] = loc_visible;
246 }
247
248 m_frame->SetVisibleLayers( visibleLayers );
250 break;
251
254 break;
255
258 break;
259
262 break;
263
264 case ID_LAYER_MOVE_UP:
266 break;
267
270 break;
271
272 case ID_LAYER_DELETE:
274
275 break;
276 }
277}
278
280{
282 return false;
283
284 // postprocess after active layer selection ensure active layer visible
285 wxCommandEvent event;
287 onPopupSelection( event );
288 return true;
289}
290
291
293{
295
296 Freeze();
297
298 for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
299 {
300 // Don't show inactive layers
301 if ( GetImagesList()->GetGbrImage(layer) == nullptr )
302 continue;
303
304 int aRow = findLayerRow( layer );
305 bool visible = true;
307 wxString msg = GetImagesList()->GetDisplayName( layer,
308 /* include layer number */ false,
309 /* Get the full name */ true );
310
311 if( m_frame->GetCanvas() )
312 visible = m_frame->GetCanvas()->GetView()->IsLayerVisible( GERBER_DRAW_LAYER( layer ) );
313 else
314 visible = m_frame->IsLayerVisible( layer );
315
316 if( aRow >= 0 )
317 {
318 updateLayerRow( findLayerRow( layer ), msg );
319 SetLayerVisible( layer, visible );
320 }
321 else
322 {
323 AppendLayerRow( LAYER_WIDGET::ROW( msg, layer, color, wxEmptyString, visible, true ) );
324 }
325 }
326
328 Thaw();
329}
330
331
333{
334 AddRightClickMenuItems( &aMenu );
335}
336
337
338void GERBER_LAYER_WIDGET::OnLayerColorChange( int aLayer, const COLOR4D& aColor )
339{
340 // NOTE: Active layer in GerbView is stored as 0-indexed, but layer color is
341 // stored according to the GERBER_DRAW_LAYER() offset.
342 m_frame->SetLayerColor( GERBER_DRAW_LAYER( aLayer ), aColor );
343
344 KIGFX::VIEW* view = m_frame->GetCanvas()->GetView();
345 COLOR_SETTINGS* color_settings = m_frame->GetColorSettings();
346 color_settings->SetColor( aLayer, aColor );
347
348 view->GetPainter()->GetSettings()->LoadColors( color_settings );
349 view->UpdateLayerColor( GERBER_DRAW_LAYER( aLayer ) );
350
352}
353
354
356{
357 // the layer change from the GERBER_LAYER_WIDGET can be denied by returning
358 // false from this function.
359 int layer = m_frame->GetActiveLayer();
360
361 m_frame->SetActiveLayer( aLayer, false );
363
364 if( layer != m_frame->GetActiveLayer() )
365 {
366 if( ! OnLayerSelected() )
367 {
368 auto settings = static_cast<KIGFX::GERBVIEW_PAINTER*>
369 ( m_frame->GetCanvas()->GetView()->GetPainter() )->GetSettings();
370 int dcodeSelected = m_frame->m_DCodeSelector->GetSelectedDCodeId();
371 settings->m_dcodeHighlightValue = dcodeSelected;
374 }
375 }
376
377 return true;
378}
379
380
381void GERBER_LAYER_WIDGET::OnLayerVisible( int aLayer, bool isVisible, bool isFinal )
382{
383 LSET visibleLayers = m_frame->GetVisibleLayers();
384
385 visibleLayers[ aLayer ] = isVisible;
386
387 m_frame->SetVisibleLayers( visibleLayers );
388
389 if( isFinal )
391}
392
393
395{
396 m_frame->SetVisibleElementColor( aId, aColor );
397
398 auto view = m_frame->GetCanvas()->GetView();
399
400 COLOR_SETTINGS* color_settings = m_frame->GetColorSettings();
401 color_settings->SetColor( aId, aColor );
402
403 view->GetPainter()->GetSettings()->LoadColors( color_settings );
404 view->UpdateLayerColor( aId );
405 view->MarkTargetDirty( KIGFX::TARGET_NONCACHED );
406 view->UpdateAllItems( KIGFX::COLOR );
408}
409
410
411void GERBER_LAYER_WIDGET::OnRenderEnable( int aId, bool isEnabled )
412{
413 m_frame->SetElementVisibility( aId, isEnabled );
414
415 if( m_frame->GetCanvas() )
416 {
417 if( aId == LAYER_GERBVIEW_GRID )
418 {
421 }
422 else
423 {
424 m_frame->GetCanvas()->GetView()->SetLayerVisible( aId, isEnabled );
425 }
426 }
427
429}
int color
Definition: DXF_plotter.cpp:58
#define RR
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
Definition: arraydim.h:31
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition: bitmap.cpp:104
Color settings are a bit different than most of the settings objects in that there can be more than o...
void SetColor(int aLayer, const COLOR4D &aColor)
virtual EDA_DRAW_PANEL_GAL * GetCanvas() const
Return a pointer to GAL-based canvas of given EDA draw frame.
bool IsGridVisible() const
virtual KIGFX::VIEW * GetView() const
Return a pointer to the #VIEW instance used in the panel.
virtual void Refresh(bool aEraseBackground=true, const wxRect *aRect=nullptr) override
KIGFX::GAL * GetGAL() const
Return a pointer to the GAL instance used in the panel.
GERBER_FILE_IMAGE_LIST is a helper class to handle a list of GERBER_FILE_IMAGE files which are loaded...
static GERBER_FILE_IMAGE_LIST & GetImagesList()
const wxString GetDisplayName(int aIdx, bool aNameOnly=false, bool aFullName=false)
Get the display name for the layer at aIdx.
GERBER_FILE_IMAGE_LIST * GetImagesList()
void OnRenderEnable(int aId, bool isEnabled) override
Notify client code whenever the user changes an rendering enable in one of the rendering checkboxes.
void onPopupSelection(wxCommandEvent &event)
bool OnLayerSelect(int aLayer) override
Notify client code whenever the user selects a different layer.
void OnLayerRightClick(wxMenu &aMenu) override
Notify client code about a layer being right-clicked.
void onRightDownLayers(wxMouseEvent &event)
Put up a popup menu for the layer panel.
void OnLayerVisible(int aLayer, bool isVisible, bool isFinal) override
Notify client code about a layer visibility change.
void CollectCurrentColorSettings(COLOR_SETTINGS *aColorSettings)
Collect the current color settings and put it in aColorSettings.
void SetLayersManagerTabsText()
Update the layer manager tabs labels.
void AddRightClickMenuItems(wxMenu *aMenu)
Add menu items to a menu that should be shown when right-clicking the Gerber layer widget.
bool OnLayerSelected()
Ensure the active layer is visible, and other layers not visible when m_alwaysShowActiveLayer is true...
GERBER_LAYER_WIDGET(GERBVIEW_FRAME *aParent, wxWindow *aFocusOwner)
void OnLayerColorChange(int aLayer, const COLOR4D &aColor) override
Notify client code about a layer color change.
void OnRenderColorChange(int aId, const COLOR4D &aColor) override
Notify client code whenever the user changes a rendering color.
void ReFillRender()
Rebuild Render for instance after the config is read.
void ReFill()
Rebuild Render for instance after the config is read.
static TOOL_ACTION moveLayerUp
static TOOL_ACTION moveLayerDown
COLOR_SETTINGS * GetColorSettings(bool aForceRefresh=false) const override
Returns a pointer to the active color theme settings.
void SetLayerColor(int aLayer, const COLOR4D &aColor)
COLOR4D GetVisibleElementColor(int aLayerID)
Return the color of a gerber visible element.
bool IsLayerVisible(int aLayer) const
Test whether a given layer is visible.
void SortLayersByX2Attributes()
LSET GetVisibleLayers() const
A proxy function that calls the correspondent function in m_BoardSettings.
void syncLayerBox(bool aRebuildLayerBox=false)
Update the currently "selected" layer within m_SelLayerBox.
int GetActiveLayer() const
Return the active layer.
bool IsElementVisible(int aLayerID) const
Test whether a given element category is visible.
DCODE_SELECTION_BOX * m_DCodeSelector
void SetActiveLayer(int aLayer, bool doLayerWidgetUpdate=true)
change the currently active layer to aLayer and update the GERBER_LAYER_WIDGET.
void SetVisibleElementColor(int aLayerID, const COLOR4D &aColor)
void SetVisibleLayers(LSET aLayerMask)
A proxy function that calls the correspondent function in m_BoardSettings.
COLOR4D GetLayerColor(int aLayer) const
void SortLayersByFileExtension()
void Erase_Current_DrawLayer(bool query)
void SetElementVisibility(int aLayerID, bool aNewState)
Change the visibility of an element category.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
void SetGridVisibility(bool aVisibility)
Set the visibility setting of the grid.
Methods for drawing GerbView specific items.
virtual RENDER_SETTINGS * GetSettings()=0
Return a pointer to current settings that are going to be used when drawing items.
virtual void LoadColors(const COLOR_SETTINGS *aSettings)
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
Definition: view.h:68
void SetLayerVisible(int aLayer, bool aVisible=true)
Control the visibility of a particular layer.
Definition: view.h:401
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition: view.cpp:1563
void UpdateLayerColor(int aLayer)
Apply the new coloring scheme held by RENDER_SETTINGS in case that it has changed.
Definition: view.cpp:783
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:418
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:221
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition: view.h:625
Manage a list of layers with the notion of a "current" layer, and layer specific visibility control.
Definition: layer_widget.h:78
static int getDecodedId(int aControlId)
Decode aControlId to original un-encoded value.
void AppendRenderRows(const ROW *aRowsArray, int aRowCount)
Append new rows in the render portion of the widget.
Definition: layer_widget.h:200
int GetLayerRowCount() const
Return the number of rows in the layer tab.
void UpdateLayouts()
void passOnFocus()
Give away the keyboard focus up to the main parent window.
COLOR4D GetRenderColor(int aRow) const
Return the color of the Render ROW in position aRow.
void updateLayerRow(int aRow, const wxString &aName)
int findLayerRow(int aLayer) const
Return the row index that aLayer resides in, or -1 if not found.
int findRenderRow(int aId) const
void SetLayerVisible(int aLayer, bool isVisible)
Set aLayer visible or not.
void ClearLayerRows()
Empty out the layer rows.
wxWindow * getLayerComp(int aRow, int aColumn) const
Return the component within the m_LayersFlexGridSizer at aRow and aCol or NULL if these parameters ar...
void AppendLayerRow(const ROW &aRow)
Append a new row in the layer portion of the widget.
void ClearRenderRows()
Empty out the render rows.
COLOR4D GetLayerColor(int aLayer) const
Return the color of the layer ROW associated with aLayer id.
wxNotebook * m_notebook
Definition: layer_widget.h:465
wxScrolledWindow * m_LayerScrolledWindow
Definition: layer_widget.h:467
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:36
TOOL_MANAGER * GetToolManager() const
Return the MVC controller.
Definition: tools_holder.h:55
bool RunAction(const std::string &aActionName, T aParam)
Run the specified action immediately, pausing the current action to run the new one.
Definition: tool_manager.h:150
@ WHITE
Definition: color4d.h:48
@ DARKGRAY
Definition: color4d.h:46
@ DARKRED
Definition: color4d.h:53
@ BLACK
Definition: color4d.h:44
#define _(s)
@ LAYER_GERBVIEW_DRAWINGSHEET
Definition: layer_ids.h:435
@ GERBVIEW_LAYER_ID_START
Definition: layer_ids.h:425
@ LAYER_GERBVIEW_BACKGROUND
Definition: layer_ids.h:434
@ LAYER_DCODES
Definition: layer_ids.h:430
@ LAYER_NEGATIVE_OBJECTS
Definition: layer_ids.h:431
@ LAYER_GERBVIEW_PAGE_LIMITS
Definition: layer_ids.h:436
@ LAYER_GERBVIEW_GRID
Definition: layer_ids.h:432
#define GERBER_DRAWLAYERS_COUNT
Definition: layer_ids.h:420
#define GERBER_DRAW_LAYER(x)
Definition: layer_ids.h:441
#define COLUMN_COLOR_LYR_CB
Definition: layer_widget.h:53
@ COLOR
Color has changed.
Definition: view_item.h:53
@ TARGET_NONCACHED
Auxiliary rendering target (noncached)
Definition: definitions.h:49
KICOMMON_API wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmapBundle &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
Definition: ui_common.cpp:372
Provide all the data needed to add a row to a LAYER_WIDGET.
Definition: layer_widget.h:85
COLOR4D color
COLOR4D::UNSPECIFIED if none.
Definition: layer_widget.h:88
bool state
initial wxCheckBox state
Definition: layer_widget.h:89