From f525476870e4baa3e5d303d94d8bc70026603b4c Mon Sep 17 00:00:00 2001 From: Jaakko Salli Date: Sun, 13 Dec 2009 12:00:04 +0000 Subject: [PATCH] Added wxPropertyGridManager header support; Refactored wxPropertyGrid DoSetSplitterPosition() code git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62867 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/propgrid/manager.h | 80 ++++-- include/wx/propgrid/propgrid.h | 45 +++- include/wx/propgrid/propgridpagestate.h | 3 +- interface/wx/propgrid/manager.h | 49 +++- interface/wx/propgrid/propgrid.h | 7 +- samples/propgrid/propgrid.cpp | 15 +- samples/propgrid/propgrid.h | 1 + src/propgrid/manager.cpp | 315 +++++++++++++++++++++++- src/propgrid/propgrid.cpp | 41 +-- src/propgrid/propgridpagestate.cpp | 9 +- 10 files changed, 491 insertions(+), 74 deletions(-) diff --git a/include/wx/propgrid/manager.h b/include/wx/propgrid/manager.h index 75db8dafdf..135803a929 100644 --- a/include/wx/propgrid/manager.h +++ b/include/wx/propgrid/manager.h @@ -23,6 +23,7 @@ #include "wx/button.h" #include "wx/textctrl.h" #include "wx/dialog.h" +#include // ----------------------------------------------------------------------- @@ -161,8 +162,7 @@ protected: */ virtual void DoSetSplitterPosition( int pos, int splitterColumn = 0, - bool allPages = false, - bool fromAutoCenter = false ); + int flags = wxPG_SPLITTER_REFRESH ); /** Page label (may be referred as name in some parts of documentation). Can be set in constructor, or passed in @@ -188,6 +188,11 @@ private: // ----------------------------------------------------------------------- +#if wxUSE_HEADERCTRL +class wxPGHeaderCtrl; +#endif + + /** @class wxPropertyGridManager wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid, @@ -534,7 +539,21 @@ public: return p->GetParentState()->DoSelectProperty(p, focus); } - /** Sets number of columns on given page (default is current page). + /** + Sets a column title. Default title for column 0 is "Property", + and "Value" for column 1. + + @remarks If header is not shown yet, then calling this + member function will make it visible. + */ + void SetColumnTitle( int idx, const wxString& title ); + + /** + Sets number of columns on given page (default is current page). + + @remarks If you use header, then you should always use this + member function to set the column count, instead of + ones present in wxPropertyGrid or wxPropertyGridPage. */ void SetColumnCount( int colCount, int page = -1 ); @@ -555,20 +574,40 @@ public: */ void SetSplitterLeft( bool subProps = false, bool allPages = true ); - /** Sets splitter position on individual page. */ - void SetPageSplitterPosition( int page, int pos, int column = 0 ) - { - GetPage(page)->DoSetSplitterPosition( pos, column ); - } + /** + Sets splitter position on individual page. - /** Sets splitter position for all pages. - @remarks - Splitter position cannot exceed grid size, and therefore setting it - during form creation may fail as initial grid size is often smaller - than desired splitter position, especially when sizers are being used. + @remarks If you use header, then you should always use this + member function to set the splitter position, instead of + ones present in wxPropertyGrid or wxPropertyGridPage. + */ + void SetPageSplitterPosition( int page, int pos, int column = 0 ); + + /** + Sets splitter position for all pages. + + @remarks Splitter position cannot exceed grid size, and therefore + setting it during form creation may fail as initial grid + size is often smaller than desired splitter position, + especially when sizers are being used. + + If you use header, then you should always use this + member function to set the splitter position, instead of + ones present in wxPropertyGrid or wxPropertyGridPage. */ void SetSplitterPosition( int pos, int column = 0 ); +#if wxUSE_HEADERCTRL + /** + Show or hide the property grid header control. It is hidden + by the default. + + @remarks Grid may look better if you use wxPG_NO_INTERNAL_BORDER + window style when showing a header. + */ + void ShowHeader(bool show = true); +#endif + protected: // @@ -600,13 +639,11 @@ public: virtual void SetWindowStyleFlag ( long style ); virtual bool Reparent( wxWindowBase *newParent ); +#ifndef SWIG + protected: virtual wxSize DoGetBestSize() const; -public: - -#ifndef SWIG - // // Event handlers // @@ -620,8 +657,8 @@ public: void OnToolbarClick( wxCommandEvent &event ); void OnResize( wxSizeEvent& event ); void OnPropertyGridSelect( wxPropertyGridEvent& event ); + void OnPGColDrag( wxPropertyGridEvent& event ); -protected: wxPropertyGrid* m_pPropGrid; @@ -629,12 +666,17 @@ protected: #if wxUSE_TOOLBAR wxToolBar* m_pToolbar; +#endif +#if wxUSE_HEADERCTRL + wxPGHeaderCtrl* m_pHeaderCtrl; #endif wxStaticText* m_pTxtHelpCaption; wxStaticText* m_pTxtHelpContent; wxPropertyGridPage* m_emptyPage; + wxArrayString m_columnLabels; + long m_iFlags; // Selected page index. @@ -664,6 +706,8 @@ protected: unsigned char m_onSplitter; + bool m_showHeader; + virtual wxPGProperty* DoGetPropertyByName( const wxString& name ) const; /** Select and displays a given page. */ diff --git a/include/wx/propgrid/propgrid.h b/include/wx/propgrid/propgrid.h index 2cd2d51d7b..db6c2bb94d 100644 --- a/include/wx/propgrid/propgrid.h +++ b/include/wx/propgrid/propgrid.h @@ -192,8 +192,8 @@ wxPG_TOOLBAR = 0x00001000, */ wxPG_DESCRIPTION = 0x00002000, -/** wxPropertyGridManager only: don't show an internal border around - the property grid. +/** wxPropertyGridManager only: don't show an internal border around the + property grid. Recommended if you use a header. */ wxPG_NO_INTERNAL_BORDER = 0x00004000 }; @@ -511,6 +511,19 @@ enum wxPG_KEYBOARD_ACTIONS // Don't make any graphics updates #define wxPG_SEL_NO_REFRESH 0x0100 +// ----------------------------------------------------------------------- + +// DoSetSplitterPosition() flags + +enum wxPG_SET_SPLITTER_POSITION_SPLITTER_FLAGS +{ + wxPG_SPLITTER_REFRESH = 0x0001, + wxPG_SPLITTER_ALL_PAGES = 0x0002, + wxPG_SPLITTER_FROM_EVENT = 0x0004, + wxPG_SPLITTER_FROM_AUTO_CENTER = 0x0008 +}; + + // ----------------------------------------------------------------------- #ifndef SWIG @@ -640,7 +653,9 @@ enum wxPG_KEYBOARD_ACTIONS starts resizing a column - can be vetoed. @event{EVT_PG_COL_DRAGGING,(id, func)} Respond to wxEVT_PG_COL_DRAGGING, event, generated when a - column resize by user is in progress. + column resize by user is in progress. This event is also generated + when user double-clicks the splitter in order to recenter + it. @event{EVT_PG_COL_END_DRAG(id, func)} Respond to wxEVT_PG_COL_END_DRAG event, generated after column resize by user has finished. @@ -662,6 +677,7 @@ class WXDLLIMPEXP_PROPGRID friend class wxPropertyGridPageState; friend class wxPropertyGridInterface; friend class wxPropertyGridManager; + friend class wxPGHeaderCtrl; DECLARE_DYNAMIC_CLASS(wxPropertyGrid) public: @@ -894,6 +910,9 @@ public: /** Returns background colour of margin. */ wxColour GetMarginColour() const { return m_colMargin; } + /** Returns margin width. */ + int GetMarginWidth() const { return m_marginWidth; } + /** Returns most up-to-date value of selected property. This will return value different from GetSelectedProperty()->GetValue() only when text @@ -1176,10 +1195,9 @@ public: during form creation may fail as initial grid size is often smaller than desired splitter position, especially when sizers are being used. */ - void SetSplitterPosition( int newxpos, int col = 0 ) + void SetSplitterPosition( int newXPos, int col = 0 ) { - DoSetSplitterPosition_(newxpos, true, col); - m_pState->m_isSplitterPreSet = true; + DoSetSplitterPosition(newXPos, col, wxPG_SPLITTER_REFRESH); } /** @@ -1994,6 +2012,10 @@ protected: void DoSetSelection( const wxArrayPGProperty& newSelection, int selFlags = 0 ); + void DoSetSplitterPosition( int newxpos, + int splitterIndex = 0, + int flags = wxPG_SPLITTER_REFRESH ); + bool DoAddToSelection( wxPGProperty* prop, int selFlags = 0 ); @@ -2007,11 +2029,6 @@ protected: wxPGProperty* DoGetItemAtY( int y ) const; - void DoSetSplitterPosition_( int newxpos, - bool refresh = true, - int splitterIndex = 0, - bool allPages = false ); - void DestroyEditorWnd( wxWindow* wnd ); void FreeEditors(); @@ -2039,7 +2056,11 @@ protected: void PrepareAfterItemsAdded(); - // Omit the wxPG_SEL_NOVALIDATE flag to allow vetoing the event + /** + Send event from the property grid. + + Omit the wxPG_SEL_NOVALIDATE flag to allow vetoing the event + */ bool SendEvent( int eventType, wxPGProperty* p, wxVariant* pValue = NULL, unsigned int selFlags = wxPG_SEL_NOVALIDATE, diff --git a/include/wx/propgrid/propgridpagestate.h b/include/wx/propgrid/propgridpagestate.h index f2a2a07043..5ba7674fbe 100644 --- a/include/wx/propgrid/propgridpagestate.h +++ b/include/wx/propgrid/propgridpagestate.h @@ -463,8 +463,7 @@ public: */ virtual void DoSetSplitterPosition( int pos, int splitterColumn = 0, - bool allPages = false, - bool fromAutoCenter = false ); + int flags = 0 ); bool EnableCategories( bool enable ); diff --git a/interface/wx/propgrid/manager.h b/interface/wx/propgrid/manager.h index 3aa7e9746c..b7dc75ebbe 100644 --- a/interface/wx/propgrid/manager.h +++ b/interface/wx/propgrid/manager.h @@ -128,8 +128,8 @@ public: @class wxPropertyGridManager wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid, - which can optionally have toolbar for mode and page selection, and a help text - box. + which can optionally have toolbar for mode and page selection, a help text + box, and a header. wxPropertyGridManager inherits from wxPropertyGridInterface, and as such it has most property manipulation functions. However, only some of them affect @@ -183,6 +183,9 @@ public: page->Append( "Text",wxPG_LABEL,"(no text)" ); page->Append( new wxFontProperty("Font",wxPG_LABEL) ); + + // Display a header above the grid + pgMan->ShowHeader(); @endcode @section propgridmanager_window_styles_ Window Styles @@ -427,9 +430,22 @@ public: /** Sets number of columns on given page (default is current page). + + @remarks If you use header, then you should always use this + member function to set the column count, instead of + ones present in wxPropertyGrid or wxPropertyGridPage. */ void SetColumnCount( int colCount, int page = -1 ); + /** + Sets a column title. Default title for column 0 is "Property", + and "Value" for column 1. + + @remarks If header is not shown yet, then calling this + member function will make it visible. + */ + void SetColumnTitle( int idx, const wxString& title ); + /** Sets label and text in description box. */ @@ -451,22 +467,41 @@ public: */ void SetSplitterLeft( bool subProps = false, bool allPages = true ); - /** Sets splitter position on individual page. */ + /** + Sets splitter position on individual page. + + @remarks If you use header, then you should always use this + member function to set the splitter position, instead of + ones present in wxPropertyGrid or wxPropertyGridPage. + */ void SetPageSplitterPosition( int page, int pos, int column = 0 ); /** Sets splitter position for all pages. - @remarks Splitter position cannot exceed grid size, and therefore setting - it during form creation may fail as initial grid size is often - smaller than desired splitter position, especially when sizers - are being used. + @remarks Splitter position cannot exceed grid size, and therefore + setting it during form creation may fail as initial grid + size is often smaller than desired splitter position, + especially when sizers are being used. + + If you use header, then you should always use this + member function to set the splitter position, instead of + ones present in wxPropertyGrid or wxPropertyGridPage. */ void SetSplitterPosition( int pos, int column = 0 ); /** Synonyme for SelectPage(name). */ void SetStringSelection( const wxChar* name ); + /** + Show or hide the property grid header control. It is hidden + by the default. + + @remarks Grid may look better if you use wxPG_NO_INTERNAL_BORDER + window style when showing a header. + */ + void ShowHeader(bool show = true); + protected: // diff --git a/interface/wx/propgrid/propgrid.h b/interface/wx/propgrid/propgrid.h index 7ff8e48637..a21f8cbcc0 100644 --- a/interface/wx/propgrid/propgrid.h +++ b/interface/wx/propgrid/propgrid.h @@ -91,7 +91,8 @@ wxPG_TOOLBAR = 0x00001000, */ wxPG_DESCRIPTION = 0x00002000, -/** wxPropertyGridManager only: don't show an internal border around the property grid +/** wxPropertyGridManager only: don't show an internal border around the + property grid. Recommended if you use a header. */ wxPG_NO_INTERNAL_BORDER = 0x00004000 @@ -397,7 +398,9 @@ typedef int (*wxPGSortCallback)(wxPropertyGrid* propGrid, starts resizing a column - can be vetoed. @event{EVT_PG_COL_DRAGGING,(id, func)} Respond to wxEVT_PG_COL_DRAGGING, event, generated when a - column resize by user is in progress. + column resize by user is in progress. This event is also generated + when user double-clicks the splitter in order to recenter + it. @event{EVT_PG_COL_END_DRAG(id, func)} Respond to wxEVT_PG_COL_END_DRAG event, generated after column resize by user has finished. diff --git a/samples/propgrid/propgrid.cpp b/samples/propgrid/propgrid.cpp index efef59ef59..7af6429db2 100644 --- a/samples/propgrid/propgrid.cpp +++ b/samples/propgrid/propgrid.cpp @@ -689,7 +689,8 @@ enum ID_RESTORESTATE, ID_RUNMINIMAL, ID_ENABLELABELEDITING, - ID_VETOCOLDRAG + ID_VETOCOLDRAG, + ID_SHOWHEADER }; // ----------------------------------------------------------------------- @@ -758,6 +759,7 @@ BEGIN_EVENT_TABLE(FormMain, wxFrame) EVT_MENU( ID_CLEARMODIF, FormMain::OnClearModifyStatusClick ) EVT_MENU( ID_FREEZE, FormMain::OnFreezeClick ) EVT_MENU( ID_ENABLELABELEDITING, FormMain::OnEnableLabelEditing ) + EVT_MENU( ID_SHOWHEADER, FormMain::OnShowHeader ) EVT_MENU( ID_DUMPLIST, FormMain::OnDumpList ) EVT_MENU( ID_COLOURSCHEME1, FormMain::OnColourScheme ) @@ -2300,6 +2302,9 @@ FormMain::FormMain(const wxString& title, const wxPoint& pos, const wxSize& size wxT("Select window style flags used by the grid.")); menuTry->Append(ID_ENABLELABELEDITING, "Enable label editing", "This calls wxPropertyGrid::MakeColumnEditable(0)"); + menuTry->AppendCheckItem(ID_SHOWHEADER, + "Enable header", + "This calls wxPropertyGridManager::ShowHeader()"); menuTry->AppendSeparator(); menuTry->AppendRadioItem( ID_COLOURSCHEME1, wxT("Standard Colour Scheme") ); menuTry->AppendRadioItem( ID_COLOURSCHEME2, wxT("White Colour Scheme") ); @@ -2858,6 +2863,14 @@ void FormMain::OnEnableLabelEditing( wxCommandEvent& WXUNUSED(event) ) // ----------------------------------------------------------------------- +void FormMain::OnShowHeader( wxCommandEvent& event ) +{ + m_pPropGridManager->ShowHeader(event.IsChecked()); + m_pPropGridManager->SetColumnTitle(2, _("Units")); +} + +// ----------------------------------------------------------------------- + void FormMain::OnAbout(wxCommandEvent& WXUNUSED(event)) { wxString msg; diff --git a/samples/propgrid/propgrid.h b/samples/propgrid/propgrid.h index 7af74f31c5..96a79c5af8 100644 --- a/samples/propgrid/propgrid.h +++ b/samples/propgrid/propgrid.h @@ -190,6 +190,7 @@ public: void OnClearModifyStatusClick( wxCommandEvent& event ); void OnFreezeClick( wxCommandEvent& event ); void OnEnableLabelEditing( wxCommandEvent& event ); + void OnShowHeader( wxCommandEvent& event ); void OnDumpList( wxCommandEvent& event ); void OnCatColours( wxCommandEvent& event ); void OnSetColumns( wxCommandEvent& event ); diff --git a/src/propgrid/manager.cpp b/src/propgrid/manager.cpp index 0c1d5a726a..0b148c403e 100644 --- a/src/propgrid/manager.cpp +++ b/src/propgrid/manager.cpp @@ -209,18 +209,197 @@ void wxPropertyGridPage::SetSplitterPosition( int splitterPos, int col ) void wxPropertyGridPage::DoSetSplitterPosition( int pos, int splitterColumn, - bool allPages, - bool fromAutoCenter ) + int flags ) { - if ( allPages && m_manager->GetPageCount() ) + if ( (flags & wxPG_SPLITTER_ALL_PAGES) && m_manager->GetPageCount() ) m_manager->SetSplitterPosition( pos, splitterColumn ); else wxPropertyGridPageState::DoSetSplitterPosition( pos, splitterColumn, - allPages, - fromAutoCenter ); + flags ); } +// ----------------------------------------------------------------------- +// wxPGHeaderCtrl +// ----------------------------------------------------------------------- + +#if wxUSE_HEADERCTRL + +class wxPGHeaderCtrl : public wxHeaderCtrl +{ +public: + wxPGHeaderCtrl(wxPropertyGridManager* manager) : + wxHeaderCtrl() + { + m_manager = manager; + EnsureColumnCount(2); + + // Seed titles with defaults + m_columns[0]->SetTitle(_("Property")); + m_columns[1]->SetTitle(_("Value")); + } + + virtual ~wxPGHeaderCtrl() + { + for (unsigned int i=0; iGetColumnWidth(idx); + int colMinWidth = page->GetColumnMinWidth(idx); + if ( idx == 0 ) + { + wxPropertyGrid* pg = m_manager->GetGrid(); + int margin = pg->GetMarginWidth(); + + // Compensate for the internal border + margin += (pg->GetSize().x - pg->GetClientSize().x) / 2; + + colWidth += margin; + colMinWidth += margin; + } + *pMinWidth = colMinWidth; + return colWidth; + } + + void OnPageChanged(const wxPropertyGridPage* page) + { + m_page = page; + OnPageUpdated(); + } + + void OnPageUpdated() + { + // Get column info from the page + const wxPropertyGridPage* page = m_page; + unsigned int colCount = page->GetColumnCount(); + EnsureColumnCount(colCount); + + for ( unsigned int i=0; iSetWidth(colWidth); + colInfo->SetMinWidth(colMinWidth); + } + + SetColumnCount(colCount); + } + + void OnColumWidthsChanged() + { + const wxPropertyGridPage* page = m_page; + unsigned int colCount = page->GetColumnCount(); + + for ( unsigned int i=0; iSetWidth(colWidth); + colInfo->SetMinWidth(colMinWidth); + UpdateColumn(i); + } + } + + virtual const wxHeaderColumn& GetColumn(unsigned int idx) const + { + return *m_columns[idx]; + } + + void SetColumnTitle(unsigned int idx, const wxString& title) + { + EnsureColumnCount(idx+1); + m_columns[idx]->SetTitle(title); + } + +private: + void EnsureColumnCount(unsigned int count) + { + while ( m_columns.size() < count ) + { + wxHeaderColumnSimple* colInfo = new wxHeaderColumnSimple(""); + m_columns.push_back(colInfo); + } + } + + void OnSetColumnWidth(int col, int colWidth) + { + wxPropertyGrid* pg = m_manager->GetGrid(); + + // Compensate for the internal border + int x = -((pg->GetSize().x - pg->GetClientSize().x) / 2); + + for ( int i=0; iGetWidth(); + + x += colWidth; + + pg->DoSetSplitterPosition(x, col, + wxPG_SPLITTER_REFRESH | + wxPG_SPLITTER_FROM_EVENT); + } + + virtual bool ProcessEvent( wxEvent& event ) + { + if ( event.IsKindOf(CLASSINFO(wxHeaderCtrlEvent)) ) + { + wxHeaderCtrlEvent& hcEvent = + static_cast(event); + + wxPropertyGrid* pg = m_manager->GetGrid(); + int col = hcEvent.GetColumn(); + int evtType = event.GetEventType(); + + if ( evtType == wxEVT_COMMAND_HEADER_RESIZING ) + { + int colWidth = hcEvent.GetWidth(); + + OnSetColumnWidth(col, colWidth); + + pg->SendEvent(wxEVT_PG_COL_DRAGGING, + NULL, NULL, 0, + (unsigned int)col); + + return true; + } + else if ( evtType == wxEVT_COMMAND_HEADER_BEGIN_RESIZE ) + { + // Never allow column resize if layout is static + if ( m_manager->HasFlag(wxPG_STATIC_SPLITTER) ) + hcEvent.Veto(); + // Allow application to veto dragging + else if ( pg->SendEvent(wxEVT_PG_COL_BEGIN_DRAG, + NULL, NULL, 0, + (unsigned int)col) ) + hcEvent.Veto(); + + return true; + } + else if ( evtType == wxEVT_COMMAND_HEADER_END_RESIZE ) + { + pg->SendEvent(wxEVT_PG_COL_END_DRAG, + NULL, NULL, 0, + (unsigned int)col); + + return true; + } + } + + return wxHeaderCtrl::ProcessEvent(event); + } + + wxPropertyGridManager* m_manager; + const wxPropertyGridPage* m_page; + wxVector m_columns; +}; + +#endif // wxUSE_HEADERCTRL + // ----------------------------------------------------------------------- // wxPropertyGridManager // ----------------------------------------------------------------------- @@ -235,7 +414,7 @@ IMPLEMENT_CLASS(wxPropertyGridManager, wxPanel) #define ID_ADVTOOLBAR_OFFSET 1 #define ID_ADVHELPCAPTION_OFFSET 2 #define ID_ADVHELPCONTENT_OFFSET 3 -//#define ID_ADVBUTTON_OFFSET 4 +#define ID_ADVHEADERCTRL_OFFSET 4 #define ID_ADVTBITEMSBASE_OFFSET 5 // Must be last. // ----------------------------------------------------------------------- @@ -309,6 +488,10 @@ void wxPropertyGridManager::Init1() #if wxUSE_TOOLBAR m_pToolbar = NULL; +#endif +#if wxUSE_HEADERCTRL + m_pHeaderCtrl = NULL; + m_showHeader = false; #endif m_pTxtHelpCaption = NULL; m_pTxtHelpContent = NULL; @@ -413,9 +596,13 @@ void wxPropertyGridManager::Init2( int style ) // Connect to property grid onselect event. // NB: Even if wxID_ANY is used, this doesn't connect properly in wxPython // (see wxPropertyGridManager::ProcessEvent). - Connect(m_pPropGrid->GetId()/*wxID_ANY*/, - wxEVT_PG_SELECTED, - wxPropertyGridEventHandler(wxPropertyGridManager::OnPropertyGridSelect) ); + Connect(m_pPropGrid->GetId(), + wxEVT_PG_SELECTED, + wxPropertyGridEventHandler(wxPropertyGridManager::OnPropertyGridSelect)); + + Connect(m_pPropGrid->GetId(), + wxEVT_PG_COL_DRAGGING, + wxPropertyGridEventHandler(wxPropertyGridManager::OnPGColDrag)); // Connect to toolbar button events. Connect(baseId+ID_ADVTBITEMSBASE_OFFSET,baseId+ID_ADVTBITEMSBASE_OFFSET+50, @@ -616,6 +803,11 @@ bool wxPropertyGridManager::DoSelectPage( int index ) } #endif +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + m_pHeaderCtrl->OnPageChanged(nextPage); +#endif + return true; } @@ -733,6 +925,11 @@ void wxPropertyGridManager::SetColumnCount( int colCount, int page ) GetPageState(page)->SetColumnCount( colCount ); GetGrid()->Refresh(); + +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + m_pHeaderCtrl->OnPageUpdated(); +#endif } // ----------------------------------------------------------------------- @@ -899,6 +1096,31 @@ bool wxPropertyGridManager::IsPageModified( size_t index ) const // ----------------------------------------------------------------------- +#if wxUSE_HEADERCTRL +void wxPropertyGridManager::ShowHeader(bool show) +{ + if ( show != m_showHeader) + { + m_showHeader = show; + RecreateControls(); + } +} +#endif + +// ----------------------------------------------------------------------- + +#if wxUSE_HEADERCTRL +void wxPropertyGridManager::SetColumnTitle( int idx, const wxString& title ) +{ + if ( !m_pHeaderCtrl ) + ShowHeader(); + + m_pHeaderCtrl->SetColumnTitle(idx, title); +} +#endif + +// ----------------------------------------------------------------------- + bool wxPropertyGridManager::IsPropertySelected( wxPGPropArg id ) const { wxPG_PROP_ARG_CALL_PROLOG_RETVAL(false) @@ -1110,6 +1332,15 @@ void wxPropertyGridManager::RecalculatePositions( int width, int height ) } #endif + // Header comes after the tool bar +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + { + m_pHeaderCtrl->SetSize(0, propgridY, width, -1); + propgridY += m_pHeaderCtrl->GetSize().y; + } +#endif + // Help box. if ( m_pTxtHelpCaption ) { @@ -1311,6 +1542,31 @@ void wxPropertyGridManager::RecreateControls() } #endif +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + { + wxPGHeaderCtrl* hc; + + if ( !m_pHeaderCtrl ) + { + hc = new wxPGHeaderCtrl(this); + hc->Create(this, baseId+ID_ADVHEADERCTRL_OFFSET); + m_pHeaderCtrl = hc; + } + else + { + m_pHeaderCtrl->Show(); + } + + m_pHeaderCtrl->OnPageChanged(GetCurrentPage()); + } + else + { + if ( m_pHeaderCtrl ) + m_pHeaderCtrl->Hide(); + } +#endif + if ( m_windowStyle & wxPG_DESCRIPTION ) { // Has help box. @@ -1557,6 +1813,11 @@ void wxPropertyGridManager::SetSplitterLeft( bool subProps, bool allPages ) if ( highest > 0 ) m_pPropGrid->SetSplitterPosition( highest ); } + +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + m_pHeaderCtrl->OnColumWidthsChanged(); +#endif } // ----------------------------------------------------------------------- @@ -1573,6 +1834,19 @@ void wxPropertyGridManager::OnPropertyGridSelect( wxPropertyGridEvent& event ) // ----------------------------------------------------------------------- +void +wxPropertyGridManager::OnPGColDrag( wxPropertyGridEvent& WXUNUSED(event) ) +{ +#if wxUSE_HEADERCTRL + if ( !m_showHeader ) + return; + + m_pHeaderCtrl->OnColumWidthsChanged(); +#endif +} + +// ----------------------------------------------------------------------- + void wxPropertyGridManager::OnResize( wxSizeEvent& WXUNUSED(event) ) { int width, height; @@ -1737,9 +2011,28 @@ void wxPropertyGridManager::SetSplitterPosition( int pos, int splitterColumn ) for ( i=0; iDoSetSplitterPosition( pos, splitterColumn, false ); - page->m_isSplitterPreSet = true; + page->DoSetSplitterPosition( pos, splitterColumn, + wxPG_SPLITTER_REFRESH ); } + +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + m_pHeaderCtrl->OnColumWidthsChanged(); +#endif +} + +// ----------------------------------------------------------------------- + +void wxPropertyGridManager::SetPageSplitterPosition( int page, + int pos, + int column ) +{ + GetPage(page)->DoSetSplitterPosition( pos, column ); + +#if wxUSE_HEADERCTRL + if ( m_showHeader ) + m_pHeaderCtrl->OnColumWidthsChanged(); +#endif } // ----------------------------------------------------------------------- diff --git a/src/propgrid/propgrid.cpp b/src/propgrid/propgrid.cpp index 5d39a2e7e2..1120d4ce51 100644 --- a/src/propgrid/propgrid.cpp +++ b/src/propgrid/propgrid.cpp @@ -2677,24 +2677,29 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState ) // Call to SetSplitterPosition will always disable splitter auto-centering // if parent window is shown. -void wxPropertyGrid::DoSetSplitterPosition_( int newxpos, bool refresh, - int splitterIndex, - bool allPages ) +void wxPropertyGrid::DoSetSplitterPosition( int newxpos, + int splitterIndex, + int flags ) { if ( ( newxpos < wxPG_DRAG_MARGIN ) ) return; wxPropertyGridPageState* state = m_pState; - state->DoSetSplitterPosition( newxpos, splitterIndex, allPages ); + if ( flags & wxPG_SPLITTER_FROM_EVENT ) + state->m_dontCenterSplitter = true; + + state->DoSetSplitterPosition(newxpos, splitterIndex, flags); - if ( refresh ) + if ( flags & wxPG_SPLITTER_REFRESH ) { if ( GetSelection() ) CorrectEditorWidgetSizeX(); Refresh(); } + + return; } // ----------------------------------------------------------------------- @@ -4476,7 +4481,16 @@ bool wxPropertyGrid::HandleMouseClick( int x, unsigned int y, wxMouseEvent &even if ( event.GetEventType() == wxEVT_LEFT_DCLICK ) { // Double-clicking the splitter causes auto-centering - CenterSplitter( true ); + if ( m_pState->GetColumnCount() <= 2 ) + { + CenterSplitter( true ); + + SendEvent(wxEVT_PG_COL_DRAGGING, + m_propHover, + NULL, + wxPG_SEL_NOVALIDATE, + (unsigned int)m_draggedSplitter); + } } else if ( m_dragStatus == 0 ) { @@ -4650,17 +4664,10 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y, if ( newSplitterX != splitterX ) { // Move everything - state->m_dontCenterSplitter = true; - state->DoSetSplitterPosition(newSplitterX, - m_draggedSplitter, - false); - state->m_fSplitterX = (float) newSplitterX; - - if ( GetSelection() ) - CorrectEditorWidgetSizeX(); - - Update(); - Refresh(); + DoSetSplitterPosition(newSplitterX, + m_draggedSplitter, + wxPG_SPLITTER_REFRESH | + wxPG_SPLITTER_FROM_EVENT); SendEvent(wxEVT_PG_COL_DRAGGING, m_propHover, diff --git a/src/propgrid/propgridpagestate.cpp b/src/propgrid/propgridpagestate.cpp index 6736b69c3a..8c8d00667e 100644 --- a/src/propgrid/propgridpagestate.cpp +++ b/src/propgrid/propgridpagestate.cpp @@ -842,8 +842,7 @@ void wxPropertyGridPageState::PropagateColSizeDec( int column, void wxPropertyGridPageState::DoSetSplitterPosition( int newXPos, int splitterColumn, - bool WXUNUSED(allPages), - bool fromAutoCenter ) + int flags ) { wxPropertyGrid* pg = GetGrid(); @@ -878,7 +877,8 @@ void wxPropertyGridPageState::DoSetSplitterPosition( int newXPos, if ( splitterColumn == 0 ) m_fSplitterX = (double) newXPos; - if ( !fromAutoCenter ) + if ( !(flags & wxPG_SPLITTER_FROM_AUTO_CENTER) && + !(flags & wxPG_SPLITTER_FROM_EVENT) ) { // Don't allow initial splitter auto-positioning after this. m_isSplitterPreSet = true; @@ -1083,7 +1083,8 @@ void wxPropertyGridPageState::CheckColumnWidths( int widthChange ) } } - DoSetSplitterPosition((int)splitterX, 0, false, true); + DoSetSplitterPosition((int)splitterX, 0, + wxPG_SPLITTER_FROM_AUTO_CENTER); m_fSplitterX = splitterX; // needed to retain accuracy } -- 2.45.2