wxDEFINE_EVENT( wxEVT_GRID_EDITOR_SHOWN, wxGridEvent );
wxDEFINE_EVENT( wxEVT_GRID_EDITOR_HIDDEN, wxGridEvent );
wxDEFINE_EVENT( wxEVT_GRID_EDITOR_CREATED, wxGridEditorCreatedEvent );
+wxDEFINE_EVENT( wxEVT_GRID_TABBING, wxGridEvent );
// ----------------------------------------------------------------------------
// private helpers
m_created = true;
}
+ InvalidateBestSize();
+
return m_created;
}
// now anyhow, so just set the parameters directly
m_xScrollPixelsPerLine = GRID_SCROLL_LINE_X;
m_yScrollPixelsPerLine = GRID_SCROLL_LINE_Y;
+
+ m_tabBehaviour = Tab_Stop;
}
// ----------------------------------------------------------------------------
if ( !m_colAt.IsEmpty() )
{
//Shift the column IDs
- int i;
for ( i = 0; i < m_numCols - numCols; i++ )
{
if ( m_colAt[i] >= (int)pos )
m_colAt.Add( 0, numCols );
//Set the new columns' positions
- int i;
for ( i = oldNumCols; i < m_numCols; i++ )
{
m_colAt[i] = i;
break;
}
+ InvalidateBestSize();
+
if (result && !GetBatchCount() )
m_gridWin->Refresh();
void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event )
{
- int x, y;
- wxPoint pos( event.GetPosition() );
- CalcUnscrolledPosition( pos.x, pos.y, &x, &y );
+ int x;
+ CalcUnscrolledPosition( event.GetPosition().x, 0, &x, NULL );
int col = XToCol(x);
if ( event.Dragging() )
//
else if ( event.LeftDown() )
{
- int col = XToEdgeOfCol(x);
- if ( col != wxNOT_FOUND && CanDragColSize(col) )
+ int colEdge = XToEdgeOfCol(x);
+ if ( colEdge != wxNOT_FOUND && CanDragColSize(colEdge) )
{
ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, GetColLabelWindow());
}
else // not a request to start resizing
{
- col = XToCol(x);
if ( col >= 0 &&
!SendEvent( wxEVT_GRID_LABEL_LEFT_CLICK, -1, col, event ) )
{
oper.SelectSize(rect) = oper.Select(size);
int subtractLines = 0;
- const int lineStart = doper.PosToLine(this, posLineStart);
- if ( lineStart >= 0 )
+ int line = doper.PosToLine(this, posLineStart);
+ if ( line >= 0 )
{
// ensure that if we have a multi-cell block we redraw all of
// it by increasing the refresh area to cover it entirely if a
// part of it is affected
const int lineEnd = doper.PosToLine(this, posLineEnd, true);
- for ( int line = lineStart; line < lineEnd; line++ )
+ for ( ; line < lineEnd; line++ )
{
int cellLines = oper.Select(
GetCellSize(oper.MakeCoords(m_dragRowOrCol, line)));
break;
case WXK_TAB:
- if (event.ShiftDown())
- {
- if ( GetGridCursorCol() > 0 )
- {
- MoveCursorLeft( false );
- }
- else
- {
- // at left of grid
- DisableCellEditControl();
- }
- }
- else
{
- if ( GetGridCursorCol() < GetNumberCols() - 1 )
+ // send an event to the grid's parents for custom handling
+ wxGridEvent gridEvt(GetId(), wxEVT_GRID_TABBING, this,
+ GetGridCursorRow(), GetGridCursorCol(),
+ -1, -1, false, event);
+ if ( ProcessWindowEvent(gridEvt) )
{
- MoveCursorRight( false );
- }
- else
- {
- // at right of grid
- DisableCellEditControl();
+ // the event has been handled so no need for more processing
+ break;
}
}
+ DoGridProcessTab( event );
break;
case WXK_HOME:
{
}
+void wxGrid::DoGridProcessTab(wxKeyboardState& kbdState)
+{
+ const bool isForwardTab = !kbdState.ShiftDown();
+
+ // TAB processing only changes when we are at the borders of the grid, so
+ // let's first handle the common behaviour when we are not at the border.
+ if ( isForwardTab )
+ {
+ if ( GetGridCursorCol() < GetNumberCols() - 1 )
+ {
+ MoveCursorRight( false );
+ return;
+ }
+ }
+ else // going back
+ {
+ if ( GetGridCursorCol() )
+ {
+ MoveCursorLeft( false );
+ return;
+ }
+ }
+
+
+ // We only get here if the cursor is at the border of the grid, apply the
+ // configured behaviour.
+ switch ( m_tabBehaviour )
+ {
+ case Tab_Stop:
+ // Nothing special to do, we remain at the current cell.
+ break;
+
+ case Tab_Wrap:
+ // Go to the beginning of the next or the end of the previous row.
+ if ( isForwardTab )
+ {
+ if ( GetGridCursorRow() < GetNumberRows() - 1 )
+ {
+ GoToCell( GetGridCursorRow() + 1, 0 );
+ return;
+ }
+ }
+ else
+ {
+ if ( GetGridCursorRow() > 0 )
+ {
+ GoToCell( GetGridCursorRow() - 1, GetNumberCols() - 1 );
+ return;
+ }
+ }
+ break;
+
+ case Tab_Leave:
+ if ( Navigate( isForwardTab ? wxNavigationKeyEvent::IsForward
+ : wxNavigationKeyEvent::IsBackward ) )
+ return;
+ break;
+ }
+
+ // If we remain in this cell, stop editing it if we were doing so.
+ DisableCellEditControl();
+}
+
bool wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
{
if ( SendEvent(wxEVT_GRID_SELECT_CELL, coords) == -1 )
// implicitly, causing this out-of order render.
#if !defined(__WXMAC__)
wxGridCellEditor *editor = attr->GetEditor(this, row, col);
- editor->PaintBackground(rect, attr);
+ editor->PaintBackground(dc, rect, *attr);
editor->DecRef();
#endif
}
return PosToLinePos(x, true /* clip */, wxGridColumnOperations());
}
-// return the row number such that the y coord is near the edge of, or -1 if
+// return the row/col number such that the pos is near the edge of, or -1 if
// not near an edge.
//
// notice that position can only possibly be near an edge if the row/column is
// _never_ be considered to be near the edge).
int wxGrid::PosToEdgeOfLine(int pos, const wxGridOperations& oper) const
{
- const int line = oper.PosToLine(this, pos, true);
+ // Get the bottom or rightmost line that could match.
+ int line = oper.PosToLine(this, pos, true);
if ( oper.GetLineSize(this, line) > WXGRID_LABEL_EDGE_ZONE )
{
pos - oper.GetLineStartPos(this,
line) < WXGRID_LABEL_EDGE_ZONE )
{
- return oper.GetLineBefore(this, line);
+ // We need to find the previous visible line, so skip all the
+ // hidden (of size 0) ones.
+ do
+ {
+ line = oper.GetLineBefore(this, line);
+ }
+ while ( line >= 0 && oper.GetLineSize(this, line) == 0 );
+
+ // It can possibly be -1 here.
+ return line;
}
}
}
m_rowLabelWidth = width;
+ InvalidateBestSize();
CalcWindowSizes();
wxScrolledWindow::Refresh( true );
}
}
m_colLabelHeight = height;
+ InvalidateBestSize();
CalcWindowSizes();
wxScrolledWindow::Refresh( true );
}
// We're showing back a previously hidden row/column.
wxASSERT_MSG( sizeNew == -1, wxS("New size must be positive or -1.") );
- wxASSERT_MSG( sizeCurrent < 0, wxS("May only show back if hidden.") );
+ // If it's already visible, simply do nothing.
+ if ( sizeCurrent >= 0 )
+ return 0;
+ // Otherwise show it by restoring its old size.
sizeCurrent = -sizeCurrent;
// This is positive which is correct.
else if ( sizeNew == 0 )
{
// We're hiding a row/column.
- wxASSERT_MSG( sizeCurrent > 0, wxS("Can't hide if already hidden.") );
+ // If it's already hidden, simply do nothing.
+ if ( sizeCurrent <= 0 )
+ return 0;
+
+ // Otherwise hide it and also remember the shown size to be able to
+ // restore it later.
sizeCurrent = -sizeCurrent;
// This is negative which is correct.
// The value of -1 is special and means to fit the height to the row label.
if ( height == -1 )
{
+ // As with the columns, ignore attempts to auto-size the hidden rows.
+ if ( GetRowHeight(row) == 0 )
+ return;
+
long w, h;
wxArrayString lines;
wxClientDC dc(m_rowLabelWin);
m_rowBottoms[i] += diff;
}
+ InvalidateBestSize();
+
if ( !GetBatchCount() )
{
CalcDimensions();
// The value of -1 is special and means to fit the width to the column label.
if ( width == -1 )
{
+ // We currently don't support auto-sizing hidden columns. We could, but
+ // it's not clear whether this is really needed and it would make the
+ // code more complex.
+ if ( GetColWidth(col) == 0 )
+ return;
+
long w, h;
wxArrayString lines;
wxClientDC dc(m_colWindow);
m_colRights[GetColAt(colPos)] += diff;
}
+ InvalidateBestSize();
+
if ( !GetBatchCount() )
{
CalcDimensions();
{
const bool column = direction == wxGRID_COLUMN;
+ // We don't support auto-sizing hidden rows or columns, this doesn't seem
+ // to make much sense.
+ if ( column )
+ {
+ if ( GetColWidth(colOrRow) == 0 )
+ return;
+ }
+ else
+ {
+ if ( GetRowHeight(colOrRow) == 0 )
+ return;
+ }
+
wxClientDC dc(m_gridWin);
// cancel editing of cell
row = rowOrCol;
col = colOrRow;
}
- else
+ else
{
row = colOrRow;
col = rowOrCol;
wxSize size(self->SetOrCalcColumnSizes(true) - m_rowLabelWidth + m_extraWidth,
self->SetOrCalcRowSizes(true) - m_colLabelHeight + m_extraHeight);
- // NOTE: This size should be cached, but first we need to add calls to
- // InvalidateBestSize everywhere that could change the results of this
- // calculation.
- // CacheBestSize(size);
-
return wxSize(size.x + m_rowLabelWidth, size.y + m_colLabelHeight)
+ GetWindowBorderSize();
}