]>
Commit | Line | Data |
---|---|---|
1 | ///////////////////////////////////////////////////////////////////////////// | |
2 | // Name: propgrid.h | |
3 | // Purpose: topic overview | |
4 | // Author: wxWidgets team | |
5 | // RCS-ID: $Id: | |
6 | // Licence: wxWindows license | |
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 | ||
20 | wxPropertyGrid is a specialized grid for editing properties such as strings, | |
21 | numbers, flagsets, fonts, and colours. It is possible, for example, to categorize | |
22 | properties, set up a complete tree-hierarchy, add multiple columns, and set | |
23 | arbitrary per-property attributes. | |
24 | ||
25 | @li @ref propgrid_basics | |
26 | @li @ref propgrid_categories | |
27 | @li @ref propgrid_parentprops | |
28 | @li @ref propgrid_enumandflags | |
29 | @li @ref propgrid_advprops | |
30 | @li @ref propgrid_iterating | |
31 | @li @ref propgrid_operations | |
32 | @li @ref propgrid_events | |
33 | @li @ref propgrid_validating | |
34 | @li @ref propgrid_populating | |
35 | @li @ref propgrid_cellrender | |
36 | @li @ref propgrid_customizing | |
37 | @li @ref propgrid_usage2 | |
38 | @li @ref propgrid_subclassing | |
39 | @li @ref propgrid_misc | |
40 | @li @ref propgrid_proplist | |
41 | @li @ref propgrid_userhelp | |
42 | @li @ref propgrid_notes | |
43 | @li @ref propgrid_newprops | |
44 | @li @ref propgrid_neweditors | |
45 | ||
46 | @section propgrid_basics Creating and Populating wxPropertyGrid | |
47 | ||
48 | As seen here, wxPropertyGrid is constructed in the same way as | |
49 | other wxWidgets controls: | |
50 | ||
51 | @code | |
52 | ||
53 | // Necessary header file | |
54 | #include <wx/propgrid/propgrid.h> | |
55 | ||
56 | ... | |
57 | ||
58 | // Assumes code is in frame/dialog constructor | |
59 | ||
60 | // Construct wxPropertyGrid control | |
61 | wxPropertyGrid* pg = new wxPropertyGrid( | |
62 | this, // parent | |
63 | PGID, // id | |
64 | wxDefaultPosition, // position | |
65 | wxDefaultSize, // size | |
66 | // Here are just some of the supported window styles | |
67 | wxPG_AUTO_SORT | // Automatic sorting after items added | |
68 | wxPG_SPLITTER_AUTO_CENTER | // Automatically center splitter until user manually adjusts it | |
69 | // Default style | |
70 | wxPG_DEFAULT_STYLE ); | |
71 | ||
72 | // Window style flags are at premium, so some less often needed ones are | |
73 | // available as extra window styles (wxPG_EX_xxx) which must be set using | |
74 | // SetExtraStyle member function. wxPG_EX_HELP_AS_TOOLTIPS, for instance, | |
75 | // allows displaying help strings as tooltips. | |
76 | pg->SetExtraStyle( wxPG_EX_HELP_AS_TOOLTIPS ); | |
77 | ||
78 | @endcode | |
79 | ||
80 | (for complete list of new window styles: @link wndflags Additional Window Styles@endlink) | |
81 | ||
82 | wxPropertyGrid is usually populated with lines like this: | |
83 | ||
84 | @code | |
85 | pg->Append( new wxStringProperty(wxT("Label"),wxT("Name"),wxT("Initial Value")) ); | |
86 | @endcode | |
87 | ||
88 | Naturally, wxStringProperty is a property class. Only the first function argument (label) | |
89 | is mandatory. Second one, name, defaults to label and, third, the initial value, to | |
90 | default value. If constant wxPG_LABEL is used as the name argument, then the label is | |
91 | automatically used as a name as well (this is more efficient than manually defining both | |
92 | as the same). Use of empty name is discouraged and will sometimes result in run-time error. | |
93 | Note that all property class constructors have quite similar constructor argument list. | |
94 | ||
95 | To demonstrate other common property classes, here's another code snippet: | |
96 | ||
97 | @code | |
98 | ||
99 | // Add int property | |
100 | pg->Append( new wxIntProperty(wxT("IntProperty"), wxPG_LABEL, 12345678) ); | |
101 | ||
102 | // Add float property (value type is actually double) | |
103 | pg->Append( new wxFloatProperty(wxT("FloatProperty"), wxPG_LABEL, 12345.678) ); | |
104 | ||
105 | // Add a bool property | |
106 | pg->Append( new wxBoolProperty(wxT("BoolProperty"), wxPG_LABEL, false) ); | |
107 | ||
108 | // A string property that can be edited in a separate editor dialog. | |
109 | pg->Append( new wxLongStringProperty(wxT("LongStringProperty"), | |
110 | wxPG_LABEL, | |
111 | wxT("This is much longer string than the ") | |
112 | wxT("first one. Edit it by clicking the button."))); | |
113 | ||
114 | // String editor with dir selector button. | |
115 | pg->Append( new wxDirProperty(wxT("DirProperty"), wxPG_LABEL, ::wxGetUserHome()) ); | |
116 | ||
117 | // wxArrayStringProperty embeds a wxArrayString. | |
118 | pg->Append( new wxArrayStringProperty(wxT("Label of ArrayStringProperty"), | |
119 | wxT("NameOfArrayStringProp"))); | |
120 | ||
121 | // A file selector property. | |
122 | pg->Append( new wxFileProperty(wxT("FileProperty"), wxPG_LABEL, wxEmptyString) ); | |
123 | ||
124 | // Extra: set wildcard for file property (format same as in wxFileDialog). | |
125 | pg->SetPropertyAttribute( wxT("FileProperty"), | |
126 | wxPG_FILE_WILDCARD, | |
127 | wxT("All files (*.*)|*.*") ); | |
128 | ||
129 | @endcode | |
130 | ||
131 | Operations on properties should be done either via wxPropertyGrid's | |
132 | (or wxPropertyGridManager's) methods, or by acquiring pointer to a property | |
133 | (Append returns a wxPGProperty* or wxPGId, which is typedef for same), and then | |
134 | calling its method. Note however that property's methods generally do not | |
135 | automatically update grid graphics. | |
136 | ||
137 | Property container functions operating on properties, such as SetPropertyValue or | |
138 | DisableProperty, all accept a special wxPGPropArg, argument which can automatically | |
139 | convert name of a property to a pointer. For instance: | |
140 | ||
141 | @code | |
142 | // A file selector property. | |
143 | wxPGPropety* p = pg->Append( new wxFileProperty(wxT("FileProperty"), wxPG_LABEL, wxEmptyString) ); | |
144 | ||
145 | // Valid: Set wildcard by name | |
146 | pg->SetPropertyAttribute( wxT("FileProperty"), | |
147 | wxPG_FILE_WILDCARD, | |
148 | wxT("All files (*.*)|*.*") ); | |
149 | ||
150 | // Also Valid: Set wildcard by ptr | |
151 | pg->SetPropertyAttribute( p, | |
152 | wxPG_FILE_WILDCARD, | |
153 | wxT("All files (*.*)|*.*") ); | |
154 | @endcode | |
155 | ||
156 | Using pointer is faster, since it doesn't require hash map lookup. Anyway, you can allways | |
157 | get property pointer (wxPGProperty*) as Append/Insert return value, or by calling | |
158 | GetPropertyByName. | |
159 | ||
160 | Below are samples for using some of the more commong operations. See | |
161 | wxPropertyGridInterface and wxPropertyGrid class references for complete list. | |
162 | ||
163 | @code | |
164 | ||
165 | // wxPGId is a short-hand for wxPGProperty*. Let's use it this time. | |
166 | wxPGId id = pg->GetPropertyByName( wxT("MyProperty") ); | |
167 | ||
168 | // There are many overloaded versions of this method, of which each accept | |
169 | // different type of value. | |
170 | pg->SetPropertyValue( wxT("MyProperty"), 200 ); | |
171 | ||
172 | // Setting a string works for all properties - conversion is done | |
173 | // automatically. | |
174 | pg->SetPropertyValue( id, wxT("400") ); | |
175 | ||
176 | // Getting property value as wxVariant. | |
177 | wxVariant value = pg->GetPropertyValue( wxT("MyProperty") ); | |
178 | ||
179 | // Getting property value as String (again, works for all typs). | |
180 | wxString value = pg->GetPropertyValueAsString( id ); | |
181 | ||
182 | // Getting property value as int. Provokes a run-time error | |
183 | // if used with property which value type is not "long". | |
184 | long value = pg->GetPropertyValueAsLong( wxT("MyProperty") ); | |
185 | ||
186 | // Set new name. | |
187 | pg->SetPropertyName( wxT("MyProperty"), wxT("X") ); | |
188 | ||
189 | // Set new label - we need to use the new name. | |
190 | pg->SetPropertyLabel( wxT("X"), wxT("New Label") ); | |
191 | ||
192 | // Disable the property. It's text will appear greyed. | |
193 | // This is probably the closest you can get if you want | |
194 | // a "read-only" property. | |
195 | pg->DisableProperty( id ); | |
196 | ||
197 | @endcode | |
198 | ||
199 | ||
200 | @section propgrid_categories Categories | |
201 | ||
202 | wxPropertyGrid has a hierarchial property storage and display model, which | |
203 | allows property categories to hold child properties and even other | |
204 | categories. Other than that, from the programmer's point of view, categories | |
205 | can be treated exactly the same as "other" properties. For example, despite | |
206 | its name, GetPropertyByName also returns a category by name, and SetPropertyLabel | |
207 | also sets label of a category. Note however that sometimes the label of a | |
208 | property category may be referred as caption (for example, there is | |
209 | SetCaptionForegroundColour method that sets text colour of a property category's label). | |
210 | ||
211 | When category is added at the top (i.e. root) level of the hierarchy, | |
212 | it becomes a *current category*. This means that all other (non-category) | |
213 | properties after it are automatically added to it. You may add | |
214 | properties to specific categories by using wxPropertyGrid::Insert or wxPropertyGrid::AppendIn. | |
215 | ||
216 | Category code sample: | |
217 | ||
218 | @code | |
219 | ||
220 | // One way to add category (similar to how other properties are added) | |
221 | pg->Append( new wxPropertyCategory(wxT("Main")) ); | |
222 | ||
223 | // All these are added to "Main" category | |
224 | pg->Append( new wxStringProperty(wxT("Name")) ); | |
225 | pg->Append( new wxIntProperty(wxT("Age"),wxPG_LABEL,25) ); | |
226 | pg->Append( new wxIntProperty(wxT("Height"),wxPG_LABEL,180) ); | |
227 | pg->Append( new wxIntProperty(wxT("Weight")) ); | |
228 | ||
229 | // Another one | |
230 | pg->Append( new wxPropertyCategory(wxT("Attrikbutes")) ); | |
231 | ||
232 | // All these are added to "Attributes" category | |
233 | pg->Append( new wxIntProperty(wxT("Intelligence")) ); | |
234 | pg->Append( new wxIntProperty(wxT("Agility")) ); | |
235 | pg->Append( new wxIntProperty(wxT("Strength")) ); | |
236 | ||
237 | @endcode | |
238 | ||
239 | ||
240 | @section propgrid_parentprops Tree-like Property Structure | |
241 | ||
242 | As a new feature in version 1.3.1, basicly any property can have children. There | |
243 | are few limitations, however. | |
244 | ||
245 | @remarks | |
246 | - Names of properties with non-category, non-root parents are not stored in hash map. | |
247 | Instead, they can be accessed with strings like "Parent.Child". For instance, in | |
248 | the sample below, child property named "Max. Speed (mph)" can be accessed by global | |
249 | name "Car.Speeds.Max Speed (mph)". | |
250 | - If you want to property's value to be a string composed based on the values of | |
251 | child properties, you must use wxStringProperty as parent and use value "<composed>". | |
252 | - Events (eg. change of value) that occur in parent do not propagate to children. Events | |
253 | that occur in children will propagate to parents, but only if they are wxStringProperties | |
254 | with "<composed>" value. | |
255 | - Old wxParentProperty class is deprecated, and remains as a typedef of wxStringProperty. | |
256 | If you want old value behavior, you must specify "<composed>" as wxStringProperty's | |
257 | value. | |
258 | ||
259 | Sample: | |
260 | ||
261 | @code | |
262 | wxPGId pid = pg->Append( new wxStringProperty(wxT("Car"),wxPG_LABEL,wxT("<composed>")) ); | |
263 | ||
264 | pg->AppendIn( pid, new wxStringProperty(wxT("Model"), | |
265 | wxPG_LABEL, | |
266 | wxT("Lamborghini Diablo SV")) ); | |
267 | ||
268 | pg->AppendIn( pid, new wxIntProperty(wxT("Engine Size (cc)"), | |
269 | wxPG_LABEL, | |
270 | 5707) ); | |
271 | ||
272 | wxPGId speedId = pg->AppendIn( pid, new wxStringProperty(wxT("Speeds"),wxPG_LABEL,wxT("<composed>")) ); | |
273 | pg->AppendIn( speedId, new wxIntProperty(wxT("Max. Speed (mph)"),wxPG_LABEL,290) ); | |
274 | pg->AppendIn( speedId, new wxFloatProperty(wxT("0-100 mph (sec)"),wxPG_LABEL,3.9) ); | |
275 | pg->AppendIn( speedId, new wxFloatProperty(wxT("1/4 mile (sec)"),wxPG_LABEL,8.6) ); | |
276 | ||
277 | // Make sure the child properties can be accessed correctly | |
278 | pg->SetPropertyValue( wxT("Car.Speeds.Max. Speed (mph)"), 300 ); | |
279 | ||
280 | pg->AppendIn( pid, new wxIntProperty(wxT("Price ($)"), | |
281 | wxPG_LABEL, | |
282 | 300000) ); | |
283 | // Displayed value of "Car" property is now: | |
284 | // "Lamborghini Diablo SV; [300; 3.9; 8.6]; 300000" | |
285 | ||
286 | @endcode | |
287 | ||
288 | @section propgrid_enumandflags wxEnumProperty and wxFlagsProperty | |
289 | ||
290 | wxEnumProperty is used when you want property's (integer or string) value | |
291 | to be selected from a popup list of choices. | |
292 | ||
293 | Creating wxEnumProperty is more complex than those described earlier. | |
294 | You have to provide list of constant labels, and optionally relevant values | |
295 | (if label indexes are not sufficient). | |
296 | ||
297 | @remarks | |
298 | ||
299 | - Value wxPG_INVALID_VALUE (equals 2147483647 which usually equals INT_MAX) is not | |
300 | allowed as value. | |
301 | ||
302 | A very simple example: | |
303 | ||
304 | @code | |
305 | ||
306 | // | |
307 | // Using wxArrayString | |
308 | // | |
309 | wxArrayString arrDiet; | |
310 | arr.Add(wxT("Herbivore")); | |
311 | arr.Add(wxT("Carnivore")); | |
312 | arr.Add(wxT("Omnivore")); | |
313 | ||
314 | pg->Append( new wxEnumProperty(wxT("Diet"), | |
315 | wxPG_LABEL, | |
316 | arrDiet) ); | |
317 | ||
318 | ||
319 | ||
320 | // | |
321 | // Using wxChar* array | |
322 | // | |
323 | const wxChar* arrayDiet[] = | |
324 | { wxT("Herbivore"), wxT("Carnivore"), wxT("Omnivore"), NULL }; | |
325 | ||
326 | pg->Append( new wxEnumProperty(wxT("Diet"), | |
327 | wxPG_LABEL, | |
328 | arrayDiet) ); | |
329 | ||
330 | ||
331 | @endcode | |
332 | ||
333 | Here's extended example using values as well: | |
334 | ||
335 | @code | |
336 | ||
337 | // | |
338 | // Using wxArrayString and wxArrayInt | |
339 | // | |
340 | wxArrayString arrDiet; | |
341 | arr.Add(wxT("Herbivore")); | |
342 | arr.Add(wxT("Carnivore")); | |
343 | arr.Add(wxT("Omnivore")); | |
344 | ||
345 | wxArrayInt arrIds; | |
346 | arrIds.Add(40); | |
347 | arrIds.Add(45); | |
348 | arrIds.Add(50); | |
349 | ||
350 | // Note that the initial value (the last argument) is the actual value, | |
351 | // not index or anything like that. Thus, our value selects "Omnivore". | |
352 | pg->Append( new wxEnumProperty(wxT("Diet"), | |
353 | wxPG_LABEL, | |
354 | arrDiet, | |
355 | arrIds, | |
356 | 50)); | |
357 | ||
358 | ||
359 | // | |
360 | // Using wxChar* and long arrays | |
361 | // | |
362 | const wxChar* array_diet[] = | |
363 | { wxT("Herbivore"), wxT("Carnivore"), wxT("Omnivore"), NULL }; | |
364 | ||
365 | long array_diet_ids[] = | |
366 | { 40, 45, 50 }; | |
367 | ||
368 | // Value can be set from string as well | |
369 | pg->Append( new wxEnumProperty(wxT("Diet"), | |
370 | wxPG_LABEL, | |
371 | array_diet, | |
372 | array_diet_ids); | |
373 | ||
374 | @endcode | |
375 | ||
376 | wxPGChoices is a class where wxEnumProperty, and other properties which | |
377 | require label storage, actually stores strings and values. It is used | |
378 | to facilitiate reference counting, and therefore recommended way of | |
379 | adding items when multiple properties share the same set. | |
380 | ||
381 | You can use wxPGChoices directly as well, filling it and then passing it | |
382 | to the constructor. Infact, if you wish to display bitmaps next to labels, | |
383 | your best choice is to use this approach. | |
384 | ||
385 | @code | |
386 | ||
387 | wxPGChoices chs; | |
388 | chs.Add(wxT("Herbivore"),40); | |
389 | chs.Add(wxT("Carnivore"),45); | |
390 | chs.Add(wxT("Omnivore"),50); | |
391 | ||
392 | // Let's add an item with bitmap, too | |
393 | chs.Add(wxT("None of the above"), wxBitmap(), 60); | |
394 | ||
395 | // Note: you can add even whole arrays to wxPGChoices | |
396 | ||
397 | pg->Append( new wxEnumProperty(wxT("Diet"), | |
398 | wxPG_LABEL, | |
399 | chs) ); | |
400 | ||
401 | // Add same choices to another property as well - this is efficient due | |
402 | // to reference counting | |
403 | pg->Append( new wxEnumProperty(wxT("Diet 2"), | |
404 | wxPG_LABEL, | |
405 | chs) ); | |
406 | ||
407 | @endcode | |
408 | ||
409 | If you later need to change choices used by a property, there is function | |
410 | for that as well. | |
411 | ||
412 | @code | |
413 | ||
414 | // | |
415 | // Example 1: Add one extra item | |
416 | wxPGChoices& choices = pg->GetPropertyChoices(wxT("Diet")); | |
417 | choices.Add(wxT("Custom"),55); | |
418 | ||
419 | // | |
420 | // Example 2: Replace all the choices | |
421 | wxPGChoices chs; | |
422 | chs.Add(wxT("<No valid items yet>"),0); | |
423 | pg->SetPropertyChoices(wxT("Diet"),chs); | |
424 | ||
425 | @endcode | |
426 | ||
427 | If you want to create your enum properties with simple (label,name,value) | |
428 | constructor, then you need to create a new property class using one of the | |
429 | supplied macro pairs. See @ref pgproperty_creating for details. | |
430 | ||
431 | <b>wxEditEnumProperty</b> is works exactly like wxEnumProperty, except | |
432 | is uses non-readonly combobox as default editor, and value is stored as | |
433 | string when it is not any of the choices. | |
434 | ||
435 | wxFlagsProperty is similar: | |
436 | ||
437 | @code | |
438 | ||
439 | const wxChar* flags_prop_labels[] = { wxT("wxICONIZE"), | |
440 | wxT("wxCAPTION"), wxT("wxMINIMIZE_BOX"), wxT("wxMAXIMIZE_BOX"), NULL }; | |
441 | ||
442 | // this value array would be optional if values matched string indexes | |
443 | long flags_prop_values[] = { wxICONIZE, wxCAPTION, wxMINIMIZE_BOX, | |
444 | wxMAXIMIZE_BOX }; | |
445 | ||
446 | pg->Append( new wxFlagsProperty(wxT("Window Style"), | |
447 | wxPG_LABEL, | |
448 | flags_prop_labels, | |
449 | flags_prop_values, | |
450 | wxDEFAULT_FRAME_STYLE) ); | |
451 | ||
452 | @endcode | |
453 | ||
454 | wxFlagsProperty can use wxPGChoices just the same way as wxEnumProperty | |
455 | (and also custom property classes can be created with similar macro pairs). | |
456 | <b>Note: </b> When changing "choices" (ie. flag labels) of wxFlagsProperty, | |
457 | you will need to use SetPropertyChoices - otherwise they will not get updated | |
458 | properly. | |
459 | ||
460 | @section propgrid_advprops Specialized Properties | |
461 | ||
462 | This section describes the use of less often needed property classes. | |
463 | To use them, you have to include <wx/propgrid/advprops.h>. | |
464 | ||
465 | @code | |
466 | ||
467 | // Necessary extra header file | |
468 | #include <wx/propgrid/advprops.h> | |
469 | ||
470 | ... | |
471 | ||
472 | // Date property. | |
473 | pg->Append( new wxDateProperty(wxT("MyDateProperty"), | |
474 | wxPG_LABEL, | |
475 | wxDateTime::Now()) ); | |
476 | ||
477 | // Image file property. Wildcard is auto-generated from available | |
478 | // image handlers, so it is not set this time. | |
479 | pg->Append( new wxImageFileProperty(wxT("Label of ImageFileProperty"), | |
480 | wxT("NameOfImageFileProp")) ); | |
481 | ||
482 | // Font property has sub-properties. Note that we give window's font as | |
483 | // initial value. | |
484 | pg->Append( new wxFontProperty(wxT("Font"), | |
485 | wxPG_LABEL, | |
486 | GetFont()) ); | |
487 | ||
488 | // Colour property with arbitrary colour. | |
489 | pg->Append( new wxColourProperty(wxT("My Colour 1"), | |
490 | wxPG_LABEL, | |
491 | wxColour(242,109,0) ) ); | |
492 | ||
493 | // System colour property. | |
494 | pg->Append( new wxSystemColourProperty(wxT("My SysColour 1"), | |
495 | wxPG_LABEL, | |
496 | wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW)) ); | |
497 | ||
498 | // System colour property with custom colour. | |
499 | pg->Append( new wxSystemColourProperty(wxT("My SysColour 2"), | |
500 | wxPG_LABEL, | |
501 | wxColour(0,200,160) ) ); | |
502 | ||
503 | // Cursor property | |
504 | pg->Append( new wxCursorProperty(wxT("My Cursor"), | |
505 | wxPG_LABEL, | |
506 | wxCURSOR_ARROW)); | |
507 | ||
508 | @endcode | |
509 | ||
510 | ||
511 | @section propgrid_iterating Iterating through a property container | |
512 | ||
513 | You can use somewhat STL'ish iterator classes to iterate through the grid. | |
514 | Here is a simple example of forward iterating through all individual | |
515 | properties (not categories or sub-propeties that are normally 'transparent' | |
516 | to application code): | |
517 | ||
518 | @code | |
519 | ||
520 | wxPropertyGridIterator it; | |
521 | ||
522 | for ( it = pg->GetIterator(); | |
523 | !it.AtEnd(); | |
524 | it++ ) | |
525 | { | |
526 | wxPGProperty* p = *it; | |
527 | // Do something with the property | |
528 | } | |
529 | ||
530 | @endcode | |
531 | ||
532 | As expected there is also a const iterator: | |
533 | ||
534 | @code | |
535 | ||
536 | wxPropertyGridConstIterator it; | |
537 | ||
538 | for ( it = pg->GetIterator(); | |
539 | !it.AtEnd(); | |
540 | it++ ) | |
541 | { | |
542 | const wxPGProperty* p = *it; | |
543 | // Do something with the property | |
544 | } | |
545 | ||
546 | @endcode | |
547 | ||
548 | You can give some arguments to GetIterator to determine which properties | |
549 | get automatically filtered out. For complete list of options, see | |
550 | @link iteratorflags List of Property Iterator Flags@endlink. GetIterator() | |
551 | also accepts other arguments. See wxPropertyGridInterface::GetIterator() | |
552 | for details. | |
553 | ||
554 | This example reverse-iterates through all visible items: | |
555 | ||
556 | @code | |
557 | ||
558 | wxPropertyGridIterator it; | |
559 | ||
560 | for ( it = pg->GetIterator(wxPG_ITERATE_VISIBLE, wxBOTTOM); | |
561 | !it.AtEnd(); | |
562 | it-- ) | |
563 | { | |
564 | wxPGProperty* p = *it; | |
565 | // Do something with the property | |
566 | } | |
567 | ||
568 | @endcode | |
569 | ||
570 | <b>wxPython Note:</b> Instead of ++ operator, use Next() method, and instead of | |
571 | * operator, use GetProperty() method. | |
572 | ||
573 | GetIterator() only works with wxPropertyGrid and the individual pages | |
574 | of wxPropertyGridManager. In order to iterate through an arbitrary | |
575 | property container, you need to use wxPropertyGridInterface::GetVIterator(). | |
576 | Note however that this virtual iterater is limited to forward iteration. | |
577 | ||
578 | @code | |
579 | ||
580 | wxPGVIterator it; | |
581 | ||
582 | for ( it = manager->GetVIterator(); | |
583 | !it.AtEnd(); | |
584 | it.Next() ) | |
585 | { | |
586 | wxPGProperty* p = it.GetProperty(); | |
587 | // Do something with the property | |
588 | } | |
589 | ||
590 | @endcode | |
591 | ||
592 | ||
593 | @section propgrid_operations More About Operating with Properties | |
594 | ||
595 | Getting value of selected wxSystemColourProperty (which value type is derived | |
596 | from wxObject): | |
597 | ||
598 | @code | |
599 | ||
600 | wxPGId id = pg->GetSelection(); | |
601 | ||
602 | if ( id ) | |
603 | { | |
604 | // Get name of property | |
605 | const wxString& name = pg->GetPropertyName( id ); | |
606 | ||
607 | // If type is not correct, GetColour() method will produce run-time error | |
608 | if ( pg->GetPropertyValueType() == wxT("wxColourPropertyValue") ) ) | |
609 | { | |
610 | wxColourPropertyValue* pcolval = | |
611 | wxDynamicCast(pg->GetPropertyValueAsWxObjectPtr(id), | |
612 | wxColourPropertyValue); | |
613 | ||
614 | // Report value | |
615 | wxString text; | |
616 | if ( pcolval->m_type == wxPG_CUSTOM_COLOUR ) | |
617 | text.Printf( wxT("It is custom colour: (%i,%i,%i)"), | |
618 | (int)pcolval->m_colour.Red(), | |
619 | (int)pcolval->m_colour.Green(), | |
620 | (int)pcolval->m_colour.Blue()); | |
621 | else | |
622 | text.Printf( wxT("It is wx system colour (number=%i): (%i,%i,%i)"), | |
623 | (int)pcolval->m_type, | |
624 | (int)pcolval->m_colour.Red(), | |
625 | (int)pcolval->m_colour.Green(), | |
626 | (int)pcolval->m_colour.Blue()); | |
627 | ||
628 | wxMessageBox( text ); | |
629 | } | |
630 | } | |
631 | ||
632 | @endcode | |
633 | ||
634 | @section propgrid_populating Populating wxPropertyGrid Automatically | |
635 | ||
636 | @subsection propgrid_fromvariants Populating from List of wxVariants | |
637 | ||
638 | Example of populating an empty wxPropertyGrid from a values stored | |
639 | in an arbitrary list of wxVariants. | |
640 | ||
641 | @code | |
642 | ||
643 | // This is a static method that initializes *all* builtin type handlers | |
644 | // available, including those for wxColour and wxFont. Refers to *all* | |
645 | // included properties, so when compiling with static library, this | |
646 | // method may increase the executable size significantly. | |
647 | pg->InitAllTypeHandlers(); | |
648 | ||
649 | // Get contents of the grid as a wxVariant list | |
650 | wxVariant all_values = pg->GetPropertyValues(); | |
651 | ||
652 | // Populate the list with values. If a property with appropriate | |
653 | // name is not found, it is created according to the type of variant. | |
654 | pg->SetPropertyValues( my_list_variant ); | |
655 | ||
656 | // In order to get wxObject ptr from a variant value, | |
657 | // wxGetVariantCast(VARIANT,CLASSNAME) macro has to be called. | |
658 | // Like this: | |
659 | wxVariant v_txcol = pg->GetPropertyValue(wxT("Text Colour")); | |
660 | const wxColour& txcol = wxGetVariantCast(v_txcol,wxColour); | |
661 | ||
662 | @endcode | |
663 | ||
664 | @subsection propgrid_fromfile Loading Population from a Text-based Storage | |
665 | ||
666 | Class wxPropertyGridPopulator may be helpful when writing code that | |
667 | loads properties from a text-source. In fact, the supplied xrc handler | |
668 | (src/xh_propgrid.cpp) uses it. See that code for more info. | |
669 | NOTE: src/xh_propgrid.cpp is not included in the library by default, | |
670 | to avoid dependency to wxXRC. You will need to add it to your application | |
671 | separately. | |
672 | ||
673 | @subsection propgrid_editablestate Saving and Restoring User-Editable State | |
674 | ||
675 | You can use wxPGEditableState and wxPGMEditableState classes, and | |
676 | wxPropertyGrid::SaveEditableState() and wxPropertyGrid::RestoreEditableState() | |
677 | to save and restore user-editable state (selected property, expanded/ | |
678 | collapsed properties, and scrolled position). For convience with | |
679 | program configuration, wxPGEditableState has functions to save/load | |
680 | its value in wxString. For instance: | |
681 | ||
682 | @code | |
683 | // Save state into config | |
684 | wxPGEditableState edState; | |
685 | pg->SaveEditableState(&edState); | |
686 | programConfig->Store(wxT("PropertyGridState"), edState.GetAsString()); | |
687 | ||
688 | // Restore state from config | |
689 | wxPGEditableState edState; | |
690 | edState.SetFromString(programConfig->Load(wxT("PropertyGridState"))); | |
691 | pg->RestoreEditableState(edState); | |
692 | @endcode | |
693 | ||
694 | ||
695 | @section propgrid_events Event Handling | |
696 | ||
697 | Probably the most important event is the Changed event which occurs when | |
698 | value of any property is changed by the user. Use EVT_PG_CHANGED(id,func) | |
699 | in your event table to use it. | |
700 | ||
701 | For complete list of event types, see wxPropertyGrid class reference. | |
702 | ||
703 | The custom event class, wxPropertyGridEvent, has methods to directly | |
704 | access the property that triggered the event. | |
705 | ||
706 | Here's a small sample: | |
707 | ||
708 | @code | |
709 | ||
710 | // Portion of an imaginary event table | |
711 | BEGIN_EVENT_TABLE(MyForm, wxFrame) | |
712 | ||
713 | ... | |
714 | ||
715 | // This occurs when a property value changes | |
716 | EVT_PG_CHANGED( PGID, MyForm::OnPropertyGridChange ) | |
717 | ||
718 | ... | |
719 | ||
720 | END_EVENT_TABLE() | |
721 | ||
722 | void MyForm::OnPropertyGridChange( wxPropertyGridEvent& event ) | |
723 | { | |
724 | wxPGProperty *property = event.GetProperty(); | |
725 | ||
726 | // It may be NULL | |
727 | if ( !property ) | |
728 | return; | |
729 | ||
730 | // Get name of changed property | |
731 | const wxString& name = property->GetName(); | |
732 | ||
733 | // Get resulting value | |
734 | wxVariant value = property->GetValue(); | |
735 | } | |
736 | ||
737 | @endcode | |
738 | ||
739 | Another event type you might find useful is EVT_PG_CHANGING, which occurs | |
740 | just prior property value is being changed by user. You can acquire pending | |
741 | value using wxPropertyGridEvent::GetValue(), and if it is not acceptable, | |
742 | call wxPropertyGridEvent::Veto() to prevent the value change from taking | |
743 | place. | |
744 | ||
745 | @code | |
746 | ||
747 | // Portion of an imaginary event table | |
748 | BEGIN_EVENT_TABLE(MyForm, wxFrame) | |
749 | ||
750 | ... | |
751 | ||
752 | // This occurs when a property value changes | |
753 | EVT_PG_CHANGING( PGID, MyForm::OnPropertyGridChanging ) | |
754 | ||
755 | ... | |
756 | ||
757 | END_EVENT_TABLE() | |
758 | ||
759 | void MyForm::OnPropertyGridChanging( wxPropertyGridEvent& event ) | |
760 | { | |
761 | wxPGProperty* property = event.GetProperty(); | |
762 | ||
763 | if ( property == m_pWatchThisProperty ) | |
764 | { | |
765 | // GetValue() returns the pending value, but is only | |
766 | // supported by wxEVT_PG_CHANGING. | |
767 | if ( event.GetValue().GetString() == g_pThisTextIsNotAllowed ) | |
768 | { | |
769 | event.Veto(); | |
770 | return; | |
771 | } | |
772 | } | |
773 | } | |
774 | ||
775 | @endcode | |
776 | ||
777 | @remarks On Sub-property Event Handling | |
778 | - For aggregate type properties (wxFontProperty, wxFlagsProperty, etc), events | |
779 | occur for the main parent property only. For other properties events occur | |
780 | for the children themselves.. | |
781 | ||
782 | - When property's child gets changed, you can use wxPropertyGridEvent::GetMainParent | |
783 | to obtain its topmost non-category parent (useful, if you have deeply nested | |
784 | properties). | |
785 | ||
786 | ||
787 | @section propgrid_validating Validating Property Values | |
788 | ||
789 | There are various ways to make sure user enters only correct values. First, you | |
790 | can use wxValidators similar to as you would with ordinary controls. Use | |
791 | wxPropertyGridInterface::SetPropertyValidator() to assign wxValidator to | |
792 | property. | |
793 | ||
794 | Second, you can subclass a property and override wxPGProperty::ValidateValue(), | |
795 | or handle wxEVT_PG_CHANGING for the same effect. Both of these methods do not | |
796 | actually prevent user from temporarily entering invalid text, but they do give | |
797 | you an opportunity to warn the user and block changed value from being committed | |
798 | in a property. | |
799 | ||
800 | Various validation failure options can be controlled globally with | |
801 | wxPropertyGrid::SetValidationFailureBehavior(), or on an event basis by | |
802 | calling wxEvent::SetValidationFailureBehavior(). Here's a code snippet of | |
803 | how to handle wxEVT_PG_CHANGING, and to set custom failure behaviour and | |
804 | message. | |
805 | ||
806 | @code | |
807 | void MyFrame::OnPropertyGridChanging(wxPropertyGridEvent& event) | |
808 | { | |
809 | wxPGProperty* property = event.GetProperty(); | |
810 | ||
811 | // You must use wxPropertyGridEvent::GetValue() to access | |
812 | // the value to be validated. | |
813 | wxVariant pendingValue = event.GetValue(); | |
814 | ||
815 | if ( property->GetName() == wxT("Font") ) | |
816 | { | |
817 | // Make sure value is not unspecified | |
818 | if ( !pendingValue.IsNull() ) | |
819 | { | |
820 | wxFont font << pendingValue; | |
821 | ||
822 | // Let's just allow Arial font | |
823 | if ( font.GetFaceName() != wxT("Arial") ) | |
824 | { | |
825 | event.Veto(); | |
826 | event.SetValidationFailureBehavior(wxPG_VFB_STAY_IN_PROPERTY | | |
827 | wxPG_VFB_BEEP | | |
828 | wxPG_VFB_SHOW_MESSAGE); | |
829 | } | |
830 | } | |
831 | } | |
832 | } | |
833 | @endcode | |
834 | ||
835 | ||
836 | @section propgrid_cellrender Customizing Individual Cell Appearance | |
837 | ||
838 | You can control text colour, background colour, and attached image of | |
839 | each cell in the property grid. Use wxPropertyGridInterface::SetPropertyCell() or | |
840 | wxPGProperty::SetCell() for this purpose. | |
841 | ||
842 | In addition, it is possible to control these characteristics for | |
843 | wxPGChoices list items. See wxPGChoices::Item() and wxPGChoiceEntry class | |
844 | reference for more info. | |
845 | ||
846 | ||
847 | @section propgrid_customizing Customizing Properties (without sub-classing) | |
848 | ||
849 | In this section are presented miscellaneous ways to have custom appearance | |
850 | and behavior for your properties without all the necessary hassle | |
851 | of sub-classing a property class etc. | |
852 | ||
853 | @subsection propgrid_customimage Setting Value Image | |
854 | ||
855 | Every property can have a small value image placed in front of the | |
856 | actual value text. Built-in example of this can be seen with | |
857 | wxColourProperty and wxImageFileProperty, but for others it can | |
858 | be set using wxPropertyGrid::SetPropertyImage method. | |
859 | ||
860 | @subsection propgrid_customvalidator Setting Validator | |
861 | ||
862 | You can set wxValidator for a property using wxPropertyGrid::SetPropertyValidator. | |
863 | ||
864 | Validator will work just like in wxWidgets (ie. editorControl->SetValidator(validator) | |
865 | is called). | |
866 | ||
867 | @subsection propgrid_customeditor Setting Property's Editor Control(s) | |
868 | ||
869 | You can set editor control (or controls, in case of a control and button), | |
870 | of any property using wxPropertyGrid::SetPropertyEditor. Editors are passed | |
871 | using wxPG_EDITOR(EditorName) macro, and valid built-in EditorNames are | |
872 | TextCtrl, Choice, ComboBox, CheckBox, TextCtrlAndButton, ChoiceAndButton, | |
873 | SpinCtrl, and DatePickerCtrl. Two last mentioned ones require call to | |
874 | static member function wxPropertyGrid::RegisterAdditionalEditors(). | |
875 | ||
876 | Following example changes wxColourProperty's editor from default Choice | |
877 | to TextCtrlAndButton. wxColourProperty has its internal event handling set | |
878 | up so that button click events of the button will be used to trigger | |
879 | colour selection dialog. | |
880 | ||
881 | @code | |
882 | ||
883 | wxPGId colProp = pg->Append(wxColourProperty(wxT("Text Colour"))); | |
884 | ||
885 | pg->SetPropertyEditor(colProp,wxPG_EDITOR(TextCtrlAndButton)); | |
886 | ||
887 | @endcode | |
888 | ||
889 | Naturally, creating and setting custom editor classes is a possibility as | |
890 | well. For more information, see wxPGEditor class reference. | |
891 | ||
892 | @subsection propgrid_editorattrs Property Attributes Recognized by Editors | |
893 | ||
894 | <b>SpinCtrl</b> editor can make use of property's "Min", "Max", "Step" and "Wrap" attributes. | |
895 | ||
896 | @subsection propgrid_multiplebuttons Adding Multiple Buttons Next to an Editor | |
897 | ||
898 | See wxPGMultiButton class reference. | |
899 | ||
900 | @subsection propgrid_customeventhandling Handling Events Passed from Properties | |
901 | ||
902 | <b>wxEVT_COMMAND_BUTTON_CLICKED </b>(corresponds to event table macro EVT_BUTTON): | |
903 | Occurs when editor button click is not handled by the property itself | |
904 | (as is the case, for example, if you set property's editor to TextCtrlAndButton | |
905 | from the original TextCtrl). | |
906 | ||
907 | @subsection propgrid_attributes Property Attributes | |
908 | ||
909 | Miscellaneous values, often specific to a property type, can be set | |
910 | using wxPropertyGrid::SetPropertyAttribute and wxPropertyGrid::SetPropertyAttributeAll | |
911 | methods. | |
912 | ||
913 | Attribute names are strings and values wxVariant. Arbitrary names are allowed | |
914 | inorder to store user values. Constant equivalents of all attribute string names are | |
915 | provided. Some of them are defined as cached strings, so using constants can provide | |
916 | for smaller binary size. | |
917 | ||
918 | For complete list of attributes, see @link attrids Property Attributes@endlink. | |
919 | ||
920 | @subsection propgrid_boolcheckbox Setting wxBoolProperties to Use Check Box | |
921 | ||
922 | To have all wxBoolProperties to use CheckBox editor instead of Choice, use | |
923 | following (call after bool properties have been added): | |
924 | ||
925 | @code | |
926 | pg->SetPropertyAttributeAll(wxPG_BOOL_USE_CHECKBOX,true); | |
927 | @endcode | |
928 | ||
929 | ||
930 | @section propgrid_usage2 Using wxPropertyGridManager | |
931 | ||
932 | wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid, | |
933 | which can optionally have toolbar for mode and page selection, and a help text | |
934 | box. | |
935 | ||
936 | wxPropertyGridManager inherits from wxPropertyGridInterface, and as such | |
937 | it has most property manipulation functions. However, only some of them affect | |
938 | properties on all pages (eg. GetPropertyByName() and ExpandAll()), while some | |
939 | (eg. Append()) only apply to the currently selected page. | |
940 | ||
941 | To operate explicitly on properties on specific page, use wxPropertyGridManager::GetPage() | |
942 | to obtain pointer to page's wxPropertyGridPage object. | |
943 | ||
944 | Visual methods, such as SetCellBackgroundColour and GetNextVisible are only | |
945 | available in wxPropertyGrid. Use wxPropertyGridManager::GetGrid() to obtain | |
946 | pointer to it. | |
947 | ||
948 | Iteration methods will not work in wxPropertyGridManager. Instead, you must acquire | |
949 | the internal grid (GetGrid()) or wxPropertyGridPage object (GetPage()). | |
950 | ||
951 | wxPropertyGridManager constructor has exact same format as wxPropertyGrid | |
952 | constructor, and basicly accepts same extra window style flags (albeit also | |
953 | has some extra ones). | |
954 | ||
955 | Here's some example code for creating and populating a wxPropertyGridManager: | |
956 | ||
957 | @code | |
958 | ||
959 | wxPropertyGridManager* pgMan = new wxPropertyGridManager(this, PGID, | |
960 | wxDefaultPosition, wxDefaultSize, | |
961 | // These and other similar styles are automatically | |
962 | // passed to the embedded wxPropertyGrid. | |
963 | wxPG_BOLD_MODIFIED|wxPG_SPLITTER_AUTO_CENTER| | |
964 | // Include toolbar. | |
965 | wxPG_TOOLBAR | | |
966 | // Include description box. | |
967 | wxPG_DESCRIPTION | | |
968 | // Include compactor. | |
969 | wxPG_COMPACTOR | | |
970 | // Plus defaults. | |
971 | wxPGMAN_DEFAULT_STYLE | |
972 | ); | |
973 | ||
974 | wxPropertyGridPage* page; | |
975 | ||
976 | // Adding a page sets target page to the one added, so | |
977 | // we don't have to call SetTargetPage if we are filling | |
978 | // it right after adding. | |
979 | pgMan->AddPage(wxT("First Page")); | |
980 | page = pgMan->GetLastPage(); | |
981 | ||
982 | page->Append( new wxPropertyCategory(wxT("Category A1")) ); | |
983 | ||
984 | page->Append( new wxIntProperty(wxT("Number"),wxPG_LABEL,1) ); | |
985 | ||
986 | page->Append( new wxColourProperty(wxT("Colour"),wxPG_LABEL,*wxWHITE) ); | |
987 | ||
988 | pgMan->AddPage(wxT("Second Page")); | |
989 | page = pgMan->GetLastPage(); | |
990 | ||
991 | page->Append( wxT("Text"),wxPG_LABEL,wxT("(no text)") ); | |
992 | ||
993 | page->Append( new wxFontProperty(wxT("Font"),wxPG_LABEL) ); | |
994 | ||
995 | @endcode | |
996 | ||
997 | @subsection propgrid_propgridpage wxPropertyGridPage | |
998 | ||
999 | wxPropertyGridPage is holder of properties for one page in manager. It is derived from | |
1000 | wxEvtHandler, so you can subclass it to process page-specific property grid events. Hand | |
1001 | over your page instance in wxPropertyGridManager::AddPage. | |
1002 | ||
1003 | Please note that the wxPropertyGridPage itself only sports subset of wxPropertyGrid API | |
1004 | (but unlike manager, this include item iteration). Naturally it inherits from | |
1005 | wxPropertyGridMethods and wxPropertyGridPageState. | |
1006 | ||
1007 | ||
1008 | @section propgrid_subclassing Subclassing wxPropertyGrid and wxPropertyGridManager | |
1009 | ||
1010 | Few things to note: | |
1011 | ||
1012 | - Only a small percentage of member functions are virtual. If you need more, | |
1013 | just e-mail to wx-dev mailing list. | |
1014 | ||
1015 | - Data manipulation is done in wxPropertyGridPageState class. So, instead of | |
1016 | overriding wxPropertyGrid::Insert, you'll probably want to override wxPropertyGridPageState::DoInsert. | |
1017 | ||
1018 | - Override wxPropertyGrid::CreateState to instantiate your derivate wxPropertyGridPageState. | |
1019 | For wxPropertyGridManager, you'll need to subclass wxPropertyGridPage instead (since it | |
1020 | is derived from wxPropertyGridPageState), and hand over instances in wxPropertyGridManager::AddPage | |
1021 | calls. | |
1022 | ||
1023 | - You can use a derivate wxPropertyGrid with manager by overriding wxPropertyGridManager::CreatePropertyGrid | |
1024 | member function. | |
1025 | ||
1026 | ||
1027 | @section propgrid_misc Miscellaneous Topics | |
1028 | ||
1029 | @subsection propgrid_namescope Property Name Scope | |
1030 | ||
1031 | All properties which parent is category or root can be accessed | |
1032 | directly by their base name (ie. name given for property in its constructor). | |
1033 | Other properties can be accessed via "ParentsName.BaseName" notation, | |
1034 | Naturally, all property names should be unique. | |
1035 | ||
1036 | @subsection propgrid_nonuniquelabels Non-unique Labels | |
1037 | ||
1038 | It is possible to have properties with identical label under same parent. | |
1039 | However, care must be taken to ensure that each property still has | |
1040 | unique (base) name. | |
1041 | ||
1042 | @subsection propgrid_boolproperty wxBoolProperty | |
1043 | ||
1044 | There are few points about wxBoolProperty that require futher discussion: | |
1045 | - wxBoolProperty can be shown as either normal combobox or as a checkbox. | |
1046 | Property attribute wxPG_BOOL_USE_CHECKBOX is used to change this. | |
1047 | For example, if you have a wxFlagsProperty, you can | |
1048 | set its all items to use check box using the following: | |
1049 | @code | |
1050 | pg->SetPropertyAttribute(wxT("MyFlagsProperty"),wxPG_BOOL_USE_CHECKBOX,true,wxPG_RECURSE); | |
1051 | @endcode | |
1052 | ||
1053 | - Default item names for wxBoolProperty are [wxT("False"),wxT("True")]. This can be | |
1054 | changed using wxPropertyGrid::SetBoolChoices(trueChoice,falseChoice). | |
1055 | ||
1056 | @subsection propgrid_textctrlupdates Updates from wxTextCtrl Based Editor | |
1057 | ||
1058 | Changes from wxTextCtrl based property editors are committed (ie. | |
1059 | wxEVT_PG_CHANGED is sent etc.) *only* when (1) user presser enter, (2) | |
1060 | user moves to edit another property, or (3) when focus leaves | |
1061 | the grid. | |
1062 | ||
1063 | Because of this, you may find it useful, in some apps, to call | |
1064 | wxPropertyGrid::CommitChangesFromEditor() just before you need to do any | |
1065 | computations based on property grid values. Note that CommitChangesFromEditor() | |
1066 | will dispatch wxEVT_PG_CHANGED with ProcessEvent, so any of your event handlers | |
1067 | will be called immediately. | |
1068 | ||
1069 | @subsection propgrid_splittercentering Centering the Splitter | |
1070 | ||
1071 | If you need to center the splitter, but only once when the program starts, | |
1072 | then do <b>not</b> use the wxPG_SPLITTER_AUTO_CENTER window style, but the | |
1073 | wxPropertyGrid::CenterSplitter() method. <b>However, be sure to call it after | |
1074 | the sizer setup and SetSize calls!</b> (ie. usually at the end of the | |
1075 | frame/dialog constructor) | |
1076 | ||
1077 | @subsection propgrid_splittersetting Setting Splitter Position When Creating Property Grid | |
1078 | ||
1079 | Splitter position cannot exceed grid size, and therefore setting it during | |
1080 | form creation may fail as initial grid size is often smaller than desired | |
1081 | splitter position, especially when sizers are being used. | |
1082 | ||
1083 | @subsection propgrid_colourproperty wxColourProperty and wxSystemColourProperty | |
1084 | ||
1085 | Through subclassing, these two property classes provide substantial customization | |
1086 | features. Subclass wxSystemColourProperty if you want to use wxColourPropertyValue | |
1087 | (which features colour type in addition to wxColour), and wxColourProperty if plain | |
1088 | wxColour is enough. | |
1089 | ||
1090 | Override wxSystemColourProperty::ColourToString() to redefine how colours are | |
1091 | printed as strings. | |
1092 | ||
1093 | Override wxSystemColourProperty::GetCustomColourIndex() to redefine location of | |
1094 | the item that triggers colour picker dialog (default is last). | |
1095 | ||
1096 | Override wxSystemColourProperty::GetColour() to determine which colour matches | |
1097 | which choice entry. | |
1098 | ||
1099 | @section propgrid_proplist Property Class Descriptions | |
1100 | ||
1101 | See @ref pgproperty_properties | |
1102 | ||
1103 | */ | |
1104 |