]>
Commit | Line | Data |
---|---|---|
1c4293cb VZ |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: propgrid.h | |
3 | // Purpose: topic overview | |
4 | // Author: wxWidgets team | |
de003797 | 5 | // RCS-ID: $Id$ |
526954c5 | 6 | // Licence: wxWindows licence |
1c4293cb VZ |
7 | ///////////////////////////////////////////////////////////////////////////// |
8 | ||
9 | /** | |
10 | ||
11 | @page overview_propgrid wxPropertyGrid Overview | |
12 | ||
13 | Key Classes: | |
14 | @li wxPGProperty | |
15 | @li wxPropertyGrid | |
16 | @li wxPropertyGridEvent | |
17 | @li wxPropertyGridManager | |
18 | @li wxPropertyGridPage | |
19 | ||
bba3f9b5 JS |
20 | wxPropertyGrid is a specialized grid for editing properties - in other |
21 | words name = value pairs. List of ready-to-use property classes include | |
22 | strings, numbers, flag sets, fonts, colours and many others. It is possible, | |
23 | for example, to categorize properties, set up a complete tree-hierarchy, | |
24 | add more than two columns, and set arbitrary per-property attributes. | |
1c4293cb | 25 | |
8622887c JS |
26 | As this version of wxPropertyGrid has some backward-incompatible changes |
27 | from version 1.4, everybody who need to maintain custom property classes | |
28 | should carefully read final section in @ref propgrid_compat. | |
29 | ||
216214f8 JS |
30 | @li @ref propgrid_basics |
31 | @li @ref propgrid_categories | |
32 | @li @ref propgrid_parentprops | |
33 | @li @ref propgrid_enumandflags | |
34 | @li @ref propgrid_advprops | |
bba3f9b5 | 35 | @li @ref propgrid_processingvalues |
216214f8 | 36 | @li @ref propgrid_iterating |
216214f8 | 37 | @li @ref propgrid_events |
534090e3 | 38 | @li @ref propgrid_tooltipandhint |
216214f8 JS |
39 | @li @ref propgrid_validating |
40 | @li @ref propgrid_populating | |
41 | @li @ref propgrid_cellrender | |
94f090f2 | 42 | @li @ref propgrid_keyhandling |
216214f8 JS |
43 | @li @ref propgrid_customizing |
44 | @li @ref propgrid_usage2 | |
45 | @li @ref propgrid_subclassing | |
46 | @li @ref propgrid_misc | |
47 | @li @ref propgrid_proplist | |
8622887c | 48 | @li @ref propgrid_compat |
216214f8 JS |
49 | |
50 | @section propgrid_basics Creating and Populating wxPropertyGrid | |
1c4293cb VZ |
51 | |
52 | As seen here, wxPropertyGrid is constructed in the same way as | |
53 | other wxWidgets controls: | |
54 | ||
55 | @code | |
56 | ||
57 | // Necessary header file | |
58 | #include <wx/propgrid/propgrid.h> | |
59 | ||
60 | ... | |
61 | ||
62 | // Assumes code is in frame/dialog constructor | |
63 | ||
64 | // Construct wxPropertyGrid control | |
65 | wxPropertyGrid* pg = new wxPropertyGrid( | |
66 | this, // parent | |
67 | PGID, // id | |
68 | wxDefaultPosition, // position | |
69 | wxDefaultSize, // size | |
70 | // Here are just some of the supported window styles | |
71 | wxPG_AUTO_SORT | // Automatic sorting after items added | |
72 | wxPG_SPLITTER_AUTO_CENTER | // Automatically center splitter until user manually adjusts it | |
73 | // Default style | |
74 | wxPG_DEFAULT_STYLE ); | |
75 | ||
76 | // Window style flags are at premium, so some less often needed ones are | |
77 | // available as extra window styles (wxPG_EX_xxx) which must be set using | |
78 | // SetExtraStyle member function. wxPG_EX_HELP_AS_TOOLTIPS, for instance, | |
bba3f9b5 | 79 | // allows displaying help strings as tool tips. |
1c4293cb VZ |
80 | pg->SetExtraStyle( wxPG_EX_HELP_AS_TOOLTIPS ); |
81 | ||
82 | @endcode | |
83 | ||
b55018ec | 84 | (for complete list of new window styles, see @ref propgrid_window_styles) |
1c4293cb VZ |
85 | |
86 | wxPropertyGrid is usually populated with lines like this: | |
87 | ||
88 | @code | |
d6ae8b5b | 89 | pg->Append( new wxStringProperty("Label", "Name", "Initial Value") ); |
1c4293cb VZ |
90 | @endcode |
91 | ||
92 | Naturally, wxStringProperty is a property class. Only the first function argument (label) | |
93 | is mandatory. Second one, name, defaults to label and, third, the initial value, to | |
94 | default value. If constant wxPG_LABEL is used as the name argument, then the label is | |
d665918b JS |
95 | automatically used as a name as well (this is more efficient than manually defining both |
96 | as the same). Use of empty name is discouraged and will sometimes result in run-time error. | |
97 | Note that all property class constructors have quite similar constructor argument list. | |
1c4293cb VZ |
98 | |
99 | To demonstrate other common property classes, here's another code snippet: | |
100 | ||
101 | @code | |
102 | ||
103 | // Add int property | |
d6ae8b5b | 104 | pg->Append( new wxIntProperty("IntProperty", wxPG_LABEL, 12345678) ); |
1c4293cb VZ |
105 | |
106 | // Add float property (value type is actually double) | |
d6ae8b5b | 107 | pg->Append( new wxFloatProperty("FloatProperty", wxPG_LABEL, 12345.678) ); |
1c4293cb VZ |
108 | |
109 | // Add a bool property | |
d6ae8b5b | 110 | pg->Append( new wxBoolProperty("BoolProperty", wxPG_LABEL, false) ); |
1c4293cb VZ |
111 | |
112 | // A string property that can be edited in a separate editor dialog. | |
d6ae8b5b | 113 | pg->Append( new wxLongStringProperty("LongStringProperty", |
1c4293cb | 114 | wxPG_LABEL, |
d6ae8b5b JS |
115 | "This is much longer string than the " |
116 | "first one. Edit it by clicking the button.")); | |
1c4293cb VZ |
117 | |
118 | // String editor with dir selector button. | |
d6ae8b5b | 119 | pg->Append( new wxDirProperty("DirProperty", wxPG_LABEL, ::wxGetUserHome()) ); |
1c4293cb VZ |
120 | |
121 | // wxArrayStringProperty embeds a wxArrayString. | |
d6ae8b5b JS |
122 | pg->Append( new wxArrayStringProperty("Label of ArrayStringProperty", |
123 | "NameOfArrayStringProp")); | |
1c4293cb VZ |
124 | |
125 | // A file selector property. | |
d6ae8b5b | 126 | pg->Append( new wxFileProperty("FileProperty", wxPG_LABEL, wxEmptyString) ); |
1c4293cb | 127 | |
bba3f9b5 | 128 | // Extra: set wild card for file property (format same as in wxFileDialog). |
d6ae8b5b | 129 | pg->SetPropertyAttribute( "FileProperty", |
1c4293cb | 130 | wxPG_FILE_WILDCARD, |
d6ae8b5b | 131 | "All files (*.*)|*.*" ); |
1c4293cb VZ |
132 | |
133 | @endcode | |
134 | ||
bba3f9b5 JS |
135 | Operations on properties are usually done by directly calling wxPGProperty's |
136 | or wxPropertyGridInterface's member functions. wxPropertyGridInterface is an | |
137 | abstract base class for property containers such as wxPropertyGrid, | |
138 | wxPropertyGridManager, and wxPropertyGridPage. Note however that wxPGProperty's | |
139 | member functions generally do not refresh the grid. | |
1c4293cb | 140 | |
bba3f9b5 JS |
141 | wxPropertyGridInterface's property operation member functions , such as |
142 | SetPropertyValue() and DisableProperty(), all accept a special wxPGPropArg id | |
143 | argument, using which you can refer to properties either by their pointer | |
144 | (for performance) or by their name (for convenience). For instance: | |
1c4293cb VZ |
145 | |
146 | @code | |
bba3f9b5 | 147 | // Add a file selector property. |
d6ae8b5b | 148 | wxPGPropety* prop = pg->Append( new wxFileProperty("FileProperty", |
bba3f9b5 JS |
149 | wxPG_LABEL, |
150 | wxEmptyString) ); | |
1c4293cb | 151 | |
bba3f9b5 | 152 | // Valid: Set wild card by name |
d6ae8b5b | 153 | pg->SetPropertyAttribute( "FileProperty", |
1c4293cb | 154 | wxPG_FILE_WILDCARD, |
d6ae8b5b | 155 | "All files (*.*)|*.*" ); |
1c4293cb | 156 | |
bba3f9b5 JS |
157 | // Also Valid: Set wild card by property pointer |
158 | pg->SetPropertyAttribute( prop, | |
1c4293cb | 159 | wxPG_FILE_WILDCARD, |
d6ae8b5b | 160 | "All files (*.*)|*.*" ); |
1c4293cb VZ |
161 | @endcode |
162 | ||
bba3f9b5 JS |
163 | Using pointer is faster, since it doesn't require hash map lookup. Anyway, |
164 | you can always get property pointer (wxPGProperty*) as return value from Append() | |
165 | or Insert(), or by calling wxPropertyGridInterface::GetPropertyByName() or | |
166 | just plain GetProperty(). | |
1c4293cb | 167 | |
216214f8 | 168 | @section propgrid_categories Categories |
1c4293cb | 169 | |
bba3f9b5 | 170 | wxPropertyGrid has a hierarchic property storage and display model, which |
1c4293cb VZ |
171 | allows property categories to hold child properties and even other |
172 | categories. Other than that, from the programmer's point of view, categories | |
173 | can be treated exactly the same as "other" properties. For example, despite | |
bba3f9b5 JS |
174 | its name, GetPropertyByName() also returns a category by name. Note however |
175 | that sometimes the label of a property category may be referred as caption | |
176 | (for example, there is wxPropertyGrid::SetCaptionTextColour() method | |
177 | that sets text colour of property category labels). | |
1c4293cb VZ |
178 | |
179 | When category is added at the top (i.e. root) level of the hierarchy, | |
180 | it becomes a *current category*. This means that all other (non-category) | |
bba3f9b5 JS |
181 | properties after it are automatically appended to it. You may add |
182 | properties to specific categories by using wxPropertyGridInterface::Insert | |
183 | or wxPropertyGridInterface::AppendIn. | |
1c4293cb VZ |
184 | |
185 | Category code sample: | |
186 | ||
187 | @code | |
188 | ||
189 | // One way to add category (similar to how other properties are added) | |
d6ae8b5b | 190 | pg->Append( new wxPropertyCategory("Main") ); |
1c4293cb VZ |
191 | |
192 | // All these are added to "Main" category | |
d6ae8b5b JS |
193 | pg->Append( new wxStringProperty("Name") ); |
194 | pg->Append( new wxIntProperty("Age",wxPG_LABEL,25) ); | |
195 | pg->Append( new wxIntProperty("Height",wxPG_LABEL,180) ); | |
196 | pg->Append( new wxIntProperty("Weight") ); | |
1c4293cb VZ |
197 | |
198 | // Another one | |
d6ae8b5b | 199 | pg->Append( new wxPropertyCategory("Attributes") ); |
1c4293cb VZ |
200 | |
201 | // All these are added to "Attributes" category | |
d6ae8b5b JS |
202 | pg->Append( new wxIntProperty("Intelligence") ); |
203 | pg->Append( new wxIntProperty("Agility") ); | |
204 | pg->Append( new wxIntProperty("Strength") ); | |
1c4293cb VZ |
205 | |
206 | @endcode | |
207 | ||
208 | ||
216214f8 | 209 | @section propgrid_parentprops Tree-like Property Structure |
1c4293cb | 210 | |
bba3f9b5 | 211 | Basically any property can have children. There are few limitations, however. |
1c4293cb VZ |
212 | |
213 | @remarks | |
bba3f9b5 JS |
214 | - Names of properties with non-category, non-root parents are not stored in global |
215 | hash map. Instead, they can be accessed with strings like "Parent.Child". | |
216 | For instance, in the sample below, child property named "Max. Speed (mph)" | |
217 | can be accessed by global name "Car.Speeds.Max Speed (mph)". | |
218 | - If you want to property's value to be a string composed of the child property values, | |
219 | you must use wxStringProperty as parent and use magic string "<composed>" as its | |
220 | value. | |
1c4293cb VZ |
221 | - Events (eg. change of value) that occur in parent do not propagate to children. Events |
222 | that occur in children will propagate to parents, but only if they are wxStringProperties | |
223 | with "<composed>" value. | |
1c4293cb VZ |
224 | |
225 | Sample: | |
226 | ||
227 | @code | |
d6ae8b5b | 228 | wxPGProperty* carProp = pg->Append(new wxStringProperty("Car", |
bba3f9b5 | 229 | wxPG_LABEL, |
d6ae8b5b | 230 | "<composed>")); |
bba3f9b5 | 231 | |
d6ae8b5b | 232 | pg->AppendIn(carProp, new wxStringProperty("Model", |
bba3f9b5 | 233 | wxPG_LABEL, |
d6ae8b5b | 234 | "Lamborghini Diablo SV")); |
1c4293cb | 235 | |
d6ae8b5b | 236 | pg->AppendIn(carProp, new wxIntProperty("Engine Size (cc)", |
1c4293cb | 237 | wxPG_LABEL, |
bba3f9b5 | 238 | 5707) ); |
1c4293cb | 239 | |
bba3f9b5 | 240 | wxPGProperty* speedsProp = pg->AppendIn(carProp, |
d6ae8b5b | 241 | new wxStringProperty("Speeds", |
bba3f9b5 | 242 | wxPG_LABEL, |
d6ae8b5b | 243 | "<composed>")); |
1c4293cb | 244 | |
d6ae8b5b | 245 | pg->AppendIn( speedsProp, new wxIntProperty("Max. Speed (mph)", |
bba3f9b5 | 246 | wxPG_LABEL,290) ); |
d6ae8b5b | 247 | pg->AppendIn( speedsProp, new wxFloatProperty("0-100 mph (sec)", |
bba3f9b5 | 248 | wxPG_LABEL,3.9) ); |
d6ae8b5b | 249 | pg->AppendIn( speedsProp, new wxFloatProperty("1/4 mile (sec)", |
bba3f9b5 | 250 | wxPG_LABEL,8.6) ); |
1c4293cb | 251 | |
bba3f9b5 | 252 | // This is how child property can be referred to by name |
d6ae8b5b | 253 | pg->SetPropertyValue( "Car.Speeds.Max. Speed (mph)", 300 ); |
1c4293cb | 254 | |
d6ae8b5b | 255 | pg->AppendIn(carProp, new wxIntProperty("Price ($)", |
bba3f9b5 JS |
256 | wxPG_LABEL, |
257 | 300000) ); | |
258 | ||
259 | // Displayed value of "Car" property is now very close to this: | |
260 | // "Lamborghini Diablo SV; 5707 [300; 3.9; 8.6] 300000" | |
1c4293cb VZ |
261 | |
262 | @endcode | |
263 | ||
216214f8 | 264 | @section propgrid_enumandflags wxEnumProperty and wxFlagsProperty |
1c4293cb VZ |
265 | |
266 | wxEnumProperty is used when you want property's (integer or string) value | |
267 | to be selected from a popup list of choices. | |
268 | ||
bba3f9b5 JS |
269 | Creating wxEnumProperty is slightly more complex than those described |
270 | earlier. You have to provide list of constant labels, and optionally relevant | |
271 | values (if label indexes are not sufficient). | |
1c4293cb VZ |
272 | |
273 | @remarks | |
274 | ||
939d9364 JS |
275 | - Value wxPG_INVALID_VALUE (equals INT_MAX) is not allowed as list |
276 | item value. | |
1c4293cb VZ |
277 | |
278 | A very simple example: | |
279 | ||
280 | @code | |
281 | ||
282 | // | |
283 | // Using wxArrayString | |
284 | // | |
285 | wxArrayString arrDiet; | |
d6ae8b5b JS |
286 | arr.Add("Herbivore"); |
287 | arr.Add("Carnivore"); | |
288 | arr.Add("Omnivore"); | |
1c4293cb | 289 | |
d6ae8b5b | 290 | pg->Append( new wxEnumProperty("Diet", |
1c4293cb VZ |
291 | wxPG_LABEL, |
292 | arrDiet) ); | |
293 | ||
1c4293cb VZ |
294 | // |
295 | // Using wxChar* array | |
296 | // | |
297 | const wxChar* arrayDiet[] = | |
298 | { wxT("Herbivore"), wxT("Carnivore"), wxT("Omnivore"), NULL }; | |
299 | ||
d6ae8b5b | 300 | pg->Append( new wxEnumProperty("Diet", |
1c4293cb VZ |
301 | wxPG_LABEL, |
302 | arrayDiet) ); | |
303 | ||
1c4293cb VZ |
304 | @endcode |
305 | ||
306 | Here's extended example using values as well: | |
307 | ||
308 | @code | |
309 | ||
310 | // | |
311 | // Using wxArrayString and wxArrayInt | |
312 | // | |
313 | wxArrayString arrDiet; | |
d6ae8b5b JS |
314 | arr.Add("Herbivore"); |
315 | arr.Add("Carnivore"); | |
316 | arr.Add("Omnivore"); | |
1c4293cb VZ |
317 | |
318 | wxArrayInt arrIds; | |
319 | arrIds.Add(40); | |
320 | arrIds.Add(45); | |
321 | arrIds.Add(50); | |
322 | ||
323 | // Note that the initial value (the last argument) is the actual value, | |
324 | // not index or anything like that. Thus, our value selects "Omnivore". | |
d6ae8b5b | 325 | pg->Append( new wxEnumProperty("Diet", |
1c4293cb VZ |
326 | wxPG_LABEL, |
327 | arrDiet, | |
328 | arrIds, | |
329 | 50)); | |
330 | ||
1c4293cb VZ |
331 | @endcode |
332 | ||
333 | wxPGChoices is a class where wxEnumProperty, and other properties which | |
bba3f9b5 JS |
334 | require storage for list of items, actually stores strings and values. It is |
335 | used to facilitate reference counting, and therefore recommended way of | |
1c4293cb VZ |
336 | adding items when multiple properties share the same set. |
337 | ||
338 | You can use wxPGChoices directly as well, filling it and then passing it | |
bba3f9b5 | 339 | to the constructor. In fact, if you wish to display bitmaps next to labels, |
1c4293cb VZ |
340 | your best choice is to use this approach. |
341 | ||
342 | @code | |
343 | ||
344 | wxPGChoices chs; | |
d6ae8b5b JS |
345 | chs.Add("Herbivore", 40); |
346 | chs.Add("Carnivore", 45); | |
347 | chs.Add("Omnivore", 50); | |
1c4293cb VZ |
348 | |
349 | // Let's add an item with bitmap, too | |
d6ae8b5b | 350 | chs.Add("None of the above", wxBitmap(), 60); |
1c4293cb | 351 | |
d6ae8b5b | 352 | pg->Append( new wxEnumProperty("Primary Diet", |
1c4293cb VZ |
353 | wxPG_LABEL, |
354 | chs) ); | |
355 | ||
356 | // Add same choices to another property as well - this is efficient due | |
357 | // to reference counting | |
d6ae8b5b | 358 | pg->Append( new wxEnumProperty("Secondary Diet", |
1c4293cb VZ |
359 | wxPG_LABEL, |
360 | chs) ); | |
1c4293cb VZ |
361 | @endcode |
362 | ||
d5774494 JS |
363 | You can later change choices of property by using wxPGProperty::AddChoice(), |
364 | wxPGProperty::InsertChoice(), wxPGProperty::DeleteChoice(), and | |
365 | wxPGProperty::SetChoices(). | |
1c4293cb | 366 | |
bba3f9b5 JS |
367 | <b>wxEditEnumProperty</b> works exactly like wxEnumProperty, except |
368 | is uses non-read-only combo box as default editor, and value is stored as | |
1c4293cb VZ |
369 | string when it is not any of the choices. |
370 | ||
939d9364 | 371 | wxFlagsProperty has similar construction: |
1c4293cb VZ |
372 | |
373 | @code | |
374 | ||
375 | const wxChar* flags_prop_labels[] = { wxT("wxICONIZE"), | |
376 | wxT("wxCAPTION"), wxT("wxMINIMIZE_BOX"), wxT("wxMAXIMIZE_BOX"), NULL }; | |
377 | ||
378 | // this value array would be optional if values matched string indexes | |
379 | long flags_prop_values[] = { wxICONIZE, wxCAPTION, wxMINIMIZE_BOX, | |
380 | wxMAXIMIZE_BOX }; | |
381 | ||
d6ae8b5b | 382 | pg->Append( new wxFlagsProperty("Window Style", |
1c4293cb VZ |
383 | wxPG_LABEL, |
384 | flags_prop_labels, | |
385 | flags_prop_values, | |
386 | wxDEFAULT_FRAME_STYLE) ); | |
387 | ||
388 | @endcode | |
389 | ||
390 | wxFlagsProperty can use wxPGChoices just the same way as wxEnumProperty | |
bba3f9b5 | 391 | <b>Note:</b> When changing "choices" (ie. flag labels) of wxFlagsProperty, |
939d9364 | 392 | you will need to use wxPGProperty::SetChoices() to replace all choices |
bba3f9b5 | 393 | at once - otherwise implicit child properties will not get updated properly. |
1c4293cb | 394 | |
216214f8 | 395 | @section propgrid_advprops Specialized Properties |
1c4293cb VZ |
396 | |
397 | This section describes the use of less often needed property classes. | |
398 | To use them, you have to include <wx/propgrid/advprops.h>. | |
399 | ||
400 | @code | |
401 | ||
402 | // Necessary extra header file | |
403 | #include <wx/propgrid/advprops.h> | |
404 | ||
405 | ... | |
406 | ||
407 | // Date property. | |
d6ae8b5b | 408 | pg->Append( new wxDateProperty("MyDateProperty", |
1c4293cb VZ |
409 | wxPG_LABEL, |
410 | wxDateTime::Now()) ); | |
411 | ||
bba3f9b5 | 412 | // Image file property. Wild card is auto-generated from available |
1c4293cb | 413 | // image handlers, so it is not set this time. |
d6ae8b5b JS |
414 | pg->Append( new wxImageFileProperty("Label of ImageFileProperty", |
415 | "NameOfImageFileProp") ); | |
1c4293cb VZ |
416 | |
417 | // Font property has sub-properties. Note that we give window's font as | |
418 | // initial value. | |
d6ae8b5b | 419 | pg->Append( new wxFontProperty("Font", |
1c4293cb VZ |
420 | wxPG_LABEL, |
421 | GetFont()) ); | |
422 | ||
423 | // Colour property with arbitrary colour. | |
d6ae8b5b | 424 | pg->Append( new wxColourProperty("My Colour 1", |
1c4293cb VZ |
425 | wxPG_LABEL, |
426 | wxColour(242,109,0) ) ); | |
427 | ||
428 | // System colour property. | |
d6ae8b5b | 429 | pg->Append( new wxSystemColourProperty("My SysColour 1", |
1c4293cb VZ |
430 | wxPG_LABEL, |
431 | wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)) ); | |
432 | ||
433 | // System colour property with custom colour. | |
d6ae8b5b | 434 | pg->Append( new wxSystemColourProperty("My SysColour 2", |
1c4293cb VZ |
435 | wxPG_LABEL, |
436 | wxColour(0,200,160) ) ); | |
437 | ||
438 | // Cursor property | |
d6ae8b5b | 439 | pg->Append( new wxCursorProperty("My Cursor", |
1c4293cb VZ |
440 | wxPG_LABEL, |
441 | wxCURSOR_ARROW)); | |
442 | ||
443 | @endcode | |
444 | ||
445 | ||
bba3f9b5 JS |
446 | @section propgrid_processingvalues Processing Property Values |
447 | ||
4e0bdd56 JS |
448 | Properties store their values internally as wxVariant, but is also possible to |
449 | obtain them as wxAny, using implicit conversion. You can get property | |
450 | values with wxPGProperty::GetValue() and | |
451 | wxPropertyGridInterface::GetPropertyValue(). | |
452 | ||
453 | Below is a code example which handles wxEVT_PG_CHANGED event: | |
454 | ||
455 | @code | |
456 | ||
457 | void MyWindowClass::OnPropertyGridChanged(wxPropertyGridEvent& event) | |
458 | { | |
459 | wxPGProperty* property = event.GetProperty(); | |
460 | ||
461 | // Do nothing if event did not have associated property | |
462 | if ( !property ) | |
463 | return; | |
464 | ||
465 | // GetValue() returns wxVariant, but it is converted transparently to | |
466 | // wxAny | |
467 | wxAny value = property->GetValue(); | |
468 | ||
469 | // Also, handle the case where property value is unspecified | |
470 | if ( value.IsNull() ) | |
471 | return; | |
472 | ||
473 | // Handle changes in values, as needed | |
474 | if ( property.GetName() == "MyStringProperty" ) | |
475 | OnMyStringPropertyChanged(value.As<wxString>()); | |
476 | else if ( property.GetName() == "MyColourProperty" ) | |
477 | OnMyColourPropertyChanged(value.As<wxColour>()); | |
478 | } | |
479 | ||
480 | @endcode | |
481 | ||
482 | You can get a string-representation of property's value using | |
483 | wxPGProperty::GetValueAsString() or | |
484 | wxPropertyGridInterface::GetPropertyValueAsString(). This particular function | |
485 | is very safe to use with any kind of property. | |
486 | ||
487 | @note There is a one case in which you may want to take extra care when | |
488 | dealing with raw wxVariant values. That is, integer-type properties, | |
489 | such as wxIntProperty and wxUIntProperty, store value internally as | |
490 | wx(U)LongLong when number doesn't fit into standard long type. Using | |
491 | << operator to get wx(U)LongLong from wxVariant is customized to work | |
492 | quite safely with various types of variant data. However, you can also | |
493 | bypass this problem by using wxAny in your code instead of wxVariant. | |
bba3f9b5 JS |
494 | |
495 | Note that in some cases property value can be Null variant, which means | |
496 | that property value is unspecified. This usually occurs only when | |
497 | wxPG_EX_AUTO_UNSPECIFIED_VALUES extra window style is defined or when you | |
498 | manually set property value to Null (or unspecified). | |
499 | ||
500 | ||
216214f8 | 501 | @section propgrid_iterating Iterating through a property container |
1c4293cb VZ |
502 | |
503 | You can use somewhat STL'ish iterator classes to iterate through the grid. | |
504 | Here is a simple example of forward iterating through all individual | |
bba3f9b5 JS |
505 | properties (not categories nor private child properties that are normally |
506 | 'transparent' to application code): | |
1c4293cb VZ |
507 | |
508 | @code | |
509 | ||
510 | wxPropertyGridIterator it; | |
511 | ||
512 | for ( it = pg->GetIterator(); | |
513 | !it.AtEnd(); | |
514 | it++ ) | |
515 | { | |
516 | wxPGProperty* p = *it; | |
517 | // Do something with the property | |
518 | } | |
519 | ||
520 | @endcode | |
521 | ||
522 | As expected there is also a const iterator: | |
523 | ||
524 | @code | |
525 | ||
526 | wxPropertyGridConstIterator it; | |
527 | ||
528 | for ( it = pg->GetIterator(); | |
529 | !it.AtEnd(); | |
530 | it++ ) | |
531 | { | |
532 | const wxPGProperty* p = *it; | |
533 | // Do something with the property | |
534 | } | |
535 | ||
536 | @endcode | |
537 | ||
538 | You can give some arguments to GetIterator to determine which properties | |
539 | get automatically filtered out. For complete list of options, see | |
b55018ec JS |
540 | @ref propgrid_iterator_flags. GetIterator() also accepts other arguments. |
541 | See wxPropertyGridInterface::GetIterator() for details. | |
1c4293cb VZ |
542 | |
543 | This example reverse-iterates through all visible items: | |
544 | ||
545 | @code | |
546 | ||
547 | wxPropertyGridIterator it; | |
548 | ||
549 | for ( it = pg->GetIterator(wxPG_ITERATE_VISIBLE, wxBOTTOM); | |
550 | !it.AtEnd(); | |
551 | it-- ) | |
552 | { | |
553 | wxPGProperty* p = *it; | |
554 | // Do something with the property | |
555 | } | |
556 | ||
557 | @endcode | |
558 | ||
863d1ce7 JS |
559 | @beginWxPythonOnly |
560 | PropertyGridInterface has some useful pythonic iterators as attributes. | |
561 | @c Properties lets you iterate through all items that are not category | |
562 | captions or private children. @c Items lets you iterate through everything | |
563 | except private children. Also, there are GetPyIterator() and GetPyVIterator(), | |
564 | which return pythonic iterators instead of normal wxPropertyGridIterator. | |
565 | ||
566 | If you need to use C++ style iterators in wxPython code, note that | |
567 | Instead of ++ operator, use Next() method, and instead of | |
1c4293cb | 568 | * operator, use GetProperty() method. |
863d1ce7 | 569 | @endWxPythonOnly |
1c4293cb VZ |
570 | |
571 | GetIterator() only works with wxPropertyGrid and the individual pages | |
572 | of wxPropertyGridManager. In order to iterate through an arbitrary | |
bba3f9b5 JS |
573 | property container (such as entire wxPropertyGridManager), you need to use |
574 | wxPropertyGridInterface::GetVIterator(). Note however that this virtual | |
575 | iterator is limited to forward iteration. | |
1c4293cb VZ |
576 | |
577 | @code | |
578 | ||
579 | wxPGVIterator it; | |
580 | ||
581 | for ( it = manager->GetVIterator(); | |
582 | !it.AtEnd(); | |
583 | it.Next() ) | |
584 | { | |
585 | wxPGProperty* p = it.GetProperty(); | |
586 | // Do something with the property | |
587 | } | |
588 | ||
589 | @endcode | |
590 | ||
216214f8 | 591 | @section propgrid_populating Populating wxPropertyGrid Automatically |
1c4293cb | 592 | |
216214f8 | 593 | @subsection propgrid_fromvariants Populating from List of wxVariants |
1c4293cb VZ |
594 | |
595 | Example of populating an empty wxPropertyGrid from a values stored | |
596 | in an arbitrary list of wxVariants. | |
597 | ||
598 | @code | |
599 | ||
bba3f9b5 | 600 | // This is a static method that initializes *all* built-in type handlers |
1c4293cb VZ |
601 | // available, including those for wxColour and wxFont. Refers to *all* |
602 | // included properties, so when compiling with static library, this | |
bba3f9b5 | 603 | // method may increase the executable size noticeably. |
1c4293cb VZ |
604 | pg->InitAllTypeHandlers(); |
605 | ||
606 | // Get contents of the grid as a wxVariant list | |
607 | wxVariant all_values = pg->GetPropertyValues(); | |
608 | ||
609 | // Populate the list with values. If a property with appropriate | |
610 | // name is not found, it is created according to the type of variant. | |
611 | pg->SetPropertyValues( my_list_variant ); | |
612 | ||
1c4293cb VZ |
613 | @endcode |
614 | ||
216214f8 | 615 | @subsection propgrid_fromfile Loading Population from a Text-based Storage |
1c4293cb VZ |
616 | |
617 | Class wxPropertyGridPopulator may be helpful when writing code that | |
bba3f9b5 JS |
618 | loads properties from a text-source. In fact, the wxPropertyGrid xrc-handler |
619 | (which may not be currently included in wxWidgets, but probably will be in | |
620 | near future) uses it. | |
1c4293cb | 621 | |
bba3f9b5 | 622 | @subsection editablestate Saving and Restoring User-Editable State |
1c4293cb | 623 | |
bba3f9b5 JS |
624 | You can use wxPropertyGridInterface::SaveEditableState() and |
625 | wxPropertyGridInterface::RestoreEditableState() to save and restore | |
626 | user-editable state (selected property, expanded/collapsed properties, | |
627 | selected page, scrolled position, and splitter positions). | |
1c4293cb | 628 | |
216214f8 | 629 | @section propgrid_events Event Handling |
1c4293cb VZ |
630 | |
631 | Probably the most important event is the Changed event which occurs when | |
632 | value of any property is changed by the user. Use EVT_PG_CHANGED(id,func) | |
633 | in your event table to use it. | |
634 | ||
635 | For complete list of event types, see wxPropertyGrid class reference. | |
636 | ||
bba3f9b5 JS |
637 | However, one type of event that might need focused attention is EVT_PG_CHANGING, |
638 | which occurs just prior property value is being changed by user. You can | |
639 | acquire pending value using wxPropertyGridEvent::GetValue(), and if it is | |
640 | not acceptable, call wxPropertyGridEvent::Veto() to prevent the value change | |
641 | from taking place. | |
1c4293cb VZ |
642 | |
643 | @code | |
644 | ||
1c4293cb VZ |
645 | void MyForm::OnPropertyGridChanging( wxPropertyGridEvent& event ) |
646 | { | |
647 | wxPGProperty* property = event.GetProperty(); | |
648 | ||
649 | if ( property == m_pWatchThisProperty ) | |
650 | { | |
651 | // GetValue() returns the pending value, but is only | |
652 | // supported by wxEVT_PG_CHANGING. | |
653 | if ( event.GetValue().GetString() == g_pThisTextIsNotAllowed ) | |
654 | { | |
655 | event.Veto(); | |
656 | return; | |
657 | } | |
658 | } | |
659 | } | |
660 | ||
661 | @endcode | |
662 | ||
bba3f9b5 JS |
663 | @remarks On Child Property Event Handling |
664 | - For properties which have private, implicit children (wxFontProperty and | |
665 | wxFlagsProperty), events occur for the main parent property only. | |
666 | For other properties events occur for the children themselves. See | |
667 | @ref propgrid_parentprops. | |
1c4293cb | 668 | |
bba3f9b5 | 669 | - When property's child gets changed, you can use wxPropertyGridEvent::GetMainParent() |
1c4293cb VZ |
670 | to obtain its topmost non-category parent (useful, if you have deeply nested |
671 | properties). | |
672 | ||
534090e3 JS |
673 | @section propgrid_tooltipandhint Help String, Hint and Tool Tips |
674 | ||
675 | For each property you can specify two different types of help text. First, | |
676 | you can use wxPropertyGridInterface::SetPropertyHelpString() or | |
677 | wxPGProperty::SetHelpString() to set property's help text. Second, you | |
678 | can use wxPGProperty::SetAttribute() to set property's "Hint" attribute. | |
679 | ||
680 | Difference between hint and help string is that the hint is shown in an empty | |
681 | property value cell, while help string is shown either in the description text | |
682 | box, as a tool tip, or on the status bar, whichever of these is available. | |
683 | ||
684 | To enable display of help string as tool tips, you must explicitly use | |
685 | the wxPG_EX_HELP_AS_TOOLTIPS extra window style. | |
1c4293cb | 686 | |
216214f8 | 687 | @section propgrid_validating Validating Property Values |
1c4293cb VZ |
688 | |
689 | There are various ways to make sure user enters only correct values. First, you | |
690 | can use wxValidators similar to as you would with ordinary controls. Use | |
8622887c | 691 | wxPropertyGridInterface::SetPropertyValidator() to assign wxValidator to |
1c4293cb VZ |
692 | property. |
693 | ||
694 | Second, you can subclass a property and override wxPGProperty::ValidateValue(), | |
bba3f9b5 | 695 | or handle wxEVT_PG_CHANGING for the same effect. Both of these ways do not |
1c4293cb VZ |
696 | actually prevent user from temporarily entering invalid text, but they do give |
697 | you an opportunity to warn the user and block changed value from being committed | |
698 | in a property. | |
699 | ||
700 | Various validation failure options can be controlled globally with | |
701 | wxPropertyGrid::SetValidationFailureBehavior(), or on an event basis by | |
702 | calling wxEvent::SetValidationFailureBehavior(). Here's a code snippet of | |
703 | how to handle wxEVT_PG_CHANGING, and to set custom failure behaviour and | |
704 | message. | |
705 | ||
706 | @code | |
707 | void MyFrame::OnPropertyGridChanging(wxPropertyGridEvent& event) | |
708 | { | |
709 | wxPGProperty* property = event.GetProperty(); | |
710 | ||
711 | // You must use wxPropertyGridEvent::GetValue() to access | |
712 | // the value to be validated. | |
713 | wxVariant pendingValue = event.GetValue(); | |
714 | ||
d6ae8b5b | 715 | if ( property->GetName() == "Font" ) |
1c4293cb VZ |
716 | { |
717 | // Make sure value is not unspecified | |
718 | if ( !pendingValue.IsNull() ) | |
719 | { | |
bba3f9b5 JS |
720 | wxFont font; |
721 | font << pendingValue; | |
1c4293cb VZ |
722 | |
723 | // Let's just allow Arial font | |
d6ae8b5b | 724 | if ( font.GetFaceName() != "Arial" ) |
1c4293cb VZ |
725 | { |
726 | event.Veto(); | |
727 | event.SetValidationFailureBehavior(wxPG_VFB_STAY_IN_PROPERTY | | |
728 | wxPG_VFB_BEEP | | |
4fb5dadb | 729 | wxPG_VFB_SHOW_MESSAGEBOX); |
1c4293cb VZ |
730 | } |
731 | } | |
732 | } | |
733 | } | |
734 | @endcode | |
735 | ||
736 | ||
216214f8 | 737 | @section propgrid_cellrender Customizing Individual Cell Appearance |
1c4293cb VZ |
738 | |
739 | You can control text colour, background colour, and attached image of | |
740 | each cell in the property grid. Use wxPropertyGridInterface::SetPropertyCell() or | |
741 | wxPGProperty::SetCell() for this purpose. | |
742 | ||
743 | In addition, it is possible to control these characteristics for | |
bba3f9b5 | 744 | wxPGChoices list items. See wxPGChoices class reference for more info. |
1c4293cb | 745 | |
94f090f2 JS |
746 | @section propgrid_keyhandling Customizing Keyboard Handling |
747 | ||
748 | There is probably one preference for keyboard handling for every developer | |
749 | out there, and as a conveniency control wxPropertyGrid tries to cater for | |
750 | that. By the default arrow keys are used for navigating between properties, | |
751 | and TAB key is used to move focus between the property editor and the | |
752 | first column. When the focus is in the editor, arrow keys usually no longer | |
753 | work for navigation since they are consumed by the editor. | |
754 | ||
755 | There are mainly two functions which you can use this customize things, | |
756 | wxPropertyGrid::AddActionTrigger() and wxPropertyGrid::DedicateKey(). | |
757 | First one can be used to set a navigation event to occur on a specific key | |
758 | press and the second is used to divert a key from property editors, making it | |
759 | possible for the grid to use keys normally consumed by the focused editors. | |
760 | ||
761 | For example, let's say you want to have an ENTER-based editing scheme. That | |
762 | is, editor is focused on ENTER press and the next property is selected when | |
763 | the user finishes editing and presses ENTER again. Code like this would | |
764 | accomplish the task: | |
765 | ||
766 | @code | |
767 | // Have property editor focus on Enter | |
768 | propgrid->AddActionTrigger( wxPG_ACTION_EDIT, WXK_RETURN ); | |
769 | ||
770 | // Have Enter work as action trigger even when editor is focused | |
771 | propgrid->DedicateKey( WXK_RETURN ); | |
772 | ||
773 | // Let Enter also navigate to the next property | |
774 | propgrid->AddActionTrigger( wxPG_ACTION_NEXT_PROPERTY, WXK_RETURN ); | |
775 | ||
776 | @endcode | |
777 | ||
778 | wxPG_ACTION_EDIT is prioritized above wxPG_ACTION_NEXT_PROPERTY so that the | |
779 | above code can work without conflicts. For a complete list of available | |
780 | actions, see @ref propgrid_keyboard_actions. | |
781 | ||
782 | Here's another trick. Normally the up and down cursor keys are consumed by | |
783 | the focused wxTextCtrl editor and as such can't be used for navigating between | |
784 | properties when that editor is focused. However, using DedicateKey() we can | |
785 | change this so that instead of the cursor keys moving the caret inside the | |
786 | wxTextCtrl, they navigate between adjacent properties. As such: | |
787 | ||
788 | @code | |
789 | propgrid->DedicateKey(WXK_UP); | |
790 | propgrid->DedicateKey(WXK_DOWN); | |
791 | @endcode | |
792 | ||
1c4293cb | 793 | |
216214f8 | 794 | @section propgrid_customizing Customizing Properties (without sub-classing) |
1c4293cb VZ |
795 | |
796 | In this section are presented miscellaneous ways to have custom appearance | |
4c51a665 | 797 | and behaviour for your properties without all the necessary hassle |
1c4293cb VZ |
798 | of sub-classing a property class etc. |
799 | ||
216214f8 | 800 | @subsection propgrid_customimage Setting Value Image |
1c4293cb VZ |
801 | |
802 | Every property can have a small value image placed in front of the | |
803 | actual value text. Built-in example of this can be seen with | |
804 | wxColourProperty and wxImageFileProperty, but for others it can | |
805 | be set using wxPropertyGrid::SetPropertyImage method. | |
806 | ||
216214f8 | 807 | @subsection propgrid_customeditor Setting Property's Editor Control(s) |
1c4293cb VZ |
808 | |
809 | You can set editor control (or controls, in case of a control and button), | |
810 | of any property using wxPropertyGrid::SetPropertyEditor. Editors are passed | |
bba3f9b5 | 811 | as wxPGEditor_EditorName, and valid built-in EditorNames are |
1c4293cb VZ |
812 | TextCtrl, Choice, ComboBox, CheckBox, TextCtrlAndButton, ChoiceAndButton, |
813 | SpinCtrl, and DatePickerCtrl. Two last mentioned ones require call to | |
814 | static member function wxPropertyGrid::RegisterAdditionalEditors(). | |
815 | ||
816 | Following example changes wxColourProperty's editor from default Choice | |
817 | to TextCtrlAndButton. wxColourProperty has its internal event handling set | |
818 | up so that button click events of the button will be used to trigger | |
819 | colour selection dialog. | |
820 | ||
821 | @code | |
822 | ||
d6ae8b5b | 823 | wxPGProperty* colProp = new wxColourProperty("Text Colour"); |
bba3f9b5 JS |
824 | pg->Append(colProp); |
825 | pg->SetPropertyEditor(colProp, wxPGEditor_TextCtrlAndButton); | |
1c4293cb VZ |
826 | |
827 | @endcode | |
828 | ||
829 | Naturally, creating and setting custom editor classes is a possibility as | |
830 | well. For more information, see wxPGEditor class reference. | |
831 | ||
216214f8 | 832 | @subsection propgrid_editorattrs Property Attributes Recognized by Editors |
1c4293cb | 833 | |
bba3f9b5 JS |
834 | <b>SpinCtrl</b> editor can make use of property's "Min", "Max", "Step" and |
835 | "Wrap" attributes. | |
1c4293cb | 836 | |
216214f8 | 837 | @subsection propgrid_multiplebuttons Adding Multiple Buttons Next to an Editor |
1c4293cb VZ |
838 | |
839 | See wxPGMultiButton class reference. | |
840 | ||
216214f8 | 841 | @subsection propgrid_customeventhandling Handling Events Passed from Properties |
1c4293cb VZ |
842 | |
843 | <b>wxEVT_COMMAND_BUTTON_CLICKED </b>(corresponds to event table macro EVT_BUTTON): | |
844 | Occurs when editor button click is not handled by the property itself | |
845 | (as is the case, for example, if you set property's editor to TextCtrlAndButton | |
846 | from the original TextCtrl). | |
847 | ||
216214f8 | 848 | @subsection propgrid_attributes Property Attributes |
1c4293cb VZ |
849 | |
850 | Miscellaneous values, often specific to a property type, can be set | |
bba3f9b5 JS |
851 | using wxPropertyGridInterface::SetPropertyAttribute() and |
852 | wxPropertyGridInterface::SetPropertyAttributeAll() methods. | |
1c4293cb VZ |
853 | |
854 | Attribute names are strings and values wxVariant. Arbitrary names are allowed | |
bba3f9b5 JS |
855 | in order to store values that are relevant to application only and not |
856 | property grid. Constant equivalents of all attribute string names are | |
857 | provided. Some of them are defined as cached strings, so using these constants | |
858 | can provide for smaller binary size. | |
1c4293cb | 859 | |
b55018ec | 860 | For complete list of attributes, see @ref propgrid_property_attributes. |
1c4293cb | 861 | |
1c4293cb | 862 | |
216214f8 | 863 | @section propgrid_usage2 Using wxPropertyGridManager |
1c4293cb VZ |
864 | |
865 | wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid, | |
bba3f9b5 JS |
866 | which can optionally have tool bar for mode and page selection, and a help text |
867 | box. For more information, see wxPropertyGridManager class reference. | |
1c4293cb | 868 | |
216214f8 | 869 | @subsection propgrid_propgridpage wxPropertyGridPage |
1c4293cb VZ |
870 | |
871 | wxPropertyGridPage is holder of properties for one page in manager. It is derived from | |
872 | wxEvtHandler, so you can subclass it to process page-specific property grid events. Hand | |
bba3f9b5 | 873 | over your page instance in wxPropertyGridManager::AddPage(). |
1c4293cb VZ |
874 | |
875 | Please note that the wxPropertyGridPage itself only sports subset of wxPropertyGrid API | |
876 | (but unlike manager, this include item iteration). Naturally it inherits from | |
bba3f9b5 | 877 | wxPropertyGridInterface. |
1c4293cb | 878 | |
bba3f9b5 | 879 | For more information, see wxPropertyGridPage class reference. |
1c4293cb | 880 | |
bba3f9b5 JS |
881 | |
882 | @section propgrid_subclassing Sub-classing wxPropertyGrid and wxPropertyGridManager | |
1c4293cb VZ |
883 | |
884 | Few things to note: | |
885 | ||
886 | - Only a small percentage of member functions are virtual. If you need more, | |
887 | just e-mail to wx-dev mailing list. | |
888 | ||
889 | - Data manipulation is done in wxPropertyGridPageState class. So, instead of | |
bba3f9b5 JS |
890 | overriding wxPropertyGrid::Insert(), you'll probably want to override |
891 | wxPropertyGridPageState::DoInsert(). See header file for details. | |
1c4293cb | 892 | |
bba3f9b5 JS |
893 | - Override wxPropertyGrid::CreateState() to instantiate your derivate |
894 | wxPropertyGridPageState. For wxPropertyGridManager, you'll need to subclass | |
895 | wxPropertyGridPage instead (since it is derived from wxPropertyGridPageState), | |
896 | and hand over instances in wxPropertyGridManager::AddPage() calls. | |
1c4293cb | 897 | |
bba3f9b5 JS |
898 | - You can use a derivate wxPropertyGrid with manager by overriding |
899 | wxPropertyGridManager::CreatePropertyGrid() member function. | |
1c4293cb VZ |
900 | |
901 | ||
216214f8 | 902 | @section propgrid_misc Miscellaneous Topics |
1c4293cb | 903 | |
216214f8 | 904 | @subsection propgrid_namescope Property Name Scope |
1c4293cb | 905 | |
258ccb95 JS |
906 | All properties which parent is category or root can be accessed |
907 | directly by their base name (ie. name given for property in its constructor). | |
908 | Other properties can be accessed via "ParentsName.BaseName" notation, | |
909 | Naturally, all property names should be unique. | |
1c4293cb | 910 | |
216214f8 | 911 | @subsection propgrid_nonuniquelabels Non-unique Labels |
258ccb95 JS |
912 | |
913 | It is possible to have properties with identical label under same parent. | |
914 | However, care must be taken to ensure that each property still has | |
915 | unique (base) name. | |
1c4293cb | 916 | |
216214f8 | 917 | @subsection propgrid_boolproperty wxBoolProperty |
1c4293cb | 918 | |
bba3f9b5 JS |
919 | There are few points about wxBoolProperty that require further discussion: |
920 | - wxBoolProperty can be shown as either normal combo box or as a check box. | |
1c4293cb VZ |
921 | Property attribute wxPG_BOOL_USE_CHECKBOX is used to change this. |
922 | For example, if you have a wxFlagsProperty, you can | |
923 | set its all items to use check box using the following: | |
924 | @code | |
d6ae8b5b | 925 | pg->SetPropertyAttribute("MyFlagsProperty", wxPG_BOOL_USE_CHECKBOX, true, wxPG_RECURSE); |
1c4293cb | 926 | @endcode |
8622887c | 927 | |
bba3f9b5 JS |
928 | Following will set all individual bool properties in your control to |
929 | use check box: | |
8622887c | 930 | |
bba3f9b5 JS |
931 | @code |
932 | pg->SetPropertyAttributeAll(wxPG_BOOL_USE_CHECKBOX, true); | |
933 | @endcode | |
1c4293cb | 934 | |
939d9364 | 935 | - Default item names for wxBoolProperty are ["False", "True"]. This can be |
bba3f9b5 JS |
936 | changed using static function wxPropertyGrid::SetBoolChoices(trueChoice, |
937 | falseChoice). | |
1c4293cb | 938 | |
216214f8 | 939 | @subsection propgrid_textctrlupdates Updates from wxTextCtrl Based Editor |
1c4293cb VZ |
940 | |
941 | Changes from wxTextCtrl based property editors are committed (ie. | |
942 | wxEVT_PG_CHANGED is sent etc.) *only* when (1) user presser enter, (2) | |
943 | user moves to edit another property, or (3) when focus leaves | |
944 | the grid. | |
945 | ||
946 | Because of this, you may find it useful, in some apps, to call | |
947 | wxPropertyGrid::CommitChangesFromEditor() just before you need to do any | |
948 | computations based on property grid values. Note that CommitChangesFromEditor() | |
949 | will dispatch wxEVT_PG_CHANGED with ProcessEvent, so any of your event handlers | |
950 | will be called immediately. | |
951 | ||
216214f8 | 952 | @subsection propgrid_splittercentering Centering the Splitter |
1c4293cb VZ |
953 | |
954 | If you need to center the splitter, but only once when the program starts, | |
955 | then do <b>not</b> use the wxPG_SPLITTER_AUTO_CENTER window style, but the | |
956 | wxPropertyGrid::CenterSplitter() method. <b>However, be sure to call it after | |
957 | the sizer setup and SetSize calls!</b> (ie. usually at the end of the | |
958 | frame/dialog constructor) | |
959 | ||
4c51a665 | 960 | Splitter centering behaviour can be customized using |
fe01f16e JS |
961 | wxPropertyGridInterface::SetColumnProportion(). Usually it is used to set |
962 | non-equal column proportions, which in essence stops the splitter(s) from | |
963 | being 'centered' as such, and instead just auto-resized. | |
964 | ||
216214f8 | 965 | @subsection propgrid_splittersetting Setting Splitter Position When Creating Property Grid |
1c4293cb VZ |
966 | |
967 | Splitter position cannot exceed grid size, and therefore setting it during | |
968 | form creation may fail as initial grid size is often smaller than desired | |
969 | splitter position, especially when sizers are being used. | |
970 | ||
216214f8 | 971 | @subsection propgrid_colourproperty wxColourProperty and wxSystemColourProperty |
1c4293cb | 972 | |
bba3f9b5 | 973 | Through sub-classing, these two property classes provide substantial customization |
1c4293cb VZ |
974 | features. Subclass wxSystemColourProperty if you want to use wxColourPropertyValue |
975 | (which features colour type in addition to wxColour), and wxColourProperty if plain | |
976 | wxColour is enough. | |
977 | ||
978 | Override wxSystemColourProperty::ColourToString() to redefine how colours are | |
979 | printed as strings. | |
980 | ||
981 | Override wxSystemColourProperty::GetCustomColourIndex() to redefine location of | |
982 | the item that triggers colour picker dialog (default is last). | |
983 | ||
984 | Override wxSystemColourProperty::GetColour() to determine which colour matches | |
985 | which choice entry. | |
986 | ||
216214f8 | 987 | @section propgrid_proplist Property Class Descriptions |
1c4293cb VZ |
988 | |
989 | See @ref pgproperty_properties | |
990 | ||
8622887c JS |
991 | @section propgrid_compat Changes from wxPropertyGrid 1.4 |
992 | ||
993 | Version of wxPropertyGrid bundled with wxWidgets 2.9+ has various backward- | |
994 | incompatible changes from version 1.4, which had a stable API and will remain | |
995 | as the last separate branch. | |
996 | ||
4c51a665 | 997 | Note that in general any behaviour-breaking changes should not compile or run |
8622887c JS |
998 | without warnings or errors. |
999 | ||
1000 | @subsection propgrid_compat_general General Changes | |
1001 | ||
1002 | - Tab-traversal can no longer be used to travel between properties. Now | |
1003 | it only causes focus to move from main grid to editor of selected property. | |
1004 | Arrow keys are now your primary means of navigating between properties, | |
1005 | with keyboard. This change allowed fixing broken tab traversal on wxGTK | |
1006 | (which is open issue in wxPropertyGrid 1.4). | |
1007 | ||
4c51a665 | 1008 | - wxPG_EX_UNFOCUS_ON_ENTER style is removed and is now default behaviour. |
e8e754bf JS |
1009 | That is, when enter is pressed, editing is considered done and focus |
1010 | moves back to the property grid from the editor control. | |
1011 | ||
8622887c JS |
1012 | - A few member functions were removed from wxPropertyGridInterface. |
1013 | Please use wxPGProperty's counterparts from now on. | |
1014 | ||
4c51a665 | 1015 | - wxPGChoices now has proper Copy-On-Write behaviour. |
8622887c JS |
1016 | |
1017 | - wxPGChoices::SetExclusive() was renamed to AllocExclusive(). | |
1018 | ||
1019 | - wxPGProperty::SetPropertyChoicesExclusive() was removed. Instead, use | |
1020 | GetChoices().AllocExclusive(). | |
1021 | ||
1022 | - wxPGProperty::ClearModifiedStatus() is removed. Please use | |
1023 | SetModifiedStatus() instead. | |
1024 | ||
1025 | - wxPropertyGridInterface::GetExpandedProperties() is removed. You should | |
1026 | now use wxPropertyGridInterface::GetEditableState() instead. | |
1c4293cb | 1027 | |
08c1613f | 1028 | - wxPG_EX_DISABLE_TLP_TRACKING is now enabled by default. To get the old |
4c51a665 | 1029 | behaviour (recommended if you don't use a system that reparents the grid |
08c1613f JS |
1030 | on its own), use the wxPG_EX_ENABLE_TLP_TRACKING extra style. |
1031 | ||
8622887c JS |
1032 | - Extended window style wxPG_EX_LEGACY_VALIDATORS was removed. |
1033 | ||
4c51a665 | 1034 | - Default property validation failure behaviour has been changed to |
4fb5dadb JS |
1035 | (wxPG_VFB_MARK_CELL | wxPG_VFB_SHOW_MESSAGEBOX), which means that the |
1036 | cell is marked red and wxMessageBox is shown. This is more user-friendly | |
4c51a665 | 1037 | than the old behaviour, which simply beeped and prevented leaving the |
4fb5dadb JS |
1038 | property editor until a valid value was entered. |
1039 | ||
8622887c JS |
1040 | - wxPropertyGridManager now has same Get/SetSelection() semantics as |
1041 | wxPropertyGrid. | |
1042 | ||
1043 | - Various wxPropertyGridManager page-related functions now return pointer | |
1044 | to the page object instead of index. | |
1045 | ||
2906967c JS |
1046 | - wxArrayEditorDialog used by wxArrayStringProperty and some sample |
1047 | properties has been renamed to wxPGArrayEditorDialog. Also, it now uses | |
1048 | wxEditableListBox for editing. | |
1049 | ||
8622887c JS |
1050 | - Instead of calling wxPropertyGrid::SetButtonShortcut(), use |
1051 | wxPropertyGrid::SetActionTrigger(wxPG_ACTION_PRESS_BUTTON). | |
1052 | ||
1053 | - wxPGProperty::GetCell() now returns a reference. AcquireCell() was removed. | |
1054 | ||
1055 | - wxPGMultiButton::FinalizePosition() has been renamed to Finalize(), | |
1056 | and it has slightly different argument list. | |
1057 | ||
1058 | - wxPropertyGridEvent::HasProperty() is removed. You can use GetProperty() | |
1059 | as immediate replacement when checking if event has a property. | |
1060 | ||
534090e3 JS |
1061 | - "InlineHelp" property has been replaced with "Hint". |
1062 | ||
27c14b30 JS |
1063 | - wxPropertyGrid::CanClose() has been removed. Call |
1064 | wxPropertyGridInterface::EditorValidate() instead. | |
1065 | ||
6c78066f JS |
1066 | - wxPGProperty::SetFlag() has been moved to private API. This was done to |
1067 | underline the fact that it was not the preferred method to change a | |
1068 | property's state since it never had any desired side-effects. ChangeFlag() | |
1069 | still exists for those who really need to achieve the same effect. | |
1070 | ||
aae9e5bd JS |
1071 | - wxArrayStringProperty default delimiter is now comma (','), and it can |
1072 | be changed by setting the new "Delimiter" attribute. | |
1073 | ||
8622887c JS |
1074 | @subsection propgrid_compat_propdev Property and Editor Sub-classing Changes |
1075 | ||
1076 | - Confusing custom property macros have been eliminated. | |
1077 | ||
1078 | - Implement wxPGProperty::ValueToString() instead of GetValueAsString(). | |
1079 | ||
1080 | - wxPGProperty::ChildChanged() must now return the modified value of | |
1081 | whole property instead of writing it back into 'thisValue' argument. | |
1082 | ||
1083 | - Removed wxPropertyGrid::PrepareValueForDialogEditing(). Use | |
1084 | wxPropertyGrid::GetPendingEditedValue() instead. | |
1085 | ||
1086 | - wxPGProperty::GetChoiceInfo() is removed, as all properties now carry | |
1087 | wxPGChoices instance (protected wxPGProperty::m_choices). | |
1088 | ||
1089 | - Connect() should no longer be called in implementations of | |
1090 | wxPGEditor::CreateControls(). wxPropertyGrid automatically passes all | |
1091 | events from editor to wxPGEditor::OnEvent() and wxPGProperty::OnEvent(), | |
1092 | as appropriate. | |
0cd4552a JS |
1093 | |
1094 | - wxPython: Previously some of the reimplemented member functions needed a | |
1095 | 'Py' prefix. This is no longer necessary. For instance, if you previously | |
1096 | implemented PyStringToValue() for your custom property, you should now | |
1097 | just implement StringToValue(). | |
8622887c | 1098 | */ |