X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bcf324bebe65cd7ee49c139533ceea52dceb4b91..4cd4a9ff70cdfdfc054747d7dae6101da3f94c03:/src/propgrid/propgrid.cpp diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index a9c96cb0ae..62459e6476 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -63,8 +63,6 @@ #include "wx/timer.h" #include "wx/dcbuffer.h" -#include "wx/clipbrd.h" -#include "wx/dataobj.h" #ifdef __WXMSW__ #include "wx/msw/private.h" @@ -154,6 +152,15 @@ public: IMPLEMENT_DYNAMIC_CLASS(wxPGGlobalVarsClassManager, wxModule) +// When wxPG is loaded dynamically after the application is already running +// then the built-in module system won't pick this one up. Add it manually. +void wxPGInitResourceModule() +{ + wxModule* module = new wxPGGlobalVarsClassManager; + module->Init(); + wxModule::RegisterModule(module); +} + wxPGGlobalVarsClass* wxPGGlobalVars = NULL; @@ -176,7 +183,7 @@ wxPGGlobalVarsClass::wxPGGlobalVarsClass() wxVariant v; - // Prepare some shared variants + // Prepare some shared variants m_vEmptyString = wxString(); m_vZero = (long) 0; m_vMinusOne = (long) -1; @@ -188,14 +195,13 @@ wxPGGlobalVarsClass::wxPGGlobalVarsClass() m_strlong = wxS("long"); m_strbool = wxS("bool"); m_strlist = wxS("list"); + m_strDefaultValue = wxS("DefaultValue"); m_strMin = wxS("Min"); m_strMax = wxS("Max"); m_strUnits = wxS("Units"); m_strInlineHelp = wxS("InlineHelp"); -#ifdef __WXDEBUG__ m_warnings = 0; -#endif } @@ -231,46 +237,6 @@ void wxPropertyGridInitGlobalsIfNeeded() { } -// ----------------------------------------------------------------------- -// wxPGTLWHandler -// Intercepts Close-events sent to wxPropertyGrid's top-level parent, -// and tries to commit property value. -// ----------------------------------------------------------------------- - -class wxPGTLWHandler : public wxEvtHandler -{ -public: - - wxPGTLWHandler( wxPropertyGrid* pg ) - : wxEvtHandler() - { - m_pg = pg; - } - -protected: - - void OnClose( wxCloseEvent& event ) - { - // ClearSelection forces value validation/commit. - if ( event.CanVeto() && !m_pg->ClearSelection() ) - { - event.Veto(); - return; - } - - event.Skip(); - } - -private: - wxPropertyGrid* m_pg; - - DECLARE_EVENT_TABLE() -}; - -BEGIN_EVENT_TABLE(wxPGTLWHandler, wxEvtHandler) - EVT_CLOSE(wxPGTLWHandler::OnClose) -END_EVENT_TABLE() - // ----------------------------------------------------------------------- // wxPGCanvas // ----------------------------------------------------------------------- @@ -467,7 +433,6 @@ void wxPropertyGrid::Init1() m_propHover = NULL; m_eventObject = this; m_curFocused = NULL; - m_tlwHandler = NULL; m_sortFunction = NULL; m_inDoPropertyChanged = 0; m_inCommitChangesFromEditor = 0; @@ -498,10 +463,10 @@ void wxPropertyGrid::Init1() #endif #ifndef wxPG_ICON_WIDTH - m_expandbmp = NULL; - m_collbmp = NULL; - m_iconWidth = 11; - m_iconHeight = 11; + m_expandbmp = NULL; + m_collbmp = NULL; + m_iconWidth = 11; + m_iconHeight = 11; #else m_iconWidth = wxPG_ICON_WIDTH; #endif @@ -558,31 +523,22 @@ void wxPropertyGrid::Init2() #ifndef wxPG_ICON_WIDTH // create two bitmap nodes for drawing - m_expandbmp = new wxBitmap(expand_xpm); - m_collbmp = new wxBitmap(collapse_xpm); + m_expandbmp = new wxBitmap(expand_xpm); + m_collbmp = new wxBitmap(collapse_xpm); - // calculate average font height for bitmap centering + // calculate average font height for bitmap centering - m_iconWidth = m_expandbmp->GetWidth(); - m_iconHeight = m_expandbmp->GetHeight(); + m_iconWidth = m_expandbmp->GetWidth(); + m_iconHeight = m_expandbmp->GetHeight(); #endif m_curcursor = wxCURSOR_ARROW; m_cursorSizeWE = new wxCursor( wxCURSOR_SIZEWE ); - // adjust bitmap icon y position so they are centered + // adjust bitmap icon y position so they are centered m_vspacing = wxPG_DEFAULT_VSPACING; - if ( !m_font.Ok() ) - { - wxFont useFont = wxScrolledWindow::GetFont(); - wxScrolledWindow::SetOwnFont( useFont ); - } - else - { - // This should be otherwise called by SetOwnFont - CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING ); - } + CalculateFontAndBitmapStuff( wxPG_DEFAULT_VSPACING ); // Allocate cell datas indirectly by calling setter m_propertyDefaultCell.SetBgCol(*wxBLACK); @@ -593,15 +549,15 @@ void wxPropertyGrid::Init2() // This helps with flicker SetBackgroundStyle( wxBG_STYLE_CUSTOM ); - // Hook the TLW - wxPGTLWHandler* handler = new wxPGTLWHandler(this); - m_tlp = ::wxGetTopLevelParent(this); - m_tlwHandler = handler; - m_tlp->PushEventHandler(handler); + // Hook the top-level parent + m_tlp = NULL; + m_tlpClosed = NULL; + m_tlpClosedTime = 0; + OnTLPChanging(::wxGetTopLevelParent(this)); - // set virtual size to this window size + // set virtual size to this window size wxSize wndsize = GetSize(); - SetVirtualSize(wndsize.GetWidth(), wndsize.GetWidth()); + SetVirtualSize(wndsize.GetWidth(), wndsize.GetWidth()); m_timeCreated = ::wxGetLocalTimeMillis(); @@ -634,15 +590,13 @@ wxPropertyGrid::~wxPropertyGrid() if ( m_iFlags & wxPG_FL_MOUSE_CAPTURED ) m_canvas->ReleaseMouse(); - wxPGTLWHandler* handler = (wxPGTLWHandler*) m_tlwHandler; - m_tlp->RemoveEventHandler(handler); - delete handler; + // Call with NULL to disconnect event handling + OnTLPChanging(NULL); -#ifdef __WXDEBUG__ - if ( IsEditorsValueModified() ) - ::wxMessageBox(wxS("Most recent change in property editor was lost!!!\n\n(if you don't want this to happen, close your frames and dialogs using Close(false).)"), - wxS("wxPropertyGrid Debug Warning") ); -#endif + wxASSERT_MSG( !IsEditorsValueModified(), + wxS("Most recent change in property editor was lost!!! ") + wxS("(if you don't want this to happen, close your frames ") + wxS("and dialogs using Close(false).)") ); #if wxPG_DOUBLE_BUFFER if ( m_doubleBuffer ) @@ -657,8 +611,8 @@ wxPropertyGrid::~wxPropertyGrid() delete m_cursorSizeWE; #ifndef wxPG_ICON_WIDTH - delete m_expandbmp; - delete m_collbmp; + delete m_expandbmp; + delete m_collbmp; #endif // Delete common value records @@ -837,28 +791,102 @@ void wxPropertyGrid::SetExtraStyle( long exStyle ) // returns the best acceptable minimal size wxSize wxPropertyGrid::DoGetBestSize() const { - int hei = 15; - if ( m_lineHeight > hei ) - hei = m_lineHeight; - wxSize sz = wxSize( 60, hei+40 ); + int lineHeight = wxMax(15, m_lineHeight); + // don't make the grid too tall (limit height to 10 items) but don't + // make it too small neither + int numLines = wxMin + ( + wxMax(m_pState->m_properties->GetChildCount(), 3), + 10 + ); + + const wxSize sz = wxSize(60, lineHeight*numLines + 40); CacheBestSize(sz); return sz; } +// ----------------------------------------------------------------------- + +void wxPropertyGrid::OnTLPChanging( wxWindow* newTLP ) +{ + wxLongLong currentTime = ::wxGetLocalTimeMillis(); + + // + // Parent changed so let's redetermine and re-hook the + // correct top-level window. + if ( m_tlp ) + { + m_tlp->Disconnect( wxEVT_CLOSE_WINDOW, + wxCloseEventHandler(wxPropertyGrid::OnTLPClose), + NULL, this ); + m_tlpClosed = m_tlp; + m_tlpClosedTime = currentTime; + } + + if ( newTLP ) + { + // Only accept new tlp if same one was not just dismissed. + if ( newTLP != m_tlpClosed || + m_tlpClosedTime+250 < currentTime ) + { + newTLP->Connect( wxEVT_CLOSE_WINDOW, + wxCloseEventHandler(wxPropertyGrid::OnTLPClose), + NULL, this ); + m_tlpClosed = NULL; + } + else + { + newTLP = NULL; + } + } + + m_tlp = newTLP; +} + +// ----------------------------------------------------------------------- + +void wxPropertyGrid::OnTLPClose( wxCloseEvent& event ) +{ + // ClearSelection forces value validation/commit. + if ( event.CanVeto() && !ClearSelection() ) + { + event.Veto(); + return; + } + + // Ok, it can close, set tlp pointer to NULL. Some other event + // handler can of course veto the close, but our OnIdle() should + // then be able to regain the tlp pointer. + OnTLPChanging(NULL); + + event.Skip(); +} + +// ----------------------------------------------------------------------- + +bool wxPropertyGrid::Reparent( wxWindowBase *newParent ) +{ + OnTLPChanging((wxWindow*)newParent); + + bool res = wxScrolledWindow::Reparent(newParent); + + return res; +} + // ----------------------------------------------------------------------- // wxPropertyGrid Font and Colour Methods // ----------------------------------------------------------------------- void wxPropertyGrid::CalculateFontAndBitmapStuff( int vspacing ) { - int x = 0, y = 0; + int x = 0, y = 0; m_captionFont = wxScrolledWindow::GetFont(); - GetTextExtent(wxS("jG"), &x, &y, 0, 0, &m_captionFont); + GetTextExtent(wxS("jG"), &x, &y, 0, 0, &m_captionFont); m_subgroup_extramargin = x + (x/2); - m_fontHeight = y; + m_fontHeight = y; #if wxPG_USE_RENDERER_NATIVE m_iconWidth = wxPG_ICON_WIDTH; @@ -887,7 +915,7 @@ void wxPropertyGrid::CalculateFontAndBitmapStuff( int vspacing ) m_marginWidth = m_gutterWidth*2 + m_iconWidth; m_captionFont.SetWeight(wxBOLD); - GetTextExtent(wxS("jG"), &x, &y, 0, 0, &m_captionFont); + GetTextExtent(wxS("jG"), &x, &y, 0, 0, &m_captionFont); m_lineHeight = m_fontHeight+(2*m_spacingy)+1; @@ -1045,32 +1073,14 @@ bool wxPropertyGrid::SetFont( const wxFont& font ) // Must disable active editor. ClearSelection(false); - // TODO: Following code is disabled with wxMac because - // it is reported to fail. I (JMS) cannot debug it - // personally right now. - // CS: should be fixed now, leaving old code in just in case, TODO: REMOVE -#if 1 // !defined(__WXMAC__) bool res = wxScrolledWindow::SetFont( font ); - if ( res ) + if ( res && GetParent()) // may not have been Create()ed yet { CalculateFontAndBitmapStuff( m_vspacing ); - - if ( m_pState ) - m_pState->CalculateFontAndBitmapStuff(m_vspacing); - Refresh(); } return res; -#else - // ** wxMAC Only ** - // TODO: Remove after SetFont crash fixed. - if ( m_iFlags & wxPG_FL_INITIALIZED ) - { - wxLogDebug(wxT("WARNING: propGrid.cpp: wxPropertyGrid::SetFont has been disabled on wxMac since there has been crash reported in it. If you are willing to debug the cause, replace line '#if !defined(__WXMAC__)' with line '#if 1' in wxPropertyGrid::SetFont.")); - } - return false; -#endif } // ----------------------------------------------------------------------- @@ -1670,7 +1680,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, int x = m_marginWidth - xRelMod; - const wxFont& normalfont = m_font; + wxFont normalFont = GetFont(); bool reallyFocused = (m_iFlags & wxPG_FL_FOCUSED) != 0; @@ -1707,7 +1717,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, // TODO: Only render columns that are within clipping region. - dc.SetFont(normalfont); + dc.SetFont(normalFont); wxPropertyGridConstIterator it( state, wxPG_ITERATE_VISIBLE, firstItem ); int endScanBottomY = lastItemBottomY + lh; @@ -1983,7 +1993,7 @@ int wxPropertyGrid::DoDrawItems( wxDC& dc, } if ( fontChanged ) - dc.SetFont(normalfont); + dc.SetFont(normalFont); y += rowHeight; } @@ -2141,8 +2151,6 @@ void wxPropertyGrid::Refresh( bool WXUNUSED(eraseBackground), void wxPropertyGrid::Clear() { - ClearSelection(false); - m_pState->DoClear(); m_propHover = NULL; @@ -2591,7 +2599,7 @@ void wxPropertyGrid::DoShowPropertyError( wxPGProperty* WXUNUSED(property), cons } #endif - ::wxMessageBox(msg, _T("Property Error")); + ::wxMessageBox(msg, wxT("Property Error")); } // ----------------------------------------------------------------------- @@ -2666,7 +2674,7 @@ bool wxPropertyGrid::DoOnValidationFailure( wxPGProperty* property, wxVariant& W wxString msg = m_validationInfo.m_failureMessage; if ( !msg.length() ) - msg = _T("You have entered invalid value. Press ESC to cancel editing."); + msg = wxT("You have entered invalid value. Press ESC to cancel editing."); DoShowPropertyError(property, msg); } @@ -2871,10 +2879,10 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) wxVariant pendingValue(selected->GetValueRef()); wxWindow* wnd = GetEditorControl(); + wxWindow* editorWnd = wxDynamicCast(event.GetEventObject(), wxWindow); int selFlags = 0; bool wasUnspecified = selected->IsValueUnspecified(); int usesAutoUnspecified = selected->UsesAutoUnspecified(); - bool valueIsPending = false; m_chgInfo_changedProperty = NULL; @@ -2920,17 +2928,19 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) if ( !buttonWasHandled ) { - if ( wnd ) + if ( wnd || m_wndEditor2 ) { // First call editor class' event handler. const wxPGEditor* editor = selected->GetEditorClass(); - if ( editor->OnEvent( this, selected, wnd, event ) ) + if ( editor->OnEvent( this, selected, editorWnd, event ) ) { // If changes, validate them if ( DoEditorValidate() ) { - if ( editor->GetValueFromControl( pendingValue, m_selected, wnd ) ) + if ( editor->GetValueFromControl( pendingValue, + m_selected, + wnd ) ) valueIsPending = true; } else @@ -2943,7 +2953,7 @@ void wxPropertyGrid::HandleCustomEditorEvent( wxEvent &event ) // Then the property's custom handler (must be always called, unless // validation failed). if ( !validationFailure ) - buttonWasHandled = selected->OnEvent( this, wnd, event ); + buttonWasHandled = selected->OnEvent( this, editorWnd, event ); } // SetValueInEvent(), as called in one of the functions referred above @@ -3007,24 +3017,25 @@ wxRect wxPropertyGrid::GetEditorWidgetRect( wxPGProperty* p, int column ) const { int itemy = p->GetY2(m_lineHeight); int vy = 0; - int cust_img_space = 0; int splitterX = m_pState->DoGetSplitterPosition(column-1); int colEnd = splitterX + m_pState->m_colWidths[column]; + int imageOffset = 0; // TODO: If custom image detection changes from current, change this. - if ( m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE /*p->m_flags & wxPG_PROP_CUSTOMIMAGE*/ ) + if ( m_iFlags & wxPG_FL_CUR_USES_CUSTOM_IMAGE ) { //m_iFlags |= wxPG_FL_CUR_USES_CUSTOM_IMAGE; - int imwid = p->OnMeasureImage().x; - if ( imwid < 1 ) imwid = wxPG_CUSTOM_IMAGE_WIDTH; - cust_img_space = imwid + wxCC_CUSTOM_IMAGE_MARGIN1 + wxCC_CUSTOM_IMAGE_MARGIN2; + int iw = p->OnMeasureImage().x; + if ( iw < 1 ) + iw = wxPG_CUSTOM_IMAGE_WIDTH; + imageOffset = p->GetImageOffset(iw); } return wxRect ( - splitterX+cust_img_space+wxPG_XBEFOREWIDGET+wxPG_CONTROL_MARGIN+1, + splitterX+imageOffset+wxPG_XBEFOREWIDGET+wxPG_CONTROL_MARGIN+1, itemy-vy, - colEnd-splitterX-wxPG_XBEFOREWIDGET-wxPG_CONTROL_MARGIN-cust_img_space-1, + colEnd-splitterX-wxPG_XBEFOREWIDGET-wxPG_CONTROL_MARGIN-imageOffset-1, m_lineHeight-1 ); } @@ -3234,10 +3245,14 @@ bool wxPropertyGrid::DoSelectProperty( wxPGProperty* p, unsigned int flags ) { /* if (p) + { wxLogDebug(wxT("SelectProperty( %s (%s[%i]) )"),p->m_label.c_str(), p->m_parent->m_label.c_str(),p->GetIndexInParent()); + } else + { wxLogDebug(wxT("SelectProperty( NULL, -1 )")); + } */ if ( m_inDoSelectProperty ) @@ -3777,16 +3792,10 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos ) m_pState->EnsureVirtualHeight(); -#ifdef __WXDEBUG__ - int by1 = m_pState->GetVirtualHeight(); - int by2 = m_pState->GetActualVirtualHeight(); - if ( by1 != by2 ) - { - wxString s = wxString::Format(wxT("VirtualHeight=%i, ActualVirtualHeight=%i, should match!"), by1, by2); - wxFAIL_MSG(s.c_str()); - wxLogDebug(s); - } -#endif + wxASSERT_LEVEL_2_MSG( + m_pState->GetVirtualHeight() == m_pState->GetActualVirtualHeight(), + "VirtualHeight and ActualVirtualHeight should match" + ); m_iFlags |= wxPG_FL_RECALCULATING_VIRTUAL_SIZE; @@ -3797,7 +3806,7 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos ) GetClientSize(&width,&height); // Now adjust virtual size. - SetVirtualSize(x, y); + SetVirtualSize(x, y); int xAmount = 0; int xPos = 0; @@ -3816,7 +3825,7 @@ void wxPropertyGrid::RecalculateVirtualSize( int forceXPos ) else if ( xPos > (xAmount-(width/wxPG_PIXELS_PER_UNIT)) ) xPos = 0; - int yAmount = (y+wxPG_PIXELS_PER_UNIT+2)/wxPG_PIXELS_PER_UNIT; + int yAmount = y / wxPG_PIXELS_PER_UNIT; int yPos = GetScrollPos( wxVERTICAL ); SetScrollbars( wxPG_PIXELS_PER_UNIT, wxPG_PIXELS_PER_UNIT, @@ -4294,7 +4303,7 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, wxMouseEvent &event if ( space ) { int tw, th; - GetTextExtent( tipString, &tw, &th, 0, 0, &m_font ); + GetTextExtent( tipString, &tw, &th, 0, 0 ); if ( tw > space ) { SetToolTip( tipString ); @@ -4847,9 +4856,7 @@ void wxPropertyGrid::HandleKeyEvent( wxKeyEvent &event, bool fromChild ) // Travel and expand/collapse int selectDir = -2; - if ( p->GetChildCount() && - !(p->m_flags & wxPG_PROP_DISABLED) - ) + if ( p->GetChildCount() ) { if ( action == wxPG_ACTION_COLLAPSE_PROPERTY || secondAction == wxPG_ACTION_COLLAPSE_PROPERTY ) { @@ -4960,6 +4967,14 @@ void wxPropertyGrid::OnIdle( wxIdleEvent& WXUNUSED(event) ) if ( newFocused != m_curFocused ) HandleFocusChange( newFocused ); + + // + // Check if top-level parent has changed + wxWindow* tlp = ::wxGetTopLevelParent(this); + if ( tlp != m_tlp ) + { + OnTLPChanging(tlp); + } } bool wxPropertyGrid::IsEditorFocused() const @@ -5059,11 +5074,7 @@ void wxPropertyGrid::OnFocusEvent( wxFocusEvent& event ) void wxPropertyGrid::OnChildFocusEvent( wxChildFocusEvent& event ) { HandleFocusChange((wxWindow*)event.GetEventObject()); - - // - // event.Skip() being commented out is aworkaround for bug reported - // in ticket #4840 (wxScrolledWindow problem with automatic scrolling). - //event.Skip(); + event.Skip(); } // ----------------------------------------------------------------------- @@ -5090,15 +5101,18 @@ void wxPropertyGrid::OnCaptureChange( wxMouseCaptureChangedEvent& WXUNUSED(event // ----------------------------------------------------------------------- // noDefCheck = true prevents infinite recursion. -wxPGEditor* wxPropertyGrid::RegisterEditorClass( wxPGEditor* editorClass, - bool noDefCheck ) +wxPGEditor* wxPropertyGrid::DoRegisterEditorClass( wxPGEditor* editorClass, + const wxString& editorName, + bool noDefCheck ) { wxASSERT( editorClass ); if ( !noDefCheck && wxPGGlobalVars->m_mapEditorClasses.empty() ) RegisterDefaultEditors(); - wxString name = editorClass->GetName(); + wxString name = editorName; + if ( name.length() == 0 ) + name = editorClass->GetName(); // Existing editor under this name? wxPGHashMapS2P::iterator vt_it = wxPGGlobalVars->m_mapEditorClasses.find(name); @@ -5235,7 +5249,6 @@ wxPGChoiceEntry::wxPGChoiceEntry() wxPGChoicesData::wxPGChoicesData() { - m_refCount = 1; } wxPGChoicesData::~wxPGChoicesData() @@ -5287,15 +5300,15 @@ wxPGChoiceEntry& wxPGChoicesData::Insert( int index, IMPLEMENT_DYNAMIC_CLASS(wxPropertyGridEvent, wxCommandEvent) -wxDEFINE_EVENT( wxEVT_PG_SELECTED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_CHANGING, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_CHANGED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_HIGHLIGHTED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_RIGHT_CLICK, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_PAGE_CHANGED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_ITEM_EXPANDED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_ITEM_COLLAPSED, wxPropertyGridEvent ) -wxDEFINE_EVENT( wxEVT_PG_DOUBLE_CLICK, wxPropertyGridEvent ) +wxDEFINE_EVENT( wxEVT_PG_SELECTED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_CHANGING, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_CHANGED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_HIGHLIGHTED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_RIGHT_CLICK, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_PAGE_CHANGED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_ITEM_EXPANDED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_ITEM_COLLAPSED, wxPropertyGridEvent ); +wxDEFINE_EVENT( wxEVT_PG_DOUBLE_CLICK, wxPropertyGridEvent ); // -----------------------------------------------------------------------