From c0b042fce9be0fab67f229f35ffd117f4e1e0730 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Wed, 23 Jun 1999 11:26:19 +0000 Subject: [PATCH] in-place editing code from Michael Bedward integrated (with my docs) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2874 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/grid.tex | 18 +- include/wx/generic/gridg.h | 594 +++++++++++++++++++------------------ samples/grid/test.cpp | 11 + src/generic/gridg.cpp | 227 +++++++++++--- 4 files changed, 514 insertions(+), 336 deletions(-) diff --git a/docs/latex/wx/grid.tex b/docs/latex/wx/grid.tex index fb5d809879..95af331651 100644 --- a/docs/latex/wx/grid.tex +++ b/docs/latex/wx/grid.tex @@ -15,7 +15,9 @@ wxGrid is a class for displaying and editing tabular information. \wxheading{Window styles} -There are no specific window styles for this class. +There are no specific window styles for this class, but you may use different +SetXXX() functions to change the controls behaviour (for example, to enable +in-place editing). See also \helpref{window styles overview}{windowstyles}. @@ -257,6 +259,12 @@ Returns the row position of the currently selected cell. Returns TRUE if the grid cells can be edited. +\membersection{wxGrid::GetEditInPlace}\label{wxgridgeteditinplace} + +\constfunc{bool}{GetEditInPlace}{\void} + +Returns TRUE if editing in-place is enabled. + \membersection{wxGrid::GetHorizScrollBar}\label{wxgridgethorizscrollbar} \constfunc{wxScrollBar *}{GetHorizScrollBar}{\void} @@ -528,6 +536,14 @@ If {\it editable} is TRUE (the default), the grid cells will be editable by mean text edit control. If FALSE, the text edit control will be hidden and the user will not be able to edit the cell contents. +\membersection{wxGrid::SetEditInPlace}\label{wxgridseteditinplace} + +\func{void}{SetEditInPlace}{\param{bool}{ edit = TRUE}} + +Enables (if {\it edit} is TRUE, default value) or disables in-place editing. +When it is enabled, the cells contents can be changed by typing text directly +in the cell. + \membersection{wxGrid::SetGridCursor}\label{wxgridsetgridcursor} \func{void}{SetGridCursor}{\param{int }{row}, \param{int}{ col}} diff --git a/include/wx/generic/gridg.h b/include/wx/generic/gridg.h index b7bd11f4be..213a5fadba 100644 --- a/include/wx/generic/gridg.h +++ b/include/wx/generic/gridg.h @@ -2,11 +2,12 @@ // Name: gridg.h // Purpose: wxGenericGrid // Author: Julian Smart -// Modified by: +// Modified by: Michael Bedward 20 April 1999 +// Added edit in place facility // Created: 01/02/97 // RCS-ID: $Id$ // Copyright: (c) -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef __GRIDH_G__ @@ -34,322 +35,339 @@ #define wxGRID_DEFAULT_HORIZONAL_LABEL_HEIGHT 20 #ifndef wxLEFT -#define wxLEFT 0x0400 + #define wxLEFT 0x0400 #endif #ifndef wxRIGHT -#define wxRIGHT 0x0800 + #define wxRIGHT 0x0800 #endif #define WXGENERIC_GRID_VERSION 0.5 class WXDLLEXPORT wxGridEvent; class WXDLLEXPORT wxGridCell; -class WXDLLEXPORT wxGenericGrid: public wxPanel + +class WXDLLEXPORT wxGenericGrid : public wxPanel { - DECLARE_DYNAMIC_CLASS(wxGenericGrid) - public: - wxGenericGrid(void); - - inline wxGenericGrid(wxWindow *parent, int x, int y, int width, int height, long style = 0, char *name = "grid") - { - Create(parent, -1, wxPoint(x, y), wxSize(width, height), style, name); - } - inline wxGenericGrid(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style = 0, const wxString& name = "grid") - { - Create(parent, id, pos, size, style, name); - } - ~wxGenericGrid(void); - - void OnPaint(wxPaintEvent& event); - void OnEraseBackground(wxEraseEvent& event); - void OnMouseEvent(wxMouseEvent& event); - void OnSize(wxSizeEvent& event); - - bool Create(wxWindow *parent, wxWindowID, const wxPoint& pos, const wxSize& size, long style = 0, const wxString& name = "grid"); - - bool CreateGrid(int nRows, int nCols, wxString **cellValues = (wxString **) NULL, short *widths = (short *) NULL, - short defaultWidth = wxGRID_DEFAULT_CELL_WIDTH, short defaultHeight = wxGRID_DEFAULT_CELL_HEIGHT); - void PaintGrid(wxDC& dc); - void ClearGrid(void); - virtual wxGridCell *GetCell(int row, int col) const; - inline wxGridCell ***GetCells(void) const { return m_gridCells; } - bool InsertCols(int pos = 0, int n = 1, bool updateLabels = TRUE); - bool InsertRows(int pos = 0, int n = 1, bool updateLabels = TRUE); - bool AppendCols(int n = 1, bool updateLabels = TRUE); - bool AppendRows(int n = 1, bool updateLabels = TRUE); - bool DeleteCols(int pos = 0, int n = 1, bool updateLabels = TRUE); - bool DeleteRows(int pos = 0, int n = 1, bool updateLabels = TRUE); - - // Cell accessors - void SetCellValue(const wxString& val, int row, int col); - wxString& GetCellValue(int row, int col) const; - void SetCellAlignment(int flag, int row, int col); - void SetCellAlignment(int flag); - int GetCellAlignment(int row, int col) const; - int GetCellAlignment(void) const; - void SetCellTextColour(const wxColour& val, int row, int col); - void SetCellTextColour(const wxColour& col); - wxColour& GetCellTextColour(int row, int col) const; - inline wxColour& GetCellTextColour(void) const { return (wxColour&) m_cellTextColour; } - void SetCellBackgroundColour(const wxColour& col); - void SetCellBackgroundColour(const wxColour& colour, int row, int col); - inline wxColour& GetCellBackgroundColour(void) const { return (wxColour&) m_cellBackgroundColour; } - wxColour& GetCellBackgroundColour(int row, int col) const; - inline wxFont& GetCellTextFont(void) const { return (wxFont&) m_cellTextFont; } - wxFont& GetCellTextFont(int row, int col) const; - void SetCellTextFont(const wxFont& fnt); - void SetCellTextFont(const wxFont& fnt, int row, int col); - wxBitmap *GetCellBitmap(int row, int col) const; - void SetCellBitmap(wxBitmap *bitmap, int row, int col); - - // Size accessors - void SetColumnWidth(int col, int width); - int GetColumnWidth(int col) const; - void SetRowHeight(int row, int height); - int GetRowHeight(int row) const; - - // Label accessors - void SetLabelSize(int orientation, int sz); - int GetLabelSize(int orientation) const; - void SetLabelAlignment(int orientation, int alignment); - int GetLabelAlignment(int orientation) const; - wxGridCell *GetLabelCell(int orientation, int pos) const; - void SetLabelValue(int orientation, const wxString& val, int pos); - wxString& GetLabelValue(int orientation, int pos) const; - void SetLabelTextColour(const wxColour& colour); - void SetLabelBackgroundColour(const wxColour& colour); - inline wxColour& GetLabelTextColour(void) const { return (wxColour&) m_labelTextColour; } - inline wxColour& GetLabelBackgroundColour(void) { return (wxColour&) m_labelBackgroundColour; } - inline wxFont& GetLabelTextFont(void) { return (wxFont&) m_labelTextFont; } - inline void SetLabelTextFont(const wxFont& fnt) { m_labelTextFont = fnt; } - - // Miscellaneous accessors - inline int GetCursorRow(void) const { return m_wCursorRow; } - inline int GetCursorColumn(void) const { return m_wCursorColumn; } - void SetGridCursor(int row, int col); - inline int GetRows(void) const { return m_totalRows; } - inline int GetCols(void) const { return m_totalCols; } - inline int GetScrollPosX(void) const { return m_scrollPosX; } - inline int GetScrollPosY(void) const { return m_scrollPosY; } - inline void SetScrollPosX(int pos) { m_scrollPosX = pos; } - inline void SetScrollPosY(int pos) { m_scrollPosY = pos; } - inline wxTextCtrl *GetTextItem(void) const { return m_textItem; } - inline wxScrollBar *GetHorizScrollBar(void) const { return m_hScrollBar; } - inline wxScrollBar *GetVertScrollBar(void) const { return m_vScrollBar; } - inline bool GetEditable(void) const { return m_editable; } - void SetEditable(bool edit); - inline wxRect& GetCurrentRect(void) const { return (wxRect&) m_currentRect; } - inline bool CurrentCellVisible(void) const { return m_currentRectVisible; } - inline void SetDividerPen(const wxPen& pen) { m_divisionPen = pen; } - inline wxPen& GetDividerPen(void) const { return (wxPen&) m_divisionPen; } - - // High-level event handling - // Override e.g. to check value of current cell; but call - // base member for default processing. - virtual void OnSelectCellImplementation(wxDC *dc, int row, int col); - - virtual void OnSelectCell(int WXUNUSED(row), int WXUNUSED(col)) {}; - void _OnSelectCell(wxGridEvent& event); - - // Override to create your own class of grid cell - virtual wxGridCell *OnCreateCell(void); - void _OnCreateCell(wxGridEvent& event); - - // Override to change labels e.g. creation of grid, inserting/deleting a row/col. - // By default, auto-labels the grid. - virtual void OnChangeLabels(void); - void _OnChangeLabels(wxGridEvent& event); - - // Override to change the label of the edit field when selecting a cell - // By default, sets it to e.g. A12 - virtual void OnChangeSelectionLabel(void); - void _OnChangeSelectionLabel(wxGridEvent& event); - - // Override for event processing - virtual void OnCellChange(int WXUNUSED(row), int WXUNUSED(col)) {}; - virtual void OnCellLeftClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {}; - virtual void OnCellRightClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {}; - virtual void OnLabelLeftClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {}; - virtual void OnLabelRightClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {}; - - void _OnCellChange(wxGridEvent& event); - void _OnCellLeftClick(wxGridEvent& event); - void _OnCellRightClick(wxGridEvent& event); - void _OnLabelLeftClick(wxGridEvent& event); - void _OnLabelRightClick(wxGridEvent& event); - - // Activation: call from wxFrame::OnActivate - void OnActivate(bool active); - - // Miscellaneous - void AdjustScrollbars(void); - void UpdateDimensions(void); - - /* INTERNAL - */ - void SetCurrentRect (int Row, int Column, int canvasW = -1, int canvasH = -1); - void HighlightCell (wxDC *dc); - void DrawCellText(void); - void SetGridClippingRegion(wxDC *dc); - virtual bool CellHitTest(int x, int y, int *row, int *col); - virtual bool LabelSashHitTest(int x, int y, int *orientation, int *rowOrCol, int *startPos); - virtual bool LabelHitTest(int x, int y, int *row, int *col); - // Painting - virtual void DrawLabelAreas(wxDC *dc); - virtual void DrawEditableArea(wxDC *dc); - virtual void DrawGridLines(wxDC *dc); - virtual void DrawColumnLabels(wxDC *dc); - virtual void DrawColumnLabel(wxDC *dc, wxRect *rect, int col); - virtual void DrawRowLabels(wxDC *dc); - virtual void DrawRowLabel(wxDC *dc, wxRect *rect, int row); - virtual void DrawCells(wxDC *dc); - virtual void DrawCellValue(wxDC *dc, wxRect *rect, int row, int col); - virtual void DrawCellBackground(wxDC *dc, wxRect *rect, int row, int col); - virtual void DrawTextRect(wxDC *dc, const wxString& text, wxRect *rect, int flag); - virtual void DrawBitmapRect(wxDC *dc, wxBitmap *bitmap, wxRect *rect, int flag); - - // Refresh cell and optionally set the text field - void RefreshCell(int row, int col, bool setText = FALSE); - - // Don't refresh within the outer pair of these. - inline void BeginBatch(void) { m_batchCount ++; } - inline void EndBatch(void) { m_batchCount --; } - inline int GetBatchCount(void) { return m_batchCount; } - - void OnText(wxCommandEvent& ev); - void OnGridScroll(wxScrollEvent& ev); - - protected: - wxPanel* m_editingPanel; // Contains the text control - wxTextCtrl* m_textItem; - wxScrollBar* m_hScrollBar; - wxScrollBar* m_vScrollBar; - int m_wCursorRow; - int m_wCursorColumn; - wxRect m_currentRect; - bool m_currentRectVisible; - wxGridCell*** m_gridCells; - wxGridCell** m_rowLabelCells; - wxGridCell** m_colLabelCells; - bool m_editCreated; - bool m_editable; - - int m_totalRows; - int m_totalCols; - - // Row and column we're currently looking at - int m_scrollPosX; - int m_scrollPosY; - - // Dimensions - int m_leftOfSheet; - int m_topOfSheet; - int m_rightOfSheet; // Calculated from m_colWidths - int m_bottomOfSheet; // Calculated from m_rowHeights - int m_totalGridWidth; // Total 'virtual' size - int m_totalGridHeight; - int m_cellHeight; // For now, a default - int m_verticalLabelWidth; - int m_horizontalLabelHeight; - int m_verticalLabelAlignment; - int m_horizontalLabelAlignment; - int m_cellAlignment; - short* m_colWidths; // Dynamically allocated - short* m_rowHeights; // Dynamically allocated - int m_scrollWidth; // Vert. scroll width, horiz. scroll height - - // Colours - wxColour m_cellTextColour; - wxColour m_cellBackgroundColour; - wxFont m_cellTextFont; - wxColour m_labelTextColour; - wxColour m_labelBackgroundColour; - wxBrush m_labelBackgroundBrush; - wxFont m_labelTextFont; - wxPen m_divisionPen; - wxBitmap* m_doubleBufferingBitmap; - - // Position of Edit control - wxRect m_editControlPosition; - - // Drag status - int m_dragStatus; - int m_dragRowOrCol; - int m_dragStartPosition; - int m_dragLastPosition; - wxCursor m_horizontalSashCursor; - wxCursor m_verticalSashCursor; - - // To avoid multiple refreshes, use Begin/EndBatch - int m_batchCount; - -DECLARE_EVENT_TABLE() + DECLARE_DYNAMIC_CLASS(wxGenericGrid) + +public: + wxGenericGrid(); + + wxGenericGrid(wxWindow *parent, int x, int y, int width, int height, long style = 0, char *name = "grid") + { + Create(parent, -1, wxPoint(x, y), wxSize(width, height), style, name); + } + wxGenericGrid(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style = 0, const wxString& name = "grid") + { + Create(parent, id, pos, size, style, name); + } + ~wxGenericGrid(); + + bool Create(wxWindow *parent, wxWindowID, const wxPoint& pos, const wxSize& size, long style = 0, const wxString& name = "grid"); + + bool CreateGrid(int nRows, int nCols, wxString **cellValues = (wxString **) NULL, short *widths = (short *) NULL, + short defaultWidth = wxGRID_DEFAULT_CELL_WIDTH, short defaultHeight = wxGRID_DEFAULT_CELL_HEIGHT); + void PaintGrid(wxDC& dc); + void ClearGrid(); + virtual wxGridCell *GetCell(int row, int col) const; + wxGridCell ***GetCells() const { return m_gridCells; } + bool InsertCols(int pos = 0, int n = 1, bool updateLabels = TRUE); + bool InsertRows(int pos = 0, int n = 1, bool updateLabels = TRUE); + bool AppendCols(int n = 1, bool updateLabels = TRUE); + bool AppendRows(int n = 1, bool updateLabels = TRUE); + bool DeleteCols(int pos = 0, int n = 1, bool updateLabels = TRUE); + bool DeleteRows(int pos = 0, int n = 1, bool updateLabels = TRUE); + + // Cell accessors + void SetCellValue(const wxString& val, int row, int col); + wxString& GetCellValue(int row, int col) const; + void SetCellAlignment(int flag, int row, int col); + void SetCellAlignment(int flag); + int GetCellAlignment(int row, int col) const; + int GetCellAlignment() const; + void SetCellTextColour(const wxColour& val, int row, int col); + void SetCellTextColour(const wxColour& col); + wxColour& GetCellTextColour(int row, int col) const; + wxColour& GetCellTextColour() const { return (wxColour&) m_cellTextColour; } + void SetCellBackgroundColour(const wxColour& col); + void SetCellBackgroundColour(const wxColour& colour, int row, int col); + wxColour& GetCellBackgroundColour() const { return (wxColour&) m_cellBackgroundColour; } + wxColour& GetCellBackgroundColour(int row, int col) const; + wxFont& GetCellTextFont() const { return (wxFont&) m_cellTextFont; } + wxFont& GetCellTextFont(int row, int col) const; + void SetCellTextFont(const wxFont& fnt); + void SetCellTextFont(const wxFont& fnt, int row, int col); + wxBitmap *GetCellBitmap(int row, int col) const; + void SetCellBitmap(wxBitmap *bitmap, int row, int col); + + // Size accessors + void SetColumnWidth(int col, int width); + int GetColumnWidth(int col) const; + void SetRowHeight(int row, int height); + int GetRowHeight(int row) const; + + // Label accessors + void SetLabelSize(int orientation, int sz); + int GetLabelSize(int orientation) const; + void SetLabelAlignment(int orientation, int alignment); + int GetLabelAlignment(int orientation) const; + wxGridCell *GetLabelCell(int orientation, int pos) const; + void SetLabelValue(int orientation, const wxString& val, int pos); + wxString& GetLabelValue(int orientation, int pos) const; + void SetLabelTextColour(const wxColour& colour); + void SetLabelBackgroundColour(const wxColour& colour); + wxColour& GetLabelTextColour() const { return (wxColour&) m_labelTextColour; } + wxColour& GetLabelBackgroundColour() { return (wxColour&) m_labelBackgroundColour; } + wxFont& GetLabelTextFont() { return (wxFont&) m_labelTextFont; } + void SetLabelTextFont(const wxFont& fnt) { m_labelTextFont = fnt; } + + // Miscellaneous accessors + int GetCursorRow() const { return m_wCursorRow; } + int GetCursorColumn() const { return m_wCursorColumn; } + void SetGridCursor(int row, int col); + int GetRows() const { return m_totalRows; } + int GetCols() const { return m_totalCols; } + int GetScrollPosX() const { return m_scrollPosX; } + int GetScrollPosY() const { return m_scrollPosY; } + void SetScrollPosX(int pos) { m_scrollPosX = pos; } + void SetScrollPosY(int pos) { m_scrollPosY = pos; } + wxTextCtrl *GetTextItem() const { return m_textItem; } + wxScrollBar *GetHorizScrollBar() const { return m_hScrollBar; } + wxScrollBar *GetVertScrollBar() const { return m_vScrollBar; } + bool GetEditable() const { return m_editable; } + void SetEditable(bool edit); + + bool GetEditInPlace() const { return m_editInPlace; } + void SetEditInPlace(bool edit = TRUE); + + wxRect& GetCurrentRect() const { return (wxRect&) m_currentRect; } + bool CurrentCellVisible() const { return m_currentRectVisible; } + void SetDividerPen(const wxPen& pen) { m_divisionPen = pen; } + wxPen& GetDividerPen() const { return (wxPen&) m_divisionPen; } + + // High-level event handling + // Override e.g. to check value of current cell; but call + // base member for default processing. + virtual void OnSelectCellImplementation(wxDC *dc, int row, int col); + + virtual void OnSelectCell(int WXUNUSED(row), int WXUNUSED(col)) {}; + void _OnSelectCell(wxGridEvent& event); + + // Override to create your own class of grid cell + virtual wxGridCell *OnCreateCell(); + void _OnCreateCell(wxGridEvent& event); + + // Override to change labels e.g. creation of grid, inserting/deleting a row/col. + // By default, auto-labels the grid. + virtual void OnChangeLabels(); + void _OnChangeLabels(wxGridEvent& event); + + // Override to change the label of the edit field when selecting a cell + // By default, sets it to e.g. A12 + virtual void OnChangeSelectionLabel(); + void _OnChangeSelectionLabel(wxGridEvent& event); + + // Override for event processing + virtual void OnCellChange(int WXUNUSED(row), int WXUNUSED(col)) {}; + virtual void OnCellLeftClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {}; + virtual void OnCellRightClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {}; + virtual void OnLabelLeftClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {}; + virtual void OnLabelRightClick(int WXUNUSED(row), int WXUNUSED(col), int WXUNUSED(x), int WXUNUSED(y), bool WXUNUSED(control), bool WXUNUSED(shift)) {}; + + void _OnCellChange(wxGridEvent& event); + void _OnCellLeftClick(wxGridEvent& event); + void _OnCellRightClick(wxGridEvent& event); + void _OnLabelLeftClick(wxGridEvent& event); + void _OnLabelRightClick(wxGridEvent& event); + + // Activation: call from wxFrame::OnActivate + void OnActivate(bool active); + + // Miscellaneous + void AdjustScrollbars(); + void UpdateDimensions(); + + void SetCurrentRect (int Row, int Column, int canvasW = -1, int canvasH = -1); + void HighlightCell (wxDC *dc); + void DrawCellText(); + void SetGridClippingRegion(wxDC *dc); + + virtual bool CellHitTest(int x, int y, int *row, int *col); + virtual bool LabelSashHitTest(int x, int y, int *orientation, int *rowOrCol, int *startPos); + virtual bool LabelHitTest(int x, int y, int *row, int *col); + + // Painting + virtual void DrawLabelAreas(wxDC *dc); + virtual void DrawEditableArea(wxDC *dc); + virtual void DrawGridLines(wxDC *dc); + virtual void DrawColumnLabels(wxDC *dc); + virtual void DrawColumnLabel(wxDC *dc, wxRect *rect, int col); + virtual void DrawRowLabels(wxDC *dc); + virtual void DrawRowLabel(wxDC *dc, wxRect *rect, int row); + virtual void DrawCells(wxDC *dc); + virtual void DrawCellValue(wxDC *dc, wxRect *rect, int row, int col); + virtual void DrawCellBackground(wxDC *dc, wxRect *rect, int row, int col); + virtual void DrawTextRect(wxDC *dc, const wxString& text, wxRect *rect, int flag); + virtual void DrawBitmapRect(wxDC *dc, wxBitmap *bitmap, wxRect *rect, int flag); + + // Refresh cell and optionally set the text field + void RefreshCell(int row, int col, bool setText = FALSE); + + // Don't refresh within the outer pair of these. + void BeginBatch() { m_batchCount ++; } + void EndBatch() { m_batchCount --; } + int GetBatchCount() { return m_batchCount; } + + // implementation from now on + + void OnPaint(wxPaintEvent& event); + void OnEraseBackground(wxEraseEvent& event); + void OnMouseEvent(wxMouseEvent& event); + void OnSize(wxSizeEvent& event); + void OnText(wxCommandEvent& ev); + void OnTextInPlace(wxCommandEvent& ev); + void OnGridScroll(wxScrollEvent& ev); + +protected: + wxPanel* m_editingPanel; // Contains the text control + wxTextCtrl* m_textItem; + wxTextCtrl* m_inPlaceTextItem; + + wxScrollBar* m_hScrollBar; + wxScrollBar* m_vScrollBar; + int m_wCursorRow; + int m_wCursorColumn; + wxRect m_currentRect; + bool m_currentRectVisible; + wxGridCell*** m_gridCells; + wxGridCell** m_rowLabelCells; + wxGridCell** m_colLabelCells; + + bool m_editCreated; + bool m_editable; + bool m_editInPlace; + bool m_inOnTextInPlace; + + int m_totalRows; + int m_totalCols; + + // Row and column we're currently looking at + int m_scrollPosX; + int m_scrollPosY; + + // Dimensions + int m_leftOfSheet; + int m_topOfSheet; + int m_rightOfSheet; // Calculated from m_colWidths + int m_bottomOfSheet; // Calculated from m_rowHeights + int m_totalGridWidth; // Total 'virtual' size + int m_totalGridHeight; + int m_cellHeight; // For now, a default + int m_verticalLabelWidth; + int m_horizontalLabelHeight; + int m_verticalLabelAlignment; + int m_horizontalLabelAlignment; + int m_cellAlignment; + short* m_colWidths; // Dynamically allocated + short* m_rowHeights; // Dynamically allocated + int m_scrollWidth; // Vert. scroll width, horiz. scroll height + + // Colours + wxColour m_cellTextColour; + wxColour m_cellBackgroundColour; + wxFont m_cellTextFont; + wxColour m_labelTextColour; + wxColour m_labelBackgroundColour; + wxBrush m_labelBackgroundBrush; + wxFont m_labelTextFont; + wxPen m_divisionPen; + wxBitmap* m_doubleBufferingBitmap; + + // Position of Edit control + wxRect m_editControlPosition; + + // Drag status + int m_dragStatus; + int m_dragRowOrCol; + int m_dragStartPosition; + int m_dragLastPosition; + wxCursor m_horizontalSashCursor; + wxCursor m_verticalSashCursor; + + // To avoid multiple refreshes, use Begin/EndBatch + int m_batchCount; + + DECLARE_EVENT_TABLE() }; #define wxGRID_TEXT_CTRL 2000 #define wxGRID_HSCROLL 2001 #define wxGRID_VSCROLL 2002 +#define wxGRID_EDIT_IN_PLACE_TEXT_CTRL 2003 -class WXDLLEXPORT wxGridCell: public wxObject +class WXDLLEXPORT wxGridCell : public wxObject { - public: - wxString textValue; - wxFont font; - wxColour textColour; - wxColour backgroundColour; - wxBrush backgroundBrush; - wxBitmap* cellBitmap; - int alignment; - - wxGridCell(wxGenericGrid *window = (wxGenericGrid *) NULL); - ~wxGridCell(void); - - virtual wxString& GetTextValue(void) const { return (wxString&) textValue; } - virtual void SetTextValue(const wxString& str) { textValue = str; } - inline wxFont& GetFont(void) const { return (wxFont&) font; } - inline void SetFont(const wxFont& f) { font = f; } - inline wxColour& GetTextColour(void) const { return (wxColour&) textColour; } - inline void SetTextColour(const wxColour& colour) { textColour = colour; } - inline wxColour& GetBackgroundColour(void) const { return (wxColour&) backgroundColour; } - void SetBackgroundColour(const wxColour& colour); - inline wxBrush& GetBackgroundBrush(void) const { return (wxBrush&) backgroundBrush; } - inline void SetBackgroundBrush(const wxBrush& brush) { backgroundBrush = brush; } - inline int GetAlignment(void) const { return alignment; } - inline void SetAlignment(int align) { alignment = align; } - inline wxBitmap *GetCellBitmap(void) const { return cellBitmap; } - inline void SetCellBitmap(wxBitmap *bitmap) { cellBitmap = bitmap; } +public: + wxString textValue; + wxFont font; + wxColour textColour; + wxColour backgroundColour; + wxBrush backgroundBrush; + wxBitmap* cellBitmap; + int alignment; + + wxGridCell(wxGenericGrid *window = (wxGenericGrid *) NULL); + ~wxGridCell(); + + virtual wxString& GetTextValue() const { return (wxString&) textValue; } + virtual void SetTextValue(const wxString& str) { textValue = str; } + wxFont& GetFont() const { return (wxFont&) font; } + void SetFont(const wxFont& f) { font = f; } + wxColour& GetTextColour() const { return (wxColour&) textColour; } + void SetTextColour(const wxColour& colour) { textColour = colour; } + wxColour& GetBackgroundColour() const { return (wxColour&) backgroundColour; } + void SetBackgroundColour(const wxColour& colour); + wxBrush& GetBackgroundBrush() const { return (wxBrush&) backgroundBrush; } + void SetBackgroundBrush(const wxBrush& brush) { backgroundBrush = brush; } + int GetAlignment() const { return alignment; } + void SetAlignment(int align) { alignment = align; } + wxBitmap *GetCellBitmap() const { return cellBitmap; } + void SetCellBitmap(wxBitmap *bitmap) { cellBitmap = bitmap; } }; -class WXDLLEXPORT wxGrid: public wxGenericGrid +class WXDLLEXPORT wxGrid : public wxGenericGrid { - public: - wxGrid(void):wxGenericGrid() {} +public: + wxGrid() : wxGenericGrid() { } wxGrid(wxWindow *parent, int x=-1, int y=-1, int width=-1, int height=-1, - long style=0, char *name = "gridWindow"): - wxGenericGrid(parent, x, y, width, height, style, name) - { - } + long style=0, char *name = "gridWindow") + : wxGenericGrid(parent, x, y, width, height, style, name) + { + } }; -class WXDLLEXPORT wxGridEvent : public wxCommandEvent { +class WXDLLEXPORT wxGridEvent : public wxCommandEvent +{ DECLARE_DYNAMIC_CLASS(wxGridEvent) + public: wxGridEvent() : wxCommandEvent(), m_row(-1), m_col(-1), m_x(-1), m_y(-1), - m_control(0), m_shift(0), m_cell(0) - {} + m_control(0), m_shift(0), m_cell(0) + { + } wxGridEvent(int id, wxEventType type, wxObject* obj, - int row=-1, int col=-1, int x=-1, int y=-1, - bool control=FALSE, bool shift=FALSE) + int row=-1, int col=-1, int x=-1, int y=-1, + bool control=FALSE, bool shift=FALSE) : wxCommandEvent(type, id), m_row(row), m_col(col), m_x(x), m_y(y), - m_control(control), m_shift(shift), m_cell(0) - { - SetEventObject(obj); - } - + m_control(control), m_shift(shift), m_cell(0) + { + SetEventObject(obj); + } +//private: int m_row; int m_col; int m_x; @@ -382,5 +400,5 @@ typedef void (wxEvtHandler::*wxGridEventFunction)(wxGridEvent&); #define EVT_GRID_LABEL_LCLICK(fn) { wxEVT_GRID_LABEL_LCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &fn, NULL }, #define EVT_GRID_LABEL_RCLICK(fn) { wxEVT_GRID_LABEL_RCLICK, -1, -1, (wxObjectEventFunction) (wxEventFunction) (wxGridEventFunction) &fn, NULL }, -#endif +#endif // __GRIDH_G__ diff --git a/samples/grid/test.cpp b/samples/grid/test.cpp index 7662b5b09c..f7cf501a1b 100644 --- a/samples/grid/test.cpp +++ b/samples/grid/test.cpp @@ -34,6 +34,7 @@ class MyApp: public wxApp bool OnInit(void); }; + // Define a new frame type class MyFrame: public wxFrame { public: @@ -41,6 +42,7 @@ class MyFrame: public wxFrame MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, const wxSize& size); void ToggleEditable(wxCommandEvent& event); + void ToggleEditInPlace(wxCommandEvent& event); void ToggleRowLabel(wxCommandEvent& event); void ToggleColLabel(wxCommandEvent& event); void ToggleDividers(wxCommandEvent& event); @@ -66,6 +68,7 @@ wxBitmap *cellBitmap2 = (wxBitmap *) NULL; // ID for the menu quit command #define GRID_QUIT 1 #define GRID_TOGGLE_EDITABLE 2 +#define GRID_TOGGLE_EDITINPLACE 22 #define GRID_LEFT_CELL 3 #define GRID_CENTRE_CELL 4 #define GRID_RIGHT_CELL 5 @@ -105,6 +108,7 @@ bool MyApp::OnInit(void) wxMenu *settings_menu = new wxMenu; settings_menu->Append(GRID_TOGGLE_EDITABLE, "&Toggle editable"); + settings_menu->Append(GRID_TOGGLE_EDITINPLACE, "&Toggle edit in place"); settings_menu->Append(GRID_TOGGLE_ROW_LABEL, "Toggle ro&w label"); settings_menu->Append(GRID_TOGGLE_COL_LABEL, "Toggle co&l label"); settings_menu->Append(GRID_TOGGLE_DIVIDERS, "Toggle ÷rs"); @@ -164,6 +168,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString& title, const wxPoint& pos, cons BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_MENU(GRID_TOGGLE_EDITABLE, MyFrame::ToggleEditable) + EVT_MENU(GRID_TOGGLE_EDITINPLACE, MyFrame::ToggleEditInPlace) EVT_MENU(GRID_TOGGLE_ROW_LABEL, MyFrame::ToggleRowLabel) EVT_MENU(GRID_TOGGLE_COL_LABEL, MyFrame::ToggleColLabel) EVT_MENU(GRID_TOGGLE_DIVIDERS, MyFrame::ToggleDividers) @@ -185,6 +190,12 @@ void MyFrame::ToggleEditable(wxCommandEvent& WXUNUSED(event)) grid->Refresh(); } +void MyFrame::ToggleEditInPlace(wxCommandEvent& WXUNUSED(event)) +{ + grid->SetEditInPlace(!grid->GetEditInPlace()); + grid->Refresh(); +} + void MyFrame::ToggleRowLabel(wxCommandEvent& WXUNUSED(event)) { if (grid->GetLabelSize(wxVERTICAL) > 0) diff --git a/src/generic/gridg.cpp b/src/generic/gridg.cpp index 82e11ce420..db89849d02 100644 --- a/src/generic/gridg.cpp +++ b/src/generic/gridg.cpp @@ -2,7 +2,8 @@ // Name: gridg.cpp // Purpose: wxGenericGrid // Author: Julian Smart -// Modified by: +// Modified by: Michael Bedward 20 Apr 1999 +// Added edit in place facility // Created: 04/01/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart and Markus Holzem @@ -18,7 +19,7 @@ #include "wx/wxprec.h" #ifdef __BORLANDC__ - #pragma hdrstop +#pragma hdrstop #endif #ifndef WX_PRECOMP @@ -36,9 +37,9 @@ // Set to zero to use no double-buffering #ifdef __WXMSW__ -#define wxUSE_DOUBLE_BUFFERING 1 + #define wxUSE_DOUBLE_BUFFERING 1 #else -#define wxUSE_DOUBLE_BUFFERING 0 + #define wxUSE_DOUBLE_BUFFERING 0 #endif #define wxGRID_DRAG_NONE 0 @@ -54,6 +55,7 @@ BEGIN_EVENT_TABLE(wxGenericGrid, wxPanel) EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground) EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent) EVT_TEXT(wxGRID_TEXT_CTRL, wxGenericGrid::OnText) + EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL, wxGenericGrid::OnTextInPlace) EVT_COMMAND_SCROLL(wxGRID_HSCROLL, wxGenericGrid::OnGridScroll) EVT_COMMAND_SCROLL(wxGRID_VSCROLL, wxGenericGrid::OnGridScroll) @@ -71,8 +73,6 @@ BEGIN_EVENT_TABLE(wxGenericGrid, wxPanel) END_EVENT_TABLE() - - wxGenericGrid::wxGenericGrid(void) { m_batchCount = 0; @@ -89,6 +89,10 @@ wxGenericGrid::wxGenericGrid(void) m_textItem = (wxTextCtrl *) NULL; m_currentRectVisible = FALSE; m_editable = TRUE; + + m_editInPlace = TRUE; + m_inOnTextInPlace = FALSE; + #if defined(__WIN95__) m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X); #elif defined(__WXGTK__) @@ -209,8 +213,9 @@ bool wxGenericGrid::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, m_editingPanel = new wxPanel(this); m_textItem = new wxTextCtrl(m_editingPanel, wxGRID_TEXT_CTRL, "", - wxPoint(m_editControlPosition.x, m_editControlPosition.y), wxSize(m_editControlPosition.width, -1), - 0); + wxPoint(m_editControlPosition.x, m_editControlPosition.y), + wxSize(m_editControlPosition.width, -1), + 0); m_textItem->Show(TRUE); m_textItem->SetFocus(); int controlW, controlH; @@ -227,6 +232,13 @@ bool wxGenericGrid::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, // SetSize(pos.x, pos.y, size.x, size.y); + m_inPlaceTextItem = new wxTextCtrl( (wxPanel*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL, "", + wxPoint( m_currentRect.x-2, m_currentRect.y-2 ), + wxSize( m_currentRect.width+4, m_currentRect.height+4 ), + wxNO_BORDER ); + m_inPlaceTextItem->Show(TRUE); + m_inPlaceTextItem->SetFocus(); + return TRUE; } @@ -517,7 +529,7 @@ void wxGenericGrid::PaintGrid(wxDC& dc) /* Hilight present cell */ SetCurrentRect(m_wCursorRow, m_wCursorColumn); - if (m_currentRectVisible) + if (m_currentRectVisible && !(m_editable && m_editInPlace)) HighlightCell(& dc); dc.DestroyClippingRegion(); @@ -1400,8 +1412,11 @@ void wxGenericGrid::OnSelectCellImplementation(wxDC *dc, int row, int col) SetGridClippingRegion(dc); // Remove the highlight from the old cell - if (m_currentRectVisible) - HighlightCell(dc); + if ( m_currentRectVisible && !(m_editable && m_editInPlace) ) + { + HighlightCell(dc); + } + // Highlight the new cell and copy its content to the edit control SetCurrentRect(m_wCursorRow, m_wCursorColumn); @@ -1416,20 +1431,48 @@ void wxGenericGrid::OnSelectCellImplementation(wxDC *dc, int row, int col) SetGridClippingRegion(dc); - // 1) Why isn't this needed for Windows?? - // Probably because of the SetValue?? JS. - // 2) Arrrrrgh. This isn't needed anywhere, - // of course. One hour of debugging... RR. - // Put back for Motif only on advice of Michael Bedward + + if ( m_editable && m_editInPlace ) + { + m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2, + m_currentRect.width+4, m_currentRect.height+4 ); + + if ( cell ) + { + if ( cell->GetTextValue().IsNull() ) + { + m_inPlaceTextItem->SetValue( "" ); + } + else + { + m_inPlaceTextItem->SetFont( cell->GetFont() ); + m_inPlaceTextItem->SetValue( cell->GetTextValue() ); + } + } + + m_inPlaceTextItem->Show(TRUE); + m_inPlaceTextItem->SetFocus(); + } + else + { + // 1) Why isn't this needed for Windows?? + // Probably because of the SetValue?? JS. + // 2) Arrrrrgh. This isn't needed anywhere, + // of course. One hour of debugging... RR. + // + // 3) It *is* needed for Motif - michael + // #ifdef __WXMOTIF__ - HighlightCell(dc); + if ( !(m_editable && m_editInPlace) ) + HighlightCell(dc); #endif + } dc->DestroyClippingRegion(); - //OnSelectCell(row, col); + OnSelectCell(row, col); wxGridEvent g_evt2(GetId(), wxEVT_GRID_SELECT_CELL, this, row, col); - GetEventHandler()->ProcessEvent(g_evt2); + GetEventHandler()->ProcessEvent(g_evt2); } wxGridCell *wxGenericGrid::OnCreateCell(void) @@ -1515,8 +1558,6 @@ void wxGenericGrid::DrawCellText(void) if (!cell) return; - static wxChar szEdit[300]; - wxClientDC dc(this); dc.BeginDrawing(); @@ -1525,7 +1566,7 @@ void wxGenericGrid::DrawCellText(void) dc.SetBackgroundMode(wxTRANSPARENT); dc.SetBrush(cell->GetBackgroundBrush()); - wxStrcpy(szEdit, m_textItem->GetValue()); + wxString editValue = m_textItem->GetValue(); wxRect rect; rect = m_currentRect; @@ -1534,8 +1575,9 @@ void wxGenericGrid::DrawCellText(void) rect.width -= 5; rect.height -= 4; - DrawTextRect(& dc, _T(" "), &rect, wxLEFT); - DrawTextRect(& dc, szEdit, &rect, cell->GetAlignment()); + // FIXME: what's this string of spaces supposed to represent? + DrawTextRect(& dc, " ", &rect, wxLEFT); + DrawTextRect(& dc, editValue, &rect, cell->GetAlignment()); dc.DestroyClippingRegion(); @@ -1966,6 +2008,12 @@ void wxGenericGrid::SetEditable(bool edit) m_textItem->Show(TRUE); m_textItem->SetFocus(); } + + if (m_inPlaceTextItem) + { + m_inPlaceTextItem->Show(TRUE); + m_inPlaceTextItem->SetFocus(); + } } else { @@ -1975,6 +2023,11 @@ void wxGenericGrid::SetEditable(bool edit) m_textItem->Show(FALSE); m_editingPanel->Show(FALSE); } + + if ( m_inPlaceTextItem ) + { + m_inPlaceTextItem->Show(FALSE); + } } UpdateDimensions(); SetCurrentRect(GetCursorRow(), GetCursorColumn()); @@ -1994,6 +2047,47 @@ void wxGenericGrid::SetEditable(bool edit) */ } + +void wxGenericGrid::SetEditInPlace(bool edit) +{ + if ( m_editInPlace != edit ) + { + m_editInPlace = edit; + + if ( m_editInPlace ) // switched on + { + if ( m_currentRectVisible && m_editable ) + { + m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2, + m_currentRect.width+4, m_currentRect.height+4 ); + + wxGridCell *cell = GetCell(m_wCursorRow, m_wCursorColumn); + + if ( cell ) + { + if ( cell->GetTextValue().IsNull() ) + { + m_inPlaceTextItem->SetValue( "" ); + } + else + { + m_inPlaceTextItem->SetFont( cell->GetFont() ); + m_inPlaceTextItem->SetValue( cell->GetTextValue() ); + } + } + + m_inPlaceTextItem->Show( TRUE ); + m_inPlaceTextItem->SetFocus(); + } + } + else // switched off + { + m_inPlaceTextItem->Show( FALSE ); + } + } +} + + void wxGenericGrid::SetCellAlignment(int flag, int row, int col) { wxGridCell *cell = GetCell(row, col); @@ -2394,7 +2488,7 @@ void wxGenericGrid::SetGridCursor(int row, int col) SetGridClippingRegion(& dc); - if (m_currentRectVisible) + if (m_currentRectVisible && !(m_editable && m_editInPlace) ) HighlightCell(& dc); m_wCursorRow = row; @@ -2405,7 +2499,7 @@ void wxGenericGrid::SetGridCursor(int row, int col) SetCurrentRect(row, col, cw, ch); - if (m_currentRectVisible) + if (m_currentRectVisible && !(m_editable && m_editInPlace) ) HighlightCell(& dc); dc.DestroyClippingRegion(); @@ -2455,28 +2549,56 @@ void wxGridCell::SetBackgroundColour(const wxColour& colour) void wxGenericGrid::OnText(wxCommandEvent& WXUNUSED(ev) ) { - wxGenericGrid *grid = this; - wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn()); - if (cell && grid->CurrentCellVisible()) - { - cell->SetTextValue(grid->GetTextItem()->GetValue()); - wxClientDC dc(grid); - - dc.BeginDrawing(); - grid->SetGridClippingRegion(& dc); - grid->DrawCellBackground(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn()); - grid->DrawCellValue(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn()); - grid->HighlightCell(& dc); - dc.DestroyClippingRegion(); - dc.EndDrawing(); - - //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn()); - wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_CHANGE, grid, - grid->GetCursorRow(), grid->GetCursorColumn()); - GetEventHandler()->ProcessEvent(g_evt); + // michael - added this conditional to prevent change to + // grid cell text when edit control is hidden but still has + // focus + // + if ( m_editable ) + { + wxGenericGrid *grid = this; + wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn()); + if (cell && grid->CurrentCellVisible()) + { + cell->SetTextValue(grid->GetTextItem()->GetValue()); + if ( m_editInPlace && !m_inOnTextInPlace ) + { + m_inPlaceTextItem->SetValue( grid->GetTextItem()->GetValue() ); + } + + wxClientDC dc(grid); + + dc.BeginDrawing(); + grid->SetGridClippingRegion(& dc); + grid->DrawCellBackground(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn()); + grid->DrawCellValue(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn()); + if ( !(m_editable && m_editInPlace ) ) grid->HighlightCell(& dc); + dc.DestroyClippingRegion(); + dc.EndDrawing(); + + //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn()); + wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_CHANGE, grid, + grid->GetCursorRow(), grid->GetCursorColumn()); + GetEventHandler()->ProcessEvent(g_evt); + + // grid->DrawCellText(); + } + } +} -// grid->DrawCellText(); - } +void wxGenericGrid::OnTextInPlace(wxCommandEvent& ev ) +{ + if ( m_editable ) + { + wxGenericGrid *grid = this; + wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn()); + if (cell && grid->CurrentCellVisible()) + { + m_inOnTextInPlace = TRUE; + grid->GetTextItem()->SetValue( m_inPlaceTextItem->GetValue() ); + OnText( ev ); + m_inOnTextInPlace = FALSE; + } + } } void wxGenericGrid::OnGridScroll(wxScrollEvent& ev) @@ -2486,6 +2608,8 @@ void wxGenericGrid::OnGridScroll(wxScrollEvent& ev) if ( inScroll ) return; + if ( m_editInPlace ) m_inPlaceTextItem->Show(FALSE); + inScroll = TRUE; wxGenericGrid *win = this; @@ -2512,6 +2636,15 @@ void wxGenericGrid::OnGridScroll(wxScrollEvent& ev) AdjustScrollbars(); if (change) win->Refresh(FALSE); + + if ( m_editInPlace && m_currentRectVisible ) + { + m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2, + m_currentRect.width+4, m_currentRect.height+4 ); + m_inPlaceTextItem->Show( TRUE ); + m_inPlaceTextItem->SetFocus(); + } + inScroll = FALSE; } -- 2.47.2