22#include <wx/clipbrd.h>
23#include <wx/combobox.h>
24#include <wx/stattext.h>
25#include <wx/textentry.h>
33#include "wx/dcclient.h"
42 wxStaticText* aUnitLabel,
bool allowEval,
bool aBindFrameEvents ) :
43 UNIT_BINDER( aParent, aParent, aLabel, aValueCtrl, aUnitLabel, allowEval, aBindFrameEvents )
48 wxWindow* aValueCtrl, wxStaticText* aUnitLabel,
bool aAllowEval,
49 bool aBindFocusEvent ) :
55 m_iuScale( &aUnitsProvider->GetIuScale() ),
56 m_units( aUnitsProvider->GetUserUnits() ),
60 m_eval( aUnitsProvider->GetUserUnits() ),
72 evalCtrl->DeferToBinder();
77 wxWindow* parent = m_valueCtrl->GetParent();
79 while( parent && !dynamic_cast<DIALOG_SHIM*>( parent ) )
80 parent = parent->GetParent();
84 m_dialogShim = static_cast<DIALOG_SHIM*>( parent );
85 m_dialogShim->RegisterUnitBinder( this, m_valueCtrl );
89 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>( m_valueCtrl );
93 wxClientDC dc( m_valueCtrl );
95 wxSize
minSize = m_valueCtrl->GetMinSize();
98 if( m_iuScale->IU_PER_MM <=
schIUScale.IU_PER_MM )
101 minWidth = dc.GetTextExtent( wxT(
"XXX.XXXXX" ) ).GetWidth();
107 minWidth = dc.GetTextExtent( wxT(
"XXX.XXXXXXXX" ) ).GetWidth();
110 if(
minSize.GetWidth() < minWidth )
111 m_valueCtrl->SetMinSize( wxSize( minWidth,
minSize.GetHeight() ) );
115 textEntry->ChangeValue( wxT(
"-0" ) );
117 textEntry->ChangeValue( wxT(
"0" ) );
125 m_valueCtrl->Connect( wxEVT_DESTROY, wxWindowDestroyEventHandler( UNIT_BINDER::onValueCtrlDestroyed ),
127 m_valueCtrl->Connect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ), nullptr, this );
128 m_valueCtrl->Connect( wxEVT_KILL_FOCUS, wxFocusEventHandler( UNIT_BINDER::onKillFocus ), nullptr, this );
129 m_valueCtrl->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( UNIT_BINDER::onClick ), nullptr, this );
130 m_valueCtrl->Connect( wxEVT_COMBOBOX, wxCommandEventHandler( UNIT_BINDER::onComboBox ), nullptr, this );
133 if( m_bindFocusEvent )
205 wxComboBox*
const combo =
dynamic_cast<wxComboBox*
>(
m_valueCtrl );
206 std::vector<long long int> comboValues;
211 for(
unsigned int i = 0; i < combo->GetCount(); i++ )
213 const wxString value = combo->GetString( i );
215 comboValues.push_back( conv );
219 SetUnits( provider->GetUserUnits() );
237 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
243 textEntry->SelectAll();
253 wxComboBox* combo =
dynamic_cast<wxComboBox*
>(
m_valueCtrl );
256 const wxString value = combo->GetStringSelection();
291 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
297 wxString oldStr =
m_eval.OriginalText();
299 if( oldStr.length() && oldStr != textEntry->GetValue() )
301 textEntry->ChangeValue( oldStr );
312 textEntry->SelectAll();
322 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
326 wxString value = textEntry->GetValue();
327 bool success =
m_eval.Process( value );
329 if( success && !value.IsEmpty() )
343 textEntry->ChangeValue( value );
347 if( wxTheClipboard->Open() )
349 wxString sel = textEntry->GetStringSelection();
350 bool clipTarget = wxTheClipboard->IsUsingPrimarySelection();
351 wxTheClipboard->UsePrimarySelection(
true );
352 wxTheClipboard->SetData(
new wxTextDataObject( sel ) );
353 wxTheClipboard->UsePrimarySelection( clipTarget );
354 wxTheClipboard->Close();
368 wxString desc = aLabel->GetLabel();
370 desc.EndsWith( wxT(
":" ), &desc );
398 default: conversions = 1;
break;
401 double boundIU = aBound;
403 for(
int i = 0; i < conversions; ++i )
404 boundIU =
FromUserUnit( aIuScale, aBoundUnits, boundIU );
409 return { boundIU,
StringFromValue( aIuScale, aDisplayUnits, boundIU, addUnitsText, aDataType ) };
415 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
434 textEntry->SelectAll();
437 wxPostEvent(
this, wxCommandEvent( DELAY_FOCUS ) );
448 textEntry->SelectAll();
451 wxPostEvent(
this, wxCommandEvent( DELAY_FOCUS ) );
471 if( !formula.IsEmpty() )
472 m_eval.Process( formula );
482 if( displayValue == 0 && !std::signbit( displayValue ) &&
m_negativeZero )
497 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
498 wxStaticText* staticText =
dynamic_cast<wxStaticText*
>(
m_valueCtrl );
500 wxString value = aValue;
511 textEntry->SetValue( value );
512 else if( staticText )
513 staticText->SetLabel( value );
531 textValue = wxT(
"-" ) + textValue;
543 if( displayValue == 0 && !std::signbit( displayValue ) &&
m_negativeZero )
544 textValue = wxT(
"-" ) + textValue;
552 wxString formula =
m_eval.OriginalText();
556 return wxEmptyString;
561 return wxEmptyString;
573 if( !formula.IsEmpty() )
574 m_eval.Process( formula );
592 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
593 wxStaticText* staticText =
dynamic_cast<wxStaticText*
>(
m_valueCtrl );
595 wxString value = aValue;
606 textEntry->ChangeValue( value );
607 else if( staticText )
608 staticText->SetLabel( value );
620 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
623 return wxEmptyString;
629 formula.Trim(
true ).Trim(
false );
631 if( formula.IsEmpty() || formula.ToDouble( &plainNumber ) || formula.ToCDouble( &plainNumber ) )
632 return wxEmptyString;
634 return m_eval.Process( formula ) ? formula : wxString();
643 if( !
m_eval.Process( aFormula ) )
652 m_eval.Process( aFormula );
668 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
669 wxStaticText* staticText =
dynamic_cast<wxStaticText*
>(
m_valueCtrl );
674 value = textEntry->GetValue();
679 value = textEntry->GetValue();
681 else if( staticText )
683 value = staticText->GetLabel();
700 int64_t tmp = aValue;
702 if( !aValueUsesUserUnits )
705 aValue =
static_cast<double>( tmp ) /
scale;
707 if( !aValueUsesUserUnits )
717 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
718 wxStaticText* staticText =
dynamic_cast<wxStaticText*
>(
m_valueCtrl );
723 value = textEntry->GetValue();
728 value = textEntry->GetValue();
730 else if( staticText )
732 value = staticText->GetLabel();
754 wxComboBox* cb =
dynamic_cast<wxComboBox*
>(
m_valueCtrl );
759 for(
long long int value : aOptions )
766 wxComboBox* cb =
dynamic_cast<wxComboBox*
>(
m_valueCtrl );
771 for(
double value : aOptions )
778 wxTextEntry* te =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
789 if( wxTextEntry* te =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl ) )
790 return te->GetValue().IsEmpty();
798 if( wxTextEntry* te =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl ) )
799 return te->SetValue( wxEmptyString );
852 UNIT_BINDER( aParent, nullptr, nullptr, nullptr, true, false )
873 [&]( wxShowEvent& e )
constexpr EDA_IU_SCALE schIUScale
The base frame for deriving all KiCad main window classes.
The base class for create windows for drawing purpose.
void SetControl(wxWindow *aControl)
PROPERTY_EDITOR_UNIT_BINDER(EDA_DRAW_FRAME *aParent)
virtual ~PROPERTY_EDITOR_UNIT_BINDER()
wxTextCtrl wrapper to handle math expression evaluation.
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)
DIALOG_SHIM * m_dialogShim
The dialog this binder registered itself with, or nullptr if it isn't owned by a dialog.
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 wxString GetFormula() const
Return the expression the user entered if it is more than a plain number, otherwise an empty string.
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.
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.
wxString formulaYielding(long long int aValue) const
Return the retained expression if it evaluates to aValue, otherwise an empty string.
static RANGE_BOUND ConvertRangeBound(const EDA_IU_SCALE &aIuScale, EDA_UNITS aBoundUnits, double aBound, EDA_UNITS aDisplayUnits, EDA_DATA_TYPE aDataType)
Convert a range bound and format its display string honoring aDataType.
wxStaticText * m_unitLabel
Can be nullptr.
bool m_unitsInValue
Units label should be included in value text.
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.
virtual void RestoreValue(int aValue, const wxString &aFormula)
Set a value (in Internal Units) as ChangeValue() does and reinstate the expression that produced it.
virtual bool RestoreFormula(const wxString &aFormula)
Show the result of an expression returned by GetFormula() and retain the expression so that it reappe...
ORIGIN_TRANSFORMS & m_originTransforms
A reference to an ORIGIN_TRANSFORMS object.
long m_selStart
Selection start and end of the original text.
virtual void SetDoubleOptionsList(std::span< const double > aOptions)
void onValueCtrlDestroyed(wxWindowDestroyEvent &aEvent)
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)
void delayedFocusHandler(wxCommandEvent &aEvent)
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
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.
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.
This file is part of the common library.
const int minSize
Push and Shove router track width and via size dialog.
EDA_DATA_TYPE
The type of unit.
static wxString valueDescriptionFromLabel(wxStaticText *aLabel)
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.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
A range bound converted to internal units together with its user-facing display string.
#define INDETERMINATE_ACTION
#define INDETERMINATE_STATE
Used for holding indeterminate values, such as with multiple selections holding different values or c...
wxDEFINE_EVENT(DELAY_FOCUS, wxCommandEvent)
static wxString valueDescriptionFromLabel(wxStaticText *aLabel)