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 <grid_tricks.h>
27#include <eda_text.h>
29#include <kidialog.h>
30
31
32// Columns of layer classes grid
33enum
34{
41};
42
43enum
44{
51
53};
54
55
57 PCB_EDIT_FRAME* aFrame ) :
59 m_arrowLength( aFrame, m_lblArrowLength, m_dimensionArrowLength, m_arrowLengthUnits ),
60 m_extensionOffset( aFrame, m_lblExtensionOffset, m_dimensionExtensionOffset,
61 m_dimensionExtensionOffsetUnits )
62{
63 m_Frame = aFrame;
65
71 m_grid->SetDefaultRowSize( m_grid->GetDefaultRowSize() + FromDIP( 4 ) );
72 m_grid->SetUseNativeColLabels();
73
74 // Work around a bug in wxWidgets where it fails to recalculate the grid height
75 // after changing the default row size
76 m_grid->AppendRows( 1 );
77 m_grid->DeleteRows( m_grid->GetNumberRows() - 1, 1 );
78
79 // Gives a suitable size to m_grid columns
80 // The default wxWidget col size is not very good
81 // Calculate a min best size to handle longest usual numeric values:
82 int min_best_width = m_grid->GetTextExtent( wxT( "555,555555 mils" ) ).x;
83
84 for( int i = 0; i < m_grid->GetNumberCols(); ++i )
85 {
86 // We calculate the column min size only from texts sizes, not using the initial col width
87 // as this initial width is sometimes strange depending on the language (wxGrid bug?)
88 int min_width = m_grid->GetVisibleWidth( i );
89
90 m_grid->SetColMinimalWidth( i, min_width );
91
92 // We use a "best size" >= min_best_width
93 m_grid->SetColSize( i, std::max( min_width, min_best_width ) );
94 }
95
96 m_grid->PushEventHandler( new GRID_TRICKS( m_grid ) );
97
98 m_Frame->Bind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_TEXT_AND_GRAPHICS::onUnitsChanged, this );
99}
100
101
103{
104 // destroy GRID_TRICKS before m_grid.
105 m_grid->PopEventHandler( true );
106
107 m_Frame->Unbind( EDA_EVT_UNITS_CHANGED, &PANEL_SETUP_TEXT_AND_GRAPHICS::onUnitsChanged, this );
108}
109
110
112{
113 BOARD_DESIGN_SETTINGS tempBDS( nullptr, "dummy" );
115
116 m_BrdSettings = &tempBDS; // No, address of stack var does not escape function
117
120
121 m_BrdSettings = saveBDS;
122
123 aEvent.Skip();
124}
125
126
128{
129 wxColour disabledColour = wxSystemSettings::GetColour( wxSYS_COLOUR_FRAMEBK );
130
131#define SET_MILS_CELL( row, col, val ) \
132 m_grid->SetCellValue( row, col, m_Frame->StringFromValue( val, true ) )
133
134#define DISABLE_CELL( row, col ) \
135 m_grid->SetReadOnly( row, col ); m_grid->SetCellBackgroundColour( row, col, disabledColour );
136
137 for( int i = 0; i < ROW_COUNT; ++i )
138 {
140
141 if( i == ROW_EDGES || i == ROW_COURTYARD )
142 {
148 }
149 else
150 {
154 m_grid->SetCellValue( i, COL_TEXT_ITALIC,
155 m_BrdSettings->m_TextItalic[ i ] ? wxT( "1" ) : wxT( "" ) );
156 m_grid->SetCellValue( i, COL_TEXT_UPRIGHT,
157 m_BrdSettings->m_TextUpright[ i ] ? wxT( "1" ) : wxT( "" ) );
158
159 auto attr = new wxGridCellAttr;
160 attr->SetRenderer( new wxGridCellBoolRenderer() );
161 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
162 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
163 m_grid->SetAttr( i, COL_TEXT_ITALIC, attr );
164
165 attr = new wxGridCellAttr;
166 attr->SetRenderer( new wxGridCellBoolRenderer() );
167 attr->SetReadOnly(); // not really; we delegate interactivity to GRID_TRICKS
168 attr->SetAlignment( wxALIGN_CENTER, wxALIGN_CENTER );
169 m_grid->SetAttr( i, COL_TEXT_UPRIGHT, attr );
170 }
171 }
172
173 // Work around an issue where wxWidgets doesn't calculate the row width on its own
174 for( int col = 0; col < m_grid->GetNumberCols(); col++ )
175 m_grid->SetColMinimalWidth( col, m_grid->GetVisibleWidth( col ) );
176
177 m_grid->SetRowLabelSize( m_grid->GetVisibleWidth( -1, true, true, true ) );
178
179 Layout();
180
181 m_dimensionUnits->SetSelection( static_cast<int>( m_BrdSettings->m_DimensionUnitsMode ) );
182 m_dimensionUnitsFormat->SetSelection( static_cast<int>( m_BrdSettings->m_DimensionUnitsFormat ) );
183 m_dimensionPrecision->SetSelection( static_cast<int>( m_BrdSettings->m_DimensionPrecision ) );
185
186 int position = static_cast<int>( m_BrdSettings->m_DimensionTextPosition );
187 m_dimensionTextPositionMode->SetSelection( position );
188
192
193 return true;
194}
195
196
198{
200 return false;
201
202 // A minimal value for sizes and thickness
203 const int minWidth = pcbIUScale.mmToIU( MINIMUM_LINE_WIDTH_MM );
204 const int maxWidth = pcbIUScale.mmToIU( MAXIMUM_LINE_WIDTH_MM );
206 const int maxSize = pcbIUScale.mmToIU( TEXT_MAX_SIZE_MM );
207 wxString errorsMsg;
208 UNITS_PROVIDER* unitProvider = m_Frame;
209
210 for( int i = 0; i < ROW_COUNT; ++i )
211 {
212 bool badParam = false;
213
214 int lineWidth = m_grid->GetUnitValue( i, COL_LINE_THICKNESS );
215
216 if( lineWidth < minWidth || lineWidth > maxWidth )
217 {
218 if( !errorsMsg.IsEmpty() )
219 errorsMsg += wxT( "\n\n" );
220
221 errorsMsg += wxString::Format( _( "%s: Incorrect line width.\n"
222 "It must be between %s and %s" ),
223 m_grid->GetRowLabelValue( i ),
224 unitProvider->StringFromValue( minWidth , true),
225 unitProvider->StringFromValue( maxWidth , true) );
226 badParam = true;
227 }
228
229 if( !badParam )
230 m_BrdSettings->m_LineThickness[ i ] = lineWidth;
231
232 if( i == ROW_EDGES || i == ROW_COURTYARD )
233 continue;
234
235 badParam = false;
236 int textWidth = m_grid->GetUnitValue( i, COL_TEXT_WIDTH );
237 int textHeight = m_grid->GetUnitValue( i, COL_TEXT_HEIGHT );
238 int textThickness = m_grid->GetUnitValue( i, COL_TEXT_THICKNESS );
239
240 if( textWidth < minSize || textHeight < minSize
241 || textWidth > maxSize || textHeight > maxSize )
242 {
243 if( !errorsMsg.IsEmpty() )
244 errorsMsg += wxT( "\n\n" );
245
246 errorsMsg += wxString::Format( _( "%s: Text size is incorrect.\n"
247 "Size must be between %s and %s" ),
248 m_grid->GetRowLabelValue( i ),
249 unitProvider->StringFromValue( minSize , true),
250 unitProvider->StringFromValue( maxSize , true) );
251 badParam = true;
252 }
253
254 // Text thickness cannot be > text size /4 to be readable
255 int textMaxThickness = std::min( maxWidth, std::min( textWidth, textHeight ) /4);
256
257 if( !badParam && ( textThickness < minWidth || textThickness > textMaxThickness ) )
258 {
259 if( !errorsMsg.IsEmpty() )
260 errorsMsg += wxT( "\n\n" );
261
262
263 if( textThickness > textMaxThickness )
264 errorsMsg += wxString::Format( _( "%s: Text thickness is too large.\n"
265 "It will be truncated to %s" ),
266 m_grid->GetRowLabelValue( i ),
267 unitProvider->StringFromValue( textMaxThickness , true) );
268
269 else if( textThickness < minWidth )
270 errorsMsg += wxString::Format( _( "%s: Text thickness is too small.\n"
271 "It will be truncated to %s" ),
272 m_grid->GetRowLabelValue( i ),
273 unitProvider->StringFromValue( minWidth , true ) );
274
275 textThickness = std::min( textThickness, textMaxThickness );
276 textThickness = std::max( textThickness, minWidth );
277 SET_MILS_CELL( i, COL_TEXT_THICKNESS, textThickness );
278 }
279
280 if( !badParam )
281 {
282 m_BrdSettings->m_TextSize[ i ] = VECTOR2I( textWidth, textHeight );
283 m_BrdSettings->m_TextThickness[ i ] = textThickness;
284 }
285
287 wxGridCellBoolEditor::IsTrueValue( m_grid->GetCellValue( i, COL_TEXT_ITALIC ) );
289 wxGridCellBoolEditor::IsTrueValue( m_grid->GetCellValue( i, COL_TEXT_UPRIGHT ) );
290 }
291
292 // These are all stored in project file, not board, so no need for OnModify()
293
294 int mode = m_dimensionUnits->GetSelection();
295 m_BrdSettings->m_DimensionUnitsMode = static_cast<DIM_UNITS_MODE>( mode );
296 int format = m_dimensionUnitsFormat->GetSelection();
297 m_BrdSettings->m_DimensionUnitsFormat = static_cast<DIM_UNITS_FORMAT>( format );
298 int precision = m_dimensionPrecision->GetSelection();
299 m_BrdSettings->m_DimensionPrecision = static_cast<DIM_PRECISION>( precision );
301 int position = m_dimensionTextPositionMode->GetSelection();
302 m_BrdSettings->m_DimensionTextPosition = static_cast<DIM_TEXT_POSITION>( position );
306
307
308 if( errorsMsg.IsEmpty() )
309 return true;
310
311 KIDIALOG dlg( wxGetTopLevelParent( this ), errorsMsg, KIDIALOG::KD_ERROR,
312 _( "Parameter error" ) );
313 dlg.ShowModal();
314
315 return false;
316}
317
318
320{
322 return;
323
324 BOARD_DESIGN_SETTINGS* savedSettings = m_BrdSettings;
325
326 m_BrdSettings = &aBoard->GetDesignSettings();
328
329 m_BrdSettings = savedSettings;
330}
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:282
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.cpp:794
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: kidialog.h:43
@ KD_ERROR
Definition: kidialog.h:46
int ShowModal() override
Definition: kidialog.cpp:95
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:691
int GetUnitValue(int aRow, int aCol)
Apply standard KiCad unit and eval services to a numeric cell.
Definition: wx_grid.cpp:652
void SetAutoEvalCols(const std::vector< int > &aCols)
Definition: wx_grid.h:122
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:643
bool CommitPendingChanges(bool aQuietMode=false)
Close any open cell edit controls.
Definition: wx_grid.cpp:594
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
This file is part of the common library.
#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< int32_t > VECTOR2I
Definition: vector2d.h:638