// Author: Jaakko Salli
// Modified by:
// Created: 2005-01-14
-// RCS-ID: $Id:
// Copyright: (c) Jaakko Salli
-// Licence: wxWindows license
+// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/pen.h"
#include "wx/brush.h"
#include "wx/cursor.h"
- #include "wx/dialog.h"
#include "wx/settings.h"
- #include "wx/msgdlg.h"
- #include "wx/choice.h"
#include "wx/textctrl.h"
- #include "wx/dirdlg.h"
- #include "wx/combobox.h"
- #include "wx/layout.h"
#include "wx/sizer.h"
- #include "wx/textdlg.h"
- #include "wx/filedlg.h"
#include "wx/statusbr.h"
#include "wx/intl.h"
#endif
// This define is necessary to prevent macro clearing
#define __wxPG_SOURCE_FILE__
-#include <wx/propgrid/propgrid.h>
+#include "wx/propgrid/propgrid.h"
-#include <wx/propgrid/manager.h>
+#include "wx/propgrid/manager.h"
#define wxPG_MAN_ALTERNATE_BASE_ID 11249 // Needed for wxID_ANY madnesss
// wxPropertyGridManager
// -----------------------------------------------------------------------
-const wxChar *wxPropertyGridManagerNameStr = wxT("wxPropertyGridManager");
+const char wxPropertyGridManagerNameStr[] = "wxPropertyGridManager";
// 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",
"................"
};
-#define GETPAGESTATE(page) ((wxPropertyGridPage*)m_arrPages.Item(page))->GetStatePtr()
-
// -----------------------------------------------------------------------
// wxPropertyGridPage
// -----------------------------------------------------------------------
DoSetSplitterPosition(splitterPos, col, false);
}
-void wxPropertyGridPage::DoSetSplitterPosition( int pos, int splitterColumn, bool allPages )
+void wxPropertyGridPage::DoSetSplitterPosition( int pos,
+ int splitterColumn,
+ int flags )
{
- if ( allPages && m_manager->GetPageCount() )
+ if ( (flags & wxPG_SPLITTER_ALL_PAGES) && m_manager->GetPageCount() )
m_manager->SetSplitterPosition( pos, splitterColumn );
else
- DoSetSplitterPositionThisPage( pos, splitterColumn );
+ wxPropertyGridPageState::DoSetSplitterPosition( pos,
+ splitterColumn,
+ 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(wxCLASSINFO(wxHeaderCtrlEvent)) )
+ {
+ wxHeaderCtrlEvent& hcEvent =
+ static_cast<wxHeaderCtrlEvent&>(event);
+
+ wxPropertyGrid* pg = m_manager->GetGrid();
+ int col = hcEvent.GetColumn();
+ int evtType = event.GetEventType();
+
+ if ( evtType == wxEVT_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_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_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
// -----------------------------------------------------------------------
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_ADVTBITEMSBASE_OFFSET 5 // Must be last.
-
// -----------------------------------------------------------------------
BEGIN_EVENT_TABLE(wxPropertyGridManager, wxPanel)
const wxPoint& pos,
const wxSize& size,
long style,
- const wxChar* name )
+ const wxString& name )
: wxPanel()
{
Init1();
const wxPoint& pos,
const wxSize& size,
long style,
- const wxChar* name )
+ const wxString& name )
{
+ if ( !m_pPropGrid )
+ m_pPropGrid = CreatePropertyGrid();
bool res = wxPanel::Create( parent, id, pos, size,
(style&0xFFFF0000)|wxWANTS_CHARS,
name );
Init2(style);
+ // FIXME: this changes call ordering so wxPropertyGrid is created
+ // immediately, before SetExtraStyle has a chance to be called. However,
+ // without it, we may get assertions if size is wxDefaultSize.
+ //SetInitialSize(size);
+
return res;
}
void wxPropertyGridManager::Init1()
{
- //m_pPropGrid = (wxPropertyGrid*) NULL;
- m_pPropGrid = CreatePropertyGrid();
+ m_pPropGrid = NULL;
#if wxUSE_TOOLBAR
- m_pToolbar = (wxToolBar*) NULL;
+ m_pToolbar = NULL;
+#endif
+#if wxUSE_HEADERCTRL
+ m_pHeaderCtrl = NULL;
+ m_showHeader = false;
#endif
- m_pTxtHelpCaption = (wxStaticText*) NULL;
- m_pTxtHelpContent = (wxStaticText*) NULL;
+ m_pTxtHelpCaption = NULL;
+ m_pTxtHelpContent = NULL;
- m_emptyPage = (wxPropertyGridPage*) NULL;
+ m_emptyPage = NULL;
m_selPage = -1;
m_nextDescBoxSize = -1;
+ m_categorizedModeToolId = -1;
+ m_alphabeticModeToolId = -1;
+
m_extraHeight = 0;
m_dragStatus = 0;
m_onSplitter = 0;
// -----------------------------------------------------------------------
// These flags are always used in wxPropertyGrid integrated in wxPropertyGridManager.
-#ifndef __WXMAC__
- #define wxPG_MAN_PROPGRID_FORCED_FLAGS (wxSIMPLE_BORDER| \
+#define wxPG_MAN_PROPGRID_FORCED_FLAGS ( wxBORDER_THEME | \
wxNO_FULL_REPAINT_ON_RESIZE| \
wxCLIP_CHILDREN)
-#else
- #define wxPG_MAN_PROPGRID_FORCED_FLAGS (wxNO_BORDER| \
- wxNO_FULL_REPAINT_ON_RESIZE| \
- wxCLIP_CHILDREN)
-#endif
// Which flags can be passed to underlying wxPropertyGrid.
#define wxPG_MAN_PASS_FLAGS_MASK (0xFFF0|wxTAB_TRAVERSAL)
pd->m_manager = this;
wxPropertyGridPageState* state = pd->GetStatePtr();
state->m_pPropGrid = m_pPropGrid;
- m_arrPages.Add( (void*)pd );
+ m_arrPages.push_back( pd );
m_pPropGrid->m_pState = state;
wxWindowID baseId = GetId();
if ( baseId < 0 )
baseId = wxPG_MAN_ALTERNATE_BASE_ID;
- m_baseId = baseId;
-
#ifdef __WXMAC__
// Smaller controls on Mac
SetWindowVariant(wxWINDOW_VARIANT_SMALL);
-#endif
+#endif
+
+ long propGridFlags = (m_windowStyle&wxPG_MAN_PASS_FLAGS_MASK)
+ |wxPG_MAN_PROPGRID_FORCED_FLAGS;
+
+ propGridFlags &= ~wxBORDER_MASK;
+
+ if ((style & wxPG_NO_INTERNAL_BORDER) == 0)
+ {
+ propGridFlags |= wxBORDER_THEME;
+ }
+ else
+ {
+ propGridFlags |= wxBORDER_NONE;
+ wxWindow::SetExtraStyle(wxPG_EX_TOOLBAR_SEPARATOR);
+ }
// Create propertygrid.
- m_pPropGrid->Create(this,baseId,wxPoint(0,0),csz,
- (m_windowStyle&wxPG_MAN_PASS_FLAGS_MASK)
- |wxPG_MAN_PROPGRID_FORCED_FLAGS);
+ m_pPropGrid->Create(this,baseId,wxPoint(0,0),csz, propGridFlags);
m_pPropGrid->m_eventObject = this;
m_pPropGrid->SetExtraStyle(wxPG_EX_INIT_NOCAT);
- m_nextTbInd = baseId+ID_ADVTBITEMSBASE_OFFSET + 2;
-
-
// 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 to toolbar button events.
- Connect(baseId+ID_ADVTBITEMSBASE_OFFSET,baseId+ID_ADVTBITEMSBASE_OFFSET+50,
- wxEVT_COMMAND_TOOL_CLICKED,
- wxCommandEventHandler(wxPropertyGridManager::OnToolbarClick) );
+ Connect(m_pPropGrid->GetId(),
+ wxEVT_PG_COL_DRAGGING,
+ wxPropertyGridEventHandler(wxPropertyGridManager::OnPGColDrag));
// Optional initial controls.
m_width = -12345;
{
END_MOUSE_CAPTURE
- m_pPropGrid->DoSelectProperty(NULL);
- m_pPropGrid->m_pState = NULL;
+ //m_pPropGrid->ClearSelection();
+ wxDELETE(m_pPropGrid);
size_t i;
- for ( i=0; i<m_arrPages.GetCount(); i++ )
+ for ( i=0; i<m_arrPages.size(); i++ )
{
- delete (wxPropertyGridPage*)m_arrPages.Item(i);
+ delete m_arrPages[i];
}
delete m_emptyPage;
// TODO: Need to do caption recacalculations for other pages as well.
unsigned int i;
- for ( i=0; i<m_arrPages.GetCount(); i++ )
+ for ( i=0; i<m_arrPages.size(); i++ )
{
wxPropertyGridPage* page = GetPage(i);
void wxPropertyGridManager::SetWindowStyleFlag( long style )
{
+ int oldWindowStyle = GetWindowStyleFlag();
+
wxWindow::SetWindowStyleFlag( style );
m_pPropGrid->SetWindowStyleFlag( (m_pPropGrid->GetWindowStyleFlag()&~(wxPG_MAN_PASS_FLAGS_MASK)) |
(style&wxPG_MAN_PASS_FLAGS_MASK) );
+
+ // Need to re-position windows?
+ if ( (oldWindowStyle & (wxPG_TOOLBAR|wxPG_DESCRIPTION)) !=
+ (style & (wxPG_TOOLBAR|wxPG_DESCRIPTION)) )
+ {
+ RecreateControls();
+ }
+}
+
+// -----------------------------------------------------------------------
+
+bool wxPropertyGridManager::Reparent( wxWindowBase *newParent )
+{
+ if ( m_pPropGrid )
+ m_pPropGrid->OnTLPChanging((wxWindow*)newParent);
+
+ bool res = wxPanel::Reparent(newParent);
+
+ return res;
}
// -----------------------------------------------------------------------
if ( m_selPage == index )
return true;
- if ( m_pPropGrid->m_selected )
+ if ( m_pPropGrid->GetSelection() )
{
if ( !m_pPropGrid->ClearSelection() )
return false;
}
+#if wxUSE_TOOLBAR
wxPropertyGridPage* prevPage;
if ( m_selPage >= 0 )
prevPage = GetPage(m_selPage);
else
prevPage = m_emptyPage;
+#endif
wxPropertyGridPage* nextPage;
if ( index >= 0 )
{
- nextPage = (wxPropertyGridPage*)m_arrPages.Item(index);
+ nextPage = m_arrPages[index];
nextPage->OnShow();
}
if ( m_pToolbar )
{
if ( index >= 0 )
- m_pToolbar->ToggleTool( nextPage->m_id, true );
+ m_pToolbar->ToggleTool( nextPage->m_toolId, true );
else
- m_pToolbar->ToggleTool( prevPage->m_id, false );
+ m_pToolbar->ToggleTool( prevPage->m_toolId, false );
}
#endif
+#if wxUSE_HEADERCTRL
+ if ( m_showHeader )
+ m_pHeaderCtrl->OnPageChanged(nextPage);
+#endif
+
return true;
}
size_t i;
for ( i=0; i<GetPageCount(); i++ )
{
- if ( ((wxPropertyGridPage*)m_arrPages.Item(i))->m_label == name )
+ if ( m_arrPages[i]->m_label == name )
return i;
}
return wxNOT_FOUND;
size_t i;
for ( i=0; i<GetPageCount(); i++ )
{
- if ( pState == ((wxPropertyGridPage*)m_arrPages.Item(i))->GetStatePtr() )
+ if ( pState == m_arrPages[i]->GetStatePtr() )
return i;
}
const wxString& wxPropertyGridManager::GetPageName( int index ) const
{
wxASSERT( index >= 0 && index < (int)GetPageCount() );
- return ((wxPropertyGridPage*)m_arrPages.Item(index))->m_label;
+ return m_arrPages[index]->m_label;
}
// -----------------------------------------------------------------------
if ( page == -1 )
return m_pState;
- return GETPAGESTATE(page);
+ return m_arrPages[page];
}
// -----------------------------------------------------------------------
void wxPropertyGridManager::Clear()
{
+ m_pPropGrid->ClearSelection(false);
+
m_pPropGrid->Freeze();
int i;
for ( i=(int)GetPageCount()-1; i>=0; i-- )
RemovePage(i);
- // Reset toolbar ids
- m_nextTbInd = m_baseId+ID_ADVTBITEMSBASE_OFFSET + 2;
-
m_pPropGrid->Thaw();
}
if ( page >= 0 && page < (int)GetPageCount() )
{
- wxPropertyGridPageState* state = GETPAGESTATE(page);
+ wxPropertyGridPageState* state = m_arrPages[page];
if ( state == m_pPropGrid->GetState() )
m_pPropGrid->Clear();
GetPageState(page)->SetColumnCount( colCount );
GetGrid()->Refresh();
+
+#if wxUSE_HEADERCTRL
+ if ( m_showHeader )
+ m_pHeaderCtrl->OnPageUpdated();
+#endif
}
// -----------------------------------------------------------------------
size_t wxPropertyGridManager::GetPageCount() const
{
- if ( !(m_iFlags & wxPG_MAN_FL_PAGE_INSERTED) )
- return 0;
+ if ( !(m_iFlags & wxPG_MAN_FL_PAGE_INSERTED) )
+ return 0;
- return m_arrPages.GetCount();
+ return m_arrPages.size();
}
// -----------------------------------------------------------------------
-int wxPropertyGridManager::InsertPage( int index, const wxString& label,
- const wxBitmap& bmp, wxPropertyGridPage* pageObj )
+wxPropertyGridPage* wxPropertyGridManager::InsertPage( int index,
+ const wxString& label,
+ const wxBitmap& bmp,
+ wxPropertyGridPage* pageObj )
{
if ( index < 0 )
index = GetPageCount();
- wxCHECK_MSG( (size_t)index == GetPageCount(), -1,
+ wxCHECK_MSG( (size_t)index == GetPageCount(), NULL,
wxT("wxPropertyGridManager currently only supports appending pages (due to wxToolBar limitation)."));
bool needInit = true;
state->InitNonCatMode();
}
- if ( label.length() )
+ if ( !label.empty() )
{
wxASSERT_MSG( !pageObj->m_label.length(),
wxT("If page label is given in constructor, empty label must be given in AddPage"));
pageObj->m_label = label;
}
- pageObj->m_id = m_nextTbInd;
+ pageObj->m_toolId = -1;
+
+ if ( !HasFlag(wxPG_SPLITTER_AUTO_CENTER) )
+ pageObj->m_dontCenterSplitter = true;
if ( isPageInserted )
- m_arrPages.Add( (void*)pageObj );
+ m_arrPages.push_back( pageObj );
#if wxUSE_TOOLBAR
if ( m_windowStyle & wxPG_TOOLBAR )
m_pToolbar->GetToolsCount() < 3 )
m_pToolbar->AddSeparator();
+ wxToolBarToolBase* tool;
+
if ( &bmp != &wxNullBitmap )
- m_pToolbar->AddTool(m_nextTbInd,label,bmp,label,wxITEM_RADIO);
- //m_pToolbar->InsertTool(index+3,m_nextTbInd,bmp);
+ tool = m_pToolbar->AddTool(wxID_ANY, label, bmp,
+ label, wxITEM_RADIO);
else
- m_pToolbar->AddTool(m_nextTbInd,label,wxBitmap( (const char**)gs_xpm_defpage ),
- label,wxITEM_RADIO);
+ tool = m_pToolbar->AddTool(wxID_ANY, label,
+ wxBitmap(gs_xpm_defpage),
+ label, wxITEM_RADIO);
- m_nextTbInd++;
+ pageObj->m_toolId = tool->GetId();
+
+ // Connect to toolbar button events.
+ Connect(pageObj->m_toolId,
+ wxEVT_TOOL,
+ wxCommandEventHandler(
+ wxPropertyGridManager::OnToolbarClick));
m_pToolbar->Realize();
}
wxASSERT( pageObj->GetGrid() );
- return index;
+ return pageObj;
}
// -----------------------------------------------------------------------
size_t i;
for ( i=0; i<GetPageCount(); i++ )
{
- if ( ((wxPropertyGridPage*)m_arrPages.Item(i))->GetStatePtr()->m_anyModified )
+ if ( m_arrPages[i]->GetStatePtr()->m_anyModified )
return true;
}
return false;
bool wxPropertyGridManager::IsPageModified( size_t index ) const
{
- if ( ((wxPropertyGridPage*)m_arrPages.Item(index))->GetStatePtr()->m_anyModified )
+ if ( m_arrPages[index]->GetStatePtr()->m_anyModified )
return true;
return false;
}
// -----------------------------------------------------------------------
+#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)
+ for ( unsigned int i=0; i<GetPageCount(); i++ )
+ {
+ if ( GetPageState(i)->DoIsPropertySelected(p) )
+ return true;
+ }
+ return false;
+}
+
+// -----------------------------------------------------------------------
+
wxPGProperty* wxPropertyGridManager::GetPageRoot( int index ) const
{
wxASSERT( index >= 0 );
- wxASSERT( index < (int)m_arrPages.GetCount() );
+ wxASSERT( index < (int)m_arrPages.size() );
- return ((wxPropertyGridPage*)m_arrPages.Item(index))->GetStatePtr()->m_properties;
+ return m_arrPages[index]->GetStatePtr()->m_properties;
}
// -----------------------------------------------------------------------
false,
wxT("invalid page index") );
- wxPropertyGridPage* pd = (wxPropertyGridPage*)m_arrPages.Item(page);
+ wxPropertyGridPage* pd = m_arrPages[page];
- if ( m_arrPages.GetCount() == 1 )
+ if ( m_arrPages.size() == 1 )
{
// Last page: do not remove page entry
m_pPropGrid->Clear();
m_iFlags &= ~wxPG_MAN_FL_PAGE_INSERTED;
pd->m_label.clear();
}
+
// Change selection if current is page
else if ( page == m_selPage )
{
}
#endif
- if ( m_arrPages.GetCount() > 1 )
+ if ( m_arrPages.size() > 1 )
{
- m_arrPages.RemoveAt(page);
+ m_arrPages.erase(m_arrPages.begin() + page);
delete pd;
}
// -----------------------------------------------------------------------
-void wxPropertyGridManager::RepaintSplitter( wxDC& dc, int new_splittery, int new_width,
- int new_height, bool desc_too )
+void wxPropertyGridManager::RepaintDescBoxDecorations( wxDC& dc,
+ int newSplitterY,
+ int newWidth,
+ int newHeight )
{
- int use_hei = new_height;
-
// Draw background
wxColour bgcol = GetBackgroundColour();
- dc.SetBrush( bgcol );
- dc.SetPen( bgcol );
- int rect_hei = use_hei-new_splittery;
- if ( !desc_too )
- rect_hei = m_splitterHeight;
- dc.DrawRectangle(0,new_splittery,new_width,rect_hei);
- dc.SetPen ( wxSystemSettings::GetColour ( wxSYS_COLOUR_3DDKSHADOW ) );
- int splitter_bottom = new_splittery+m_splitterHeight - 1;
- int box_height = use_hei-splitter_bottom;
- if ( box_height > 1 )
- dc.DrawRectangle(0,splitter_bottom,new_width,box_height);
+ dc.SetBrush(bgcol);
+ dc.SetPen(bgcol);
+ int rectHeight = m_splitterHeight;
+ dc.DrawRectangle(0, newSplitterY, newWidth, rectHeight);
+ dc.SetPen( wxSystemSettings::GetColour(wxSYS_COLOUR_3DDKSHADOW) );
+ int splitterBottom = newSplitterY + m_splitterHeight - 1;
+ int boxHeight = newHeight - splitterBottom;
+ if ( boxHeight > 1 )
+ dc.DrawRectangle(0, splitterBottom, newWidth, boxHeight);
else
- dc.DrawLine(0,splitter_bottom,new_width,splitter_bottom);
+ dc.DrawLine(0, splitterBottom, newWidth, splitterBottom);
}
// -----------------------------------------------------------------------
-void wxPropertyGridManager::RefreshHelpBox( int new_splittery, int new_width, int new_height )
+void wxPropertyGridManager::UpdateDescriptionBox( int new_splittery, int new_width, int new_height )
{
- //if ( new_splittery == m_splitterY && new_width == m_width )
- // return;
-
int use_hei = new_height;
use_hei--;
- //wxRendererNative::Get().DrawSplitterSash(this,dc,
- //wxSize(width,m_splitterHeight),new_splittery,wxHORIZONTAL);
-
- //wxRendererNative::Get().DrawSplitterBorder(this,dc,
- // wxRect(0,new_splittery,new_width,m_splitterHeight));
-
// Fix help control positions.
int cap_hei = m_pPropGrid->m_fontHeight;
int cap_y = new_splittery+m_splitterHeight+5;
}
}
- wxClientDC dc(this);
- RepaintSplitter( dc, new_splittery, new_width, new_height, true );
+ wxRect r(0, new_splittery, new_width, new_height-new_splittery);
+ RefreshRect(r);
m_splitterY = new_splittery;
#if wxUSE_TOOLBAR
if ( m_pToolbar )
{
- int tbHeight;
+ m_pToolbar->SetSize(0, 0, width, -1);
+ propgridY += m_pToolbar->GetSize().y;
- #if ( wxMINOR_VERSION < 6 || (wxMINOR_VERSION == 6 && wxRELEASE_NUMBER < 2) )
- tbHeight = -1;
- #else
- // In wxWidgets 2.6.2+, Toolbar default height may be broken
- #if defined(__WXMSW__)
- tbHeight = 24;
- #elif defined(__WXGTK__)
- tbHeight = -1; // 22;
- #elif defined(__WXMAC__)
- tbHeight = 22;
- #else
- tbHeight = 22;
- #endif
- #endif
+ if (GetExtraStyle() & wxPG_EX_TOOLBAR_SEPARATOR)
+ propgridY += 1;
+ }
+#endif
- m_pToolbar->SetSize(0,0,width,tbHeight);
- propgridY += m_pToolbar->GetSize().y;
+ // 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
propgridBottomY = new_splittery;
- RefreshHelpBox( new_splittery, width, height );
+ UpdateDescriptionBox( new_splittery, width, height );
}
if ( m_iFlags & wxPG_FL_INITIALIZED )
{
int pgh = propgridBottomY - propgridY;
+ if ( pgh < 0 )
+ pgh = 0;
m_pPropGrid->SetSize( 0, propgridY, width, pgh );
m_extraHeight = height - pgh;
{
if ( m_windowStyle & wxPG_DESCRIPTION )
{
- m_nextDescBoxSize = ht;
- if ( refresh )
- RecalculatePositions(m_width, m_height);
+ if ( ht != GetDescBoxHeight() )
+ {
+ m_nextDescBoxSize = ht;
+ if ( refresh )
+ RecalculatePositions(m_width, m_height);
+ }
}
}
int wxPropertyGridManager::GetDescBoxHeight() const
{
- return GetClientSize().y - m_splitterY;
+ return GetClientSize().y - m_splitterY - m_splitterHeight;
}
// -----------------------------------------------------------------------
// Update everything inside the box
wxRect r = GetUpdateRegion().GetBox();
- // Repaint splitter?
- int r_bottom = r.y + r.height;
- int splitter_bottom = m_splitterY + m_splitterHeight;
- if ( r.y < splitter_bottom && r_bottom >= m_splitterY )
- RepaintSplitter( dc, m_splitterY, m_width, m_height, false );
+ if (GetExtraStyle() & wxPG_EX_TOOLBAR_SEPARATOR)
+ {
+ if (m_pToolbar && m_pPropGrid)
+ {
+ wxPen marginPen(m_pPropGrid->GetMarginColour());
+ dc.SetPen(marginPen);
+
+ int y = m_pPropGrid->GetPosition().y-1;
+ dc.DrawLine(0, y, GetClientSize().x, y);
+ }
+ }
+
+ // Repaint splitter and any other description box decorations
+ if ( (r.y + r.height) >= m_splitterY && m_splitterY != -1)
+ RepaintDescBoxDecorations( dc, m_splitterY, m_width, m_height );
}
// -----------------------------------------------------------------------
if ( was_shown )
Show ( false );
- wxWindowID baseId = m_pPropGrid->GetId();
- if ( baseId < 0 )
- baseId = wxPG_MAN_ALTERNATE_BASE_ID;
-
#if wxUSE_TOOLBAR
if ( m_windowStyle & wxPG_TOOLBAR )
{
// Has toolbar.
if ( !m_pToolbar )
{
- m_pToolbar = new wxToolBar(this,baseId+ID_ADVTOOLBAR_OFFSET,
- wxDefaultPosition,wxDefaultSize,
- ((GetExtraStyle()&wxPG_EX_NO_FLAT_TOOLBAR)?0:wxTB_FLAT)
- /*| wxTB_HORIZONTAL | wxNO_BORDER*/ );
+ long toolBarFlags = ((GetExtraStyle()&wxPG_EX_NO_FLAT_TOOLBAR)?0:wxTB_FLAT);
+ if (GetExtraStyle() & wxPG_EX_NO_TOOLBAR_DIVIDER)
+ toolBarFlags |= wxTB_NODIVIDER;
+
+ m_pToolbar = new wxToolBar(this, wxID_ANY,
+ wxDefaultPosition,
+ wxDefaultSize,
+ toolBarFlags);
+ m_pToolbar->SetToolBitmapSize(wxSize(16, 15));
#if defined(__WXMSW__)
// Eliminate toolbar flicker on XP
{
wxString desc1(_("Categorized Mode"));
wxString desc2(_("Alphabetic Mode"));
- m_pToolbar->AddTool(baseId+ID_ADVTBITEMSBASE_OFFSET+0,
- desc1,wxBitmap ( (const char**)gs_xpm_catmode ),
- desc1,wxITEM_RADIO);
- m_pToolbar->AddTool(baseId+ID_ADVTBITEMSBASE_OFFSET+1,
- desc2,wxBitmap ( (const char**)gs_xpm_noncatmode ),
- desc2,wxITEM_RADIO);
+
+ wxToolBarToolBase* tool;
+
+ tool = m_pToolbar->AddTool(wxID_ANY,
+ desc1,
+ wxBitmap(gs_xpm_catmode),
+ desc1,
+ wxITEM_RADIO);
+ m_categorizedModeToolId = tool->GetId();
+
+ tool = m_pToolbar->AddTool(wxID_ANY,
+ desc2,
+ wxBitmap(gs_xpm_noncatmode),
+ desc2,
+ wxITEM_RADIO);
+ m_alphabeticModeToolId = tool->GetId();
+
m_pToolbar->Realize();
+
+ Connect(m_categorizedModeToolId,
+ wxEVT_TOOL,
+ wxCommandEventHandler(
+ wxPropertyGridManager::OnToolbarClick));
+ Connect(m_alphabeticModeToolId,
+ wxEVT_TOOL,
+ wxCommandEventHandler(
+ wxPropertyGridManager::OnToolbarClick));
+ }
+ else
+ {
+ m_categorizedModeToolId = -1;
+ m_alphabeticModeToolId = -1;
}
}
- if ( (GetExtraStyle()&wxPG_EX_MODE_BUTTONS) )
+ if ( (GetExtraStyle() & wxPG_EX_MODE_BUTTONS) )
{
// Toggle correct mode button.
// TODO: This doesn't work in wxMSW (when changing,
// both items will get toggled).
- int toggle_but_on_ind = ID_ADVTBITEMSBASE_OFFSET+0;
- int toggle_but_off_ind = ID_ADVTBITEMSBASE_OFFSET+1;
+ int toggle_but_on_ind;
+ int toggle_but_off_ind;
if ( m_pPropGrid->m_pState->IsInNonCatMode() )
{
- toggle_but_on_ind++;
- toggle_but_off_ind--;
+ toggle_but_on_ind = m_alphabeticModeToolId;
+ toggle_but_off_ind = m_categorizedModeToolId;
+ }
+ else
+ {
+ toggle_but_on_ind = m_categorizedModeToolId;
+ toggle_but_off_ind = m_alphabeticModeToolId;
}
- m_pToolbar->ToggleTool(baseId+toggle_but_on_ind,true);
- m_pToolbar->ToggleTool(baseId+toggle_but_off_ind,false);
+ m_pToolbar->ToggleTool(toggle_but_on_ind, true);
+ m_pToolbar->ToggleTool(toggle_but_off_ind, false);
}
}
// No toolbar.
if ( m_pToolbar )
m_pToolbar->Destroy();
- m_pToolbar = (wxToolBar*) NULL;
+ m_pToolbar = NULL;
+ }
+#endif
+
+#if wxUSE_HEADERCTRL
+ if ( m_showHeader )
+ {
+ wxPGHeaderCtrl* hc;
+
+ if ( !m_pHeaderCtrl )
+ {
+ hc = new wxPGHeaderCtrl(this);
+ hc->Create(this, wxID_ANY);
+ m_pHeaderCtrl = hc;
+ }
+ else
+ {
+ m_pHeaderCtrl->Show();
+ }
+
+ m_pHeaderCtrl->OnPageChanged(GetCurrentPage());
+ }
+ else
+ {
+ if ( m_pHeaderCtrl )
+ m_pHeaderCtrl->Hide();
}
#endif
if ( !m_pTxtHelpCaption )
{
- m_pTxtHelpCaption = new wxStaticText (this,baseId+ID_ADVHELPCAPTION_OFFSET,wxEmptyString);
+ m_pTxtHelpCaption = new wxStaticText(this,
+ wxID_ANY,
+ wxT(""),
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_LEFT|wxST_NO_AUTORESIZE);
m_pTxtHelpCaption->SetFont( m_pPropGrid->m_captionFont );
- m_pTxtHelpCaption->SetCursor ( *wxSTANDARD_CURSOR );
+ m_pTxtHelpCaption->SetCursor( *wxSTANDARD_CURSOR );
}
if ( !m_pTxtHelpContent )
{
- m_pTxtHelpContent = new wxStaticText (this,baseId+ID_ADVHELPCONTENT_OFFSET,
- wxEmptyString,wxDefaultPosition,wxDefaultSize,wxALIGN_LEFT|wxST_NO_AUTORESIZE);
- m_pTxtHelpContent->SetCursor ( *wxSTANDARD_CURSOR );
+ m_pTxtHelpContent = new wxStaticText(this,
+ wxID_ANY,
+ wxT(""),
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxALIGN_LEFT|wxST_NO_AUTORESIZE);
+ m_pTxtHelpContent->SetCursor( *wxSTANDARD_CURSOR );
}
+
+ SetDescribedProperty(GetSelection());
}
else
{
if ( m_pTxtHelpCaption )
m_pTxtHelpCaption->Destroy();
- m_pTxtHelpCaption = (wxStaticText*) NULL;
+ m_pTxtHelpCaption = NULL;
if ( m_pTxtHelpContent )
m_pTxtHelpContent->Destroy();
- m_pTxtHelpContent = (wxStaticText*) NULL;
+ m_pTxtHelpContent = NULL;
}
int width, height;
size_t i;
for ( i=0; i<GetPageCount(); i++ )
{
- wxPropertyGridPageState* pState = ((wxPropertyGridPage*)m_arrPages.Item(i))->GetStatePtr();
+ wxPropertyGridPageState* pState = m_arrPages[i]->GetStatePtr();
wxPGProperty* p = pState->BaseGetPropertyByName(name);
if ( p )
{
// -----------------------------------------------------------------------
-size_t wxPropertyGridManager::GetChildrenCount( int page_index )
-{
- return GetChildrenCount( GetPage(page_index)->GetStatePtr()->m_properties );
-}
-
-// -----------------------------------------------------------------------
-
void wxPropertyGridManager::OnToolbarClick( wxCommandEvent &event )
{
int id = event.GetId();
- if ( id >= 0 )
- {
- int baseId = m_pPropGrid->GetId();
- if ( baseId < 0 )
- baseId = wxPG_MAN_ALTERNATE_BASE_ID;
- if ( id == ( baseId + ID_ADVTBITEMSBASE_OFFSET + 0 ) )
+ if ( id == m_categorizedModeToolId )
+ {
+ // Categorized mode.
+ if ( m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES )
{
- // Categorized mode.
- if ( m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES )
- m_pPropGrid->EnableCategories( true );
+ if ( !m_pPropGrid->HasInternalFlag(wxPG_FL_CATMODE_AUTO_SORT) )
+ m_pPropGrid->m_windowStyle &= ~wxPG_AUTO_SORT;
+ m_pPropGrid->EnableCategories( true );
}
- else if ( id == ( baseId + ID_ADVTBITEMSBASE_OFFSET + 1 ) )
+ }
+ else if ( id == m_alphabeticModeToolId )
+ {
+ // Alphabetic mode.
+ if ( !(m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES) )
{
- // Alphabetic mode.
- if ( !(m_pPropGrid->m_windowStyle & wxPG_HIDE_CATEGORIES) )
- m_pPropGrid->EnableCategories( false );
+ if ( m_pPropGrid->HasFlag(wxPG_AUTO_SORT) )
+ m_pPropGrid->SetInternalFlag(wxPG_FL_CATMODE_AUTO_SORT);
+ else
+ m_pPropGrid->ClearInternalFlag(wxPG_FL_CATMODE_AUTO_SORT);
+
+ m_pPropGrid->m_windowStyle |= wxPG_AUTO_SORT;
+ m_pPropGrid->EnableCategories( false );
}
- else
- {
- // Page Switching.
+ }
+ else
+ {
+ // Page Switching.
- int index = -1;
- size_t i;
- wxPropertyGridPage* pdc;
+ int index = -1;
+ size_t i;
+ wxPropertyGridPage* pdc;
- // Find page with given id.
- for ( i=0; i<GetPageCount(); i++ )
+ // Find page with given id.
+ for ( i=0; i<GetPageCount(); i++ )
+ {
+ pdc = m_arrPages[i];
+ if ( pdc->m_toolId == id )
{
- pdc = (wxPropertyGridPage*)m_arrPages.Item(i);
- if ( pdc->m_id == id )
- {
- index = i;
- break;
- }
+ index = i;
+ break;
}
+ }
- wxASSERT( index >= 0 );
+ wxASSERT( index >= 0 );
- if ( DoSelectPage( index ) )
- {
+ if ( DoSelectPage( index ) )
+ {
+ // Event dispatching must be last.
+ m_pPropGrid->SendEvent( wxEVT_PG_PAGE_CHANGED, NULL );
+ }
+ else
+ {
+ // TODO: Depress the old button on toolbar.
+ }
+ }
+}
- // Event dispatching must be last.
- m_pPropGrid->SendEvent( wxEVT_PG_PAGE_CHANGED, (wxPGProperty*) NULL );
+// -----------------------------------------------------------------------
- }
- else
- {
- // TODO: Depress the old button on toolbar.
- }
+bool wxPropertyGridManager::SetEditableStateItem( const wxString& name, wxVariant value )
+{
+ if ( name == wxS("descboxheight") )
+ {
+ SetDescBoxHeight(value.GetLong(), true);
+ return true;
+ }
+ return false;
+}
- }
+// -----------------------------------------------------------------------
+
+wxVariant wxPropertyGridManager::GetEditableStateItem( const wxString& name ) const
+{
+ if ( name == wxS("descboxheight") )
+ {
+ return (long) GetDescBoxHeight();
}
+ return wxNullVariant;
}
// -----------------------------------------------------------------------
m_pTxtHelpCaption->SetSize(-1,osz1.y);
m_pTxtHelpContent->SetSize(-1,osz2.y);
- if ( (m_iFlags & wxPG_FL_DESC_REFRESH_REQUIRED) || (osz2.x<(m_width-10)) )
- RefreshHelpBox( m_splitterY, m_width, m_height );
+ UpdateDescriptionBox( m_splitterY, m_width, m_height );
}
}
}
else
{
- m_pTxtHelpCaption->SetLabel(wxEmptyString);
- m_pTxtHelpContent->SetLabel(wxEmptyString);
+ SetDescription( wxEmptyString, wxEmptyString );
}
}
}
else
{
wxClientDC dc(this);
- dc.SetFont(m_pPropGrid->m_font);
+ dc.SetFont(m_pPropGrid->GetFont());
int highest = 0;
unsigned int i;
for ( i=0; i<GetPageCount(); i++ )
{
- int maxW = m_pState->GetColumnFitWidth(dc, GETPAGESTATE(i)->m_properties, 0, subProps );
+ int maxW = m_pState->GetColumnFitWidth(dc, m_arrPages[i]->m_properties, 0, subProps );
maxW += m_pPropGrid->m_marginWidth;
if ( maxW > highest )
highest = maxW;
+ m_pState->m_dontCenterSplitter = true;
}
if ( highest > 0 )
- m_pPropGrid->SetSplitterPosition( highest );
+ SetSplitterPosition( highest );
+ }
+
+#if wxUSE_HEADERCTRL
+ if ( m_showHeader )
+ m_pHeaderCtrl->OnColumWidthsChanged();
+#endif
+}
+
+void wxPropertyGridManager::SetPageSplitterLeft(int page, bool subProps)
+{
+ wxASSERT_MSG( (page < (int) GetPageCount()),
+ wxT("SetPageSplitterLeft() has no effect until pages have been added") );
+
+ if (page < (int) GetPageCount())
+ {
+ wxClientDC dc(this);
+ dc.SetFont(m_pPropGrid->GetFont());
+
+ int maxW = m_pState->GetColumnFitWidth(dc, m_arrPages[page]->m_properties, 0, subProps );
+ maxW += m_pPropGrid->m_marginWidth;
+ SetPageSplitterPosition( page, maxW );
- 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);
+ }
+ }
+ }
+
+#if wxUSE_HEADERCTRL
+ if ( m_showHeader )
+ m_pHeaderCtrl->OnColumWidthsChanged();
+#endif
}
// -----------------------------------------------------------------------
m_splitterY = sy;
m_pPropGrid->SetSize( m_width, m_splitterY - m_pPropGrid->GetPosition().y );
- RefreshHelpBox( m_splitterY, m_width, m_height );
+ UpdateDescriptionBox( m_splitterY, m_width, m_height );
m_extraHeight -= change;
InvalidateBestSize();
void wxPropertyGridManager::OnMouseUp( wxMouseEvent &event )
{
- // No event type check - basicly calling this method should
+ // No event type check - basically calling this method should
// just stop dragging.
if ( m_dragStatus >= 1 )
for ( i=0; i<GetPageCount(); i++ )
{
wxPropertyGridPage* page = GetPage(i);
- page->DoSetSplitterPositionThisPage( pos, splitterColumn );
+ 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
}
// -----------------------------------------------------------------------