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