]> git.saurik.com Git - wxWidgets.git/blame - src/propgrid/manager.cpp
next attempt
[wxWidgets.git] / src / propgrid / manager.cpp
CommitLineData
1c4293cb
VZ
1/////////////////////////////////////////////////////////////////////////////
2// Name: src/propgrid/manager.cpp
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// For compilers that support precompilation, includes "wx/wx.h".
13#include "wx/wxprec.h"
14
15#ifdef __BORLANDC__
16 #pragma hdrstop
17#endif
18
19#ifndef WX_PRECOMP
20 #include "wx/defs.h"
21 #include "wx/object.h"
22 #include "wx/hash.h"
23 #include "wx/string.h"
24 #include "wx/log.h"
25 #include "wx/event.h"
26 #include "wx/window.h"
27 #include "wx/panel.h"
28 #include "wx/dc.h"
29 #include "wx/pen.h"
30 #include "wx/brush.h"
31 #include "wx/cursor.h"
32 #include "wx/dialog.h"
33 #include "wx/settings.h"
34 #include "wx/msgdlg.h"
35 #include "wx/choice.h"
36 #include "wx/textctrl.h"
37 #include "wx/dirdlg.h"
38 #include "wx/combobox.h"
39 #include "wx/layout.h"
40 #include "wx/sizer.h"
41 #include "wx/textdlg.h"
42 #include "wx/filedlg.h"
43 #include "wx/statusbr.h"
44 #include "wx/intl.h"
45#endif
46
47// This define is necessary to prevent macro clearing
48#define __wxPG_SOURCE_FILE__
49
50#include <wx/propgrid/propgrid.h>
51
52#include <wx/propgrid/manager.h>
53
54
55#define wxPG_MAN_ALTERNATE_BASE_ID 11249 // Needed for wxID_ANY madnesss
56
57
58// -----------------------------------------------------------------------
59
60// For wxMSW cursor consistency, we must do mouse capturing even
61// when using custom controls
62
63#define BEGIN_MOUSE_CAPTURE \
64 if ( !(m_iFlags & wxPG_FL_MOUSE_CAPTURED) ) \
65 { \
66 CaptureMouse(); \
67 m_iFlags |= wxPG_FL_MOUSE_CAPTURED; \
68 }
69
70#define END_MOUSE_CAPTURE \
71 if ( m_iFlags & wxPG_FL_MOUSE_CAPTURED ) \
72 { \
73 ReleaseMouse(); \
74 m_iFlags &= ~(wxPG_FL_MOUSE_CAPTURED); \
75 }
76
77// -----------------------------------------------------------------------
78// wxPropertyGridManager
79// -----------------------------------------------------------------------
80
81const wxChar *wxPropertyGridManagerNameStr = wxT("wxPropertyGridManager");
82
83
84// Categoric Mode Icon
85static const char* gs_xpm_catmode[] = {
86"16 16 5 1",
87". c none",
88"B c black",
89"D c #868686",
90"L c #CACACA",
91"W c #FFFFFF",
92".DDD............",
93".DLD.BBBBBB.....",
94".DDD............",
95".....DDDDD.DDD..",
96"................",
97".....DDDDD.DDD..",
98"................",
99".....DDDDD.DDD..",
100"................",
101".....DDDDD.DDD..",
102"................",
103".DDD............",
104".DLD.BBBBBB.....",
105".DDD............",
106".....DDDDD.DDD..",
107"................"
108};
109
110// Alphabetic Mode Icon
111static const char* gs_xpm_noncatmode[] = {
112"16 16 5 1",
113". c none",
114"B c black",
115"D c #868686",
116"L c #000080",
117"W c #FFFFFF",
118"..DBD...DDD.DDD.",
119".DB.BD..........",
120".BBBBB..DDD.DDD.",
121".B...B..........",
122"...L....DDD.DDD.",
123"...L............",
124".L.L.L..DDD.DDD.",
125"..LLL...........",
126"...L....DDD.DDD.",
127"................",
128".BBBBB..DDD.DDD.",
129"....BD..........",
130"...BD...DDD.DDD.",
131"..BD............",
132".BBBBB..DDD.DDD.",
133"................"
134};
135
136// Default Page Icon.
137static const char* gs_xpm_defpage[] = {
138"16 16 5 1",
139". c none",
140"B c black",
141"D c #868686",
142"L c #000080",
143"W c #FFFFFF",
144"................",
145"................",
146"..BBBBBBBBBBBB..",
147"..B..........B..",
148"..B.BB.LLLLL.B..",
149"..B..........B..",
150"..B.BB.LLLLL.B..",
151"..B..........B..",
152"..B.BB.LLLLL.B..",
153"..B..........B..",
154"..B.BB.LLLLL.B..",
155"..B..........B..",
156"..BBBBBBBBBBBB..",
157"................",
158"................",
159"................"
160};
161
162#define GETPAGESTATE(page) ((wxPropertyGridPage*)m_arrPages.Item(page))->GetStatePtr()
163
164// -----------------------------------------------------------------------
165// wxPropertyGridPage
166// -----------------------------------------------------------------------
167
168
169IMPLEMENT_CLASS(wxPropertyGridPage, wxEvtHandler)
170
171
172BEGIN_EVENT_TABLE(wxPropertyGridPage, wxEvtHandler)
173END_EVENT_TABLE()
174
175
176wxPropertyGridPage::wxPropertyGridPage()
177 : wxEvtHandler(), wxPropertyGridInterface(), wxPropertyGridPageState()
178{
179 m_pState = this; // wxPropertyGridInterface to point to State
180 m_manager = NULL;
181 m_isDefault = false;
182}
183
184wxPropertyGridPage::~wxPropertyGridPage()
185{
186}
187
188void wxPropertyGridPage::Clear()
189{
190 GetStatePtr()->DoClear();
191}
192
193wxSize wxPropertyGridPage::FitColumns()
194{
195 wxSize sz = DoFitColumns();
196 return sz;
197}
198
199void wxPropertyGridPage::RefreshProperty( wxPGProperty* p )
200{
201 if ( m_manager )
202 m_manager->RefreshProperty(p);
203}
204
205void wxPropertyGridPage::OnShow()
206{
207}
208
209void wxPropertyGridPage::SetSplitterPosition( int splitterPos, int col )
210{
211 wxPropertyGrid* pg = GetGrid();
212 if ( pg->GetState() == this )
213 pg->SetSplitterPosition(splitterPos);
214 else
215 DoSetSplitterPosition(splitterPos, col, false);
216}
217
218void wxPropertyGridPage::DoSetSplitterPosition( int pos, int splitterColumn, bool allPages )
219{
220 if ( allPages && m_manager->GetPageCount() )
221 m_manager->SetSplitterPosition( pos, splitterColumn );
222 else
223 DoSetSplitterPositionThisPage( pos, splitterColumn );
224}
225
226// -----------------------------------------------------------------------
227// wxPropertyGridManager
228// -----------------------------------------------------------------------
229
230// Final default splitter y is client height minus this.
231#define wxPGMAN_DEFAULT_NEGATIVE_SPLITTER_Y 100
232
233// -----------------------------------------------------------------------
234
235IMPLEMENT_CLASS(wxPropertyGridManager, wxPanel)
236
237#define ID_ADVTOOLBAR_OFFSET 1
238#define ID_ADVHELPCAPTION_OFFSET 2
239#define ID_ADVHELPCONTENT_OFFSET 3
240#define ID_ADVBUTTON_OFFSET 4
241#define ID_ADVTBITEMSBASE_OFFSET 5 // Must be last.
242
243// -----------------------------------------------------------------------
244
245BEGIN_EVENT_TABLE(wxPropertyGridManager, wxPanel)
246 EVT_MOTION(wxPropertyGridManager::OnMouseMove)
247 EVT_SIZE(wxPropertyGridManager::OnResize)
248 EVT_PAINT(wxPropertyGridManager::OnPaint)
249 EVT_LEFT_DOWN(wxPropertyGridManager::OnMouseClick)
250 EVT_LEFT_UP(wxPropertyGridManager::OnMouseUp)
251 EVT_LEAVE_WINDOW(wxPropertyGridManager::OnMouseEntry)
252 //EVT_ENTER_WINDOW(wxPropertyGridManager::OnMouseEntry)
253END_EVENT_TABLE()
254
255// -----------------------------------------------------------------------
256
257wxPropertyGridManager::wxPropertyGridManager()
258 : wxPanel()
259{
260 Init1();
261}
262
263// -----------------------------------------------------------------------
264
265wxPropertyGridManager::wxPropertyGridManager( wxWindow *parent,
266 wxWindowID id,
267 const wxPoint& pos,
268 const wxSize& size,
269 long style,
270 const wxChar* name )
271 : wxPanel()
272{
273 Init1();
274 Create(parent,id,pos,size,style,name);
275}
276
277// -----------------------------------------------------------------------
278
279bool wxPropertyGridManager::Create( wxWindow *parent,
280 wxWindowID id,
281 const wxPoint& pos,
282 const wxSize& size,
283 long style,
284 const wxChar* name )
285{
286
287 bool res = wxPanel::Create( parent, id, pos, size,
288 (style&0xFFFF0000)|wxWANTS_CHARS,
289 name );
290 Init2(style);
291
292 return res;
293}
294
295// -----------------------------------------------------------------------
296
297//
298// Initialize values to defaults
299//
300void wxPropertyGridManager::Init1()
301{
302
303 //m_pPropGrid = (wxPropertyGrid*) NULL;
304 m_pPropGrid = CreatePropertyGrid();
305
306#if wxUSE_TOOLBAR
307 m_pToolbar = (wxToolBar*) NULL;
308#endif
309 m_pTxtHelpCaption = (wxStaticText*) NULL;
310 m_pTxtHelpContent = (wxStaticText*) NULL;
311
312 m_emptyPage = (wxPropertyGridPage*) NULL;
313
314 m_selPage = -1;
315
316 m_width = m_height = 0;
317
318 m_splitterHeight = 5;
319
320 m_splitterY = -1; // -1 causes default to be set.
321
322 m_nextDescBoxSize = -1;
323
324 m_extraHeight = 0;
325 m_dragStatus = 0;
326 m_onSplitter = 0;
327 m_iFlags = 0;
328}
329
330// -----------------------------------------------------------------------
331
332// These flags are always used in wxPropertyGrid integrated in wxPropertyGridManager.
333#ifndef __WXMAC__
334 #define wxPG_MAN_PROPGRID_FORCED_FLAGS (wxSIMPLE_BORDER| \
335 wxNO_FULL_REPAINT_ON_RESIZE| \
336 wxCLIP_CHILDREN)
337#else
338 #define wxPG_MAN_PROPGRID_FORCED_FLAGS (wxNO_BORDER| \
339 wxNO_FULL_REPAINT_ON_RESIZE| \
340 wxCLIP_CHILDREN)
341#endif
342
343// Which flags can be passed to underlying wxPropertyGrid.
344#define wxPG_MAN_PASS_FLAGS_MASK (0xFFF0|wxTAB_TRAVERSAL)
345
346//
347// Initialize after parent etc. set
348//
349void wxPropertyGridManager::Init2( int style )
350{
351
352 if ( m_iFlags & wxPG_FL_INITIALIZED )
353 return;
354
355 m_windowStyle |= (style&0x0000FFFF);
356
357 wxSize csz = GetClientSize();
358
359 m_cursorSizeNS = wxCursor(wxCURSOR_SIZENS);
360
361 // Prepare the first page
362 // NB: But just prepare - you still need to call Add/InsertPage
363 // to actually add properties on it.
364 wxPropertyGridPage* pd = new wxPropertyGridPage();
365 pd->m_isDefault = true;
366 pd->m_manager = this;
367 wxPropertyGridPageState* state = pd->GetStatePtr();
368 state->m_pPropGrid = m_pPropGrid;
369 m_arrPages.Add( (void*)pd );
370 m_pPropGrid->m_pState = state;
371
372 wxWindowID baseId = GetId();
373 wxWindowID useId = baseId;
374 if ( baseId < 0 )
375 baseId = wxPG_MAN_ALTERNATE_BASE_ID;
376
377 m_baseId = baseId;
378
379#ifdef __WXMAC__
380 // Smaller controls on Mac
381 SetWindowVariant(wxWINDOW_VARIANT_SMALL);
382#endif
383
384 // Create propertygrid.
385 m_pPropGrid->Create(this,baseId,wxPoint(0,0),csz,
386 (m_windowStyle&wxPG_MAN_PASS_FLAGS_MASK)
387 |wxPG_MAN_PROPGRID_FORCED_FLAGS);
388
389 m_pPropGrid->m_eventObject = this;
390
391 m_pPropGrid->SetId(useId);
392
393 m_pPropGrid->m_iFlags |= wxPG_FL_IN_MANAGER;
394
395 m_pState = m_pPropGrid->m_pState;
396
397 m_pPropGrid->SetExtraStyle(wxPG_EX_INIT_NOCAT);
398
399 m_nextTbInd = baseId+ID_ADVTBITEMSBASE_OFFSET + 2;
400
401
402 // Connect to property grid onselect event.
403 // NB: Even if wxID_ANY is used, this doesn't connect properly in wxPython
404 // (see wxPropertyGridManager::ProcessEvent).
405 Connect(m_pPropGrid->GetId()/*wxID_ANY*/,
406 wxEVT_PG_SELECTED,
407 wxPropertyGridEventHandler(wxPropertyGridManager::OnPropertyGridSelect) );
408
409 // Connect to toolbar button events.
410 Connect(baseId+ID_ADVTBITEMSBASE_OFFSET,baseId+ID_ADVTBITEMSBASE_OFFSET+50,
411 wxEVT_COMMAND_TOOL_CLICKED,
412 wxCommandEventHandler(wxPropertyGridManager::OnToolbarClick) );
413
414 // Optional initial controls.
415 m_width = -12345;
416
417 m_iFlags |= wxPG_FL_INITIALIZED;
418
419}
420
421// -----------------------------------------------------------------------
422
423wxPropertyGridManager::~wxPropertyGridManager()
424{
425 END_MOUSE_CAPTURE
426
427 m_pPropGrid->DoSelectProperty(NULL);
428 m_pPropGrid->m_pState = NULL;
429
430 size_t i;
431 for ( i=0; i<m_arrPages.GetCount(); i++ )
432 {
433 delete (wxPropertyGridPage*)m_arrPages.Item(i);
434 }
435
436 delete m_emptyPage;
437}
438
439// -----------------------------------------------------------------------
440
441wxPropertyGrid* wxPropertyGridManager::CreatePropertyGrid() const
442{
443 return new wxPropertyGrid();
444}
445
446// -----------------------------------------------------------------------
447
448void wxPropertyGridManager::SetId( wxWindowID winid )
449{
450 wxWindow::SetId(winid);
451
452 // TODO: Reconnect propgrid event handler(s).
453
454 m_pPropGrid->SetId(winid);
455}
456
457// -----------------------------------------------------------------------
458
459wxSize wxPropertyGridManager::DoGetBestSize() const
460{
461 return wxSize(60,150);
462}
463
464// -----------------------------------------------------------------------
465
466bool wxPropertyGridManager::SetFont( const wxFont& font )
467{
468 bool res = wxWindow::SetFont(font);
469 m_pPropGrid->SetFont(font);
470
471 // TODO: Need to do caption recacalculations for other pages as well.
472 unsigned int i;
473 for ( i=0; i<m_arrPages.GetCount(); i++ )
474 {
475 wxPropertyGridPage* page = GetPage(i);
476
477 if ( page != m_pPropGrid->GetState() )
478 page->CalculateFontAndBitmapStuff(-1);
479 }
480
481 return res;
482}
483
484// -----------------------------------------------------------------------
485
486void wxPropertyGridManager::SetExtraStyle( long exStyle )
487{
488 wxWindow::SetExtraStyle( exStyle );
489 m_pPropGrid->SetExtraStyle( exStyle & 0xFFFFF000 );
490#if wxUSE_TOOLBAR
491 if ( (exStyle & wxPG_EX_NO_FLAT_TOOLBAR) && m_pToolbar )
492 RecreateControls();
493#endif
494}
495
496// -----------------------------------------------------------------------
497
498void wxPropertyGridManager::Freeze()
499{
500 m_pPropGrid->Freeze();
501 wxWindow::Freeze();
502}
503
504// -----------------------------------------------------------------------
505
506void wxPropertyGridManager::Thaw()
507{
508 wxWindow::Thaw();
509 m_pPropGrid->Thaw();
510}
511
512// -----------------------------------------------------------------------
513
514void wxPropertyGridManager::SetWindowStyleFlag( long style )
515{
516 wxWindow::SetWindowStyleFlag( style );
517 m_pPropGrid->SetWindowStyleFlag( (m_pPropGrid->GetWindowStyleFlag()&~(wxPG_MAN_PASS_FLAGS_MASK)) |
518 (style&wxPG_MAN_PASS_FLAGS_MASK) );
519}
520
521// -----------------------------------------------------------------------
522
523// Actually shows given page.
524bool wxPropertyGridManager::DoSelectPage( int index )
525{
526 // -1 means no page was selected
527 //wxASSERT( m_selPage >= 0 );
528
529 wxCHECK_MSG( index >= -1 && index < (int)GetPageCount(),
530 false,
531 wxT("invalid page index") );
532
533 if ( m_selPage == index )
534 return true;
535
536 if ( m_pPropGrid->m_selected )
537 {
538 if ( !m_pPropGrid->ClearSelection() )
539 return false;
540 }
541
542 wxPropertyGridPage* prevPage;
543
544 if ( m_selPage >= 0 )
545 prevPage = GetPage(m_selPage);
546 else
547 prevPage = m_emptyPage;
548
549 wxPropertyGridPage* nextPage;
550
551 if ( index >= 0 )
552 {
553 nextPage = (wxPropertyGridPage*)m_arrPages.Item(index);
554
555 nextPage->OnShow();
556 }
557 else
558 {
559 if ( !m_emptyPage )
560 {
561 m_emptyPage = new wxPropertyGridPage();
562 m_emptyPage->m_pPropGrid = m_pPropGrid;
563 }
564
565 nextPage = m_emptyPage;
566 }
567
568 m_iFlags |= wxPG_FL_DESC_REFRESH_REQUIRED;
569
570 m_pPropGrid->SwitchState( nextPage->GetStatePtr() );
571
572 m_pState = m_pPropGrid->m_pState;
573
574 m_selPage = index;
575
576#if wxUSE_TOOLBAR
577 if ( m_pToolbar )
578 {
579 if ( index >= 0 )
580 m_pToolbar->ToggleTool( nextPage->m_id, true );
581 else
582 m_pToolbar->ToggleTool( prevPage->m_id, false );
583 }
584#endif
585
586 return true;
587}
588
589// -----------------------------------------------------------------------
590
591// Changes page *and* set the target page for insertion operations.
592void wxPropertyGridManager::SelectPage( int index )
593{
594 DoSelectPage(index);
595}
596
597// -----------------------------------------------------------------------
598
599int wxPropertyGridManager::GetPageByName( const wxString& name ) const
600{
601 size_t i;
602 for ( i=0; i<GetPageCount(); i++ )
603 {
604 if ( ((wxPropertyGridPage*)m_arrPages.Item(i))->m_label == name )
605 return i;
606 }
607 return wxNOT_FOUND;
608}
609
610// -----------------------------------------------------------------------
611
612int wxPropertyGridManager::GetPageByState( const wxPropertyGridPageState* pState ) const
613{
614 wxASSERT( pState );
615
616 size_t i;
617 for ( i=0; i<GetPageCount(); i++ )
618 {
619 if ( pState == ((wxPropertyGridPage*)m_arrPages.Item(i))->GetStatePtr() )
620 return i;
621 }
622
623 return wxNOT_FOUND;
624}
625
626// -----------------------------------------------------------------------
627
628const wxString& wxPropertyGridManager::GetPageName( int index ) const
629{
630 wxASSERT( index >= 0 && index < (int)GetPageCount() );
631 return ((wxPropertyGridPage*)m_arrPages.Item(index))->m_label;
632}
633
634// -----------------------------------------------------------------------
635
636wxPropertyGridPageState* wxPropertyGridManager::GetPageState( int page ) const
637{
638 // Do not change this into wxCHECK because returning NULL is important
639 // for wxPropertyGridInterface page enumeration mechanics.
640 if ( page >= (int)GetPageCount() )
641 return NULL;
642
643 if ( page == -1 )
644 return m_pState;
645 return GETPAGESTATE(page);
646}
647
648// -----------------------------------------------------------------------
649
650void wxPropertyGridManager::Clear()
651{
652 m_pPropGrid->Freeze();
653
654 int i;
655 for ( i=(int)GetPageCount()-1; i>=0; i-- )
656 RemovePage(i);
657
658 // Reset toolbar ids
659 m_nextTbInd = m_baseId+ID_ADVTBITEMSBASE_OFFSET + 2;
660
661 m_pPropGrid->Thaw();
662}
663
664// -----------------------------------------------------------------------
665
666void wxPropertyGridManager::ClearPage( int page )
667{
668 wxASSERT( page >= 0 );
669 wxASSERT( page < (int)GetPageCount() );
670
671 if ( page >= 0 && page < (int)GetPageCount() )
672 {
673 wxPropertyGridPageState* state = GETPAGESTATE(page);
674
675 if ( state == m_pPropGrid->GetState() )
676 m_pPropGrid->Clear();
677 else
678 state->DoClear();
679 }
680}
681
682// -----------------------------------------------------------------------
683
684int wxPropertyGridManager::GetColumnCount( int page ) const
685{
686 wxASSERT( page >= -1 );
687 wxASSERT( page < (int)GetPageCount() );
688
689 return GetPageState(page)->GetColumnCount();
690}
691
692// -----------------------------------------------------------------------
693
694void wxPropertyGridManager::SetColumnCount( int colCount, int page )
695{
696 wxASSERT( page >= -1 );
697 wxASSERT( page < (int)GetPageCount() );
698
699 GetPageState(page)->SetColumnCount( colCount );
700 GetGrid()->Refresh();
701}
702// -----------------------------------------------------------------------
703
704void wxPropertyGridManager::SetPropertyAttributeAll( const wxString& attrName, wxVariant value )
705{
706 size_t i;
707 for ( i=0; i<GetPageCount(); i++ )
708 {
709 wxPropertyGridPage* page = (wxPropertyGridPage*)m_arrPages.Item(i);
710
711 DoSetPropertyAttribute(page->GetStatePtr()->m_properties, attrName, value, wxPG_RECURSE);
712 }
713}
714
715// -----------------------------------------------------------------------
716
717size_t wxPropertyGridManager::GetPageCount() const
718{
719 if ( !(m_iFlags & wxPG_MAN_FL_PAGE_INSERTED) )
720 return 0;
721
722 return m_arrPages.GetCount();
723}
724
725// -----------------------------------------------------------------------
726
727int wxPropertyGridManager::InsertPage( int index, const wxString& label,
728 const wxBitmap& bmp, wxPropertyGridPage* pageObj )
729{
730 if ( index < 0 )
731 index = GetPageCount();
732
733 wxCHECK_MSG( (size_t)index == GetPageCount(), -1,
734 wxT("wxPropertyGridManager currently only supports appending pages (due to wxToolBar limitation)."));
735
736 bool needInit = true;
737 bool isPageInserted = m_iFlags & wxPG_MAN_FL_PAGE_INSERTED ? true : false;
738
739 wxASSERT( index == 0 || isPageInserted );
740
741 if ( !pageObj )
742 {
743 // No custom page object was given, so we will either re-use the default base
744 // page (if index==0), or create a new default page object.
745 if ( !isPageInserted )
746 {
747 pageObj = GetPage(0);
748 // Of course, if the base page was custom, we need to delete and
749 // re-create it.
750 if ( !pageObj->m_isDefault )
751 {
752 delete pageObj;
753 pageObj = new wxPropertyGridPage();
754 m_arrPages[0] = pageObj;
755 }
756 needInit = false;
757 }
758 else
759 {
760 pageObj = new wxPropertyGridPage();
761 }
762 pageObj->m_isDefault = true;
763 }
764 else
765 {
766 if ( !isPageInserted )
767 {
768 // Initial page needs to be deleted and replaced
769 delete GetPage(0);
770 m_arrPages[0] = pageObj;
771 m_pPropGrid->m_pState = pageObj->GetStatePtr();
772 }
773 }
774
775 wxPropertyGridPageState* state = pageObj->GetStatePtr();
776
777 pageObj->m_manager = this;
778
779 if ( needInit )
780 {
781 state->m_pPropGrid = m_pPropGrid;
782 state->InitNonCatMode();
783 }
784
785 if ( label.length() )
786 {
787 wxASSERT_MSG( !pageObj->m_label.length(),
788 wxT("If page label is given in constructor, empty label must be given in AddPage"));
789 pageObj->m_label = label;
790 }
791
792 pageObj->m_id = m_nextTbInd;
793
794 if ( isPageInserted )
795 m_arrPages.Add( (void*)pageObj );
796
797#if wxUSE_TOOLBAR
798 if ( m_windowStyle & wxPG_TOOLBAR )
799 {
800 if ( !m_pToolbar )
801 RecreateControls();
802
803 if ( !(GetExtraStyle()&wxPG_EX_HIDE_PAGE_BUTTONS) )
804 {
805 wxASSERT( m_pToolbar );
806
807 // Add separator before first page.
808 if ( GetPageCount() < 2 && (GetExtraStyle()&wxPG_EX_MODE_BUTTONS) &&
809 m_pToolbar->GetToolsCount() < 3 )
810 m_pToolbar->AddSeparator();
811
812 if ( &bmp != &wxNullBitmap )
813 m_pToolbar->AddTool(m_nextTbInd,label,bmp,label,wxITEM_RADIO);
814 //m_pToolbar->InsertTool(index+3,m_nextTbInd,bmp);
815 else
816 m_pToolbar->AddTool(m_nextTbInd,label,wxBitmap( (const char**)gs_xpm_defpage ),
817 label,wxITEM_RADIO);
818
819 m_nextTbInd++;
820
821 m_pToolbar->Realize();
822 }
823 }
824#else
825 wxUnusedVar(bmp);
826#endif
827
828 // If selected page was above the point of insertion, fix the current page index
829 if ( isPageInserted )
830 {
831 if ( m_selPage >= index )
832 {
833 m_selPage += 1;
834 }
835 }
836 else
837 {
838 // Set this value only when adding the first page
839 m_selPage = 0;
840 }
841
842 pageObj->Init();
843
844 m_iFlags |= wxPG_MAN_FL_PAGE_INSERTED;
845
846 wxASSERT( pageObj->GetGrid() );
847
848 return index;
849}
850
851// -----------------------------------------------------------------------
852
853bool wxPropertyGridManager::IsAnyModified() const
854{
855 size_t i;
856 for ( i=0; i<GetPageCount(); i++ )
857 {
858 if ( ((wxPropertyGridPage*)m_arrPages.Item(i))->GetStatePtr()->m_anyModified )
859 return true;
860 }
861 return false;
862}
863
864// -----------------------------------------------------------------------
865
866bool wxPropertyGridManager::IsPageModified( size_t index ) const
867{
868 if ( ((wxPropertyGridPage*)m_arrPages.Item(index))->GetStatePtr()->m_anyModified )
869 return true;
870 return false;
871}
872
873// -----------------------------------------------------------------------
874
875wxPGProperty* wxPropertyGridManager::GetPageRoot( int index ) const
876{
877 wxASSERT( index >= 0 );
878 wxASSERT( index < (int)m_arrPages.GetCount() );
879
880 return ((wxPropertyGridPage*)m_arrPages.Item(index))->GetStatePtr()->m_properties;
881}
882
883// -----------------------------------------------------------------------
884
885bool wxPropertyGridManager::RemovePage( int page )
886{
887 wxCHECK_MSG( (page >= 0) && (page < (int)GetPageCount()),
888 false,
889 wxT("invalid page index") );
890
891 wxPropertyGridPage* pd = (wxPropertyGridPage*)m_arrPages.Item(page);
892
893 if ( m_arrPages.GetCount() == 1 )
894 {
895 // Last page: do not remove page entry
896 m_pPropGrid->Clear();
897 m_selPage = -1;
898 m_iFlags &= ~wxPG_MAN_FL_PAGE_INSERTED;
899 pd->m_label.clear();
900 }
901 // Change selection if current is page
902 else if ( page == m_selPage )
903 {
904 if ( !m_pPropGrid->ClearSelection() )
905 return false;
906
907 // Substitute page to select
908 int substitute = page - 1;
909 if ( substitute < 0 )
910 substitute = page + 1;
911
912 SelectPage(substitute);
913 }
914
915 // Remove toolbar icon
916#if wxUSE_TOOLBAR
917 if ( HasFlag(wxPG_TOOLBAR) )
918 {
919 wxASSERT( m_pToolbar );
920
921 int toolPos = GetExtraStyle() & wxPG_EX_MODE_BUTTONS ? 3 : 0;
922 toolPos += page;
923
924 // Delete separator as well, for consistency
925 if ( (GetExtraStyle() & wxPG_EX_MODE_BUTTONS) &&
926 GetPageCount() == 1 )
927 m_pToolbar->DeleteToolByPos(2);
928
929 m_pToolbar->DeleteToolByPos(toolPos);
930 }
931#endif
932
933 if ( m_arrPages.GetCount() > 1 )
934 {
935 m_arrPages.RemoveAt(page);
936 delete pd;
937 }
938
939 // Adjust indexes that were above removed
940 if ( m_selPage > page )
941 m_selPage--;
942
943 return true;
944}
945
946// -----------------------------------------------------------------------
947
948bool wxPropertyGridManager::ProcessEvent( wxEvent& event )
949{
950 int evtType = event.GetEventType();
951
952 // NB: For some reason, under wxPython, Connect in Init doesn't work properly,
953 // so we'll need to call OnPropertyGridSelect manually. Multiple call's
954 // don't really matter.
955 if ( evtType == wxEVT_PG_SELECTED )
956 OnPropertyGridSelect((wxPropertyGridEvent&)event);
957
958 // Property grid events get special attention
959 if ( evtType >= wxPG_BASE_EVT_TYPE &&
960 evtType < (wxPG_MAX_EVT_TYPE) &&
961 m_selPage >= 0 )
962 {
963 wxPropertyGridPage* page = GetPage(m_selPage);
964 wxPropertyGridEvent* pgEvent = wxDynamicCast(&event, wxPropertyGridEvent);
965
966 // Add property grid events to appropriate custom pages
967 // but stop propagating to parent if page says it is
968 // handling everything.
969 if ( pgEvent && !page->m_isDefault )
970 {
971 /*if ( pgEvent->IsPending() )
972 page->AddPendingEvent(event);
973 else*/
974 page->ProcessEvent(event);
975
976 if ( page->IsHandlingAllEvents() )
977 event.StopPropagation();
978 }
979 }
980
981 return wxPanel::ProcessEvent(event);
982}
983
984// -----------------------------------------------------------------------
985
986void wxPropertyGridManager::RepaintSplitter( wxDC& dc, int new_splittery, int new_width,
987 int new_height, bool desc_too )
988{
989 int use_hei = new_height;
990
991 // Draw background
992 wxColour bgcol = GetBackgroundColour();
993 dc.SetBrush( bgcol );
994 dc.SetPen( bgcol );
995 int rect_hei = use_hei-new_splittery;
996 if ( !desc_too )
997 rect_hei = m_splitterHeight;
998 dc.DrawRectangle(0,new_splittery,new_width,rect_hei);
999 dc.SetPen ( wxSystemSettings::GetColour ( wxSYS_COLOUR_3DDKSHADOW ) );
1000 int splitter_bottom = new_splittery+m_splitterHeight - 1;
1001 int box_height = use_hei-splitter_bottom;
1002 if ( box_height > 1 )
1003 dc.DrawRectangle(0,splitter_bottom,new_width,box_height);
1004 else
1005 dc.DrawLine(0,splitter_bottom,new_width,splitter_bottom);
1006}
1007
1008// -----------------------------------------------------------------------
1009
1010void wxPropertyGridManager::RefreshHelpBox( int new_splittery, int new_width, int new_height )
1011{
1012 //if ( new_splittery == m_splitterY && new_width == m_width )
1013 // return;
1014
1015 int use_hei = new_height;
1016 use_hei--;
1017
1018 //wxRendererNative::Get().DrawSplitterSash(this,dc,
1019 //wxSize(width,m_splitterHeight),new_splittery,wxHORIZONTAL);
1020
1021 //wxRendererNative::Get().DrawSplitterBorder(this,dc,
1022 // wxRect(0,new_splittery,new_width,m_splitterHeight));
1023
1024 // Fix help control positions.
1025 int cap_hei = m_pPropGrid->m_fontHeight;
1026 int cap_y = new_splittery+m_splitterHeight+5;
1027 int cnt_y = cap_y+cap_hei+3;
1028 int sub_cap_hei = cap_y+cap_hei-use_hei;
1029 int cnt_hei = use_hei-cnt_y;
1030 if ( sub_cap_hei > 0 )
1031 {
1032 cap_hei -= sub_cap_hei;
1033 cnt_hei = 0;
1034 }
1035 if ( cap_hei <= 2 )
1036 {
1037 m_pTxtHelpCaption->Show( false );
1038 m_pTxtHelpContent->Show( false );
1039 }
1040 else
1041 {
1042 m_pTxtHelpCaption->SetSize(3,cap_y,new_width-6,cap_hei);
1043 m_pTxtHelpCaption->Wrap(-1);
1044 m_pTxtHelpCaption->Show( true );
1045 if ( cnt_hei <= 2 )
1046 {
1047 m_pTxtHelpContent->Show( false );
1048 }
1049 else
1050 {
1051 m_pTxtHelpContent->SetSize(3,cnt_y,new_width-6,cnt_hei);
1052 m_pTxtHelpContent->Show( true );
1053 }
1054 }
1055
1056 wxClientDC dc(this);
1057 RepaintSplitter( dc, new_splittery, new_width, new_height, true );
1058
1059 m_splitterY = new_splittery;
1060
1061 m_iFlags &= ~(wxPG_FL_DESC_REFRESH_REQUIRED);
1062}
1063
1064// -----------------------------------------------------------------------
1065
1066void wxPropertyGridManager::RecalculatePositions( int width, int height )
1067{
1068 int propgridY = 0;
1069 int propgridBottomY = height;
1070
1071 // Toolbar at the top.
1072#if wxUSE_TOOLBAR
1073 if ( m_pToolbar )
1074 {
1075 int tbHeight;
1076
1077 #if ( wxMINOR_VERSION < 6 || (wxMINOR_VERSION == 6 && wxRELEASE_NUMBER < 2) )
1078 tbHeight = -1;
1079 #else
1080 // In wxWidgets 2.6.2+, Toolbar default height may be broken
1081 #if defined(__WXMSW__)
1082 tbHeight = 24;
1083 #elif defined(__WXGTK__)
1084 tbHeight = -1; // 22;
1085 #elif defined(__WXMAC__)
1086 tbHeight = 22;
1087 #else
1088 tbHeight = 22;
1089 #endif
1090 #endif
1091
1092 m_pToolbar->SetSize(0,0,width,tbHeight);
1093 propgridY += m_pToolbar->GetSize().y;
1094 }
1095#endif
1096
1097 // Help box.
1098 if ( m_pTxtHelpCaption )
1099 {
1100 int new_splittery = m_splitterY;
1101
1102 // Move m_splitterY
1103 if ( ( m_splitterY >= 0 || m_nextDescBoxSize ) && m_height > 32 )
1104 {
1105 if ( m_nextDescBoxSize >= 0 )
1106 {
1107 new_splittery = m_height - m_nextDescBoxSize - m_splitterHeight;
1108 m_nextDescBoxSize = -1;
1109 }
1110 new_splittery += (height-m_height);
1111 }
1112 else
1113 {
1114 new_splittery = height - wxPGMAN_DEFAULT_NEGATIVE_SPLITTER_Y;
1115 if ( new_splittery < 32 )
1116 new_splittery = 32;
1117 }
1118
1119 // Check if beyond minimum.
1120 int nspy_min = propgridY + m_pPropGrid->m_lineHeight;
1121 if ( new_splittery < nspy_min )
1122 new_splittery = nspy_min;
1123
1124 propgridBottomY = new_splittery;
1125
1126 RefreshHelpBox( new_splittery, width, height );
1127 }
1128
1129 if ( m_iFlags & wxPG_FL_INITIALIZED )
1130 {
1131 int pgh = propgridBottomY - propgridY;
1132 m_pPropGrid->SetSize( 0, propgridY, width, pgh );
1133
1134 m_extraHeight = height - pgh;
1135
1136 m_width = width;
1137 m_height = height;
1138 }
1139}
1140
1141// -----------------------------------------------------------------------
1142
1143void wxPropertyGridManager::SetDescBoxHeight( int ht, bool refresh )
1144{
1145 if ( m_windowStyle & wxPG_DESCRIPTION )
1146 {
1147 m_nextDescBoxSize = ht;
1148 if ( refresh )
1149 RecalculatePositions(m_width, m_height);
1150 }
1151}
1152
1153// -----------------------------------------------------------------------
1154
1155int wxPropertyGridManager::GetDescBoxHeight() const
1156{
1157 return GetClientSize().y - m_splitterY;
1158}
1159
1160// -----------------------------------------------------------------------
1161
1162void wxPropertyGridManager::OnPaint( wxPaintEvent& WXUNUSED(event) )
1163{
1164 wxPaintDC dc(this);
1165
1166 // Update everything inside the box
1167 wxRect r = GetUpdateRegion().GetBox();
1168
1169 // Repaint splitter?
1170 int r_bottom = r.y + r.height;
1171 int splitter_bottom = m_splitterY + m_splitterHeight;
1172 if ( r.y < splitter_bottom && r_bottom >= m_splitterY )
1173 RepaintSplitter( dc, m_splitterY, m_width, m_height, false );
1174}
1175
1176// -----------------------------------------------------------------------
1177
1178void wxPropertyGridManager::Refresh(bool eraseBackground, const wxRect* rect )
1179{
1180 m_pPropGrid->Refresh(eraseBackground);
1181 wxWindow::Refresh(eraseBackground,rect);
1182}
1183
1184// -----------------------------------------------------------------------
1185
1186void wxPropertyGridManager::RefreshProperty( wxPGProperty* p )
1187{
1188 wxPropertyGrid* grid = p->GetGrid();
1189
1190 if ( GetPage(m_selPage)->GetStatePtr() == p->GetParent()->GetParentState() )
1191 grid->RefreshProperty(p);
1192}
1193
1194// -----------------------------------------------------------------------
1195
1196void wxPropertyGridManager::RecreateControls()
1197{
1198
1199 bool was_shown = IsShown();
1200 if ( was_shown )
1201 Show ( false );
1202
1203 wxWindowID baseId = m_pPropGrid->GetId();
1204 if ( baseId < 0 )
1205 baseId = wxPG_MAN_ALTERNATE_BASE_ID;
1206
1207#if wxUSE_TOOLBAR
1208 if ( m_windowStyle & wxPG_TOOLBAR )
1209 {
1210 // Has toolbar.
1211 if ( !m_pToolbar )
1212 {
1213 m_pToolbar = new wxToolBar(this,baseId+ID_ADVTOOLBAR_OFFSET,
1214 wxDefaultPosition,wxDefaultSize,
1215 ((GetExtraStyle()&wxPG_EX_NO_FLAT_TOOLBAR)?0:wxTB_FLAT)
1216 /*| wxTB_HORIZONTAL | wxNO_BORDER*/ );
1217
1218 #if defined(__WXMSW__)
1219 // Eliminate toolbar flicker on XP
1220 // NOTE: Not enabled since it corrupts drawing somewhat.
1221
1222 /*
1223 #ifndef WS_EX_COMPOSITED
1224 #define WS_EX_COMPOSITED 0x02000000L
1225 #endif
1226
1227 HWND hWnd = (HWND)m_pToolbar->GetHWND();
1228
1229 ::SetWindowLong( hWnd, GWL_EXSTYLE,
1230 ::GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_COMPOSITED );
1231 */
1232
1233 #endif
1234
1235 m_pToolbar->SetCursor ( *wxSTANDARD_CURSOR );
1236
1237 if ( (GetExtraStyle()&wxPG_EX_MODE_BUTTONS) )
1238 {
1239 wxString desc1(_("Categorized Mode"));
1240 wxString desc2(_("Alphabetic Mode"));
1241 m_pToolbar->AddTool(baseId+ID_ADVTBITEMSBASE_OFFSET+0,
1242 desc1,wxBitmap ( (const char**)gs_xpm_catmode ),
1243 desc1,wxITEM_RADIO);
1244 m_pToolbar->AddTool(baseId+ID_ADVTBITEMSBASE_OFFSET+1,
1245 desc2,wxBitmap ( (const char**)gs_xpm_noncatmode ),
1246 desc2,wxITEM_RADIO);
1247 m_pToolbar->Realize();
1248 }
1249
1250 }
1251
1252 if ( (GetExtraStyle()&wxPG_EX_MODE_BUTTONS) )
1253 {
1254 // Toggle correct mode button.
1255 // TODO: This doesn't work in wxMSW (when changing,
1256 // both items will get toggled).
1257 int toggle_but_on_ind = ID_ADVTBITEMSBASE_OFFSET+0;
1258 int toggle_but_off_ind = ID_ADVTBITEMSBASE_OFFSET+1;
1259 if ( m_pPropGrid->m_pState->IsInNonCatMode() )
1260 {
1261 toggle_but_on_ind++;
1262 toggle_but_off_ind--;
1263 }
1264
1265 m_pToolbar->ToggleTool(baseId+toggle_but_on_ind,true);
1266 m_pToolbar->ToggleTool(baseId+toggle_but_off_ind,false);
1267 }
1268
1269 }
1270 else
1271 {
1272 // No toolbar.
1273 if ( m_pToolbar )
1274 m_pToolbar->Destroy();
1275 m_pToolbar = (wxToolBar*) NULL;
1276 }
1277#endif
1278
1279 if ( m_windowStyle & wxPG_DESCRIPTION )
1280 {
1281 // Has help box.
1282 m_pPropGrid->m_iFlags |= (wxPG_FL_NOSTATUSBARHELP);
1283
1284 if ( !m_pTxtHelpCaption )
1285 {
1286 m_pTxtHelpCaption = new wxStaticText (this,baseId+ID_ADVHELPCAPTION_OFFSET,wxEmptyString);
1287 m_pTxtHelpCaption->SetFont( m_pPropGrid->m_captionFont );
1288 m_pTxtHelpCaption->SetCursor ( *wxSTANDARD_CURSOR );
1289 }
1290 if ( !m_pTxtHelpContent )
1291 {
1292 m_pTxtHelpContent = new wxStaticText (this,baseId+ID_ADVHELPCONTENT_OFFSET,
1293 wxEmptyString,wxDefaultPosition,wxDefaultSize,wxALIGN_LEFT|wxST_NO_AUTORESIZE);
1294 m_pTxtHelpContent->SetCursor ( *wxSTANDARD_CURSOR );
1295 }
1296 }
1297 else
1298 {
1299 // No help box.
1300 m_pPropGrid->m_iFlags &= ~(wxPG_FL_NOSTATUSBARHELP);
1301
1302 if ( m_pTxtHelpCaption )
1303 m_pTxtHelpCaption->Destroy();
1304
1305 m_pTxtHelpCaption = (wxStaticText*) NULL;
1306
1307 if ( m_pTxtHelpContent )
1308 m_pTxtHelpContent->Destroy();
1309
1310 m_pTxtHelpContent = (wxStaticText*) NULL;
1311 }
1312
1313 int width, height;
1314
1315 GetClientSize(&width,&height);
1316
1317 RecalculatePositions(width,height);
1318
1319 if ( was_shown )
1320 Show ( true );
1321}
1322
1323// -----------------------------------------------------------------------
1324
1325wxPGProperty* wxPropertyGridManager::DoGetPropertyByName( const wxString& name ) const
1326{
1327 size_t i;
1328 for ( i=0; i<GetPageCount(); i++ )
1329 {
1330 wxPropertyGridPageState* pState = ((wxPropertyGridPage*)m_arrPages.Item(i))->GetStatePtr();
1331 wxPGProperty* p = pState->BaseGetPropertyByName(name);
1332 if ( p )
1333 {
1334 return p;
1335 }
1336 }
1337 return NULL;
1338}
1339
1340// -----------------------------------------------------------------------
1341
1342bool wxPropertyGridManager::EnsureVisible( wxPGPropArg id )
1343{
1344 wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false)
1345
1346 wxPropertyGridPageState* parentState = p->GetParentState();
1347
1348 // Select correct page.
1349 if ( m_pPropGrid->m_pState != parentState )
1350 DoSelectPage( GetPageByState(parentState) );
1351
1352 return m_pPropGrid->EnsureVisible(id);
1353}
1354
1355// -----------------------------------------------------------------------
1356
1357size_t wxPropertyGridManager::GetChildrenCount( int page_index )
1358{
1359 return GetChildrenCount( GetPage(page_index)->GetStatePtr()->m_properties );
1360}
1361
1362// -----------------------------------------------------------------------
1363
1364void wxPropertyGridManager::OnToolbarClick( wxCommandEvent &event )
1365{
1366 int id = event.GetId();
1367 if ( id >= 0 )
1368 {
1369 int baseId = m_pPropGrid->GetId();
1370 if ( baseId < 0 )
1371 baseId = wxPG_MAN_ALTERNATE_BASE_ID;
1372
1373 if ( id == ( baseId + ID_ADVTBITEMSBASE_OFFSET + 0 ) )
1374 {
1375 // Categorized mode.
1376 if ( m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES )
1377 m_pPropGrid->EnableCategories( true );
1378 }
1379 else if ( id == ( baseId + ID_ADVTBITEMSBASE_OFFSET + 1 ) )
1380 {
1381 // Alphabetic mode.
1382 if ( !(m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES) )
1383 m_pPropGrid->EnableCategories( false );
1384 }
1385 else
1386 {
1387 // Page Switching.
1388
1389 int index = -1;
1390 size_t i;
1391 wxPropertyGridPage* pdc;
1392
1393 // Find page with given id.
1394 for ( i=0; i<GetPageCount(); i++ )
1395 {
1396 pdc = (wxPropertyGridPage*)m_arrPages.Item(i);
1397 if ( pdc->m_id == id )
1398 {
1399 index = i;
1400 break;
1401 }
1402 }
1403
1404 wxASSERT( index >= 0 );
1405
1406 if ( DoSelectPage( index ) )
1407 {
1408
1409 // Event dispatching must be last.
1410 m_pPropGrid->SendEvent( wxEVT_PG_PAGE_CHANGED, (wxPGProperty*) NULL );
1411
1412 }
1413 else
1414 {
1415 // TODO: Depress the old button on toolbar.
1416 }
1417
1418 }
1419 }
1420}
1421
1422// -----------------------------------------------------------------------
1423
1424void wxPropertyGridManager::SetDescription( const wxString& label, const wxString& content )
1425{
1426 if ( m_pTxtHelpCaption )
1427 {
1428 wxSize osz1 = m_pTxtHelpCaption->GetSize();
1429 wxSize osz2 = m_pTxtHelpContent->GetSize();
1430
1431 m_pTxtHelpCaption->SetLabel(label);
1432 m_pTxtHelpContent->SetLabel(content);
1433
1434 m_pTxtHelpCaption->SetSize(-1,osz1.y);
1435 m_pTxtHelpContent->SetSize(-1,osz2.y);
1436
1437 if ( (m_iFlags & wxPG_FL_DESC_REFRESH_REQUIRED) || (osz2.x<(m_width-10)) )
1438 RefreshHelpBox( m_splitterY, m_width, m_height );
1439 }
1440}
1441
1442// -----------------------------------------------------------------------
1443
1444void wxPropertyGridManager::SetDescribedProperty( wxPGProperty* p )
1445{
1446 if ( m_pTxtHelpCaption )
1447 {
1448 if ( p )
1449 {
1450 SetDescription( p->GetLabel(), p->GetHelpString() );
1451 }
1452 else
1453 {
1454 m_pTxtHelpCaption->SetLabel(wxEmptyString);
1455 m_pTxtHelpContent->SetLabel(wxEmptyString);
1456 }
1457 }
1458}
1459
1460// -----------------------------------------------------------------------
1461
1462void wxPropertyGridManager::SetSplitterLeft( bool subProps, bool allPages )
1463{
1464 if ( !allPages )
1465 {
1466 m_pPropGrid->SetSplitterLeft(subProps);
1467 }
1468 else
1469 {
1470 wxClientDC dc(this);
1471 dc.SetFont(m_pPropGrid->m_font);
1472
1473 int highest = 0;
1474 unsigned int i;
1475
1476 for ( i=0; i<GetPageCount(); i++ )
1477 {
1478 int maxW = m_pState->GetColumnFitWidth(dc, GETPAGESTATE(i)->m_properties, 0, subProps );
1479 maxW += m_pPropGrid->m_marginWidth;
1480 if ( maxW > highest )
1481 highest = maxW;
1482 }
1483
1484 if ( highest > 0 )
1485 m_pPropGrid->SetSplitterPosition( highest );
1486
1487 m_pPropGrid->m_iFlags |= wxPG_FL_DONT_CENTER_SPLITTER;
1488 }
1489}
1490
1491// -----------------------------------------------------------------------
1492
1493void wxPropertyGridManager::OnPropertyGridSelect( wxPropertyGridEvent& event )
1494{
1495 // Check id.
1496 wxASSERT_MSG( GetId() == m_pPropGrid->GetId(),
1497 wxT("wxPropertyGridManager id must be set with wxPropertyGridManager::SetId (not wxWindow::SetId).") );
1498
1499 SetDescribedProperty(event.GetProperty());
1500 event.Skip();
1501}
1502
1503// -----------------------------------------------------------------------
1504
1505void wxPropertyGridManager::OnResize( wxSizeEvent& WXUNUSED(event) )
1506{
1507 int width, height;
1508
1509 GetClientSize(&width,&height);
1510
1511 if ( m_width == -12345 )
1512 RecreateControls();
1513
1514 RecalculatePositions(width,height);
1515}
1516
1517// -----------------------------------------------------------------------
1518
1519void wxPropertyGridManager::OnMouseEntry( wxMouseEvent& WXUNUSED(event) )
1520{
1521 // Correct cursor. This is required atleast for wxGTK, for which
1522 // setting button's cursor to *wxSTANDARD_CURSOR does not work.
1523 SetCursor( wxNullCursor );
1524 m_onSplitter = 0;
1525}
1526
1527// -----------------------------------------------------------------------
1528
1529void wxPropertyGridManager::OnMouseMove( wxMouseEvent &event )
1530{
1531 if ( !m_pTxtHelpCaption )
1532 return;
1533
1534 int y = event.m_y;
1535
1536 if ( m_dragStatus > 0 )
1537 {
1538 int sy = y - m_dragOffset;
1539
1540 // Calculate drag limits
1541 int bottom_limit = m_height - m_splitterHeight + 1;
1542 int top_limit = m_pPropGrid->m_lineHeight;
1543#if wxUSE_TOOLBAR
1544 if ( m_pToolbar ) top_limit += m_pToolbar->GetSize().y;
1545#endif
1546
1547 if ( sy >= top_limit && sy < bottom_limit )
1548 {
1549
1550 int change = sy - m_splitterY;
1551 if ( change )
1552 {
1553 m_splitterY = sy;
1554
1555 m_pPropGrid->SetSize( m_width, m_splitterY - m_pPropGrid->GetPosition().y );
1556 RefreshHelpBox( m_splitterY, m_width, m_height );
1557
1558 m_extraHeight -= change;
1559 InvalidateBestSize();
1560 }
1561
1562 }
1563
1564 }
1565 else
1566 {
1567 if ( y >= m_splitterY && y < (m_splitterY+m_splitterHeight+2) )
1568 {
1569 SetCursor ( m_cursorSizeNS );
1570 m_onSplitter = 1;
1571 }
1572 else
1573 {
1574 if ( m_onSplitter )
1575 {
1576 SetCursor ( wxNullCursor );
1577 }
1578 m_onSplitter = 0;
1579 }
1580 }
1581}
1582
1583// -----------------------------------------------------------------------
1584
1585void wxPropertyGridManager::OnMouseClick( wxMouseEvent &event )
1586{
1587 int y = event.m_y;
1588
1589 // Click on splitter.
1590 if ( y >= m_splitterY && y < (m_splitterY+m_splitterHeight+2) )
1591 {
1592 if ( m_dragStatus == 0 )
1593 {
1594 //
1595 // Begin draggin the splitter
1596 //
1597
1598 BEGIN_MOUSE_CAPTURE
1599
1600 m_dragStatus = 1;
1601
1602 m_dragOffset = y - m_splitterY;
1603
1604 }
1605 }
1606}
1607
1608// -----------------------------------------------------------------------
1609
1610void wxPropertyGridManager::OnMouseUp( wxMouseEvent &event )
1611{
1612 // No event type check - basicly calling this method should
1613 // just stop dragging.
1614
1615 if ( m_dragStatus >= 1 )
1616 {
1617 //
1618 // End Splitter Dragging
1619 //
1620
1621 int y = event.m_y;
1622
1623 // DO NOT ENABLE FOLLOWING LINE!
1624 // (it is only here as a reminder to not to do it)
1625 //m_splitterY = y;
1626
1627 // This is necessary to return cursor
1628 END_MOUSE_CAPTURE
1629
1630 // Set back the default cursor, if necessary
1631 if ( y < m_splitterY || y >= (m_splitterY+m_splitterHeight+2) )
1632 {
1633 SetCursor ( wxNullCursor );
1634 }
1635
1636 m_dragStatus = 0;
1637 }
1638}
1639
1640// -----------------------------------------------------------------------
1641
1642void wxPropertyGridManager::SetSplitterPosition( int pos, int splitterColumn )
1643{
1644 wxASSERT_MSG( GetPageCount(),
1645 wxT("SetSplitterPosition() has no effect until pages have been added") );
1646
1647 size_t i;
1648 for ( i=0; i<GetPageCount(); i++ )
1649 {
1650 wxPropertyGridPage* page = GetPage(i);
1651 page->DoSetSplitterPositionThisPage( pos, splitterColumn );
1652 }
1653
1654 m_pPropGrid->SetInternalFlag(wxPG_FL_SPLITTER_PRE_SET);
1655}
1656
1657// -----------------------------------------------------------------------
1658// wxPGVIterator_Manager
1659// -----------------------------------------------------------------------
1660
1661// Default returned by wxPropertyGridInterface::CreateVIterator().
1662class wxPGVIteratorBase_Manager : public wxPGVIteratorBase
1663{
1664public:
1665 wxPGVIteratorBase_Manager( wxPropertyGridManager* manager, int flags )
1666 : m_manager(manager), m_flags(flags), m_curPage(0)
1667 {
1668 m_it.Init(manager->GetPage(0), flags);
1669 }
1670 virtual ~wxPGVIteratorBase_Manager() { }
1671 virtual void Next()
1672 {
1673 m_it.Next();
1674
1675 // Next page?
1676 if ( m_it.AtEnd() )
1677 {
1678 m_curPage++;
1679 if ( m_curPage < m_manager->GetPageCount() )
1680 m_it.Init( m_manager->GetPage(m_curPage), m_flags );
1681 }
1682 }
1683private:
1684 wxPropertyGridManager* m_manager;
1685 int m_flags;
1686 unsigned int m_curPage;
1687};
1688
1689wxPGVIterator wxPropertyGridManager::GetVIterator( int flags ) const
1690{
1691 return wxPGVIterator( new wxPGVIteratorBase_Manager( (wxPropertyGridManager*)this, flags ) );
1692}