Add nullable int and double to property system.
This commit is contained in:
parent
876449b83d
commit
e62b4f8ff4
|
@ -584,6 +584,7 @@ set( COMMON_SRCS
|
|||
properties/pg_editors.cpp
|
||||
properties/pg_properties.cpp
|
||||
properties/property_mgr.cpp
|
||||
properties/std_optional_variants.cpp
|
||||
|
||||
database/database_connection.cpp
|
||||
database/database_lib_settings.cpp
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2022-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#include <eda_draw_frame.h>
|
||||
#include <dialogs/dialog_color_picker.h>
|
||||
#include <properties/std_optional_variants.h>
|
||||
#include <properties/eda_angle_variant.h>
|
||||
#include <properties/pg_editors.h>
|
||||
#include <properties/pg_properties.h>
|
||||
|
@ -30,6 +30,7 @@
|
|||
const wxString PG_UNIT_EDITOR::EDITOR_NAME = wxS( "KiCadUnitEditor" );
|
||||
const wxString PG_CHECKBOX_EDITOR::EDITOR_NAME = wxS( "KiCadCheckboxEditor" );
|
||||
const wxString PG_COLOR_EDITOR::EDITOR_NAME = wxS( "KiCadColorEditor" );
|
||||
const wxString PG_RATIO_EDITOR::EDITOR_NAME = wxS( "KiCadRatioEditor" );
|
||||
|
||||
|
||||
PG_UNIT_EDITOR::PG_UNIT_EDITOR( EDA_DRAW_FRAME* aFrame ) :
|
||||
|
@ -108,7 +109,16 @@ void PG_UNIT_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) c
|
|||
{
|
||||
wxVariant var = aProperty->GetValue();
|
||||
|
||||
if( var.GetType() == wxPG_VARIANT_TYPE_LONG )
|
||||
if( var.GetType() == wxT( "std::optional<int>" ) )
|
||||
{
|
||||
auto* variantData = static_cast<STD_OPTIONAL_INT_VARIANT_DATA*>( var.GetData() );
|
||||
|
||||
if( variantData->Value().has_value() )
|
||||
m_unitBinder->ChangeValue( variantData->Value().value() );
|
||||
else
|
||||
m_unitBinder->ChangeValue( wxEmptyString );
|
||||
}
|
||||
else if( var.GetType() == wxPG_VARIANT_TYPE_LONG )
|
||||
{
|
||||
m_unitBinder->ChangeValue( var.GetLong() );
|
||||
}
|
||||
|
@ -161,11 +171,12 @@ bool PG_UNIT_EDITOR::GetValueFromControl( wxVariant& aVariant, wxPGProperty* aPr
|
|||
wxCHECK_MSG( textCtrl, false, "PG_UNIT_EDITOR requires a text control!" );
|
||||
wxString textVal = textCtrl->GetValue();
|
||||
|
||||
if( aProperty->UsesAutoUnspecified() && textVal.empty() )
|
||||
if( textVal == wxT( "<...>" ) )
|
||||
{
|
||||
aVariant.MakeNull();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool changed;
|
||||
|
||||
if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) != nullptr )
|
||||
|
@ -205,6 +216,33 @@ bool PG_UNIT_EDITOR::GetValueFromControl( wxVariant& aVariant, wxPGProperty* aPr
|
|||
m_unitBinder->SetDoubleValue( result.ToDouble() );
|
||||
}
|
||||
}
|
||||
else if( aVariant.GetType() == wxT( "std::optional<int>" ) )
|
||||
{
|
||||
auto* variantData = static_cast<STD_OPTIONAL_INT_VARIANT_DATA*>( aVariant.GetData() );
|
||||
std::optional<int> result;
|
||||
|
||||
if( m_unitBinder->IsNull() )
|
||||
{
|
||||
changed = ( aVariant.IsNull() || variantData->Value().has_value() );
|
||||
|
||||
if( changed )
|
||||
{
|
||||
aVariant = wxVariant( std::optional<int>() );
|
||||
m_unitBinder->SetValue( wxEmptyString );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = std::optional<int>( m_unitBinder->GetValue() );
|
||||
changed = ( aVariant.IsNull() || result != variantData->Value() );
|
||||
|
||||
if( changed )
|
||||
{
|
||||
aVariant = wxVariant( result );
|
||||
m_unitBinder->SetValue( result.value() );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
long result = m_unitBinder->GetValue();
|
||||
|
@ -321,3 +359,91 @@ KIGFX::COLOR4D PG_COLOR_EDITOR::colorFromProperty( wxPGProperty* aProperty ) con
|
|||
{
|
||||
return colorFromVariant( aProperty->GetValue() );
|
||||
}
|
||||
|
||||
|
||||
bool PG_RATIO_EDITOR::GetValueFromControl( wxVariant& aVariant, wxPGProperty* aProperty,
|
||||
wxWindow* aCtrl ) const
|
||||
{
|
||||
wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl );
|
||||
wxCHECK_MSG( textCtrl, false, "PG_RATIO_EDITOR requires a text control!" );
|
||||
wxString textVal = textCtrl->GetValue();
|
||||
|
||||
if( textVal == wxT( "<...>" ) )
|
||||
{
|
||||
aVariant.MakeNull();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool changed;
|
||||
|
||||
if( aVariant.GetType() == wxT( "std::optional<double>" ) )
|
||||
{
|
||||
auto* variantData = static_cast<STD_OPTIONAL_DOUBLE_VARIANT_DATA*>( aVariant.GetData() );
|
||||
|
||||
if( textVal.empty() )
|
||||
{
|
||||
changed = ( aVariant.IsNull() || variantData->Value().has_value() );
|
||||
|
||||
if( changed )
|
||||
aVariant = wxVariant( std::optional<double>() );
|
||||
}
|
||||
else
|
||||
{
|
||||
double dblValue;
|
||||
textVal.ToDouble( &dblValue );
|
||||
std::optional<double> result( dblValue );
|
||||
changed = ( aVariant.IsNull() || result != variantData->Value() );
|
||||
|
||||
if( changed )
|
||||
{
|
||||
aVariant = wxVariant( result );
|
||||
textCtrl->SetValue( wxString::Format( wxS( "%g" ), dblValue ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
double result;
|
||||
textVal.ToDouble( &result );
|
||||
changed = ( aVariant.IsNull() || result != aVariant.GetDouble() );
|
||||
|
||||
if( changed )
|
||||
{
|
||||
aVariant = result;
|
||||
textCtrl->SetValue( wxString::Format( wxS( "%g" ), result ) );
|
||||
}
|
||||
}
|
||||
|
||||
// Changing unspecified always causes event (returning
|
||||
// true here should be enough to trigger it).
|
||||
if( !changed && aVariant.IsNull() )
|
||||
changed = true;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
void PG_RATIO_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const
|
||||
{
|
||||
wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl );
|
||||
wxVariant var = aProperty->GetValue();
|
||||
|
||||
if( var.GetType() == wxT( "std::optional<double>" ) )
|
||||
{
|
||||
auto* variantData = static_cast<STD_OPTIONAL_DOUBLE_VARIANT_DATA*>( var.GetData() );
|
||||
wxString strValue;
|
||||
|
||||
if( variantData->Value().has_value() )
|
||||
strValue = wxString::Format( wxS( "%g" ), variantData->Value().value() );
|
||||
|
||||
textCtrl->ChangeValue( strValue );
|
||||
}
|
||||
else if( var.GetType() == wxPG_VARIANT_TYPE_DOUBLE )
|
||||
{
|
||||
textCtrl->ChangeValue( wxString::Format( wxS( "%g" ), var.GetDouble() ) );
|
||||
}
|
||||
else if( !aProperty->IsValueUnspecified() )
|
||||
{
|
||||
wxFAIL_MSG( wxT( "PG_RATIO_EDITOR should only be used with scale-free numeric properties!" ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2020-2023 CERN
|
||||
* Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||
* Copyright (C) 2021-2024 KiCad Developers, see AUTHORS.TXT for contributors.
|
||||
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
|
@ -27,6 +27,7 @@
|
|||
#include <eda_draw_frame.h>
|
||||
#include <eda_units.h>
|
||||
#include <properties/color4d_variant.h>
|
||||
#include <properties/std_optional_variants.h>
|
||||
#include <properties/eda_angle_variant.h>
|
||||
#include <properties/pg_properties.h>
|
||||
#include <properties/pg_editors.h>
|
||||
|
@ -36,6 +37,82 @@
|
|||
#include <widgets/color_swatch.h>
|
||||
|
||||
|
||||
class wxAnyToSTD_OPTIONAL_INT_VARIANTRegistrationImpl : public wxAnyToVariantRegistration
|
||||
{
|
||||
public:
|
||||
wxAnyToSTD_OPTIONAL_INT_VARIANTRegistrationImpl( wxVariantDataFactory factory )
|
||||
: wxAnyToVariantRegistration( factory )
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static bool IsSameClass(const wxAnyValueType* otherType)
|
||||
{
|
||||
return AreSameClasses( *s_instance.get(), *otherType );
|
||||
}
|
||||
|
||||
static wxAnyValueType* GetInstance()
|
||||
{
|
||||
return s_instance.get();
|
||||
}
|
||||
|
||||
virtual wxAnyValueType* GetAssociatedType() override
|
||||
{
|
||||
return wxAnyToSTD_OPTIONAL_INT_VARIANTRegistrationImpl::GetInstance();
|
||||
}
|
||||
private:
|
||||
static bool AreSameClasses(const wxAnyValueType& a, const wxAnyValueType& b)
|
||||
{
|
||||
return wxTypeId(a) == wxTypeId(b);
|
||||
}
|
||||
|
||||
static wxAnyValueTypeScopedPtr s_instance;
|
||||
};
|
||||
|
||||
|
||||
wxAnyValueTypeScopedPtr wxAnyToSTD_OPTIONAL_INT_VARIANTRegistrationImpl::s_instance( new wxAnyValueTypeImpl<std::optional<int>>() );
|
||||
|
||||
static wxAnyToSTD_OPTIONAL_INT_VARIANTRegistrationImpl s_wxAnyToSTD_OPTIONAL_INT_VARIANTRegistration( &STD_OPTIONAL_INT_VARIANT_DATA::VariantDataFactory );
|
||||
|
||||
|
||||
class wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistrationImpl : public wxAnyToVariantRegistration
|
||||
{
|
||||
public:
|
||||
wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistrationImpl( wxVariantDataFactory factory )
|
||||
: wxAnyToVariantRegistration( factory )
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
static bool IsSameClass(const wxAnyValueType* otherType)
|
||||
{
|
||||
return AreSameClasses( *s_instance.get(), *otherType );
|
||||
}
|
||||
|
||||
static wxAnyValueType* GetInstance()
|
||||
{
|
||||
return s_instance.get();
|
||||
}
|
||||
|
||||
virtual wxAnyValueType* GetAssociatedType() override
|
||||
{
|
||||
return wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistrationImpl::GetInstance();
|
||||
}
|
||||
private:
|
||||
static bool AreSameClasses(const wxAnyValueType& a, const wxAnyValueType& b)
|
||||
{
|
||||
return wxTypeId(a) == wxTypeId(b);
|
||||
}
|
||||
|
||||
static wxAnyValueTypeScopedPtr s_instance;
|
||||
};
|
||||
|
||||
|
||||
wxAnyValueTypeScopedPtr wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistrationImpl::s_instance( new wxAnyValueTypeImpl<std::optional<double>>() );
|
||||
|
||||
static wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistrationImpl s_wxAnyToSTD_OPTIONAL_DOUBLE_VARIANTRegistration( &STD_OPTIONAL_DOUBLE_VARIANT_DATA::VariantDataFactory );
|
||||
|
||||
|
||||
class wxAnyToEDA_ANGLE_VARIANTRegistrationImpl : public wxAnyToVariantRegistration
|
||||
{
|
||||
public:
|
||||
|
@ -146,6 +223,10 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME*
|
|||
break;
|
||||
}
|
||||
|
||||
case PROPERTY_DISPLAY::PT_RATIO:
|
||||
ret = new PGPROPERTY_RATIO();
|
||||
break;
|
||||
|
||||
default:
|
||||
wxFAIL;
|
||||
KI_FALLTHROUGH;
|
||||
|
@ -232,9 +313,27 @@ bool PGPROPERTY_DISTANCE::StringToDistance( wxVariant& aVariant, const wxString&
|
|||
|
||||
wxString PGPROPERTY_DISTANCE::DistanceToString( wxVariant& aVariant, int aArgFlags ) const
|
||||
{
|
||||
wxCHECK( aVariant.GetType() == wxPG_VARIANT_TYPE_LONG, wxEmptyString );
|
||||
long distanceIU;
|
||||
|
||||
if( aVariant.GetType() == wxT( "std::optional<int>" ) )
|
||||
{
|
||||
auto* variantData = static_cast<STD_OPTIONAL_INT_VARIANT_DATA*>( aVariant.GetData() );
|
||||
|
||||
if( !variantData->Value().has_value() )
|
||||
return wxEmptyString;
|
||||
|
||||
distanceIU = variantData->Value().value();
|
||||
}
|
||||
else if( aVariant.GetType() == wxPG_VARIANT_TYPE_LONG )
|
||||
{
|
||||
distanceIU = aVariant.GetLong();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG( wxT( "Expected int (or std::optional<int>) value type" ) );
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
long distanceIU = aVariant.GetLong();
|
||||
ORIGIN_TRANSFORMS& transforms = m_parentFrame->GetOriginTransforms();
|
||||
|
||||
distanceIU = transforms.ToDisplay( static_cast<long long int>( distanceIU ), m_coordType );
|
||||
|
@ -281,6 +380,23 @@ PGPROPERTY_SIZE::PGPROPERTY_SIZE( EDA_DRAW_FRAME* aParentFrame ) :
|
|||
}
|
||||
|
||||
|
||||
bool PGPROPERTY_SIZE::ValidateValue( wxVariant& aValue, wxPGValidationInfo& aValidationInfo ) const
|
||||
{
|
||||
if( aValue.GetType() == wxT( "std::optional<int>" ) )
|
||||
{
|
||||
auto* data = static_cast<STD_OPTIONAL_INT_VARIANT_DATA*>( aValue.GetData() );
|
||||
|
||||
if( !data->Value().has_value() )
|
||||
return wxEmptyString;
|
||||
|
||||
wxVariant value( data->Value().value() );
|
||||
return wxUIntProperty::ValidateValue( value, aValidationInfo );
|
||||
}
|
||||
|
||||
return wxUIntProperty::ValidateValue( aValue, aValidationInfo );
|
||||
}
|
||||
|
||||
|
||||
wxValidator* PGPROPERTY_SIZE::DoGetValidator() const
|
||||
{
|
||||
return nullptr;
|
||||
|
@ -301,6 +417,79 @@ wxValidator* PGPROPERTY_COORD::DoGetValidator() const
|
|||
}
|
||||
|
||||
|
||||
PGPROPERTY_RATIO::PGPROPERTY_RATIO() :
|
||||
wxFloatProperty( wxPG_LABEL, wxPG_LABEL, 0 )
|
||||
{
|
||||
SetEditor( PG_RATIO_EDITOR::EDITOR_NAME );
|
||||
}
|
||||
|
||||
|
||||
const wxPGEditor* PGPROPERTY_RATIO::DoGetEditorClass() const
|
||||
{
|
||||
wxCHECK_MSG( m_customEditor, wxPGEditor_TextCtrl,
|
||||
wxT( "Make sure to RegisterEditorClass() for PGPROPERTY_RATIO!" ) );
|
||||
return m_customEditor;
|
||||
}
|
||||
|
||||
|
||||
bool PGPROPERTY_RATIO::StringToValue( wxVariant& aVariant, const wxString& aText,
|
||||
int aArgFlags ) const
|
||||
{
|
||||
// TODO(JE): Are there actual use cases for this?
|
||||
wxCHECK_MSG( false, false, wxS( "PGPROPERTY_RATIO::StringToValue should not be used." ) );
|
||||
}
|
||||
|
||||
|
||||
wxString PGPROPERTY_RATIO::ValueToString( wxVariant& aVariant, int aArgFlags ) const
|
||||
{
|
||||
double value;
|
||||
|
||||
if( aVariant.GetType() == wxT( "std::optional<double>" ) )
|
||||
{
|
||||
auto* variantData = static_cast<STD_OPTIONAL_DOUBLE_VARIANT_DATA*>( aVariant.GetData() );
|
||||
|
||||
if( !variantData->Value().has_value() )
|
||||
return wxEmptyString;
|
||||
|
||||
value = variantData->Value().value();
|
||||
}
|
||||
else if( aVariant.GetType() == wxPG_VARIANT_TYPE_DOUBLE )
|
||||
{
|
||||
value = aVariant.GetDouble();
|
||||
}
|
||||
else
|
||||
{
|
||||
wxFAIL_MSG( wxT( "Expected double (or std::optional<double>) value type" ) );
|
||||
return wxEmptyString;
|
||||
}
|
||||
|
||||
return wxString::Format( wxS( "%g" ), value );
|
||||
}
|
||||
|
||||
|
||||
bool PGPROPERTY_RATIO::ValidateValue( wxVariant& aValue, wxPGValidationInfo& aValidationInfo ) const
|
||||
{
|
||||
if( aValue.GetType() == wxT( "std::optional<double>" ) )
|
||||
{
|
||||
auto* data = static_cast<STD_OPTIONAL_DOUBLE_VARIANT_DATA*>( aValue.GetData() );
|
||||
|
||||
if( !data->Value().has_value() )
|
||||
return wxEmptyString;
|
||||
|
||||
wxVariant value( data->Value().value() );
|
||||
return wxFloatProperty::ValidateValue( value, aValidationInfo );
|
||||
}
|
||||
|
||||
return wxFloatProperty::ValidateValue( aValue, aValidationInfo );
|
||||
}
|
||||
|
||||
|
||||
wxValidator* PGPROPERTY_RATIO::DoGetValidator() const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool PGPROPERTY_ANGLE::StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags ) const
|
||||
{
|
||||
double value = 0.0;
|
||||
|
@ -408,7 +597,7 @@ PGPROPERTY_BOOL::PGPROPERTY_BOOL( const wxString& aLabel, const wxString& aName,
|
|||
const wxPGEditor* PGPROPERTY_BOOL::DoGetEditorClass() const
|
||||
{
|
||||
wxCHECK_MSG( m_customEditor, wxPGEditor_CheckBox,
|
||||
wxT( "Make sure to set custom editor for PGPROPERTY_BOOL!" ) );
|
||||
wxT( "Make sure to RegisterEditorClass() for PGPROPERTY_BOOL!" ) );
|
||||
return m_customEditor;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <properties/std_optional_variants.h>
|
||||
|
||||
|
||||
STD_OPTIONAL_INT_VARIANT_DATA::STD_OPTIONAL_INT_VARIANT_DATA() :
|
||||
wxVariantData()
|
||||
{}
|
||||
|
||||
|
||||
STD_OPTIONAL_INT_VARIANT_DATA::STD_OPTIONAL_INT_VARIANT_DATA( std::optional<int> aValue ) :
|
||||
wxVariantData(),
|
||||
m_value( aValue )
|
||||
{}
|
||||
|
||||
|
||||
bool STD_OPTIONAL_INT_VARIANT_DATA::Eq( wxVariantData& aOther ) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return dynamic_cast<STD_OPTIONAL_INT_VARIANT_DATA&>( aOther ).m_value == m_value;
|
||||
}
|
||||
catch( std::bad_cast& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STD_OPTIONAL_DOUBLE_VARIANT_DATA::STD_OPTIONAL_DOUBLE_VARIANT_DATA() :
|
||||
wxVariantData()
|
||||
{}
|
||||
|
||||
|
||||
STD_OPTIONAL_DOUBLE_VARIANT_DATA::STD_OPTIONAL_DOUBLE_VARIANT_DATA( std::optional<double> aValue ) :
|
||||
wxVariantData(),
|
||||
m_value( aValue )
|
||||
{}
|
||||
|
||||
|
||||
bool STD_OPTIONAL_DOUBLE_VARIANT_DATA::Eq( wxVariantData& aOther ) const
|
||||
{
|
||||
try
|
||||
{
|
||||
return dynamic_cast<STD_OPTIONAL_DOUBLE_VARIANT_DATA&>( aOther ).m_value == m_value;
|
||||
}
|
||||
catch( std::bad_cast& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -240,13 +240,15 @@ void UNIT_BINDER::onKillFocus( wxFocusEvent& aEvent )
|
|||
|
||||
if( m_allowEval && textEntry )
|
||||
{
|
||||
if( m_eval.Process( textEntry->GetValue() ) )
|
||||
wxString value = textEntry->GetValue();
|
||||
|
||||
if( !value.IsEmpty() && m_eval.Process( value ) )
|
||||
{
|
||||
textEntry->GetSelection( &m_selStart, &m_selEnd );
|
||||
|
||||
wxString value = m_eval.Result();
|
||||
value = m_eval.Result();
|
||||
|
||||
if( m_unitsInValue )
|
||||
if( m_unitsInValue && !value.IsEmpty() )
|
||||
{
|
||||
if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
|
||||
value += wxT( " " );
|
||||
|
@ -387,7 +389,7 @@ void UNIT_BINDER::SetValue( const wxString& aValue )
|
|||
|
||||
wxString value = aValue;
|
||||
|
||||
if( m_unitsInValue )
|
||||
if( m_unitsInValue && !value.IsEmpty() )
|
||||
{
|
||||
if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
|
||||
value += wxT( " " );
|
||||
|
@ -450,7 +452,7 @@ void UNIT_BINDER::ChangeValue( const wxString& aValue )
|
|||
|
||||
wxString value = aValue;
|
||||
|
||||
if( m_unitsInValue )
|
||||
if( m_unitsInValue && !value.IsEmpty() )
|
||||
{
|
||||
if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
|
||||
value += wxT( " " );
|
||||
|
@ -479,7 +481,9 @@ long long int UNIT_BINDER::GetValue()
|
|||
|
||||
if( textEntry )
|
||||
{
|
||||
if( m_needsEval && m_eval.Process( textEntry->GetValue() ) )
|
||||
value = textEntry->GetValue();
|
||||
|
||||
if( m_needsEval && !value.IsEmpty() && m_eval.Process( value ) )
|
||||
value = m_eval.Result();
|
||||
else
|
||||
value = textEntry->GetValue();
|
||||
|
@ -528,7 +532,9 @@ double UNIT_BINDER::GetDoubleValue()
|
|||
|
||||
if( textEntry )
|
||||
{
|
||||
if( m_needsEval && m_eval.Process( textEntry->GetValue() ) )
|
||||
value = textEntry->GetValue();
|
||||
|
||||
if( m_needsEval && !value.IsEmpty() && m_eval.Process( value ) )
|
||||
value = m_eval.Result();
|
||||
else
|
||||
value = textEntry->GetValue();
|
||||
|
@ -567,19 +573,14 @@ bool UNIT_BINDER::IsIndeterminate() const
|
|||
}
|
||||
|
||||
|
||||
wxString UNIT_BINDER::GetOriginalText() const
|
||||
bool UNIT_BINDER::IsNull() const
|
||||
{
|
||||
wxTextEntry* textEntry = dynamic_cast<wxTextEntry*>( m_valueCtrl );
|
||||
wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
|
||||
wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl );
|
||||
|
||||
if( m_allowEval )
|
||||
return m_eval.OriginalText();
|
||||
else if( textEntry )
|
||||
return textEntry->GetValue();
|
||||
else if( staticText )
|
||||
return staticText->GetLabel();
|
||||
else
|
||||
return wxEmptyString;
|
||||
if( te )
|
||||
return te->GetValue().IsEmpty();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -110,4 +110,19 @@ private:
|
|||
KIGFX::COLOR4D colorFromProperty( wxPGProperty* aProperty ) const;
|
||||
};
|
||||
|
||||
|
||||
class PG_RATIO_EDITOR : public wxPGTextCtrlEditor
|
||||
{
|
||||
public:
|
||||
static const wxString EDITOR_NAME;
|
||||
|
||||
wxString GetName() const override { return EDITOR_NAME; }
|
||||
|
||||
bool GetValueFromControl( wxVariant& aVariant, wxPGProperty* aProperty,
|
||||
wxWindow* aCtrl ) const override;
|
||||
|
||||
void UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const override;
|
||||
};
|
||||
|
||||
|
||||
#endif //KICAD_PG_EDITORS_H
|
||||
|
|
|
@ -91,6 +91,8 @@ public:
|
|||
return DistanceToString( aVariant, aArgFlags );
|
||||
}
|
||||
|
||||
bool ValidateValue( wxVariant& aValue, wxPGValidationInfo& aValidationInfo ) const override;
|
||||
|
||||
wxValidator* DoGetValidator() const override;
|
||||
};
|
||||
|
||||
|
@ -175,6 +177,26 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
class PGPROPERTY_RATIO : public wxFloatProperty
|
||||
{
|
||||
public:
|
||||
PGPROPERTY_RATIO();
|
||||
|
||||
const wxPGEditor* DoGetEditorClass() const override;
|
||||
|
||||
virtual ~PGPROPERTY_RATIO() = default;
|
||||
|
||||
bool StringToValue( wxVariant& aVariant, const wxString& aText,
|
||||
int aArgFlags = 0 ) const override;
|
||||
|
||||
wxString ValueToString( wxVariant& aVariant, int aArgFlags = 0 ) const override;
|
||||
|
||||
bool ValidateValue( wxVariant& aValue, wxPGValidationInfo& aValidationInfo ) const override;
|
||||
|
||||
wxValidator* DoGetValidator() const override;
|
||||
};
|
||||
|
||||
|
||||
class PGPROPERTY_STRING : public wxStringProperty
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <memory>
|
||||
#include <typeindex>
|
||||
#include <type_traits>
|
||||
#include "std_optional_variants.h"
|
||||
|
||||
class wxPGProperty;
|
||||
class INSPECTABLE;
|
||||
|
@ -58,7 +59,8 @@ enum PROPERTY_DISPLAY
|
|||
PT_AREA, ///< Area expressed in distance units-squared (mm/inch)
|
||||
PT_COORD, ///< Coordinate expressed in distance units (mm/inch)
|
||||
PT_DEGREE, ///< Angle expressed in degrees
|
||||
PT_DECIDEGREE ///< Angle expressed in decidegrees
|
||||
PT_DECIDEGREE, ///< Angle expressed in decidegrees
|
||||
PT_RATIO
|
||||
};
|
||||
|
||||
///< Macro to generate unique identifier for a type
|
||||
|
@ -347,6 +349,16 @@ protected:
|
|||
{
|
||||
a = static_cast<unsigned>( var.GetLong() );
|
||||
}
|
||||
else if( pv.CheckType<std::optional<int>>() )
|
||||
{
|
||||
auto* data = static_cast<STD_OPTIONAL_INT_VARIANT_DATA*>( var.GetData() );
|
||||
a = data->Value();
|
||||
}
|
||||
else if( pv.CheckType<std::optional<double>>() )
|
||||
{
|
||||
auto* data = static_cast<STD_OPTIONAL_DOUBLE_VARIANT_DATA*>( var.GetData() );
|
||||
a = data->Value();
|
||||
}
|
||||
else if( pv.CheckType<EDA_ANGLE>() )
|
||||
{
|
||||
EDA_ANGLE_VARIANT_DATA* ad = static_cast<EDA_ANGLE_VARIANT_DATA*>( var.GetData() );
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef STD_OPTIONAL_VARIANT_H
|
||||
#define STD_OPTIONAL_VARIANT_H
|
||||
|
||||
#include <optional>
|
||||
#include <wx/variant.h>
|
||||
|
||||
/*
|
||||
* Wrappers to allow use of std::optional<int> and std::optional<double> with the wxVariant
|
||||
* system.
|
||||
*/
|
||||
|
||||
class STD_OPTIONAL_INT_VARIANT_DATA : public wxVariantData
|
||||
{
|
||||
public:
|
||||
STD_OPTIONAL_INT_VARIANT_DATA();
|
||||
|
||||
STD_OPTIONAL_INT_VARIANT_DATA( std::optional<int> aValue );
|
||||
|
||||
bool Eq( wxVariantData& aOther ) const override;
|
||||
|
||||
wxString GetType() const override { return wxT( "std::optional<int>" ); }
|
||||
|
||||
bool GetAsAny( wxAny* aAny ) const override
|
||||
{
|
||||
*aAny = m_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<int> Value() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
static wxVariantData* VariantDataFactory( const wxAny& aAny )
|
||||
{
|
||||
return new STD_OPTIONAL_INT_VARIANT_DATA( aAny.As<std::optional<int>>() );
|
||||
}
|
||||
|
||||
protected:
|
||||
std::optional<int> m_value;
|
||||
};
|
||||
|
||||
|
||||
class STD_OPTIONAL_DOUBLE_VARIANT_DATA : public wxVariantData
|
||||
{
|
||||
public:
|
||||
STD_OPTIONAL_DOUBLE_VARIANT_DATA();
|
||||
|
||||
STD_OPTIONAL_DOUBLE_VARIANT_DATA( std::optional<double> aValue );
|
||||
|
||||
bool Eq( wxVariantData& aOther ) const override;
|
||||
|
||||
wxString GetType() const override { return wxT( "std::optional<double>" ); }
|
||||
|
||||
bool GetAsAny( wxAny* aAny ) const override
|
||||
{
|
||||
*aAny = m_value;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<double> Value() const
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
static wxVariantData* VariantDataFactory( const wxAny& aAny )
|
||||
{
|
||||
return new STD_OPTIONAL_DOUBLE_VARIANT_DATA( aAny.As<std::optional<double>>() );
|
||||
}
|
||||
|
||||
protected:
|
||||
std::optional<double> m_value;
|
||||
};
|
||||
|
||||
#endif //STD_OPTIONAL_VARIANT_H
|
|
@ -143,10 +143,9 @@ public:
|
|||
bool IsIndeterminate() const;
|
||||
|
||||
/**
|
||||
* Return the pre-evaluated text (or the current text if evaluation is not supported).
|
||||
* Used primarily to remember values between dialog invocations.
|
||||
* Return true if the control holds no value (ie: empty string, **not** 0).
|
||||
*/
|
||||
wxString GetOriginalText() const;
|
||||
bool IsNull() const;
|
||||
|
||||
/**
|
||||
* Validate the control against the given range, informing the user of any errors found.
|
||||
|
|
|
@ -80,6 +80,18 @@ PCB_PROPERTIES_PANEL::PCB_PROPERTIES_PANEL( wxWindow* aParent, PCB_BASE_EDIT_FRA
|
|||
{
|
||||
m_checkboxEditorInstance = static_cast<PG_CHECKBOX_EDITOR*>( it->second );
|
||||
}
|
||||
|
||||
it = wxPGGlobalVars->m_mapEditorClasses.find( PG_RATIO_EDITOR::EDITOR_NAME );
|
||||
|
||||
if( it == wxPGGlobalVars->m_mapEditorClasses.end() )
|
||||
{
|
||||
PG_RATIO_EDITOR* ratioEditor = new PG_RATIO_EDITOR();
|
||||
m_ratioEditorInstance = static_cast<PG_RATIO_EDITOR*>( wxPropertyGrid::RegisterEditorClass( ratioEditor ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ratioEditorInstance = static_cast<PG_RATIO_EDITOR*>( it->second );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ class PCB_BASE_EDIT_FRAME;
|
|||
class PROPERTY_MANAGER;
|
||||
class PG_UNIT_EDITOR;
|
||||
class PG_CHECKBOX_EDITOR;
|
||||
class PG_RATIO_EDITOR;
|
||||
|
||||
class PCB_PROPERTIES_PANEL : public PROPERTIES_PANEL
|
||||
{
|
||||
|
@ -54,10 +55,12 @@ protected:
|
|||
///< Regenerates caches storing layer and net names
|
||||
void updateLists( const BOARD* aBoard );
|
||||
|
||||
protected:
|
||||
PCB_BASE_EDIT_FRAME* m_frame;
|
||||
PROPERTY_MANAGER& m_propMgr;
|
||||
PG_UNIT_EDITOR* m_unitEditorInstance;
|
||||
PG_CHECKBOX_EDITOR* m_checkboxEditorInstance;
|
||||
PG_RATIO_EDITOR* m_ratioEditorInstance;
|
||||
|
||||
wxPGChoices m_nets;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue