KiCad PCB EDA Suite
Loading...
Searching...
No Matches
pg_editors.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <eda_draw_frame.h>
26#include <widgets/unit_binder.h>
27#include <bitmaps.h>
28#include <frame_type.h>
29#include <kiway_player.h>
30#include <kiway.h>
31#include <wx/filedlg.h>
32#include <wx/intl.h>
33#include <eda_doc.h>
34
35#include <wx/button.h>
36#include <wx/bmpbuttn.h>
37
38#include <wx/log.h>
39
40const wxString PG_UNIT_EDITOR::EDITOR_NAME = wxS( "KiCadUnitEditor" );
41const wxString PG_CHECKBOX_EDITOR::EDITOR_NAME = wxS( "KiCadCheckboxEditor" );
42const wxString PG_COLOR_EDITOR::EDITOR_NAME = wxS( "KiCadColorEditor" );
43const wxString PG_RATIO_EDITOR::EDITOR_NAME = wxS( "KiCadRatioEditor" );
44const wxString PG_FPID_EDITOR::EDITOR_NAME = wxS( "KiCadFpidEditor" );
45const wxString PG_URL_EDITOR::EDITOR_NAME = wxS( "KiCadUrlEditor" );
46
47
49 wxPGTextCtrlEditor(),
50 m_frame( aFrame )
51{
52 m_unitBinder = std::make_unique<PROPERTY_EDITOR_UNIT_BINDER>( m_frame );
53 m_unitBinder->SetUnits( m_frame->GetUserUnits() );
54
56}
57
58
62
63
65{
66 if( !aFrame )
67 return EDITOR_NAME + "NoFrame";
68
69 return EDITOR_NAME + aFrame->GetName();
70}
71
72
74{
75 m_frame = aFrame;
76
77 if( aFrame )
78 {
79 m_unitBinder = std::make_unique<PROPERTY_EDITOR_UNIT_BINDER>( m_frame );
80 m_unitBinder->SetUnits( m_frame->GetUserUnits() );
81 }
82 else
83 {
84 m_unitBinder = nullptr;
85 }
86}
87
88
89wxPGWindowList PG_UNIT_EDITOR::CreateControls( wxPropertyGrid* aPropGrid, wxPGProperty* aProperty,
90 const wxPoint& aPos, const wxSize& aSize ) const
91{
92 wxASSERT( m_unitBinder );
93
94#if wxCHECK_VERSION( 3, 3, 0 )
95 wxString text = aProperty->GetValueAsString( wxPGPropValFormatFlags::EditableValue );
96#else
97 wxString text = aProperty->GetValueAsString( wxPG_EDITABLE_VALUE );
98#endif
99 wxWindow* win = aPropGrid->GenerateEditorTextCtrl( aPos, aSize, text, nullptr, 0,
100 aProperty->GetMaxLength() );
101 wxPGWindowList ret( win, nullptr );
102
103 m_unitBinder->SetControl( win );
104 m_unitBinder->RequireEval();
105 m_unitBinder->SetUnits( m_frame->GetUserUnits() );
106
107 if( PGPROPERTY_DISTANCE* prop = dynamic_cast<PGPROPERTY_DISTANCE*>( aProperty ) )
108 {
109 m_unitBinder->SetCoordType( prop->CoordType() );
110 }
111 else if( dynamic_cast<PGPROPERTY_AREA*>( aProperty) != nullptr )
112 {
113 m_unitBinder->SetDataType( EDA_DATA_TYPE::AREA );
114 }
115 else if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) != nullptr )
116 {
118 m_unitBinder->SetUnits( EDA_UNITS::DEGREES );
119 }
120 else if( dynamic_cast<PGPROPERTY_TIME*>( aProperty ) != nullptr )
121 {
122 m_unitBinder->SetUnits( EDA_UNITS::PS );
123 }
124
125 UpdateControl( aProperty, win );
126
127 return ret;
128}
129
130
131void PG_UNIT_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const
132{
133 wxVariant var = aProperty->GetValue();
134
135 if( var.GetType() == wxT( "std::optional<int>" ) )
136 {
137 auto* variantData = static_cast<STD_OPTIONAL_INT_VARIANT_DATA*>( var.GetData() );
138
139 if( variantData->Value().has_value() )
140 m_unitBinder->ChangeValue( variantData->Value().value() );
141 else
142 m_unitBinder->ChangeValue( wxEmptyString );
143 }
144 else if( var.GetType() == wxPG_VARIANT_TYPE_LONG )
145 {
146 m_unitBinder->ChangeValue( var.GetLong() );
147 }
148 else if( var.GetType() == wxPG_VARIANT_TYPE_LONGLONG )
149 {
150 m_unitBinder->ChangeDoubleValue( var.GetLongLong().ToDouble() );
151 }
152 else if( var.GetType() == wxPG_VARIANT_TYPE_DOUBLE )
153 {
154 m_unitBinder->ChangeValue( var.GetDouble() );
155 }
156 else if( var.GetType() == wxT( "EDA_ANGLE" ) )
157 {
158 EDA_ANGLE_VARIANT_DATA* angleData = static_cast<EDA_ANGLE_VARIANT_DATA*>( var.GetData() );
159 m_unitBinder->ChangeAngleValue( angleData->Angle() );
160 }
161 else if( !aProperty->IsValueUnspecified() )
162 {
163 wxFAIL_MSG( wxT( "PG_UNIT_EDITOR should only be used with numeric properties!" ) );
164 }
165}
166
167
168bool PG_UNIT_EDITOR::OnEvent( wxPropertyGrid* aPropGrid, wxPGProperty* aProperty,
169 wxWindow* aCtrl, wxEvent& aEvent ) const
170{
171 if( aEvent.GetEventType() == wxEVT_LEFT_UP )
172 {
173 if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl ) )
174 {
175 if( !textCtrl->HasFocus() )
176 {
177 textCtrl->SelectAll();
178 return false;
179 }
180 }
181 }
182
183 return wxPGTextCtrlEditor::OnEvent( aPropGrid, aProperty, aCtrl, aEvent );
184}
185
186
187bool PG_UNIT_EDITOR::GetValueFromControl( wxVariant& aVariant, wxPGProperty* aProperty,
188 wxWindow* aCtrl ) const
189{
190 if( !m_unitBinder )
191 return false;
192
193 wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl );
194 wxCHECK_MSG( textCtrl, false, "PG_UNIT_EDITOR requires a text control!" );
195 wxString textVal = textCtrl->GetValue();
196
197 if( textVal == wxT( "<...>" ) )
198 {
199 aVariant.MakeNull();
200 return true;
201 }
202
203 bool changed;
204
205 if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) != nullptr )
206 {
207 EDA_ANGLE angle = m_unitBinder->GetAngleValue();
208
209 if( aVariant.GetType() == wxT( "EDA_ANGLE" ) )
210 {
211 EDA_ANGLE_VARIANT_DATA* ad = static_cast<EDA_ANGLE_VARIANT_DATA*>( aVariant.GetData() );
212 changed = ( aVariant.IsNull() || angle != ad->Angle() );
213
214 if( changed )
215 {
216 ad->SetAngle( angle );
217 m_unitBinder->SetAngleValue( angle );
218 }
219 }
220 else
221 {
222 changed = ( aVariant.IsNull() || angle.AsDegrees() != aVariant.GetDouble() );
223
224 if( changed )
225 {
226 aVariant = angle.AsDegrees();
227 m_unitBinder->SetValue( angle.AsDegrees() );
228 }
229 }
230 }
231 else if( dynamic_cast<PGPROPERTY_AREA*>( aProperty ) != nullptr )
232 {
233 wxLongLongNative result = m_unitBinder->GetValue();
234 changed = ( aVariant.IsNull() || result != aVariant.GetLongLong() );
235
236 if( changed )
237 {
238 aVariant = result;
239 m_unitBinder->SetDoubleValue( result.ToDouble() );
240 }
241 }
242 else if( aVariant.GetType() == wxT( "std::optional<int>" ) )
243 {
244 auto* variantData = static_cast<STD_OPTIONAL_INT_VARIANT_DATA*>( aVariant.GetData() );
245 std::optional<int> result;
246
247 if( m_unitBinder->IsNull() )
248 {
249 changed = ( aVariant.IsNull() || variantData->Value().has_value() );
250
251 if( changed )
252 {
253 aVariant = wxVariant( std::optional<int>() );
254 m_unitBinder->SetValue( wxEmptyString );
255 }
256 }
257 else
258 {
259 result = std::optional<int>( m_unitBinder->GetValue() );
260 changed = ( aVariant.IsNull() || result != variantData->Value() );
261
262 if( changed )
263 {
264 aVariant = wxVariant( result );
265 m_unitBinder->SetValue( result.value() );
266 }
267 }
268 }
269 else
270 {
271 long result = m_unitBinder->GetValue();
272 changed = ( aVariant.IsNull() || result != aVariant.GetLong() );
273
274 if( changed )
275 {
276 aVariant = result;
277 m_unitBinder->SetValue( result );
278 }
279 }
280
281 // Changing unspecified always causes event (returning
282 // true here should be enough to trigger it).
283 if( !changed && aVariant.IsNull() )
284 changed = true;
285
286 return changed;
287}
288
289
291 wxPGCheckBoxEditor()
292{
293}
294
295
296wxPGWindowList PG_CHECKBOX_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
297 const wxPoint& aPos, const wxSize& aSize ) const
298{
299 // Override wx behavior and toggle unspecified checkboxes to "true"
300 // CreateControls for a checkbox editor is only triggered when the user activates the checkbox
301 // Set the value to false here; the base class will then trigger an event setting it true.
302 if( aProperty->IsValueUnspecified() )
303 aProperty->SetValueFromInt( 0 );
304
305 return wxPGCheckBoxEditor::CreateControls( aGrid, aProperty, aPos, aSize );
306}
307
308
309bool PG_COLOR_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aWindow,
310 wxEvent& aEvent ) const
311{
312 return false;
313}
314
315
316wxPGWindowList PG_COLOR_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
317 const wxPoint& aPos, const wxSize& aSize ) const
318{
319 auto colorProp = dynamic_cast<PGPROPERTY_COLOR4D*>( aProperty );
320
321 if( !colorProp )
322 return nullptr;
323
325 KIGFX::COLOR4D defColor = colorFromVariant( colorProp->GetDefaultValue() );
326
327 COLOR_SWATCH* editor = new COLOR_SWATCH( aGrid->GetPanel(), color, wxID_ANY,
328 colorProp->GetBackgroundColor(), defColor,
329 SWATCH_LARGE, true );
330 editor->SetPosition( aPos );
331 editor->SetSize( aSize );
332
333 editor->Bind( COLOR_SWATCH_CHANGED,
334 [=]( wxCommandEvent& aEvt )
335 {
336 wxVariant val;
337 auto data = new COLOR4D_VARIANT_DATA( editor->GetSwatchColor() );
338 val.SetData( data );
339 aGrid->ChangePropertyValue( colorProp, val );
340 } );
341
342#if wxCHECK_VERSION( 3, 3, 0 )
343 if( aGrid->GetInternalFlags() & wxPropertyGrid::wxPG_FL_ACTIVATION_BY_CLICK )
344#else
345 if( aGrid->GetInternalFlags() & wxPG_FL_ACTIVATION_BY_CLICK )
346#endif
347 {
348 aGrid->CallAfter(
349 [=]()
350 {
351 editor->GetNewSwatchColor();
352 } );
353 }
354
355 return editor;
356}
357
358
359void PG_COLOR_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const
360{
361 if( auto swatch = dynamic_cast<COLOR_SWATCH*>( aCtrl ) )
362 swatch->SetSwatchColor( colorFromProperty( aProperty ), false );
363}
364
365
366KIGFX::COLOR4D PG_COLOR_EDITOR::colorFromVariant( const wxVariant& aVariant ) const
367{
369 COLOR4D_VARIANT_DATA* data = nullptr;
370
371 if( aVariant.IsType( wxS( "COLOR4D" ) ) )
372 {
373 data = static_cast<COLOR4D_VARIANT_DATA*>( aVariant.GetData() );
374 color = data->Color();
375 }
376
377 return color;
378}
379
380
382{
383 return colorFromVariant( aProperty->GetValue() );
384}
385
386
387bool PG_RATIO_EDITOR::GetValueFromControl( wxVariant& aVariant, wxPGProperty* aProperty,
388 wxWindow* aCtrl ) const
389{
390 wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl );
391 wxCHECK_MSG( textCtrl, false, "PG_RATIO_EDITOR requires a text control!" );
392 wxString textVal = textCtrl->GetValue();
393
394 if( textVal == wxT( "<...>" ) )
395 {
396 aVariant.MakeNull();
397 return true;
398 }
399
400 bool changed;
401
402 if( aVariant.GetType() == wxT( "std::optional<double>" ) )
403 {
404 auto* variantData = static_cast<STD_OPTIONAL_DOUBLE_VARIANT_DATA*>( aVariant.GetData() );
405
406 if( textVal.empty() )
407 {
408 changed = ( aVariant.IsNull() || variantData->Value().has_value() );
409
410 if( changed )
411 aVariant = wxVariant( std::optional<double>() );
412 }
413 else
414 {
415 double dblValue;
416 textVal.ToDouble( &dblValue );
417 std::optional<double> result( dblValue );
418 changed = ( aVariant.IsNull() || result != variantData->Value() );
419
420 if( changed )
421 {
422 aVariant = wxVariant( result );
423 textCtrl->SetValue( wxString::Format( wxS( "%g" ), dblValue ) );
424 }
425 }
426 }
427 else
428 {
429 double result;
430 textVal.ToDouble( &result );
431 changed = ( aVariant.IsNull() || result != aVariant.GetDouble() );
432
433 if( changed )
434 {
435 aVariant = result;
436 textCtrl->SetValue( wxString::Format( wxS( "%g" ), result ) );
437 }
438 }
439
440 // Changing unspecified always causes event (returning
441 // true here should be enough to trigger it).
442 if( !changed && aVariant.IsNull() )
443 changed = true;
444
445 return changed;
446}
447
448
449void PG_RATIO_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const
450{
451 wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl );
452 wxVariant var = aProperty->GetValue();
453
454 wxCHECK_MSG( textCtrl, /*void*/, wxT( "PG_RATIO_EDITOR must be used with a textCtrl!" ) );
455
456 if( var.GetType() == wxT( "std::optional<double>" ) )
457 {
458 auto* variantData = static_cast<STD_OPTIONAL_DOUBLE_VARIANT_DATA*>( var.GetData() );
459 wxString strValue;
460
461 if( variantData->Value().has_value() )
462 strValue = wxString::Format( wxS( "%g" ), variantData->Value().value() );
463
464 textCtrl->ChangeValue( strValue );
465 }
466 else if( var.GetType() == wxPG_VARIANT_TYPE_DOUBLE )
467 {
468 textCtrl->ChangeValue( wxString::Format( wxS( "%g" ), var.GetDouble() ) );
469 }
470 else if( !aProperty->IsValueUnspecified() )
471 {
472 wxFAIL_MSG( wxT( "PG_RATIO_EDITOR should only be used with scale-free numeric "
473 "properties!" ) );
474 }
475}
476
477
479{
480 m_editorName = BuildEditorName( aFrame );
481}
482
483
485{
486 m_frame = aFrame;
487 m_editorName = BuildEditorName( aFrame );
488}
489
490
492{
493 if( !aFrame )
494 return EDITOR_NAME + "NoFrame";
495
496 return EDITOR_NAME + aFrame->GetName();
497}
498
499
500wxPGWindowList PG_FPID_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
501 const wxPoint& aPos, const wxSize& aSize ) const
502{
503 wxPGMultiButton* buttons = new wxPGMultiButton( aGrid, aSize );
504 buttons->Add( KiBitmap( BITMAPS::small_library ) );
505 buttons->Finalize( aGrid, aPos );
506 wxSize textSize = buttons->GetPrimarySize();
507 wxWindow* textCtrl = aGrid->GenerateEditorTextCtrl( aPos, textSize,
508 aProperty->GetValueAsString(), nullptr, 0,
509 aProperty->GetMaxLength() );
510 wxPGWindowList ret( textCtrl, buttons );
511 return ret;
512}
513
514
515bool PG_FPID_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl,
516 wxEvent& aEvent ) const
517{
518 if( aEvent.GetEventType() == wxEVT_BUTTON )
519 {
520 wxString fpid = aProperty->GetValue().GetString();
521
522 if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_frame ) )
523 {
524 if( frame->ShowModal( &fpid, m_frame ) )
525 aGrid->ChangePropertyValue( aProperty, fpid );
526
527 frame->Destroy();
528 }
529
530 return true;
531 }
532
533 return wxPGTextCtrlEditor::OnEvent( aGrid, aProperty, aCtrl, aEvent );
534}
535
536
538{
539 m_editorName = BuildEditorName( aFrame );
540}
541
542
544{
545 m_frame = aFrame;
546 m_editorName = BuildEditorName( aFrame );
547}
548
549
551{
552 if( !aFrame )
553 return EDITOR_NAME + "NoFrame";
554
555 return EDITOR_NAME + aFrame->GetName();
556}
557
558
559wxPGWindowList PG_URL_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
560 const wxPoint& aPos, const wxSize& aSize ) const
561{
562 wxPGMultiButton* buttons = new wxPGMultiButton( aGrid, aSize );
563 // Use a folder icon when no datasheet is set; otherwise use a globe icon.
564 wxString urlValue = aProperty->GetValueAsString();
565 bool hasUrl = !( urlValue.IsEmpty() || urlValue == wxS( "~" ) );
566 buttons->Add( KiBitmap( hasUrl ? BITMAPS::www : BITMAPS::small_folder ) );
567 buttons->Finalize( aGrid, aPos );
568 wxSize textSize = buttons->GetPrimarySize();
569 wxWindow* textCtrl = aGrid->GenerateEditorTextCtrl( aPos, textSize,
570 aProperty->GetValueAsString(), nullptr, 0,
571 aProperty->GetMaxLength() );
572 wxPGWindowList ret( textCtrl, buttons );
573 return ret;
574}
575
576
577bool PG_URL_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl,
578 wxEvent& aEvent ) const
579{
580 if( aEvent.GetEventType() == wxEVT_BUTTON )
581 {
582 wxString filename = aProperty->GetValue().GetString();
583
584 if( filename.IsEmpty() || filename == wxS( "~" ) )
585 {
586 wxFileDialog openFileDialog( m_frame, _( "Open file" ), wxS( "" ), wxS( "" ),
587 _( "All Files" ) + wxS( " (*.*)|*.*" ),
588 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
589
590 if( openFileDialog.ShowModal() == wxID_OK )
591 {
592 filename = openFileDialog.GetPath();
593 aGrid->ChangePropertyValue( aProperty, wxString::Format( wxS( "file://%s" ),
594 filename ) );
595 }
596 }
597 else
598 {
599 GetAssociatedDocument( m_frame, filename, &m_frame->Prj() );
600 }
601
602 // Update the button icon to reflect presence/absence of URL
603 if( wxObject* src = aEvent.GetEventObject() )
604 {
605 wxString newUrl = aProperty->GetValueAsString();
606 bool hasUrl = !( newUrl.IsEmpty() || newUrl == wxS( "~" ) );
607 auto bmp = KiBitmap( hasUrl ? BITMAPS::www : BITMAPS::small_folder );
608
609 if( wxWindow* win = wxDynamicCast( src, wxWindow ) )
610 {
611 if( wxBitmapButton* bb = wxDynamicCast( win, wxBitmapButton ) )
612 {
613 bb->SetBitmap( bmp );
614 }
615 else if( wxButton* b = wxDynamicCast( win, wxButton ) )
616 {
617 b->SetBitmap( bmp );
618 }
619 else if( wxWindow* parent = win->GetParent() )
620 {
621 if( wxPGMultiButton* buttons = wxDynamicCast( parent, wxPGMultiButton ) )
622 {
623 wxWindow* btn0 = buttons->GetButton( 0 );
624 if( wxBitmapButton* bb0 = wxDynamicCast( btn0, wxBitmapButton ) )
625 bb0->SetBitmap( bmp );
626 else if( wxButton* b0 = wxDynamicCast( btn0, wxButton ) )
627 b0->SetBitmap( bmp );
628 }
629 }
630 }
631 }
632 return true;
633 }
634
635 return wxPGTextCtrlEditor::OnEvent( aGrid, aProperty, aCtrl, aEvent );
636}
int color
wxBitmap KiBitmap(BITMAPS aBitmap, int aHeightTag)
Construct a wxBitmap from an image identifier Returns the image from the active theme if the image ha...
Definition bitmap.cpp:104
const KIGFX::COLOR4D & Color()
A simple color swatch of the kind used to set layer colors.
const EDA_ANGLE & Angle()
void SetAngle(const EDA_ANGLE &aAngle)
double AsDegrees() const
Definition eda_angle.h:116
The base class for create windows for drawing purpose.
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:104
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:398
A wxFrame capable of the OpenProjectFiles function, meaning it can load a portion of a KiCad project.
A wxEnumProperty that displays a color next to the enum value.
wxPGWindowList CreateControls(wxPropertyGrid *aGrid, wxPGProperty *aProperty, const wxPoint &aPos, const wxSize &aSize) const override
static const wxString EDITOR_NAME
Definition pg_editors.h:75
static const wxString EDITOR_NAME
Definition pg_editors.h:91
wxPGWindowList CreateControls(wxPropertyGrid *aGrid, wxPGProperty *aProperty, const wxPoint &aPos, const wxSize &aSize) const override
bool OnEvent(wxPropertyGrid *aGrid, wxPGProperty *aProperty, wxWindow *aWindow, wxEvent &aEvent) const override
KIGFX::COLOR4D colorFromVariant(const wxVariant &aVariant) const
void UpdateControl(wxPGProperty *aProperty, wxWindow *aCtrl) const override
KIGFX::COLOR4D colorFromProperty(wxPGProperty *aProperty) const
wxString m_editorName
Definition pg_editors.h:151
void UpdateFrame(EDA_DRAW_FRAME *aFrame)
PG_FPID_EDITOR(EDA_DRAW_FRAME *aFrame)
wxPGWindowList CreateControls(wxPropertyGrid *aGrid, wxPGProperty *aProperty, const wxPoint &aPos, const wxSize &aSize) const override
static const wxString EDITOR_NAME
Definition pg_editors.h:131
EDA_DRAW_FRAME * m_frame
Definition pg_editors.h:150
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
bool OnEvent(wxPropertyGrid *aGrid, wxPGProperty *aProperty, wxWindow *aCtrl, wxEvent &aEvent) const override
bool GetValueFromControl(wxVariant &aVariant, wxPGProperty *aProperty, wxWindow *aCtrl) const override
static const wxString EDITOR_NAME
Definition pg_editors.h:117
void UpdateControl(wxPGProperty *aProperty, wxWindow *aCtrl) const override
std::unique_ptr< PROPERTY_EDITOR_UNIT_BINDER > m_unitBinder
Definition pg_editors.h:66
wxPGWindowList CreateControls(wxPropertyGrid *aPropGrid, wxPGProperty *aProperty, const wxPoint &aPos, const wxSize &aSize) const override
static const wxString EDITOR_NAME
Definition pg_editors.h:34
void UpdateControl(wxPGProperty *aProperty, wxWindow *aCtrl) const override
void UpdateFrame(EDA_DRAW_FRAME *aFrame)
When restarting an editor, the instance of PG_UNIT_EDITOR may be the same but the referenced frame is...
EDA_DRAW_FRAME * m_frame
Definition pg_editors.h:64
PG_UNIT_EDITOR(EDA_DRAW_FRAME *aFrame)
bool GetValueFromControl(wxVariant &aVariant, wxPGProperty *aProperty, wxWindow *aCtrl) const override
wxString m_editorName
Definition pg_editors.h:68
bool OnEvent(wxPropertyGrid *aPropGrid, wxPGProperty *aProperty, wxWindow *aCtrl, wxEvent &aEvent) const override
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
virtual ~PG_UNIT_EDITOR()
static const wxString EDITOR_NAME
Definition pg_editors.h:158
PG_URL_EDITOR(EDA_DRAW_FRAME *aFrame)
wxString m_editorName
Definition pg_editors.h:178
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
void UpdateFrame(EDA_DRAW_FRAME *aFrame)
EDA_DRAW_FRAME * m_frame
Definition pg_editors.h:177
wxPGWindowList CreateControls(wxPropertyGrid *aGrid, wxPGProperty *aProperty, const wxPoint &aPos, const wxSize &aSize) const override
bool OnEvent(wxPropertyGrid *aGrid, wxPGProperty *aProperty, wxWindow *aCtrl, wxEvent &aEvent) const override
@ SWATCH_LARGE
#define _(s)
bool GetAssociatedDocument(wxWindow *aParent, const wxString &aDocName, PROJECT *aProject, SEARCH_STACK *aPaths, std::vector< EMBEDDED_FILES * > aFilesStack)
Open a document (file) with the suitable browser.
Definition eda_doc.cpp:62
This file is part of the common library.
@ FRAME_FOOTPRINT_CHOOSER
Definition frame_type.h:44
static std::string strValue(double aValue)
wxString result
Test unit parsing edge cases and error handling.