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