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
34#include "widgets/unit_binder.h"
35#include "wx/dcclient.h"
36
37
38wxDEFINE_EVENT( DELAY_FOCUS, wxCommandEvent );
39
40
41UNIT_BINDER::UNIT_BINDER( EDA_DRAW_FRAME* aParent, wxStaticText* aLabel, wxWindow* aValueCtrl,
42 wxStaticText* aUnitLabel, bool allowEval, bool aBindFrameEvents ) :
43 UNIT_BINDER( aParent, aParent, aLabel, aValueCtrl, aUnitLabel, allowEval, aBindFrameEvents )
44{
45}
46
47UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource,
48 wxStaticText* aLabel, wxWindow* aValueCtrl, wxStaticText* aUnitLabel,
49 bool aAllowEval, bool aBindFocusEvent ) :
50 m_bindFocusEvent( aBindFocusEvent ),
51 m_label( aLabel ),
52 m_valueCtrl( aValueCtrl ),
53 m_unitLabel( aUnitLabel ),
54 m_iuScale( &aUnitsProvider->GetIuScale() ),
55 m_negativeZero( false ),
56 m_dataType( EDA_DATA_TYPE::DISTANCE ),
57 m_precision( 0 ),
58 m_eval( aUnitsProvider->GetUserUnits() ),
59 m_unitsInValue( false ),
60 m_originTransforms( aUnitsProvider->GetOriginTransforms() ),
61 m_coordType( ORIGIN_TRANSFORMS::NOT_A_COORD )
62{
63 init( aUnitsProvider );
64 m_allowEval = aAllowEval && ( !m_valueCtrl || dynamic_cast<wxTextEntry*>( m_valueCtrl ) );
65 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
66
67 if( textEntry )
68 {
69 wxClientDC dc( m_valueCtrl );
70
71 // Gives enough room to display a value in inches in textEntry
72 // 3 digits + '.' + 10 digits
73 wxSize minSize = m_valueCtrl->GetMinSize();
74 int minWidth = dc.GetTextExtent( wxT( "XXX.XXXXXXXXXX" ) ).GetWidth();
75
76 if( minSize.GetWidth() < minWidth )
77 m_valueCtrl->SetMinSize( wxSize( minWidth, minSize.GetHeight() ) );
78
79 // Use ChangeValue() instead of SetValue() so we don't generate events.
80 if( m_negativeZero )
81 textEntry->ChangeValue( wxT( "-0" ) );
82 else
83 textEntry->ChangeValue( wxT( "0" ) );
84 }
85
86 if( m_unitLabel )
88
89 if( m_valueCtrl )
90 {
91 m_valueCtrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ),
92 nullptr, this );
93 m_valueCtrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( UNIT_BINDER::onKillFocus ),
94 nullptr, this );
95 m_valueCtrl->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( UNIT_BINDER::onClick ),
96 nullptr, this );
97 m_valueCtrl->Connect( wxEVT_COMBOBOX, wxCommandEventHandler( UNIT_BINDER::onComboBox ),
98 nullptr, this );
99 }
100
101 if( m_bindFocusEvent )
102 {
103 Connect( DELAY_FOCUS, wxCommandEventHandler( UNIT_BINDER::delayedFocusHandler ), nullptr,
104 this );
105 }
106
107 if( aEventSource )
108 {
109 aEventSource->Connect( EDA_EVT_UNITS_CHANGED,
110 wxCommandEventHandler( UNIT_BINDER::onUnitsChanged ),
111 nullptr, this );
112 }
113}
114
115
117{
118 if( m_bindFocusEvent )
119 {
120 Disconnect( DELAY_FOCUS, wxCommandEventHandler( UNIT_BINDER::delayedFocusHandler ), nullptr,
121 this );
122 }
123
124 if( m_valueCtrl )
125 {
126 m_valueCtrl->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ),
127 nullptr, this );
128 m_valueCtrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( UNIT_BINDER::onKillFocus ),
129 nullptr, this );
130 m_valueCtrl->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( UNIT_BINDER::onClick ),
131 nullptr, this );
132 m_valueCtrl->Disconnect( wxEVT_COMBOBOX, wxCommandEventHandler( UNIT_BINDER::onComboBox ),
133 nullptr, this );
134 }
135}
136
137
139{
140 m_units = aProvider->GetUserUnits();
141 m_needsEval = false;
142 m_selStart = 0;
143 m_selEnd = 0;
144}
145
146
148{
149 m_units = aUnits;
150
152 m_eval.LocaleChanged(); // In case locale changed since last run
153
154 if( m_unitLabel )
156}
157
158
159void UNIT_BINDER::SetPrecision( int aLength )
160{
161 m_precision = std::min( aLength, 6 );
162}
163
164
166{
167 m_dataType = aDataType;
168
169 if( m_unitLabel )
171}
172
173
174void UNIT_BINDER::onUnitsChanged( wxCommandEvent& aEvent )
175{
176 EDA_BASE_FRAME* provider = static_cast<EDA_BASE_FRAME*>( aEvent.GetClientData() );
177
178 if( m_units != EDA_UNITS::UNSCALED
179 && m_units != EDA_UNITS::DEGREES
180 && m_units != EDA_UNITS::PERCENT )
181 {
182 int temp = GetIntValue();
183
184 wxComboBox* const combo = dynamic_cast<wxComboBox*>( m_valueCtrl );
185 std::vector<long long int> comboValues;
186
187 // Read out the current values
188 if( combo )
189 {
190 for( unsigned int i = 0; i < combo->GetCount(); i++ )
191 {
192 const wxString value = combo->GetString( i );
194 value, m_dataType );
195 comboValues.push_back( conv );
196 }
197 }
198
199 SetUnits( provider->GetUserUnits() );
200 m_iuScale = &provider->GetIuScale();
201
202 // Re-populate the combo box with updated values
203 if( combo )
204 {
205 SetOptionsList( comboValues );
206 }
207
208 if( !IsIndeterminate() )
209 SetValue( temp );
210 }
211
212 aEvent.Skip();
213}
214
215
216void UNIT_BINDER::onClick( wxMouseEvent& aEvent )
217{
218 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
219
220 if( textEntry && ( textEntry->GetValue() == INDETERMINATE_ACTION
221 || textEntry->GetValue() == INDETERMINATE_STATE ) )
222 {
223 // These are tokens, not strings, so do a select all
224 textEntry->SelectAll();
225 }
226
227 // Needed at least on Windows to avoid hanging
228 aEvent.Skip();
229}
230
231
232void UNIT_BINDER::onComboBox( wxCommandEvent& aEvent )
233{
234 wxComboBox* combo = dynamic_cast<wxComboBox*>( m_valueCtrl );
235 wxCHECK( combo, /*void*/ );
236
237 const wxString value = combo->GetStringSelection();
238 const long long int conv =
240
241 SetValue( conv );
242
243 aEvent.Skip();
244}
245
246
247void UNIT_BINDER::onSetFocus( wxFocusEvent& aEvent )
248{
249 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
250
251 if( textEntry )
252 {
253 if( m_allowEval )
254 {
255 wxString oldStr = m_eval.OriginalText();
256
257 if( oldStr.length() && oldStr != textEntry->GetValue() )
258 {
259 textEntry->ChangeValue( oldStr );
260 textEntry->SetSelection( m_selStart, m_selEnd );
261 }
262
263 m_needsEval = true;
264 }
265
266 if( textEntry->GetValue() == INDETERMINATE_ACTION
267 || textEntry->GetValue() == INDETERMINATE_STATE )
268 {
269 // These are tokens, not strings, so do a select all
270 textEntry->SelectAll();
271 }
272 }
273
274 aEvent.Skip();
275}
276
277
278void UNIT_BINDER::onKillFocus( wxFocusEvent& aEvent )
279{
280 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
281
282 if( m_allowEval && textEntry )
283 {
284 wxString value = textEntry->GetValue();
285 bool success = m_eval.Process( value );
286
287 if( success && !value.IsEmpty() )
288 {
289 textEntry->GetSelection( &m_selStart, &m_selEnd );
290
291 value = m_eval.Result();
292
293 if( m_unitsInValue && !value.IsEmpty() )
294 {
295 if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
296 value += wxT( " " );
297
299 }
300
301 textEntry->ChangeValue( value );
302
303#ifdef __WXGTK__
304 // Manually copy the selected text to the primary selection clipboard
305 if( wxTheClipboard->Open() )
306 {
307 wxString sel = textEntry->GetStringSelection();
308 bool clipTarget = wxTheClipboard->IsUsingPrimarySelection();
309 wxTheClipboard->UsePrimarySelection( true );
310 wxTheClipboard->SetData( new wxTextDataObject( sel ) );
311 wxTheClipboard->UsePrimarySelection( clipTarget );
312 wxTheClipboard->Close();
313 }
314#endif
315 }
316
317 m_needsEval = false;
318 }
319
320 aEvent.Skip();
321}
322
323
324wxString valueDescriptionFromLabel( wxStaticText* aLabel )
325{
326 wxString desc = aLabel->GetLabel();
327
328 desc.EndsWith( wxT( ":" ), &desc );
329 return desc;
330}
331
332
333void UNIT_BINDER::delayedFocusHandler( wxCommandEvent& )
334{
335 if( !m_errorMessage.IsEmpty() )
337
338 m_errorMessage = wxEmptyString;
339 m_valueCtrl->SetFocus();
340}
341
342
343bool UNIT_BINDER::Validate( double aMin, double aMax, EDA_UNITS aUnits )
344{
345 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
346
347 if( !textEntry
348 || textEntry->GetValue() == INDETERMINATE_ACTION
349 || textEntry->GetValue() == INDETERMINATE_STATE )
350 {
351 return true;
352 }
353
354 // TODO: Validate() does not currently support m_dataType being anything other than DISTANCE
355 // Note: aMin and aMax are not always given in internal units
356 if( GetValue() < EDA_UNIT_UTILS::UI::FromUserUnit( *m_iuScale, aUnits, aMin ) )
357 {
358 double val_min_iu = EDA_UNIT_UTILS::UI::FromUserUnit( *m_iuScale, aUnits, aMin );
359 m_errorMessage = wxString::Format( _( "%s must be at least %s." ),
362 val_min_iu,
363 true ) );
364
365 textEntry->SelectAll();
366
367 // Don't focus directly; we might be inside a KillFocus event handler
368 wxPostEvent( this, wxCommandEvent( DELAY_FOCUS ) );
369
370 return false;
371 }
372
373 if( GetValue() > EDA_UNIT_UTILS::UI::FromUserUnit( *m_iuScale, aUnits, aMax ) )
374 {
375 double val_max_iu = EDA_UNIT_UTILS::UI::FromUserUnit( *m_iuScale, aUnits, aMax );
376 m_errorMessage = wxString::Format( _( "%s must be less than %s." ),
379 val_max_iu,
380 true ) );
381
382 textEntry->SelectAll();
383
384 // Don't focus directly; we might be inside a KillFocus event handler
385 wxPostEvent( this, wxCommandEvent( DELAY_FOCUS ) );
386
387 return false;
388 }
389
390 return true;
391}
392
393
394void UNIT_BINDER::SetValue( long long int aValue )
395{
396 double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
397 wxString textValue = EDA_UNIT_UTILS::UI::StringFromValue( *m_iuScale, m_units, displayValue,
398 false, m_dataType );
399
400 if( displayValue == 0 && m_negativeZero )
401 SetValue( wxT( "-" ) + textValue );
402 else
403 SetValue( textValue );
404}
405
406
407void UNIT_BINDER::SetDoubleValue( double aValue )
408{
409 double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
411 setPrecision( displayValue, false ),
412 false, m_dataType );
413
414 if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
415 SetValue( wxT( "-" ) + textValue );
416 else
417 SetValue( textValue );
418}
419
420
422{
423 SetDoubleValue( aValue.AsDegrees() );
424}
425
426
427void UNIT_BINDER::SetValue( const wxString& aValue )
428{
429 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
430 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
431
432 wxString value = aValue;
433
434 if( m_unitsInValue && !value.IsEmpty() )
435 {
436 if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
437 value += wxT( " " );
438
440 }
441
442 if( textEntry )
443 textEntry->SetValue( value );
444 else if( staticText )
445 staticText->SetLabel( value );
446
447 if( m_allowEval )
448 m_eval.Clear();
449
450 if( m_unitLabel )
452
453}
454
455
456wxString UNIT_BINDER::getTextForValue( long long int aValue ) const
457{
458 const double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
459 wxString textValue = EDA_UNIT_UTILS::UI::StringFromValue(
460 *m_iuScale, m_units, setPrecision( displayValue, false ), false, m_dataType );
461
462 if( displayValue == 0 && m_negativeZero )
463 textValue = wxT( "-" ) + textValue;
464
465 return textValue;
466}
467
468
469wxString UNIT_BINDER::getTextForDoubleValue( double aValue ) const
470{
471 const double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
472 wxString textValue = EDA_UNIT_UTILS::UI::StringFromValue(
473 *m_iuScale, m_units, setPrecision( displayValue, false ), false, m_dataType );
474
475 if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
476 textValue = wxT( "-" ) + textValue;
477
478 return textValue;
479}
480
481
482void UNIT_BINDER::ChangeValue( int aValue )
483{
484 ChangeValue( getTextForValue( aValue ) );
485}
486
487
489{
491}
492
493
495{
496 ChangeDoubleValue( aValue.AsDegrees() );
497}
498
499
500void UNIT_BINDER::ChangeValue( const wxString& aValue )
501{
502 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
503 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
504
505 wxString value = aValue;
506
507 if( m_unitsInValue && !value.IsEmpty() )
508 {
509 if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
510 value += wxT( " " );
511
513 }
514
515 if( textEntry )
516 textEntry->ChangeValue( value );
517 else if( staticText )
518 staticText->SetLabel( value );
519
520 if( m_allowEval )
521 m_eval.Clear();
522
523 if( m_unitLabel )
525}
526
527
529{
530 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
531 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
532 wxString value;
533
534 if( textEntry )
535 {
536 value = textEntry->GetValue();
537
538 if( m_needsEval && !value.IsEmpty() && m_eval.Process( value ) )
539 value = m_eval.Result();
540 else
541 value = textEntry->GetValue();
542 }
543 else if( staticText )
544 {
545 value = staticText->GetLabel();
546 }
547 else
548 {
549 return 0;
550 }
551
552 long long int displayValue = EDA_UNIT_UTILS::UI::ValueFromString( *m_iuScale, m_units, value,
553 m_dataType );
554 return m_originTransforms.FromDisplay( displayValue, m_coordType );
555}
556
557
558double UNIT_BINDER::setPrecision( double aValue, bool aValueUsesUserUnits ) const
559{
560 if( m_precision > 1 )
561 {
562 int scale = pow( 10, m_precision );
563 int64_t tmp = aValue;
564
565 if( !aValueUsesUserUnits )
566 {
568 }
569
570 aValue = static_cast<double>( tmp ) / scale;
571
572 if( !aValueUsesUserUnits )
574 }
575
576 return aValue;
577}
578
579
581{
582 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
583 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
584 wxString value;
585
586 if( textEntry )
587 {
588 value = textEntry->GetValue();
589
590 if( m_needsEval && !value.IsEmpty() && m_eval.Process( value ) )
591 value = m_eval.Result();
592 else
593 value = textEntry->GetValue();
594 }
595 else if( staticText )
596 {
597 value = staticText->GetLabel();
598 }
599 else
600 {
601 return 0.0;
602 }
603
605 value, m_dataType );
606 displayValue = setPrecision( displayValue, false );
607
608 return m_originTransforms.FromDisplay( displayValue, m_coordType );
609}
610
611
613{
615}
616
617
618void UNIT_BINDER::SetOptionsList( std::span<const long long int> aOptions )
619{
620 wxComboBox* cb = dynamic_cast<wxComboBox*>( m_valueCtrl );
621 wxCHECK( cb, /* void */ );
622
623 cb->Clear();
624
625 for( long long int value : aOptions )
626 {
627 cb->Append( getTextForValue( value ) );
628 }
629}
630
631
632void UNIT_BINDER::SetDoubleOptionsList( std::span<const double> aOptions )
633{
634 wxComboBox* cb = dynamic_cast<wxComboBox*>( m_valueCtrl );
635 wxCHECK( cb, /* void */ );
636
637 cb->Clear();
638
639 for( double value : aOptions )
640 {
641 cb->Append( getTextForDoubleValue( value ) );
642 }
643}
644
645
647{
648 wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl );
649
650 if( te )
651 return te->GetValue() == INDETERMINATE_STATE || te->GetValue() == INDETERMINATE_ACTION;
652
653 return false;
654}
655
656
658{
659 if( wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl ) )
660 return te->GetValue().IsEmpty();
661
662 return false;
663}
664
665
667{
668 if( wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl ) )
669 return te->SetValue( wxEmptyString );
670}
671
672
673void UNIT_BINDER::SetLabel( const wxString& aLabel )
674{
675 m_label->SetLabel( aLabel );
676}
677
678
679void UNIT_BINDER::Enable( bool aEnable )
680{
681 if( m_label )
682 m_label->Enable( aEnable );
683
684 m_valueCtrl->Enable( aEnable );
685
686 if( m_unitLabel )
687 m_unitLabel->Enable( aEnable );
688}
689
690
691void UNIT_BINDER::Show( bool aShow, bool aResize )
692{
693 m_label->Show( aShow );
694 m_valueCtrl->Show( aShow );
695
696 if( m_unitLabel )
697 m_unitLabel->Show( aShow );
698
699 if( aResize )
700 {
701 if( aShow )
702 {
703 m_label->SetSize( -1, -1 );
704 m_valueCtrl->SetSize( -1, -1 );
705
706 if( m_unitLabel )
707 m_unitLabel->SetSize( -1, -1 );
708 }
709 else
710 {
711 m_label->SetSize( 0, 0 );
712 m_valueCtrl->SetSize( 0, 0 );
713
714 if( m_unitLabel )
715 m_unitLabel->SetSize( 0, 0 );
716 }
717 }
718}
719
720
722 UNIT_BINDER( aParent, nullptr, nullptr, nullptr, true, false )
723{
724 m_unitsInValue = true;
725}
726
727
729{
730}
731
733{
734 m_valueCtrl = aControl;
735
736 if( m_valueCtrl )
737 {
738 m_valueCtrl->Bind( wxEVT_SET_FOCUS, &PROPERTY_EDITOR_UNIT_BINDER::onSetFocus, this );
739 m_valueCtrl->Bind( wxEVT_KILL_FOCUS, &PROPERTY_EDITOR_UNIT_BINDER::onKillFocus, this );
740 m_valueCtrl->Bind( wxEVT_LEFT_UP, &PROPERTY_EDITOR_UNIT_BINDER::onClick, this );
741
742 m_valueCtrl->Bind( wxEVT_SHOW,
743 [&]( wxShowEvent& e )
744 {
745 if( !e.IsShown() )
746 SetControl( nullptr );
747 } );
748 }
749}
double AsDegrees() const
Definition: eda_angle.h:113
The base frame for deriving all KiCad main window classes.
The base class for create windows for drawing purpose.
wxString OriginalText() const
wxString Result() const
void SetDefaultUnits(EDA_UNITS aUnits)
bool Process(const wxString &aString)
A class to perform either relative or absolute display origin transforms for a single axis of a point...
virtual int FromDisplay(int aValue, COORD_TYPES_T aCoordType) const
virtual int ToDisplay(int aValue, COORD_TYPES_T aCoordType) const
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.
Definition: unit_binder.h:270
wxString getTextForValue(long long int aValue) const
int GetIntValue()
Definition: unit_binder.h:129
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)
virtual long long int GetValue()
Return the current value in Internal Units.
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...
bool m_allowEval
Definition: unit_binder.h:258
wxString getTextForDoubleValue(double aValue) const
const EDA_IU_SCALE * m_iuScale
Currently used units.
Definition: unit_binder.h:249
wxString m_errorMessage
Definition: unit_binder.h:255
virtual EDA_ANGLE GetAngleValue()
bool m_negativeZero
Indicates "-0" should be displayed for 0.
Definition: unit_binder.h:251
int m_precision
0 to 6.
Definition: unit_binder.h:253
wxStaticText * m_unitLabel
Can be nullptr.
Definition: unit_binder.h:246
bool m_unitsInValue
Units label should be included in value text.
Definition: unit_binder.h:264
wxWindow * m_valueCtrl
Definition: unit_binder.h:245
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)
Definition: unit_binder.cpp:41
wxStaticText * m_label
The bound widgets.
Definition: unit_binder.h:244
ORIGIN_TRANSFORMS & m_originTransforms
A reference to an ORIGIN_TRANSFORMS object.
Definition: unit_binder.h:267
bool m_bindFocusEvent
Definition: unit_binder.h:241
long m_selStart
Selection start and end of the original text.
Definition: unit_binder.h:261
virtual void SetDoubleOptionsList(std::span< const double > aOptions)
EDA_UNITS m_units
Definition: unit_binder.h:250
virtual double GetDoubleValue()
Return the current value in Internal 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...
bool m_needsEval
Definition: unit_binder.h:259
void SetDataType(EDA_DATA_TYPE aDataType)
Used to override the datatype of the displayed property (default is DISTANCE)
void delayedFocusHandler(wxCommandEvent &aEvent)
EDA_DATA_TYPE m_dataType
Definition: unit_binder.h:252
virtual void SetAngleValue(const EDA_ANGLE &aValue)
void SetLabel(const wxString &aLabel)
void init(UNITS_PROVIDER *aProvider)
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.
void SetNull()
virtual ~UNIT_BINDER() override
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
Definition: unit_binder.h:257
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:195
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:46
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",...
Definition: eda_units.cpp:487
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.
Definition: eda_units.cpp:648
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.
Definition: eda_units.cpp:290
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.
Definition: eda_units.cpp:553
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.
Definition: eda_units.cpp:261
KICOMMON_API wxString GetLabel(EDA_UNITS aUnits, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
Get the units string for a given units type.
Definition: eda_units.cpp:156
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)