// Categoric Mode Icon
-static const char* gs_xpm_catmode[] = {
+static const char* const gs_xpm_catmode[] = {
"16 16 5 1",
". c none",
"B c black",
};
// Alphabetic Mode Icon
-static const char* gs_xpm_noncatmode[] = {
+static const char* const gs_xpm_noncatmode[] = {
"16 16 5 1",
". c none",
"B c black",
};
// Default Page Icon.
-static const char* gs_xpm_defpage[] = {
+static const char* const gs_xpm_defpage[] = {
"16 16 5 1",
". c none",
"B c black",
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; 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
// -----------------------------------------------------------------------
#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.
// -----------------------------------------------------------------------
#if wxUSE_TOOLBAR
m_pToolbar = NULL;
+#endif
+#if wxUSE_HEADERCTRL
+ m_pHeaderCtrl = NULL;
+ m_showHeader = false;
#endif
m_pTxtHelpCaption = NULL;
m_pTxtHelpContent = NULL;
// 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,
}
#endif
+#if wxUSE_HEADERCTRL
+ if ( m_showHeader )
+ m_pHeaderCtrl->OnPageChanged(nextPage);
+#endif
+
return true;
}
GetPageState(page)->SetColumnCount( colCount );
GetGrid()->Refresh();
+
+#if wxUSE_HEADERCTRL
+ if ( m_showHeader )
+ m_pHeaderCtrl->OnPageUpdated();
+#endif
}
// -----------------------------------------------------------------------
pageObj->m_id = m_nextTbInd;
+ if ( !HasFlag(wxPG_SPLITTER_AUTO_CENTER) )
+ pageObj->m_dontCenterSplitter = true;
+
if ( isPageInserted )
m_arrPages.push_back( pageObj );
m_pToolbar->AddTool(m_nextTbInd,label,bmp,label,wxITEM_RADIO);
//m_pToolbar->InsertTool(index+3,m_nextTbInd,bmp);
else
- m_pToolbar->AddTool(m_nextTbInd,label,wxBitmap( (const char**)gs_xpm_defpage ),
+ m_pToolbar->AddTool(m_nextTbInd,label,wxBitmap(gs_xpm_defpage),
label,wxITEM_RADIO);
m_nextTbInd++;
// -----------------------------------------------------------------------
+#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)
}
#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 )
{
wxString desc1(_("Categorized Mode"));
wxString desc2(_("Alphabetic Mode"));
m_pToolbar->AddTool(baseId+ID_ADVTBITEMSBASE_OFFSET+0,
- desc1,wxBitmap ( (const char**)gs_xpm_catmode ),
+ desc1,wxBitmap (gs_xpm_catmode),
desc1,wxITEM_RADIO);
m_pToolbar->AddTool(baseId+ID_ADVTBITEMSBASE_OFFSET+1,
- desc2,wxBitmap ( (const char**)gs_xpm_noncatmode ),
+ desc2,wxBitmap (gs_xpm_noncatmode),
desc2,wxITEM_RADIO);
m_pToolbar->Realize();
}
}
#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.
maxW += m_pPropGrid->m_marginWidth;
if ( maxW > highest )
highest = maxW;
+ m_pState->m_dontCenterSplitter = true;
}
if ( highest > 0 )
m_pPropGrid->SetSplitterPosition( highest );
-
- m_pPropGrid->m_iFlags |= wxPG_FL_DONT_CENTER_SPLITTER;
}
+
+#if wxUSE_HEADERCTRL
+ if ( m_showHeader )
+ m_pHeaderCtrl->OnColumWidthsChanged();
+#endif
}
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
+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;
- GetClientSize(&width,&height);
+ GetClientSize(&width, &height);
if ( m_width == -12345 )
RecreateControls();
- RecalculatePositions(width,height);
+ RecalculatePositions(width, height);
+
+ if ( m_pPropGrid && m_pPropGrid->m_parent )
+ {
+ int pgWidth, pgHeight;
+ m_pPropGrid->GetClientSize(&pgWidth, &pgHeight);
+
+ // Regenerate splitter positions for non-current pages
+ for ( unsigned int i=0; i<GetPageCount(); i++ )
+ {
+ wxPropertyGridPage* page = GetPage(i);
+ if ( page != m_pPropGrid->GetState() )
+ {
+ page->OnClientWidthChange(pgWidth,
+ pgWidth - page->m_width,
+ true);
+ }
+ }
+ }
}
// -----------------------------------------------------------------------
for ( i=0; i<GetPageCount(); i++ )
{
wxPropertyGridPage* page = GetPage(i);
- page->DoSetSplitterPosition( pos, splitterColumn, false );
+ page->DoSetSplitterPosition( pos, splitterColumn,
+ wxPG_SPLITTER_REFRESH );
}
- m_pPropGrid->SetInternalFlag(wxPG_FL_SPLITTER_PRE_SET);
+#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
}
// -----------------------------------------------------------------------