UNIT_BINDER: Handle binding of combo-box option lists

This is useful if you want to give some preset options
to a user (e.g. recently used value) but stil have them
controlled and presented using the UNIT_BINDER logic.
This commit is contained in:
John Beard 2024-09-19 06:23:11 +01:00
parent 0d2371c9c3
commit 46e7228945
2 changed files with 116 additions and 22 deletions

View File

@ -24,6 +24,7 @@
*/
#include <wx/clipbrd.h>
#include <wx/combobox.h>
#include <wx/stattext.h>
#include <wx/textentry.h>
#include <eda_units.h>
@ -93,6 +94,8 @@ UNIT_BINDER::UNIT_BINDER( UNITS_PROVIDER* aUnitsProvider, wxWindow* aEventSource
nullptr, this );
m_valueCtrl->Connect( wxEVT_LEFT_UP, wxMouseEventHandler( UNIT_BINDER::onClick ),
nullptr, this );
m_valueCtrl->Connect( wxEVT_COMBOBOX, wxCommandEventHandler( UNIT_BINDER::onComboBox ),
nullptr, this );
}
if( m_bindFocusEvent )
@ -121,11 +124,13 @@ UNIT_BINDER::~UNIT_BINDER()
if( m_valueCtrl )
{
m_valueCtrl->Disconnect( wxEVT_SET_FOCUS, wxFocusEventHandler( UNIT_BINDER::onSetFocus ),
nullptr, this );
nullptr, this );
m_valueCtrl->Disconnect( wxEVT_KILL_FOCUS, wxFocusEventHandler( UNIT_BINDER::onKillFocus ),
nullptr, this );
nullptr, this );
m_valueCtrl->Disconnect( wxEVT_LEFT_UP, wxMouseEventHandler( UNIT_BINDER::onClick ),
nullptr, this );
nullptr, this );
m_valueCtrl->Disconnect( wxEVT_COMBOBOX, wxCommandEventHandler( UNIT_BINDER::onComboBox ),
nullptr, this );
}
}
@ -176,9 +181,30 @@ void UNIT_BINDER::onUnitsChanged( wxCommandEvent& aEvent )
{
int temp = GetIntValue();
wxComboBox* const combo = dynamic_cast<wxComboBox*>( m_valueCtrl );
std::vector<long long int> comboValues;
// Read out the current values
if( combo )
{
for( unsigned int i = 0; i < combo->GetCount(); i++ )
{
const wxString value = combo->GetString( i );
long long int conv = EDA_UNIT_UTILS::UI::ValueFromString( *m_iuScale, m_units,
value, m_dataType );
comboValues.push_back( conv );
}
}
SetUnits( provider->GetUserUnits() );
m_iuScale = &provider->GetIuScale();
// Re-populate the combo box with updated values
if( combo )
{
SetOptionsList( comboValues );
}
if( !IsIndeterminate() )
SetValue( temp );
}
@ -203,6 +229,21 @@ void UNIT_BINDER::onClick( wxMouseEvent& aEvent )
}
void UNIT_BINDER::onComboBox( wxCommandEvent& aEvent )
{
wxComboBox* combo = dynamic_cast<wxComboBox*>( m_valueCtrl );
wxCHECK( combo, /*void*/ );
const wxString value = combo->GetStringSelection();
const long long int conv =
EDA_UNIT_UTILS::UI::ValueFromString( *m_iuScale, m_units, value, m_dataType );
SetValue( conv );
aEvent.Skip();
}
void UNIT_BINDER::onSetFocus( wxFocusEvent& aEvent )
{
wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
@ -411,31 +452,41 @@ void UNIT_BINDER::SetValue( const wxString& aValue )
}
void UNIT_BINDER::ChangeValue( int aValue )
wxString UNIT_BINDER::getTextForValue( long long int aValue ) const
{
double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
wxString textValue = EDA_UNIT_UTILS::UI::StringFromValue( *m_iuScale, m_units,
setPrecision( displayValue, false ),
false, m_dataType );
const double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
wxString textValue = EDA_UNIT_UTILS::UI::StringFromValue(
*m_iuScale, m_units, setPrecision( aValue, false ), false, m_dataType );
if( displayValue == 0 && m_negativeZero )
ChangeValue( wxT( "-" ) + textValue );
else
ChangeValue( textValue );
textValue = wxT( "-" ) + textValue;
return textValue;
}
wxString UNIT_BINDER::getTextForDoubleValue( double aValue ) const
{
const double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
wxString textValue = EDA_UNIT_UTILS::UI::StringFromValue(
*m_iuScale, m_units, setPrecision( displayValue, false ), false, m_dataType );
if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
textValue = wxT( "-" ) + textValue;
return textValue;
}
void UNIT_BINDER::ChangeValue( int aValue )
{
ChangeValue( getTextForValue( aValue ) );
}
void UNIT_BINDER::ChangeDoubleValue( double aValue )
{
double displayValue = m_originTransforms.ToDisplay( aValue, m_coordType );
wxString textValue = EDA_UNIT_UTILS::UI::StringFromValue( *m_iuScale, m_units,
setPrecision( displayValue, false ),
false, m_dataType );
if( displayValue == 0 && !std::signbit( displayValue ) && m_negativeZero )
ChangeValue( wxT( "-" ) + textValue );
else
ChangeValue( textValue );
ChangeValue( getTextForDoubleValue( aValue ) );
}
@ -503,7 +554,7 @@ long long int UNIT_BINDER::GetValue()
}
double UNIT_BINDER::setPrecision( double aValue, bool aValueUsesUserUnits )
double UNIT_BINDER::setPrecision( double aValue, bool aValueUsesUserUnits ) const
{
if( m_precision > 1 )
{
@ -562,6 +613,34 @@ EDA_ANGLE UNIT_BINDER::GetAngleValue()
}
void UNIT_BINDER::SetOptionsList( std::span<const long long int> aOptions )
{
wxComboBox* cb = dynamic_cast<wxComboBox*>( m_valueCtrl );
wxCHECK( cb, /* void */ );
cb->Clear();
for( long long int value : aOptions )
{
cb->Append( getTextForValue( value ) );
}
}
void UNIT_BINDER::SetDoubleOptionsList( std::span<const double> aOptions )
{
wxComboBox* cb = dynamic_cast<wxComboBox*>( m_valueCtrl );
wxCHECK( cb, /* void */ );
cb->Clear();
for( double value : aOptions )
{
cb->Append( getTextForDoubleValue( value ) );
}
}
bool UNIT_BINDER::IsIndeterminate() const
{
wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl );

View File

@ -26,6 +26,8 @@
#ifndef __UNIT_BINDER_H_
#define __UNIT_BINDER_H_
#include <span>
#include <base_units.h>
#include <units_provider.h>
#include <libeval/numeric_evaluator.h>
@ -136,6 +138,15 @@ public:
virtual EDA_ANGLE GetAngleValue();
/**
* Set the list of options for a combobox control.
*
* Doesn't affect the value of the control.
*/
virtual void SetOptionsList( std::span<const long long int> aOptions );
virtual void SetDoubleOptionsList( std::span<const double> aOptions );
/**
* Return true if the control holds the indeterminate value (for instance, if it
* represents a multiple selection of differing values).
@ -201,6 +212,7 @@ public:
protected:
void init( UNITS_PROVIDER* aProvider );
void onClick( wxMouseEvent& aEvent );
void onComboBox( wxCommandEvent& aEvent );
void onSetFocus( wxFocusEvent& aEvent );
void onKillFocus( wxFocusEvent& aEvent );
@ -219,7 +231,10 @@ protected:
* and set to false if aValue is a internal unit value.
* @return the "rounded" value.
*/
double setPrecision( double aValue, bool aValueUsesUserUnits );
double setPrecision( double aValue, bool aValueUsesUserUnits ) const;
wxString getTextForValue( long long int aValue ) const;
wxString getTextForDoubleValue( double aValue ) const;
protected:
bool m_bindFocusEvent;