+// header column providing access to the column information stored in wxGrid
+// via wxHeaderColumn interface
+class wxGridHeaderColumn : public wxHeaderColumn
+{
+public:
+ wxGridHeaderColumn(wxGrid *grid, int col)
+ : m_grid(grid),
+ m_col(col)
+ {
+ }
+
+ virtual wxString GetTitle() const { return m_grid->GetColLabelValue(m_col); }
+ virtual wxBitmap GetBitmap() const { return wxNullBitmap; }
+ virtual int GetWidth() const { return m_grid->GetColSize(m_col); }
+ virtual int GetMinWidth() const { return 0; }
+ virtual wxAlignment GetAlignment() const
+ {
+ int horz,
+ vert;
+ m_grid->GetColLabelAlignment(&horz, &vert);
+
+ return static_cast<wxAlignment>(horz);
+ }
+
+ virtual int GetFlags() const
+ {
+ // we can't know in advance whether we can sort by this column or not
+ // with wxGrid API so suppose we can by default
+ int flags = wxCOL_SORTABLE;
+ if ( m_grid->CanDragColSize() )
+ flags |= wxCOL_RESIZABLE;
+ if ( m_grid->CanDragColMove() )
+ flags |= wxCOL_REORDERABLE;
+ if ( GetWidth() == 0 )
+ flags |= wxCOL_HIDDEN;
+
+ return flags;
+ }
+
+ virtual bool IsSortKey() const
+ {
+ return m_grid->IsSortingBy(m_col);
+ }
+
+ virtual bool IsSortOrderAscending() const
+ {
+ return m_grid->IsSortOrderAscending();
+ }
+
+private:
+ // these really should be const but are not because the column needs to be
+ // assignable to be used in a wxVector (in STL build, in non-STL build we
+ // avoid the need for this)
+ wxGrid *m_grid;
+ int m_col;
+};
+
+// header control retreiving column information from the grid
+class wxGridHeaderCtrl : public wxHeaderCtrl
+{
+public:
+ wxGridHeaderCtrl(wxGrid *owner)
+ : wxHeaderCtrl(owner,
+ wxID_ANY,
+ wxDefaultPosition,
+ wxDefaultSize,
+ wxHD_ALLOW_HIDE |
+ (owner->CanDragColMove() ? wxHD_ALLOW_REORDER : 0))
+ {
+ }
+
+protected:
+ virtual const wxHeaderColumn& GetColumn(unsigned int idx) const
+ {
+ return m_columns[idx];
+ }
+
+private:
+ wxGrid *GetOwner() const { return static_cast<wxGrid *>(GetParent()); }
+
+ // override the base class method to update our m_columns array
+ virtual void OnColumnCountChanging(unsigned int count)
+ {
+ const unsigned countOld = m_columns.size();
+ if ( count < countOld )
+ {
+ // just discard the columns which don't exist any more (notice that
+ // we can't use resize() here as it would require the vector
+ // value_type, i.e. wxGridHeaderColumn to be default constructible,
+ // which it is not)
+ m_columns.erase(m_columns.begin() + count, m_columns.end());
+ }
+ else // new columns added
+ {
+ // add columns for the new elements
+ for ( unsigned n = countOld; n < count; n++ )
+ m_columns.push_back(wxGridHeaderColumn(GetOwner(), n));
+ }
+ }
+
+ // override to implement column auto sizing
+ virtual bool UpdateColumnWidthToFit(unsigned int idx, int widthTitle)
+ {
+ // TODO: currently grid doesn't support computing the column best width
+ // from its contents so we just use the best label width as is
+ GetOwner()->SetColSize(idx, widthTitle);
+
+ return true;
+ }
+
+ // overridden to react to the actions using the columns popup menu
+ virtual void UpdateColumnVisibility(unsigned int idx, bool show)
+ {
+ GetOwner()->SetColSize(idx, show ? wxGRID_AUTOSIZE : 0);
+
+ // as this is done by the user we should notify the main program about
+ // it
+ GetOwner()->SendEvent(wxEVT_GRID_COL_SIZE, -1, idx);
+ }
+
+ // overridden to react to the columns order changes in the customization
+ // dialog
+ virtual void UpdateColumnsOrder(const wxArrayInt& order)
+ {
+ GetOwner()->SetColumnsOrder(order);
+ }
+
+
+ // event handlers forwarding wxHeaderCtrl events to wxGrid
+ void OnClick(wxHeaderCtrlEvent& event)
+ {
+ GetOwner()->DoColHeaderClick(event.GetColumn());
+ }
+
+ void OnBeginResize(wxHeaderCtrlEvent& event)
+ {
+ GetOwner()->DoStartResizeCol(event.GetColumn());
+
+ event.Skip();
+ }
+
+ void OnResizing(wxHeaderCtrlEvent& event)
+ {
+ GetOwner()->DoUpdateResizeColWidth(event.GetWidth());
+ }
+
+ void OnEndResize(wxHeaderCtrlEvent& event)
+ {
+ GetOwner()->DoEndDragResizeCol();
+
+ event.Skip();
+ }
+
+ void OnBeginReorder(wxHeaderCtrlEvent& event)
+ {
+ GetOwner()->DoStartMoveCol(event.GetColumn());
+ }
+
+ void OnEndReorder(wxHeaderCtrlEvent& event)
+ {
+ GetOwner()->DoEndMoveCol(event.GetNewOrder());
+ }
+
+ wxVector<wxGridHeaderColumn> m_columns;
+
+ DECLARE_EVENT_TABLE()
+ DECLARE_NO_COPY_CLASS(wxGridHeaderCtrl)
+};
+
+BEGIN_EVENT_TABLE(wxGridHeaderCtrl, wxHeaderCtrl)
+ EVT_HEADER_CLICK(wxID_ANY, wxGridHeaderCtrl::OnClick)
+
+ EVT_HEADER_BEGIN_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnBeginResize)
+ EVT_HEADER_RESIZING(wxID_ANY, wxGridHeaderCtrl::OnResizing)
+ EVT_HEADER_END_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnEndResize)
+
+ EVT_HEADER_BEGIN_REORDER(wxID_ANY, wxGridHeaderCtrl::OnBeginReorder)
+ EVT_HEADER_END_REORDER(wxID_ANY, wxGridHeaderCtrl::OnEndReorder)
+END_EVENT_TABLE()
+