KiCad PCB EDA Suite
Loading...
Searching...
No Matches
unit_binder.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) 2014-2015 CERN
5 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
6 * Author: Maciej Suminski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <wx/clipbrd.h>
27#include <wx/combobox.h>
28#include <wx/stattext.h>
29#include <wx/textentry.h>
30#include <eda_units.h>
31#include <eda_draw_frame.h>
32#include <confirm.h>
33#include <dialog_shim.h>
34
35#include "widgets/unit_binder.h"
36#include "wx/dcclient.h"
37
38using namespace EDA_UNIT_UTILS::UI;
39
40
41wxDEFINE_EVENT( DELAY_FOCUS, wxCommandEvent );
42
43
44UNIT_BINDER::UNIT_BINDER( EDA_DRAW_FRAME* aParent, wxStaticText* aLabel, wxWindow* aValueCtrl,
45 wxStaticText* aUnitLabel, bool allowEval, bool aBindFrameEvents ) :
46 UNIT_BINDER( aParent, aParent, aLabel, aValueCtrl, aUnitLabel, allowEval, aBindFrameEvents )
47{
48}
49
50UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource,
51 wxStaticText* aLabel, wxWindow* aValueCtrl, wxStaticText* aUnitLabel,
52 bool aAllowEval, bool aBindFocusEvent ) :
53 m_bindFocusEvent( aBindFocusEvent ),
54 m_label( aLabel ),
55 m_valueCtrl( aValueCtrl ),
56 m_eventSource( aEventSource ),
57 m_unitLabel( aUnitLabel ),
58 m_iuScale( &aUnitsProvider->GetIuScale() ),
59 m_units( aUnitsProvider->GetUserUnits() ),
60 m_negativeZero( false ),
62 m_precision( 0 ),
63 m_eval( aUnitsProvider->GetUserUnits() ),
64 m_allowEval( aAllowEval && ( !m_valueCtrl || dynamic_cast<wxTextEntry*>( m_valueCtrl ) ) ),
65 m_needsEval( false ),
66 m_selStart( 0 ),
67 m_selEnd( 0 ),
68 m_unitsInValue( false ),
69 m_originTransforms( aUnitsProvider->GetOriginTransforms() ),
70 m_coordType( ORIGIN_TRANSFORMS::NOT_A_COORD )
71{
72 if( m_valueCtrl )
73 {
74 // Register the UNIT_BINDER for control state save/restore
75 wxWindow* parent = m_valueCtrl->GetParent();
76
77 while( parent && !dynamic_cast<DIALOG_SHIM*>( parent ) )
78 parent = parent->GetParent();
79
80 if( parent )
81 static_cast<DIALOG_SHIM*>( parent )->RegisterUnitBinder( this, m_valueCtrl );
82 }
83
84 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
85
86 if( textEntry )
87 {
88 wxClientDC dc( m_valueCtrl );
89
90 // Gives enough room to display a value in inches in textEntry
91 // 3 digits + '.' + 10 digits
92 wxSize minSize = m_valueCtrl->GetMinSize();
93 int minWidth = dc.GetTextExtent( wxT( "XXX.XXXXXXXXXX" ) ).GetWidth();
94
95 if( minSize.GetWidth() < minWidth )
96 m_valueCtrl->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
97
98 // Use ChangeValue() instead of SetValue() so we don't generate events.
99 if( m_negativeZero )
100 textEntry->ChangeValue( wxT( "-0" ) );
101 else
102 textEntry->ChangeValue( wxT( "0" ) );
103 }
104
105 if( m_unitLabel )
107
108 if( m_valueCtrl )
109 {
110 m_valueCtrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ), nullptr, this );
111 m_valueCtrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( UNIT_BINDER::onKillFocus ), nullptr, this );
112 m_valueCtrl->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( UNIT_BINDER::onClick ), nullptr, this );
113 m_valueCtrl->Connect( wxEVT_COMBOBOX, wxCommandEventHandler( UNIT_BINDER::onComboBox ), nullptr, this );
114 }
115
116 if( m_bindFocusEvent )
117 Connect( DELAY_FOCUS, wxCommandEventHandler( UNIT_BINDER::delayedFocusHandler ), nullptr, this );
118
119 if( m_eventSource )
120 {
121 m_eventSource->Connect( EDA_EVT_UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
122 nullptr, this );
123 }
124}
125
126
128{
129 if( m_valueCtrl )
130 {
131 m_valueCtrl->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ), nullptr, this );
132 m_valueCtrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( UNIT_BINDER::onKillFocus ), nullptr, this );
133 m_valueCtrl->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( UNIT_BINDER::onClick ), nullptr, this );
134 m_valueCtrl->Disconnect( wxEVT_COMBOBOX, wxCommandEventHandler( UNIT_BINDER::onComboBox ), nullptr, this );
135 }
136
137 if( m_bindFocusEvent )
138 Disconnect( DELAY_FOCUS, wxCommandEventHandler( UNIT_BINDER::delayedFocusHandler ), nullptr, this );
139
140 if( m_eventSource )
141 {
142 m_eventSource->Disconnect( EDA_EVT_UNITS_CHANGED, wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
143 nullptr, this );
144 }
145}
146
147
149{
150 m_units = aUnits;
151
152 m_eval.SetDefaultUnits( m_units );
153 m_eval.LocaleChanged(); // In case locale changed since last run
154
155 if( m_unitLabel )
157}
158
159
160void UNIT_BINDER::SetPrecision( int aLength )
161{
162 m_precision = std::min( aLength, 6 );
163}
164
165
167{
168 m_dataType = aDataType;
169
170 if( m_unitLabel )
172}
173
174
175void UNIT_BINDER::onUnitsChanged( wxCommandEvent& aEvent )
176{
177 EDA_BASE_FRAME* provider = static_cast<EDA_BASE_FRAME*>( aEvent.GetClientData() );
178
179 if( !UnitsInvariant() )
180 {
181 int temp = GetIntValue();
182
183 wxComboBox* const combo = dynamic_cast<wxComboBox*>( m_valueCtrl );
184 std::vector<long long int> comboValues;
185
186 // Read out the current values
187 if( combo )
188 {
189 for( unsigned int i = 0; i < combo->GetCount(); i++ )
190 {
191 const wxString value = combo->GetString( i );
192 long long int conv = ValueFromString( *m_iuScale, m_units, value, m_dataType );
193 comboValues.push_back( conv );
194 }
195 }
196
197 SetUnits( provider->GetUserUnits() );
198 m_iuScale = &provider->GetIuScale();
199
200 // Re-populate the combo box with updated values
201 if( combo )
202 {
203 SetOptionsList( comboValues );
204 }
205
206 if( !IsIndeterminate() )
207 SetValue( temp );
208 }
209
210 aEvent.Skip();
211}
212
213
214void UNIT_BINDER::onClick( wxMouseEvent& aEvent )
215{
216 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
217
218 if( textEntry && ( textEntry->GetValue() == INDETERMINATE_ACTION
219 || textEntry->GetValue() == INDETERMINATE_STATE ) )
220 {
221 // These are tokens, not strings, so do a select all
222 textEntry->SelectAll();
223 }
224
225 // Needed at least on Windows to avoid hanging
226 aEvent.Skip();
227}
228
229
230void UNIT_BINDER::onComboBox( wxCommandEvent& aEvent )
231{
232 wxComboBox* combo = dynamic_cast<wxComboBox*>( m_valueCtrl );
233 wxCHECK( combo, /*void*/ );
234
235 const wxString value = combo->GetStringSelection();
236 const long long int conv = ValueFromString( *m_iuScale, m_units, value, m_dataType );
237
238 CallAfter(
239 [this, conv]
240 {
241 SetValue( conv );
242 } );
243
244 aEvent.Skip();
245}
246
247
248void UNIT_BINDER::onSetFocus( wxFocusEvent& aEvent )
249{
250 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
251
252 if( textEntry )
253 {
254 if( m_allowEval )
255 {
256 wxString oldStr = m_eval.OriginalText();
257
258 if( oldStr.length() && oldStr != textEntry->GetValue() )
259 {
260 textEntry->ChangeValue( oldStr );
261 textEntry->SetSelection( m_selStart, m_selEnd );
262 }
263
264 m_needsEval = true;
265 }
266
267 if( textEntry->GetValue() == INDETERMINATE_ACTION
268 || textEntry->GetValue() == INDETERMINATE_STATE )
269 {
270 // These are tokens, not strings, so do a select all
271 textEntry->SelectAll();
272 }
273 }
274
275 aEvent.Skip();
276}
277
278
279void UNIT_BINDER::onKillFocus( wxFocusEvent& aEvent )
280{
281 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
282
283 if( m_allowEval && textEntry )
284 {
285 wxString value = textEntry->GetValue();
286 bool success = m_eval.Process( value );
287
288 if( success && !value.IsEmpty() )
289 {
290 textEntry->GetSelection( &m_selStart, &m_selEnd );
291
292 value = m_eval.Result();
293
294 if( m_unitsInValue && !value.IsEmpty() )
295 {
297 value += wxT( " " );
298
300 }
301
302 textEntry->ChangeValue( value );
303
304#ifdef __WXGTK__
305 // Manually copy the selected text to the primary selection clipboard
306 if( wxTheClipboard->Open() )
307 {
308 wxString sel = textEntry->GetStringSelection();
309 bool clipTarget = wxTheClipboard->IsUsingPrimarySelection();
310 wxTheClipboard->UsePrimarySelection( true );
311 wxTheClipboard->SetData( new wxTextDataObject( sel ) );
312 wxTheClipboard->UsePrimarySelection( clipTarget );
313 wxTheClipboard->Close();
314 }
315#endif
316 }
317
318 m_needsEval = false;
319 }
320
321 aEvent.Skip();
322}
323
324
325wxString valueDescriptionFromLabel( wxStaticText* aLabel )
326{
327 wxString desc = aLabel->GetLabel();
328
329 desc.EndsWith( wxT( ":" ), &desc );
330 return desc;
331}
332
333
334void UNIT_BINDER::delayedFocusHandler( wxCommandEvent& )
335{
336 if( !m_errorMessage.IsEmpty() )
338
339 m_errorMessage = wxEmptyString;
340 m_valueCtrl->SetFocus();
341}
342
343
344bool UNIT_BINDER::Validate( double aMin, double aMax, EDA_UNITS aUnits )
345{
346 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
347
348 if( !textEntry
349 || textEntry->GetValue() == INDETERMINATE_ACTION
350 || textEntry->GetValue() == INDETERMINATE_STATE )
351 {
352 return true;
353 }
354
355 // TODO: Validate() does not currently support m_dataType being anything other than DISTANCE
356 // Note: aMin and aMax are not always given in internal units
357 if( GetValue() < FromUserUnit( *m_iuScale, aUnits, aMin ) )
358 {
359 double val_min_iu = FromUserUnit( *m_iuScale, aUnits, aMin );
360 m_errorMessage = wxString::Format( _( "%s must be at least %s." ),
362 StringFromValue( *m_iuScale, m_units, val_min_iu, true ) );
363
364 textEntry->SelectAll();
365
366 // Don't focus directly; we might be inside a KillFocus event handler
367 wxPostEvent( this, wxCommandEvent( DELAY_FOCUS ) );
368
369 return false;
370 }
371
372 if( GetValue() > FromUserUnit( *m_iuScale, aUnits, aMax ) )
373 {
374 double val_max_iu = FromUserUnit( *m_iuScale, aUnits, aMax );
375 m_errorMessage = wxString::Format( _( "%s must be less than %s." ),
377 StringFromValue( *m_iuScale, m_units, val_max_iu, true ) );
378
379 textEntry->SelectAll();
380
381 // Don't focus directly; we might be inside a KillFocus event handler
382 wxPostEvent( this, wxCommandEvent( DELAY_FOCUS ) );
383
384 return false;
385 }
386
387 return true;
388}
389
390
391void UNIT_BINDER::SetValue( long long int aValue )
392{
393 double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
394 wxString textValue = StringFromValue( *m_iuScale, m_units, displayValue, false, m_dataType );
395
396 if( displayValue == 0 && m_negativeZero )
397 SetValue( wxT( "-" ) + textValue );
398 else
399 SetValue( textValue );
400}
401
402
403void UNIT_BINDER::SetDoubleValue( double aValue )
404{
405 double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
406 wxString textValue = StringFromValue( *m_iuScale, m_units, setPrecision( displayValue, false ), false,
407 m_dataType );
408
409 if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
410 SetValue( wxT( "-" ) + textValue );
411 else
412 SetValue( textValue );
413}
414
415
417{
418 SetDoubleValue( aValue.AsDegrees() );
419}
420
421
422void UNIT_BINDER::SetValue( const wxString& aValue )
423{
424 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
425 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
426
427 wxString value = aValue;
428
429 if( m_unitsInValue && !value.IsEmpty() )
430 {
432 value += wxT( " " );
433
435 }
436
437 if( textEntry )
438 textEntry->SetValue( value );
439 else if( staticText )
440 staticText->SetLabel( value );
441
442 if( m_allowEval )
443 m_eval.Clear();
444
445 if( m_unitLabel )
447
448}
449
450
451wxString UNIT_BINDER::getTextForValue( long long int aValue ) const
452{
453 const double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
454 wxString textValue = StringFromValue( *m_iuScale, m_units, setPrecision( displayValue, false ), false,
455 m_dataType );
456
457 if( displayValue == 0 && m_negativeZero )
458 textValue = wxT( "-" ) + textValue;
459
460 return textValue;
461}
462
463
464wxString UNIT_BINDER::getTextForDoubleValue( double aValue ) const
465{
466 const double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
467 wxString textValue = StringFromValue( *m_iuScale, m_units, setPrecision( displayValue, false ), false,
468 m_dataType );
469
470 if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
471 textValue = wxT( "-" ) + textValue;
472
473 return textValue;
474}
475
476
477void UNIT_BINDER::ChangeValue( int aValue )
478{
479 ChangeValue( getTextForValue( aValue ) );
480}
481
482
484{
486}
487
488
490{
491 ChangeDoubleValue( aValue.AsDegrees() );
492}
493
494
495void UNIT_BINDER::ChangeValue( const wxString& aValue )
496{
497 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
498 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
499
500 wxString value = aValue;
501
502 if( m_unitsInValue && !value.IsEmpty() )
503 {
505 value += wxT( " " );
506
508 }
509
510 if( textEntry )
511 textEntry->ChangeValue( value );
512 else if( staticText )
513 staticText->SetLabel( value );
514
515 if( m_allowEval )
516 m_eval.Clear();
517
518 if( m_unitLabel )
520}
521
522
523long long int UNIT_BINDER::GetValue() const
524{
525 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
526 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
527 wxString value;
528
529 if( textEntry )
530 {
531 value = textEntry->GetValue();
532
533 if( m_needsEval && !value.IsEmpty() && m_eval.Process( value ) )
534 value = m_eval.Result();
535 else
536 value = textEntry->GetValue();
537 }
538 else if( staticText )
539 {
540 value = staticText->GetLabel();
541 }
542 else
543 {
544 return 0;
545 }
546
547 long long int displayValue = ValueFromString( *m_iuScale, m_units, value, m_dataType );
548 return m_originTransforms.FromDisplay( displayValue, m_coordType );
549}
550
551
552double UNIT_BINDER::setPrecision( double aValue, bool aValueUsesUserUnits ) const
553{
554 if( m_precision > 1 )
555 {
556 int scale = pow( 10, m_precision );
557 int64_t tmp = aValue;
558
559 if( !aValueUsesUserUnits )
560 tmp = ToUserUnit( *m_iuScale, m_units, aValue ) * scale;
561
562 aValue = static_cast<double>( tmp ) / scale;
563
564 if( !aValueUsesUserUnits )
565 aValue = FromUserUnit( *m_iuScale, m_units, aValue );
566 }
567
568 return aValue;
569}
570
571
573{
574 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
575 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
576 wxString value;
577
578 if( textEntry )
579 {
580 value = textEntry->GetValue();
581
582 if( m_needsEval && !value.IsEmpty() && m_eval.Process( value ) )
583 value = m_eval.Result();
584 else
585 value = textEntry->GetValue();
586 }
587 else if( staticText )
588 {
589 value = staticText->GetLabel();
590 }
591 else
592 {
593 return 0.0;
594 }
595
596 double displayValue = DoubleValueFromString( *m_iuScale, m_units, value, m_dataType );
597 displayValue = setPrecision( displayValue, false );
598
599 return m_originTransforms.FromDisplay( displayValue, m_coordType );
600}
601
602
607
608
609void UNIT_BINDER::SetOptionsList( std::span<const long long int> aOptions )
610{
611 wxComboBox* cb = dynamic_cast<wxComboBox*>( m_valueCtrl );
612 wxCHECK( cb, /* void */ );
613
614 cb->Clear();
615
616 for( long long int value : aOptions )
617 cb->Append( getTextForValue( value ) );
618}
619
620
621void UNIT_BINDER::SetDoubleOptionsList( std::span<const double> aOptions )
622{
623 wxComboBox* cb = dynamic_cast<wxComboBox*>( m_valueCtrl );
624 wxCHECK( cb, /* void */ );
625
626 cb->Clear();
627
628 for( double value : aOptions )
629 cb->Append( getTextForDoubleValue( value ) );
630}
631
632
634{
635 wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl );
636
637 if( te )
638 return te->GetValue() == INDETERMINATE_STATE || te->GetValue() == INDETERMINATE_ACTION;
639
640 return false;
641}
642
643
645{
646 if( wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl ) )
647 return te->GetValue().IsEmpty();
648
649 return false;
650}
651
652
654{
655 if( wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl ) )
656 return te->SetValue( wxEmptyString );
657}
658
659
660void UNIT_BINDER::SetLabel( const wxString& aLabel )
661{
662 m_label->SetLabel( aLabel );
663}
664
665
666void UNIT_BINDER::Enable( bool aEnable )
667{
668 if( m_label )
669 m_label->Enable( aEnable );
670
671 m_valueCtrl->Enable( aEnable );
672
673 if( m_unitLabel )
674 m_unitLabel->Enable( aEnable );
675}
676
677
678void UNIT_BINDER::Show( bool aShow, bool aResize )
679{
680 m_label->Show( aShow );
681 m_valueCtrl->Show( aShow );
682
683 if( m_unitLabel )
684 m_unitLabel->Show( aShow );
685
686 if( aResize )
687 {
688 if( aShow )
689 {
690 m_label->SetSize( -1, -1 );
691 m_valueCtrl->SetSize( -1, -1 );
692
693 if( m_unitLabel )
694 m_unitLabel->SetSize( -1, -1 );
695 }
696 else
697 {
698 m_label->SetSize( 0, 0 );
699 m_valueCtrl->SetSize( 0, 0 );
700
701 if( m_unitLabel )
702 m_unitLabel->SetSize( 0, 0 );
703 }
704 }
705}
706
707
709 UNIT_BINDER( aParent, nullptr, nullptr, nullptr, true, false )
710{
711 m_unitsInValue = true;
712}
713
714
718
720{
721 m_valueCtrl = aControl;
722
723 if( m_valueCtrl )
724 {
725 m_valueCtrl->Bind( wxEVT_SET_FOCUS, &PROPERTY_EDITOR_UNIT_BINDER::onSetFocus, this );
726 m_valueCtrl->Bind( wxEVT_KILL_FOCUS, &PROPERTY_EDITOR_UNIT_BINDER::onKillFocus, this );
727 m_valueCtrl->Bind( wxEVT_LEFT_UP, &PROPERTY_EDITOR_UNIT_BINDER::onClick, this );
728
729 m_valueCtrl->Bind( wxEVT_SHOW,
730 [&]( wxShowEvent& e )
731 {
732 if( !e.IsShown() )
733 SetControl( nullptr );
734 } );
735 }
736}
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition dialog_shim.h:68
double AsDegrees() const
Definition eda_angle.h:116
The base frame for deriving all KiCad main window classes.
The base class for create windows for drawing purpose.
A class to perform either relative or absolute display origin transforms for a single axis of a point...
void SetControl(wxWindow *aControl)
PROPERTY_EDITOR_UNIT_BINDER(EDA_DRAW_FRAME *aParent)
const EDA_IU_SCALE & GetIuScale() const
EDA_UNITS GetUserUnits() const
double setPrecision(double aValue, bool aValueUsesUserUnits) const
When m_precision > 0 truncate the value aValue to show only m_precision digits in mantissa.
ORIGIN_TRANSFORMS::COORD_TYPES_T m_coordType
Type of coordinate for display origin transforms.
wxString getTextForValue(long long int aValue) const
virtual void ChangeDoubleValue(double aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion WITHOUT trigger...
void onKillFocus(wxFocusEvent &aEvent)
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
void onClick(wxMouseEvent &aEvent)
virtual void SetPrecision(int aLength)
Normally not needed, but can be used to set the precision when using internal units that are floats (...
virtual void SetUnits(EDA_UNITS aUnits)
Normally not needed (as the UNIT_BINDER inherits from the parent frame), but can be used to set to DE...
virtual double GetDoubleValue() const
Return the current value in Internal Units.
wxString getTextForDoubleValue(double aValue) const
const EDA_IU_SCALE * m_iuScale
Currently used units.
wxString m_errorMessage
virtual EDA_ANGLE GetAngleValue()
bool m_negativeZero
Indicates "-0" should be displayed for 0.
virtual long long int GetValue() const
Return the current value in Internal Units.
int m_precision
0 to 6.
wxStaticText * m_unitLabel
Can be nullptr.
bool m_unitsInValue
Units label should be included in value text.
wxWindow * m_valueCtrl
wxWindow * m_eventSource
void onSetFocus(wxFocusEvent &aEvent)
void onComboBox(wxCommandEvent &aEvent)
UNIT_BINDER(EDA_DRAW_FRAME *aParent, wxStaticText *aLabel, wxWindow *aValueCtrl, wxStaticText *aUnitLabel, bool aAllowEval=true, bool aBindFocusEvent=true)
wxStaticText * m_label
The bound widgets.
ORIGIN_TRANSFORMS & m_originTransforms
A reference to an ORIGIN_TRANSFORMS object.
bool m_bindFocusEvent
long m_selStart
Selection start and end of the original text.
virtual void SetDoubleOptionsList(std::span< const double > aOptions)
EDA_UNITS m_units
virtual void SetOptionsList(std::span< const long long int > aOptions)
Set the list of options for a combobox control.
bool IsIndeterminate() const
Return true if the control holds the indeterminate value (for instance, if it represents a multiple s...
void SetDataType(EDA_DATA_TYPE aDataType)
Used to override the datatype of the displayed property (default is DISTANCE)
int GetIntValue() const
void delayedFocusHandler(wxCommandEvent &aEvent)
EDA_DATA_TYPE m_dataType
virtual void SetAngleValue(const EDA_ANGLE &aValue)
void SetLabel(const wxString &aLabel)
virtual void ChangeAngleValue(const EDA_ANGLE &aValue)
virtual void SetDoubleValue(double aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
virtual ~UNIT_BINDER() override
bool UnitsInvariant() const
Definition unit_binder.h:73
virtual bool Validate(double aMin, double aMax, EDA_UNITS aUnits=EDA_UNITS::UNSCALED)
Validate the control against the given range, informing the user of any errors found.
virtual void ChangeValue(int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion WITHOUT trigger...
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
void Show(bool aShow, bool aResize=false)
Show/hide the label, widget and units label.
NUMERIC_EVALUATOR m_eval
bool IsNull() const
Return true if the control holds no value (ie: empty string, not 0).
void onUnitsChanged(wxCommandEvent &aEvent)
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition confirm.cpp:194
This file is part of the common library.
const int minSize
Push and Shove router track width and via size dialog.
#define _(s)
@ DEGREES_T
Definition eda_angle.h:31
EDA_DATA_TYPE
The type of unit.
Definition eda_units.h:38
EDA_UNITS
Definition eda_units.h:48
KICOMMON_API double FromUserUnit(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnit, double aValue)
Return in internal units the value aValue given in a real unit such as "in", "mm",...
KICOMMON_API long long int ValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue in aUnits to internal units used by the application.
KICOMMON_API wxString StringFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=false, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Return the string from aValue according to aUnits (inch, mm ...) for display.
KICOMMON_API double DoubleValueFromString(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, const wxString &aTextValue, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Convert aTextValue to a double.
KICOMMON_API double ToUserUnit(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnit, double aValue)
Convert aValue in internal units to the appropriate user units defined by aUnit.
KICOMMON_API wxString GetLabel(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
int GetUserUnits()
Return the currently selected user unit value for the interface.
const int scale
#define INDETERMINATE_ACTION
Definition ui_common.h:47
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
Definition ui_common.h:46
wxDEFINE_EVENT(DELAY_FOCUS, wxCommandEvent)
wxString valueDescriptionFromLabel(wxStaticText *aLabel)