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 <view/view.h>
35#include <gerbview_painter.h>
38#include <tool/tool_manager.h>
40
41#include "layer_widget.h"
44#include "dcode_selection_box.h"
45
46
47GERBER_LAYER_WIDGET::GERBER_LAYER_WIDGET( GERBVIEW_FRAME* aParent, wxWindow* aFocusOwner ) :
48 LAYER_WIDGET( aParent, aFocusOwner ),
49 m_frame( aParent )
50{
52
54
55 // Update default tabs labels for GerbView
57
58 // handle the popup menu over the layer window.
59 m_LayerScrolledWindow->Connect( wxEVT_RIGHT_DOWN,
60 wxMouseEventHandler( GERBER_LAYER_WIDGET::onRightDownLayers ),
61 nullptr, this );
62
63 // since Popupmenu() calls this->ProcessEvent() we must call this->Connect()
64 // and not m_LayerScrolledWindow->Connect()
65 Connect( ID_LAYER_MANAGER_START, ID_LAYER_MANAGER_END, wxEVT_COMMAND_MENU_SELECTED,
66 wxCommandEventHandler( GERBER_LAYER_WIDGET::onPopupSelection ), nullptr, this );
67}
68
69
71{
73}
74
75
77{
78 m_notebook->SetPageText( 0, _( "Layers" ) );
79 m_notebook->SetPageText( 1, _( "Items" ) );
80}
81
82
84{
85 std::vector<int>render_layers{ LAYER_DCODES, LAYER_NEGATIVE_OBJECTS, LAYER_GERBVIEW_GRID,
88
89 for( int layer: render_layers )
90 {
91 int row = findRenderRow( layer );
92
93 if( row < 0 )
94 continue;
95
97
98 if( color != COLOR4D::UNSPECIFIED )
99 aColorSettings->SetColor( layer, color );
100 }
101
102 for( int layer = GERBVIEW_LAYER_ID_START; layer < GERBVIEW_LAYER_ID_START + GERBER_DRAWLAYERS_COUNT; layer++ )
103 {
104 int row = findLayerRow( layer - GERBVIEW_LAYER_ID_START );
105
106 if( row < 0 ) // Not existing in layer list
107 continue;
108
109 COLOR4D color = GetLayerColor( row );
110
111 if( color != COLOR4D::UNSPECIFIED )
112 aColorSettings->SetColor( layer, color );
113 }
114}
115
116
118{
120
121 // Fixed "Rendering" tab rows within the LAYER_WIDGET, only the initial color
122 // is changed before appending to the LAYER_WIDGET. This is an automatic variable
123 // not a static variable, change the color & state after copying from code to renderRows
124 // on the stack.
125 LAYER_WIDGET::ROW renderRows[7] = {
126
127#define RR LAYER_WIDGET::ROW // Render Row abbreviation to reduce source width
128
129 RR( _( "DCodes" ), LAYER_DCODES, WHITE,
130 _( "Show DCodes identification" ) ),
131 RR( _( "Negative Objects" ), LAYER_NEGATIVE_OBJECTS, DARKGRAY,
132 _( "Show negative objects in this color" ) ),
133 RR(),
134 RR( _( "Grid" ), LAYER_GERBVIEW_GRID, WHITE,
135 _( "Show the (x,y) grid dots" ) ),
136 RR( _( "Drawing Sheet" ), LAYER_GERBVIEW_DRAWINGSHEET, DARKRED,
137 _( "Show drawing sheet border and title block") ),
138 RR( _( "Page Limits" ), LAYER_GERBVIEW_PAGE_LIMITS, WHITE,
139 _( "Show drawing sheet page limits" ) ),
140 RR( _( "Background" ), LAYER_GERBVIEW_BACKGROUND, BLACK,
141 _( "PCB Background" ), true, false )
142 };
143
144 for( unsigned row = 0; row < arrayDim( renderRows ); ++row )
145 {
146 if( renderRows[row].color != COLOR4D::UNSPECIFIED ) // does this row show a color?
147 renderRows[row].color = m_frame->GetVisibleElementColor( renderRows[row].id );
148
149 if( renderRows[row].id ) // if not the separator
150 renderRows[row].state = m_frame->IsElementVisible( renderRows[row].id );
151 }
152
153 AppendRenderRows( renderRows, arrayDim(renderRows) );
154}
155
156
158{
159 // Remember: menu text is capitalized (see our rules_for_capitalization_in_Kicad_UI.txt)
160 KIUI::AddMenuItem( aMenu, ID_SHOW_ALL_LAYERS, _( "Show All Layers" ),
161 KiBitmap( BITMAPS::show_all_layers ) );
162
163 KIUI::AddMenuItem( aMenu, ID_SHOW_NO_LAYERS_BUT_ACTIVE, _( "Hide All Layers But Active" ),
164 KiBitmap( BITMAPS::select_w_layer ) );
165
167 _( "Always Hide All Layers But Active" ),
168 KiBitmap( BITMAPS::select_w_layer ) );
169
170 KIUI::AddMenuItem( aMenu, ID_SHOW_NO_LAYERS, _( "Hide All Layers" ),
171 KiBitmap( BITMAPS::show_no_layers ) );
172
173 aMenu->AppendSeparator();
174
175 KIUI::AddMenuItem( aMenu, ID_SORT_GBR_LAYERS_X2, _( "Sort Layers if X2 Mode" ),
176 KiBitmap( BITMAPS::reload ) );
177
178 KIUI::AddMenuItem( aMenu, ID_SORT_GBR_LAYERS_FILE_EXT, _( "Sort Layers by File Extension" ),
179 KiBitmap( BITMAPS::reload ) );
180
181 aMenu->AppendSeparator();
182
184 _( "Layers Display Parameters: Offset and Rotation" ),
185 KiBitmap( BITMAPS::tools ) );
186
187 aMenu->AppendSeparator();
188
189 KIUI::AddMenuItem( aMenu, ID_LAYER_MOVE_UP, _( "Move Current Layer Up" ),
190 KiBitmap( BITMAPS::up ) );
191
192 KIUI::AddMenuItem( aMenu, ID_LAYER_MOVE_DOWN, _( "Move Current Layer Down" ),
193 KiBitmap( BITMAPS::down ) );
194
195 KIUI::AddMenuItem( aMenu, ID_LAYER_DELETE, _( "Clear Current Layer..." ),
196 KiBitmap( BITMAPS::delete_gerber ) );
197}
198
199
200void GERBER_LAYER_WIDGET::onRightDownLayers( wxMouseEvent& event )
201{
202 wxMenu menu;
203
204 AddRightClickMenuItems( &menu );
205 PopupMenu( &menu );
206
207 passOnFocus();
208}
209
210
211void GERBER_LAYER_WIDGET::onPopupSelection( wxCommandEvent& event )
212{
213 int layer;
214 int rowCount;
215 int menuId = event.GetId();
216 bool visible = (menuId == ID_SHOW_ALL_LAYERS) ? true : false;
217 LSET visibleLayers;
218 bool force_active_layer_visible;
219
220 switch( menuId )
221 {
226 // Set the display layers options. Sorting layers has no effect to these options
228 force_active_layer_visible = ( menuId == ID_SHOW_NO_LAYERS_BUT_ACTIVE ||
230
231 // Update icons and check boxes
232 rowCount = GetLayerRowCount();
233
234 for( int row = 0; row < rowCount; ++row )
235 {
236 wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
237 layer = getDecodedId( cb->GetId() );
238 bool loc_visible = visible;
239
240 if( force_active_layer_visible && (layer == m_frame->GetActiveLayer() ) )
241 loc_visible = true;
242
243 cb->SetValue( loc_visible );
244 visibleLayers[ row ] = loc_visible;
245 }
246
247 m_frame->SetVisibleLayers( visibleLayers );
249 break;
250
253 break;
254
257 break;
258
261 break;
262
263 case ID_LAYER_MOVE_UP:
265 break;
266
269 break;
270
271 case ID_LAYER_DELETE:
273
274 break;
275 }
276}
277
279{
281 return false;
282
283 // postprocess after active layer selection ensure active layer visible
284 wxCommandEvent event;
286 onPopupSelection( event );
287 return true;
288}
289
290
292{
294
295 Freeze();
296
297 for( int layer = 0; layer < GERBER_DRAWLAYERS_COUNT; ++layer )
298 {
299 // Don't show inactive layers
300 if ( GetImagesList()->GetGbrImage(layer) == nullptr )
301 continue;
302
303 int aRow = findLayerRow( layer );
304 bool visible = true;
306 wxString msg = GetImagesList()->GetDisplayName( layer,
307 /* include layer number */ false,
308 /* Get the full name */ true );
309
310 if( m_frame->GetCanvas() )
311 visible = m_frame->GetCanvas()->GetView()->IsLayerVisible( GERBER_DRAW_LAYER( layer ) );
312 else
313 visible = m_frame->IsLayerVisible( layer );
314
315 if( aRow >= 0 )
316 {
317 updateLayerRow( findLayerRow( layer ), msg );
318 SetLayerVisible( layer, visible );
319 }
320 else
321 {
322 AppendLayerRow( LAYER_WIDGET::ROW( msg, layer, color, wxEmptyString, visible, true ) );
323 }
324 }
325
327 Thaw();
328}
329
330
332{
333 AddRightClickMenuItems( &aMenu );
334}
335
336
337void GERBER_LAYER_WIDGET::OnLayerColorChange( int aLayer, const COLOR4D& aColor )
338{
339 // NOTE: Active layer in GerbView is stored as 0-indexed, but layer color is
340 // stored according to the GERBER_DRAW_LAYER() offset.
341 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.
GBR_LAYER_BOX_SELECTOR * m_SelLayerBox
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:395
void UpdateAllItems(int aUpdateFlags)
Update all items in the view according to the given flags.
Definition: view.cpp:1518
void UpdateLayerColor(int aLayer)
Apply the new coloring scheme held by RENDER_SETTINGS in case that it has changed.
Definition: view.cpp:742
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
Definition: view.h:412
PAINTER * GetPainter() const
Return the painter object used by the view for drawing #VIEW_ITEMS.
Definition: view.h:215
void MarkTargetDirty(int aTarget)
Set or clear target 'dirty' flag.
Definition: view.h:619
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: layer_ids.h:573
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:145
@ 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:431
@ GERBVIEW_LAYER_ID_START
Definition: layer_ids.h:421
@ LAYER_GERBVIEW_BACKGROUND
Definition: layer_ids.h:430
@ LAYER_DCODES
Definition: layer_ids.h:426
@ LAYER_NEGATIVE_OBJECTS
Definition: layer_ids.h:427
@ LAYER_GERBVIEW_PAGE_LIMITS
Definition: layer_ids.h:432
@ LAYER_GERBVIEW_GRID
Definition: layer_ids.h:428
#define GERBER_DRAWLAYERS_COUNT
Definition: layer_ids.h:416
#define GERBER_DRAW_LAYER(x)
Definition: layer_ids.h:437
#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
wxMenuItem * AddMenuItem(wxMenu *aMenu, int aId, const wxString &aText, const wxBitmap &aImage, wxItemKind aType=wxITEM_NORMAL)
Create and insert a menu item with an icon into aMenu.
Definition: ui_common.cpp:369
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