KiCad PCB EDA Suite
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 <jon@craftyjon.com>
5  * Copyright (C) 2020 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 
21 #include <board.h>
22 #include <board_commit.h>
23 #include <pcb_dimension.h>
24 #include <pcb_base_edit_frame.h>
25 #include <pcb_layer_box_selector.h>
26 #include <widgets/unit_binder.h>
27 #include <wx/msgdlg.h>
28 
30 
31 
32 
34  BOARD_ITEM* aItem ) :
36  m_frame( aParent ),
37  m_cbLayerActual( m_cbLayer ),
38  m_txtValueActual( m_txtValue ),
39  m_textWidth( aParent, m_lblTextWidth, m_txtTextWidth, m_lblTextWidthUnits ),
40  m_textHeight( aParent, m_lblTextHeight, m_txtTextHeight, m_lblTextHeightUnits ),
41  m_textThickness( aParent, m_lblTextThickness, m_txtTextThickness, m_lblTextThicknessUnits ),
42  m_textPosX( aParent, m_lblTextPosX, m_txtTextPosX, m_lblTextPosXUnits ),
43  m_textPosY( aParent, m_lblTextPosY, m_txtTextPosY, m_lblTextPosYUnits ),
44  m_orientValidator( 1, &m_orientValue ),
45  m_lineThickness( aParent, m_lblLineThickness, m_txtLineThickness, m_lblLineThicknessUnits ),
46  m_arrowLength( aParent, m_lblArrowLength, m_txtArrowLength, m_lblArrowLengthUnits ),
47  m_extensionOffset( aParent, m_lblExtensionOffset, m_txtExtensionOffset, m_lblExtensionOffsetUnits )
48 {
49  wxASSERT( BaseType( aItem->Type() ) == PCB_DIMENSION_T );
50  m_dimension = static_cast<PCB_DIMENSION_BASE*>( aItem );
51  m_previewDimension = static_cast<PCB_DIMENSION_BASE*>( m_dimension->Clone() );
53 
54  switch( m_dimension->Type() )
55  {
56  case PCB_DIM_LEADER_T:
57  // Hide the main format controls and keep the leader controls shown
58  m_sizerFormat->GetStaticBox()->Hide();
59  m_sizerCenter->GetStaticBox()->Hide();
60 
63 
64  // Remove a fewings from text format
65  m_lblTextPositionMode->Hide();
66  m_cbTextPositionMode->Hide();
67  break;
68 
69  case PCB_DIM_CENTER_T:
70  m_sizerLeader->GetStaticBox()->Hide();
71  m_sizerFormat->GetStaticBox()->Hide();
72  m_sizerText->GetStaticBox()->Hide();
73 
74  m_lblArrowLength->Hide();
75  m_txtArrowLength->Hide();
76  m_lblArrowLengthUnits->Hide();
77 
78  m_lblExtensionOffset->Hide();
79  m_txtExtensionOffset->Hide();
81 
83  break;
84 
85  default:
86  m_sizerLeader->GetStaticBox()->Hide();
87  m_sizerCenter->GetStaticBox()->Hide();
88  break;
89  }
90 
91  // Fix the size after hiding/showing some of the properties
92  Layout();
93 
94  // Configure display origin transforms
97 
98  // Configure the layers list selector. Note that footprints are built outside the current
99  // board and so we may need to show all layers if the text is on an unactivated layer.
102 
104  m_cbLayerActual->SetBoardFrame( aParent );
106 
107  m_orientValue = 0.0;
108  m_orientValidator.SetRange( -360.0, 360.0 );
109  m_cbTextOrientation->SetValidator( m_orientValidator );
111 
112  // Handle decimal separators in combo dropdown
113  for( size_t i = 0; i < m_cbTextOrientation->GetCount(); ++i )
114  {
115  wxString item = m_cbTextOrientation->GetString( i );
116  item.Replace( '.', localeconv()->decimal_point[0] );
117  m_cbTextOrientation->SetString( i, item );
118  }
119 
120  m_sdbSizerOK->SetDefault();
121 
122  m_cbOverrideValue->Bind( wxEVT_CHECKBOX,
123  [&]( wxCommandEvent& evt )
124  {
125  m_txtValue->Enable( m_cbOverrideValue->GetValue() );
126 
127  if( !m_cbOverrideValue->GetValue() )
128  m_txtValue->SetValue( m_dimension->GetValueText() );
129  } );
130 
131  auto updateEventHandler =
132  [&]( wxCommandEvent& evt )
133  {
134  if( !m_cbOverrideValue->GetValue() )
135  m_txtValue->ChangeValue( m_dimension->GetValueText() );
136 
138  };
139 
140  // No need to use m_txtValueActual here since we don't have previewing for leaders
141  m_txtValue->Bind( wxEVT_TEXT, updateEventHandler );
142  m_txtPrefix->Bind( wxEVT_TEXT, updateEventHandler );
143  m_txtSuffix->Bind( wxEVT_TEXT, updateEventHandler );
144 
145  m_cbUnits->Bind( wxEVT_CHOICE, updateEventHandler );
146  m_cbUnitsFormat->Bind( wxEVT_CHOICE, updateEventHandler );
147  m_cbPrecision->Bind( wxEVT_CHOICE, updateEventHandler );
148  m_cbSuppressZeroes->Bind( wxEVT_CHECKBOX, updateEventHandler );
149 
150  m_cbTextPositionMode->Bind( wxEVT_CHOICE,
151  [&]( wxCommandEvent& aEvt )
152  {
153  // manual mode
154  bool allowPositioning = ( m_cbTextPositionMode->GetSelection() == 2 );
155 
156  m_txtTextPosX->Enable( allowPositioning );
157  m_txtTextPosY->Enable( allowPositioning );
158  } );
159 
160  m_cbKeepAligned->Bind( wxEVT_CHECKBOX,
161  [&]( wxCommandEvent& aEvt )
162  {
163  m_cbTextOrientation->Enable( !m_cbKeepAligned->GetValue() );
164  } );
165 
167 }
168 
169 
171 {
172  delete m_previewDimension;
173 }
174 
175 
177 {
178  BOARD* board = m_frame->GetBoard();
179 
182 
183  switch( m_dimension->GetUnitsMode() )
184  {
185  case DIM_UNITS_MODE::INCHES: m_cbUnits->SetSelection( 0 ); break;
186  case DIM_UNITS_MODE::MILS: m_cbUnits->SetSelection( 1 ); break;
187  case DIM_UNITS_MODE::MILLIMETRES: m_cbUnits->SetSelection( 2 ); break;
188  case DIM_UNITS_MODE::AUTOMATIC: m_cbUnits->SetSelection( 3 ); break;
189  }
190 
191  m_cbUnitsFormat->SetSelection( static_cast<int>( m_dimension->GetUnitsFormat() ) );
192  m_cbPrecision->SetSelection( static_cast<int>( m_dimension->GetPrecision() ) );
193 
196 
198  {
199  wxMessageBox( _( "This item was on a non-existing or forbidden layer.\n"
200  "It has been moved to the first allowed layer." ) );
201  m_cbLayerActual->SetSelection( 0 );
202  }
203 
205 
207 
208  m_textWidth.SetValue( text.GetTextSize().x );
209  m_textHeight.SetValue( text.GetTextSize().y );
210  m_textThickness.SetValue( text.GetTextThickness() );
211 
212  m_textPosX.SetValue( text.GetTextPos().x );
213  m_textPosY.SetValue( text.GetTextPos().y );
214  m_cbTextPositionMode->SetSelection( static_cast<int>( m_dimension->GetTextPositionMode() ) );
215 
217  {
218  m_txtTextPosX->Disable();
219  m_txtTextPosY->Disable();
220  }
221 
222  m_orientValue = text.GetTextAngleDegrees();
225 
226  m_cbItalic->SetValue( text.IsItalic() );
227  m_cbMirrored->SetValue( text.IsMirrored() );
228  EDA_TEXT_HJUSTIFY_T hJustify = text.GetHorizJustify();
229  m_cbJustification->SetSelection( (int) hJustify + 1 );
230 
234 
235  // Do this last; it depends on the other settings
237  {
238  wxString txt = board->ConvertKIIDsToCrossReferences( m_dimension->GetOverrideText() );
239  m_txtValueActual->SetValue( txt );
240  }
241  else
242  {
243  m_txtValueActual->SetValue( m_dimension->GetValueText() );
244  }
245 
246  m_orientValidator.TransferToWindow();
247 
248  if( m_dimension->Type() == PCB_DIM_LEADER_T )
249  {
250  PCB_DIM_LEADER* leader = static_cast<PCB_DIM_LEADER*>( m_dimension );
251  m_cbTextFrame->SetSelection( static_cast<int>( leader->GetTextFrame() ) );
252  }
253 
254  return DIALOG_DIMENSION_PROPERTIES_BASE::TransferDataToWindow();
255 }
256 
257 
259 {
260  if( !DIALOG_DIMENSION_PROPERTIES_BASE::TransferDataFromWindow() )
261  return false;
262 
263  BOARD_COMMIT commit( m_frame );
264  commit.Modify( m_dimension );
265 
266  // If no other command in progress, prepare undo command
267  // (for a command in progress, will be made later, at the completion of command)
268  bool pushCommit = ( m_dimension->GetEditFlags() == 0 );
269 
270  /* set flag in edit to force undo/redo/abort proper operation,
271  * and avoid new calls to SaveCopyInUndoList for the same dimension
272  * this can occurs when a dimension is moved, and then rotated, edited ..
273  */
274  if( !pushCommit )
276 
278 
279  if( pushCommit )
280  commit.Push( _( "Change dimension properties" ) );
281 
282  return true;
283 }
284 
285 
287 {
288  BOARD* board = m_frame->GetBoard();
289 
290  m_orientValidator.TransferFromWindow();
291 
292  aTarget->SetOverrideTextEnabled( m_cbOverrideValue->GetValue() );
293 
294  if( m_cbOverrideValue->GetValue() )
295  {
296  wxString txt = board->ConvertCrossReferencesToKIIDs( m_txtValueActual->GetValue() );
297  aTarget->SetOverrideText( txt );
298  }
299 
300  aTarget->SetPrefix( board->ConvertCrossReferencesToKIIDs( m_txtPrefix->GetValue() ) );
301  aTarget->SetSuffix( board->ConvertCrossReferencesToKIIDs( m_txtSuffix->GetValue() ) );
302  aTarget->SetLayer( static_cast<PCB_LAYER_ID>( m_cbLayerActual->GetLayerSelection() ) );
303 
304  switch( m_cbUnits->GetSelection() )
305  {
306  case 0:
308  break;
309 
310  case 1:
312  break;
313 
314  case 2:
316  break;
317 
318  case 3:
320  aTarget->SetUnits( m_frame->GetUserUnits() );
321  break;
322  }
323 
324  aTarget->SetUnitsFormat( static_cast<DIM_UNITS_FORMAT>( m_cbUnitsFormat->GetSelection() ) );
325  aTarget->SetPrecision( m_cbPrecision->GetSelection() );
326  aTarget->SetSuppressZeroes( m_cbSuppressZeroes->GetValue() );
327 
328  PCB_TEXT& text = aTarget->Text();
329 
330  DIM_TEXT_POSITION tpm = static_cast<DIM_TEXT_POSITION>( m_cbTextPositionMode->GetSelection() );
331  aTarget->SetTextPositionMode( tpm );
332 
333  if( tpm == DIM_TEXT_POSITION::MANUAL )
334  {
335  wxPoint pos( m_textPosX.GetValue(), m_textPosY.GetValue() );
336  text.SetPosition( pos );
337  }
338 
339  aTarget->SetKeepTextAligned( m_cbKeepAligned->GetValue() );
340 
341  text.SetTextAngle( KiROUND( m_orientValue * 10.0 ) );
342  text.SetTextWidth( m_textWidth.GetValue() );
343  text.SetTextHeight( m_textHeight.GetValue() );
344  text.SetTextThickness( m_textThickness.GetValue() );
345  text.SetItalic( m_cbItalic->GetValue() );
346  text.SetMirrored( m_cbMirrored->GetValue() );
347  int justification = m_cbJustification->GetSelection() - 1;
348  text.SetHorizJustify( static_cast<EDA_TEXT_HJUSTIFY_T>( justification ) );
349 
351  aTarget->SetArrowLength( m_arrowLength.GetValue() );
353 
354  if( aTarget->Type() == PCB_DIM_LEADER_T )
355  {
356  PCB_DIM_LEADER* leader = static_cast<PCB_DIM_LEADER*>( aTarget );
357  leader->SetTextFrame( static_cast<DIM_TEXT_FRAME>( m_cbTextFrame->GetSelection() ) );
358  }
359 
360  aTarget->Update();
361 }
362 
363 
365 {
368 }
bool GetKeepTextAligned() const
DIM_UNITS_FORMAT GetUnitsFormat() const
void SetUnits(EDA_UNITS aUnits)
DIM_TEXT_POSITION
Where to place the text on a dimension.
Definition: pcb_dimension.h:47
COMMIT & Modify(EDA_ITEM *aItem)
Create an undo entry for an item that has been already modified.
Definition: commit.h:103
EDA_TEXT_HJUSTIFY_T
Definition: eda_text.h:61
Class DIALOG_DIMENSION_PROPERTIES_BASE.
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition: typeinfo.h:101
wxString GetValueText() const
void SetUnitsFormat(const DIM_UNITS_FORMAT aFormat)
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition: board_item.h:80
void SetOverrideText(const wxString &aValue)
void SetKeepTextAligned(bool aKeepAligned)
PCB_TEXT & Text()
int GetExtensionOffset() const
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
Definition: typeinfo.h:235
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition: typeinfo.h:102
void SetFlags(EDA_ITEM_FLAGS aMask)
Definition: eda_item.h:153
bool GetOverrideTextEnabled() const
Abstract dimension API.
Definition: pcb_dimension.h:95
void SetBoardFrame(PCB_BASE_FRAME *aFrame)
wxFloatingPointValidator< double > m_orientValidator
PCB_LAYER_BOX_SELECTOR * m_cbLayerActual
void SetSuppressZeroes(bool aSuppress)
bool IsLayerEnabled(PCB_LAYER_ID aLayer) const
A proxy function that calls the correspondent function in m_BoardSettings tests whether a given layer...
Definition: board.cpp:491
void SetExtensionOffset(int aOffset)
int GetPrecision() const
virtual EDA_ITEM * Clone() const
Create a duplicate of this item with linked list members set to NULL.
Definition: eda_item.cpp:83
void SetLineThickness(int aWidth)
DIM_UNITS_MODE GetUnitsMode() const
wxString GetPrefix() const
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
LAYER_NUM GetLayerSelection() const
wxString GetShownText(int aDepth=0) const override
Return the string actually shown after processing of the base text.
Definition: pcb_text.cpp:56
DIM_TEXT_FRAME GetTextFrame() const
void SetOverrideTextEnabled(bool aOverride)
int GetArrowLength() const
wxString GetSuffix() const
void ShowNonActivatedLayers(bool aShow)
bool GetSuppressZeroes() const
void SetParent(EDA_ITEM *aParent) override
void SetPrefix(const wxString &aPrefix)
void SetArrowLength(int aLength)
#define _(s)
int SetLayerSelection(LAYER_NUM layer)
void SetSuffix(const wxString &aSuffix)
EDA_ITEM_FLAGS GetEditFlags() const
Definition: eda_item.h:158
void SetPrecision(int aPrecision)
bool SetLayersHotkeys(bool value)
class PCB_DIMENSION_BASE: abstract dimension meta-type
Definition: typeinfo.h:99
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
Common, abstract interface for edit frames.
Information pertinent to a Pcbnew printed circuit board.
Definition: board.h:190
virtual void SetValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
wxString ConvertCrossReferencesToKIIDs(const wxString &aSource) const
Convert cross-references back and forth between ${refDes:field} and ${kiid:field}.
Definition: board.cpp:982
DIALOG_DIMENSION_PROPERTIES(PCB_BASE_EDIT_FRAME *aParent, BOARD_ITEM *aItem)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".
Definition: util.h:73
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Revert the commit by restoring the modified items state.
virtual long long int GetValue()
Return the current value in Internal Units.
void SetTextFrame(DIM_TEXT_FRAME aFrame)
wxString ConvertKIIDsToCrossReferences(const wxString &aSource) const
Definition: board.cpp:1036
A leader is a dimension-like object pointing to a specific point.
void SetCoordType(ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType)
Set the current origin transform mode.
Definition: unit_binder.h:173
#define IN_EDIT
Item currently edited.
BOARD * GetBoard() const
Text placement is manually set by the user.
void SetUnitsMode(DIM_UNITS_MODE aMode)
DIM_TEXT_POSITION GetTextPositionMode() const
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
Definition: board_item.h:171
int GetLineThickness() const
void updateDimensionFromDialog(PCB_DIMENSION_BASE *aTarget)
wxString GetOverrideText() const
EDA_UNITS GetUserUnits() const
Return the user units currently in use.
void SetTextPositionMode(DIM_TEXT_POSITION aMode)
KICAD_T Type() const
Returns the type of object.
Definition: eda_item.h:113
void Update()
Update the dimension's cached text and geometry.