Added label editing capability into wxPropertyGrid
[wxWidgets.git] / include / wx / propgrid / propgridpagestate.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/propgrid/propgridpagestate.h
3 // Purpose: wxPropertyGridPageState class
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: 2008-08-24
7 // RCS-ID: $Id$
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_PROPGRID_PROPGRIDPAGESTATE_H_
13 #define _WX_PROPGRID_PROPGRIDPAGESTATE_H_
14
15 #if wxUSE_PROPGRID
16
17 #include "wx/propgrid/property.h"
18
19 // -----------------------------------------------------------------------
20
21 /** @section propgrid_hittestresult wxPropertyGridHitTestResult
22
23 A return value from wxPropertyGrid::HitTest(),
24 contains all you need to know about an arbitrary location on the grid.
25 */
26 struct WXDLLIMPEXP_PROPGRID wxPropertyGridHitTestResult
27 {
28 friend class wxPropertyGridPageState;
29 public:
30
31 wxPGProperty* GetProperty() const { return property; }
32
33 /** Column. -1 for margin. */
34 int column;
35
36 /** Index of splitter hit, -1 for none. */
37 int splitter;
38
39 /** If splitter hit, offset to that */
40 int splitterHitOffset;
41
42 private:
43 /** Property. NULL if empty space below properties was hit */
44 wxPGProperty* property;
45 };
46
47 // -----------------------------------------------------------------------
48
49 #define wxPG_IT_CHILDREN(A) ((A)<<16)
50
51 /** @section propgrid_iterator_flags wxPropertyGridIterator Flags
52 @{
53
54 NOTES: At lower 16-bits, there are flags to check if item will be included.
55 At higher 16-bits, there are same flags, but to instead check if children
56 will be included.
57 */
58
59 enum wxPG_ITERATOR_FLAGS
60 {
61
62 /**
63 Iterate through 'normal' property items (does not include children of
64 aggregate or hidden items by default).
65 */
66 wxPG_ITERATE_PROPERTIES = wxPG_PROP_PROPERTY |
67 wxPG_PROP_MISC_PARENT |
68 wxPG_PROP_AGGREGATE |
69 wxPG_PROP_COLLAPSED |
70 wxPG_IT_CHILDREN(wxPG_PROP_MISC_PARENT) |
71 wxPG_IT_CHILDREN(wxPG_PROP_CATEGORY),
72
73 /** Iterate children of collapsed parents, and individual items that are hidden.
74 */
75 wxPG_ITERATE_HIDDEN = wxPG_PROP_HIDDEN |
76 wxPG_IT_CHILDREN(wxPG_PROP_COLLAPSED),
77
78 /**
79 Iterate children of parent that is an aggregate property (ie has fixed
80 children).
81 */
82 wxPG_ITERATE_FIXED_CHILDREN = wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE) |
83 wxPG_ITERATE_PROPERTIES,
84
85 /** Iterate categories.
86 Note that even without this flag, children of categories are still iterated
87 through.
88 */
89 wxPG_ITERATE_CATEGORIES = wxPG_PROP_CATEGORY |
90 wxPG_IT_CHILDREN(wxPG_PROP_CATEGORY) |
91 wxPG_PROP_COLLAPSED,
92
93 wxPG_ITERATE_ALL_PARENTS = wxPG_PROP_MISC_PARENT |
94 wxPG_PROP_AGGREGATE |
95 wxPG_PROP_CATEGORY,
96
97 wxPG_ITERATE_ALL_PARENTS_RECURSIVELY = wxPG_ITERATE_ALL_PARENTS |
98 wxPG_IT_CHILDREN(
99 wxPG_ITERATE_ALL_PARENTS),
100
101 wxPG_ITERATOR_FLAGS_ALL = wxPG_PROP_PROPERTY |
102 wxPG_PROP_MISC_PARENT |
103 wxPG_PROP_AGGREGATE |
104 wxPG_PROP_HIDDEN |
105 wxPG_PROP_CATEGORY |
106 wxPG_PROP_COLLAPSED,
107
108 wxPG_ITERATOR_MASK_OP_ITEM = wxPG_ITERATOR_FLAGS_ALL,
109
110 // (wxPG_PROP_MISC_PARENT|wxPG_PROP_AGGREGATE|wxPG_PROP_CATEGORY)
111 wxPG_ITERATOR_MASK_OP_PARENT = wxPG_ITERATOR_FLAGS_ALL,
112
113 /** Combines all flags needed to iterate through visible properties
114 (ie hidden properties and children of collapsed parents are skipped).
115 */
116 wxPG_ITERATE_VISIBLE = wxPG_ITERATE_PROPERTIES |
117 wxPG_PROP_CATEGORY |
118 wxPG_IT_CHILDREN(wxPG_PROP_AGGREGATE),
119
120 /** Iterate all items.
121 */
122 wxPG_ITERATE_ALL = wxPG_ITERATE_VISIBLE |
123 wxPG_ITERATE_HIDDEN,
124
125 /** Iterate through individual properties (ie categories and children of
126 aggregate properties are skipped).
127 */
128 wxPG_ITERATE_NORMAL = wxPG_ITERATE_PROPERTIES |
129 wxPG_ITERATE_HIDDEN,
130
131 /** Default iterator flags.
132 */
133 wxPG_ITERATE_DEFAULT = wxPG_ITERATE_NORMAL
134
135 };
136
137 /** @}
138 */
139
140
141 #define wxPG_ITERATOR_CREATE_MASKS(FLAGS, A, B) \
142 A = (FLAGS ^ wxPG_ITERATOR_MASK_OP_ITEM) & \
143 wxPG_ITERATOR_MASK_OP_ITEM & 0xFFFF; \
144 B = ((FLAGS>>16) ^ wxPG_ITERATOR_MASK_OP_PARENT) & \
145 wxPG_ITERATOR_MASK_OP_PARENT & 0xFFFF;
146
147
148 // Macro to test if children of PWC should be iterated through
149 #define wxPG_ITERATOR_PARENTEXMASK_TEST(PWC, PARENTMASK) \
150 ( \
151 !(PWC->GetFlags() & PARENTMASK) && \
152 PWC->GetChildCount() \
153 )
154
155
156 // Base for wxPropertyGridIterator classes.
157 class WXDLLIMPEXP_PROPGRID wxPropertyGridIteratorBase
158 {
159 public:
160 wxPropertyGridIteratorBase()
161 {
162 }
163
164 void Assign( const wxPropertyGridIteratorBase& it );
165
166 bool AtEnd() const { return m_property == NULL; }
167
168 /** Get current property.
169 */
170 wxPGProperty* GetProperty() const { return m_property; }
171
172 void Init( wxPropertyGridPageState* state,
173 int flags,
174 wxPGProperty* property,
175 int dir = 1 );
176
177 void Init( wxPropertyGridPageState* state,
178 int flags,
179 int startPos = wxTOP,
180 int dir = 0 );
181
182 /** Iterate to the next property.
183 */
184 void Next( bool iterateChildren = true );
185
186 /** Iterate to the previous property.
187 */
188 void Prev();
189
190 /**
191 Set base parent, ie a property when, in which iteration returns, it
192 ends.
193
194 Default base parent is the root of the used wxPropertyGridPageState.
195 */
196 void SetBaseParent( wxPGProperty* baseParent )
197 { m_baseParent = baseParent; }
198
199 protected:
200
201 wxPGProperty* m_property;
202
203 private:
204 wxPropertyGridPageState* m_state;
205 wxPGProperty* m_baseParent;
206
207 // Masks are used to quickly exclude items
208 int m_itemExMask;
209 int m_parentExMask;
210 };
211
212
213 #define wxPG_IMPLEMENT_ITERATOR(CLASS, PROPERTY, STATE) \
214 CLASS( STATE* state, int flags = wxPG_ITERATE_DEFAULT, \
215 PROPERTY* property = NULL, int dir = 1 ) \
216 : wxPropertyGridIteratorBase() \
217 { Init( (wxPropertyGridPageState*)state, flags, \
218 (wxPGProperty*)property, dir ); } \
219 CLASS( STATE* state, int flags, int startPos, int dir = 0 ) \
220 : wxPropertyGridIteratorBase() \
221 { Init( (wxPropertyGridPageState*)state, flags, startPos, dir ); } \
222 CLASS() \
223 : wxPropertyGridIteratorBase() \
224 { \
225 m_property = NULL; \
226 } \
227 CLASS( const CLASS& it ) \
228 : wxPropertyGridIteratorBase( ) \
229 { \
230 Assign(it); \
231 } \
232 ~CLASS() \
233 { \
234 } \
235 const CLASS& operator=( const CLASS& it ) \
236 { \
237 if (this != &it) \
238 Assign(it); \
239 return *this; \
240 } \
241 CLASS& operator++() { Next(); return *this; } \
242 CLASS operator++(int) { CLASS it=*this;Next();return it; } \
243 CLASS& operator--() { Prev(); return *this; } \
244 CLASS operator--(int) { CLASS it=*this;Prev();return it; } \
245 PROPERTY* operator *() const { return (PROPERTY*)m_property; } \
246 static PROPERTY* OneStep( STATE* state, \
247 int flags = wxPG_ITERATE_DEFAULT, \
248 PROPERTY* property = NULL, \
249 int dir = 1 ) \
250 { \
251 CLASS it( state, flags, property, dir ); \
252 if ( property ) \
253 { \
254 if ( dir == 1 ) it.Next(); \
255 else it.Prev(); \
256 } \
257 return *it; \
258 }
259
260
261 /** @class wxPropertyGridIterator
262
263 Preferable way to iterate through contents of wxPropertyGrid,
264 wxPropertyGridManager, and wxPropertyGridPage.
265
266 See wxPropertyGridInterface::GetIterator() for more information about usage.
267
268 @library{wxpropgrid}
269 @category{propgrid}
270 */
271 class WXDLLIMPEXP_PROPGRID
272 wxPropertyGridIterator : public wxPropertyGridIteratorBase
273 {
274 public:
275
276 wxPG_IMPLEMENT_ITERATOR(wxPropertyGridIterator,
277 wxPGProperty,
278 wxPropertyGridPageState)
279
280 protected:
281 };
282
283
284 // Const version of wxPropertyGridIterator.
285 class WXDLLIMPEXP_PROPGRID
286 wxPropertyGridConstIterator : public wxPropertyGridIteratorBase
287 {
288 public:
289 wxPG_IMPLEMENT_ITERATOR(wxPropertyGridConstIterator,
290 const wxPGProperty,
291 const wxPropertyGridPageState)
292
293 /**
294 Additional copy constructor.
295 */
296 wxPropertyGridConstIterator( const wxPropertyGridIterator& other )
297 {
298 Assign(other);
299 }
300
301 /**
302 Additional assignment operator.
303 */
304 const wxPropertyGridConstIterator& operator=( const wxPropertyGridIterator& it )
305 {
306 Assign(it);
307 return *this;
308 }
309
310 protected:
311 };
312
313 // -----------------------------------------------------------------------
314
315 /** Base class to derive new viterators.
316 */
317 class WXDLLIMPEXP_PROPGRID wxPGVIteratorBase : public wxObjectRefData
318 {
319 friend class wxPGVIterator;
320 public:
321 wxPGVIteratorBase() { }
322 virtual void Next() = 0;
323 protected:
324 virtual ~wxPGVIteratorBase() { }
325
326 wxPropertyGridIterator m_it;
327 };
328
329 /** @class wxPGVIterator
330
331 Abstract implementation of a simple iterator. Can only be used
332 to iterate in forward order, and only through the entire container.
333 Used to have functions dealing with all properties work with both
334 wxPropertyGrid and wxPropertyGridManager.
335 */
336 class WXDLLIMPEXP_PROPGRID wxPGVIterator
337 {
338 public:
339 wxPGVIterator() { m_pIt = NULL; }
340 wxPGVIterator( wxPGVIteratorBase* obj ) { m_pIt = obj; }
341 ~wxPGVIterator() { UnRef(); }
342 void UnRef() { if (m_pIt) m_pIt->DecRef(); }
343 wxPGVIterator( const wxPGVIterator& it )
344 {
345 m_pIt = it.m_pIt;
346 m_pIt->IncRef();
347 }
348 #ifndef SWIG
349 const wxPGVIterator& operator=( const wxPGVIterator& it )
350 {
351 if (this != &it)
352 {
353 UnRef();
354 m_pIt = it.m_pIt;
355 m_pIt->IncRef();
356 }
357 return *this;
358 }
359 #endif
360 void Next() { m_pIt->Next(); }
361 bool AtEnd() const { return m_pIt->m_it.AtEnd(); }
362 wxPGProperty* GetProperty() const { return m_pIt->m_it.GetProperty(); }
363 protected:
364 wxPGVIteratorBase* m_pIt;
365 };
366
367 // -----------------------------------------------------------------------
368
369 #ifndef SWIG
370 // We won't need this class from wxPython
371
372 /** @class wxPropertyGridPageState
373
374 Contains low-level property page information (properties, column widths,
375 etc) of a single wxPropertyGrid or single wxPropertyGridPage. Generally you
376 should not use this class directly, but instead member functions in
377 wxPropertyGridInterface, wxPropertyGrid, wxPropertyGridPage, and
378 wxPropertyGridManager.
379
380 @remarks
381 - In separate wxPropertyGrid component this class was known as
382 wxPropertyGridState.
383 - Currently this class is not implemented in wxPython.
384
385 @library{wxpropgrid}
386 @category{propgrid}
387 */
388 class WXDLLIMPEXP_PROPGRID wxPropertyGridPageState
389 {
390 friend class wxPGProperty;
391 friend class wxPropertyGrid;
392 friend class wxPGCanvas;
393 friend class wxPropertyGridInterface;
394 friend class wxPropertyGridPage;
395 friend class wxPropertyGridManager;
396 public:
397
398 /** Default constructor. */
399 wxPropertyGridPageState();
400
401 /** Destructor. */
402 virtual ~wxPropertyGridPageState();
403
404 /** Makes sure all columns have minimum width.
405 */
406 void CheckColumnWidths( int widthChange = 0 );
407
408 /**
409 Override this member function to add custom behavior on property
410 deletion.
411 */
412 virtual void DoDelete( wxPGProperty* item, bool doDelete = true );
413
414 wxSize DoFitColumns( bool allowGridResize = false );
415
416 wxPGProperty* DoGetItemAtY( int y ) const;
417
418 /**
419 Override this member function to add custom behavior on property
420 insertion.
421 */
422 virtual wxPGProperty* DoInsert( wxPGProperty* parent,
423 int index,
424 wxPGProperty* property );
425
426 /**
427 This needs to be overridden in grid used the manager so that splitter
428 changes can be propagated to other pages.
429 */
430 virtual void DoSetSplitterPosition( int pos,
431 int splitterColumn = 0,
432 bool allPages = false,
433 bool fromAutoCenter = false );
434
435 bool EnableCategories( bool enable );
436
437 /** Make sure virtual height is up-to-date.
438 */
439 void EnsureVirtualHeight()
440 {
441 if ( m_vhCalcPending )
442 {
443 RecalculateVirtualHeight();
444 m_vhCalcPending = 0;
445 }
446 }
447
448 /** Enables or disables given property and its subproperties. */
449 bool DoEnableProperty( wxPGProperty* p, bool enable );
450
451 /** Returns (precalculated) height of contained visible properties.
452 */
453 unsigned int GetVirtualHeight() const
454 {
455 wxASSERT( !m_vhCalcPending );
456 return m_virtualHeight;
457 }
458
459 /** Returns (precalculated) height of contained visible properties.
460 */
461 unsigned int GetVirtualHeight()
462 {
463 EnsureVirtualHeight();
464 return m_virtualHeight;
465 }
466
467 /** Returns actual height of contained visible properties.
468 @remarks
469 Mostly used for internal diagnostic purposes.
470 */
471 inline unsigned int GetActualVirtualHeight() const;
472
473 unsigned int GetColumnCount() const
474 {
475 return (unsigned int) m_colWidths.size();
476 }
477
478 int GetColumnMinWidth( int column ) const;
479
480 int GetColumnWidth( unsigned int column ) const
481 {
482 return m_colWidths[column];
483 }
484
485 wxPropertyGrid* GetGrid() const { return m_pPropGrid; }
486
487 /** Returns last item which could be iterated using given flags.
488 @param flags
489 @link iteratorflags List of iterator flags@endlink
490 */
491 wxPGProperty* GetLastItem( int flags = wxPG_ITERATE_DEFAULT );
492
493 const wxPGProperty* GetLastItem( int flags = wxPG_ITERATE_DEFAULT ) const
494 {
495 return ((wxPropertyGridPageState*)this)->GetLastItem(flags);
496 }
497
498 /**
499 Returns currently selected property.
500 */
501 wxPGProperty* GetSelection() const
502 {
503 if ( m_selection.size() == 0 )
504 return NULL;
505 return m_selection[0];
506 }
507
508 void DoSetSelection( wxPGProperty* prop )
509 {
510 m_selection.clear();
511 if ( prop )
512 m_selection.push_back(prop);
513 }
514
515 bool DoClearSelection()
516 {
517 return DoSelectProperty(NULL);
518 }
519
520 void DoRemoveFromSelection( wxPGProperty* prop );
521
522 wxPropertyCategory* GetPropertyCategory( const wxPGProperty* p ) const;
523
524 wxPGProperty* GetPropertyByLabel( const wxString& name,
525 wxPGProperty* parent = NULL ) const;
526
527 wxVariant DoGetPropertyValues( const wxString& listname,
528 wxPGProperty* baseparent,
529 long flags ) const;
530
531 wxPGProperty* DoGetRoot() const { return m_properties; }
532
533 void DoSetPropertyName( wxPGProperty* p, const wxString& newName );
534
535 // Returns combined width of margin and all the columns
536 int GetVirtualWidth() const
537 {
538 return m_width;
539 }
540
541 /**
542 Returns minimal width for given column so that all images and texts
543 will fit entirely.
544
545 Used by SetSplitterLeft() and DoFitColumns().
546 */
547 int GetColumnFitWidth(wxClientDC& dc,
548 wxPGProperty* pwc,
549 unsigned int col,
550 bool subProps) const;
551
552 /**
553 Returns information about arbitrary position in the grid.
554
555 @param pt
556 Logical coordinates in the virtual grid space. Use
557 wxScrolledWindow::CalcUnscrolledPosition() if you need to
558 translate a scrolled position into a logical one.
559 */
560 wxPropertyGridHitTestResult HitTest( const wxPoint& pt ) const;
561
562 /** Returns true if page is visibly displayed.
563 */
564 inline bool IsDisplayed() const;
565
566 bool IsInNonCatMode() const { return (bool)(m_properties == m_abcArray); }
567
568 void DoLimitPropertyEditing( wxPGProperty* p, bool limit = true )
569 {
570 p->SetFlagRecursively(wxPG_PROP_NOEDITOR, limit);
571 }
572
573 bool DoSelectProperty( wxPGProperty* p, unsigned int flags = 0 );
574
575 /** widthChange is non-client.
576 */
577 void OnClientWidthChange( int newWidth,
578 int widthChange,
579 bool fromOnResize = false );
580
581 /** Recalculates m_virtualHeight.
582 */
583 void RecalculateVirtualHeight()
584 {
585 m_virtualHeight = GetActualVirtualHeight();
586 }
587
588 void SetColumnCount( int colCount );
589
590 void PropagateColSizeDec( int column, int decrease, int dir );
591
592 bool DoHideProperty( wxPGProperty* p, bool hide, int flags = wxPG_RECURSE );
593
594 bool DoSetPropertyValueString( wxPGProperty* p, const wxString& value );
595
596 bool DoSetPropertyValue( wxPGProperty* p, wxVariant& value );
597
598 bool DoSetPropertyValueWxObjectPtr( wxPGProperty* p, wxObject* value );
599 void DoSetPropertyValues( const wxVariantList& list,
600 wxPGProperty* default_category );
601
602 void SetSplitterLeft( bool subProps = false );
603
604 /** Set virtual width for this particular page. */
605 void SetVirtualWidth( int width );
606
607 void DoSortChildren( wxPGProperty* p, int flags = 0 );
608 void DoSort( int flags = 0 );
609
610 bool PrepareAfterItemsAdded();
611
612 /** Called after virtual height needs to be recalculated.
613 */
614 void VirtualHeightChanged()
615 {
616 m_vhCalcPending = 1;
617 }
618
619 /** Base append. */
620 wxPGProperty* DoAppend( wxPGProperty* property );
621
622 /** Returns property by its name. */
623 wxPGProperty* BaseGetPropertyByName( const wxString& name ) const;
624
625 /** Called in, for example, wxPropertyGrid::Clear. */
626 void DoClear();
627
628 bool DoIsPropertySelected( wxPGProperty* prop ) const;
629
630 bool DoCollapse( wxPGProperty* p );
631
632 bool DoExpand( wxPGProperty* p );
633
634 void CalculateFontAndBitmapStuff( int vspacing );
635
636 protected:
637
638 int DoGetSplitterPosition( int splitterIndex = 0 ) const;
639
640 /** Returns column at x coordinate (in GetGrid()->GetPanel()).
641 @param pSplitterHit
642 Give pointer to int that receives index to splitter that is at x.
643 @param pSplitterHitOffset
644 Distance from said splitter.
645 */
646 int HitTestH( int x, int* pSplitterHit, int* pSplitterHitOffset ) const;
647
648 bool PrepareToAddItem( wxPGProperty* property,
649 wxPGProperty* scheduledParent );
650
651 /** If visible, then this is pointer to wxPropertyGrid.
652 This shall *never* be NULL to indicate that this state is not visible.
653 */
654 wxPropertyGrid* m_pPropGrid;
655
656 /** Pointer to currently used array. */
657 wxPGProperty* m_properties;
658
659 /** Array for categoric mode. */
660 wxPGRootProperty m_regularArray;
661
662 /** Array for root of non-categoric mode. */
663 wxPGRootProperty* m_abcArray;
664
665 /** Dictionary for name-based access. */
666 wxPGHashMapS2P m_dictName;
667
668 /** List of column widths (first column does not include margin). */
669 wxArrayInt m_colWidths;
670
671 /** List of indices of columns the user can edit by clicking it. */
672 wxArrayInt m_editableColumns;
673
674 double m_fSplitterX;
675
676 /** Most recently added category. */
677 wxPropertyCategory* m_currentCategory;
678
679 /** Array of selected property. */
680 wxArrayPGProperty m_selection;
681
682 /** Virtual width. */
683 int m_width;
684
685 /** Indicates total virtual height of visible properties. */
686 unsigned int m_virtualHeight;
687
688 /** 1 if m_lastCaption is also the bottommost caption. */
689 unsigned char m_lastCaptionBottomnest;
690
691 /** 1 items appended/inserted, so stuff needs to be done before drawing;
692 If m_virtualHeight == 0, then calcylatey's must be done.
693 Otherwise just sort.
694 */
695 unsigned char m_itemsAdded;
696
697 /** 1 if any value is modified. */
698 unsigned char m_anyModified;
699
700 unsigned char m_vhCalcPending;
701
702 private:
703 /** Only inits arrays, doesn't migrate things or such. */
704 void InitNonCatMode();
705 };
706
707 #endif // #ifndef SWIG
708
709 // -----------------------------------------------------------------------
710
711 #endif // wxUSE_PROPGRID
712
713 #endif // _WX_PROPGRID_PROPGRIDPAGESTATE_H_
714