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 (C) 2022 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
28#include <wx/log.h>
29
30const wxString PG_UNIT_EDITOR::EDITOR_NAME = wxS( "KiCadUnitEditor" );
31const wxString PG_CHECKBOX_EDITOR::EDITOR_NAME = wxS( "KiCadCheckboxEditor" );
32const wxString PG_COLOR_EDITOR::EDITOR_NAME = wxS( "KiCadColorEditor" );
33
34
36 wxPGTextCtrlEditor(),
37 m_frame( aFrame )
38{
39 m_unitBinder = std::make_unique<PROPERTY_EDITOR_UNIT_BINDER>( m_frame );
40 m_unitBinder->SetUnits( m_frame->GetUserUnits() );
41
43}
44
45
47{
48}
49
50
52{
53 return EDITOR_NAME + aFrame->GetName();
54}
55
56
58{
59 m_frame = aFrame;
60
61 if( aFrame )
62 {
63 m_unitBinder = std::make_unique<PROPERTY_EDITOR_UNIT_BINDER>( m_frame );
64 m_unitBinder->SetUnits( m_frame->GetUserUnits() );
65 }
66 else
67 {
68 m_unitBinder = nullptr;
69 }
70}
71
72
73wxPGWindowList PG_UNIT_EDITOR::CreateControls( wxPropertyGrid* aPropGrid, wxPGProperty* aProperty,
74 const wxPoint& aPos, const wxSize& aSize ) const
75{
76 wxASSERT( m_unitBinder );
77
78 wxString text = aProperty->GetValueAsString( wxPG_EDITABLE_VALUE );
79 wxWindow* win = aPropGrid->GenerateEditorTextCtrl( aPos, aSize, text, nullptr, 0,
80 aProperty->GetMaxLength() );
81 wxPGWindowList ret( win, nullptr );
82
83 m_unitBinder->SetControl( win );
84 m_unitBinder->RequireEval();
85 m_unitBinder->SetUnits( m_frame->GetUserUnits() );
86
87 if( PGPROPERTY_DISTANCE* prop = dynamic_cast<PGPROPERTY_DISTANCE*>( aProperty ) )
88 {
89 m_unitBinder->SetCoordType( prop->CoordType() );
90 }
91 else if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) != nullptr )
92 {
94 m_unitBinder->SetUnits( EDA_UNITS::DEGREES );
95 }
96
97 UpdateControl( aProperty, win );
98
99 return ret;
100}
101
102
103void PG_UNIT_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const
104{
105 wxVariant var = aProperty->GetValue();
106
107 if( var.GetType() == wxPG_VARIANT_TYPE_LONG )
108 {
109 m_unitBinder->ChangeValue( var.GetLong() );
110 }
111 else if( var.GetType() == wxPG_VARIANT_TYPE_DOUBLE )
112 {
113 m_unitBinder->ChangeValue( var.GetDouble() );
114 }
115 else if( var.GetType() == wxT( "EDA_ANGLE" ) )
116 {
117 EDA_ANGLE_VARIANT_DATA* angleData = static_cast<EDA_ANGLE_VARIANT_DATA*>( var.GetData() );
118 m_unitBinder->ChangeAngleValue( angleData->Angle() );
119 }
120 else if( !aProperty->IsValueUnspecified() )
121 {
122 wxFAIL_MSG( wxT( "PG_UNIT_EDITOR should only be used with numeric properties!" ) );
123 }
124}
125
126
127bool PG_UNIT_EDITOR::OnEvent( wxPropertyGrid* aPropGrid, wxPGProperty* aProperty,
128 wxWindow* aCtrl, wxEvent& aEvent ) const
129{
130 if( aEvent.GetEventType() == wxEVT_LEFT_UP )
131 {
132 if( wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl ) )
133 {
134 if( !textCtrl->HasFocus() )
135 {
136 textCtrl->SelectAll();
137 return false;
138 }
139 }
140 }
141
142 return wxPGTextCtrlEditor::OnEvent( aPropGrid, aProperty, aCtrl, aEvent );
143}
144
145
146bool PG_UNIT_EDITOR::GetValueFromControl( wxVariant& aVariant, wxPGProperty* aProperty,
147 wxWindow* aCtrl ) const
148{
149 if( !m_unitBinder )
150 return false;
151
152 wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>( aCtrl );
153 wxCHECK_MSG( textCtrl, false, "PG_UNIT_EDITOR requires a text control!" );
154 wxString textVal = textCtrl->GetValue();
155
156 if( aProperty->UsesAutoUnspecified() && textVal.empty() )
157 {
158 aVariant.MakeNull();
159 return true;
160 }
161 bool changed;
162
163 if( dynamic_cast<PGPROPERTY_ANGLE*>( aProperty ) != nullptr )
164 {
165 EDA_ANGLE angle = m_unitBinder->GetAngleValue();
166
167 if( aVariant.GetType() == wxT( "EDA_ANGLE" ) )
168 {
169 EDA_ANGLE_VARIANT_DATA* ad = static_cast<EDA_ANGLE_VARIANT_DATA*>( aVariant.GetData() );
170 changed = ( aVariant.IsNull() || angle != ad->Angle() );
171
172 if( changed )
173 {
174 ad->SetAngle( angle );
175 m_unitBinder->SetAngleValue( angle );
176 }
177 }
178 else
179 {
180 changed = ( aVariant.IsNull() || angle.AsDegrees() != aVariant.GetDouble() );
181
182 if( changed )
183 {
184 aVariant = angle.AsDegrees();
185 m_unitBinder->SetValue( angle.AsDegrees() );
186 }
187 }
188 }
189 else
190 {
191 long result = m_unitBinder->GetValue();
192 changed = ( aVariant.IsNull() || result != aVariant.GetLong() );
193
194 if( changed )
195 {
196 aVariant = result;
197 m_unitBinder->SetValue( result );
198 }
199 }
200
201 // Changing unspecified always causes event (returning
202 // true here should be enough to trigger it).
203 if( !changed && aVariant.IsNull() )
204 changed = true;
205
206 return changed;
207}
208
209
211 wxPGCheckBoxEditor()
212{
213}
214
215
216wxPGWindowList PG_CHECKBOX_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
217 const wxPoint& aPos, const wxSize& aSize ) const
218{
219 // Override wx behavior and toggle unspecified checkboxes to "true"
220 // CreateControls for a checkbox editor is only triggered when the user activates the checkbox
221 // Set the value to false here; the base class will then trigger an event setting it true.
222 if( aProperty->IsValueUnspecified() )
223 aProperty->SetValueFromInt( 0 );
224
225 return wxPGCheckBoxEditor::CreateControls( aGrid, aProperty, aPos, aSize );
226}
227
228
229bool PG_COLOR_EDITOR::OnEvent( wxPropertyGrid* aGrid, wxPGProperty* aProperty, wxWindow* aWindow,
230 wxEvent& aEvent ) const
231{
232 return false;
233}
234
235
236wxPGWindowList PG_COLOR_EDITOR::CreateControls( wxPropertyGrid* aGrid, wxPGProperty* aProperty,
237 const wxPoint& aPos, const wxSize& aSize ) const
238{
239 auto colorProp = dynamic_cast<PGPROPERTY_COLOR4D*>( aProperty );
240
241 if( !colorProp )
242 return nullptr;
243
245 KIGFX::COLOR4D defColor = colorFromVariant( colorProp->GetDefaultValue() );
246
247 COLOR_SWATCH* editor = new COLOR_SWATCH( aGrid->GetPanel(), color, wxID_ANY,
248 colorProp->GetBackgroundColor(), defColor,
249 SWATCH_LARGE, true );
250 editor->SetPosition( aPos );
251 editor->SetSize( aSize );
252
253 editor->Bind( COLOR_SWATCH_CHANGED,
254 [=]( wxCommandEvent& aEvt )
255 {
256 wxVariant val;
257 auto data = new COLOR4D_VARIANT_DATA( editor->GetSwatchColor() );
258 val.SetData( data );
259 aGrid->ChangePropertyValue( colorProp, val );
260 } );
261
262#if wxCHECK_VERSION( 3, 3, 0 )
263 if( aGrid->GetInternalFlags() & wxPropertyGrid::wxPG_FL_ACTIVATION_BY_CLICK )
264#else
265 if( aGrid->GetInternalFlags() & wxPG_FL_ACTIVATION_BY_CLICK )
266#endif
267 {
268 aGrid->CallAfter(
269 [=]()
270 {
271 editor->GetNewSwatchColor();
272 } );
273 }
274
275 return editor;
276}
277
278
279void PG_COLOR_EDITOR::UpdateControl( wxPGProperty* aProperty, wxWindow* aCtrl ) const
280{
281 if( auto swatch = dynamic_cast<COLOR_SWATCH*>( aCtrl ) )
282 swatch->SetSwatchColor( colorFromProperty( aProperty ), false );
283}
284
285
286KIGFX::COLOR4D PG_COLOR_EDITOR::colorFromVariant( const wxVariant& aVariant ) const
287{
289 COLOR4D_VARIANT_DATA* data = nullptr;
290
291 if( aVariant.IsType( wxS( "COLOR4D" ) ) )
292 {
293 data = static_cast<COLOR4D_VARIANT_DATA*>( aVariant.GetData() );
294 color = data->Color();
295 }
296
297 return color;
298}
299
300
302{
303 return colorFromVariant( aProperty->GetValue() );
304}
int color
Definition: DXF_plotter.cpp:58
const KIGFX::COLOR4D & Color()
A simple color swatch of the kind used to set layer colors.
Definition: color_swatch.h:57
const EDA_ANGLE & Angle()
void SetAngle(const EDA_ANGLE &aAngle)
double AsDegrees() const
Definition: eda_angle.h:149
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:382
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
Definition: pg_editors.cpp:216
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
Definition: pg_editors.cpp:236
bool OnEvent(wxPropertyGrid *aGrid, wxPGProperty *aProperty, wxWindow *aWindow, wxEvent &aEvent) const override
Definition: pg_editors.cpp:229
KIGFX::COLOR4D colorFromVariant(const wxVariant &aVariant) const
Definition: pg_editors.cpp:286
void UpdateControl(wxPGProperty *aProperty, wxWindow *aCtrl) const override
Definition: pg_editors.cpp:279
KIGFX::COLOR4D colorFromProperty(wxPGProperty *aProperty) const
Definition: pg_editors.cpp:301
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
Definition: pg_editors.cpp:73
static const wxString EDITOR_NAME
Definition: pg_editors.h:34
void UpdateControl(wxPGProperty *aProperty, wxWindow *aCtrl) const override
Definition: pg_editors.cpp:103
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...
Definition: pg_editors.cpp:57
EDA_DRAW_FRAME * m_frame
Definition: pg_editors.h:64
PG_UNIT_EDITOR(EDA_DRAW_FRAME *aFrame)
Definition: pg_editors.cpp:35
bool GetValueFromControl(wxVariant &aVariant, wxPGProperty *aProperty, wxWindow *aCtrl) const override
Definition: pg_editors.cpp:146
wxString m_editorName
Definition: pg_editors.h:68
bool OnEvent(wxPropertyGrid *aPropGrid, wxPGProperty *aProperty, wxWindow *aCtrl, wxEvent &aEvent) const override
Definition: pg_editors.cpp:127
static wxString BuildEditorName(EDA_DRAW_FRAME *aFrame)
Definition: pg_editors.cpp:51
virtual ~PG_UNIT_EDITOR()
Definition: pg_editors.cpp:46
EDA_UNITS GetUserUnits() const
@ SWATCH_LARGE
Definition: color_swatch.h:42