KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_setup_text_and_graphics.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) 2018-2023 KiCad Developers, see change_log.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 <pcb_edit_frame.h>
26#include <widgets/wx_grid.h>
27#include <grid_tricks.h>
28#include <eda_text.h>
30
31#include <wx/treebook.h>
32#include <confirm.h>
33
34
35// Columns of layer classes grid
36enum
37{
44};
45
46enum
47{
54
56};
57
58
60 PCB_EDIT_FRAME* aFrame ) :
62 m_arrowLength( aFrame, m_lblArrowLength, m_dimensionArrowLength, m_arrowLengthUnits ),
63 m_extensionOffset( aFrame, m_lblExtensionOffset, m_dimensionExtensionOffset,
64 m_dimensionExtensionOffsetUnits )
65{
66 m_Frame = aFrame;
68
74 m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + FromDIP( 4 ) );
75 m_grid->SetUseNativeColLabels();
76
77 // Work around a bug in wxWidgets where it fails to recalculate the grid height
78 // after changing the default row size
79 m_grid->AppendRows( 1 );
80 m_grid->DeleteRows( m_grid->GetNumberRows() - 1, 1 );
81
82 // Gives a suitable size to m_grid columns
83 // The default wxWidget col size is not very good
84 // Calculate a min best size to handle longest usual numeric values:
85 int min_best_width = m_grid->GetTextExtent( wxT( "555,555555 mils" ) ).x;
86
87 for( int i = 0; i < m_grid->GetNumberCols(); ++i )
88 {
89 // We calculate the column min size only from texts sizes, not using the initial col width
90 // as this initial width is sometimes strange depending on the language (wxGrid bug?)
91 int min_width = m_grid->GetVisibleWidth( i );
92
93 m_grid->SetColMinimalWidth( i, min_width );
94
95 // We use a "best size" >= min_best_width
96 m_grid->SetColSize( i, std::max( min_width, min_best_width ) );
97 }
98
99 m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
100
101 m_Frame->Bind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_TEXT_AND_GRAPHICS::onUnitsChanged, this );
102}
103
104
106{
107 // destroy GRID_TRICKS before m_grid.
108 m_grid->PopEventHandler( true );
109
110 m_Frame->Unbind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_TEXT_AND_GRAPHICS::onUnitsChanged, this );
111}
112
113
115{
116 BOARD_DESIGN_SETTINGS tempBDS( nullptr, "dummy" );
118
119 m_BrdSettings = &tempBDS; // No, address of stack var does not escape function
120
123
124 m_BrdSettings = saveBDS;
125
126 aEvent.Skip();
127}
128
129
131{
132 wxColour disabledColour = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK );
133
134#define SET_MILS_CELL( row, col, val ) \
135 m_grid->SetCellValue( row, col, m_Frame->StringFromValue( val, true ) )
136
137#define DISABLE_CELL( row, col ) \
138 m_grid->SetReadOnly( row, col ); m_grid->SetCellBackgroundColour( row, col, disabledColour );
139
140 for( int i = 0; i < ROW_COUNT; ++i )
141 {
143
144 if( i == ROW_EDGES || i == ROW_COURTYARD )
145 {
151 }
152 else
153 {
157 m_grid->SetCellValue( i, COL_TEXT_ITALIC,
158 m_BrdSettings->m_TextItalic[ i ] ? wxT( "1" ) : wxT( "" ) );
159 m_grid->SetCellValue( i, COL_TEXT_UPRIGHT,
160 m_BrdSettings->m_TextUpright[ i ] ? wxT( "1" ) : wxT( "" ) );
161
162 auto attr = new wxGridCellAttr;
163 attr->SetRenderer( new wxGridCellBoolRenderer() );
164 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
165 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
166 m_grid->SetAttr( i, COL_TEXT_ITALIC, attr );
167
168 attr = new wxGridCellAttr;
169 attr->SetRenderer( new wxGridCellBoolRenderer() );
170 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
171 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
172 m_grid->SetAttr( i, COL_TEXT_UPRIGHT, attr );
173 }
174 }
175
176 // Work around an issue where wxWidgets doesn't calculate the row width on its own
177 for( int col = 0; col < m_grid->GetNumberCols(); col++ )
178 m_grid->SetColMinimalWidth( col, m_grid->GetVisibleWidth( col ) );
179
180 m_grid->SetRowLabelSize( m_grid->GetVisibleWidth( -1, true, true, true ) );
181
182 Layout();
183
184 m_dimensionUnits->SetSelection( static_cast<int>( m_BrdSettings->m_DimensionUnitsMode ) );
185 m_dimensionUnitsFormat->SetSelection( static_cast<int>( m_BrdSettings->m_DimensionUnitsFormat ) );
186 m_dimensionPrecision->SetSelection( static_cast<int>( m_BrdSettings->m_DimensionPrecision ) );
188
189 int position = static_cast<int>( m_BrdSettings->m_DimensionTextPosition );
190 m_dimensionTextPositionMode->SetSelection( position );
191
195
196 return true;
197}
198
199
201{
203 return false;
204
205 // A minimal value for sizes and thickness
206 const int minWidth = pcbIUScale.mmToIU( MINIMUM_LINE_WIDTH_MM );
207 const int maxWidth = pcbIUScale.mmToIU( MAXIMUM_LINE_WIDTH_MM );
209 const int maxSize = pcbIUScale.mmToIU( TEXT_MAX_SIZE_MM );
210 wxString errorsMsg;
211 UNITS_PROVIDER* unitProvider = m_Frame;
212
213 for( int i = 0; i < ROW_COUNT; ++i )
214 {
215 bool badParam = false;
216
217 int lineWidth = m_grid->GetUnitValue( i, COL_LINE_THICKNESS );
218
219 if( lineWidth < minWidth || lineWidth > maxWidth )
220 {
221 if( !errorsMsg.IsEmpty() )
222 errorsMsg += wxT( "\n\n" );
223
224 errorsMsg += wxString::Format( _( "%s: Incorrect line width.\n"
225 "It must be between %s and %s" ),
226 m_grid->GetRowLabelValue( i ),
227 unitProvider->StringFromValue( minWidth , true),
228 unitProvider->StringFromValue( maxWidth , true) );
229 badParam = true;
230 }
231
232 if( !badParam )
233 m_BrdSettings->m_LineThickness[ i ] = lineWidth;
234
235 if( i == ROW_EDGES || i == ROW_COURTYARD )
236 continue;
237
238 badParam = false;
239 int textWidth = m_grid->GetUnitValue( i, COL_TEXT_WIDTH );
240 int textHeight = m_grid->GetUnitValue( i, COL_TEXT_HEIGHT );
241 int textThickness = m_grid->GetUnitValue( i, COL_TEXT_THICKNESS );
242
243 if( textWidth < minSize || textHeight < minSize
244 || textWidth > maxSize || textHeight > maxSize )
245 {
246 if( !errorsMsg.IsEmpty() )
247 errorsMsg += wxT( "\n\n" );
248
249 errorsMsg += wxString::Format( _( "%s: Text size is incorrect.\n"
250 "Size must be between %s and %s" ),
251 m_grid->GetRowLabelValue( i ),
252 unitProvider->StringFromValue( minSize , true),
253 unitProvider->StringFromValue( maxSize , true) );
254 badParam = true;
255 }
256
257 // Text thickness cannot be > text size /4 to be readable
258 int textMaxThickness = std::min( maxWidth, std::min( textWidth, textHeight ) /4);
259
260 if( !badParam && ( textThickness < minWidth || textThickness > textMaxThickness ) )
261 {
262 if( !errorsMsg.IsEmpty() )
263 errorsMsg += wxT( "\n\n" );
264
265
266 if( textThickness > textMaxThickness )
267 errorsMsg += wxString::Format( _( "%s: Text thickness is too large.\n"
268 "It will be truncated to %s" ),
269 m_grid->GetRowLabelValue( i ),
270 unitProvider->StringFromValue( textMaxThickness , true) );
271
272 else if( textThickness < minWidth )
273 errorsMsg += wxString::Format( _( "%s: Text thickness is too small.\n"
274 "It will be truncated to %s" ),
275 m_grid->GetRowLabelValue( i ),
276 unitProvider->StringFromValue( minWidth , true ) );
277
278 textThickness = std::min( textThickness, textMaxThickness );
279 textThickness = std::max( textThickness, minWidth );
280 SET_MILS_CELL( i, COL_TEXT_THICKNESS, textThickness );
281 }
282
283 if( !badParam )
284 {
285 m_BrdSettings->m_TextSize[ i ] = VECTOR2I( textWidth, textHeight );
286 m_BrdSettings->m_TextThickness[ i ] = textThickness;
287 }
288
290 wxGridCellBoolEditor::IsTrueValue( m_grid->GetCellValue( i, COL_TEXT_ITALIC ) );
292 wxGridCellBoolEditor::IsTrueValue( m_grid->GetCellValue( i, COL_TEXT_UPRIGHT ) );
293 }
294
295 // These are all stored in project file, not board, so no need for OnModify()
296
297 int mode = m_dimensionUnits->GetSelection();
298 m_BrdSettings->m_DimensionUnitsMode = static_cast<DIM_UNITS_MODE>( mode );
299 int format = m_dimensionUnitsFormat->GetSelection();
300 m_BrdSettings->m_DimensionUnitsFormat = static_cast<DIM_UNITS_FORMAT>( format );
301 int precision = m_dimensionPrecision->GetSelection();
302 m_BrdSettings->m_DimensionPrecision = static_cast<DIM_PRECISION>( precision );
304 int position = m_dimensionTextPositionMode->GetSelection();
305 m_BrdSettings->m_DimensionTextPosition = static_cast<DIM_TEXT_POSITION>( position );
309
310
311 if( errorsMsg.IsEmpty() )
312 return true;
313
314 KIDIALOG dlg( wxGetTopLevelParent( this ), errorsMsg, KIDIALOG::KD_ERROR,
315 _( "Parameter error" ) );
316 dlg.ShowModal();
317
318 return false;
319}
320
321
323{
325 return;
326
327 BOARD_DESIGN_SETTINGS* savedSettings = m_BrdSettings;
328
329 m_BrdSettings = &aBoard->GetDesignSettings();
331
332 m_BrdSettings = savedSettings;
333}
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
#define MINIMUM_LINE_WIDTH_MM
#define MAXIMUM_LINE_WIDTH_MM
Container for design settings for a BOARD object.
DIM_PRECISION m_DimensionPrecision
Number of digits after the decimal.
DIM_UNITS_FORMAT m_DimensionUnitsFormat
bool m_TextUpright[LAYER_CLASS_COUNT]
int m_TextThickness[LAYER_CLASS_COUNT]
int m_LineThickness[LAYER_CLASS_COUNT]
VECTOR2I m_TextSize[LAYER_CLASS_COUNT]
bool m_TextItalic[LAYER_CLASS_COUNT]
DIM_TEXT_POSITION m_DimensionTextPosition
DIM_UNITS_MODE m_DimensionUnitsMode
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:281
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:797
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
Definition: grid_tricks.h:61
Helper class to create more flexible dialogs, including 'do not show again' checkbox handling.
Definition: confirm.h:47
@ KD_ERROR
Definition: confirm.h:50
int ShowModal() override
Definition: confirm.cpp:100
Class PANEL_SETUP_TEXT_AND_GRAPHICS_BASE.
PANEL_SETUP_TEXT_AND_GRAPHICS(wxWindow *aParentWindow, PCB_EDIT_FRAME *aFrame)
void onUnitsChanged(wxCommandEvent &aEvent)
BOARD * GetBoard() const
The main frame for Pcbnew.
wxString StringFromValue(double aValue, bool aAddUnitLabel=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
Converts aValue in internal units into a united string.
virtual long long int GetValue()
Return the current value in Internal Units.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
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:655
int GetUnitValue(int aRow, int aCol)
Apply standard KiCad unit and eval services to a numeric cell.
Definition: wx_grid.cpp:616
void SetAutoEvalCols(const std::vector< int > &aCols)
Definition: wx_grid.h:114
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:607
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:558
This file is part of the common library.
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
#define TEXT_MIN_SIZE_MM
Minimum text size (1 micron).
Definition: eda_text.h:45
#define TEXT_MAX_SIZE_MM
Maximum text size in mm (~10 inches)
Definition: eda_text.h:46
#define SET_MILS_CELL(row, col, val)
#define DISABLE_CELL(row, col)
DIM_TEXT_POSITION
Where to place the text on a dimension.
Definition: pcb_dimension.h:62
DIM_UNITS_FORMAT
How to display the units in a dimension's text.
Definition: pcb_dimension.h:40
DIM_UNITS_MODE
Used for storing the units selection in the file because EDA_UNITS alone doesn't cut it.
Definition: pcb_dimension.h:72
DIM_PRECISION
Definition: pcb_dimension.h:47
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588