]> git.saurik.com Git - wxWidgets.git/blob - include/wx/propgrid/manager.h
support column reordering using drag and drop when using wxHeaderCtrl
[wxWidgets.git] / include / wx / propgrid / manager.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: wx/propgrid/manager.h
3 // Purpose: wxPropertyGridManager
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: 2005-01-14
7 // RCS-ID: $Id$
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef _WX_PROPGRID_MANAGER_H_
13 #define _WX_PROPGRID_MANAGER_H_
14
15 #if wxUSE_PROPGRID
16
17 #include "wx/propgrid/propgrid.h"
18
19 #include "wx/dcclient.h"
20 #include "wx/scrolwin.h"
21 #include "wx/toolbar.h"
22 #include "wx/stattext.h"
23 #include "wx/button.h"
24 #include "wx/textctrl.h"
25 #include "wx/dialog.h"
26
27 // -----------------------------------------------------------------------
28
29 #ifndef SWIG
30 extern WXDLLIMPEXP_DATA_PROPGRID(const char) wxPropertyGridManagerNameStr[];
31 #endif
32
33 /** @class wxPropertyGridPage
34
35 Holder of property grid page information. You can subclass this and
36 give instance in wxPropertyGridManager::AddPage. It inherits from
37 wxEvtHandler and can be used to process events specific to this
38 page (id of events will still be same as manager's). If you don't
39 want to use it to process all events of the page, you need to
40 return false in the derived wxPropertyGridPage::IsHandlingAllEvents.
41
42 Please note that wxPropertyGridPage lacks many non-const property
43 manipulation functions found in wxPropertyGridManager. Please use
44 parent manager (m_manager member variable) when needed.
45
46 Please note that most member functions are inherited and as such not
47 documented on this page. This means you will probably also want to read
48 wxPropertyGridInterface class reference.
49
50 @section propgridpage_event_handling Event Handling
51
52 wxPropertyGridPage receives events emitted by its wxPropertyGridManager, but
53 only those events that are specific to that page. If
54 wxPropertyGridPage::IsHandlingAllEvents returns false, then unhandled
55 events are sent to the manager's parent, as usual.
56
57 See @ref propgrid_event_handling "wxPropertyGrid Event Handling"
58 for more information.
59
60 @library{wxpropgrid}
61 @category{propgrid}
62 */
63 class WXDLLIMPEXP_PROPGRID wxPropertyGridPage : public wxEvtHandler,
64 public wxPropertyGridInterface,
65 public wxPropertyGridPageState
66 {
67 friend class wxPropertyGridManager;
68 #ifndef SWIG
69 DECLARE_CLASS(wxPropertyGridPage)
70 #endif
71 public:
72
73 wxPropertyGridPage();
74 virtual ~wxPropertyGridPage();
75
76 /** Deletes all properties on page.
77 */
78 virtual void Clear();
79
80 /**
81 Reduces column sizes to minimum possible that contents are still
82 visibly (naturally some margin space will be applied as well).
83
84 @return
85 Minimum size for the page to still display everything.
86
87 @remarks
88 This function only works properly if size of containing grid was
89 already fairly large.
90
91 Note that you can also get calculated column widths by calling
92 GetColumnWidth() immediately after this function returns.
93 */
94 wxSize FitColumns();
95
96 /** Returns page index in manager;
97 */
98 inline int GetIndex() const;
99
100 /** Returns x-coordinate position of splitter on a page.
101 */
102 int GetSplitterPosition( int col = 0 ) const
103 { return GetStatePtr()->DoGetSplitterPosition(col); }
104
105 /** Returns "root property". It does not have name, etc. and it is not
106 visible. It is only useful for accessing its children.
107 */
108 wxPGProperty* GetRoot() const { return GetStatePtr()->DoGetRoot(); }
109
110 /** Return pointer to contained property grid state.
111 */
112 wxPropertyGridPageState* GetStatePtr()
113 {
114 return this;
115 }
116
117 /** Return pointer to contained property grid state.
118 */
119 const wxPropertyGridPageState* GetStatePtr() const
120 {
121 return this;
122 }
123
124 /**
125 Returns id of the tool bar item that represents this page on
126 wxPropertyGridManager's wxToolBar.
127 */
128 int GetToolId() const
129 {
130 return m_id;
131 }
132
133 /** Do any member initialization in this method.
134 @remarks
135 - Called every time the page is added into a manager.
136 - You can add properties to the page here.
137 */
138 virtual void Init() {}
139
140 /** Return false here to indicate unhandled events should be
141 propagated to manager's parent, as normal.
142 */
143 virtual bool IsHandlingAllEvents() const { return true; }
144
145 /** Called every time page is about to be shown.
146 Useful, for instance, creating properties just-in-time.
147 */
148 virtual void OnShow();
149
150 virtual void RefreshProperty( wxPGProperty* p );
151
152 /** Sets splitter position on page.
153 @remarks
154 Splitter position cannot exceed grid size, and therefore setting it
155 during form creation may fail as initial grid size is often smaller
156 than desired splitter position, especially when sizers are being used.
157 */
158 void SetSplitterPosition( int splitterPos, int col = 0 );
159
160 protected:
161
162 /** Propagate to other pages.
163 */
164 virtual void DoSetSplitterPosition( int pos,
165 int splitterColumn = 0,
166 bool allPages = false,
167 bool fromAutoCenter = false );
168
169 /** Page label (may be referred as name in some parts of documentation).
170 Can be set in constructor, or passed in
171 wxPropertyGridManager::AddPage(), but *not* in both.
172 */
173 wxString m_label;
174
175 #ifndef SWIG
176
177 //virtual bool ProcessEvent( wxEvent& event );
178
179 wxPropertyGridManager* m_manager;
180
181 int m_id; // toolbar index
182
183 private:
184 bool m_isDefault; // is this base page object?
185
186 private:
187 DECLARE_EVENT_TABLE()
188 #endif
189 };
190
191 // -----------------------------------------------------------------------
192
193 /** @class wxPropertyGridManager
194
195 wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid,
196 which can optionally have toolbar for mode and page selection, and help
197 text box.
198 Use window flags to select components to include.
199
200 @section propgridmanager_window_styles_ Window Styles
201
202 See @ref propgrid_window_styles.
203
204 @section propgridmanager_event_handling Event Handling
205
206 See @ref propgrid_event_handling "wxPropertyGrid Event Handling"
207 for more information.
208
209 @library{wxpropgrid}
210 @category{propgrid}
211 */
212 class WXDLLIMPEXP_PROPGRID
213 wxPropertyGridManager : public wxPanel, public wxPropertyGridInterface
214 {
215 #ifndef SWIG
216 DECLARE_CLASS(wxPropertyGridManager)
217 #endif
218 friend class wxPropertyGridPage;
219 public:
220
221 #ifdef SWIG
222 %pythonAppend wxPropertyGridManager {
223 self._setOORInfo(self)
224 self.DoDefaultTypeMappings()
225 self.edited_objects = {}
226 self.DoDefaultValueTypeMappings()
227 if not hasattr(self.__class__,'_vt2setter'):
228 self.__class__._vt2setter = {}
229 }
230 %pythonAppend wxPropertyGridManager() ""
231
232 wxPropertyGridManager( wxWindow *parent, wxWindowID id = wxID_ANY,
233 const wxPoint& pos = wxDefaultPosition,
234 const wxSize& size = wxDefaultSize,
235 long style = wxPGMAN_DEFAULT_STYLE,
236 const wxChar* name =
237 wxPyPropertyGridManagerNameStr );
238 %RenameCtor(PrePropertyGridManager, wxPropertyGridManager());
239
240 #else
241
242 /**
243 Two step constructor.
244 Call Create when this constructor is called to build up the
245 wxPropertyGridManager.
246 */
247 wxPropertyGridManager();
248
249 /** The default constructor. The styles to be used are styles valid for
250 the wxWindow.
251 @see @link wndflags Additional Window Styles@endlink
252 */
253 wxPropertyGridManager( wxWindow *parent, wxWindowID id = wxID_ANY,
254 const wxPoint& pos = wxDefaultPosition,
255 const wxSize& size = wxDefaultSize,
256 long style = wxPGMAN_DEFAULT_STYLE,
257 const wxString& name = wxPropertyGridManagerNameStr );
258
259 /** Destructor */
260 virtual ~wxPropertyGridManager();
261
262 #endif
263
264 /** Creates new property page. Note that the first page is not created
265 automatically.
266 @param label
267 A label for the page. This may be shown as a toolbar tooltip etc.
268 @param bmp
269 Bitmap image for toolbar. If wxNullBitmap is used, then a built-in
270 default image is used.
271 @param pageObj
272 wxPropertyGridPage instance. Manager will take ownership of this object.
273 NULL indicates that a default page instance should be created.
274
275 @return
276 Returns pointer to created page.
277
278 @remarks
279 If toolbar is used, it is highly recommended that the pages are
280 added when the toolbar is not turned off using window style flag
281 switching.
282 */
283 wxPropertyGridPage* AddPage( const wxString& label = wxEmptyString,
284 const wxBitmap& bmp = wxPG_NULL_BITMAP,
285 wxPropertyGridPage* pageObj = NULL )
286 {
287 return InsertPage(-1, label, bmp, pageObj);
288 }
289
290 /** Deletes all all properties and all pages.
291 */
292 virtual void Clear();
293
294 /** Deletes all properties on given page.
295 */
296 void ClearPage( int page );
297
298 /** Forces updating the value of property from the editor control.
299 Returns true if DoPropertyChanged was actually called.
300 */
301 bool CommitChangesFromEditor( wxUint32 flags = 0 )
302 {
303 return m_pPropGrid->CommitChangesFromEditor(flags);
304 }
305
306 /**
307 Two step creation.
308 Whenever the control is created without any parameters, use Create to
309 actually create it. Don't access the control's public methods before
310 this is called.
311 @see @link wndflags Additional Window Styles@endlink
312 */
313 bool Create( wxWindow *parent, wxWindowID id = wxID_ANY,
314 const wxPoint& pos = wxDefaultPosition,
315 const wxSize& size = wxDefaultSize,
316 long style = wxPGMAN_DEFAULT_STYLE,
317 const wxString& name = wxPropertyGridManagerNameStr );
318
319 /**
320 Enables or disables (shows/hides) categories according to parameter
321 enable.
322
323 WARNING: Not tested properly, use at your own risk.
324 */
325 bool EnableCategories( bool enable )
326 {
327 long fl = m_windowStyle | wxPG_HIDE_CATEGORIES;
328 if ( enable ) fl = m_windowStyle & ~(wxPG_HIDE_CATEGORIES);
329 SetWindowStyleFlag(fl);
330 return true;
331 }
332
333 /** Selects page, scrolls and/or expands items to ensure that the
334 given item is visible. Returns true if something was actually done.
335 */
336 bool EnsureVisible( wxPGPropArg id );
337
338 /** Returns number of columns on given page. By the default,
339 returns number of columns on current page. */
340 int GetColumnCount( int page = -1 ) const;
341
342 /** Returns height of the description text box. */
343 int GetDescBoxHeight() const;
344
345 /** Returns pointer to the contained wxPropertyGrid. This does not change
346 after wxPropertyGridManager has been created, so you can safely obtain
347 pointer once and use it for the entire lifetime of the instance.
348 */
349 wxPropertyGrid* GetGrid()
350 {
351 wxASSERT(m_pPropGrid);
352 return m_pPropGrid;
353 };
354
355 const wxPropertyGrid* GetGrid() const
356 {
357 wxASSERT(m_pPropGrid);
358 return (const wxPropertyGrid*)m_pPropGrid;
359 };
360
361 /** Returns iterator class instance.
362 @remarks
363 Calling this method in wxPropertyGridManager causes run-time assertion
364 failure. Please only iterate through individual pages or use
365 CreateVIterator().
366 */
367 wxPropertyGridIterator GetIterator( int flags = wxPG_ITERATE_DEFAULT,
368 wxPGProperty* firstProp = NULL )
369 {
370 wxFAIL_MSG( "Please only iterate through individual pages "
371 "or use CreateVIterator()" );
372 return wxPropertyGridInterface::GetIterator( flags, firstProp );
373 }
374
375 wxPropertyGridConstIterator
376 GetIterator(int flags = wxPG_ITERATE_DEFAULT,
377 wxPGProperty* firstProp = NULL) const
378 {
379 wxFAIL_MSG( "Please only iterate through individual pages "
380 " or use CreateVIterator()" );
381 return wxPropertyGridInterface::GetIterator( flags, firstProp );
382 }
383
384 /** Returns iterator class instance.
385 @remarks
386 Calling this method in wxPropertyGridManager causes run-time assertion
387 failure. Please only iterate through individual pages or use
388 CreateVIterator().
389 */
390 wxPropertyGridIterator GetIterator( int flags, int startPos )
391 {
392 wxFAIL_MSG( "Please only iterate through individual pages "
393 "or use CreateVIterator()" );
394
395 return wxPropertyGridInterface::GetIterator( flags, startPos );
396 }
397
398 wxPropertyGridConstIterator GetIterator( int flags, int startPos ) const
399 {
400 wxFAIL_MSG( "Please only iterate through individual pages "
401 "or use CreateVIterator()" );
402 return wxPropertyGridInterface::GetIterator( flags, startPos );
403 }
404
405 /** Similar to GetIterator, but instead returns wxPGVIterator instance,
406 which can be useful for forward-iterating through arbitrary property
407 containers.
408 */
409 virtual wxPGVIterator GetVIterator( int flags ) const;
410
411 /** Returns currently selected page.
412 */
413 wxPropertyGridPage* GetCurrentPage() const
414 {
415 return GetPage(m_selPage);
416 }
417
418 /** Returns page object for given page index.
419 */
420 wxPropertyGridPage* GetPage( unsigned int ind ) const
421 {
422 return m_arrPages[ind];
423 }
424
425 /** Returns page object for given page name.
426 */
427 wxPropertyGridPage* GetPage( const wxString& name ) const
428 {
429 return GetPage(GetPageByName(name));
430 }
431
432 /**
433 Returns index for a page name.
434
435 If no match is found, wxNOT_FOUND is returned.
436 */
437 int GetPageByName( const wxString& name ) const;
438
439 /** Returns index for a relevant propertygrid state.
440
441 If no match is found, wxNOT_FOUND is returned.
442 */
443 int GetPageByState( const wxPropertyGridPageState* pstate ) const;
444
445 protected:
446 /** Returns wxPropertyGridPageState of given page, current page's for -1.
447 */
448 virtual wxPropertyGridPageState* GetPageState( int page ) const;
449
450 public:
451 /** Returns number of managed pages. */
452 size_t GetPageCount() const;
453
454 /** Returns name of given page. */
455 const wxString& GetPageName( int index ) const;
456
457 /** Returns "root property" of the given page. It does not have name, etc.
458 and it is not visible. It is only useful for accessing its children.
459 */
460 wxPGProperty* GetPageRoot( int index ) const;
461
462 /** Returns index to currently selected page. */
463 int GetSelectedPage() const { return m_selPage; }
464
465 /** Alias for GetSelection(). */
466 wxPGProperty* GetSelectedProperty() const
467 {
468 return GetSelection();
469 }
470
471 /** Shortcut for GetGrid()->GetSelection(). */
472 wxPGProperty* GetSelection() const
473 {
474 return m_pPropGrid->GetSelection();
475 }
476
477 /** Returns a pointer to the toolbar currently associated with the
478 wxPropertyGridManager (if any). */
479 wxToolBar* GetToolBar() const { return m_pToolbar; }
480
481 /** Creates new property page. Note that the first page is not created
482 automatically.
483 @param index
484 Add to this position. -1 will add as the last item.
485 @param label
486 A label for the page. This may be shown as a toolbar tooltip etc.
487 @param bmp
488 Bitmap image for toolbar. If wxNullBitmap is used, then a built-in
489 default image is used.
490 @param pageObj
491 wxPropertyGridPage instance. Manager will take ownership of this object.
492 If NULL, default page object is constructed.
493
494 @return
495 Returns pointer to created page.
496 */
497 virtual wxPropertyGridPage* InsertPage( int index,
498 const wxString& label,
499 const wxBitmap& bmp = wxNullBitmap,
500 wxPropertyGridPage* pageObj = NULL );
501
502 /**
503 Returns true if any property on any page has been modified by the user.
504 */
505 bool IsAnyModified() const;
506
507 /**
508 Returns true if updating is frozen (ie Freeze() called but not yet
509 Thaw() ).
510 */
511 bool IsFrozen() const { return m_pPropGrid->m_frozen > 0; }
512
513 /**
514 Returns true if any property on given page has been modified by the
515 user.
516 */
517 bool IsPageModified( size_t index ) const;
518
519 virtual void Refresh( bool eraseBackground = true,
520 const wxRect* rect = (const wxRect*) NULL );
521
522 /** Removes a page.
523 @return
524 Returns false if it was not possible to remove page in question.
525 */
526 virtual bool RemovePage( int page );
527
528 /** Select and displays a given page.
529
530 @param index
531 Index of page being seleced. Can be -1 to select nothing.
532 */
533 void SelectPage( int index );
534
535 /** Select and displays a given page (by label). */
536 void SelectPage( const wxString& label )
537 {
538 int index = GetPageByName(label);
539 wxCHECK_RET( index >= 0, wxT("No page with such name") );
540 SelectPage( index );
541 }
542
543 /** Select and displays a given page. */
544 void SelectPage( wxPropertyGridPage* ptr )
545 {
546 SelectPage( GetPageByState(ptr) );
547 }
548
549 /** Select a property. */
550 bool SelectProperty( wxPGPropArg id, bool focus = false )
551 {
552 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
553 return p->GetParentState()->DoSelectProperty(p, focus);
554 }
555
556 /** Sets number of columns on given page (default is current page).
557 */
558 void SetColumnCount( int colCount, int page = -1 );
559
560 /** Sets label and text in description box.
561 */
562 void SetDescription( const wxString& label, const wxString& content );
563
564 /** Sets y coordinate of the description box splitter. */
565 void SetDescBoxHeight( int ht, bool refresh = true );
566
567 /** Moves splitter as left as possible, while still allowing all
568 labels to be shown in full.
569 @param subProps
570 If false, will still allow sub-properties (ie. properties which
571 parent is not root or category) to be cropped.
572 @param allPages
573 If true, takes labels on all pages into account.
574 */
575 void SetSplitterLeft( bool subProps = false, bool allPages = true );
576
577 /** Sets splitter position on individual page. */
578 void SetPageSplitterPosition( int page, int pos, int column = 0 )
579 {
580 GetPage(page)->DoSetSplitterPosition( pos, column );
581 }
582
583 /** Sets splitter position for all pages.
584 @remarks
585 Splitter position cannot exceed grid size, and therefore setting it
586 during form creation may fail as initial grid size is often smaller
587 than desired splitter position, especially when sizers are being used.
588 */
589 void SetSplitterPosition( int pos, int column = 0 );
590
591 #ifdef SWIG
592 %pythoncode {
593 def GetValuesFromPage(self,
594 page,
595 dict_=None,
596 as_strings=False,
597 inc_attributes=False):
598 "Same as GetValues, but returns values from specific page only."
599 "For argument descriptions, see GetValues."
600 return page.GetPropertyValues(dict_, as_strings, inc_attributes)
601 }
602 #endif
603
604 protected:
605
606 //
607 // Subclassing helpers
608 //
609
610 /** Creates property grid for the manager. Override to use subclassed
611 wxPropertyGrid.
612 */
613 virtual wxPropertyGrid* CreatePropertyGrid() const;
614
615 public:
616 virtual void RefreshProperty( wxPGProperty* p );
617
618 //
619 // Overridden functions - no documentation required.
620 //
621
622 void SetId( wxWindowID winid );
623
624 virtual void Freeze();
625 virtual void Thaw();
626 virtual void SetExtraStyle ( long exStyle );
627 virtual bool SetFont ( const wxFont& font );
628 virtual void SetWindowStyleFlag ( long style );
629
630 protected:
631 virtual wxSize DoGetBestSize() const;
632
633 public:
634
635 #ifndef SWIG
636
637 virtual bool ProcessEvent( wxEvent& event );
638 //
639 // Event handlers
640 //
641 void OnMouseMove( wxMouseEvent &event );
642 void OnMouseClick( wxMouseEvent &event );
643 void OnMouseUp( wxMouseEvent &event );
644 void OnMouseEntry( wxMouseEvent &event );
645
646 void OnPaint( wxPaintEvent &event );
647
648 void OnToolbarClick( wxCommandEvent &event );
649 void OnResize( wxSizeEvent& event );
650 void OnPropertyGridSelect( wxPropertyGridEvent& event );
651
652 protected:
653
654 wxPropertyGrid* m_pPropGrid;
655
656 wxVector<wxPropertyGridPage*> m_arrPages;
657
658 #if wxUSE_TOOLBAR
659 wxToolBar* m_pToolbar;
660 #endif
661 wxStaticText* m_pTxtHelpCaption;
662 wxStaticText* m_pTxtHelpContent;
663
664 wxPropertyGridPage* m_emptyPage;
665
666 long m_iFlags;
667
668 // Selected page index.
669 int m_selPage;
670
671 int m_width;
672
673 int m_height;
674
675 int m_extraHeight;
676
677 int m_splitterY;
678
679 int m_splitterHeight;
680
681 int m_nextTbInd;
682
683 int m_dragOffset;
684
685 wxCursor m_cursorSizeNS;
686
687 int m_nextDescBoxSize;
688
689 wxWindowID m_baseId;
690
691 unsigned char m_dragStatus;
692
693 unsigned char m_onSplitter;
694
695 virtual wxPGProperty* DoGetPropertyByName( const wxString& name ) const;
696
697 /** Select and displays a given page. */
698 virtual bool DoSelectPage( int index );
699
700 // Sets some members to defaults.
701 void Init1();
702
703 // Initializes some members.
704 void Init2( int style );
705
706 /*#ifdef __WXMSW__
707 virtual WXDWORD MSWGetStyle(long flags, WXDWORD *exstyle) const;
708 #endif*/
709
710 /** Recalculates new positions for components, according to the
711 given size.
712 */
713 void RecalculatePositions( int width, int height );
714
715 /** (Re)creates/destroys controls, according to the window style bits. */
716 void RecreateControls();
717
718 void UpdateDescriptionBox( int new_splittery, int new_width, int new_height );
719
720 void RepaintSplitter( wxDC& dc,
721 int new_splittery,
722 int new_width,
723 int new_height,
724 bool desc_too );
725
726 void SetDescribedProperty( wxPGProperty* p );
727
728 // Reimplement these to handle "descboxheight" state item
729 virtual bool SetEditableStateItem( const wxString& name, wxVariant value );
730 virtual wxVariant GetEditableStateItem( const wxString& name ) const;
731
732 private:
733 DECLARE_EVENT_TABLE()
734 #endif // #ifndef SWIG
735 };
736
737 // -----------------------------------------------------------------------
738
739 inline int wxPropertyGridPage::GetIndex() const
740 {
741 if ( !m_manager )
742 return wxNOT_FOUND;
743 return m_manager->GetPageByState(this);
744 }
745
746 // -----------------------------------------------------------------------
747
748 #endif // wxUSE_PROPGRID
749
750 #endif // _WX_PROPGRID_MANAGER_H_