22#include <wx/stattext.h>
23#include <wx/textentry.h>
32 wxStaticText* aUnitLabel ) :
39 wxStaticText* aLabel, wxWindow* aValueCtrl, wxStaticText* aUnitLabel ) :
44 m_iuScale( &aUnitsProvider->GetIuScale() ),
45 m_units( aUnitsProvider->GetUserUnits() ),
46 m_eval( aUnitsProvider->GetUserUnits() ),
138 text.Trim(
true ).Trim(
false );
139 return text.IsEmpty();
217 wxString desc = aLabel->GetLabel();
219 desc.EndsWith( wxT(
":" ), &desc );
226 std::optional<int> offset;
227 std::optional<double> ratio;
231 return wxString::Format(
_(
"%s could not be parsed as a distance and/or percentage offset." ),
235 return wxEmptyString;
243 std::optional<int> offset;
244 std::optional<double> ratio;
267 m_units = provider->GetUserUnits();
280 std::optional<double>& aRatio )
const
282 aOffset = std::nullopt;
283 aRatio = std::nullopt;
285 wxString input = aInput;
286 input.Trim(
true ).Trim(
false );
288 if( input.IsEmpty() )
296 bool lastWasOperator =
true;
298 for(
size_t i = 0; i < input.Length(); ++i )
300 wxChar ch = input[i];
302 if( ( ch ==
'+' || ch ==
'-' ) && !lastWasOperator )
308 lastWasOperator =
true;
313 lastWasOperator = ( ch ==
'+' || ch ==
'-' );
319 wxString currentTerm;
321 for(
size_t i = 0; i <
normalized.Length(); ++i )
327 if( !currentTerm.IsEmpty() )
329 currentTerm.Trim(
true ).Trim(
false );
330 terms.Add( currentTerm );
340 if( !currentTerm.IsEmpty() )
342 currentTerm.Trim(
true ).Trim(
false );
343 terms.Add( currentTerm );
347 double totalOffset = 0.0;
348 double totalRatio = 0.0;
349 bool hasOffset =
false;
350 bool hasRatio =
false;
353 for(
const wxString& term : terms )
360 else if( term ==
"-" )
366 bool invalidTerm =
true;
369 if( term.EndsWith(
"%" ) )
371 wxString numPart = term.Left( term.Length() - 1 );
372 numPart.Trim(
true ).Trim(
false );
375 if( numPart.ToDouble( &value ) )
377 totalRatio +=
sign * value / 100.0;
392 if(
result.ToDouble( &value ) )
396 totalOffset +=
sign * iuValue;
410 aOffset =
static_cast<int>( totalOffset );
415 return hasOffset || hasRatio;
424 if( aOffset.has_value() && aOffset.value() != 0 )
430 if( aRatio.has_value() &&
std::abs( aRatio.value() ) > 1e-9 )
432 double percent = aRatio.value() * 100.0;
438 result += wxString::Format(
" + %.4g%%", percent );
440 result += wxString::Format(
" - %.4g%%", -percent );
444 result = wxString::Format(
"%.4g%%", percent );
447 else if( aOffset.has_value() && aOffset.value() == 0 )
459 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
462 return textEntry->GetValue();
464 return wxEmptyString;
470 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
473 textEntry->ChangeValue( aValue );
static std::optional< VECTOR2D > normalized(const VECTOR2D &aVec)
The base frame for deriving all KiCad main window classes.
The base class for create windows for drawing purpose.
bool IsNull() const
Return true if the control holds no value (ie: empty string).
std::optional< int > GetOffsetValue() const
Get the absolute offset value (in Internal Units).
void onTextChanged(wxCommandEvent &aEvent)
MARGIN_OFFSET_BINDER(EDA_DRAW_FRAME *aParent, wxStaticText *aLabel, wxWindow *aValueCtrl, wxStaticText *aUnitLabel)
std::optional< double > GetRatioValue() const
Get the ratio value as a fraction (e.g., -0.05 for -5%).
const EDA_IU_SCALE * m_iuScale
virtual ~MARGIN_OFFSET_BINDER() override
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
void onSetFocus(wxFocusEvent &aEvent)
bool parseInput(const wxString &aInput, std::optional< int > &aOffset, std::optional< double > &aRatio) const
Parse the input string and extract offset and ratio values.
wxStaticText * m_unitLabel
Can be nullptr.
void SetRatioValue(std::optional< double > aRatio)
Set the ratio value as a fraction (e.g., -0.05 for -5%).
std::optional< int > m_cachedOffset
void Show(bool aShow, bool aResize=false)
Show/hide the label, widget and units label.
std::optional< double > m_cachedRatio
wxString getTextValue() const
Get the current text from the control.
void onKillFocus(wxFocusEvent &aEvent)
void setTextValue(const wxString &aValue)
Set the text in the control without triggering events.
wxString formatValue(std::optional< int > aOffset, std::optional< double > aRatio) const
Format the offset and ratio values into a display string.
void onUnitsChanged(wxCommandEvent &aEvent)
void SetOffsetValue(std::optional< int > aValue)
Set the absolute offset value (in Internal Units).
bool Process(const wxString &aString)
static wxString valueDescriptionFromLabel(wxStaticText *aLabel)
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.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
wxString result
Test unit parsing edge cases and error handling.
constexpr int sign(T val)