- Main change is the addition of wxGridSelectRowsOrColumns selection mode

(which is still probably buggy, wxGridSelection needs to be reviewed)
- Add XYToCell() overloads returning wxGridCellCoords (instead of modifying the
  argument passed by reference -- where did this come from?) and document them.
- Added GoToCell() which does make the new current cell visible unlike
  SetGridCursor() (which was documented as doing it, but wasn't)
- Changed SetCurrentCell() to only not change the cell if wxEVT_GRID_SELECT_CELL
  it generates is vetoed, not just processed as this seems to make more sense
- Split jumbo (~400 lines) ProcessGridCellMouseEvent() function into chunks
- Add many more comments to make reading this code seem less like puzzle
  solving for the next unfortunate soul to do it


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@55746 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-09-19 23:33:04 +00:00
parent 0e0977894a
commit 8a3e536cd5
8 changed files with 717 additions and 502 deletions

View File

@@ -392,6 +392,7 @@ All (GUI):
- wxWindow::IsBeingDeleted() now returns true not only if the window itself is
marked for destruction but also if any of its parent windows are.
- Improved drawing of the hint during column move in wxGrid.
- Add wxGridSelectRowsOrColumns selection mode to wxGrid.
- Get/HasModifiers() of wxKeyEvent are now also available in wxMouseEvent.
wxGTK:

View File

@@ -320,7 +320,7 @@ public:
// Show or hide the edit control, use the specified attributes to set
// colours/fonts for it
virtual void Show(bool show, wxGridCellAttr *attr = (wxGridCellAttr *)NULL);
virtual void Show(bool show, wxGridCellAttr *attr = 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
@@ -1145,6 +1145,10 @@ public:
bool takeOwnership = false,
wxGridSelectionModes selmode = wxGridSelectCells );
bool ProcessTableMessage(wxGridTableMessage&);
wxGridTableBase *GetTable() const { return m_table; }
void SetSelectionMode(wxGridSelectionModes selmode);
wxGridSelectionModes GetSelectionMode() const;
@@ -1163,20 +1167,6 @@ public:
wxGridCellCoordsArray CalcCellsExposed( const wxRegion& reg ) const;
// ------ event handlers
//
void ProcessRowLabelMouseEvent( wxMouseEvent& event );
void ProcessColLabelMouseEvent( wxMouseEvent& event );
void ProcessCornerLabelMouseEvent( wxMouseEvent& event );
void ProcessGridCellMouseEvent( wxMouseEvent& event );
bool ProcessTableMessage( wxGridTableMessage& );
void DoEndDragResizeRow();
void DoEndDragResizeCol();
void DoEndDragMoveCol();
wxGridTableBase * GetTable() const { return m_table; }
void ClearGrid();
bool InsertRows(int pos = 0, int numRows = 1, bool updateLabels = true)
{
@@ -1261,8 +1251,7 @@ public:
int GetBatchCount() { return m_batchCount; }
virtual void Refresh(bool eraseb = true,
const wxRect* rect = (const wxRect *) NULL);
virtual void Refresh(bool eraseb = true, const wxRect* rect = NULL);
// Use this, rather than wxWindow::Refresh(), to force an
// immediate repainting of the grid. Has no effect if you are
@@ -1297,7 +1286,12 @@ public:
// grid cells and labels so you will need to convert from device
// coordinates for mouse events etc.
//
void XYToCell( int x, int y, wxGridCellCoords& ) const;
wxGridCellCoords XYToCell(int x, int y) const;
void XYToCell(int x, int y, wxGridCellCoords& coords) const
{ coords = XYToCell(x, y); }
wxGridCellCoords XYToCell(const wxPoint& pos) const
{ return XYToCell(pos.x, pos.y); }
int YToRow( int y, bool clipToMinMax = false ) const;
int XToCol( int x, bool clipToMinMax = false ) const;
@@ -1324,8 +1318,20 @@ public:
// ------ grid cursor movement functions
//
void SetGridCursor( int row, int col )
{ SetCurrentCell( wxGridCellCoords(row, col) ); }
void SetGridCursor(int row, int col) { SetCurrentCell(row, col); }
void SetGridCursor(const wxGridCellCoords& c) { SetCurrentCell(c); }
void GoToCell(int row, int col)
{
if ( SetCurrentCell(row, col) )
MakeCellVisible(row, col);
}
void GoToCell(const wxGridCellCoords& coords)
{
if ( SetCurrentCell(coords) )
MakeCellVisible(coords);
}
bool MoveCursorUp( bool expandSelection );
bool MoveCursorDown( bool expandSelection );
@@ -1867,10 +1873,22 @@ protected:
wxGridCellCoords m_currentCellCoords;
wxGridCellCoords m_selectingTopLeft;
wxGridCellCoords m_selectingBottomRight;
wxGridCellCoords m_selectingKeyboard;
// the corners of the block being currently selected or wxGridNoCellCoords
wxGridCellCoords m_selectedBlockTopLeft;
wxGridCellCoords m_selectedBlockBottomRight;
// when selecting blocks of cells (either from the keyboard using Shift
// with cursor keys, or by dragging the mouse), the selection is anchored
// at m_currentCellCoords which defines one of the corners of the rectangle
// being selected -- and this variable defines the other corner, i.e. it's
// either m_selectedBlockTopLeft or m_selectedBlockBottomRight depending on
// which of them is not m_currentCellCoords
//
// if no block selection is in process, it is set to wxGridNoCellCoords
wxGridCellCoords m_selectedBlockCorner;
wxGridSelection *m_selection;
wxColour m_selectionBackground;
wxColour m_selectionForeground;
@@ -2007,12 +2025,22 @@ protected:
// for this to work, you should always use it and not set m_cursorMode
// directly!
void ChangeCursorMode(CursorMode mode,
wxWindow *win = (wxWindow *)NULL,
wxWindow *win = NULL,
bool captureMouse = true);
wxWindow *m_winCapture; // the window which captured the mouse
// this variable is used not for finding the correct current cursor but
// mainly for finding out what is going to happen if the mouse starts being
// dragged right now
//
// by default it is WXGRID_CURSOR_SELECT_CELL meaning that nothing else is
// going on, and it is set to one of RESIZE/SELECT/MOVE values while the
// corresponding operation will be started if the user starts dragging the
// mouse from the current position
CursorMode m_cursorMode;
//Column positions
wxArrayInt m_colAt;
int m_moveToCol;
@@ -2029,7 +2057,16 @@ protected:
int m_dragLastPos;
int m_dragRowOrCol;
// true if a drag operation is in progress; when this is true,
// m_startDragPos is valid, i.e. not wxDefaultPosition
bool m_isDragging;
// the position (in physical coordinates) where the user started dragging
// the mouse or wxDefaultPosition if mouse isn't being dragged
//
// notice that this can be != wxDefaultPosition while m_isDragging is still
// false because we wait until the mouse is moved some distance away before
// setting m_isDragging to true
wxPoint m_startDragPos;
bool m_waitForSlowClick;
@@ -2053,14 +2090,20 @@ protected:
bool Redimension( wxGridTableMessage& );
int SendEvent( const wxEventType, int row, int col, wxMouseEvent& );
int SendEvent( const wxEventType, int row, int col );
int SendEvent( const wxEventType type)
{
return SendEvent(type,
m_currentCellCoords.GetRow(),
m_currentCellCoords.GetCol());
}
// generate the appropriate grid event and return -1 if it was vetoed, 1 if
// it was processed (but not vetoed) and 0 if it wasn't processed
int SendEvent(const wxEventType evtType,
int row, int col,
wxMouseEvent& e);
int SendEvent(const wxEventType evtType,
const wxGridCellCoords& coords,
wxMouseEvent& e)
{ return SendEvent(evtType, coords.GetRow(), coords.GetCol(), e); }
int SendEvent(const wxEventType evtType, int row, int col);
int SendEvent(const wxEventType evtType, const wxGridCellCoords& coords)
{ return SendEvent(evtType, coords.GetRow(), coords.GetCol()); }
int SendEvent(const wxEventType evtType)
{ return SendEvent(evtType, m_currentCellCoords); }
void OnPaint( wxPaintEvent& );
void OnSize( wxSizeEvent& );
@@ -2070,16 +2113,20 @@ protected:
void OnEraseBackground( wxEraseEvent& );
void SetCurrentCell( const wxGridCellCoords& coords );
void SetCurrentCell( int row, int col )
{ SetCurrentCell( wxGridCellCoords(row, col) ); }
bool SetCurrentCell( const wxGridCellCoords& coords );
bool SetCurrentCell( int row, int col )
{ return SetCurrentCell( wxGridCellCoords(row, col) ); }
void HighlightBlock( int topRow, int leftCol, int bottomRow, int rightCol );
void HighlightBlock( const wxGridCellCoords& topLeft,
const wxGridCellCoords& bottomRight )
{ HighlightBlock( topLeft.GetRow(), topLeft.GetCol(),
bottomRight.GetRow(), bottomRight.GetCol() ); }
// this function is called to extend the block being currently selected
// from mouse and keyboard event handlers
void UpdateBlockBeingSelected(int topRow, int leftCol,
int bottomRow, int rightCol);
void UpdateBlockBeingSelected(const wxGridCellCoords& topLeft,
const wxGridCellCoords& bottomRight)
{ UpdateBlockBeingSelected(topLeft.GetRow(), topLeft.GetCol(),
bottomRight.GetRow(), bottomRight.GetCol()); }
// ------ functions to get/send data (see also public functions)
//
@@ -2090,10 +2137,56 @@ protected:
friend class wxGridRowOperations;
friend class wxGridColumnOperations;
// they call our private Process{{Corner,Col,Row}Label,GridCell}MouseEvent()
friend class wxGridCornerLabelWindow;
friend class wxGridColLabelWindow;
friend class wxGridRowLabelWindow;
friend class wxGridWindow;
private:
// implement wxScrolledWindow method to return m_gridWin size
virtual wxSize GetSizeAvailableForScrollTarget(const wxSize& size);
// event handlers and their helpers
// --------------------------------
// process mouse drag event in WXGRID_CURSOR_SELECT_CELL mode
void DoGridCellDrag(wxMouseEvent& event,
const wxGridCellCoords& coords,
bool isFirstDrag);
// process row/column resizing drag event
void DoGridLineDrag(wxMouseEvent& event, const wxGridOperations& oper);
// process mouse drag event in the grid window
void DoGridDragEvent(wxMouseEvent& event, const wxGridCellCoords& coords);
// process different clicks on grid cells
void DoGridCellLeftDown(wxMouseEvent& event,
const wxGridCellCoords& coords,
const wxPoint& pos);
void DoGridCellLeftDClick(wxMouseEvent& event,
const wxGridCellCoords& coords,
const wxPoint& pos);
void DoGridCellLeftUp(wxMouseEvent& event, const wxGridCellCoords& coords);
// process movement (but not dragging) event in the grid cell area
void DoGridMouseMoveEvent(wxMouseEvent& event,
const wxGridCellCoords& coords,
const wxPoint& pos);
// process mouse events in the grid window
void ProcessGridCellMouseEvent(wxMouseEvent& event);
// process mouse events in the row/column labels/corner windows
void ProcessRowLabelMouseEvent(wxMouseEvent& event);
void ProcessColLabelMouseEvent(wxMouseEvent& event);
void ProcessCornerLabelMouseEvent(wxMouseEvent& event);
void DoEndDragResizeRow();
void DoEndDragResizeCol();
void DoEndDragMoveCol();
// common implementations of methods defined for both rows and columns
void DeselectLine(int line, const wxGridOperations& oper);

View File

@@ -44,10 +44,23 @@ public:
bool ControlDown = false, bool ShiftDown = false,
bool AltDown = false, bool MetaDown = false,
bool sendEvent = true );
void SelectBlock( const wxGridCellCoords& topLeft,
const wxGridCellCoords& bottomRight,
bool ControlDown = false, bool ShiftDown = false,
bool AltDown = false, bool MetaDown = false,
bool sendEvent = true )
{
SelectBlock(topLeft.GetRow(), topLeft.GetCol(),
bottomRight.GetRow(), bottomRight.GetCol(),
ControlDown, ShiftDown, AltDown, MetaDown,
sendEvent);
}
void SelectCell( int row, int col,
bool ControlDown = false, bool ShiftDown = false,
bool AltDown = false, bool MetaDown = false,
bool sendEvent = true );
void ToggleCellSelection( int row, int col,
bool ControlDown = false,
bool ShiftDown = false,

View File

@@ -2130,6 +2130,19 @@ public:
*/
wxGridTableBase *GetTable() const;
//@{
/**
Make the given cell current and ensure it is visible.
This method is equivalent to calling MakeCellVisible() and
SetGridCursor() and so, as with the latter, a wxEVT_GRID_SELECT_CELL
event is generated by it and the selected cell doesn't change if the
event is vetoed.
*/
void GoToCell(int row, int col);
void GoToCell(const wxGridCellCoords& coords);
//@}
/**
Returns @true if drawing of grid lines is turned on, @false otherwise.
*/
@@ -2693,12 +2706,22 @@ public:
*/
void SetDefaultRowSize(int height, bool resizeExistingRows = false);
//@{
/**
Set the grid cursor to the specified cell.
This function calls MakeCellVisible().
The grid cursor indicates the current cell and can be moved by the user
using the arrow keys or the mouse.
Calling this function generates a wxEVT_GRID_SELECT_CELL event and if
the event handler vetoes this event, the cursor is not moved.
This function doesn't make the target call visible, use GoToCell() to
do this.
*/
void SetGridCursor(int row, int col);
void SetGridCursor(const wxGridCellCoords& coords);
//@}
/**
Sets the colour used to draw grid lines.
@@ -2883,6 +2906,27 @@ public:
*/
int XToEdgeOfCol(int x) const;
//@{
/**
Translates logical pixel coordinates to the grid cell coordinates.
Notice that this function expects logical coordinates on input so if
you use this function in a mouse event handler you need to translate
the mouse position, which is expressed in device coordinates, to
logical ones.
@see XToCol(), YToRow()
*/
// XYToCell(int, int, wxGridCellCoords&) overload is intentionally
// undocumented, using it is ugly and non-const reference parameters are
// not used in wxWidgets API
wxGridCellCoords XYToCell(int x, int y) const;
wxGridCellCoords XYToCell(const wxPoint& pos) const;
//@}
/**
Returns the row whose bottom edge is close to the given logical y
position.

View File

@@ -92,6 +92,7 @@ BEGIN_EVENT_TABLE( GridFrame, wxFrame )
EVT_MENU( ID_SELCELLS, GridFrame::SelectCells )
EVT_MENU( ID_SELROWS, GridFrame::SelectRows )
EVT_MENU( ID_SELCOLS, GridFrame::SelectCols )
EVT_MENU( ID_SELROWSORCOLS, GridFrame::SelectRowsOrCols )
EVT_MENU( ID_SET_CELL_FG_COLOUR, GridFrame::SetCellFgColour )
EVT_MENU( ID_SET_CELL_BG_COLOUR, GridFrame::SetCellBgColour )
@@ -223,9 +224,10 @@ GridFrame::GridFrame()
selectionMenu,
_T("Change selection mode") );
selectionMenu->Append( ID_SELCELLS, _T("Select &Cells") );
selectionMenu->Append( ID_SELROWS, _T("Select &Rows") );
selectionMenu->Append( ID_SELCOLS, _T("Select C&ols") );
selectionMenu->Append( ID_SELCELLS, _T("Select &cells") );
selectionMenu->Append( ID_SELROWS, _T("Select &rows") );
selectionMenu->Append( ID_SELCOLS, _T("Select col&umns") );
selectionMenu->Append( ID_SELROWSORCOLS, _T("Select rows &or columns") );
wxMenu *autosizeMenu = new wxMenu;
autosizeMenu->Append( ID_SIZE_ROW, _T("Selected &row data") );
@@ -807,6 +809,11 @@ void GridFrame::SelectCols( wxCommandEvent& WXUNUSED(ev) )
grid->SetSelectionMode( wxGrid::wxGridSelectColumns );
}
void GridFrame::SelectRowsOrCols( wxCommandEvent& WXUNUSED(ev) )
{
grid->SetSelectionMode( wxGrid::wxGridSelectRowsOrColumns );
}
void GridFrame::SetCellFgColour( wxCommandEvent& WXUNUSED(ev) )
{
wxColour col = wxGetColourFromUser(this);

View File

@@ -64,6 +64,7 @@ class GridFrame : public wxFrame
void SelectCells( wxCommandEvent& );
void SelectRows( wxCommandEvent& );
void SelectCols( wxCommandEvent& );
void SelectRowsOrCols( wxCommandEvent& );
void DeselectCell(wxCommandEvent& event);
void DeselectCol(wxCommandEvent& event);
@@ -144,6 +145,7 @@ public:
ID_SELCELLS,
ID_SELROWS,
ID_SELCOLS,
ID_SELROWSORCOLS,
ID_SET_CELL_FG_COLOUR,
ID_SET_CELL_BG_COLOUR,
ID_VTABLE,

File diff suppressed because it is too large Load Diff

View File

@@ -385,15 +385,30 @@ void wxGridSelection::SelectBlock( int topRow, int leftCol,
bool sendEvent )
{
// Fix the coordinates of the block if needed.
if ( m_selectionMode == wxGrid::wxGridSelectRows )
switch ( m_selectionMode )
{
leftCol = 0;
rightCol = m_grid->GetNumberCols() - 1;
}
else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
{
topRow = 0;
bottomRow = m_grid->GetNumberRows() - 1;
default:
wxFAIL_MSG( "unknown selection mode" );
// fall through
case wxGrid::wxGridSelectCells:
// nothing to do -- in this mode arbitrary blocks can be selected
break;
case wxGrid::wxGridSelectRows:
leftCol = 0;
rightCol = m_grid->GetNumberCols() - 1;
break;
case wxGrid::wxGridSelectColumns:
topRow = 0;
bottomRow = m_grid->GetNumberRows() - 1;
break;
case wxGrid::wxGridSelectRowsOrColumns:
// block selection doesn't make sense for this mode, we could only
// select the entire grid but this wouldn't be useful
return;
}
if ( topRow > bottomRow )