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