X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/7807d81c7303d1f019719714c40cbe1d1741bbf6..530a7383f26e57b61748d76502229283462a0ede:/include/wx/generic/grid.h?ds=sidebyside diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index d2342fcd9f..a572f9d4a0 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -31,7 +31,7 @@ #include "wx/textctrl.h" #include "wx/combobox.h" #include "wx/dynarray.h" - +#include "wx/timer.h" // Default parameters for wxGrid // @@ -50,9 +50,273 @@ #define WXGRID_MIN_COL_WIDTH 15 #define WXGRID_DEFAULT_SCROLLBAR_WIDTH 16 +// ---------------------------------------------------------------------------- +// forward declarations +// ---------------------------------------------------------------------------- class WXDLLEXPORT wxGrid; +class WXDLLEXPORT wxGridCellAttr; +class WXDLLEXPORT wxGridCellAttrProviderData; +class WXDLLEXPORT wxGridColLabelWindow; +class WXDLLEXPORT wxGridCornerLabelWindow; +class WXDLLEXPORT wxGridRowLabelWindow; +class WXDLLEXPORT wxGridTableBase; +class WXDLLEXPORT wxGridWindow; + +// ---------------------------------------------------------------------------- +// wxGridCellRenderer: this class is responsible for actually drawing the cell +// in the grid. You may pass it to the wxGridCellAttr (below) to change the +// format of one given cell or to wxGrid::SetDefaultRenderer() to change the +// view of all cells. This is an ABC, you will normally use one of the +// predefined derived classes or derive oyur own class from it. +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxGridCellRenderer +{ +public: + // draw the given cell on the provided DC inside the given rectangle + // using the style specified by the attribute and the default or selected + // state corresponding to the isSelected value. + // + // this pure virtual function has a default implementation which will + // prepare the DC using the given attribute: it will draw the rectangle + // with the bg colour from attr and set the text colour and font + virtual void Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int row, int col, + bool isSelected) = 0; +}; + +// the default renderer for the cells containing string data +class WXDLLEXPORT wxGridCellStringRenderer : public wxGridCellRenderer +{ +public: + // draw the string + virtual void Draw(wxGrid& grid, + wxGridCellAttr& attr, + wxDC& dc, + const wxRect& rect, + int row, int col, + bool isSelected); +}; + + +// ---------------------------------------------------------------------------- +// wxGridCellEditor: This class is responsible for providing and manipulating +// the in-place edit controls for the grid. Instances of wxGridCellEditor +// (actually, instances of derived classes since it is an ABC) can be +// associated with the cell attributes for individual cells, rows, columns, or +// even for the entire grid. +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxGridCellEditor +{ +public: + wxGridCellEditor(); + virtual ~wxGridCellEditor(); + + bool IsCreated() { return m_control != NULL; } + + // Creates the actual edit control + virtual void Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler) = 0; + + // Size and position the edit control + virtual void SetSize(const wxRect& rect); + + // Show or hide the edit control + virtual void Show(bool show); + + // 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, + wxGridCellAttr* attr) = 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, wxGridCellAttr* attr) = 0; + + // Reset the value in the control back to its starting value + virtual void Reset() = 0; + // If the editor is enabled by pressing keys on the grid, + // this will be called to let the editor do something about + // that first key if desired. + virtual void StartingKey(wxKeyEvent& event); + + // Some types of controls on some platforms may need some help + // with the Return key. + virtual void HandleReturn(wxKeyEvent& event); + + // Final cleanup + virtual void Destroy(); + +protected: + wxControl* m_control; +}; + + +class WXDLLEXPORT wxGridCellTextEditor : public wxGridCellEditor +{ +public: + wxGridCellTextEditor(); + + virtual void Create(wxWindow* parent, + wxWindowID id, + wxEvtHandler* evtHandler); + + virtual void BeginEdit(int row, int col, wxGrid* grid, + wxGridCellAttr* attr); + + virtual bool EndEdit(int row, int col, bool saveValue, + wxGrid* grid, wxGridCellAttr* attr); + + virtual void Reset(); + virtual void StartingKey(wxKeyEvent& event); + virtual void HandleReturn(wxKeyEvent& event); + + +private: + wxString m_startValue; +}; + +// ---------------------------------------------------------------------------- +// 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 +// class may be returned by wxGridTable::GetAttr(). +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxGridCellAttr +{ +public: + // ctors + wxGridCellAttr() + { + Init(); + SetAlignment(0, 0); + } + + wxGridCellAttr(const wxColour& colText, + const wxColour& colBack, + const wxFont& font, + int hAlign, + int vAlign) + : m_colText(colText), m_colBack(colBack), m_font(font) + { + Init(); + SetAlignment(hAlign, vAlign); + } + + // default copy ctor ok + + // this class is ref counted: it is created with ref count of 1, so + // calling DecRef() once will delete it. Calling IncRef() allows to lock + // it until the matching DecRef() is called + void IncRef() { m_nRef++; } + void DecRef() { if ( !--m_nRef ) delete this; } + void SafeIncRef() { if ( this ) IncRef(); } + void SafeDecRef() { if ( this ) DecRef(); } + + // setters + void SetTextColour(const wxColour& colText) { m_colText = colText; } + void SetBackgroundColour(const wxColour& colBack) { m_colBack = colBack; } + void SetFont(const wxFont& font) { m_font = font; } + void SetAlignment(int hAlign, int vAlign) + { + m_hAlign = hAlign; + m_vAlign = vAlign; + } + + // takes ownership of the pointer + void SetRenderer(wxGridCellRenderer *renderer) + { delete m_renderer; m_renderer = renderer; } + void SetEditor(wxGridCellEditor* editor) + { delete m_editor; m_editor = editor; } + + // accessors + bool HasTextColour() const { return m_colText.Ok(); } + bool HasBackgroundColour() const { return m_colBack.Ok(); } + bool HasFont() const { return m_font.Ok(); } + bool HasAlignment() const { return m_hAlign || m_vAlign; } + bool HasRenderer() const { return m_renderer != NULL; } + bool HasEditor() const { return m_editor != NULL; } + + const wxColour& GetTextColour() const; + const wxColour& GetBackgroundColour() const; + const wxFont& GetFont() const; + void GetAlignment(int *hAlign, int *vAlign) const; + wxGridCellRenderer *GetRenderer() const; + wxGridCellEditor *GetEditor() const; + + void SetDefAttr(wxGridCellAttr* defAttr) { m_defGridAttr = defAttr; } + +private: + // the common part of all ctors + void Init() { + m_nRef = 1; + m_renderer = NULL; + m_editor = NULL; + } + + // the dtor is private because only DecRef() can delete us + ~wxGridCellAttr() { delete m_renderer; delete m_editor; } + + // the ref count - when it goes to 0, we die + size_t m_nRef; + + wxColour m_colText, + m_colBack; + wxFont m_font; + int m_hAlign, + m_vAlign; + + wxGridCellRenderer* m_renderer; + wxGridCellEditor* m_editor; + wxGridCellAttr* m_defGridAttr; + + // suppress the stupid gcc warning about the class having private dtor and + // no friends + friend class wxGridCellAttrDummyFriend; +}; + +// ---------------------------------------------------------------------------- +// wxGridCellAttrProvider: class used by wxGridTableBase to retrieve/store the +// cell attributes. +// ---------------------------------------------------------------------------- + +// implementation note: we separate it from wxGridTableBase because we wish to +// avoid deriving a new table class if possible, and sometimes it will be +// enough to just derive another wxGridCellAttrProvider instead +// +// the default implementation is reasonably efficient for the generic case, +// but you might still wish to implement your own for some specific situations +// if you have performance problems with the stock one +class WXDLLEXPORT wxGridCellAttrProvider +{ +public: + wxGridCellAttrProvider(); + virtual ~wxGridCellAttrProvider(); + + // DecRef() must be called on the returned pointer + virtual wxGridCellAttr *GetAttr(int row, int col) const; + + // all these functions take ownership of the pointer, don't call DecRef() + // on it + virtual void SetAttr(wxGridCellAttr *attr, int row, int col); + virtual void SetRowAttr(wxGridCellAttr *attr, int row); + virtual void SetColAttr(wxGridCellAttr *attr, int col); + +private: + void InitData(); + + wxGridCellAttrProviderData *m_data; +}; ////////////////////////////////////////////////////////////////////// // @@ -93,13 +357,35 @@ public: virtual void SetRowLabelValue( int WXUNUSED(row), const wxString& ) {} virtual void SetColLabelValue( int WXUNUSED(col), const wxString& ) {} + // Attribute handling + // + + // give us the attr provider to use - we take ownership of the pointer + void SetAttrProvider(wxGridCellAttrProvider *attrProvider); + + // get the currently used attr provider (may be NULL) + wxGridCellAttrProvider *GetAttrProvider() const { return m_attrProvider; } + + // by default forwarded to wxGridCellAttrProvider if any. May be + // overridden to handle attributes directly in this class. + virtual wxGridCellAttr *GetAttr( int row, int col ); + + // these functions take ownership of the pointer + virtual void SetAttr(wxGridCellAttr* attr, int row, int col); + virtual void SetRowAttr(wxGridCellAttr *attr, int row); + virtual void SetColAttr(wxGridCellAttr *attr, int col); + private: wxGrid * m_view; + wxGridCellAttrProvider *m_attrProvider; DECLARE_ABSTRACT_CLASS( wxGridTableBase ); }; +// ---------------------------------------------------------------------------- +// wxGridTableMessage +// ---------------------------------------------------------------------------- // IDs for messages sent from grid table to view // @@ -261,144 +547,16 @@ WX_DECLARE_EXPORTED_OBJARRAY(wxGridCellCoords, wxGridCellCoordsArray); -// This set of classes is to provide for the use of different types of -// cell edit controls in the grid while avoiding the wx class info -// system in deference to wxPython - -class WXDLLEXPORT wxGridTextCtrl : public wxTextCtrl -{ -public: - wxGridTextCtrl() {} - wxGridTextCtrl( wxWindow *, - wxGrid *, - bool isCellControl, - wxWindowID id, - const wxString& value = wxEmptyString, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0 ); - - void SetStartValue( const wxString& ); - wxString GetStartValue() { return startValue; } - -private: - wxGrid *m_grid; - - // TRUE for controls placed over cells, - // FALSE for a control on a grid control panel - bool m_isCellControl; - - wxString startValue; - - void OnKeyDown( wxKeyEvent& ); - - DECLARE_DYNAMIC_CLASS( wxGridTextCtrl ) - DECLARE_EVENT_TABLE() -}; - - -class WXDLLEXPORT wxGridRowLabelWindow : public wxWindow -{ -public: - wxGridRowLabelWindow() { m_owner = (wxGrid *)NULL; } - wxGridRowLabelWindow( wxGrid *parent, wxWindowID id, - const wxPoint &pos, const wxSize &size ); - -private: - wxGrid *m_owner; - - void OnPaint( wxPaintEvent& event ); - void OnMouseEvent( wxMouseEvent& event ); - void OnKeyDown( wxKeyEvent& event ); - - DECLARE_DYNAMIC_CLASS(wxGridRowLabelWindow) - DECLARE_EVENT_TABLE() -}; - - -class WXDLLEXPORT wxGridColLabelWindow : public wxWindow -{ -public: - wxGridColLabelWindow() { m_owner = (wxGrid *)NULL; } - wxGridColLabelWindow( wxGrid *parent, wxWindowID id, - const wxPoint &pos, const wxSize &size ); - -private: - wxGrid *m_owner; - - void OnPaint( wxPaintEvent &event ); - void OnMouseEvent( wxMouseEvent& event ); - void OnKeyDown( wxKeyEvent& event ); - - DECLARE_DYNAMIC_CLASS(wxGridColLabelWindow) - DECLARE_EVENT_TABLE() -}; - - -class WXDLLEXPORT wxGridCornerLabelWindow : public wxWindow -{ -public: - wxGridCornerLabelWindow() { m_owner = (wxGrid *)NULL; } - wxGridCornerLabelWindow( wxGrid *parent, wxWindowID id, - const wxPoint &pos, const wxSize &size ); - -private: - wxGrid *m_owner; - - void OnMouseEvent( wxMouseEvent& event ); - void OnKeyDown( wxKeyEvent& event ); - void OnPaint( wxPaintEvent& event ); - - DECLARE_DYNAMIC_CLASS(wxGridCornerLabelWindow) - DECLARE_EVENT_TABLE() -}; - - - -class WXDLLEXPORT wxGridWindow : public wxPanel -{ -public: - wxGridWindow() - { - m_owner = (wxGrid *)NULL; - m_rowLabelWin = (wxGridRowLabelWindow *)NULL; - m_colLabelWin = (wxGridColLabelWindow *)NULL; - } - - wxGridWindow( wxGrid *parent, - wxGridRowLabelWindow *rowLblWin, - wxGridColLabelWindow *colLblWin, - wxWindowID id, const wxPoint &pos, const wxSize &size ); - ~wxGridWindow(); - - void ScrollWindow( int dx, int dy, const wxRect *rect ); - -private: - wxGrid *m_owner; - wxGridRowLabelWindow *m_rowLabelWin; - wxGridColLabelWindow *m_colLabelWin; - - void OnPaint( wxPaintEvent &event ); - void OnMouseEvent( wxMouseEvent& event ); - void OnKeyDown( wxKeyEvent& ); - - DECLARE_DYNAMIC_CLASS(wxGridWindow) - DECLARE_EVENT_TABLE() -}; - - +// ---------------------------------------------------------------------------- +// wxGrid +// ---------------------------------------------------------------------------- class WXDLLEXPORT wxGrid : public wxScrolledWindow { public: wxGrid() - { - m_table = (wxGridTableBase *) NULL; - m_gridWin = (wxGridWindow *) NULL; - m_rowLabelWin = (wxGridRowLabelWindow *) NULL; - m_colLabelWin = (wxGridColLabelWindow *) NULL; - m_cornerLabelWin = (wxGridCornerLabelWindow *) NULL; - m_cellEditCtrl = (wxWindow *) NULL; + { + Create(); } wxGrid( wxWindow *parent, @@ -435,9 +593,11 @@ public: void ProcessGridCellMouseEvent( wxMouseEvent& event ); bool ProcessTableMessage( wxGridTableMessage& ); + void DoEndDragResizeRow(); + void DoEndDragResizeCol(); wxGridTableBase * GetTable() const { return m_table; } - void SetTable( wxGridTableBase *table ) { m_table = table; } + bool SetTable( wxGridTableBase *table, bool takeOwnership=FALSE ); void ClearGrid(); bool InsertRows( int pos = 0, int numRows = 1, bool updateLabels=TRUE ); @@ -451,8 +611,7 @@ public: void DrawCellBorder( wxDC& dc, const wxGridCellCoords& ); void DrawAllGridLines( wxDC& dc, const wxRegion & reg ); void DrawCell( wxDC& dc, const wxGridCellCoords& ); - void DrawCellBackground( wxDC& dc, const wxGridCellCoords& ); - void DrawCellValue( wxDC& dc, const wxGridCellCoords& ); + void DrawCellHighlight( wxDC& dc ); void DrawRowLabels( wxDC& dc ); void DrawRowLabel( wxDC& dc, int row ); @@ -492,12 +651,10 @@ public: bool IsEditable() { return m_editable; } void EnableEditing( bool edit ); -#if 0 // at the moment the cell edit control is always active void EnableCellEditControl( bool enable ); -#endif bool IsCellEditControlEnabled() - { return (m_cellEditCtrl && m_cellEditCtrlEnabled); } + { return m_cellEditCtrlEnabled; } void ShowCellEditControl(); void HideCellEditControl(); @@ -567,7 +724,7 @@ public: wxString GetColLabelValue( int col ); wxColour GetGridLineColour() { return m_gridLineColour; } - void SetRowLabelSize( int width ); + void SetRowLabelSize( int width ); void SetColLabelSize( int height ); void SetLabelBackgroundColour( const wxColour& ); void SetLabelTextColour( const wxColour& ); @@ -578,10 +735,13 @@ public: void SetColLabelValue( int col, const wxString& ); void SetGridLineColour( const wxColour& ); + // 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 EnableGridLines( bool enable = TRUE ); bool GridLinesEnabled() { return m_gridLinesEnabled; } - // ------ row and col formatting // int GetDefaultRowSize(); @@ -612,6 +772,12 @@ public: void SetDefaultCellAlignment( int horiz, int vert ); void SetCellAlignment( int row, int col, int horiz, int vert ); + // takes ownership of the pointer + void SetDefaultRenderer(wxGridCellRenderer *renderer); + void SetCellRenderer(int row, int col, wxGridCellRenderer *renderer); + wxGridCellRenderer *GetDefaultRenderer() const; + wxGridCellRenderer* GetCellRenderer(int row, int col); + // ------ cell value accessors // @@ -684,16 +850,26 @@ public: // to the client size of the grid window. // wxRect BlockToDeviceRect( const wxGridCellCoords & topLeft, - const wxGridCellCoords & bottomRight ); + const wxGridCellCoords & bottomRight ); // This function returns the rectangle that encloses the selected cells // in device coords and clipped to the client size of the grid window. // wxRect SelectionToDeviceRect() { - return BlockToDeviceRect( m_selectedTopLeft, - m_selectedBottomRight ); - } + return BlockToDeviceRect( m_selectedTopLeft, + m_selectedBottomRight ); + } + + // Access or update the selection fore/back colours + wxColour GetSelectionBackground() const + { return m_selectionBackground; } + wxColour GetSelectionForeground() const + { return m_selectionForeground; } + + void SetSelectionBackground(const wxColour& c) { m_selectionBackground = c; } + void SetSelectionForeground(const wxColour& c) { m_selectionForeground = c; } + // ------ For compatibility with previous wxGrid only... @@ -805,10 +981,10 @@ public: } wxFont GetCellTextFont() const - { return m_defaultCellFont; } + { return m_defaultCellAttr->GetFont(); } wxFont GetCellTextFont(int WXUNUSED(row), int WXUNUSED(col)) const - { return m_defaultCellFont; } + { return m_defaultCellAttr->GetFont(); } void SetCellTextFont(const wxFont& fnt) { SetDefaultCellFont( fnt ); } @@ -867,6 +1043,7 @@ protected: wxGridCornerLabelWindow *m_cornerLabelWin; wxGridTableBase *m_table; + bool m_ownTable; int m_left; int m_top; @@ -880,6 +1057,8 @@ protected: wxGridCellCoords m_selectedTopLeft; wxGridCellCoords m_selectedBottomRight; + wxColour m_selectionBackground; + wxColour m_selectionForeground; int m_defaultRowHeight; wxArrayInt m_rowHeights; @@ -888,7 +1067,6 @@ protected: int m_defaultColWidth; wxArrayInt m_colWidths; wxArrayInt m_colRights; - int m_rowLabelWidth; int m_colLabelHeight; @@ -907,7 +1085,42 @@ protected: wxColour m_gridLineColour; bool m_gridLinesEnabled; - wxFont m_defaultCellFont; + + // do we have some place to store attributes in? + bool CanHaveAttributes(); + + // returns the attribute we may modify in place: a new one if this cell + // doesn't have any yet or the existing one if it does + // + // DecRef() must be called on the returned pointer, as usual + wxGridCellAttr *GetOrCreateCellAttr(int row, int col) const; + + // cell attribute cache (currently we only cache 1, may be will do + // more/better later) + struct CachedAttr + { + int row, col; + wxGridCellAttr *attr; + } m_attrCache; + + // invalidates the attribute cache + void ClearAttrCache(); + + // adds an attribute to cache + void CacheAttr(int row, int col, wxGridCellAttr *attr) const; + + // looks for an attr in cache, returns TRUE if found + bool LookupAttr(int row, int col, wxGridCellAttr **attr) const; + + // looks for the attr in cache, if not found asks the table and caches the + // result + wxGridCellAttr *GetCellAttr(int row, int col) const; + wxGridCellAttr *GetCellAttr(const wxGridCellCoords& coords ) + { return GetCellAttr( coords.GetRow(), coords.GetCol() ); } + + // the default cell attr object for cells that don't have their own + wxGridCellAttr* m_defaultCellAttr; + wxGridCellCoordsArray m_cellsExposed; wxArrayInt m_rowsExposed; @@ -918,17 +1131,34 @@ protected: bool m_inOnKeyDown; int m_batchCount; - int m_cursorMode; - enum { WXGRID_CURSOR_SELECT_CELL, - WXGRID_CURSOR_RESIZE_ROW, - WXGRID_CURSOR_RESIZE_COL, - WXGRID_CURSOR_SELECT_ROW, - WXGRID_CURSOR_SELECT_COL + enum CursorMode + { + WXGRID_CURSOR_SELECT_CELL, + WXGRID_CURSOR_RESIZE_ROW, + WXGRID_CURSOR_RESIZE_COL, + WXGRID_CURSOR_SELECT_ROW, + WXGRID_CURSOR_SELECT_COL }; - int m_dragLastPos; - int m_dragRowOrCol; - bool m_isDragging; + // this method not only sets m_cursorMode but also sets the correct cursor + // for the given mode and, if captureMouse is not FALSE releases the mouse + // if it was captured and captures it if it must be captured + // + // for this to work, you should always use it and not set m_cursorMode + // directly! + void ChangeCursorMode(CursorMode mode, + wxWindow *win = (wxWindow *)NULL, + bool captureMouse = TRUE); + + wxWindow *m_winCapture; // the window which captured the mouse + CursorMode m_cursorMode; + + int m_dragLastPos; + int m_dragRowOrCol; + bool m_isDragging; + wxPoint m_startDragPos; + + bool m_waitForSlowClick; wxGridCellCoords m_selectionStart; @@ -936,8 +1166,6 @@ protected: wxCursor m_colResizeCursor; bool m_editable; // applies to whole grid - int m_editCtrlType; // for current cell - wxWindow* m_cellEditCtrl; bool m_cellEditCtrlEnabled; @@ -959,6 +1187,7 @@ protected: void OnPaint( wxPaintEvent& ); void OnSize( wxSizeEvent& ); void OnKeyDown( wxKeyEvent& ); + void OnEraseBackground( wxEraseEvent& ); void SetCurrentCell( const wxGridCellCoords& coords );