/////////////////////////////////////////////////////////////////////////////
-// Name: grid.h
+// Name: wx/generic/grid.h
// Purpose: wxGrid and related classes
// Author: Michael Bedward (based on code by Julian Smart, Robin Dunn)
// Modified by:
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-
#include "wx/defs.h"
#if !defined(wxUSE_NEW_GRID) || !(wxUSE_NEW_GRID)
#pragma interface "grid.h"
#endif
+#include "wx/hash.h"
#include "wx/panel.h"
#include "wx/scrolwin.h"
#include "wx/string.h"
#include "wx/dynarray.h"
#include "wx/timer.h"
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
// Default parameters for wxGrid
//
#define WXGRID_DEFAULT_NUMBER_ROWS 10
#define WXGRID_MIN_COL_WIDTH 15
#define WXGRID_DEFAULT_SCROLLBAR_WIDTH 16
+// type names for grid table values
+#define wxGRID_VALUE_STRING _T("string")
+#define wxGRID_VALUE_BOOL _T("bool")
+#define wxGRID_VALUE_NUMBER _T("long")
+#define wxGRID_VALUE_FLOAT _T("double")
+
+#define wxGRID_VALUE_TEXT wxGRID_VALUE_STRING
+#define wxGRID_VALUE_LONG wxGRID_VALUE_NUMBER
+
// ----------------------------------------------------------------------------
// forward declarations
// ----------------------------------------------------------------------------
class WXDLLEXPORT wxGridRowLabelWindow;
class WXDLLEXPORT wxGridTableBase;
class WXDLLEXPORT wxGridWindow;
+class WXDLLEXPORT wxGridTypeRegistry;
class WXDLLEXPORT wxCheckBox;
+class WXDLLEXPORT wxComboBox;
class WXDLLEXPORT wxTextCtrl;
+class WXDLLEXPORT wxSpinCtrl;
// ----------------------------------------------------------------------------
// wxGridCellRenderer: this class is responsible for actually drawing the cell
const wxRect& rect,
int row, int col,
bool isSelected) = 0;
+
+ // get the preferred size of the cell for its contents
+ virtual wxSize GetBestSize(wxGrid& grid,
+ wxGridCellAttr& attr,
+ wxDC& dc,
+ int row, int col) = 0;
+
+ // virtual dtor for any base class
+ virtual ~wxGridCellRenderer();
};
// the default renderer for the cells containing string data
const wxRect& rect,
int row, int col,
bool isSelected);
+
+ // return the string extent
+ virtual wxSize GetBestSize(wxGrid& grid,
+ wxGridCellAttr& attr,
+ wxDC& dc,
+ int row, int col);
+
+protected:
+ // set the text colours before drawing
+ void SetTextColoursAndFont(wxGrid& grid,
+ wxGridCellAttr& attr,
+ wxDC& dc,
+ bool isSelected);
+
+ // calc the string extent for given string/font
+ wxSize DoGetBestSize(wxGridCellAttr& attr,
+ wxDC& dc,
+ const wxString& text);
+};
+
+// the default renderer for the cells containing numeric (long) data
+class WXDLLEXPORT wxGridCellNumberRenderer : public wxGridCellStringRenderer
+{
+public:
+ // draw the string right aligned
+ virtual void Draw(wxGrid& grid,
+ wxGridCellAttr& attr,
+ wxDC& dc,
+ const wxRect& rect,
+ int row, int col,
+ bool isSelected);
+
+ virtual wxSize GetBestSize(wxGrid& grid,
+ wxGridCellAttr& attr,
+ wxDC& dc,
+ int row, int col);
+
+protected:
+ wxString GetString(wxGrid& grid, int row, int col);
+};
+
+class WXDLLEXPORT wxGridCellFloatRenderer : public wxGridCellStringRenderer
+{
+public:
+ wxGridCellFloatRenderer(int width, int precision);
+
+ // get/change formatting parameters
+ int GetWidth() const { return m_width; }
+ void SetWidth(int width) { m_width = width; }
+ int GetPrecision() const { return m_precision; }
+ void SetPrecision(int precision) { m_precision = precision; }
+
+ // draw the string right aligned with given width/precision
+ virtual void Draw(wxGrid& grid,
+ wxGridCellAttr& attr,
+ wxDC& dc,
+ const wxRect& rect,
+ int row, int col,
+ bool isSelected);
+
+ virtual wxSize GetBestSize(wxGrid& grid,
+ wxGridCellAttr& attr,
+ wxDC& dc,
+ int row, int col);
+protected:
+ wxString GetString(wxGrid& grid, int row, int col);
+
+private:
+ // formatting parameters
+ int m_width,
+ m_precision;
+
+ wxString m_format;
};
// renderer for boolean fields
class WXDLLEXPORT wxGridCellBoolRenderer : public wxGridCellRenderer
{
public:
-
// draw a check mark or nothing
virtual void Draw(wxGrid& grid,
wxGridCellAttr& attr,
const wxRect& rect,
int row, int col,
bool isSelected);
+
+ // return the checkmark size
+ virtual wxSize GetBestSize(wxGrid& grid,
+ wxGridCellAttr& attr,
+ wxDC& dc,
+ int row, int col);
+
+private:
+ static wxSize ms_sizeCheckMark;
};
// ----------------------------------------------------------------------------
// colours/fonts for it
virtual void Show(bool show, wxGridCellAttr *attr = (wxGridCellAttr *)NULL);
+ // Draws the part of the cell not occupied by the control: the base class
+ // version just fills it with background colour from the attribute
+ virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
+
// Fetch the value from the table and prepare the edit control
// to begin editing. Set the focus to the edit control.
virtual void BeginEdit(int row, int col, wxGrid* grid) = 0;
- // Complete the editing of the current cell. If saveValue is
- // true then send the new value back to the table. Returns true
- // if the value has changed. If necessary, the control may be
- // destroyed.
- virtual bool EndEdit(int row, int col, bool saveValue, wxGrid* grid) = 0;
+ // Complete the editing of the current cell. Returns true if the value has
+ // changed. If necessary, the control may be destroyed.
+ virtual bool EndEdit(int row, int col, wxGrid* grid) = 0;
// Reset the value in the control back to its starting value
virtual void Reset() = 0;
// that first key if desired.
virtual void StartingKey(wxKeyEvent& event);
+ // if the editor is enabled by clicking on the cell, this method will be
+ // called
+ virtual void StartingClick();
+
// Some types of controls on some platforms may need some help
// with the Return key.
virtual void HandleReturn(wxKeyEvent& event);
virtual void Create(wxWindow* parent,
wxWindowID id,
wxEvtHandler* evtHandler);
+ virtual void SetSize(const wxRect& rect);
+
+ virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, bool saveValue, wxGrid* grid);
+ virtual bool EndEdit(int row, int col, wxGrid* grid);
virtual void Reset();
virtual void StartingKey(wxKeyEvent& event);
protected:
wxTextCtrl *Text() const { return (wxTextCtrl *)m_control; }
+ // parts of our virtual functions reused by the derived classes
+ void DoBeginEdit(const wxString& startValue);
+ void DoReset(const wxString& startValue);
+
private:
wxString m_startValue;
};
+// the editor for numeric (long) data
+class WXDLLEXPORT wxGridCellNumberEditor : public wxGridCellTextEditor
+{
+public:
+ // allows to specify the range - if min == max == -1, no range checking is
+ // done
+ wxGridCellNumberEditor(int min = -1, int max = -1);
+
+ virtual void Create(wxWindow* parent,
+ wxWindowID id,
+ wxEvtHandler* evtHandler);
+
+ virtual void BeginEdit(int row, int col, wxGrid* grid);
+ virtual bool EndEdit(int row, int col, wxGrid* grid);
+
+ virtual void Reset();
+ virtual void StartingKey(wxKeyEvent& event);
+
+protected:
+ wxSpinCtrl *Spin() const { return (wxSpinCtrl *)m_control; }
+
+ // if HasRange(), we use wxSpinCtrl - otherwise wxTextCtrl
+ bool HasRange() const { return m_min != m_max; }
+
+ // string representation of m_valueOld
+ wxString GetString() const
+ { return wxString::Format(_T("%ld"), m_valueOld); }
+
+private:
+ int m_min,
+ m_max;
+
+ long m_valueOld;
+};
+
+// the editor for floating point numbers (double) data
+class WXDLLEXPORT wxGridCellFloatEditor : public wxGridCellTextEditor
+{
+public:
+ virtual void Create(wxWindow* parent,
+ wxWindowID id,
+ wxEvtHandler* evtHandler);
+
+ virtual void BeginEdit(int row, int col, wxGrid* grid);
+ virtual bool EndEdit(int row, int col, wxGrid* grid);
+
+ virtual void Reset();
+ virtual void StartingKey(wxKeyEvent& event);
+
+protected:
+ // string representation of m_valueOld
+ wxString GetString() const
+ { return wxString::Format(_T("%f"), m_valueOld); }
+
+private:
+ double m_valueOld;
+};
+
// the editor for boolean data
class WXDLLEXPORT wxGridCellBoolEditor : public wxGridCellEditor
{
virtual void Show(bool show, wxGridCellAttr *attr = (wxGridCellAttr *)NULL);
virtual void BeginEdit(int row, int col, wxGrid* grid);
- virtual bool EndEdit(int row, int col, bool saveValue, wxGrid* grid);
+ virtual bool EndEdit(int row, int col, wxGrid* grid);
virtual void Reset();
- virtual void StartingKey(wxKeyEvent& event);
+ virtual void StartingClick();
protected:
wxCheckBox *CBox() const { return (wxCheckBox *)m_control; }
private:
bool m_startValue;
-
- wxRect m_rectCell; // the total size of the cell
};
+// the editor for string data allowing to choose from the list of strings
+class WXDLLEXPORT wxGridCellChoiceEditor : public wxGridCellEditor
+{
+public:
+ // if !allowOthers, user can't type a string not in choices array
+ wxGridCellChoiceEditor(size_t count, const wxChar* choices[],
+ bool allowOthers = FALSE);
+
+ virtual void Create(wxWindow* parent,
+ wxWindowID id,
+ wxEvtHandler* evtHandler);
+
+ virtual void PaintBackground(const wxRect& rectCell, wxGridCellAttr *attr);
+
+ virtual void BeginEdit(int row, int col, wxGrid* grid);
+ virtual bool EndEdit(int row, int col, wxGrid* grid);
+
+ virtual void Reset();
+
+protected:
+ wxComboBox *Combo() const { return (wxComboBox *)m_control; }
+
+private:
+ wxString m_startValue;
+ wxArrayString m_choices;
+ bool m_allowOthers;
+};
// ----------------------------------------------------------------------------
// wxGridCellAttr: this class can be used to alter the cells appearance in
// the grid by changing their colour/font/... from default. An object of this
const wxColour& GetBackgroundColour() const;
const wxFont& GetFont() const;
void GetAlignment(int *hAlign, int *vAlign) const;
- wxGridCellRenderer *GetRenderer() const;
- wxGridCellEditor *GetEditor() const;
+ wxGridCellRenderer *GetRenderer(wxGrid* grid, int row, int col) const;
+ wxGridCellEditor *GetEditor(wxGrid* grid, int row, int col) const;
bool IsReadOnly() const { return m_isReadOnly; }
//
virtual long GetNumberRows() = 0;
virtual long GetNumberCols() = 0;
- virtual wxString GetValue( int row, int col ) = 0;
- virtual void SetValue( int row, int col, const wxString& s ) = 0;
virtual bool IsEmptyCell( int row, int col ) = 0;
+ virtual wxString GetValue( int row, int col ) = 0;
+ virtual void SetValue( int row, int col, const wxString& value ) = 0;
+
+ // Data type determination and value access
+ virtual wxString GetTypeName( int row, int col );
+ virtual bool CanGetValueAs( int row, int col, const wxString& typeName );
+ virtual bool CanSetValueAs( int row, int col, const wxString& typeName );
+
+ virtual long GetValueAsLong( int row, int col );
+ virtual double GetValueAsDouble( int row, int col );
+ virtual bool GetValueAsBool( int row, int col );
+
+ virtual void SetValueAsLong( int row, int col, long value );
+ virtual void SetValueAsDouble( int row, int col, double value );
+ virtual void SetValueAsBool( int row, int col, bool value );
+
+ // For user defined types
+ virtual void* GetValueAsCustom( int row, int col, const wxString& typeName );
+ virtual void SetValueAsCustom( int row, int col, const wxString& typeName, void* value );
+
// Overriding these is optional
//
// get the currently used attr provider (may be NULL)
wxGridCellAttrProvider *GetAttrProvider() const { return m_attrProvider; }
+ // Does this table allow attributes? Default implementation creates
+ // a wxGridCellAttrProvider if necessary.
+ virtual bool CanHaveAttributes();
+
+
// change row/col number in attribute if needed
- void UpdateAttrRows( size_t pos, int numRows );
- void UpdateAttrCols( size_t pos, int numCols );
+ virtual void UpdateAttrRows( size_t pos, int numRows );
+ virtual void UpdateAttrCols( size_t pos, int numCols );
// by default forwarded to wxGridCellAttrProvider if any. May be
- // overridden to handle attributes directly in this class.
+ // overridden to handle attributes directly in the table.
virtual wxGridCellAttr *GetAttr( int row, int col );
// these functions take ownership of the pointer
-//////////////////////////////////////////////////////////////////////
-//
+// ============================================================================
// Grid view classes
-//
-//////////////////////////////////////////////////////////////////////
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxGridCellCoords: location of a cell in the grid
+// ----------------------------------------------------------------------------
class WXDLLEXPORT wxGridCellCoords
{
//
WX_DECLARE_EXPORTED_OBJARRAY(wxGridCellCoords, wxGridCellCoordsArray);
-
-
// ----------------------------------------------------------------------------
// wxGrid
// ----------------------------------------------------------------------------
bool DeleteCols( int pos = 0, int numCols = 1, bool updateLabels=TRUE );
void DrawGridCellArea( wxDC& dc );
+ void DrawGridSpace( wxDC& dc );
void DrawCellBorder( wxDC& dc, const wxGridCellCoords& );
void DrawAllGridLines( wxDC& dc, const wxRegion & reg );
void DrawCell( wxDC& dc, const wxGridCellCoords& );
- void DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr );
+ void DrawHighlight(wxDC& dc);
+
+ // this function is called when the current cell highlight must be redrawn
+ // and may be overridden by the user
+ virtual void DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr );
void DrawRowLabels( wxDC& dc );
void DrawRowLabel( wxDC& dc, int row );
void ShowCellEditControl();
void HideCellEditControl();
- void SetEditControlValue( const wxString& s = wxEmptyString );
void SaveEditControlValue();
void SetColLabelValue( int col, const wxString& );
void SetGridLineColour( const wxColour& );
+ void EnableDragRowSize( bool enable = TRUE );
+ void DisableDragRowSize() { EnableDragRowSize( FALSE ); }
+ bool CanDragRowSize() { return m_canDragRowSize; }
+ void EnableDragColSize( bool enable = TRUE );
+ void DisableDragColSize() { EnableDragColSize( FALSE ); }
+ bool CanDragColSize() { return m_canDragColSize; }
+ void EnableDragGridSize(bool enable = TRUE);
+ void DisableDragGridSize() { EnableDragGridSize(FALSE); }
+ bool CanDragGridSize() { return m_canDragGridSize; }
+
+
// this sets the specified attribute for all cells in this row/col
void SetRowAttr(int row, wxGridCellAttr *attr);
void SetColAttr(int col, wxGridCellAttr *attr);
void SetDefaultColSize( int width, bool resizeExistingCols = FALSE );
void SetColSize( int col, int width );
+
+ // automatically size the column to fit to its contents, if setAsMin is
+ // TRUE, this optimal width will also be set as minimal width for this
+ // column
+ void AutoSizeColumn( int col, bool setAsMin = TRUE );
+
+ // auto size all columns (very ineffective for big grids!)
+ void AutoSizeColumns( bool setAsMin = TRUE );
+
+ void AutoSizeRows( bool setAsMin = TRUE );
+
+ // auto size the grid, that is make the columns/rows of the "right" size
+ // and also set the grid size to just fit its contents
+ void AutoSize();
+
+ // column won't be resized to be lesser width - this must be called during
+ // the grid creation because it won't resize the column if it's already
+ // narrower than the minimal width
+ void SetColMinimalWidth( int col, int width );
+
void SetDefaultCellBackgroundColour( const wxColour& );
void SetCellBackgroundColour( int row, int col, const wxColour& );
void SetDefaultCellTextColour( const wxColour& );
wxGridCellEditor* GetCellEditor(int row, int col);
+
// ------ cell value accessors
//
wxString GetCellValue( int row, int col )
void SetSelectionForeground(const wxColour& c) { m_selectionForeground = c; }
+ // Methods for a registry for mapping data types to Renderers/Editors
+ void RegisterDataType(const wxString& typeName,
+ wxGridCellRenderer* renderer,
+ wxGridCellEditor* editor);
+ wxGridCellEditor* GetDefaultEditorForCell(int row, int col) const;
+ wxGridCellEditor* GetDefaultEditorForCell(const wxGridCellCoords& c) const
+ { return GetDefaultEditorForCell(c.GetRow(), c.GetCol()); }
+ wxGridCellRenderer* GetDefaultRendererForCell(int row, int col) const;
+ wxGridCellEditor* GetDefaultEditorForType(const wxString& typeName) const;
+ wxGridCellRenderer* GetDefaultRendererForType(const wxString& typeName) const;
+
+
// ------ For compatibility with previous wxGrid only...
//
//
wxGrid( wxWindow *parent,
- int x = -1, int y = -1, int w = -1, int h = -1,
+ int x, int y, int w = -1, int h = -1,
long style = 0,
const wxString& name = wxPanelNameStr )
: wxScrolledWindow( parent, -1, wxPoint(x,y), wxSize(w,h), style, name )
void SetRowHeight( int row, int height )
{ SetRowSize( row, height ); }
- int GetRowHeight( int row )
- { return GetRowSize( row ); }
+ // GetRowHeight() is below
int GetViewHeight() // returned num whole rows visible
{ return 0; }
wxGRID_CHOICE,
wxGRID_COMBOBOX };
- // for wxGridCellBoolEditor
- wxWindow *GetGridWindow() const;
-
protected:
bool m_created;
bool m_displayed;
wxColour m_selectionBackground;
wxColour m_selectionForeground;
+ // NB: *never* access m_row/col arrays directly because they are created
+ // on demand, *always* use accessor functions instead!
+
+ // init the m_rowHeights/Bottoms arrays with default values
+ void InitRowHeights();
+
int m_defaultRowHeight;
wxArrayInt m_rowHeights;
wxArrayInt m_rowBottoms;
+ // init the m_colWidths/Rights arrays
+ void InitColWidths();
+
int m_defaultColWidth;
wxArrayInt m_colWidths;
wxArrayInt m_colRights;
+
+ // get the col/row coords
+ int GetColWidth(int col) const;
+ int GetColLeft(int col) const;
+ int GetColRight(int col) const;
+
+ // this function must be public for compatibility...
+public:
+ int GetRowHeight(int row) const;
+protected:
+
+ int GetRowTop(int row) const;
+ int GetRowBottom(int row) const;
+
int m_rowLabelWidth;
int m_colLabelHeight;
wxColour m_gridLineColour;
bool m_gridLinesEnabled;
+ // if a column has a minimal width, it will be the value for it in this
+ // hash table
+ wxHashTable m_colMinWidths;
+
+ // get the minimal width of the given column
+ int GetColMinimalWidth(int col) const;
// do we have some place to store attributes in?
bool CanHaveAttributes();
bool m_inOnKeyDown;
int m_batchCount;
+
+ wxGridTypeRegistry* m_typeRegistry;
+
enum CursorMode
{
WXGRID_CURSOR_SELECT_CELL,
wxWindow *m_winCapture; // the window which captured the mouse
CursorMode m_cursorMode;
+ bool m_canDragRowSize;
+ bool m_canDragColSize;
+ bool m_canDragGridSize;
int m_dragLastPos;
int m_dragRowOrCol;
bool m_isDragging;
DECLARE_EVENT_TABLE()
};
-
-
-
-
-//
-// ------ Grid event class and event types
-//
+// ----------------------------------------------------------------------------
+// Grid event class and event types
+// ----------------------------------------------------------------------------
class WXDLLEXPORT wxGridEvent : public wxNotifyEvent
{