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