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