]> git.saurik.com Git - wxWidgets.git/commitdiff
Added wxPropertyGridManager header support; Refactored wxPropertyGrid DoSetSplitterPo...
authorJaakko Salli <jaakko.salli@dnainternet.net>
Sun, 13 Dec 2009 12:00:04 +0000 (12:00 +0000)
committerJaakko Salli <jaakko.salli@dnainternet.net>
Sun, 13 Dec 2009 12:00:04 +0000 (12:00 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@62867 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

include/wx/propgrid/manager.h
include/wx/propgrid/propgrid.h
include/wx/propgrid/propgridpagestate.h
interface/wx/propgrid/manager.h
interface/wx/propgrid/propgrid.h
samples/propgrid/propgrid.cpp
samples/propgrid/propgrid.h
src/propgrid/manager.cpp
src/propgrid/propgrid.cpp
src/propgrid/propgridpagestate.cpp

index 75db8dafdf916b98c6ac8639c2a2323942b13950..135803a929fc03430df7196fae9e91c6114f4f1b 100644 (file)
@@ -23,6 +23,7 @@
 #include "wx/button.h"
 #include "wx/textctrl.h"
 #include "wx/dialog.h"
 #include "wx/button.h"
 #include "wx/textctrl.h"
 #include "wx/dialog.h"
+#include <wx/headerctrl.h>
 
 // -----------------------------------------------------------------------
 
 
 // -----------------------------------------------------------------------
 
@@ -161,8 +162,7 @@ protected:
     */
     virtual void DoSetSplitterPosition( int pos,
                                         int splitterColumn = 0,
     */
     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
 
     /** 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,
 /** @class wxPropertyGridManager
 
     wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid,
@@ -534,7 +539,21 @@ public:
         return p->GetParentState()->DoSelectProperty(p, focus);
     }
 
         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 );
 
     */
     void SetColumnCount( int colCount, int page = -1 );
 
@@ -555,20 +574,40 @@ public:
     */
     void SetSplitterLeft( bool subProps = false, bool allPages = true );
 
     */
     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 );
 
     */
     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:
 
     //
 protected:
 
     //
@@ -600,13 +639,11 @@ public:
     virtual void SetWindowStyleFlag ( long style );
     virtual bool Reparent( wxWindowBase *newParent );
 
     virtual void SetWindowStyleFlag ( long style );
     virtual bool Reparent( wxWindowBase *newParent );
 
+#ifndef SWIG
+
 protected:
     virtual wxSize DoGetBestSize() const;
 
 protected:
     virtual wxSize DoGetBestSize() const;
 
-public:
-
-#ifndef SWIG
-
     //
     // Event handlers
     //
     //
     // Event handlers
     //
@@ -620,8 +657,8 @@ public:
     void OnToolbarClick( wxCommandEvent &event );
     void OnResize( wxSizeEvent& event );
     void OnPropertyGridSelect( wxPropertyGridEvent& event );
     void OnToolbarClick( wxCommandEvent &event );
     void OnResize( wxSizeEvent& event );
     void OnPropertyGridSelect( wxPropertyGridEvent& event );
+    void OnPGColDrag( wxPropertyGridEvent& event );
 
 
-protected:
 
     wxPropertyGrid* m_pPropGrid;
 
 
     wxPropertyGrid* m_pPropGrid;
 
@@ -629,12 +666,17 @@ protected:
 
 #if wxUSE_TOOLBAR
     wxToolBar*      m_pToolbar;
 
 #if wxUSE_TOOLBAR
     wxToolBar*      m_pToolbar;
+#endif
+#if wxUSE_HEADERCTRL
+    wxPGHeaderCtrl* m_pHeaderCtrl;
 #endif
     wxStaticText*   m_pTxtHelpCaption;
     wxStaticText*   m_pTxtHelpContent;
 
     wxPropertyGridPage*     m_emptyPage;
 
 #endif
     wxStaticText*   m_pTxtHelpCaption;
     wxStaticText*   m_pTxtHelpContent;
 
     wxPropertyGridPage*     m_emptyPage;
 
+    wxArrayString   m_columnLabels;
+
     long            m_iFlags;
 
     // Selected page index.
     long            m_iFlags;
 
     // Selected page index.
@@ -664,6 +706,8 @@ protected:
 
     unsigned char   m_onSplitter;
 
 
     unsigned char   m_onSplitter;
 
+    bool            m_showHeader;
+
     virtual wxPGProperty* DoGetPropertyByName( const wxString& name ) const;
 
     /** Select and displays a given page. */
     virtual wxPGProperty* DoGetPropertyByName( const wxString& name ) const;
 
     /** Select and displays a given page. */
index 2cd2d51d7b862d9d99c30eaf42b4bcd205d29bda..db6c2bb94ddf3b0bee74685a543cbe5725c00034 100644 (file)
@@ -192,8 +192,8 @@ wxPG_TOOLBAR                        = 0x00001000,
 */
 wxPG_DESCRIPTION                    = 0x00002000,
 
 */
 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
 };
 */
 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
 
 // 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
 // -----------------------------------------------------------------------
 
 #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
         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.
     @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 wxPropertyGridPageState;
     friend class wxPropertyGridInterface;
     friend class wxPropertyGridManager;
+    friend class wxPGHeaderCtrl;
 
     DECLARE_DYNAMIC_CLASS(wxPropertyGrid)
 public:
 
     DECLARE_DYNAMIC_CLASS(wxPropertyGrid)
 public:
@@ -894,6 +910,9 @@ public:
     /** Returns background colour of margin. */
     wxColour GetMarginColour() const { return m_colMargin; }
 
     /** 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
     /**
         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.
     */
         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 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 );
 
     bool DoAddToSelection( wxPGProperty* prop,
                            int selFlags = 0 );
 
@@ -2007,11 +2029,6 @@ protected:
 
     wxPGProperty* DoGetItemAtY( int y ) const;
 
 
     wxPGProperty* DoGetItemAtY( int y ) const;
 
-    void DoSetSplitterPosition_( int newxpos,
-                                 bool refresh = true,
-                                 int splitterIndex = 0,
-                                 bool allPages = false );
-
     void DestroyEditorWnd( wxWindow* wnd );
     void FreeEditors();
 
     void DestroyEditorWnd( wxWindow* wnd );
     void FreeEditors();
 
@@ -2039,7 +2056,11 @@ protected:
 
     void PrepareAfterItemsAdded();
 
 
     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,
     bool SendEvent( int eventType, wxPGProperty* p,
                     wxVariant* pValue = NULL,
                     unsigned int selFlags = wxPG_SEL_NOVALIDATE,
index f2a2a07043bc6fc9b70fbbda96e6ee3d59064e6b..5ba7674fbed68accf99921d581ad702b3a52f8c6 100644 (file)
@@ -463,8 +463,7 @@ public:
     */
     virtual void DoSetSplitterPosition( int pos,
                                         int splitterColumn = 0,
     */
     virtual void DoSetSplitterPosition( int pos,
                                         int splitterColumn = 0,
-                                        bool allPages = false,
-                                        bool fromAutoCenter = false );
+                                        int flags = 0 );
 
     bool EnableCategories( bool enable );
 
 
     bool EnableCategories( bool enable );
 
index 3aa7e9746cee5136167da6b27916a5fdc31b79c9..b7dc75ebbee39daa44c36873e818db0eaf4cea83 100644 (file)
@@ -128,8 +128,8 @@ public:
     @class wxPropertyGridManager
 
     wxPropertyGridManager is an efficient multi-page version of wxPropertyGrid,
     @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
 
     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) );
         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
     @endcode
 
     @section propgridmanager_window_styles_ Window Styles
@@ -427,9 +430,22 @@ public:
 
     /**
         Sets number of columns on given page (default is current page).
 
     /**
         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 );
 
     */
     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.
     */
     /**
         Sets label and text in description box.
     */
@@ -451,22 +467,41 @@ public:
     */
     void SetSplitterLeft( bool subProps = false, bool allPages = true );
 
     */
     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.
 
     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 );
 
     */
     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:
 
     //
 protected:
 
     //
index 7ff8e486379366a84f140e095e589129c333bf0e..a21f8cbcc003e14097f22f07328cf011fd292f24 100644 (file)
@@ -91,7 +91,8 @@ wxPG_TOOLBAR                        = 0x00001000,
 */
 wxPG_DESCRIPTION                    = 0x00002000,
 
 */
 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
 
 */
 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
         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.
     @event{EVT_PG_COL_END_DRAG(id, func)}
         Respond to wxEVT_PG_COL_END_DRAG event, generated after column
         resize by user has finished.
index efef59ef59f92121f0904eb1b73179e0461fcc18..7af6429db2a7071bc0571995e7b75aa86e3b4369 100644 (file)
@@ -689,7 +689,8 @@ enum
     ID_RESTORESTATE,
     ID_RUNMINIMAL,
     ID_ENABLELABELEDITING,
     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_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 )
     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)");
         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") );
     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;
 void FormMain::OnAbout(wxCommandEvent& WXUNUSED(event))
 {
     wxString msg;
index 7af74f31c5d1ccc6b3d738c16d5be9eb03fbf0fa..96a79c5af8727e086a47fe0ddb807edb97f6aa54 100644 (file)
@@ -190,6 +190,7 @@ public:
     void OnClearModifyStatusClick( wxCommandEvent& event );
     void OnFreezeClick( wxCommandEvent& event );
     void OnEnableLabelEditing( wxCommandEvent& event );
     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 );
     void OnDumpList( wxCommandEvent& event );
     void OnCatColours( wxCommandEvent& event );
     void OnSetColumns( wxCommandEvent& event );
index 0c1d5a726a93de6532090a034b44e8dd3c321377..0b148c403eab3cce35a26da4ecd73f128a538e7b 100644 (file)
@@ -209,18 +209,197 @@ void wxPropertyGridPage::SetSplitterPosition( int splitterPos, int col )
 
 void wxPropertyGridPage::DoSetSplitterPosition( int pos,
                                                 int splitterColumn,
 
 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,
         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; i<m_columns.size(); i++ )
+            delete m_columns[i];
+    }
+
+    int DetermineColumnWidth(unsigned int idx, int* pMinWidth) const
+    {
+        const wxPropertyGridPage* page = m_page;
+        int colWidth = page->GetColumnWidth(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; i<colCount; i++ )
+        {
+            wxHeaderColumnSimple* colInfo = m_columns[i];
+            int colMinWidth = 0;
+            int colWidth = DetermineColumnWidth(i, &colMinWidth);
+            colInfo->SetWidth(colWidth);
+            colInfo->SetMinWidth(colMinWidth);
+        }
+
+        SetColumnCount(colCount);
+    }
+
+    void OnColumWidthsChanged()
+    {
+        const wxPropertyGridPage* page = m_page;
+        unsigned int colCount = page->GetColumnCount();
+
+        for ( unsigned int i=0; i<colCount; i++ )
+        {
+            wxHeaderColumnSimple* colInfo = m_columns[i];
+            int colMinWidth = 0;
+            int colWidth = DetermineColumnWidth(i, &colMinWidth);
+            colInfo->SetWidth(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; i<col; i++ )
+            x += m_columns[i]->GetWidth();
+
+        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<wxHeaderCtrlEvent&>(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<wxHeaderColumnSimple*> m_columns;
+};
+
+#endif // wxUSE_HEADERCTRL
+
 // -----------------------------------------------------------------------
 // wxPropertyGridManager
 // -----------------------------------------------------------------------
 // -----------------------------------------------------------------------
 // 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_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.
 
 // -----------------------------------------------------------------------
 #define ID_ADVTBITEMSBASE_OFFSET    5   // Must be last.
 
 // -----------------------------------------------------------------------
@@ -309,6 +488,10 @@ void wxPropertyGridManager::Init1()
 
 #if wxUSE_TOOLBAR
     m_pToolbar = NULL;
 
 #if wxUSE_TOOLBAR
     m_pToolbar = NULL;
+#endif
+#if wxUSE_HEADERCTRL
+    m_pHeaderCtrl = NULL;
+    m_showHeader = false;
 #endif
     m_pTxtHelpCaption = NULL;
     m_pTxtHelpContent = NULL;
 #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 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,
 
     // 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
 
     }
 #endif
 
+#if wxUSE_HEADERCTRL
+    if ( m_showHeader )
+        m_pHeaderCtrl->OnPageChanged(nextPage);
+#endif
+
     return true;
 }
 
     return true;
 }
 
@@ -733,6 +925,11 @@ void wxPropertyGridManager::SetColumnCount( int colCount, int page )
 
     GetPageState(page)->SetColumnCount( colCount );
     GetGrid()->Refresh();
 
     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)
 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
 
     }
 #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 )
     {
     // Help box.
     if ( m_pTxtHelpCaption )
     {
@@ -1311,6 +1542,31 @@ void wxPropertyGridManager::RecreateControls()
     }
 #endif
 
     }
 #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.
     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 ( 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;
 void wxPropertyGridManager::OnResize( wxSizeEvent& WXUNUSED(event) )
 {
     int width, height;
@@ -1737,9 +2011,28 @@ void wxPropertyGridManager::SetSplitterPosition( int pos, int splitterColumn )
     for ( i=0; i<GetPageCount(); i++ )
     {
         wxPropertyGridPage* page = GetPage(i);
     for ( i=0; i<GetPageCount(); i++ )
     {
         wxPropertyGridPage* page = GetPage(i);
-        page->DoSetSplitterPosition( 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
 }
 
 // -----------------------------------------------------------------------
 }
 
 // -----------------------------------------------------------------------
index 5d39a2e7e266b92bf7a8ac0b80567d87a873a150..1120d4ce516aa171f5962abd45dc5df7472fef8b 100644 (file)
@@ -2677,24 +2677,29 @@ void wxPropertyGrid::SwitchState( wxPropertyGridPageState* pNewState )
 
 // Call to SetSplitterPosition will always disable splitter auto-centering
 // if parent window is shown.
 
 // 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;
 
 {
     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();
     }
     {
         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
                     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 )
                     {
                     }
                     else if ( m_dragStatus == 0 )
                     {
@@ -4650,17 +4664,10 @@ bool wxPropertyGrid::HandleMouseMove( int x, unsigned int y,
             if ( newSplitterX != splitterX )
             {
                 // Move everything
             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,
 
                 SendEvent(wxEVT_PG_COL_DRAGGING,
                           m_propHover,
index 6736b69c3aab2c950e63beed5578fba2c7f93f02..8c8d00667eb400ea9e4d019ecd6127b83021b639 100644 (file)
@@ -842,8 +842,7 @@ void wxPropertyGridPageState::PropagateColSizeDec( int column,
 
 void wxPropertyGridPageState::DoSetSplitterPosition( int newXPos,
                                                      int splitterColumn,
 
 void wxPropertyGridPageState::DoSetSplitterPosition( int newXPos,
                                                      int splitterColumn,
-                                                     bool WXUNUSED(allPages),
-                                                     bool fromAutoCenter )
+                                                     int flags )
 {
     wxPropertyGrid* pg = GetGrid();
 
 {
     wxPropertyGrid* pg = GetGrid();
 
@@ -878,7 +877,8 @@ void wxPropertyGridPageState::DoSetSplitterPosition( int newXPos,
     if ( splitterColumn == 0 )
         m_fSplitterX = (double) 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;
     {
         // 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
     }
 
         m_fSplitterX = splitterX; // needed to retain accuracy
     }