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>
30#include <grid_tricks.h>
31#include <eda_base_frame.h>
34#include <bitmaps.h>
35#include <confirm.h>
36
37class TEXT_ITEMS_GRID_TABLE : public wxGridTableBase
38{
39 std::vector<TEXT_ITEM_INFO> m_items;
40
41public:
43 { }
44
45 int GetNumberRows() override { return m_items.size(); }
46 int GetNumberCols() override { return 3; }
47
48 wxString GetColLabelValue( int aCol ) override
49 {
50 switch( aCol )
51 {
52 case 0: return _( "Text Items" );
53 case 1: return _( "Show" );
54 case 2: return _( "Layer" );
55 default: return wxEmptyString;
56 }
57 }
58
59 wxString GetRowLabelValue( int aRow ) override
60 {
61 switch( aRow )
62 {
63 case 0: return _( "Reference designator" );
64 case 1: return _( "Value" );
65 default: return wxEmptyString;
66 }
67 }
68
69 bool CanGetValueAs( int aRow, int aCol, const wxString& aTypeName ) override
70 {
71 switch( aCol )
72 {
73 case 0: return aTypeName == wxGRID_VALUE_STRING;
74 case 1: return aTypeName == wxGRID_VALUE_BOOL;
75 case 2: return aTypeName == wxGRID_VALUE_NUMBER;
76 default: wxFAIL; return false;
77 }
78 }
79
80 bool CanSetValueAs( int aRow, int aCol, const wxString& aTypeName ) override
81 {
82 return CanGetValueAs( aRow, aCol, aTypeName );
83 }
84
85 wxString GetValue( int row, int col ) override
86 {
87 return m_items[row].m_Text;
88 }
89 void SetValue( int row, int col, const wxString& value ) override
90 {
91 if( col == 0 )
92 m_items[row].m_Text = value;
93 }
94
95 bool GetValueAsBool( int row, int col ) override
96 {
97 return m_items[row].m_Visible;
98 }
99 void SetValueAsBool( int row, int col, bool value ) override
100 {
101 if( col == 1 )
102 m_items[row].m_Visible = value;
103 }
104
105 long GetValueAsLong( int row, int col ) override
106 {
107 return m_items[row].m_Layer;
108 }
109 void SetValueAsLong( int row, int col, long value ) override
110 {
111 if( col == 2 )
112 m_items[row].m_Layer = (int) value;
113 }
114
115 bool AppendRows( size_t aNumRows = 1 ) override
116 {
117 for( size_t i = 0; i < aNumRows; ++i )
118 m_items.emplace_back( wxT( "" ), true, F_SilkS );
119
120 if( GetView() )
121 {
122 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_APPENDED, aNumRows );
123 GetView()->ProcessTableMessage( msg );
124 }
125
126 return true;
127 }
128
129 bool DeleteRows( size_t aPos, size_t aNumRows ) override
130 {
131 // aPos may be a large positive, e.g. size_t(-1), and the sum of
132 // aPos+aNumRows may wrap here, so both ends of the range are tested.
133 if( aPos < m_items.size() && aPos + aNumRows <= m_items.size() )
134 {
135 m_items.erase( m_items.begin() + aPos, m_items.begin() + aPos + aNumRows );
136
137 if( GetView() )
138 {
139 wxGridTableMessage msg( this, wxGRIDTABLE_NOTIFY_ROWS_DELETED, aPos, aNumRows );
140 GetView()->ProcessTableMessage( msg );
141 }
142 return true;
143 }
144
145 return false;
146 }
147};
148
149
150// Columns of graphics grid
151enum
152{
159
160enum
161{
168
171
172
174 UNITS_PROVIDER* aUnitsProvider ) :
176{
177 m_parent = static_cast<PAGED_DIALOG*>( aParent->GetParent() );
178
179 m_textItemsGrid->SetDefaultRowSize( m_textItemsGrid->GetDefaultRowSize() + 4 );
180
182 m_textItemsGrid->PushEventHandler( new GRID_TRICKS( m_textItemsGrid ) );
183 m_textItemsGrid->SetSelectionMode( wxGrid::wxGridSelectRows );
184
185 wxGridCellAttr* attr = new wxGridCellAttr;
186 attr->SetRenderer( new wxGridCellBoolRenderer() );
187 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
188 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
189 m_textItemsGrid->SetColAttr( 1, attr );
190
191 attr = new wxGridCellAttr;
192 attr->SetRenderer( new GRID_CELL_LAYER_RENDERER( nullptr ) );
193 attr->SetEditor( new GRID_CELL_LAYER_SELECTOR( nullptr, {} ) );
194 m_textItemsGrid->SetColAttr( 2, attr );
195
196 m_graphicsGrid->SetUnitsProvider( aUnitsProvider );
201
202 m_graphicsGrid->SetDefaultRowSize( m_graphicsGrid->GetDefaultRowSize() + 4 );
203
204 // Work around a bug in wxWidgets where it fails to recalculate the grid height
205 // after changing the default row size
206 m_graphicsGrid->AppendRows( 1 );
207 m_graphicsGrid->DeleteRows( m_graphicsGrid->GetNumberRows() - 1, 1 );
208
209 m_graphicsGrid->PushEventHandler( new GRID_TRICKS( m_graphicsGrid ) );
210
211 m_staticTextInfo->SetFont( KIUI::GetInfoFont( this ).Italic() );
212}
213
214
216{
217 // destroy GRID_TRICKS before grids.
218 m_textItemsGrid->PopEventHandler( true );
219 m_graphicsGrid->PopEventHandler( true );
220}
221
222
224{
225 wxColour disabledColour = wxSystemSettings::GetColour( wxSYS_COLOUR_BACKGROUND );
226
227 auto disableCell =
228 [&]( int row, int col )
229 {
230 m_graphicsGrid->SetReadOnly( row, col );
231 m_graphicsGrid->SetCellBackgroundColour( row, col, disabledColour );
232 };
233
234 for( int i = 0; i < ROW_COUNT; ++i )
235 {
237
238 if( i == ROW_EDGES || i == ROW_COURTYARD )
239 {
240 disableCell( i, COL_TEXT_WIDTH );
241 disableCell( i, COL_TEXT_HEIGHT );
242 disableCell( i, COL_TEXT_THICKNESS );
243 disableCell( i, COL_TEXT_ITALIC );
244 }
245 else
246 {
250 m_graphicsGrid->SetCellValue( i, COL_TEXT_ITALIC, aCfg->m_DesignSettings.m_TextItalic[ i ] ? wxT( "1" ) : wxT( "" ) );
251
252 auto attr = new wxGridCellAttr;
253 attr->SetRenderer( new wxGridCellBoolRenderer() );
254 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
255 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
256 m_graphicsGrid->SetAttr( i, COL_TEXT_ITALIC, attr );
257 }
258 }
259
260 // Footprint defaults
261 m_textItemsGrid->GetTable()->DeleteRows( 0, m_textItemsGrid->GetNumberRows() );
262 m_textItemsGrid->GetTable()->AppendRows( aCfg->m_DesignSettings.m_DefaultFPTextItems.size() );
263
264 for( size_t i = 0; i < aCfg->m_DesignSettings.m_DefaultFPTextItems.size(); ++i )
265 {
267
268 m_textItemsGrid->GetTable()->SetValue( i, 0, item.m_Text );
269 m_textItemsGrid->GetTable()->SetValueAsBool( i, 1, item.m_Visible );
270 m_textItemsGrid->GetTable()->SetValueAsLong( i, 2, item.m_Layer );
271 }
272
273 for( int col = 0; col < m_graphicsGrid->GetNumberCols(); col++ )
274 {
275 // Set the minimal width to the column label size.
276 m_graphicsGrid->SetColMinimalWidth( col, m_graphicsGrid->GetVisibleWidth( col, true, false ) );
277
278 // Set the width to see the full contents
279 if( m_graphicsGrid->IsColShown( col ) )
280 m_graphicsGrid->SetColSize( col, m_graphicsGrid->GetVisibleWidth( col, true, true, true ) );
281 }
282
283 m_graphicsGrid->SetRowLabelSize( m_graphicsGrid->GetVisibleWidth( -1, true, true, true ) );
284
285 Layout();
286}
287
288
290{
291 SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
293
294 loadFPSettings( cfg );
295
296 return true;
297}
298
299
301{
302 bool retVal = wxPanel::Show( aShow );
303
304 if( aShow )
305 {
306 // These *should* work in the constructor, and indeed they do if this panel is the
307 // first displayed. However, on OSX 3.0.5 (at least), if another panel is displayed
308 // first then the icons will be blank unless they're set here.
311 }
312
313 if( aShow && m_firstShow )
314 {
315 m_graphicsGrid->SetColSize( 0, m_graphicsGrid->GetColSize( 0 ) + 1 );
316 m_firstShow = false;
317 }
318
319 return retVal;
320}
321
322
324{
326 return false;
327
328 // Test text parameters.
329 for( int row : { ROW_SILK, ROW_COPPER, ROW_FAB, ROW_OTHERS } )
330 {
331 int textSize = std::min( m_graphicsGrid->GetUnitValue( row, COL_TEXT_WIDTH ),
333
334 if( m_graphicsGrid->GetUnitValue( row, COL_TEXT_THICKNESS ) > textSize / 4 )
335 {
336 wxString msg = _( "Text will not be readable with a thickness greater than\n"
337 "1/4 its width or height." );
339 return false;
340 }
341 }
342
343 return true;
344}
345
346
348{
349 if( !validateData() )
350 return false;
351
352 SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
353 BOARD_DESIGN_SETTINGS& cfg = mgr.GetAppSettings<FOOTPRINT_EDITOR_SETTINGS>()->m_DesignSettings;
354
355 for( int i = 0; i < ROW_COUNT; ++i )
356 {
358
359 if( i == ROW_EDGES || i == ROW_COURTYARD )
360 continue;
361
365
366 wxString msg = m_graphicsGrid->GetCellValue( i, COL_TEXT_ITALIC );
367 cfg.m_TextItalic[ i ] = wxGridCellBoolEditor::IsTrueValue( msg );
368 }
369
370 // Footprint defaults
371 wxGridTableBase* table = m_textItemsGrid->GetTable();
372 cfg.m_DefaultFPTextItems.clear();
373
374 for( int i = 0; i < m_textItemsGrid->GetNumberRows(); ++i )
375 {
376 wxString text = table->GetValue( i, 0 );
377 bool visible = table->GetValueAsBool( i, 1 );
378 int layer = (int) table->GetValueAsLong( i, 2 );
379
380 cfg.m_DefaultFPTextItems.emplace_back( text, visible, layer );
381 }
382
383 return true;
384}
385
386
387void PANEL_FP_EDITOR_DEFAULTS::OnAddTextItem( wxCommandEvent& event )
388{
390 return;
391
392 wxGridTableBase* table = m_textItemsGrid->GetTable();
393
394 int newRow = m_textItemsGrid->GetNumberRows();
395 table->AppendRows( 1 );
396 table->SetValueAsBool( newRow, 1, table->GetValueAsBool( newRow - 1, 1 ) );
397 table->SetValueAsLong( newRow, 2, table->GetValueAsLong( newRow - 1, 2 ) );
398
399 m_textItemsGrid->MakeCellVisible( newRow, 0 );
400 m_textItemsGrid->SetGridCursor( newRow, 0 );
401
402 m_textItemsGrid->EnableCellEditControl( true );
403 m_textItemsGrid->ShowCellEditControl();
404}
405
406
408{
409 wxArrayInt selectedRows = m_textItemsGrid->GetSelectedRows();
410
411 if( selectedRows.empty() && m_textItemsGrid->GetGridCursorRow() >= 0 )
412 selectedRows.push_back( m_textItemsGrid->GetGridCursorRow() );
413
414 if( selectedRows.empty() )
415 return;
416
417 for( int row : selectedRows )
418 {
419 if( row < 2 )
420 {
421 DisplayError( nullptr, _( "Reference and value are mandatory." ) );
422 return;
423 }
424 }
425
427 return;
428
429 // Reverse sort so deleting a row doesn't change the indexes of the other rows.
430 selectedRows.Sort( []( int* first, int* second ) { return *second - *first; } );
431
432 for( int row : selectedRows )
433 {
434 m_textItemsGrid->GetTable()->DeleteRows( row, 1 );
435
436 if( m_textItemsGrid->GetNumberRows() > 0 )
437 {
438 m_textItemsGrid->MakeCellVisible( std::max( 0, row-1 ),
439 m_textItemsGrid->GetGridCursorCol() );
440 m_textItemsGrid->SetGridCursor( std::max( 0, row-1 ),
441 m_textItemsGrid->GetGridCursorCol() );
442 }
443 }
444}
445
446
448{
450 cfg.Load(); // Loading without a file will init to defaults
451
452 loadFPSettings( &cfg );
453}
454
455
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:106
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]
VECTOR2I 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,...
void SetBitmap(const wxBitmap &aBmp)
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:520
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:164
void SetUnitValue(int aRow, int aCol, int aValue)
Set a unitized cell's value.
Definition: wx_grid.cpp:502
int GetUnitValue(int aRow, int aCol)
Apply standard KiCad unit and eval services to a numeric cell.
Definition: wx_grid.cpp:481
void SetAutoEvalCols(const std::vector< int > &aCols)
Definition: wx_grid.h:96
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:472
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:423
void DisplayError(wxWindow *aParent, const wxString &aText, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:300
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:156
see class PGM_BASE
KIWAY Kiway & Pgm(), KFCTL_STANDALONE
The global Program "get" accessor.
Definition: single_top.cpp:111
VECTOR2< int > VECTOR2I
Definition: vector2d.h:590