KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pg_properties.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright (C) 2020-2023 CERN
5 * Copyright (C) 2021-2023 KiCad Developers, see AUTHORS.TXT for contributors.
6 * @author Maciej Suminski <[email protected]>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 3
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <wx/dc.h>
23#include <wx/propgrid/propgrid.h>
24
25#include <macros.h>
26#include <validators.h>
27#include <eda_draw_frame.h>
28#include <eda_units.h>
34#include <properties/property.h>
35#include <string_utils.h>
37
38// reg-ex describing a signed valid value with a unit
39static const wxChar REGEX_SIGNED_DISTANCE[] = wxT( "([-+]?[0-9]+[\\.?[0-9]*) *(mm|in|mils)*" );
40static const wxChar REGEX_UNSIGNED_DISTANCE[] = wxT( "([0-9]+[\\.?[0-9]*) *(mm|in|mils)*" );
41
42
43class wxAnyToEDA_ANGLE_VARIANTRegistrationImpl : public wxAnyToVariantRegistration
44{
45public:
46 wxAnyToEDA_ANGLE_VARIANTRegistrationImpl( wxVariantDataFactory factory )
47 : wxAnyToVariantRegistration( factory )
48 {
49 }
50
51public:
52 static bool IsSameClass(const wxAnyValueType* otherType)
53 {
54 return AreSameClasses( *s_instance.get(), *otherType );
55 }
56
57 static wxAnyValueType* GetInstance()
58 {
59 return s_instance.get();
60 }
61
62 virtual wxAnyValueType* GetAssociatedType() override
63 {
65 }
66private:
67 static bool AreSameClasses(const wxAnyValueType& a, const wxAnyValueType& b)
68 {
69 return wxTypeId(a) == wxTypeId(b);
70 }
71
72 static wxAnyValueTypeScopedPtr s_instance;
73};
74
75
76wxAnyValueTypeScopedPtr wxAnyToEDA_ANGLE_VARIANTRegistrationImpl::s_instance( new wxAnyValueTypeImpl<EDA_ANGLE>() );
77
78static wxAnyToEDA_ANGLE_VARIANTRegistrationImpl s_wxAnyToEDA_ANGLE_VARIANTRegistration( &EDA_ANGLE_VARIANT_DATA::VariantDataFactory );
79
80
81class wxAnyToCOLOR4D_VARIANTRegistrationImpl : public wxAnyToVariantRegistration
82{
83public:
84 wxAnyToCOLOR4D_VARIANTRegistrationImpl( wxVariantDataFactory factory )
85 : wxAnyToVariantRegistration( factory )
86 {
87 }
88
89public:
90 static bool IsSameClass(const wxAnyValueType* otherType)
91 {
92 return AreSameClasses( *s_instance.get(), *otherType );
93 }
94
95 static wxAnyValueType* GetInstance()
96 {
97 return s_instance.get();
98 }
99
100 virtual wxAnyValueType* GetAssociatedType() override
101 {
103 }
104private:
105 static bool AreSameClasses(const wxAnyValueType& a, const wxAnyValueType& b)
106 {
107 return wxTypeId(a) == wxTypeId(b);
108 }
109
110 static wxAnyValueTypeScopedPtr s_instance;
111};
112
113wxAnyValueTypeScopedPtr wxAnyToCOLOR4D_VARIANTRegistrationImpl::s_instance( new wxAnyValueTypeImpl<KIGFX::COLOR4D>() );
114
115static wxAnyToCOLOR4D_VARIANTRegistrationImpl s_wxAnyToCOLOR4D_VARIANTRegistration( &COLOR4D_VARIANT_DATA::VariantDataFactory );
116
117
118wxPGProperty* PGPropertyFactory( const PROPERTY_BASE* aProperty, EDA_DRAW_FRAME* aFrame )
119{
120 wxPGProperty* ret = nullptr;
121 PROPERTY_DISPLAY display = aProperty->Display();
122
123 switch( display )
124 {
126 ret = new PGPROPERTY_SIZE( aFrame );
127 ret->SetEditor( PG_UNIT_EDITOR::BuildEditorName( aFrame ) );
128 break;
129
131 ret = new PGPROPERTY_COORD( aFrame, aProperty->CoordType() );
132 ret->SetEditor( PG_UNIT_EDITOR::BuildEditorName( aFrame ) );
133 break;
134
137 {
139
140 if( display == PROPERTY_DISPLAY::PT_DECIDEGREE )
141 prop->SetScale( 10.0 );
142
143 ret = prop;
144 ret->SetEditor( PG_UNIT_EDITOR::BuildEditorName( aFrame ) );
145 break;
146 }
147
148 default:
149 wxFAIL;
151 /* fall through */
153 {
154 // Create a corresponding wxPGProperty
155 size_t typeId = aProperty->TypeHash();
156
157 // Enum property
158 if( aProperty->HasChoices() )
159 {
160 // I do not know why enum property takes a non-const reference to wxPGChoices..
161 ret = new wxEnumProperty( wxPG_LABEL, wxPG_LABEL,
162 const_cast<wxPGChoices&>( aProperty->Choices() ) );
163 }
164 else if( typeId == TYPE_HASH( int ) || typeId == TYPE_HASH( long ) )
165 {
166 ret = new wxIntProperty();
167 }
168 else if( typeId == TYPE_HASH( unsigned int ) || typeId == TYPE_HASH( unsigned long ) )
169 {
170 ret = new wxUIntProperty();
171 }
172 else if( typeId == TYPE_HASH( float ) || typeId == TYPE_HASH( double ) )
173 {
174 ret = new wxFloatProperty();
175 }
176 else if( typeId == TYPE_HASH( bool ) )
177 {
178 ret = new PGPROPERTY_BOOL();
179 }
180 else if( typeId == TYPE_HASH( wxString ) )
181 {
182 ret = new PGPROPERTY_STRING();
183 }
184 else if( typeId == TYPE_HASH( COLOR4D ) )
185 {
186 ret = new PGPROPERTY_COLOR4D();
187 }
188 else
189 {
190 wxFAIL_MSG( wxString::Format( wxS( "Property %s not supported by PGPropertyFactory" ),
191 aProperty->Name() ) );
192 ret = new wxPropertyCategory();
193 ret->Enable( false );
194 }
195 break;
196 }
197 }
198
199 if( ret )
200 {
201 ret->SetLabel( wxGetTranslation( aProperty->Name() ) );
202 ret->SetName( aProperty->Name() );
203 ret->SetHelpString( wxGetTranslation( aProperty->Name() ) );
204 ret->SetClientData( const_cast<PROPERTY_BASE*>( aProperty ) );
205 }
206
207 return ret;
208}
209
210
211PGPROPERTY_DISTANCE::PGPROPERTY_DISTANCE( EDA_DRAW_FRAME* aParentFrame, const wxString& aRegEx,
213 m_parentFrame( aParentFrame ),
214 m_coordType( aCoordType )
215{
216 m_regExValidator.reset( new REGEX_VALIDATOR( aRegEx ) );
217}
218
219
221{
222}
223
224
225bool PGPROPERTY_DISTANCE::StringToDistance( wxVariant& aVariant, const wxString& aText,
226 int aArgFlags ) const
227{
228 // TODO(JE): Are there actual use cases for this?
229 wxCHECK_MSG( false, false, wxS( "PGPROPERTY_DISTANCE::StringToDistance should not be used." ) );
230}
231
232
233wxString PGPROPERTY_DISTANCE::DistanceToString( wxVariant& aVariant, int aArgFlags ) const
234{
235 wxCHECK( aVariant.GetType() == wxPG_VARIANT_TYPE_LONG, wxEmptyString );
236
237 long distanceIU = aVariant.GetLong();
238
240 const EDA_IU_SCALE& iuScale = m_parentFrame->GetIuScale();
241
242 distanceIU = transforms.ToDisplay( static_cast<long long int>( distanceIU ), m_coordType );
243
244 switch( m_parentFrame->GetUserUnits() )
245 {
246 case EDA_UNITS::INCHES:
247 return wxString::Format( wxS( "%g in" ), iuScale.IUToMils( distanceIU ) / 1000.0 );
248
249 case EDA_UNITS::MILS:
250 return wxString::Format( wxS( "%d mils" ), iuScale.IUToMils( distanceIU ) );
251
252 case EDA_UNITS::MILLIMETRES:
253 return wxString::Format( wxS( "%g mm" ), iuScale.IUTomm( distanceIU ) );
254
255 case EDA_UNITS::UNSCALED:
256 return wxString::Format( wxS( "%li" ), distanceIU );
257
258 default:
259 // DEGREEs are handled by PGPROPERTY_ANGLE
260 break;
261 }
262
263 wxFAIL;
264 return wxEmptyString;
265}
266
267
269 wxUIntProperty( wxPG_LABEL, wxPG_LABEL, 0 ),
271{
272}
273
274
276{
277 return nullptr;
278}
279
280
283 wxIntProperty( wxPG_LABEL, wxPG_LABEL, 0 ),
284 PGPROPERTY_DISTANCE( aParentFrame, REGEX_SIGNED_DISTANCE, aCoordType )
285{
286}
287
288
290{
291 return nullptr;
292}
293
294
295bool PGPROPERTY_ANGLE::StringToValue( wxVariant& aVariant, const wxString& aText, int aArgFlags ) const
296{
297 double value = 0.0;
298
299 if( !aText.ToDouble( &value ) )
300 {
301 aVariant.MakeNull();
302 return true;
303 }
304
305 value *= m_scale;
306
307 if( aVariant.IsNull() || aVariant.GetDouble() != value )
308 {
309 aVariant = value;
310 return true;
311 }
312
313 return false;
314}
315
316
317wxString PGPROPERTY_ANGLE::ValueToString( wxVariant& aVariant, int aArgFlags ) const
318{
319 if( aVariant.GetType() == wxPG_VARIANT_TYPE_DOUBLE )
320 {
321 // TODO(JE) Is this still needed?
322 return wxString::Format( wxS( "%g\u00B0" ), aVariant.GetDouble() / m_scale );
323 }
324 else if( aVariant.GetType() == wxS( "EDA_ANGLE" ) )
325 {
326 wxString ret;
327 static_cast<EDA_ANGLE_VARIANT_DATA*>( aVariant.GetData() )->Write( ret );
328 return ret;
329 }
330 else
331 {
332 wxCHECK_MSG( false, wxEmptyString, wxS( "Unexpected variant type in PGPROPERTY_ANGLE" ) );
333 }
334}
335
336
338{
339 return nullptr;
340}
341
342
344{
345 // TODO(JE) calculate size from window metrics?
346 return wxSize( 16, 12 );
347}
348
349
350void PGPROPERTY_COLORENUM::OnCustomPaint( wxDC& aDC, const wxRect& aRect,
351 wxPGPaintData& aPaintData )
352{
353 int index = aPaintData.m_choiceItem;
354
355 if( index < 0 )
356 index = GetIndex();
357
358 // GetIndex can return -1 when the control hasn't been set up yet
359 if( index < 0 || index >= static_cast<int>( GetChoices().GetCount() ) )
360 return;
361
362 wxColour color = GetColor( GetChoices().GetValue( index ) );
363
364 if( color == wxNullColour )
365 return;
366
367 aDC.SetPen( *wxTRANSPARENT_PEN );
368 aDC.SetBrush( wxBrush( color ) );
369 aDC.DrawRectangle( aRect );
370
371 aPaintData.m_drawnWidth = aRect.width;
372}
373
374
375wxString PGPROPERTY_STRING::ValueToString( wxVariant& aValue, int aFlags ) const
376{
377 if( aValue.GetType() != wxPG_VARIANT_TYPE_STRING )
378 return wxEmptyString;
379
380 return UnescapeString( aValue.GetString() );
381}
382
383
384bool PGPROPERTY_STRING::StringToValue( wxVariant& aVariant, const wxString& aString,
385 int aFlags ) const
386{
387 aVariant = EscapeString( aString, CTX_QUOTED_STR );
388 return true;
389}
390
391
392PGPROPERTY_BOOL::PGPROPERTY_BOOL( const wxString& aLabel, const wxString& aName, bool aValue ) :
393 wxBoolProperty( aLabel, aName, aValue )
394{
396}
397
398
399const wxPGEditor* PGPROPERTY_BOOL::DoGetEditorClass() const
400{
401 wxCHECK_MSG( m_customEditor, wxPGEditor_CheckBox,
402 wxT( "Make sure to set custom editor for PGPROPERTY_BOOL!" ) );
403 return m_customEditor;
404}
405
406
407PGPROPERTY_COLOR4D::PGPROPERTY_COLOR4D( const wxString& aLabel, const wxString& aName,
408 COLOR4D aValue, COLOR4D aBackgroundColor ) :
409 wxStringProperty( aLabel, aName, aValue.ToCSSString() ),
410 m_backgroundColor( aBackgroundColor )
411{
412 SetEditor( PG_COLOR_EDITOR::EDITOR_NAME );
413 SetFlag( wxPG_PROP_NOEDITOR );
414}
415
416
417bool PGPROPERTY_COLOR4D::StringToValue( wxVariant& aVariant, const wxString& aString,
418 int aFlags ) const
419{
420 aVariant.SetData( new COLOR4D_VARIANT_DATA( aString ) );
421 return true;
422}
423
424
425wxString PGPROPERTY_COLOR4D::ValueToString( wxVariant& aValue, int aFlags ) const
426{
427 wxString ret;
428
429 if( aValue.IsType( wxS( "COLOR4D" ) ) )
430 static_cast<COLOR4D_VARIANT_DATA*>( aValue.GetData() )->Write( ret );
431 else
432 return wxStringProperty::ValueToString( aValue, aFlags );
433
434 return ret;
435}
int color
Definition: DXF_plotter.cpp:58
static wxVariantData * VariantDataFactory(const wxAny &aAny)
static wxVariantData * VariantDataFactory(const wxAny &aAny)
ORIGIN_TRANSFORMS & GetOriginTransforms() override
Return a reference to the default ORIGIN_TRANSFORMS object.
The base class for create windows for drawing purpose.
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
A class to perform either relative or absolute display origin transforms for a single axis of a point...
virtual int ToDisplay(int aValue, COORD_TYPES_T aCoordType) const
COORD_TYPES_T
The supported Display Origin Transform types.
A wxEnumProperty that displays a color next to the enum value.
void SetScale(double aScale)
wxString ValueToString(wxVariant &aVariant, int aArgFlags=0) const override
double m_scale
< Scale factor to convert between raw and displayed value
wxValidator * DoGetValidator() const override
Do not perform PG validation; the UX is not what we want.
bool StringToValue(wxVariant &aVariant, const wxString &aText, int aArgFlags=0) const override
const wxPGEditor * DoGetEditorClass() const override
PGPROPERTY_BOOL(const wxString &aLabel=wxPG_LABEL, const wxString &aName=wxPG_LABEL, bool aValue=false)
bool StringToValue(wxVariant &aVariant, const wxString &aText, int aFlags=0) const override
wxString ValueToString(wxVariant &aValue, int aFlags=0) const override
PGPROPERTY_COLOR4D(const wxString &aLabel=wxPG_LABEL, const wxString &aName=wxPG_LABEL, KIGFX::COLOR4D aValue=KIGFX::COLOR4D::UNSPECIFIED, KIGFX::COLOR4D aBackground=KIGFX::COLOR4D::UNSPECIFIED)
wxColour GetColor(int aValue)
wxSize OnMeasureImage(int aItem=-1) const override
void OnCustomPaint(wxDC &aDC, const wxRect &aRect, wxPGPaintData &aPaintData) override
Customized wxPGProperty class to handle angles.
Definition: pg_properties.h:82
PGPROPERTY_COORD(EDA_DRAW_FRAME *aParentFrame, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType)
wxValidator * DoGetValidator() const override
EDA_DRAW_FRAME * m_parentFrame
Definition: pg_properties.h:55
wxString DistanceToString(wxVariant &aVariant, int aArgFlags=0) const
bool StringToDistance(wxVariant &aVariant, const wxString &aText, int aArgFlags=0) const
virtual ~PGPROPERTY_DISTANCE()=0
ORIGIN_TRANSFORMS::COORD_TYPES_T m_coordType
Definition: pg_properties.h:57
std::unique_ptr< REGEX_VALIDATOR > m_regExValidator
Definition: pg_properties.h:56
PGPROPERTY_DISTANCE(EDA_DRAW_FRAME *aParentFrame, const wxString &aRegEx, ORIGIN_TRANSFORMS::COORD_TYPES_T aCoordType)
wxValidator * DoGetValidator() const override
PGPROPERTY_SIZE(EDA_DRAW_FRAME *aParentFrame)
wxString ValueToString(wxVariant &aValue, int aFlags=0) const override
bool StringToValue(wxVariant &aVariant, const wxString &aString, int aFlags=0) const override
static const wxString EDITOR_NAME
Definition: pg_editors.h:75
static const wxString EDITOR_NAME
Definition: pg_editors.h:91
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
Definition: pg_editors.cpp:51
virtual size_t TypeHash() const =0
Return type-id of the property type.
PROPERTY_DISPLAY Display() const
Definition: property.h:281
ORIGIN_TRANSFORMS::COORD_TYPES_T CoordType() const
Definition: property.h:284
virtual bool HasChoices() const
Return true if this PROPERTY has a limited set of possible values.
Definition: property.h:233
const wxString & Name() const
Definition: property.h:209
virtual const wxPGChoices & Choices() const
Return a limited set of possible values (e.g.
Definition: property.h:215
Custom validator that checks verifies that a string exactly matches a regular expression.
Definition: validators.h:130
const EDA_IU_SCALE & GetIuScale() const
EDA_UNITS GetUserUnits() const
wxAnyToCOLOR4D_VARIANTRegistrationImpl(wxVariantDataFactory factory)
static wxAnyValueType * GetInstance()
static bool AreSameClasses(const wxAnyValueType &a, const wxAnyValueType &b)
static bool IsSameClass(const wxAnyValueType *otherType)
virtual wxAnyValueType * GetAssociatedType() override
static wxAnyValueTypeScopedPtr s_instance
static wxAnyValueTypeScopedPtr s_instance
static bool IsSameClass(const wxAnyValueType *otherType)
virtual wxAnyValueType * GetAssociatedType() override
static wxAnyValueType * GetInstance()
wxAnyToEDA_ANGLE_VARIANTRegistrationImpl(wxVariantDataFactory factory)
static bool AreSameClasses(const wxAnyValueType &a, const wxAnyValueType &b)
This file contains miscellaneous commonly used macros and functions.
#define KI_FALLTHROUGH
The KI_FALLTHROUGH macro is to be used when switch statement cases should purposely fallthrough from ...
Definition: macros.h:83
static const wxChar REGEX_SIGNED_DISTANCE[]
wxPGProperty * PGPropertyFactory(const PROPERTY_BASE *aProperty, EDA_DRAW_FRAME *aFrame)
Customized abstract wxPGProperty class to handle coordinate/size units.
static const wxChar REGEX_UNSIGNED_DISTANCE[]
#define TYPE_HASH(x)
Definition: property.h:64
PROPERTY_DISPLAY
Common property types.
Definition: property.h:55
@ PT_DEGREE
Angle expressed in degrees.
Definition: property.h:59
@ PT_COORD
Coordinate expressed in distance units (mm/inch)
Definition: property.h:58
@ PT_DECIDEGREE
Angle expressed in decidegrees.
Definition: property.h:60
@ PT_DEFAULT
Default property for a given type.
Definition: property.h:56
@ PT_SIZE
Size expressed in distance units (mm/inch)
Definition: property.h:57
wxString UnescapeString(const wxString &aSource)
wxString EscapeString(const wxString &aSource, ESCAPE_CONTEXT aContext)
The Escape/Unescape routines use HTML-entity-reference-style encoding to handle characters which are:...
@ CTX_QUOTED_STR
Definition: string_utils.h:57
constexpr double IUTomm(int iu) const
Definition: base_units.h:87
constexpr int IUToMils(int iu) const
Definition: base_units.h:100
Custom text control validator definitions.