KiCad PCB EDA Suite
Loading...
Searching...
No Matches
dialog_dimension_properties.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) 2020 Jon Evans <[email protected]>
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software: you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation, either version 3 of the License, or (at your
10 * option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
22#include <widgets/font_choice.h>
23#include <board.h>
24#include <board_commit.h>
25#include <pcb_dimension.h>
26#include <pcb_base_edit_frame.h>
28#include <widgets/unit_binder.h>
29#include <wx/msgdlg.h>
30
32
33
34
36 BOARD_ITEM* aItem ) :
38 m_frame( aParent ),
51{
52 wxASSERT( BaseType( aItem->Type() ) == PCB_DIMENSION_T );
53 m_dimension = static_cast<PCB_DIMENSION_BASE*>( aItem );
54 m_previewDimension = static_cast<PCB_DIMENSION_BASE*>( m_dimension->Clone() );
55 m_previewDimension->SetParent( m_frame->GetBoard() );
56
57 switch( m_dimension->Type() )
58 {
60 // Hide the main format controls and keep the leader controls shown
61 m_sizerFormat->GetStaticBox()->Hide();
62 m_sizerCenter->GetStaticBox()->Hide();
63
66
67 // Remove a fewings from text format
70 break;
71
73 m_sizerLeader->GetStaticBox()->Hide();
74 m_sizerFormat->GetStaticBox()->Hide();
75 m_sizerText->GetStaticBox()->Hide();
76
77 m_lblArrowLength->Hide();
78 m_txtArrowLength->Hide();
80
84
86 break;
87
88 default:
89 m_sizerLeader->GetStaticBox()->Hide();
90 m_sizerCenter->GetStaticBox()->Hide();
91 break;
92 }
93
94 m_separator0->SetIsSeparator();
95
96 m_bold->SetIsCheckButton();
98 m_italic->SetIsCheckButton();
100
101 m_separator1->SetIsSeparator();
102
103 m_alignLeft->SetIsRadioButton();
105 m_alignCenter->SetIsRadioButton();
107 m_alignRight->SetIsRadioButton();
109
110 m_separator2->SetIsSeparator();
111
112 m_mirrored->SetIsCheckButton();
114
115 m_separator3->SetIsSeparator();
116
117 // Fix the size after hiding/showing some of the properties
118 Layout();
119
120 // Configure display origin transforms
123
124 // Configure the layers list selector. Note that footprints are built outside the current
125 // board and so we may need to show all layers if the text is on an unactivated layer.
126 if( !m_frame->GetBoard()->IsLayerEnabled( m_dimension->GetLayer() ) )
127 m_cbLayerActual->ShowNonActivatedLayers( true );
128
129 m_cbLayerActual->SetLayersHotkeys( false );
130 m_cbLayerActual->SetBoardFrame( aParent );
131 m_cbLayerActual->Resync();
132
134 m_orientation.SetPrecision( 3 );
135
136 // Set predefined rotations in combo dropdown, according to the locale floating point
137 // separator notation
138 double rot_list[] = { 0.0, 90.0, -90.0, 180.0 };
139
140 for( size_t ii = 0; ii < m_cbTextOrientation->GetCount() && ii < 4; ++ii )
141 m_cbTextOrientation->SetString( ii, wxString::Format( "%.1f", rot_list[ii] ) );
142
143 m_cbOverrideValue->Bind( wxEVT_CHECKBOX,
144 [&]( wxCommandEvent& evt )
145 {
146 m_txtValue->Enable( m_cbOverrideValue->GetValue() );
147
148 if( !m_cbOverrideValue->GetValue() )
149 m_txtValue->SetValue( m_dimension->GetValueText() );
150 } );
151
152 auto updateEventHandler =
153 [&]( wxCommandEvent& evt )
154 {
155 if( !m_cbOverrideValue->GetValue() )
156 m_txtValue->ChangeValue( m_dimension->GetValueText() );
157
159 };
160
161 // No need to use m_txtValueActual here since we don't have previewing for leaders
162 m_txtValue->Bind( wxEVT_TEXT, updateEventHandler );
163 m_txtPrefix->Bind( wxEVT_TEXT, updateEventHandler );
164 m_txtSuffix->Bind( wxEVT_TEXT, updateEventHandler );
165
166 m_cbUnits->Bind( wxEVT_CHOICE, updateEventHandler );
167 m_cbUnitsFormat->Bind( wxEVT_CHOICE, updateEventHandler );
168 m_cbPrecision->Bind( wxEVT_CHOICE, updateEventHandler );
169 m_cbSuppressZeroes->Bind( wxEVT_CHECKBOX, updateEventHandler );
170
171 m_cbTextPositionMode->Bind( wxEVT_CHOICE,
172 [&]( wxCommandEvent& aEvt )
173 {
174 // manual mode
175 bool allowPositioning = ( m_cbTextPositionMode->GetSelection() == 2 );
176
177 m_txtTextPosX->Enable( allowPositioning );
178 m_txtTextPosY->Enable( allowPositioning );
179 } );
180
181 m_cbKeepAligned->Bind( wxEVT_CHECKBOX,
182 [&]( wxCommandEvent& aEvt )
183 {
184 m_cbTextOrientation->Enable( !m_cbKeepAligned->GetValue() );
185 } );
186
188
190}
191
192
197
198
200{
201 BOARD* board = m_frame->GetBoard();
202
203 m_txtValue->Enable( m_dimension->GetOverrideTextEnabled() );
204 m_cbOverrideValue->SetValue( m_dimension->GetOverrideTextEnabled() );
205
206 switch( m_dimension->GetUnitsMode() )
207 {
208 case DIM_UNITS_MODE::INCH: m_cbUnits->SetSelection( 0 ); break;
209 case DIM_UNITS_MODE::MILS: m_cbUnits->SetSelection( 1 ); break;
210 case DIM_UNITS_MODE::MM: m_cbUnits->SetSelection( 2 ); break;
211 case DIM_UNITS_MODE::AUTOMATIC: m_cbUnits->SetSelection( 3 ); break;
212 }
213
214 switch ( m_dimension->GetArrowDirection() )
215 {
216 case DIM_ARROW_DIRECTION::INWARD: m_cbArrowDirection->SetSelection( 0 ); break;
217 case DIM_ARROW_DIRECTION::OUTWARD: m_cbArrowDirection->SetSelection( 1 ); break;
218 }
219
220 m_cbUnitsFormat->SetSelection( static_cast<int>( m_dimension->GetUnitsFormat() ) );
221 m_cbPrecision->SetSelection( static_cast<int>( m_dimension->GetPrecision() ) );
222
223 m_txtPrefix->SetValue( board->ConvertKIIDsToCrossReferences( m_dimension->GetPrefix() ) );
224 m_txtSuffix->SetValue( board->ConvertKIIDsToCrossReferences( m_dimension->GetSuffix() ) );
225
226 if( m_cbLayerActual->SetLayerSelection( m_dimension->GetLayer() ) < 0 )
227 {
228 wxMessageBox( _( "This item was on a non-existing layer.\n"
229 "It has been moved to the first defined layer." ) );
230 m_cbLayerActual->SetSelection( 0 );
231 }
232
233 m_cbSuppressZeroes->SetValue( m_dimension->GetSuppressZeroes() );
234
235 m_fontCtrl->SetFontSelection( m_dimension->GetFont() );
236
237 m_textWidth.SetValue( m_dimension->GetTextSize().x );
238 m_textHeight.SetValue( m_dimension->GetTextSize().y );
239 m_textThickness.SetValue( m_dimension->GetTextThickness() );
240
241 m_textPosX.SetValue( m_dimension->GetTextPos().x );
242 m_textPosY.SetValue( m_dimension->GetTextPos().y );
243 m_cbTextPositionMode->SetSelection( static_cast<int>( m_dimension->GetTextPositionMode() ) );
244
245 if( m_dimension->GetTextPositionMode() != DIM_TEXT_POSITION::MANUAL )
246 {
247 m_txtTextPosX->Disable();
248 m_txtTextPosY->Disable();
249 }
250
251 EDA_ANGLE orientation = m_dimension->GetTextAngle();
252 m_orientation.SetAngleValue( orientation.Normalize180() );
253 m_cbTextOrientation->Enable( !m_dimension->GetKeepTextAligned() );
254 m_cbKeepAligned->SetValue( m_dimension->GetKeepTextAligned() );
255
256 m_bold->Check( m_dimension->IsBold() );
257 m_italic->Check( m_dimension->IsItalic() );
258
259 switch ( m_dimension->GetHorizJustify() )
260 {
261 case GR_TEXT_H_ALIGN_LEFT: m_alignLeft->Check( true ); break;
262 case GR_TEXT_H_ALIGN_CENTER: m_alignCenter->Check( true ); break;
263 case GR_TEXT_H_ALIGN_RIGHT: m_alignRight->Check( true ); break;
265 }
266
267 m_mirrored->Check( m_dimension->IsMirrored() );
268
269 m_lineThickness.SetValue( m_dimension->GetLineThickness() );
270 m_arrowLength.SetValue( m_dimension->GetArrowLength() );
271 m_extensionOffset.SetValue( m_dimension->GetExtensionOffset() );
272
273 if( PCB_DIM_ALIGNED* aligned = dynamic_cast<PCB_DIM_ALIGNED*>( m_dimension ) )
274 m_extensionOvershoot.SetValue( aligned->GetExtensionHeight() );
275 else
276 m_extensionOvershoot.Show( false );
277
278 // Do this last; it depends on the other settings
279 if( m_dimension->GetOverrideTextEnabled() )
280 {
281 wxString txt = board->ConvertKIIDsToCrossReferences( m_dimension->GetOverrideText() );
282 m_txtValueActual->SetValue( txt );
283 }
284 else
285 {
286 m_txtValueActual->SetValue( m_dimension->GetValueText() );
287 }
288
289 if( PCB_DIM_LEADER* leader = static_cast<PCB_DIM_LEADER*>( m_dimension ) )
290 m_cbTextFrame->SetSelection( static_cast<int>( leader->GetTextBorder() ) );
291
292 return DIALOG_DIMENSION_PROPERTIES_BASE::TransferDataToWindow();
293}
294
295
297{
298 if( !DIALOG_DIMENSION_PROPERTIES_BASE::TransferDataFromWindow() )
299 return false;
300
301 BOARD_COMMIT commit( m_frame );
302 commit.Modify( m_dimension );
303
304 // If no other command in progress, prepare undo command
305 // (for a command in progress, will be made later, at the completion of command)
306 bool pushCommit = ( m_dimension->GetEditFlags() == 0 );
307
308 /* set flag in edit to force undo/redo/abort proper operation,
309 * and avoid new calls to SaveCopyInUndoList for the same dimension
310 * this can occurs when a dimension is moved, and then rotated, edited ..
311 */
312 if( !pushCommit )
313 m_dimension->SetFlags( IN_EDIT );
314
316
317 if( pushCommit )
318 commit.Push( _( "Edit Dimension Properties" ) );
319
320 return true;
321}
322
323
324void DIALOG_DIMENSION_PROPERTIES::onFontSelected( wxCommandEvent & aEvent )
325{
326 if( KIFONT::FONT::IsStroke( aEvent.GetString() ) )
327 {
328 m_textThickness.Show( true );
329
330 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
331 int thickness = m_textThickness.GetValue();
332
333 m_bold->Check( abs( thickness - GetPenSizeForBold( textSize ) )
334 < abs( thickness - GetPenSizeForNormal( textSize ) ) );
335 }
336 else
337 {
338 m_textThickness.Show( false );
339 }
340}
341
342
343void DIALOG_DIMENSION_PROPERTIES::onBoldToggle( wxCommandEvent & aEvent )
344{
345 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
346
347 if( aEvent.IsChecked() )
348 m_textThickness.ChangeValue( GetPenSizeForBold( textSize ) );
349 else
350 m_textThickness.ChangeValue( GetPenSizeForNormal( textSize ) );
351
352 aEvent.Skip();
353}
354
355
356void DIALOG_DIMENSION_PROPERTIES::onAlignButton( wxCommandEvent& aEvent )
357{
359 {
360 if( btn->IsChecked() && btn != aEvent.GetEventObject() )
361 btn->Check( false );
362 }
363}
364
365
366void DIALOG_DIMENSION_PROPERTIES::onThickness( wxCommandEvent& event )
367{
368 int textSize = std::min( m_textWidth.GetValue(), m_textHeight.GetValue() );
369 int thickness = m_textThickness.GetValue();
370
371 m_bold->Check( abs( thickness - GetPenSizeForBold( textSize ) )
372 < abs( thickness - GetPenSizeForNormal( textSize ) ) );
373}
374
375
377{
378 BOARD* board = m_frame->GetBoard();
379
380 aTarget->SetOverrideTextEnabled( m_cbOverrideValue->GetValue() );
381
382 if( m_cbOverrideValue->GetValue() )
383 {
384 wxString txt = board->ConvertCrossReferencesToKIIDs( m_txtValueActual->GetValue() );
385 aTarget->SetOverrideText( txt );
386 }
387
388 aTarget->SetPrefix( board->ConvertCrossReferencesToKIIDs( m_txtPrefix->GetValue() ) );
389 aTarget->SetSuffix( board->ConvertCrossReferencesToKIIDs( m_txtSuffix->GetValue() ) );
390 aTarget->SetLayer( static_cast<PCB_LAYER_ID>( m_cbLayerActual->GetLayerSelection() ) );
391
392 switch ( m_cbArrowDirection->GetSelection() ) {
393 case 0: aTarget->SetArrowDirection( DIM_ARROW_DIRECTION::INWARD ); break;
394 case 1: aTarget->SetArrowDirection( DIM_ARROW_DIRECTION::OUTWARD ); break;
395 }
396
397 switch( m_cbUnits->GetSelection() )
398 {
399 case 0: aTarget->SetUnitsMode( DIM_UNITS_MODE::INCH ); break;
400 case 1: aTarget->SetUnitsMode( DIM_UNITS_MODE::MILS ); break;
401 case 2: aTarget->SetUnitsMode( DIM_UNITS_MODE::MM ); break;
402 case 3: aTarget->SetUnitsMode( DIM_UNITS_MODE::AUTOMATIC ); break;
403 }
404
405 aTarget->SetUnitsFormat( static_cast<DIM_UNITS_FORMAT>( m_cbUnitsFormat->GetSelection() ) );
406 aTarget->SetPrecision( static_cast<DIM_PRECISION>( m_cbPrecision->GetSelection() ) );
407 aTarget->SetSuppressZeroes( m_cbSuppressZeroes->GetValue() );
408
409 DIM_TEXT_POSITION tpm = static_cast<DIM_TEXT_POSITION>( m_cbTextPositionMode->GetSelection() );
410 aTarget->SetTextPositionMode( tpm );
411
412 if( tpm == DIM_TEXT_POSITION::MANUAL )
413 {
414 VECTOR2I pos( m_textPosX.GetValue(), m_textPosY.GetValue() );
415 aTarget->SetTextPos( pos );
416 }
417
418 aTarget->SetKeepTextAligned( m_cbKeepAligned->GetValue() );
419
420 aTarget->SetTextAngle( m_orientation.GetAngleValue().Normalize() );
421 aTarget->SetTextWidth( m_textWidth.GetValue() );
422 aTarget->SetTextHeight( m_textHeight.GetValue() );
423 aTarget->SetTextThickness( m_textThickness.GetValue() );
424
425 if( m_fontCtrl->HaveFontSelection() )
426 aTarget->SetFont( m_fontCtrl->GetFontSelection( m_bold->IsChecked(), m_italic->IsChecked() ) );
427
428 // Must come after SetTextWidth/Height()
429 aTarget->SetBold( m_bold->IsChecked() );
430 aTarget->SetItalic( m_italic->IsChecked() );
431
432 if( m_alignLeft->IsChecked() )
434 else if( m_alignCenter->IsChecked() )
436 else
438
439 aTarget->SetMirrored( m_mirrored->IsChecked() );
440
441 aTarget->SetLineThickness( m_lineThickness.GetValue() );
442 aTarget->SetArrowLength( m_arrowLength.GetValue() );
443 aTarget->SetExtensionOffset( m_extensionOffset.GetValue() );
444
445 if( PCB_DIM_ALIGNED* aligned = dynamic_cast<PCB_DIM_ALIGNED*>( aTarget ) )
446 aligned->SetExtensionHeight( m_extensionOvershoot.GetValue() );
447
448 if( PCB_DIM_LEADER* leader = dynamic_cast<PCB_DIM_LEADER*>( aTarget ) )
449 leader->SetTextBorder( static_cast<DIM_TEXT_BORDER>( m_cbTextFrame->GetSelection()));
450
451 aTarget->Update();
452}
453
454
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
Definition bitmap.cpp:110
@ text_align_right
@ text_align_left
@ text_align_center
A bitmap button widget that behaves like an AUI toolbar item's button when it is drawn.
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:79
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Definition board_item.h:280
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:317
wxString ConvertCrossReferencesToKIIDs(const wxString &aSource) const
Convert cross-references back and forth between ${refDes:field} and ${kiid:field}.
Definition board.cpp:1771
wxString ConvertKIIDsToCrossReferences(const wxString &aSource) const
Definition board.cpp:1825
COMMIT & Modify(EDA_ITEM *aItem, BASE_SCREEN *aScreen=nullptr, RECURSE_MODE aRecurse=RECURSE_MODE::NO_RECURSE)
Modify a given item in the model.
Definition commit.h:106
DIALOG_DIMENSION_PROPERTIES_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxString &title=_("Dimension Properties"), const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(-1,-1), long style=wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxSYSTEM_MENU)
void onFontSelected(wxCommandEvent &aEvent) override
PCB_LAYER_BOX_SELECTOR * m_cbLayerActual
void onBoldToggle(wxCommandEvent &aEvent) override
void updateDimensionFromDialog(PCB_DIMENSION_BASE *aTarget)
DIALOG_DIMENSION_PROPERTIES(PCB_BASE_EDIT_FRAME *aParent, BOARD_ITEM *aItem)
void onAlignButton(wxCommandEvent &aEvent) override
void onThickness(wxCommandEvent &aEvent) override
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
EDA_ANGLE Normalize180()
Definition eda_angle.h:268
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:110
void SetTextPos(const VECTOR2I &aPoint)
Definition eda_text.cpp:579
void SetMirrored(bool isMirrored)
Definition eda_text.cpp:394
void SetTextWidth(int aWidth)
Definition eda_text.cpp:557
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
Definition eda_text.cpp:285
void SetTextHeight(int aHeight)
Definition eda_text.cpp:568
void SetBold(bool aBold)
Set the text to be bold - this will also update the font if needed.
Definition eda_text.cpp:336
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:300
void SetItalic(bool aItalic)
Set the text to be italic - this will also update the font if needed.
Definition eda_text.cpp:308
void SetFont(KIFONT::FONT *aFont)
Definition eda_text.cpp:500
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:410
virtual bool IsStroke() const
Definition font.h:138
Common, abstract interface for edit frames.
Abstract dimension API.
void Update()
Update the dimension's cached text and geometry.
void SetUnitsFormat(const DIM_UNITS_FORMAT aFormat)
void SetPrefix(const wxString &aPrefix)
void SetExtensionOffset(int aOffset)
void SetSuppressZeroes(bool aSuppress)
void SetOverrideTextEnabled(bool aOverride)
void SetSuffix(const wxString &aSuffix)
void SetTextPositionMode(DIM_TEXT_POSITION aMode)
void SetLineThickness(int aWidth)
void SetArrowLength(int aLength)
void SetPrecision(DIM_PRECISION aPrecision)
void SetArrowDirection(const DIM_ARROW_DIRECTION &aDirection)
void SetOverrideText(const wxString &aValue)
void SetUnitsMode(DIM_UNITS_MODE aMode)
void SetKeepTextAligned(bool aKeepAligned)
For better understanding of the points that make a dimension:
A leader is a dimension-like object pointing to a specific point.
#define _(s)
#define IN_EDIT
Item currently edited.
int GetPenSizeForBold(int aTextSize)
Definition gr_text.cpp:37
int GetPenSizeForNormal(int aTextSize)
Definition gr_text.cpp:61
PCB_LAYER_ID
A quick note on layer IDs:
Definition layer_ids.h:60
DIM_TEXT_POSITION
Where to place the text on a dimension.
@ MANUAL
Text placement is manually set by the user.
DIM_UNITS_FORMAT
How to display the units in a dimension's text.
DIM_TEXT_BORDER
Frame to show around dimension text.
DIM_PRECISION
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_H_ALIGN_INDETERMINATE
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition typeinfo.h:252
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition typeinfo.h:102
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition typeinfo.h:103
@ PCB_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition typeinfo.h:100
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695