]> git.saurik.com Git - wxWidgets.git/blob - docs/doxygen/overviews/propgrid.h
Replaced @link with @ref
[wxWidgets.git] / docs / doxygen / overviews / propgrid.h
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, see @ref propgrid_window_styles)
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 @ref propgrid_iterator_flags. GetIterator() also accepts other arguments.
551 See wxPropertyGridInterface::GetIterator() for details.
552
553 This example reverse-iterates through all visible items:
554
555 @code
556
557 wxPropertyGridIterator it;
558
559 for ( it = pg->GetIterator(wxPG_ITERATE_VISIBLE, wxBOTTOM);
560 !it.AtEnd();
561 it-- )
562 {
563 wxPGProperty* p = *it;
564 // Do something with the property
565 }
566
567 @endcode
568
569 <b>wxPython Note:</b> Instead of ++ operator, use Next() method, and instead of
570 * operator, use GetProperty() method.
571
572 GetIterator() only works with wxPropertyGrid and the individual pages
573 of wxPropertyGridManager. In order to iterate through an arbitrary
574 property container, you need to use wxPropertyGridInterface::GetVIterator().
575 Note however that this virtual iterater is limited to forward iteration.
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
591
592 @section propgrid_operations More About Operating with Properties
593
594 Getting value of selected wxSystemColourProperty (which value type is derived
595 from wxObject):
596
597 @code
598
599 wxPGId id = pg->GetSelection();
600
601 if ( id )
602 {
603 // Get name of property
604 const wxString& name = pg->GetPropertyName( id );
605
606 // If type is not correct, GetColour() method will produce run-time error
607 if ( pg->GetPropertyValueType() == wxT("wxColourPropertyValue") ) )
608 {
609 wxColourPropertyValue* pcolval =
610 wxDynamicCast(pg->GetPropertyValueAsWxObjectPtr(id),
611 wxColourPropertyValue);
612
613 // Report value
614 wxString text;
615 if ( pcolval->m_type == wxPG_CUSTOM_COLOUR )
616 text.Printf( wxT("It is custom colour: (%i,%i,%i)"),
617 (int)pcolval->m_colour.Red(),
618 (int)pcolval->m_colour.Green(),
619 (int)pcolval->m_colour.Blue());
620 else
621 text.Printf( wxT("It is wx system colour (number=%i): (%i,%i,%i)"),
622 (int)pcolval->m_type,
623 (int)pcolval->m_colour.Red(),
624 (int)pcolval->m_colour.Green(),
625 (int)pcolval->m_colour.Blue());
626
627 wxMessageBox( text );
628 }
629 }
630
631 @endcode
632
633 @section propgrid_populating Populating wxPropertyGrid Automatically
634
635 @subsection propgrid_fromvariants Populating from List of wxVariants
636
637 Example of populating an empty wxPropertyGrid from a values stored
638 in an arbitrary list of wxVariants.
639
640 @code
641
642 // This is a static method that initializes *all* builtin type handlers
643 // available, including those for wxColour and wxFont. Refers to *all*
644 // included properties, so when compiling with static library, this
645 // method may increase the executable size significantly.
646 pg->InitAllTypeHandlers();
647
648 // Get contents of the grid as a wxVariant list
649 wxVariant all_values = pg->GetPropertyValues();
650
651 // Populate the list with values. If a property with appropriate
652 // name is not found, it is created according to the type of variant.
653 pg->SetPropertyValues( my_list_variant );
654
655 // In order to get wxObject ptr from a variant value,
656 // wxGetVariantCast(VARIANT,CLASSNAME) macro has to be called.
657 // Like this:
658 wxVariant v_txcol = pg->GetPropertyValue(wxT("Text Colour"));
659 const wxColour& txcol = wxGetVariantCast(v_txcol,wxColour);
660
661 @endcode
662
663 @subsection propgrid_fromfile Loading Population from a Text-based Storage
664
665 Class wxPropertyGridPopulator may be helpful when writing code that
666 loads properties from a text-source. In fact, the supplied xrc handler
667 (src/xh_propgrid.cpp) uses it. See that code for more info.
668 NOTE: src/xh_propgrid.cpp is not included in the library by default,
669 to avoid dependency to wxXRC. You will need to add it to your application
670 separately.
671
672 @subsection propgrid_editablestate Saving and Restoring User-Editable State
673
674 You can use wxPGEditableState and wxPGMEditableState classes, and
675 wxPropertyGrid::SaveEditableState() and wxPropertyGrid::RestoreEditableState()
676 to save and restore user-editable state (selected property, expanded/
677 collapsed properties, and scrolled position). For convience with
678 program configuration, wxPGEditableState has functions to save/load
679 its value in wxString. For instance:
680
681 @code
682 // Save state into config
683 wxPGEditableState edState;
684 pg->SaveEditableState(&edState);
685 programConfig->Store(wxT("PropertyGridState"), edState.GetAsString());
686
687 // Restore state from config
688 wxPGEditableState edState;
689 edState.SetFromString(programConfig->Load(wxT("PropertyGridState")));
690 pg->RestoreEditableState(edState);
691 @endcode
692
693
694 @section propgrid_events Event Handling
695
696 Probably the most important event is the Changed event which occurs when
697 value of any property is changed by the user. Use EVT_PG_CHANGED(id,func)
698 in your event table to use it.
699
700 For complete list of event types, see wxPropertyGrid class reference.
701
702 The custom event class, wxPropertyGridEvent, has methods to directly
703 access the property that triggered the event.
704
705 Here's a small sample:
706
707 @code
708
709 // Portion of an imaginary event table
710 BEGIN_EVENT_TABLE(MyForm, wxFrame)
711
712 ...
713
714 // This occurs when a property value changes
715 EVT_PG_CHANGED( PGID, MyForm::OnPropertyGridChange )
716
717 ...
718
719 END_EVENT_TABLE()
720
721 void MyForm::OnPropertyGridChange( wxPropertyGridEvent& event )
722 {
723 wxPGProperty *property = event.GetProperty();
724
725 // It may be NULL
726 if ( !property )
727 return;
728
729 // Get name of changed property
730 const wxString& name = property->GetName();
731
732 // Get resulting value
733 wxVariant value = property->GetValue();
734 }
735
736 @endcode
737
738 Another event type you might find useful is EVT_PG_CHANGING, which occurs
739 just prior property value is being changed by user. You can acquire pending
740 value using wxPropertyGridEvent::GetValue(), and if it is not acceptable,
741 call wxPropertyGridEvent::Veto() to prevent the value change from taking
742 place.
743
744 @code
745
746 // Portion of an imaginary event table
747 BEGIN_EVENT_TABLE(MyForm, wxFrame)
748
749 ...
750
751 // This occurs when a property value changes
752 EVT_PG_CHANGING( PGID, MyForm::OnPropertyGridChanging )
753
754 ...
755
756 END_EVENT_TABLE()
757
758 void MyForm::OnPropertyGridChanging( wxPropertyGridEvent& event )
759 {
760 wxPGProperty* property = event.GetProperty();
761
762 if ( property == m_pWatchThisProperty )
763 {
764 // GetValue() returns the pending value, but is only
765 // supported by wxEVT_PG_CHANGING.
766 if ( event.GetValue().GetString() == g_pThisTextIsNotAllowed )
767 {
768 event.Veto();
769 return;
770 }
771 }
772 }
773
774 @endcode
775
776 @remarks On Sub-property Event Handling
777 - For aggregate type properties (wxFontProperty, wxFlagsProperty, etc), events
778 occur for the main parent property only. For other properties events occur
779 for the children themselves..
780
781 - When property's child gets changed, you can use wxPropertyGridEvent::GetMainParent
782 to obtain its topmost non-category parent (useful, if you have deeply nested
783 properties).
784
785
786 @section propgrid_validating Validating Property Values
787
788 There are various ways to make sure user enters only correct values. First, you
789 can use wxValidators similar to as you would with ordinary controls. Use
790 wxPropertyGridInterface::SetPropertyValidator() to assign wxValidator to
791 property.
792
793 Second, you can subclass a property and override wxPGProperty::ValidateValue(),
794 or handle wxEVT_PG_CHANGING for the same effect. Both of these methods do not
795 actually prevent user from temporarily entering invalid text, but they do give
796 you an opportunity to warn the user and block changed value from being committed
797 in a property.
798
799 Various validation failure options can be controlled globally with
800 wxPropertyGrid::SetValidationFailureBehavior(), or on an event basis by
801 calling wxEvent::SetValidationFailureBehavior(). Here's a code snippet of
802 how to handle wxEVT_PG_CHANGING, and to set custom failure behaviour and
803 message.
804
805 @code
806 void MyFrame::OnPropertyGridChanging(wxPropertyGridEvent& event)
807 {
808 wxPGProperty* property = event.GetProperty();
809
810 // You must use wxPropertyGridEvent::GetValue() to access
811 // the value to be validated.
812 wxVariant pendingValue = event.GetValue();
813
814 if ( property->GetName() == wxT("Font") )
815 {
816 // Make sure value is not unspecified
817 if ( !pendingValue.IsNull() )
818 {
819 wxFont font << pendingValue;
820
821 // Let's just allow Arial font
822 if ( font.GetFaceName() != wxT("Arial") )
823 {
824 event.Veto();
825 event.SetValidationFailureBehavior(wxPG_VFB_STAY_IN_PROPERTY |
826 wxPG_VFB_BEEP |
827 wxPG_VFB_SHOW_MESSAGE);
828 }
829 }
830 }
831 }
832 @endcode
833
834
835 @section propgrid_cellrender Customizing Individual Cell Appearance
836
837 You can control text colour, background colour, and attached image of
838 each cell in the property grid. Use wxPropertyGridInterface::SetPropertyCell() or
839 wxPGProperty::SetCell() for this purpose.
840
841 In addition, it is possible to control these characteristics for
842 wxPGChoices list items. See wxPGChoices::Item() and wxPGChoiceEntry class
843 reference for more info.
844
845
846 @section propgrid_customizing Customizing Properties (without sub-classing)
847
848 In this section are presented miscellaneous ways to have custom appearance
849 and behavior for your properties without all the necessary hassle
850 of sub-classing a property class etc.
851
852 @subsection propgrid_customimage Setting Value Image
853
854 Every property can have a small value image placed in front of the
855 actual value text. Built-in example of this can be seen with
856 wxColourProperty and wxImageFileProperty, but for others it can
857 be set using wxPropertyGrid::SetPropertyImage method.
858
859 @subsection propgrid_customvalidator Setting Validator
860
861 You can set wxValidator for a property using wxPropertyGrid::SetPropertyValidator.
862
863 Validator will work just like in wxWidgets (ie. editorControl->SetValidator(validator)
864 is called).
865
866 @subsection propgrid_customeditor Setting Property's Editor Control(s)
867
868 You can set editor control (or controls, in case of a control and button),
869 of any property using wxPropertyGrid::SetPropertyEditor. Editors are passed
870 using wxPG_EDITOR(EditorName) macro, and valid built-in EditorNames are
871 TextCtrl, Choice, ComboBox, CheckBox, TextCtrlAndButton, ChoiceAndButton,
872 SpinCtrl, and DatePickerCtrl. Two last mentioned ones require call to
873 static member function wxPropertyGrid::RegisterAdditionalEditors().
874
875 Following example changes wxColourProperty's editor from default Choice
876 to TextCtrlAndButton. wxColourProperty has its internal event handling set
877 up so that button click events of the button will be used to trigger
878 colour selection dialog.
879
880 @code
881
882 wxPGId colProp = pg->Append(wxColourProperty(wxT("Text Colour")));
883
884 pg->SetPropertyEditor(colProp,wxPG_EDITOR(TextCtrlAndButton));
885
886 @endcode
887
888 Naturally, creating and setting custom editor classes is a possibility as
889 well. For more information, see wxPGEditor class reference.
890
891 @subsection propgrid_editorattrs Property Attributes Recognized by Editors
892
893 <b>SpinCtrl</b> editor can make use of property's "Min", "Max", "Step" and "Wrap" attributes.
894
895 @subsection propgrid_multiplebuttons Adding Multiple Buttons Next to an Editor
896
897 See wxPGMultiButton class reference.
898
899 @subsection propgrid_customeventhandling Handling Events Passed from Properties
900
901 <b>wxEVT_COMMAND_BUTTON_CLICKED </b>(corresponds to event table macro EVT_BUTTON):
902 Occurs when editor button click is not handled by the property itself
903 (as is the case, for example, if you set property's editor to TextCtrlAndButton
904 from the original TextCtrl).
905
906 @subsection propgrid_attributes Property Attributes
907
908 Miscellaneous values, often specific to a property type, can be set
909 using wxPropertyGrid::SetPropertyAttribute and wxPropertyGrid::SetPropertyAttributeAll
910 methods.
911
912 Attribute names are strings and values wxVariant. Arbitrary names are allowed
913 inorder to store user values. Constant equivalents of all attribute string names are
914 provided. Some of them are defined as cached strings, so using constants can provide
915 for smaller binary size.
916
917 For complete list of attributes, see @ref propgrid_property_attributes.
918
919 @subsection propgrid_boolcheckbox Setting wxBoolProperties to Use Check Box
920
921 To have all wxBoolProperties to use CheckBox editor instead of Choice, use
922 following (call after bool properties have been added):
923
924 @code
925 pg->SetPropertyAttributeAll(wxPG_BOOL_USE_CHECKBOX,true);
926 @endcode
927
928
929 @section propgrid_usage2 Using wxPropertyGridManager
930
931 wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid,
932 which can optionally have toolbar for mode and page selection, and a help text
933 box.
934
935 wxPropertyGridManager inherits from wxPropertyGridInterface, and as such
936 it has most property manipulation functions. However, only some of them affect
937 properties on all pages (eg. GetPropertyByName() and ExpandAll()), while some
938 (eg. Append()) only apply to the currently selected page.
939
940 To operate explicitly on properties on specific page, use wxPropertyGridManager::GetPage()
941 to obtain pointer to page's wxPropertyGridPage object.
942
943 Visual methods, such as SetCellBackgroundColour and GetNextVisible are only
944 available in wxPropertyGrid. Use wxPropertyGridManager::GetGrid() to obtain
945 pointer to it.
946
947 Iteration methods will not work in wxPropertyGridManager. Instead, you must acquire
948 the internal grid (GetGrid()) or wxPropertyGridPage object (GetPage()).
949
950 wxPropertyGridManager constructor has exact same format as wxPropertyGrid
951 constructor, and basicly accepts same extra window style flags (albeit also
952 has some extra ones).
953
954 Here's some example code for creating and populating a wxPropertyGridManager:
955
956 @code
957
958 wxPropertyGridManager* pgMan = new wxPropertyGridManager(this, PGID,
959 wxDefaultPosition, wxDefaultSize,
960 // These and other similar styles are automatically
961 // passed to the embedded wxPropertyGrid.
962 wxPG_BOLD_MODIFIED|wxPG_SPLITTER_AUTO_CENTER|
963 // Include toolbar.
964 wxPG_TOOLBAR |
965 // Include description box.
966 wxPG_DESCRIPTION |
967 // Include compactor.
968 wxPG_COMPACTOR |
969 // Plus defaults.
970 wxPGMAN_DEFAULT_STYLE
971 );
972
973 wxPropertyGridPage* page;
974
975 // Adding a page sets target page to the one added, so
976 // we don't have to call SetTargetPage if we are filling
977 // it right after adding.
978 pgMan->AddPage(wxT("First Page"));
979 page = pgMan->GetLastPage();
980
981 page->Append( new wxPropertyCategory(wxT("Category A1")) );
982
983 page->Append( new wxIntProperty(wxT("Number"),wxPG_LABEL,1) );
984
985 page->Append( new wxColourProperty(wxT("Colour"),wxPG_LABEL,*wxWHITE) );
986
987 pgMan->AddPage(wxT("Second Page"));
988 page = pgMan->GetLastPage();
989
990 page->Append( wxT("Text"),wxPG_LABEL,wxT("(no text)") );
991
992 page->Append( new wxFontProperty(wxT("Font"),wxPG_LABEL) );
993
994 @endcode
995
996 @subsection propgrid_propgridpage wxPropertyGridPage
997
998 wxPropertyGridPage is holder of properties for one page in manager. It is derived from
999 wxEvtHandler, so you can subclass it to process page-specific property grid events. Hand
1000 over your page instance in wxPropertyGridManager::AddPage.
1001
1002 Please note that the wxPropertyGridPage itself only sports subset of wxPropertyGrid API
1003 (but unlike manager, this include item iteration). Naturally it inherits from
1004 wxPropertyGridMethods and wxPropertyGridPageState.
1005
1006
1007 @section propgrid_subclassing Subclassing wxPropertyGrid and wxPropertyGridManager
1008
1009 Few things to note:
1010
1011 - Only a small percentage of member functions are virtual. If you need more,
1012 just e-mail to wx-dev mailing list.
1013
1014 - Data manipulation is done in wxPropertyGridPageState class. So, instead of
1015 overriding wxPropertyGrid::Insert, you'll probably want to override wxPropertyGridPageState::DoInsert.
1016
1017 - Override wxPropertyGrid::CreateState to instantiate your derivate wxPropertyGridPageState.
1018 For wxPropertyGridManager, you'll need to subclass wxPropertyGridPage instead (since it
1019 is derived from wxPropertyGridPageState), and hand over instances in wxPropertyGridManager::AddPage
1020 calls.
1021
1022 - You can use a derivate wxPropertyGrid with manager by overriding wxPropertyGridManager::CreatePropertyGrid
1023 member function.
1024
1025
1026 @section propgrid_misc Miscellaneous Topics
1027
1028 @subsection propgrid_namescope Property Name Scope
1029
1030 All properties which parent is category or root can be accessed
1031 directly by their base name (ie. name given for property in its constructor).
1032 Other properties can be accessed via "ParentsName.BaseName" notation,
1033 Naturally, all property names should be unique.
1034
1035 @subsection propgrid_nonuniquelabels Non-unique Labels
1036
1037 It is possible to have properties with identical label under same parent.
1038 However, care must be taken to ensure that each property still has
1039 unique (base) name.
1040
1041 @subsection propgrid_boolproperty wxBoolProperty
1042
1043 There are few points about wxBoolProperty that require futher discussion:
1044 - wxBoolProperty can be shown as either normal combobox or as a checkbox.
1045 Property attribute wxPG_BOOL_USE_CHECKBOX is used to change this.
1046 For example, if you have a wxFlagsProperty, you can
1047 set its all items to use check box using the following:
1048 @code
1049 pg->SetPropertyAttribute(wxT("MyFlagsProperty"),wxPG_BOOL_USE_CHECKBOX,true,wxPG_RECURSE);
1050 @endcode
1051
1052 - Default item names for wxBoolProperty are [wxT("False"),wxT("True")]. This can be
1053 changed using wxPropertyGrid::SetBoolChoices(trueChoice,falseChoice).
1054
1055 @subsection propgrid_textctrlupdates Updates from wxTextCtrl Based Editor
1056
1057 Changes from wxTextCtrl based property editors are committed (ie.
1058 wxEVT_PG_CHANGED is sent etc.) *only* when (1) user presser enter, (2)
1059 user moves to edit another property, or (3) when focus leaves
1060 the grid.
1061
1062 Because of this, you may find it useful, in some apps, to call
1063 wxPropertyGrid::CommitChangesFromEditor() just before you need to do any
1064 computations based on property grid values. Note that CommitChangesFromEditor()
1065 will dispatch wxEVT_PG_CHANGED with ProcessEvent, so any of your event handlers
1066 will be called immediately.
1067
1068 @subsection propgrid_splittercentering Centering the Splitter
1069
1070 If you need to center the splitter, but only once when the program starts,
1071 then do <b>not</b> use the wxPG_SPLITTER_AUTO_CENTER window style, but the
1072 wxPropertyGrid::CenterSplitter() method. <b>However, be sure to call it after
1073 the sizer setup and SetSize calls!</b> (ie. usually at the end of the
1074 frame/dialog constructor)
1075
1076 @subsection propgrid_splittersetting Setting Splitter Position When Creating Property Grid
1077
1078 Splitter position cannot exceed grid size, and therefore setting it during
1079 form creation may fail as initial grid size is often smaller than desired
1080 splitter position, especially when sizers are being used.
1081
1082 @subsection propgrid_colourproperty wxColourProperty and wxSystemColourProperty
1083
1084 Through subclassing, these two property classes provide substantial customization
1085 features. Subclass wxSystemColourProperty if you want to use wxColourPropertyValue
1086 (which features colour type in addition to wxColour), and wxColourProperty if plain
1087 wxColour is enough.
1088
1089 Override wxSystemColourProperty::ColourToString() to redefine how colours are
1090 printed as strings.
1091
1092 Override wxSystemColourProperty::GetCustomColourIndex() to redefine location of
1093 the item that triggers colour picker dialog (default is last).
1094
1095 Override wxSystemColourProperty::GetColour() to determine which colour matches
1096 which choice entry.
1097
1098 @section propgrid_proplist Property Class Descriptions
1099
1100 See @ref pgproperty_properties
1101
1102 */
1103