KiCad PCB EDA Suite
panel_fp_editor_defaults.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) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#include <pgm_base.h>
27#include <widgets/wx_grid.h>
29#include <grid_tricks.h>
30#include <eda_base_frame.h>
33#include <bitmaps.h>
34#include <confirm.h>
35
36class TEXT_ITEMS_GRID_TABLE : public wxGridTableBase
37{
38 std::vector<TEXT_ITEM_INFO> m_items;
39
40public:
42 { }
43
44 int GetNumberRows() override { return m_items.size(); }
45 int GetNumberCols() override { return 3; }
46
47 wxString GetColLabelValue( int aCol ) override
48 {
49 switch( aCol )
50 {
51 case 0: return _( "Text Items" );
52 case 1: return _( "Show" );
53 case 2: return _( "Layer" );
54 default: return wxEmptyString;
55 }
56 }
57
58 wxString GetRowLabelValue( int aRow ) override
59 {
60 switch( aRow )
61 {
62 case 0: return _( "Reference designator" );
63 case 1: return _( "Value" );
64 default: return wxEmptyString;
65 }
66 }
67
68 bool CanGetValueAs( int aRow, int aCol, const wxString& aTypeName ) override
69 {
70 switch( aCol )
71 {
72 case 0: return aTypeName == wxGRID_VALUE_STRING;
73 case 1: return aTypeName == wxGRID_VALUE_BOOL;
74 case 2: return aTypeName == wxGRID_VALUE_NUMBER;
75 default: wxFAIL; return false;
76 }
77 }
78
79 bool CanSetValueAs( int aRow, int aCol, const wxString& aTypeName ) override
80 {
81 return CanGetValueAs( aRow, aCol, aTypeName );
82 }
83
84 wxString GetValue( int row, int col ) override
85 {
86 return m_items[row].m_Text;
87 }
88 void SetValue( int row, int col, const wxString& value ) override
89 {
90 if( col == 0 )
91 m_items[row].m_Text = value;
92 }
93
94 bool GetValueAsBool( int row, int col ) override
95 {
96 return m_items[row].m_Visible;
97 }
98 void SetValueAsBool( int row, int col, bool value ) override
99 {
100 if( col == 1 )
101 m_items[row].m_Visible = value;
102 }
103
104 long GetValueAsLong( int row, int col ) override
105 {
106 return m_items[row].m_Layer;
107 }
108 void SetValueAsLong( int row, int col, long value ) override
109 {
110 if( col == 2 )
111 m_items[row].m_Layer = (int) value;
112 }
113
114 bool AppendRows( size_t aNumRows = 1 ) override
115 {
116 for( size_t i = 0; i < aNumRows; ++i )
117 m_items.emplace_back( wxT( "" ), true, F_SilkS );
118
119 if( GetView() )
120 {
121 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, aNumRows );
122 GetView()->ProcessTableMessage( msg );
123 }
124
125 return true;
126 }
127
128 bool DeleteRows( size_t aPos, size_t aNumRows ) override
129 {
130 // aPos may be a large positive, e.g. size_t(-1), and the sum of
131 // aPos+aNumRows may wrap here, so both ends of the range are tested.
132 if( aPos < m_items.size() && aPos + aNumRows <= m_items.size() )
133 {
134 m_items.erase( m_items.begin() + aPos, m_items.begin() + aPos + aNumRows );
135
136 if( GetView() )
137 {
138 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aPos, aNumRows );
139 GetView()->ProcessTableMessage( msg );
140 }
141 return true;
142 }
143
144 return false;
145 }
146};
147
148
149// Columns of graphics grid
150enum
151{
158
159enum
160{
167
170
171
173 UNITS_PROVIDER* aUnitsProvider ) :
175{
176 m_parent = static_cast<PAGED_DIALOG*>( aParent->GetParent() );
177
178 m_textItemsGrid->SetDefaultRowSize( m_textItemsGrid->GetDefaultRowSize() + 4 );
179
181 m_textItemsGrid->PushEventHandler( new GRID_TRICKS( m_textItemsGrid ) );
182 m_textItemsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
183
184 wxGridCellAttr* attr = new wxGridCellAttr;
185 attr->SetRenderer( new wxGridCellBoolRenderer() );
186 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
187 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
188 m_textItemsGrid->SetColAttr( 1, attr );
189
190 attr = new wxGridCellAttr;
191 attr->SetRenderer( new GRID_CELL_LAYER_RENDERER( nullptr ) );
192 attr->SetEditor( new GRID_CELL_LAYER_SELECTOR( nullptr, {} ) );
193 m_textItemsGrid->SetColAttr( 2, attr );
194
195 m_graphicsGrid->SetUnitsProvider( aUnitsProvider );
200
201 m_graphicsGrid->SetDefaultRowSize( m_graphicsGrid->GetDefaultRowSize() + 4 );
202
203 // Work around a bug in wxWidgets where it fails to recalculate the grid height
204 // after changing the default row size
205 m_graphicsGrid->AppendRows( 1 );
206 m_graphicsGrid->DeleteRows( m_graphicsGrid->GetNumberRows() - 1, 1 );
207
208 m_graphicsGrid->PushEventHandler( new GRID_TRICKS( m_graphicsGrid ) );
209
210 m_staticTextInfo->SetFont( KIUI::GetInfoFont( this ).Italic() );
211}
212
213
215{
216 // destroy GRID_TRICKS before grids.
217 m_textItemsGrid->PopEventHandler( true );
218 m_graphicsGrid->PopEventHandler( true );
219}
220
221
223{
224 wxColour disabledColour = wxSystemSettings::GetColour( wxSYS_COLOUR_BACKGROUND );
225
226 auto disableCell =
227 [&]( int row, int col )
228 {
229 m_graphicsGrid->SetReadOnly( row, col );
230 m_graphicsGrid->SetCellBackgroundColour( row, col, disabledColour );
231 };
232
233 for( int i = 0; i < ROW_COUNT; ++i )
234 {
236
237 if( i == ROW_EDGES || i == ROW_COURTYARD )
238 {
239 disableCell( i, COL_TEXT_WIDTH );
240 disableCell( i, COL_TEXT_HEIGHT );
241 disableCell( i, COL_TEXT_THICKNESS );
242 disableCell( i, COL_TEXT_ITALIC );
243 }
244 else
245 {
249 m_graphicsGrid->SetCellValue( i, COL_TEXT_ITALIC, aCfg->m_DesignSettings.m_TextItalic[ i ] ? wxT( "1" ) : wxT( "" ) );
250
251 auto attr = new wxGridCellAttr;
252 attr->SetRenderer( new wxGridCellBoolRenderer() );
253 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
254 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
255 m_graphicsGrid->SetAttr( i, COL_TEXT_ITALIC, attr );
256 }
257 }
258
259 // Footprint defaults
260 m_textItemsGrid->GetTable()->DeleteRows( 0, m_textItemsGrid->GetNumberRows() );
261 m_textItemsGrid->GetTable()->AppendRows( aCfg->m_DesignSettings.m_DefaultFPTextItems.size() );
262
263 for( size_t i = 0; i < aCfg->m_DesignSettings.m_DefaultFPTextItems.size(); ++i )
264 {
266
267 m_textItemsGrid->GetTable()->SetValue( i, 0, item.m_Text );
268 m_textItemsGrid->GetTable()->SetValueAsBool( i, 1, item.m_Visible );
269 m_textItemsGrid->GetTable()->SetValueAsLong( i, 2, item.m_Layer );
270 }
271
272 for( int col = 0; col < m_graphicsGrid->GetNumberCols(); col++ )
273 {
274 // Set the minimal width to the column label size.
275 m_graphicsGrid->SetColMinimalWidth( col, m_graphicsGrid->GetVisibleWidth( col, true, false ) );
276
277 // Set the width to see the full contents
278 if( m_graphicsGrid->IsColShown( col ) )
279 m_graphicsGrid->SetColSize( col, m_graphicsGrid->GetVisibleWidth( col, true, true, true ) );
280 }
281
282 m_graphicsGrid->SetRowLabelSize( m_graphicsGrid->GetVisibleWidth( -1, true, true, true ) );
283
284 Layout();
285}
286
287
289{
290 SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
292
293 loadFPSettings( cfg );
294
295 return true;
296}
297
298
300{
301 bool retVal = wxPanel::Show( aShow );
302
303 if( aShow )
304 {
305 // These *should* work in the constructor, and indeed they do if this panel is the
306 // first displayed. However, on OSX 3.0.5 (at least), if another panel is displayed
307 // first then the icons will be blank unless they're set here.
308 m_bpAdd->SetBitmap( KiBitmap( BITMAPS::small_plus ) );
310 }
311
312 if( aShow && m_firstShow )
313 {
314 m_graphicsGrid->SetColSize( 0, m_graphicsGrid->GetColSize( 0 ) + 1 );
315 m_firstShow = false;
316 }
317
318 return retVal;
319}
320
321
323{
325 return false;
326
327 // Test text parameters.
328 for( int row : { ROW_SILK, ROW_COPPER, ROW_FAB, ROW_OTHERS } )
329 {
330 int textSize = std::min( m_graphicsGrid->GetUnitValue( row, COL_TEXT_WIDTH ),
332
333 if( m_graphicsGrid->GetUnitValue( row, COL_TEXT_THICKNESS ) > textSize / 4 )
334 {
335 wxString msg = _( "Text will not be readable with a thickness greater than\n"
336 "1/4 its width or height." );
338 return false;
339 }
340 }
341
342 return true;
343}
344
345
347{
348 if( !validateData() )
349 return false;
350
351 SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
352 BOARD_DESIGN_SETTINGS& cfg = mgr.GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>()->m_DesignSettings;
353
354 for( int i = 0; i < ROW_COUNT; ++i )
355 {
357
358 if( i == ROW_EDGES || i == ROW_COURTYARD )
359 continue;
360
361 cfg.m_TextSize[ i ] = wxSize( m_graphicsGrid->GetUnitValue( i, COL_TEXT_WIDTH ),
364
365 wxString msg = m_graphicsGrid->GetCellValue( i, COL_TEXT_ITALIC );
366 cfg.m_TextItalic[ i ] = wxGridCellBoolEditor::IsTrueValue( msg );
367 }
368
369 // Footprint defaults
370 wxGridTableBase* table = m_textItemsGrid->GetTable();
371 cfg.m_DefaultFPTextItems.clear();
372
373 for( int i = 0; i < m_textItemsGrid->GetNumberRows(); ++i )
374 {
375 wxString text = table->GetValue( i, 0 );
376 bool visible = table->GetValueAsBool( i, 1 );
377 int layer = (int) table->GetValueAsLong( i, 2 );
378
379 cfg.m_DefaultFPTextItems.emplace_back( text, visible, layer );
380 }
381
382 return true;
383}
384
385
386void PANEL_FP_EDITOR_DEFAULTS::OnAddTextItem( wxCommandEvent& event )
387{
389 return;
390
391 wxGridTableBase* table = m_textItemsGrid->GetTable();
392
393 int newRow = m_textItemsGrid->GetNumberRows();
394 table->AppendRows( 1 );
395 table->SetValueAsBool( newRow, 1, table->GetValueAsBool( newRow - 1, 1 ) );
396 table->SetValueAsLong( newRow, 2, table->GetValueAsLong( newRow - 1, 2 ) );
397
398 m_textItemsGrid->MakeCellVisible( newRow, 0 );
399 m_textItemsGrid->SetGridCursor( newRow, 0 );
400
401 m_textItemsGrid->EnableCellEditControl( true );
402 m_textItemsGrid->ShowCellEditControl();
403}
404
405
407{
408 wxArrayInt selectedRows = m_textItemsGrid->GetSelectedRows();
409
410 if( selectedRows.empty() && m_textItemsGrid->GetGridCursorRow() >= 0 )
411 selectedRows.push_back( m_textItemsGrid->GetGridCursorRow() );
412
413 if( selectedRows.empty() )
414 return;
415
416 for( int row : selectedRows )
417 {
418 if( row < 2 )
419 {
420 DisplayError( nullptr, _( "Reference and value are mandatory." ) );
421 return;
422 }
423 }
424
426 return;
427
428 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
429 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
430
431 for( int row : selectedRows )
432 {
433 m_textItemsGrid->GetTable()->DeleteRows( row, 1 );
434
435 if( m_textItemsGrid->GetNumberRows() > 0 )
436 {
437 m_textItemsGrid->MakeCellVisible( std::max( 0, row-1 ),
438 m_textItemsGrid->GetGridCursorCol() );
439 m_textItemsGrid->SetGridCursor( std::max( 0, row-1 ),
440 m_textItemsGrid->GetGridCursorCol() );
441 }
442 }
443}
444
445
447{
449 cfg.Load(); // Loading without a file will init to defaults
450
451 loadFPSettings( &cfg );
452}
453
454
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:105
Container for design settings for a BOARD object.
std::vector< TEXT_ITEM_INFO > m_DefaultFPTextItems
int m_TextThickness[LAYER_CLASS_COUNT]
int m_LineThickness[LAYER_CLASS_COUNT]
wxSize m_TextSize[LAYER_CLASS_COUNT]
bool m_TextItalic[LAYER_CLASS_COUNT]
BOARD_DESIGN_SETTINGS m_DesignSettings
Only some of these settings are actually used for footprint editing.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
virtual void Load()
Updates the parameters of this object based on the current JSON document contents.
void SetError(const wxString &aMessage, const wxString &aPageName, int aCtrlId, int aRow=-1, int aCol=-1)
Class PANEL_FP_EDITOR_DEFAULTS_BASE.
virtual void OnAddTextItem(wxCommandEvent &event) override
void ResetPanel() override
Reset the contents of this panel.
bool Show(bool aShow) override
PANEL_FP_EDITOR_DEFAULTS(wxWindow *aParent, UNITS_PROVIDER *aUnitsProvider)
virtual void OnDeleteTextItem(wxCommandEvent &event) override
void loadFPSettings(FOOTPRINT_EDITOR_SETTINGS *aCfg)
T * GetAppSettings(bool aLoadNow=true)
Returns a handle to the a given settings by type If the settings have already been loaded,...
std::vector< TEXT_ITEM_INFO > m_items
bool DeleteRows(size_t aPos, size_t aNumRows) override
wxString GetRowLabelValue(int aRow) override
void SetValueAsLong(int row, int col, long value) override
void SetValue(int row, int col, const wxString &value) override
wxString GetValue(int row, int col) override
void SetValueAsBool(int row, int col, bool value) override
wxString GetColLabelValue(int aCol) override
bool CanSetValueAs(int aRow, int aCol, const wxString &aTypeName) override
bool GetValueAsBool(int row, int col) override
bool AppendRows(size_t aNumRows=1) override
bool CanGetValueAs(int aRow, int aCol, const wxString &aTypeName) override
long GetValueAsLong(int row, int col) override
int GetVisibleWidth(int aCol, bool aHeader=true, bool aContents=true, bool aKeep=false)
Calculates the specified column based on the actual size of the text on screen.
Definition: wx_grid.cpp:377
void SetTable(wxGridTableBase *table, bool aTakeOwnership=false)
Hide wxGrid's SetTable() method with one which doesn't mess up the grid column widths when setting th...
Definition: wx_grid.cpp:95
void SetUnitValue(int aRow, int aCol, int aValue)
Set a unitized cell's value.
Definition: wx_grid.cpp:359
int GetUnitValue(int aRow, int aCol)
Apply standard KiCad unit and eval services to a numeric cell.
Definition: wx_grid.cpp:338
void SetAutoEvalCols(const std::vector< int > &aCols)
Definition: wx_grid.h:90
void SetUnitsProvider(UNITS_PROVIDER *aProvider, int aCol=0)
Set a UNITS_PROVIDER to enable use of unit- and eval-based Getters.
Definition: wx_grid.cpp:329
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:280
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:280
This file is part of the common library.
#define _(s)
Base window classes and related definitions.
@ F_SilkS
Definition: layer_ids.h:104
wxFont GetInfoFont(wxWindow *aWindow)
Definition: ui_common.cpp:144
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111