22#include <wx/stattext.h>
23#include <wx/textentry.h>
32 wxWindow* aValueCtrl, wxStaticText* aUnitLabel ) :
39 wxWindow* aEventSource, wxStaticText* aLabel,
40 wxWindow* aValueCtrl, wxStaticText* aUnitLabel ) :
45 m_iuScale( &aUnitsProvider->GetIuScale() ),
46 m_units( aUnitsProvider->GetUserUnits() ),
47 m_eval( aUnitsProvider->GetUserUnits() ),
147 text.Trim(
true ).Trim(
false );
148 return text.IsEmpty();
228 std::optional<int> offset;
229 std::optional<double> ratio;
264 std::optional<double>& aRatio )
const
266 aOffset = std::nullopt;
267 aRatio = std::nullopt;
269 wxString input = aInput;
270 input.Trim(
true ).Trim(
false );
272 if( input.IsEmpty() )
280 bool lastWasOperator =
true;
282 for(
size_t i = 0; i < input.Length(); ++i )
284 wxChar ch = input[i];
286 if( ( ch ==
'+' || ch ==
'-' ) && !lastWasOperator )
292 lastWasOperator =
true;
297 lastWasOperator = ( ch ==
'+' || ch ==
'-' );
303 wxString currentTerm;
305 for(
size_t i = 0; i < normalized.Length(); ++i )
307 wxChar ch = normalized[i];
311 if( !currentTerm.IsEmpty() )
313 currentTerm.Trim(
true ).Trim(
false );
314 terms.Add( currentTerm );
324 if( !currentTerm.IsEmpty() )
326 currentTerm.Trim(
true ).Trim(
false );
327 terms.Add( currentTerm );
331 double totalOffset = 0.0;
332 double totalRatio = 0.0;
333 bool hasOffset =
false;
334 bool hasRatio =
false;
337 for(
const wxString& term : terms )
344 else if( term ==
"-" )
351 if( term.EndsWith(
"%" ) )
353 wxString numPart = term.Left( term.Length() - 1 );
354 numPart.Trim(
true ).Trim(
false );
357 if( numPart.ToDouble( &value ) )
359 totalRatio +=
sign * value / 100.0;
373 if(
result.ToDouble( &value ) )
377 totalOffset +=
sign * iuValue;
387 aOffset =
static_cast<int>( totalOffset );
392 return hasOffset || hasRatio || input.IsEmpty();
397 std::optional<double> aRatio )
const
402 if( aOffset.has_value() && aOffset.value() != 0 )
408 if( aRatio.has_value() &&
std::abs( aRatio.value() ) > 1e-9 )
410 double percent = aRatio.value() * 100.0;
416 result += wxString::Format(
" + %.4g%%", percent );
418 result += wxString::Format(
" - %.4g%%", -percent );
422 result = wxString::Format(
"%.4g%%", percent );
432 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
435 return textEntry->GetValue();
437 return wxEmptyString;
443 wxTextEntry* textEntry =
dynamic_cast<wxTextEntry*
>(
m_valueCtrl );
446 textEntry->ChangeValue( aValue );
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)
const EDA_IU_SCALE & GetIuScale() const
EDA_UNITS GetUserUnits() const
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)