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_editors.cpp
|
||||||
properties/pg_properties.cpp
|
properties/pg_properties.cpp
|
||||||
properties/property_mgr.cpp
|
properties/property_mgr.cpp
|
||||||
|
properties/std_optional_variants.cpp
|
||||||
|
|
||||||
database/database_connection.cpp
|
database/database_connection.cpp
|
||||||
database/database_lib_settings.cpp
|
database/database_lib_settings.cpp
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
* 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
|
* 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
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <eda_draw_frame.h>
|
#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/eda_angle_variant.h>
|
||||||
#include <properties/pg_editors.h>
|
#include <properties/pg_editors.h>
|
||||||
#include <properties/pg_properties.h>
|
#include <properties/pg_properties.h>
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
const wxString PG_UNIT_EDITOR::EDITOR_NAME = wxS( "KiCadUnitEditor" );
|
const wxString PG_UNIT_EDITOR::EDITOR_NAME = wxS( "KiCadUnitEditor" );
|
||||||
const wxString PG_CHECKBOX_EDITOR::EDITOR_NAME = wxS( "KiCadCheckboxEditor" );
|
const wxString PG_CHECKBOX_EDITOR::EDITOR_NAME = wxS( "KiCadCheckboxEditor" );
|
||||||
const wxString PG_COLOR_EDITOR::EDITOR_NAME = wxS( "KiCadColorEditor" );
|
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 ) :
|
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();
|
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() );
|
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!" );
|
wxCHECK_MSG( textCtrl, false, "PG_UNIT_EDITOR requires a text control!" );
|
||||||
wxString textVal = textCtrl->GetValue();
|
wxString textVal = textCtrl->GetValue();
|
||||||
|
|
||||||
if( aProperty->UsesAutoUnspecified() && textVal.empty() )
|
if( textVal == wxT( "<...>" ) )
|
||||||
{
|
{
|
||||||
aVariant.MakeNull();
|
aVariant.MakeNull();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool changed;
|
bool changed;
|
||||||
|
|
||||||
if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) != nullptr )
|
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() );
|
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
|
else
|
||||||
{
|
{
|
||||||
long result = m_unitBinder->GetValue();
|
long result = m_unitBinder->GetValue();
|
||||||
|
@ -321,3 +359,91 @@ KIGFX::COLOR4D PG_COLOR_EDITOR::colorFromProperty( wxPGProperty* aProperty ) con
|
||||||
{
|
{
|
||||||
return colorFromVariant( aProperty->GetValue() );
|
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.
|
* This program source code file is part of KICAD, a free EDA CAD application.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2020-2023 CERN
|
* 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>
|
* @author Maciej Suminski <maciej.suminski@cern.ch>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
#include <eda_draw_frame.h>
|
#include <eda_draw_frame.h>
|
||||||
#include <eda_units.h>
|
#include <eda_units.h>
|
||||||
#include <properties/color4d_variant.h>
|
#include <properties/color4d_variant.h>
|
||||||
|
#include <properties/std_optional_variants.h>
|
||||||
#include <properties/eda_angle_variant.h>
|
#include <properties/eda_angle_variant.h>
|
||||||
#include <properties/pg_properties.h>
|
#include <properties/pg_properties.h>
|
||||||
#include <properties/pg_editors.h>
|
#include <properties/pg_editors.h>
|
||||||
|
@ -36,6 +37,82 @@
|
||||||
#include <widgets/color_swatch.h>
|
#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
|
class wxAnyToEDA_ANGLE_VARIANTRegistrationImpl : public wxAnyToVariantRegistration
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -146,6 +223,10 @@ wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME*
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PROPERTY_DISPLAY::PT_RATIO:
|
||||||
|
ret = new PGPROPERTY_RATIO();
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
wxFAIL;
|
wxFAIL;
|
||||||
KI_FALLTHROUGH;
|
KI_FALLTHROUGH;
|
||||||
|
@ -232,9 +313,27 @@ bool PGPROPERTY_DISTANCE::StringToDistance( wxVariant& aVariant, const wxString&
|
||||||
|
|
||||||
wxString PGPROPERTY_DISTANCE::DistanceToString( wxVariant& aVariant, int aArgFlags ) const
|
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();
|
ORIGIN_TRANSFORMS& transforms = m_parentFrame->GetOriginTransforms();
|
||||||
|
|
||||||
distanceIU = transforms.ToDisplay( static_cast<long long int>( distanceIU ), m_coordType );
|
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
|
wxValidator* PGPROPERTY_SIZE::DoGetValidator() const
|
||||||
{
|
{
|
||||||
return nullptr;
|
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
|
bool PGPROPERTY_ANGLE::StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags ) const
|
||||||
{
|
{
|
||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
|
@ -408,7 +597,7 @@ PGPROPERTY_BOOL::PGPROPERTY_BOOL( const wxString& aLabel, const wxString& aName,
|
||||||
const wxPGEditor* PGPROPERTY_BOOL::DoGetEditorClass() const
|
const wxPGEditor* PGPROPERTY_BOOL::DoGetEditorClass() const
|
||||||
{
|
{
|
||||||
wxCHECK_MSG( m_customEditor, wxPGEditor_CheckBox,
|
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;
|
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_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 );
|
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 ) )
|
if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
|
||||||
value += wxT( " " );
|
value += wxT( " " );
|
||||||
|
@ -387,7 +389,7 @@ void UNIT_BINDER::SetValue( const wxString& aValue )
|
||||||
|
|
||||||
wxString value = aValue;
|
wxString value = aValue;
|
||||||
|
|
||||||
if( m_unitsInValue )
|
if( m_unitsInValue && !value.IsEmpty() )
|
||||||
{
|
{
|
||||||
if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
|
if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
|
||||||
value += wxT( " " );
|
value += wxT( " " );
|
||||||
|
@ -450,7 +452,7 @@ void UNIT_BINDER::ChangeValue( const wxString& aValue )
|
||||||
|
|
||||||
wxString value = aValue;
|
wxString value = aValue;
|
||||||
|
|
||||||
if( m_unitsInValue )
|
if( m_unitsInValue && !value.IsEmpty() )
|
||||||
{
|
{
|
||||||
if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
|
if( !( m_units == EDA_UNITS::DEGREES || m_units == EDA_UNITS::PERCENT ) )
|
||||||
value += wxT( " " );
|
value += wxT( " " );
|
||||||
|
@ -479,7 +481,9 @@ long long int UNIT_BINDER::GetValue()
|
||||||
|
|
||||||
if( textEntry )
|
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();
|
value = m_eval.Result();
|
||||||
else
|
else
|
||||||
value = textEntry->GetValue();
|
value = textEntry->GetValue();
|
||||||
|
@ -528,7 +532,9 @@ double UNIT_BINDER::GetDoubleValue()
|
||||||
|
|
||||||
if( textEntry )
|
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();
|
value = m_eval.Result();
|
||||||
else
|
else
|
||||||
value = textEntry->GetValue();
|
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 );
|
wxTextEntry* te = dynamic_cast<wxTextEntry*>( m_valueCtrl );
|
||||||
wxStaticText* staticText = dynamic_cast<wxStaticText*>( m_valueCtrl );
|
|
||||||
|
|
||||||
if( m_allowEval )
|
if( te )
|
||||||
return m_eval.OriginalText();
|
return te->GetValue().IsEmpty();
|
||||||
else if( textEntry )
|
|
||||||
return textEntry->GetValue();
|
return false;
|
||||||
else if( staticText )
|
|
||||||
return staticText->GetLabel();
|
|
||||||
else
|
|
||||||
return wxEmptyString;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -110,4 +110,19 @@ private:
|
||||||
KIGFX::COLOR4D colorFromProperty( wxPGProperty* aProperty ) const;
|
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
|
#endif //KICAD_PG_EDITORS_H
|
||||||
|
|
|
@ -91,6 +91,8 @@ public:
|
||||||
return DistanceToString( aVariant, aArgFlags );
|
return DistanceToString( aVariant, aArgFlags );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ValidateValue( wxVariant& aValue, wxPGValidationInfo& aValidationInfo ) const override;
|
||||||
|
|
||||||
wxValidator* DoGetValidator() 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
|
class PGPROPERTY_STRING : public wxStringProperty
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <typeindex>
|
#include <typeindex>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include "std_optional_variants.h"
|
||||||
|
|
||||||
class wxPGProperty;
|
class wxPGProperty;
|
||||||
class INSPECTABLE;
|
class INSPECTABLE;
|
||||||
|
@ -58,7 +59,8 @@ enum PROPERTY_DISPLAY
|
||||||
PT_AREA, ///< Area expressed in distance units-squared (mm/inch)
|
PT_AREA, ///< Area expressed in distance units-squared (mm/inch)
|
||||||
PT_COORD, ///< Coordinate expressed in distance units (mm/inch)
|
PT_COORD, ///< Coordinate expressed in distance units (mm/inch)
|
||||||
PT_DEGREE, ///< Angle expressed in degrees
|
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
|
///< Macro to generate unique identifier for a type
|
||||||
|
@ -347,6 +349,16 @@ protected:
|
||||||
{
|
{
|
||||||
a = static_cast<unsigned>( var.GetLong() );
|
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>() )
|
else if( pv.CheckType<EDA_ANGLE>() )
|
||||||
{
|
{
|
||||||
EDA_ANGLE_VARIANT_DATA* ad = static_cast<EDA_ANGLE_VARIANT_DATA*>( var.GetData() );
|
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;
|
bool IsIndeterminate() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the pre-evaluated text (or the current text if evaluation is not supported).
|
* Return true if the control holds no value (ie: empty string, **not** 0).
|
||||||
* Used primarily to remember values between dialog invocations.
|
|
||||||
*/
|
*/
|
||||||
wxString GetOriginalText() const;
|
bool IsNull() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate the control against the given range, informing the user of any errors found.
|
* 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 );
|
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 PROPERTY_MANAGER;
|
||||||
class PG_UNIT_EDITOR;
|
class PG_UNIT_EDITOR;
|
||||||
class PG_CHECKBOX_EDITOR;
|
class PG_CHECKBOX_EDITOR;
|
||||||
|
class PG_RATIO_EDITOR;
|
||||||
|
|
||||||
class PCB_PROPERTIES_PANEL : public PROPERTIES_PANEL
|
class PCB_PROPERTIES_PANEL : public PROPERTIES_PANEL
|
||||||
{
|
{
|
||||||
|
@ -54,10 +55,12 @@ protected:
|
||||||
///< Regenerates caches storing layer and net names
|
///< Regenerates caches storing layer and net names
|
||||||
void updateLists( const BOARD* aBoard );
|
void updateLists( const BOARD* aBoard );
|
||||||
|
|
||||||
|
protected:
|
||||||
PCB_BASE_EDIT_FRAME* m_frame;
|
PCB_BASE_EDIT_FRAME* m_frame;
|
||||||
PROPERTY_MANAGER& m_propMgr;
|
PROPERTY_MANAGER& m_propMgr;
|
||||||
PG_UNIT_EDITOR* m_unitEditorInstance;
|
PG_UNIT_EDITOR* m_unitEditorInstance;
|
||||||
PG_CHECKBOX_EDITOR* m_checkboxEditorInstance;
|
PG_CHECKBOX_EDITOR* m_checkboxEditorInstance;
|
||||||
|
PG_RATIO_EDITOR* m_ratioEditorInstance;
|
||||||
|
|
||||||
wxPGChoices m_nets;
|
wxPGChoices m_nets;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue