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>
27#include <widgets/unit_binder.h>
28#include <bitmaps.h>
29#include <frame_type.h>
30#include <kiway_player.h>
31#include <kiway.h>
32#include <wx/filedlg.h>
33#include <wx/intl.h>
34#include <eda_doc.h>
35#include <kiplatform/ui.h>
36#include <kiway_mail.h>
37
38#include <wx/button.h>
39#include <wx/bmpbuttn.h>
40
41#include <wx/log.h>
42
43const wxString PG_UNIT_EDITOR::EDITOR_NAME = wxS( "KiCadUnitEditor" );
44const wxString PG_CHECKBOX_EDITOR::EDITOR_NAME = wxS( "KiCadCheckboxEditor" );
45const wxString PG_COLOR_EDITOR::EDITOR_NAME = wxS( "KiCadColorEditor" );
46const wxString PG_RATIO_EDITOR::EDITOR_NAME = wxS( "KiCadRatioEditor" );
47const wxString PG_FPID_EDITOR::EDITOR_NAME = wxS( "KiCadFpidEditor" );
48const wxString PG_URL_EDITOR::EDITOR_NAME = wxS( "KiCadUrlEditor" );
49
50
52 wxPGTextCtrlEditor(),
53 m_frame( aFrame )
54{
55 m_unitBinder = std::make_unique<PROPERTY_EDITOR_UNIT_BINDER>( m_frame );
56 m_unitBinder->SetUnits( m_frame->GetUserUnits() );
57
59}
60
61
65
66
68{
69 if( !aFrame )
70 return EDITOR_NAME + "NoFrame";
71
72 return EDITOR_NAME + aFrame->GetName();
73}
74
75
77{
78 m_frame = aFrame;
79
80 if( aFrame )
81 {
82 m_unitBinder = std::make_unique<PROPERTY_EDITOR_UNIT_BINDER>( m_frame );
83 m_unitBinder->SetUnits( m_frame->GetUserUnits() );
84 }
85 else
86 {
87 m_unitBinder = nullptr;
88 }
89}
90
91
92wxPGWindowList PG_UNIT_EDITOR::CreateControls( wxPropertyGrid* aPropGrid, wxPGProperty* aProperty,
93 const wxPoint& aPos, const wxSize& aSize ) const
94{
95 wxASSERT( m_unitBinder );
96
97#if wxCHECK_VERSION( 3, 3, 0 )
98 wxString text = aProperty->GetValueAsString( wxPGPropValFormatFlags::EditableValue );
99#else
100 wxString text = aProperty->GetValueAsString( wxPG_EDITABLE_VALUE );
101#endif
102 wxWindow* win = aPropGrid->GenerateEditorTextCtrl( aPos, aSize, text, nullptr, 0,
103 aProperty->GetMaxLength() );
104 wxPGWindowList ret( win, nullptr );
105
106 m_unitBinder->SetControl( win );
107 m_unitBinder->RequireEval();
108 m_unitBinder->SetUnits( m_frame->GetUserUnits() );
109
110 if( PGPROPERTY_DISTANCE* prop = dynamic_cast<PGPROPERTY_DISTANCE*>( aProperty ) )
111 {
112 m_unitBinder->SetCoordType( prop->CoordType() );
113 }
114 else if( dynamic_cast<PGPROPERTY_AREA*>( aProperty) != nullptr )
115 {
116 m_unitBinder->SetDataType( EDA_DATA_TYPE::AREA );
117 }
118 else if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) != nullptr )
119 {
121 m_unitBinder->SetUnits( EDA_UNITS::DEGREES );
122 }
123 else if( dynamic_cast<PGPROPERTY_TIME*>( aProperty ) != nullptr )
124 {
125 m_unitBinder->SetUnits( EDA_UNITS::PS );
126 }
127
128 UpdateControl( aProperty, win );
129
130 return ret;
131}
132
133
134void PG_UNIT_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const
135{
136 wxVariant var = aProperty->GetValue();
137
138 if( var.GetType() == wxT( "std::optional<int>" ) )
139 {
140 auto* variantData = static_cast<STD_OPTIONAL_INT_VARIANT_DATA*>( var.GetData() );
141
142 if( variantData->Value().has_value() )
143 m_unitBinder->ChangeValue( variantData->Value().value() );
144 else
145 m_unitBinder->ChangeValue( wxEmptyString );
146 }
147 else if( var.GetType() == wxPG_VARIANT_TYPE_LONG )
148 {
149 m_unitBinder->ChangeValue( var.GetLong() );
150 }
151 else if( var.GetType() == wxPG_VARIANT_TYPE_LONGLONG )
152 {
153 m_unitBinder->ChangeDoubleValue( var.GetLongLong().ToDouble() );
154 }
155 else if( var.GetType() == wxPG_VARIANT_TYPE_DOUBLE )
156 {
157 m_unitBinder->ChangeValue( var.GetDouble() );
158 }
159 else if( var.GetType() == wxT( "EDA_ANGLE" ) )
160 {
161 EDA_ANGLE_VARIANT_DATA* angleData = static_cast<EDA_ANGLE_VARIANT_DATA*>( var.GetData() );
162 m_unitBinder->ChangeAngleValue( angleData->Angle() );
163 }
164 else if( !aProperty->IsValueUnspecified() )
165 {
166 wxFAIL_MSG( wxT( "PG_UNIT_EDITOR should only be used with numeric properties!" ) );
167 }
168}
169
170
171bool PG_UNIT_EDITOR::OnEvent( wxPropertyGrid* aPropGrid, wxPGProperty* aProperty,
172 wxWindow* aCtrl, wxEvent& aEvent ) const
173{
174 if( aEvent.GetEventType() == wxEVT_LEFT_UP )
175 {
176 if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl ) )
177 {
178 if( !textCtrl->HasFocus() )
179 {
180 textCtrl->SelectAll();
181 return false;
182 }
183 }
184 }
185
186 return wxPGTextCtrlEditor::OnEvent( aPropGrid, aProperty, aCtrl, aEvent );
187}
188
189
190bool PG_UNIT_EDITOR::GetValueFromControl( wxVariant& aVariant, wxPGProperty* aProperty,
191 wxWindow* aCtrl ) const
192{
193 if( !m_unitBinder )
194 return false;
195
196 wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl );
197 wxCHECK_MSG( textCtrl, false, "PG_UNIT_EDITOR requires a text control!" );
198 wxString textVal = textCtrl->GetValue();
199
200 if( textVal == wxT( "<...>" ) )
201 {
202 aVariant.MakeNull();
203 return true;
204 }
205
206 bool changed;
207
208 if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) != nullptr )
209 {
210 EDA_ANGLE angle = m_unitBinder->GetAngleValue();
211
212 if( aVariant.GetType() == wxT( "EDA_ANGLE" ) )
213 {
214 EDA_ANGLE_VARIANT_DATA* ad = static_cast<EDA_ANGLE_VARIANT_DATA*>( aVariant.GetData() );
215 changed = ( aVariant.IsNull() || angle != ad->Angle() );
216
217 if( changed )
218 {
219 ad->SetAngle( angle );
220 m_unitBinder->SetAngleValue( angle );
221 }
222 }
223 else
224 {
225 changed = ( aVariant.IsNull() || angle.AsDegrees() != aVariant.GetDouble() );
226
227 if( changed )
228 {
229 aVariant = angle.AsDegrees();
230 m_unitBinder->SetValue( angle.AsDegrees() );
231 }
232 }
233 }
234 else if( dynamic_cast<PGPROPERTY_AREA*>( aProperty ) != nullptr )
235 {
236 wxLongLongNative result = m_unitBinder->GetValue();
237 changed = ( aVariant.IsNull() || result != aVariant.GetLongLong() );
238
239 if( changed )
240 {
241 aVariant = result;
242 m_unitBinder->SetDoubleValue( result.ToDouble() );
243 }
244 }
245 else if( aVariant.GetType() == wxT( "std::optional<int>" ) )
246 {
247 auto* variantData = static_cast<STD_OPTIONAL_INT_VARIANT_DATA*>( aVariant.GetData() );
248 std::optional<int> result;
249
250 if( m_unitBinder->IsNull() )
251 {
252 changed = ( aVariant.IsNull() || variantData->Value().has_value() );
253
254 if( changed )
255 {
256 aVariant = wxVariant( std::optional<int>() );
257 m_unitBinder->SetValue( wxEmptyString );
258 }
259 }
260 else
261 {
262 result = std::optional<int>( m_unitBinder->GetValue() );
263 changed = ( aVariant.IsNull() || result != variantData->Value() );
264
265 if( changed )
266 {
267 aVariant = wxVariant( result );
268 m_unitBinder->SetValue( result.value() );
269 }
270 }
271 }
272 else
273 {
274 long result = m_unitBinder->GetValue();
275 changed = ( aVariant.IsNull() || result != aVariant.GetLong() );
276
277 if( changed )
278 {
279 aVariant = result;
280 m_unitBinder->SetValue( result );
281 }
282 }
283
284 // Changing unspecified always causes event (returning
285 // true here should be enough to trigger it).
286 if( !changed && aVariant.IsNull() )
287 changed = true;
288
289 return changed;
290}
291
292
294 wxPGCheckBoxEditor()
295{
296}
297
298
299wxPGWindowList PG_CHECKBOX_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
300 const wxPoint& aPos, const wxSize& aSize ) const
301{
302 // Override wx behavior and toggle unspecified checkboxes to "true"
303 // CreateControls for a checkbox editor is only triggered when the user activates the checkbox
304 // Set the value to false here; the base class will then trigger an event setting it true.
305 if( aProperty->IsValueUnspecified() )
306 aProperty->SetValueFromInt( 0 );
307
308 return wxPGCheckBoxEditor::CreateControls( aGrid, aProperty, aPos, aSize );
309}
310
311
312bool PG_COLOR_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aWindow,
313 wxEvent& aEvent ) const
314{
315 return false;
316}
317
318
319wxPGWindowList PG_COLOR_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
320 const wxPoint& aPos, const wxSize& aSize ) const
321{
322 auto colorProp = dynamic_cast<PGPROPERTY_COLOR4D*>( aProperty );
323
324 if( !colorProp )
325 return nullptr;
326
327 KIGFX::COLOR4D color = colorFromProperty( aProperty );
328 KIGFX::COLOR4D defColor = colorFromVariant( colorProp->GetDefaultValue() );
329
330 COLOR_SWATCH* editor = new COLOR_SWATCH( aGrid->GetPanel(), color, wxID_ANY,
331 colorProp->GetBackgroundColor(), defColor,
332 SWATCH_LARGE, true );
333 editor->SetPosition( aPos );
334 editor->SetSize( aSize );
335
336 // Capture property name instead of pointer to avoid dangling pointer if grid is rebuilt
337 wxString propName = colorProp->GetName();
338
339 editor->Bind( COLOR_SWATCH_CHANGED,
340 [=]( wxCommandEvent& aEvt )
341 {
342 wxPGProperty* prop = aGrid->GetPropertyByName( propName );
343
344 if( prop )
345 {
346 wxVariant val;
347 auto data = new COLOR4D_VARIANT_DATA( editor->GetSwatchColor() );
348 val.SetData( data );
349 aGrid->ChangePropertyValue( prop, val );
350 }
351 } );
352
353#if wxCHECK_VERSION( 3, 3, 0 )
354 if( aGrid->GetInternalFlags() & wxPropertyGrid::wxPG_FL_ACTIVATION_BY_CLICK )
355#else
356 if( aGrid->GetInternalFlags() & wxPG_FL_ACTIVATION_BY_CLICK )
357#endif
358 {
359 aGrid->CallAfter(
360 [=]()
361 {
362 editor->GetNewSwatchColor();
363
364 wxPGProperty* prop = aGrid->GetPropertyByName( propName );
365
366 if( prop )
367 aGrid->DrawItem( prop );
368 } );
369 }
370
371 return editor;
372}
373
374
375void PG_COLOR_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const
376{
377 if( auto swatch = dynamic_cast<COLOR_SWATCH*>( aCtrl ) )
378 swatch->SetSwatchColor( colorFromProperty( aProperty ), false );
379}
380
381
382KIGFX::COLOR4D PG_COLOR_EDITOR::colorFromVariant( const wxVariant& aVariant ) const
383{
385 COLOR4D_VARIANT_DATA* data = nullptr;
386
387 if( aVariant.IsType( wxS( "COLOR4D" ) ) )
388 {
389 data = static_cast<COLOR4D_VARIANT_DATA*>( aVariant.GetData() );
390 color = data->Color();
391 }
392
393 return color;
394}
395
396
398{
399 return colorFromVariant( aProperty->GetValue() );
400}
401
402
403bool PG_RATIO_EDITOR::GetValueFromControl( wxVariant& aVariant, wxPGProperty* aProperty,
404 wxWindow* aCtrl ) const
405{
406 wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl );
407 wxCHECK_MSG( textCtrl, false, "PG_RATIO_EDITOR requires a text control!" );
408 wxString textVal = textCtrl->GetValue();
409
410 if( textVal == wxT( "<...>" ) )
411 {
412 aVariant.MakeNull();
413 return true;
414 }
415
416 bool changed;
417
418 if( aVariant.GetType() == wxT( "std::optional<double>" ) )
419 {
420 auto* variantData = static_cast<STD_OPTIONAL_DOUBLE_VARIANT_DATA*>( aVariant.GetData() );
421
422 if( textVal.empty() )
423 {
424 changed = ( aVariant.IsNull() || variantData->Value().has_value() );
425
426 if( changed )
427 aVariant = wxVariant( std::optional<double>() );
428 }
429 else
430 {
431 double dblValue;
432 textVal.ToDouble( &dblValue );
433 std::optional<double> result( dblValue );
434 changed = ( aVariant.IsNull() || result != variantData->Value() );
435
436 if( changed )
437 {
438 aVariant = wxVariant( result );
439 textCtrl->SetValue( wxString::Format( wxS( "%g" ), dblValue ) );
440 }
441 }
442 }
443 else
444 {
445 double result;
446 textVal.ToDouble( &result );
447 changed = ( aVariant.IsNull() || result != aVariant.GetDouble() );
448
449 if( changed )
450 {
451 aVariant = result;
452 textCtrl->SetValue( wxString::Format( wxS( "%g" ), result ) );
453 }
454 }
455
456 // Changing unspecified always causes event (returning
457 // true here should be enough to trigger it).
458 if( !changed && aVariant.IsNull() )
459 changed = true;
460
461 return changed;
462}
463
464
465void PG_RATIO_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const
466{
467 wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl );
468 wxVariant var = aProperty->GetValue();
469
470 wxCHECK_MSG( textCtrl, /*void*/, wxT( "PG_RATIO_EDITOR must be used with a textCtrl!" ) );
471
472 if( var.GetType() == wxT( "std::optional<double>" ) )
473 {
474 auto* variantData = static_cast<STD_OPTIONAL_DOUBLE_VARIANT_DATA*>( var.GetData() );
475 wxString strValue;
476
477 if( variantData->Value().has_value() )
478 strValue = wxString::Format( wxS( "%g" ), variantData->Value().value() );
479
480 textCtrl->ChangeValue( strValue );
481 }
482 else if( var.GetType() == wxPG_VARIANT_TYPE_DOUBLE )
483 {
484 textCtrl->ChangeValue( wxString::Format( wxS( "%g" ), var.GetDouble() ) );
485 }
486 else if( !aProperty->IsValueUnspecified() )
487 {
488 wxFAIL_MSG( wxT( "PG_RATIO_EDITOR should only be used with scale-free numeric "
489 "properties!" ) );
490 }
491}
492
493
494PG_FPID_EDITOR::PG_FPID_EDITOR( EDA_DRAW_FRAME* aFrame, const std::function<std::string()>& aNetlistCallback ) :
495 m_frame( aFrame ),
496 m_netlistCallback( aNetlistCallback )
497{
498 m_editorName = BuildEditorName( aFrame );
499}
500
501
503{
504 m_frame = aFrame;
505 m_editorName = BuildEditorName( aFrame );
506}
507
508
510{
511 if( !aFrame )
512 return EDITOR_NAME + "NoFrame";
513
514 return EDITOR_NAME + aFrame->GetName();
515}
516
517
518wxPGWindowList PG_FPID_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
519 const wxPoint& aPos, const wxSize& aSize ) const
520{
521 wxPGMultiButton* buttons = new wxPGMultiButton( aGrid, aSize );
522 buttons->Add( KiBitmap( BITMAPS::small_library ) );
523 buttons->Finalize( aGrid, aPos );
524 wxSize textSize = buttons->GetPrimarySize();
525 wxWindow* textCtrl = aGrid->GenerateEditorTextCtrl( aPos, textSize,
526 aProperty->GetValueAsString(), nullptr, 0,
527 aProperty->GetMaxLength() );
528 wxPGWindowList ret( textCtrl, buttons );
529 return ret;
530}
531
532
533bool PG_FPID_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl,
534 wxEvent& aEvent ) const
535{
536 if( aEvent.GetEventType() == wxEVT_BUTTON )
537 {
538 wxString fpid = aProperty->GetValue().GetString();
539
540 if( KIWAY_PLAYER* frame = m_frame->Kiway().Player( FRAME_FOOTPRINT_CHOOSER, true, m_frame ) )
541 {
542 // Create symbol netlist for footprint picker
543 std::string symbolNetlist = m_netlistCallback();
544
545 if( !symbolNetlist.empty() )
546 {
548 frame->KiwayMailIn( event );
549 }
550
551 if( frame->ShowModal( &fpid, m_frame ) )
552 aGrid->ChangePropertyValue( aProperty, fpid );
553
554 frame->Destroy();
555 }
556
557 return true;
558 }
559
560 return wxPGTextCtrlEditor::OnEvent( aGrid, aProperty, aCtrl, aEvent );
561}
562
563
565{
566 m_editorName = BuildEditorName( aFrame );
567}
568
569
571{
572 m_frame = aFrame;
573 m_editorName = BuildEditorName( aFrame );
574}
575
576
578{
579 if( !aFrame )
580 return EDITOR_NAME + "NoFrame";
581
582 return EDITOR_NAME + aFrame->GetName();
583}
584
585
586wxPGWindowList PG_URL_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
587 const wxPoint& aPos, const wxSize& aSize ) const
588{
589 wxPGMultiButton* buttons = new wxPGMultiButton( aGrid, aSize );
590 // Use a folder icon when no datasheet is set; otherwise use a globe icon.
591 wxString urlValue = aProperty->GetValueAsString();
592 bool hasUrl = !( urlValue.IsEmpty() || urlValue == wxS( "~" ) );
593 buttons->Add( KiBitmap( hasUrl ? BITMAPS::www : BITMAPS::small_folder ) );
594 buttons->Finalize( aGrid, aPos );
595 wxSize textSize = buttons->GetPrimarySize();
596 wxWindow* textCtrl = aGrid->GenerateEditorTextCtrl( aPos, textSize,
597 aProperty->GetValueAsString(), nullptr, 0,
598 aProperty->GetMaxLength() );
599 wxPGWindowList ret( textCtrl, buttons );
600 return ret;
601}
602
603
604bool PG_URL_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aCtrl,
605 wxEvent& aEvent ) const
606{
607 if( aEvent.GetEventType() == wxEVT_BUTTON )
608 {
609 wxString filename = aProperty->GetValue().GetString();
610
611 if( filename.IsEmpty() || filename == wxS( "~" ) )
612 {
613 wxFileDialog openFileDialog( m_frame, _( "Open file" ), wxS( "" ), wxS( "" ),
614 _( "All Files" ) + wxS( " (*.*)|*.*" ),
615 wxFD_OPEN | wxFD_FILE_MUST_EXIST );
616
618
619 if( openFileDialog.ShowModal() == wxID_OK )
620 {
621 filename = openFileDialog.GetPath();
622 aGrid->ChangePropertyValue( aProperty, wxString::Format( wxS( "file://%s" ),
623 filename ) );
624 }
625 }
626 else
627 {
628 GetAssociatedDocument( m_frame, filename, &m_frame->Prj() );
629 }
630
631 // Update the button icon to reflect presence/absence of URL
632 if( wxObject* src = aEvent.GetEventObject() )
633 {
634 wxString newUrl = aProperty->GetValueAsString();
635 bool hasUrl = !( newUrl.IsEmpty() || newUrl == wxS( "~" ) );
636 auto bmp = KiBitmap( hasUrl ? BITMAPS::www : BITMAPS::small_folder );
637
638 if( wxWindow* win = wxDynamicCast( src, wxWindow ) )
639 {
640 if( wxBitmapButton* bb = wxDynamicCast( win, wxBitmapButton ) )
641 {
642 bb->SetBitmap( bmp );
643 }
644 else if( wxButton* b = wxDynamicCast( win, wxButton ) )
645 {
646 b->SetBitmap( bmp );
647 }
648 else if( wxWindow* parent = win->GetParent() )
649 {
650 if( wxPGMultiButton* buttons = wxDynamicCast( parent, wxPGMultiButton ) )
651 {
652 wxWindow* btn0 = buttons->GetButton( 0 );
653 if( wxBitmapButton* bb0 = wxDynamicCast( btn0, wxBitmapButton ) )
654 bb0->SetBitmap( bmp );
655 else if( wxButton* b0 = wxDynamicCast( btn0, wxButton ) )
656 b0->SetBitmap( bmp );
657 }
658 }
659 }
660 }
661 return true;
662 }
663
664 return wxPGTextCtrlEditor::OnEvent( aGrid, aProperty, aCtrl, aEvent );
665}
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:105
static const COLOR4D UNSPECIFIED
For legacy support; used as a value to indicate color hasn't been set yet.
Definition color4d.h:402
Carry a payload from one KIWAY_PLAYER to another within a PROJECT.
Definition kiway_mail.h:38
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)
std::function< std::string()> m_netlistCallback
Definition pg_editors.h:152
PG_FPID_EDITOR(EDA_DRAW_FRAME *aFrame, const std::function< std::string()> &aNetlistCallback)
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:159
PG_URL_EDITOR(EDA_DRAW_FRAME *aFrame)
wxString m_editorName
Definition pg_editors.h:179
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
void UpdateFrame(EDA_DRAW_FRAME *aFrame)
EDA_DRAW_FRAME * m_frame
Definition pg_editors.h:178
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:63
This file is part of the common library.
@ FRAME_FOOTPRINT_CHOOSER
Definition frame_type.h:44
@ MAIL_SYMBOL_NETLIST
Definition mail_type.h:45
void AllowNetworkFileSystems(wxDialog *aDialog)
Configure a file dialog to show network and virtual file systems.
Definition wxgtk/ui.cpp:435
static std::string strValue(double aValue)
wxString result
Test unit parsing edge cases and error handling.