- 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:
@@ -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:
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
|
@@ -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,
|
||||
|
@@ -471,11 +471,20 @@ public:
|
||||
|
||||
|
||||
// Draws a line parallel to the row or column, i.e. horizontal or vertical:
|
||||
// pos is the vertical or horizontal position of the line and start and end
|
||||
// pos is the horizontal or vertical position of the line and start and end
|
||||
// are the coordinates of the line extremities in the other direction
|
||||
virtual void
|
||||
DrawParallelLine(wxDC& dc, int start, int end, int pos) const = 0;
|
||||
|
||||
// Draw a horizontal or vertical line across the given rectangle
|
||||
// (this is implemented in terms of above and uses Select() to extract
|
||||
// start and end from the given rectangle)
|
||||
void DrawParallelLineInRect(wxDC& dc, const wxRect& rect, int pos) const
|
||||
{
|
||||
const int posStart = Select(rect.GetPosition());
|
||||
DrawParallelLine(dc, posStart, posStart + Select(rect.GetSize()), pos);
|
||||
}
|
||||
|
||||
|
||||
// Return the row or column at the given pixel coordinate.
|
||||
virtual int
|
||||
@@ -785,13 +794,22 @@ private:
|
||||
wxGridCellCoords wxGridNoCellCoords( -1, -1 );
|
||||
wxRect wxGridNoCellRect( -1, -1, -1, -1 );
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
// scroll line size
|
||||
static const size_t GRID_SCROLL_LINE_X = 15;
|
||||
static const size_t GRID_SCROLL_LINE_Y = GRID_SCROLL_LINE_X;
|
||||
const size_t GRID_SCROLL_LINE_X = 15;
|
||||
const size_t GRID_SCROLL_LINE_Y = GRID_SCROLL_LINE_X;
|
||||
|
||||
// the size of hash tables used a bit everywhere (the max number of elements
|
||||
// in these hash tables is the number of rows/columns)
|
||||
static const int GRID_HASH_SIZE = 100;
|
||||
const int GRID_HASH_SIZE = 100;
|
||||
|
||||
// the minimal distance in pixels the mouse needs to move to start a drag
|
||||
// operation
|
||||
const int DRAG_SENSITIVITY = 3;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// private helpers
|
||||
@@ -4708,22 +4726,22 @@ wxGrid::SetTable(wxGridTableBase *table,
|
||||
// If the newly set table is smaller than the
|
||||
// original one current cell and selection regions
|
||||
// might be invalid,
|
||||
m_selectingKeyboard = wxGridNoCellCoords;
|
||||
m_selectedBlockCorner = wxGridNoCellCoords;
|
||||
m_currentCellCoords =
|
||||
wxGridCellCoords(wxMin(m_numRows, m_currentCellCoords.GetRow()),
|
||||
wxMin(m_numCols, m_currentCellCoords.GetCol()));
|
||||
if (m_selectingTopLeft.GetRow() >= m_numRows ||
|
||||
m_selectingTopLeft.GetCol() >= m_numCols)
|
||||
if (m_selectedBlockTopLeft.GetRow() >= m_numRows ||
|
||||
m_selectedBlockTopLeft.GetCol() >= m_numCols)
|
||||
{
|
||||
m_selectingTopLeft = wxGridNoCellCoords;
|
||||
m_selectingBottomRight = wxGridNoCellCoords;
|
||||
m_selectedBlockTopLeft = wxGridNoCellCoords;
|
||||
m_selectedBlockBottomRight = wxGridNoCellCoords;
|
||||
}
|
||||
else
|
||||
m_selectingBottomRight =
|
||||
m_selectedBlockBottomRight =
|
||||
wxGridCellCoords(wxMin(m_numRows,
|
||||
m_selectingBottomRight.GetRow()),
|
||||
m_selectedBlockBottomRight.GetRow()),
|
||||
wxMin(m_numCols,
|
||||
m_selectingBottomRight.GetCol()));
|
||||
m_selectedBlockBottomRight.GetCol()));
|
||||
}
|
||||
CalcDimensions();
|
||||
|
||||
@@ -6132,6 +6150,8 @@ void wxGrid::CancelMouseCapture()
|
||||
if ( m_winCapture )
|
||||
{
|
||||
m_isDragging = false;
|
||||
m_startDragPos = wxDefaultPosition;
|
||||
|
||||
m_cursorMode = WXGRID_CURSOR_SELECT_CELL;
|
||||
m_winCapture->SetCursor( *wxSTANDARD_CURSOR );
|
||||
m_winCapture = NULL;
|
||||
@@ -6214,186 +6234,155 @@ void wxGrid::ChangeCursorMode(CursorMode mode,
|
||||
}
|
||||
}
|
||||
|
||||
void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
|
||||
// ----------------------------------------------------------------------------
|
||||
// grid mouse event processing
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
wxGrid::DoGridCellDrag(wxMouseEvent& event,
|
||||
const wxGridCellCoords& coords,
|
||||
bool isFirstDrag)
|
||||
{
|
||||
int x, y;
|
||||
wxPoint pos( event.GetPosition() );
|
||||
CalcUnscrolledPosition( pos.x, pos.y, &x, &y );
|
||||
if ( coords == wxGridNoCellCoords )
|
||||
return; // we're outside any valid cell
|
||||
|
||||
wxGridCellCoords coords;
|
||||
XYToCell( x, y, coords );
|
||||
|
||||
int cell_rows, cell_cols;
|
||||
bool isFirstDrag = !m_isDragging;
|
||||
GetCellSize( coords.GetRow(), coords.GetCol(), &cell_rows, &cell_cols );
|
||||
if ((cell_rows < 0) || (cell_cols < 0))
|
||||
{
|
||||
coords.SetRow(coords.GetRow() + cell_rows);
|
||||
coords.SetCol(coords.GetCol() + cell_cols);
|
||||
}
|
||||
|
||||
if ( event.Dragging() )
|
||||
{
|
||||
//wxLogDebug("pos(%d, %d) coords(%d, %d)", pos.x, pos.y, coords.GetRow(), coords.GetCol());
|
||||
|
||||
// Don't start doing anything until the mouse has been dragged at
|
||||
// least 3 pixels in any direction...
|
||||
if (! m_isDragging)
|
||||
{
|
||||
if (m_startDragPos == wxDefaultPosition)
|
||||
{
|
||||
m_startDragPos = pos;
|
||||
return;
|
||||
}
|
||||
if (abs(m_startDragPos.x - pos.x) < 4 && abs(m_startDragPos.y - pos.y) < 4)
|
||||
return;
|
||||
}
|
||||
|
||||
m_isDragging = true;
|
||||
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
|
||||
{
|
||||
// Hide the edit control, so it
|
||||
// won't interfere with drag-shrinking.
|
||||
// Hide the edit control, so it won't interfere with drag-shrinking.
|
||||
if ( IsCellEditControlShown() )
|
||||
{
|
||||
HideCellEditControl();
|
||||
SaveEditControlValue();
|
||||
}
|
||||
|
||||
if ( coords != wxGridNoCellCoords )
|
||||
switch ( event.GetModifiers() )
|
||||
{
|
||||
if ( event.CmdDown() )
|
||||
{
|
||||
if ( m_selectingKeyboard == wxGridNoCellCoords)
|
||||
m_selectingKeyboard = coords;
|
||||
HighlightBlock( m_selectingKeyboard, coords );
|
||||
}
|
||||
else if ( CanDragCell() )
|
||||
case wxMOD_CMD:
|
||||
if ( m_selectedBlockCorner == wxGridNoCellCoords)
|
||||
m_selectedBlockCorner = coords;
|
||||
UpdateBlockBeingSelected(m_selectedBlockCorner, coords);
|
||||
break;
|
||||
|
||||
case wxMOD_NONE:
|
||||
if ( CanDragCell() )
|
||||
{
|
||||
if ( isFirstDrag )
|
||||
{
|
||||
if ( m_selectingKeyboard == wxGridNoCellCoords)
|
||||
m_selectingKeyboard = coords;
|
||||
if ( m_selectedBlockCorner == wxGridNoCellCoords)
|
||||
m_selectedBlockCorner = coords;
|
||||
|
||||
SendEvent( wxEVT_GRID_CELL_BEGIN_DRAG,
|
||||
coords.GetRow(),
|
||||
coords.GetCol(),
|
||||
event );
|
||||
SendEvent(wxEVT_GRID_CELL_BEGIN_DRAG, coords, event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !IsSelection() )
|
||||
{
|
||||
HighlightBlock( coords, coords );
|
||||
|
||||
UpdateBlockBeingSelected(m_currentCellCoords, coords);
|
||||
break;
|
||||
|
||||
default:
|
||||
// we don't handle the other key modifiers
|
||||
event.Skip();
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
void wxGrid::DoGridLineDrag(wxMouseEvent& event, const wxGridOperations& oper)
|
||||
{
|
||||
wxClientDC dc(m_gridWin);
|
||||
PrepareDC(dc);
|
||||
dc.SetLogicalFunction(wxINVERT);
|
||||
|
||||
const wxRect rectWin(CalcUnscrolledPosition(wxPoint(0, 0)),
|
||||
m_gridWin->GetClientSize());
|
||||
|
||||
// erase the previously drawn line, if any
|
||||
if ( m_dragLastPos >= 0 )
|
||||
oper.DrawParallelLineInRect(dc, rectWin, m_dragLastPos);
|
||||
|
||||
// we need the vertical position for rows and horizontal for columns here
|
||||
m_dragLastPos = oper.Dual().Select(CalcUnscrolledPosition(event.GetPosition()));
|
||||
|
||||
// don't allow resizing beneath the minimal size
|
||||
const int posMin = oper.GetLineStartPos(this, m_dragRowOrCol) +
|
||||
oper.GetMinimalLineSize(this, m_dragRowOrCol);
|
||||
if ( m_dragLastPos < posMin )
|
||||
m_dragLastPos = posMin;
|
||||
|
||||
// and draw it at the new position
|
||||
oper.DrawParallelLineInRect(dc, rectWin, m_dragLastPos);
|
||||
}
|
||||
|
||||
void wxGrid::DoGridDragEvent(wxMouseEvent& event, const wxGridCellCoords& coords)
|
||||
{
|
||||
if ( !m_isDragging )
|
||||
{
|
||||
HighlightBlock( m_currentCellCoords, coords );
|
||||
}
|
||||
// Don't start doing anything until the mouse has been dragged far
|
||||
// enough
|
||||
const wxPoint& pt = event.GetPosition();
|
||||
if ( m_startDragPos == wxDefaultPosition )
|
||||
{
|
||||
m_startDragPos = pt;
|
||||
return;
|
||||
}
|
||||
|
||||
if (! IsVisible(coords))
|
||||
if ( abs(m_startDragPos.x - pt.x) <= DRAG_SENSITIVITY &&
|
||||
abs(m_startDragPos.y - pt.y) <= DRAG_SENSITIVITY )
|
||||
return;
|
||||
}
|
||||
|
||||
const bool isFirstDrag = !m_isDragging;
|
||||
m_isDragging = true;
|
||||
|
||||
switch ( m_cursorMode )
|
||||
{
|
||||
MakeCellVisible(coords);
|
||||
// TODO: need to introduce a delay or something here. The
|
||||
// scrolling is way too fast, at least under MSW and GTK.
|
||||
case WXGRID_CURSOR_SELECT_CELL:
|
||||
DoGridCellDrag(event, coords, isFirstDrag);
|
||||
break;
|
||||
|
||||
case WXGRID_CURSOR_RESIZE_ROW:
|
||||
DoGridLineDrag(event, wxGridRowOperations());
|
||||
break;
|
||||
|
||||
case WXGRID_CURSOR_RESIZE_COL:
|
||||
DoGridLineDrag(event, wxGridColumnOperations());
|
||||
break;
|
||||
|
||||
default:
|
||||
event.Skip();
|
||||
}
|
||||
}
|
||||
// Have we captured the mouse yet?
|
||||
if (! m_winCapture)
|
||||
|
||||
if ( isFirstDrag )
|
||||
{
|
||||
m_winCapture = m_gridWin;
|
||||
m_winCapture->CaptureMouse();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if ( event.LeftIsDown() &&
|
||||
m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
|
||||
void
|
||||
wxGrid::DoGridCellLeftDown(wxMouseEvent& event,
|
||||
const wxGridCellCoords& coords,
|
||||
const wxPoint& pos)
|
||||
{
|
||||
if ( SendEvent(wxEVT_GRID_CELL_LEFT_CLICK, coords, event) )
|
||||
{
|
||||
int cw, ch, left, dummy;
|
||||
m_gridWin->GetClientSize( &cw, &ch );
|
||||
CalcUnscrolledPosition( 0, 0, &left, &dummy );
|
||||
|
||||
wxClientDC dc( m_gridWin );
|
||||
PrepareDC( dc );
|
||||
y = wxMax( y, GetRowTop(m_dragRowOrCol) +
|
||||
GetRowMinimalHeight(m_dragRowOrCol) );
|
||||
dc.SetLogicalFunction(wxINVERT);
|
||||
if ( m_dragLastPos >= 0 )
|
||||
{
|
||||
dc.DrawLine( left, m_dragLastPos, left+cw, m_dragLastPos );
|
||||
}
|
||||
dc.DrawLine( left, y, left+cw, y );
|
||||
m_dragLastPos = y;
|
||||
}
|
||||
else if ( event.LeftIsDown() &&
|
||||
m_cursorMode == WXGRID_CURSOR_RESIZE_COL )
|
||||
{
|
||||
int cw, ch, dummy, top;
|
||||
m_gridWin->GetClientSize( &cw, &ch );
|
||||
CalcUnscrolledPosition( 0, 0, &dummy, &top );
|
||||
|
||||
wxClientDC dc( m_gridWin );
|
||||
PrepareDC( dc );
|
||||
x = wxMax( x, GetColLeft(m_dragRowOrCol) +
|
||||
GetColMinimalWidth(m_dragRowOrCol) );
|
||||
dc.SetLogicalFunction(wxINVERT);
|
||||
if ( m_dragLastPos >= 0 )
|
||||
{
|
||||
dc.DrawLine( m_dragLastPos, top, m_dragLastPos, top + ch );
|
||||
}
|
||||
dc.DrawLine( x, top, x, top + ch );
|
||||
m_dragLastPos = x;
|
||||
}
|
||||
|
||||
// event handled by user code, no need to do anything here
|
||||
return;
|
||||
}
|
||||
|
||||
m_isDragging = false;
|
||||
m_startDragPos = wxDefaultPosition;
|
||||
|
||||
// VZ: if we do this, the mode is reset to WXGRID_CURSOR_SELECT_CELL
|
||||
// immediately after it becomes WXGRID_CURSOR_RESIZE_ROW/COL under
|
||||
// wxGTK
|
||||
#if 0
|
||||
if ( event.Entering() || event.Leaving() )
|
||||
{
|
||||
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
|
||||
m_gridWin->SetCursor( *wxSTANDARD_CURSOR );
|
||||
}
|
||||
else
|
||||
#endif // 0
|
||||
|
||||
// ------------ Left button pressed
|
||||
//
|
||||
if ( event.LeftDown() && coords != wxGridNoCellCoords )
|
||||
{
|
||||
if ( !SendEvent( wxEVT_GRID_CELL_LEFT_CLICK,
|
||||
coords.GetRow(),
|
||||
coords.GetCol(),
|
||||
event ) )
|
||||
{
|
||||
if ( !event.CmdDown() )
|
||||
ClearSelection();
|
||||
|
||||
if ( event.ShiftDown() )
|
||||
{
|
||||
if ( m_selection )
|
||||
{
|
||||
m_selection->SelectBlock( m_currentCellCoords.GetRow(),
|
||||
m_currentCellCoords.GetCol(),
|
||||
coords.GetRow(),
|
||||
coords.GetCol(),
|
||||
m_selection->SelectBlock( m_currentCellCoords,
|
||||
coords,
|
||||
event.ControlDown(),
|
||||
event.ShiftDown(),
|
||||
event.AltDown(),
|
||||
event.MetaDown() );
|
||||
m_selectedBlockCorner = coords;
|
||||
}
|
||||
}
|
||||
else if ( XToEdgeOfCol(x) < 0 &&
|
||||
YToEdgeOfRow(y) < 0 )
|
||||
else if ( XToEdgeOfCol(pos.x) < 0 && YToEdgeOfRow(pos.y) < 0 )
|
||||
{
|
||||
DisableCellEditControl();
|
||||
MakeCellVisible( coords );
|
||||
@@ -6402,16 +6391,15 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
|
||||
{
|
||||
if ( m_selection )
|
||||
{
|
||||
m_selection->ToggleCellSelection( coords.GetRow(),
|
||||
coords.GetCol(),
|
||||
m_selection->ToggleCellSelection( coords,
|
||||
event.ControlDown(),
|
||||
event.ShiftDown(),
|
||||
event.AltDown(),
|
||||
event.MetaDown() );
|
||||
}
|
||||
m_selectingTopLeft = wxGridNoCellCoords;
|
||||
m_selectingBottomRight = wxGridNoCellCoords;
|
||||
m_selectingKeyboard = coords;
|
||||
m_selectedBlockTopLeft = wxGridNoCellCoords;
|
||||
m_selectedBlockBottomRight = wxGridNoCellCoords;
|
||||
m_selectedBlockCorner = coords;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -6420,33 +6408,27 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
|
||||
SetCurrentCell( coords );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------ Left double click
|
||||
//
|
||||
else if ( event.LeftDClick() && coords != wxGridNoCellCoords )
|
||||
void
|
||||
wxGrid::DoGridCellLeftDClick(wxMouseEvent& event,
|
||||
const wxGridCellCoords& coords,
|
||||
const wxPoint& pos)
|
||||
{
|
||||
if ( XToEdgeOfCol(pos.x) < 0 && YToEdgeOfRow(pos.y) < 0 )
|
||||
{
|
||||
DisableCellEditControl();
|
||||
|
||||
if ( XToEdgeOfCol(x) < 0 && YToEdgeOfRow(y) < 0 )
|
||||
{
|
||||
if ( !SendEvent( wxEVT_GRID_CELL_LEFT_DCLICK,
|
||||
coords.GetRow(),
|
||||
coords.GetCol(),
|
||||
event ) )
|
||||
if ( !SendEvent(wxEVT_GRID_CELL_LEFT_DCLICK, coords, event) )
|
||||
{
|
||||
// we want double click to select a cell and start editing
|
||||
// (i.e. to behave in same way as sequence of two slow clicks):
|
||||
m_waitForSlowClick = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------ Left button released
|
||||
//
|
||||
else if ( event.LeftUp() )
|
||||
{
|
||||
void
|
||||
wxGrid::DoGridCellLeftUp(wxMouseEvent& event, const wxGridCellCoords& coords)
|
||||
{
|
||||
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
|
||||
{
|
||||
if (m_winCapture)
|
||||
@@ -6469,23 +6451,21 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
|
||||
|
||||
m_waitForSlowClick = false;
|
||||
}
|
||||
else if ( m_selectingTopLeft != wxGridNoCellCoords &&
|
||||
m_selectingBottomRight != wxGridNoCellCoords )
|
||||
else if ( m_selectedBlockTopLeft != wxGridNoCellCoords &&
|
||||
m_selectedBlockBottomRight != wxGridNoCellCoords )
|
||||
{
|
||||
if ( m_selection )
|
||||
{
|
||||
m_selection->SelectBlock( m_selectingTopLeft.GetRow(),
|
||||
m_selectingTopLeft.GetCol(),
|
||||
m_selectingBottomRight.GetRow(),
|
||||
m_selectingBottomRight.GetCol(),
|
||||
m_selection->SelectBlock( m_selectedBlockTopLeft,
|
||||
m_selectedBlockBottomRight,
|
||||
event.ControlDown(),
|
||||
event.ShiftDown(),
|
||||
event.AltDown(),
|
||||
event.MetaDown() );
|
||||
}
|
||||
|
||||
m_selectingTopLeft = wxGridNoCellCoords;
|
||||
m_selectingBottomRight = wxGridNoCellCoords;
|
||||
m_selectedBlockTopLeft = wxGridNoCellCoords;
|
||||
m_selectedBlockBottomRight = wxGridNoCellCoords;
|
||||
|
||||
// Show the edit control, if it has been hidden for
|
||||
// drag-shrinking.
|
||||
@@ -6514,40 +6494,13 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
|
||||
}
|
||||
|
||||
m_dragLastPos = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------ Right button down
|
||||
//
|
||||
else if ( event.RightDown() && coords != wxGridNoCellCoords )
|
||||
{
|
||||
DisableCellEditControl();
|
||||
if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_CLICK,
|
||||
coords.GetRow(),
|
||||
coords.GetCol(),
|
||||
event ) )
|
||||
{
|
||||
// no default action at the moment
|
||||
}
|
||||
}
|
||||
|
||||
// ------------ Right double click
|
||||
//
|
||||
else if ( event.RightDClick() && coords != wxGridNoCellCoords )
|
||||
{
|
||||
DisableCellEditControl();
|
||||
if ( !SendEvent( wxEVT_GRID_CELL_RIGHT_DCLICK,
|
||||
coords.GetRow(),
|
||||
coords.GetCol(),
|
||||
event ) )
|
||||
{
|
||||
// no default action at the moment
|
||||
}
|
||||
}
|
||||
|
||||
// ------------ Moving and no button action
|
||||
//
|
||||
else if ( event.Moving() && !event.IsButton() )
|
||||
{
|
||||
void
|
||||
wxGrid::DoGridMouseMoveEvent(wxMouseEvent& WXUNUSED(event),
|
||||
const wxGridCellCoords& coords,
|
||||
const wxPoint& pos)
|
||||
{
|
||||
if ( coords.GetRow() < 0 || coords.GetCol() < 0 )
|
||||
{
|
||||
// out of grid cell area
|
||||
@@ -6555,8 +6508,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
|
||||
return;
|
||||
}
|
||||
|
||||
int dragRow = YToEdgeOfRow( y );
|
||||
int dragCol = XToEdgeOfCol( x );
|
||||
int dragRow = YToEdgeOfRow( pos.y );
|
||||
int dragCol = XToEdgeOfCol( pos.x );
|
||||
|
||||
// Dragging on the corner of a cell to resize in both
|
||||
// directions is not implemented yet...
|
||||
@@ -6594,6 +6547,76 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
|
||||
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event)
|
||||
{
|
||||
const wxPoint pos = CalcUnscrolledPosition(event.GetPosition());
|
||||
|
||||
// coordinates of the cell under mouse
|
||||
wxGridCellCoords coords = XYToCell(pos);
|
||||
|
||||
int cell_rows, cell_cols;
|
||||
GetCellSize( coords.GetRow(), coords.GetCol(), &cell_rows, &cell_cols );
|
||||
if ( (cell_rows < 0) || (cell_cols < 0) )
|
||||
{
|
||||
coords.SetRow(coords.GetRow() + cell_rows);
|
||||
coords.SetCol(coords.GetCol() + cell_cols);
|
||||
}
|
||||
|
||||
if ( event.Dragging() )
|
||||
{
|
||||
if ( event.LeftIsDown() )
|
||||
DoGridDragEvent(event, coords);
|
||||
else
|
||||
event.Skip();
|
||||
return;
|
||||
}
|
||||
|
||||
m_isDragging = false;
|
||||
m_startDragPos = wxDefaultPosition;
|
||||
|
||||
// VZ: if we do this, the mode is reset to WXGRID_CURSOR_SELECT_CELL
|
||||
// immediately after it becomes WXGRID_CURSOR_RESIZE_ROW/COL under
|
||||
// wxGTK
|
||||
#if 0
|
||||
if ( event.Entering() || event.Leaving() )
|
||||
{
|
||||
ChangeCursorMode(WXGRID_CURSOR_SELECT_CELL);
|
||||
m_gridWin->SetCursor( *wxSTANDARD_CURSOR );
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
// deal with various button presses
|
||||
if ( event.IsButton() )
|
||||
{
|
||||
if ( coords != wxGridNoCellCoords )
|
||||
{
|
||||
DisableCellEditControl();
|
||||
|
||||
if ( event.LeftDown() )
|
||||
DoGridCellLeftDown(event, coords, pos);
|
||||
else if ( event.LeftDClick() )
|
||||
DoGridCellLeftDClick(event, coords, pos);
|
||||
else if ( event.RightDown() )
|
||||
SendEvent(wxEVT_GRID_CELL_RIGHT_CLICK, coords, event);
|
||||
else if ( event.RightDClick() )
|
||||
SendEvent(wxEVT_GRID_CELL_RIGHT_DCLICK, coords, event);
|
||||
}
|
||||
|
||||
// this one should be called even if we're not over any cell
|
||||
if ( event.LeftUp() )
|
||||
{
|
||||
DoGridCellLeftUp(event, coords);
|
||||
}
|
||||
}
|
||||
else if ( event.Moving() )
|
||||
{
|
||||
DoGridMouseMoveEvent(event, coords, pos);
|
||||
}
|
||||
else // unknown mouse event?
|
||||
{
|
||||
event.Skip();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6883,12 +6906,14 @@ wxGrid::DoAppendLines(bool (wxGridTableBase::*funcAppend)(size_t),
|
||||
// ----- event handlers
|
||||
//
|
||||
|
||||
// Generate a grid event based on a mouse event and
|
||||
// return the result of ProcessEvent()
|
||||
//
|
||||
int wxGrid::SendEvent( const wxEventType type,
|
||||
// Generate a grid event based on a mouse event and return:
|
||||
// -1 if the event was vetoed
|
||||
// +1 if the event was processed (but not vetoed)
|
||||
// 0 if the event wasn't handled
|
||||
int
|
||||
wxGrid::SendEvent(const wxEventType type,
|
||||
int row, int col,
|
||||
wxMouseEvent& mouseEv )
|
||||
wxMouseEvent& mouseEv)
|
||||
{
|
||||
bool claimed, vetoed;
|
||||
|
||||
@@ -6916,8 +6941,8 @@ int wxGrid::SendEvent( const wxEventType type,
|
||||
wxGridRangeSelectEvent gridEvt( GetId(),
|
||||
type,
|
||||
this,
|
||||
m_selectingTopLeft,
|
||||
m_selectingBottomRight,
|
||||
m_selectedBlockTopLeft,
|
||||
m_selectedBlockBottomRight,
|
||||
true,
|
||||
mouseEv.ControlDown(),
|
||||
mouseEv.ShiftDown(),
|
||||
@@ -6977,11 +7002,9 @@ int wxGrid::SendEvent( const wxEventType type,
|
||||
return claimed ? 1 : 0;
|
||||
}
|
||||
|
||||
// Generate a grid event of specified type and return the result
|
||||
// of ProcessEvent().
|
||||
// Generate a grid event of specified type, return value same as above
|
||||
//
|
||||
int wxGrid::SendEvent( const wxEventType type,
|
||||
int row, int col )
|
||||
int wxGrid::SendEvent(const wxEventType type, int row, int col)
|
||||
{
|
||||
bool claimed, vetoed;
|
||||
|
||||
@@ -7224,8 +7247,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
|
||||
case WXK_HOME:
|
||||
if ( event.ControlDown() )
|
||||
{
|
||||
MakeCellVisible( 0, 0 );
|
||||
SetCurrentCell( 0, 0 );
|
||||
GoToCell(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -7236,8 +7258,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
|
||||
case WXK_END:
|
||||
if ( event.ControlDown() )
|
||||
{
|
||||
MakeCellVisible( m_numRows - 1, m_numCols - 1 );
|
||||
SetCurrentCell( m_numRows - 1, m_numCols - 1 );
|
||||
GoToCell(m_numRows - 1, m_numCols - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -7299,16 +7320,14 @@ void wxGrid::OnKeyUp( wxKeyEvent& event )
|
||||
//
|
||||
if ( event.GetKeyCode() == WXK_SHIFT )
|
||||
{
|
||||
if ( m_selectingTopLeft != wxGridNoCellCoords &&
|
||||
m_selectingBottomRight != wxGridNoCellCoords )
|
||||
if ( m_selectedBlockTopLeft != wxGridNoCellCoords &&
|
||||
m_selectedBlockBottomRight != wxGridNoCellCoords )
|
||||
{
|
||||
if ( m_selection )
|
||||
{
|
||||
m_selection->SelectBlock(
|
||||
m_selectingTopLeft.GetRow(),
|
||||
m_selectingTopLeft.GetCol(),
|
||||
m_selectingBottomRight.GetRow(),
|
||||
m_selectingBottomRight.GetCol(),
|
||||
m_selectedBlockTopLeft,
|
||||
m_selectedBlockBottomRight,
|
||||
event.ControlDown(),
|
||||
true,
|
||||
event.AltDown(),
|
||||
@@ -7316,9 +7335,9 @@ void wxGrid::OnKeyUp( wxKeyEvent& event )
|
||||
}
|
||||
}
|
||||
|
||||
m_selectingTopLeft = wxGridNoCellCoords;
|
||||
m_selectingBottomRight = wxGridNoCellCoords;
|
||||
m_selectingKeyboard = wxGridNoCellCoords;
|
||||
m_selectedBlockTopLeft = wxGridNoCellCoords;
|
||||
m_selectedBlockBottomRight = wxGridNoCellCoords;
|
||||
m_selectedBlockCorner = wxGridNoCellCoords;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7367,12 +7386,12 @@ void wxGrid::OnEraseBackground(wxEraseEvent&)
|
||||
{
|
||||
}
|
||||
|
||||
void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
|
||||
bool wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
|
||||
{
|
||||
if ( SendEvent( wxEVT_GRID_SELECT_CELL, coords.GetRow(), coords.GetCol() ) )
|
||||
if ( SendEvent(wxEVT_GRID_SELECT_CELL, coords) == -1 )
|
||||
{
|
||||
// the event has been intercepted - do nothing
|
||||
return;
|
||||
// the event has been vetoed - do nothing
|
||||
return false;
|
||||
}
|
||||
|
||||
#if !defined(__WXMAC__)
|
||||
@@ -7417,35 +7436,62 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
|
||||
DrawCellHighlight( dc, attr );
|
||||
#endif
|
||||
attr->DecRef();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void wxGrid::HighlightBlock(int topRow, int leftCol, int bottomRow, int rightCol)
|
||||
void
|
||||
wxGrid::UpdateBlockBeingSelected(int topRow, int leftCol,
|
||||
int bottomRow, int rightCol)
|
||||
{
|
||||
wxGridCellCoords updateTopLeft, updateBottomRight;
|
||||
|
||||
if ( m_selection )
|
||||
{
|
||||
if ( m_selection->GetSelectionMode() == wxGrid::wxGridSelectRows )
|
||||
switch ( m_selection->GetSelectionMode() )
|
||||
{
|
||||
default:
|
||||
wxFAIL_MSG( "unknown selection mode" );
|
||||
// fall through
|
||||
|
||||
case wxGridSelectCells:
|
||||
// arbitrary blocks selection allowed so just use the cell
|
||||
// coordinates as is
|
||||
break;
|
||||
|
||||
case wxGridSelectRows:
|
||||
// only full rows selection allowd, ensure that we do select
|
||||
// full rows
|
||||
leftCol = 0;
|
||||
rightCol = GetNumberCols() - 1;
|
||||
}
|
||||
else if ( m_selection->GetSelectionMode() == wxGrid::wxGridSelectColumns )
|
||||
{
|
||||
break;
|
||||
|
||||
case wxGridSelectColumns:
|
||||
// same as above but for columns
|
||||
topRow = 0;
|
||||
bottomRow = GetNumberRows() - 1;
|
||||
break;
|
||||
|
||||
case wxGridSelectRowsOrColumns:
|
||||
// in this mode we can select only full rows or full columns so
|
||||
// it doesn't make sense to select blocks at all (and we can't
|
||||
// extend the block because there is no preferred direction, we
|
||||
// could only extend it to cover the entire grid but this is
|
||||
// not useful)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
m_selectedBlockCorner = wxGridCellCoords(bottomRow, rightCol);
|
||||
MakeCellVisible(m_selectedBlockCorner);
|
||||
|
||||
EnsureFirstLessThanSecond(topRow, bottomRow);
|
||||
EnsureFirstLessThanSecond(leftCol, rightCol);
|
||||
|
||||
updateTopLeft = wxGridCellCoords( topRow, leftCol );
|
||||
updateBottomRight = wxGridCellCoords( bottomRow, rightCol );
|
||||
wxGridCellCoords updateTopLeft = wxGridCellCoords(topRow, leftCol),
|
||||
updateBottomRight = wxGridCellCoords(bottomRow, rightCol);
|
||||
|
||||
// First the case that we selected a completely new area
|
||||
if ( m_selectingTopLeft == wxGridNoCellCoords ||
|
||||
m_selectingBottomRight == wxGridNoCellCoords )
|
||||
if ( m_selectedBlockTopLeft == wxGridNoCellCoords ||
|
||||
m_selectedBlockBottomRight == wxGridNoCellCoords )
|
||||
{
|
||||
wxRect rect;
|
||||
rect = BlockToDeviceRect( wxGridCellCoords ( topRow, leftCol ),
|
||||
@@ -7454,8 +7500,8 @@ void wxGrid::HighlightBlock(int topRow, int leftCol, int bottomRow, int rightCol
|
||||
}
|
||||
|
||||
// Now handle changing an existing selection area.
|
||||
else if ( m_selectingTopLeft != updateTopLeft ||
|
||||
m_selectingBottomRight != updateBottomRight )
|
||||
else if ( m_selectedBlockTopLeft != updateTopLeft ||
|
||||
m_selectedBlockBottomRight != updateBottomRight )
|
||||
{
|
||||
// Compute two optimal update rectangles:
|
||||
// Either one rectangle is a real subset of the
|
||||
@@ -7469,10 +7515,10 @@ void wxGrid::HighlightBlock(int topRow, int leftCol, int bottomRow, int rightCol
|
||||
int i;
|
||||
|
||||
// Store intermediate values
|
||||
wxCoord oldLeft = m_selectingTopLeft.GetCol();
|
||||
wxCoord oldTop = m_selectingTopLeft.GetRow();
|
||||
wxCoord oldRight = m_selectingBottomRight.GetCol();
|
||||
wxCoord oldBottom = m_selectingBottomRight.GetRow();
|
||||
wxCoord oldLeft = m_selectedBlockTopLeft.GetCol();
|
||||
wxCoord oldTop = m_selectedBlockTopLeft.GetRow();
|
||||
wxCoord oldRight = m_selectedBlockBottomRight.GetCol();
|
||||
wxCoord oldBottom = m_selectedBlockBottomRight.GetRow();
|
||||
|
||||
// Determine the outer/inner coordinates.
|
||||
EnsureFirstLessThanSecond(oldLeft, leftCol);
|
||||
@@ -7531,8 +7577,8 @@ void wxGrid::HighlightBlock(int topRow, int leftCol, int bottomRow, int rightCol
|
||||
}
|
||||
|
||||
// change selection
|
||||
m_selectingTopLeft = updateTopLeft;
|
||||
m_selectingBottomRight = updateBottomRight;
|
||||
m_selectedBlockTopLeft = updateTopLeft;
|
||||
m_selectedBlockBottomRight = updateBottomRight;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -8371,7 +8417,7 @@ void wxGrid::EnableCellEditControl( bool enable )
|
||||
{
|
||||
if ( enable )
|
||||
{
|
||||
if (SendEvent( wxEVT_GRID_EDITOR_SHOWN) <0)
|
||||
if ( SendEvent(wxEVT_GRID_EDITOR_SHOWN) == -1 )
|
||||
return;
|
||||
|
||||
// this should be checked by the caller!
|
||||
@@ -8385,7 +8431,7 @@ void wxGrid::EnableCellEditControl( bool enable )
|
||||
else
|
||||
{
|
||||
//FIXME:add veto support
|
||||
SendEvent( wxEVT_GRID_EDITOR_HIDDEN );
|
||||
SendEvent(wxEVT_GRID_EDITOR_HIDDEN);
|
||||
|
||||
HideCellEditControl();
|
||||
SaveEditControlValue();
|
||||
@@ -8624,9 +8670,7 @@ void wxGrid::SaveEditControlValue()
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if ( SendEvent( wxEVT_GRID_CELL_CHANGE,
|
||||
m_currentCellCoords.GetRow(),
|
||||
m_currentCellCoords.GetCol() ) < 0 )
|
||||
if ( SendEvent(wxEVT_GRID_CELL_CHANGE) == -1 )
|
||||
{
|
||||
// Event has been vetoed, set the data back.
|
||||
SetCellValue(row, col, oldval);
|
||||
@@ -8642,19 +8686,13 @@ void wxGrid::SaveEditControlValue()
|
||||
// coordinates for mouse events etc.
|
||||
//
|
||||
|
||||
void wxGrid::XYToCell( int x, int y, wxGridCellCoords& coords ) const
|
||||
wxGridCellCoords wxGrid::XYToCell(int x, int y) const
|
||||
{
|
||||
int row = YToRow(y);
|
||||
int col = XToCol(x);
|
||||
|
||||
if ( row == -1 || col == -1 )
|
||||
{
|
||||
coords = wxGridNoCellCoords;
|
||||
}
|
||||
else
|
||||
{
|
||||
coords.Set( row, col );
|
||||
}
|
||||
return row == -1 || col == -1 ? wxGridNoCellCoords
|
||||
: wxGridCellCoords(row, col);
|
||||
}
|
||||
|
||||
// compute row or column from some (unscrolled) coordinate value, using either
|
||||
@@ -8957,28 +8995,28 @@ wxGrid::DoMoveCursor(bool expandSelection,
|
||||
|
||||
if ( expandSelection )
|
||||
{
|
||||
if ( m_selectingKeyboard == wxGridNoCellCoords )
|
||||
m_selectingKeyboard = m_currentCellCoords;
|
||||
wxGridCellCoords coords = m_selectedBlockCorner;
|
||||
if ( coords == wxGridNoCellCoords )
|
||||
coords = m_currentCellCoords;
|
||||
|
||||
if ( diroper.IsAtBoundary(m_selectingKeyboard) )
|
||||
if ( diroper.IsAtBoundary(coords) )
|
||||
return false;
|
||||
|
||||
diroper.Advance(m_selectingKeyboard);
|
||||
diroper.Advance(coords);
|
||||
|
||||
MakeCellVisible(m_selectingKeyboard);
|
||||
HighlightBlock(m_currentCellCoords, m_selectingKeyboard);
|
||||
UpdateBlockBeingSelected(m_currentCellCoords, coords);
|
||||
}
|
||||
else
|
||||
else // don't expand selection
|
||||
{
|
||||
ClearSelection();
|
||||
|
||||
if ( diroper.IsAtBoundary(m_currentCellCoords) )
|
||||
return false;
|
||||
|
||||
ClearSelection();
|
||||
|
||||
wxGridCellCoords coords = m_currentCellCoords;
|
||||
diroper.Advance(coords);
|
||||
MakeCellVisible(coords);
|
||||
SetCurrentCell(coords);
|
||||
|
||||
GoToCell(coords);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -9025,8 +9063,7 @@ bool wxGrid::DoMoveCursorByPage(const wxGridDirectionOperations& diroper)
|
||||
newRow = coords.GetRow();
|
||||
}
|
||||
|
||||
MakeCellVisible(newRow, m_currentCellCoords.GetCol());
|
||||
SetCurrentCell(newRow, m_currentCellCoords.GetCol());
|
||||
GoToCell(newRow, m_currentCellCoords.GetCol());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -9097,16 +9134,14 @@ wxGrid::DoMoveCursorByBlock(bool expandSelection,
|
||||
}
|
||||
}
|
||||
|
||||
MakeCellVisible(coords);
|
||||
if ( expandSelection )
|
||||
{
|
||||
m_selectingKeyboard = coords;
|
||||
HighlightBlock(m_currentCellCoords, m_selectingKeyboard);
|
||||
UpdateBlockBeingSelected(m_currentCellCoords, coords);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearSelection();
|
||||
SetCurrentCell(coords);
|
||||
GoToCell(coords);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -10718,17 +10753,17 @@ void wxGrid::DeselectCell( int row, int col )
|
||||
bool wxGrid::IsSelection() const
|
||||
{
|
||||
return ( m_selection && (m_selection->IsSelection() ||
|
||||
( m_selectingTopLeft != wxGridNoCellCoords &&
|
||||
m_selectingBottomRight != wxGridNoCellCoords) ) );
|
||||
( m_selectedBlockTopLeft != wxGridNoCellCoords &&
|
||||
m_selectedBlockBottomRight != wxGridNoCellCoords) ) );
|
||||
}
|
||||
|
||||
bool wxGrid::IsInSelection( int row, int col ) const
|
||||
{
|
||||
return ( m_selection && (m_selection->IsInSelection( row, col ) ||
|
||||
( row >= m_selectingTopLeft.GetRow() &&
|
||||
col >= m_selectingTopLeft.GetCol() &&
|
||||
row <= m_selectingBottomRight.GetRow() &&
|
||||
col <= m_selectingBottomRight.GetCol() )) );
|
||||
( row >= m_selectedBlockTopLeft.GetRow() &&
|
||||
col >= m_selectedBlockTopLeft.GetCol() &&
|
||||
row <= m_selectedBlockBottomRight.GetRow() &&
|
||||
col <= m_selectedBlockBottomRight.GetCol() )) );
|
||||
}
|
||||
|
||||
wxGridCellCoordsArray wxGrid::GetSelectedCells() const
|
||||
@@ -10788,13 +10823,18 @@ wxArrayInt wxGrid::GetSelectedCols() const
|
||||
|
||||
void wxGrid::ClearSelection()
|
||||
{
|
||||
wxRect r1 = BlockToDeviceRect( m_selectingTopLeft, m_selectingBottomRight);
|
||||
wxRect r2 = BlockToDeviceRect( m_currentCellCoords, m_selectingKeyboard );
|
||||
m_selectingTopLeft =
|
||||
m_selectingBottomRight =
|
||||
m_selectingKeyboard = wxGridNoCellCoords;
|
||||
wxRect r1 = BlockToDeviceRect(m_selectedBlockTopLeft,
|
||||
m_selectedBlockBottomRight);
|
||||
wxRect r2 = BlockToDeviceRect(m_currentCellCoords,
|
||||
m_selectedBlockCorner);
|
||||
|
||||
m_selectedBlockTopLeft =
|
||||
m_selectedBlockBottomRight =
|
||||
m_selectedBlockCorner = wxGridNoCellCoords;
|
||||
|
||||
Refresh( false, &r1 );
|
||||
Refresh( false, &r2 );
|
||||
|
||||
if ( m_selection )
|
||||
m_selection->ClearSelection();
|
||||
}
|
||||
|
@@ -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 )
|
||||
{
|
||||
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;
|
||||
}
|
||||
else if ( m_selectionMode == wxGrid::wxGridSelectColumns )
|
||||
{
|
||||
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 )
|
||||
|
Reference in New Issue
Block a user