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 ),
61 m_dataType( EDA_DATA_TYPE::DISTANCE ),
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
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 SetValue( conv );
239
240 aEvent.Skip();
241}
242
243
244void UNIT_BINDER::onSetFocus( wxFocusEvent& aEvent )
245{
246 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
247
248 if( textEntry )
249 {
250 if( m_allowEval )
251 {
252 wxString oldStr = m_eval.OriginalText();
253
254 if( oldStr.length() && oldStr != textEntry->GetValue() )
255 {
256 textEntry->ChangeValue( oldStr );
257 textEntry->SetSelection( m_selStart, m_selEnd );
258 }
259
260 m_needsEval = true;
261 }
262
263 if( textEntry->GetValue() == INDETERMINATE_ACTION
264 || textEntry->GetValue() == INDETERMINATE_STATE )
265 {
266 // These are tokens, not strings, so do a select all
267 textEntry->SelectAll();
268 }
269 }
270
271 aEvent.Skip();
272}
273
274
275void UNIT_BINDER::onKillFocus( wxFocusEvent& aEvent )
276{
277 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
278
279 if( m_allowEval && textEntry )
280 {
281 wxString value = textEntry->GetValue();
282 bool success = m_eval.Process( value );
283
284 if( success && !value.IsEmpty() )
285 {
286 textEntry->GetSelection( &m_selStart, &m_selEnd );
287
288 value = m_eval.Result();
289
290 if( m_unitsInValue && !value.IsEmpty() )
291 {
292 if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
293 value += wxT( " " );
294
296 }
297
298 textEntry->ChangeValue( value );
299
300#ifdef __WXGTK__
301 // Manually copy the selected text to the primary selection clipboard
302 if( wxTheClipboard->Open() )
303 {
304 wxString sel = textEntry->GetStringSelection();
305 bool clipTarget = wxTheClipboard->IsUsingPrimarySelection();
306 wxTheClipboard->UsePrimarySelection( true );
307 wxTheClipboard->SetData( new wxTextDataObject( sel ) );
308 wxTheClipboard->UsePrimarySelection( clipTarget );
309 wxTheClipboard->Close();
310 }
311#endif
312 }
313
314 m_needsEval = false;
315 }
316
317 aEvent.Skip();
318}
319
320
321wxString valueDescriptionFromLabel( wxStaticText* aLabel )
322{
323 wxString desc = aLabel->GetLabel();
324
325 desc.EndsWith( wxT( ":" ), &desc );
326 return desc;
327}
328
329
330void UNIT_BINDER::delayedFocusHandler( wxCommandEvent& )
331{
332 if( !m_errorMessage.IsEmpty() )
334
335 m_errorMessage = wxEmptyString;
336 m_valueCtrl->SetFocus();
337}
338
339
340bool UNIT_BINDER::Validate( double aMin, double aMax, EDA_UNITS aUnits )
341{
342 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
343
344 if( !textEntry
345 || textEntry->GetValue() == INDETERMINATE_ACTION
346 || textEntry->GetValue() == INDETERMINATE_STATE )
347 {
348 return true;
349 }
350
351 // TODO: Validate() does not currently support m_dataType being anything other than DISTANCE
352 // Note: aMin and aMax are not always given in internal units
353 if( GetValue() < FromUserUnit( *m_iuScale, aUnits, aMin ) )
354 {
355 double val_min_iu = FromUserUnit( *m_iuScale, aUnits, aMin );
356 m_errorMessage = wxString::Format( _( "%s must be at least %s." ),
358 StringFromValue( *m_iuScale, m_units, val_min_iu, true ) );
359
360 textEntry->SelectAll();
361
362 // Don't focus directly; we might be inside a KillFocus event handler
363 wxPostEvent( this, wxCommandEvent( DELAY_FOCUS ) );
364
365 return false;
366 }
367
368 if( GetValue() > FromUserUnit( *m_iuScale, aUnits, aMax ) )
369 {
370 double val_max_iu = FromUserUnit( *m_iuScale, aUnits, aMax );
371 m_errorMessage = wxString::Format( _( "%s must be less than %s." ),
373 StringFromValue( *m_iuScale, m_units, val_max_iu, true ) );
374
375 textEntry->SelectAll();
376
377 // Don't focus directly; we might be inside a KillFocus event handler
378 wxPostEvent( this, wxCommandEvent( DELAY_FOCUS ) );
379
380 return false;
381 }
382
383 return true;
384}
385
386
387void UNIT_BINDER::SetValue( long long int aValue )
388{
389 double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
390 wxString textValue = StringFromValue( *m_iuScale, m_units, displayValue, false, m_dataType );
391
392 if( displayValue == 0 && m_negativeZero )
393 SetValue( wxT( "-" ) + textValue );
394 else
395 SetValue( textValue );
396}
397
398
399void UNIT_BINDER::SetDoubleValue( double aValue )
400{
401 double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
402 wxString textValue = StringFromValue( *m_iuScale, m_units, setPrecision( displayValue, false ), false,
403 m_dataType );
404
405 if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
406 SetValue( wxT( "-" ) + textValue );
407 else
408 SetValue( textValue );
409}
410
411
413{
414 SetDoubleValue( aValue.AsDegrees() );
415}
416
417
418void UNIT_BINDER::SetValue( const wxString& aValue )
419{
420 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
421 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
422
423 wxString value = aValue;
424
425 if( m_unitsInValue && !value.IsEmpty() )
426 {
427 if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
428 value += wxT( " " );
429
431 }
432
433 if( textEntry )
434 textEntry->SetValue( value );
435 else if( staticText )
436 staticText->SetLabel( value );
437
438 if( m_allowEval )
439 m_eval.Clear();
440
441 if( m_unitLabel )
443
444}
445
446
447wxString UNIT_BINDER::getTextForValue( long long int aValue ) const
448{
449 const double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
450 wxString textValue = StringFromValue( *m_iuScale, m_units, setPrecision( displayValue, false ), false,
451 m_dataType );
452
453 if( displayValue == 0 && m_negativeZero )
454 textValue = wxT( "-" ) + textValue;
455
456 return textValue;
457}
458
459
460wxString UNIT_BINDER::getTextForDoubleValue( double aValue ) const
461{
462 const double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
463 wxString textValue = StringFromValue( *m_iuScale, m_units, setPrecision( displayValue, false ), false,
464 m_dataType );
465
466 if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
467 textValue = wxT( "-" ) + textValue;
468
469 return textValue;
470}
471
472
473void UNIT_BINDER::ChangeValue( int aValue )
474{
475 ChangeValue( getTextForValue( aValue ) );
476}
477
478
480{
482}
483
484
486{
487 ChangeDoubleValue( aValue.AsDegrees() );
488}
489
490
491void UNIT_BINDER::ChangeValue( const wxString& aValue )
492{
493 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
494 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
495
496 wxString value = aValue;
497
498 if( m_unitsInValue && !value.IsEmpty() )
499 {
500 if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
501 value += wxT( " " );
502
504 }
505
506 if( textEntry )
507 textEntry->ChangeValue( value );
508 else if( staticText )
509 staticText->SetLabel( value );
510
511 if( m_allowEval )
512 m_eval.Clear();
513
514 if( m_unitLabel )
516}
517
518
520{
521 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
522 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
523 wxString value;
524
525 if( textEntry )
526 {
527 value = textEntry->GetValue();
528
529 if( m_needsEval && !value.IsEmpty() && m_eval.Process( value ) )
530 value = m_eval.Result();
531 else
532 value = textEntry->GetValue();
533 }
534 else if( staticText )
535 {
536 value = staticText->GetLabel();
537 }
538 else
539 {
540 return 0;
541 }
542
543 long long int displayValue = ValueFromString( *m_iuScale, m_units, value, m_dataType );
544 return m_originTransforms.FromDisplay( displayValue, m_coordType );
545}
546
547
548double UNIT_BINDER::setPrecision( double aValue, bool aValueUsesUserUnits ) const
549{
550 if( m_precision > 1 )
551 {
552 int scale = pow( 10, m_precision );
553 int64_t tmp = aValue;
554
555 if( !aValueUsesUserUnits )
556 tmp = ToUserUnit( *m_iuScale, m_units, aValue ) * scale;
557
558 aValue = static_cast<double>( tmp ) / scale;
559
560 if( !aValueUsesUserUnits )
561 aValue = FromUserUnit( *m_iuScale, m_units, aValue );
562 }
563
564 return aValue;
565}
566
567
569{
570 wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
571 wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
572 wxString value;
573
574 if( textEntry )
575 {
576 value = textEntry->GetValue();
577
578 if( m_needsEval && !value.IsEmpty() && m_eval.Process( value ) )
579 value = m_eval.Result();
580 else
581 value = textEntry->GetValue();
582 }
583 else if( staticText )
584 {
585 value = staticText->GetLabel();
586 }
587 else
588 {
589 return 0.0;
590 }
591
592 double displayValue = DoubleValueFromString( *m_iuScale, m_units, value, m_dataType );
593 displayValue = setPrecision( displayValue, false );
594
595 return m_originTransforms.FromDisplay( displayValue, m_coordType );
596}
597
598
600{
602}
603
604
605void UNIT_BINDER::SetOptionsList( std::span<const long long int> aOptions )
606{
607 wxComboBox* cb = dynamic_cast<wxComboBox*>( m_valueCtrl );
608 wxCHECK( cb, /* void */ );
609
610 cb->Clear();
611
612 for( long long int value : aOptions )
613 cb->Append( getTextForValue( value ) );
614}
615
616
617void UNIT_BINDER::SetDoubleOptionsList( std::span<const double> aOptions )
618{
619 wxComboBox* cb = dynamic_cast<wxComboBox*>( m_valueCtrl );
620 wxCHECK( cb, /* void */ );
621
622 cb->Clear();
623
624 for( double value : aOptions )
625 cb->Append( getTextForDoubleValue( value ) );
626}
627
628
630{
631 wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl );
632
633 if( te )
634 return te->GetValue() == INDETERMINATE_STATE || te->GetValue() == INDETERMINATE_ACTION;
635
636 return false;
637}
638
639
641{
642 if( wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl ) )
643 return te->GetValue().IsEmpty();
644
645 return false;
646}
647
648
650{
651 if( wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl ) )
652 return te->SetValue( wxEmptyString );
653}
654
655
656void UNIT_BINDER::SetLabel( const wxString& aLabel )
657{
658 m_label->SetLabel( aLabel );
659}
660
661
662void UNIT_BINDER::Enable( bool aEnable )
663{
664 if( m_label )
665 m_label->Enable( aEnable );
666
667 m_valueCtrl->Enable( aEnable );
668
669 if( m_unitLabel )
670 m_unitLabel->Enable( aEnable );
671}
672
673
674void UNIT_BINDER::Show( bool aShow, bool aResize )
675{
676 m_label->Show( aShow );
677 m_valueCtrl->Show( aShow );
678
679 if( m_unitLabel )
680 m_unitLabel->Show( aShow );
681
682 if( aResize )
683 {
684 if( aShow )
685 {
686 m_label->SetSize( -1, -1 );
687 m_valueCtrl->SetSize( -1, -1 );
688
689 if( m_unitLabel )
690 m_unitLabel->SetSize( -1, -1 );
691 }
692 else
693 {
694 m_label->SetSize( 0, 0 );
695 m_valueCtrl->SetSize( 0, 0 );
696
697 if( m_unitLabel )
698 m_unitLabel->SetSize( 0, 0 );
699 }
700 }
701}
702
703
705 UNIT_BINDER( aParent, nullptr, nullptr, nullptr, true, false )
706{
707 m_unitsInValue = true;
708}
709
710
712{
713}
714
716{
717 m_valueCtrl = aControl;
718
719 if( m_valueCtrl )
720 {
721 m_valueCtrl->Bind( wxEVT_SET_FOCUS, &PROPERTY_EDITOR_UNIT_BINDER::onSetFocus, this );
722 m_valueCtrl->Bind( wxEVT_KILL_FOCUS, &PROPERTY_EDITOR_UNIT_BINDER::onKillFocus, this );
723 m_valueCtrl->Bind( wxEVT_LEFT_UP, &PROPERTY_EDITOR_UNIT_BINDER::onClick, this );
724
725 m_valueCtrl->Bind( wxEVT_SHOW,
726 [&]( wxShowEvent& e )
727 {
728 if( !e.IsShown() )
729 SetControl( nullptr );
730 } );
731 }
732}
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
Definition: dialog_shim.h:61
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.
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:275
wxString getTextForValue(long long int aValue) const
int GetIntValue()
Definition: unit_binder.h:134
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:263
wxString getTextForDoubleValue(double aValue) const
const EDA_IU_SCALE * m_iuScale
Currently used units.
Definition: unit_binder.h:254
wxString m_errorMessage
Definition: unit_binder.h:260
virtual EDA_ANGLE GetAngleValue()
bool m_negativeZero
Indicates "-0" should be displayed for 0.
Definition: unit_binder.h:256
int m_precision
0 to 6.
Definition: unit_binder.h:258
wxStaticText * m_unitLabel
Can be nullptr.
Definition: unit_binder.h:251
bool m_unitsInValue
Units label should be included in value text.
Definition: unit_binder.h:269
wxWindow * m_valueCtrl
Definition: unit_binder.h:249
wxWindow * m_eventSource
Definition: unit_binder.h:250
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:44
wxStaticText * m_label
The bound widgets.
Definition: unit_binder.h:248
ORIGIN_TRANSFORMS & m_originTransforms
A reference to an ORIGIN_TRANSFORMS object.
Definition: unit_binder.h:272
bool m_bindFocusEvent
Definition: unit_binder.h:245
long m_selStart
Selection start and end of the original text.
Definition: unit_binder.h:266
virtual void SetDoubleOptionsList(std::span< const double > aOptions)
EDA_UNITS m_units
Definition: unit_binder.h:255
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:264
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:257
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.
void SetNull()
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
Definition: unit_binder.h:262
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",...
Definition: eda_units.cpp:509
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:689
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:310
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:569
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:289
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:180
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)