X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/cfbc15ee049cbd53366d5770240c06b621de18e1..033a5ff5c71ee7e787a3bc7e9be55ca0f5d80fa1:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 04fbd31efe..0968444786 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -170,6 +170,8 @@ END_EVENT_TABLE() BEGIN_EVENT_TABLE(wxGridHeaderCtrl, wxHeaderCtrl) EVT_HEADER_CLICK(wxID_ANY, wxGridHeaderCtrl::OnClick) + EVT_HEADER_DCLICK(wxID_ANY, wxGridHeaderCtrl::OnDoubleClick) + EVT_HEADER_RIGHT_CLICK(wxID_ANY, wxGridHeaderCtrl::OnRightClick) EVT_HEADER_BEGIN_RESIZE(wxID_ANY, wxGridHeaderCtrl::OnBeginResize) EVT_HEADER_RESIZING(wxID_ANY, wxGridHeaderCtrl::OnResizing) @@ -1911,7 +1913,6 @@ bool wxGrid::Create(wxWindow *parent, wxWindowID id, Create(); SetInitialSize(size); - SetScrollRate(m_scrollLineX, m_scrollLineY); CalcDimensions(); return true; @@ -2100,8 +2101,7 @@ wxGrid::SetTable(wxGridTableBase *table, m_table = NULL; } - delete m_selection; - m_selection = NULL; + wxDELETE(m_selection); m_ownTable = false; m_numRows = 0; @@ -2250,8 +2250,11 @@ void wxGrid::Init() m_extraWidth = m_extraHeight = 0; - m_scrollLineX = GRID_SCROLL_LINE_X; - m_scrollLineY = GRID_SCROLL_LINE_Y; + // we can't call SetScrollRate() as the window isn't created yet but OTOH + // we don't need to call it neither as the scroll position is (0, 0) right + // now anyhow, so just set the parameters directly + m_xScrollPixelsPerLine = GRID_SCROLL_LINE_X; + m_yScrollPixelsPerLine = GRID_SCROLL_LINE_Y; } // ---------------------------------------------------------------------------- @@ -3469,7 +3472,34 @@ void wxGrid::ProcessColLabelMouseEvent( wxMouseEvent& event ) } else { - DoEndMoveCol(XToPos(x)); + // get the position of the column we're over + int pos = XToPos(x); + + // we may need to adjust the drop position but don't bother + // checking for it if we can't anyhow + if ( pos > 1 ) + { + // also find the index of the column we're over: notice + // that the existing "col" variable may be invalid but + // we need a valid one here + const int colValid = GetColAt(pos); + + // if we're on the "near" (usually left but right in + // RTL case) part of the column, the actual position we + // should be placed in is actually the one before it + bool onNearPart; + const int middle = GetColLeft(colValid) + + GetColWidth(colValid)/2; + if ( GetLayoutDirection() == wxLayout_LeftToRight ) + onNearPart = (x <= middle); + else // wxLayout_RightToLeft + onNearPart = (x > middle); + + if ( onNearPart ) + pos--; + } + + DoEndMoveCol(pos); } break; @@ -3582,7 +3612,7 @@ void wxGrid::ChangeCursorMode(CursorMode mode, bool captureMouse) { #if wxUSE_LOG_TRACE - static const wxChar *cursorModes[] = + static const wxChar *const cursorModes[] = { wxT("SELECT_CELL"), wxT("RESIZE_ROW"), @@ -3765,6 +3795,8 @@ void wxGrid::DoGridDragEvent(wxMouseEvent& event, const wxGridCellCoords& coords if ( isFirstDrag ) { + wxASSERT_MSG( !m_winCapture, "shouldn't capture the mouse twice" ); + m_winCapture = m_gridWin; m_winCapture->CaptureMouse(); } @@ -3810,6 +3842,29 @@ wxGrid::DoGridCellLeftDown(wxMouseEvent& event, } else { + if ( m_selection ) + { + // In row or column selection mode just clicking on the cell + // should select the row or column containing it: this is more + // convenient for the kinds of controls that use such selection + // mode and is compatible with 2.8 behaviour (see #12062). + switch ( m_selection->GetSelectionMode() ) + { + case wxGridSelectCells: + case wxGridSelectRowsOrColumns: + // nothing to do in these cases + break; + + case wxGridSelectRows: + m_selection->SelectRow(coords.GetRow()); + break; + + case wxGridSelectColumns: + m_selection->SelectCol(coords.GetCol()); + break; + } + } + m_waitForSlowClick = m_currentCellCoords == coords && coords != wxGridNoCellCoords; SetCurrentCell( coords ); @@ -3944,6 +3999,14 @@ wxGrid::DoGridMouseMoveEvent(wxMouseEvent& WXUNUSED(event), void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event) { + if ( event.Entering() || event.Leaving() ) + { + // we don't care about these events but we must not reset m_isDragging + // if they happen so return before anything else is done + event.Skip(); + return; + } + const wxPoint pos = CalcUnscrolledPosition(event.GetPosition()); // coordinates of the cell under mouse @@ -3969,17 +4032,6 @@ void wxGrid::ProcessGridCellMouseEvent(wxMouseEvent& event) 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() ) { @@ -4621,25 +4673,15 @@ void wxGrid::OnKeyDown( wxKeyEvent& event ) break; case WXK_HOME: - if ( event.ControlDown() ) - { - GoToCell(0, 0); - } - else - { - event.Skip(); - } + GoToCell(event.ControlDown() ? 0 + : m_currentCellCoords.GetRow(), + 0); break; case WXK_END: - if ( event.ControlDown() ) - { - GoToCell(m_numRows - 1, m_numCols - 1); - } - else - { - event.Skip(); - } + GoToCell(event.ControlDown() ? m_numRows - 1 + : m_currentCellCoords.GetRow(), + m_numCols - 1); break; case WXK_PAGEUP: @@ -5573,6 +5615,11 @@ void wxGrid::DrawColLabel(wxDC& dc, int col) } else { + // It is reported that we need to erase the background to avoid display + // artefacts, see #12055. + wxDCBrushChanger setBrush(dc, m_colWindow->GetBackgroundColour()); + dc.DrawRectangle(rect); + rend.DrawBorder(*this, dc, rect); } @@ -6362,7 +6409,7 @@ void wxGrid::MakeCellVisible( int row, int col ) // // Sometimes GRID_SCROLL_LINE / 2 is not enough, // so just add a full scroll unit... - ypos += m_scrollLineY; + ypos += m_yScrollPixelsPerLine; } // special handling for wide cells - show always left part of the cell! @@ -6381,15 +6428,15 @@ void wxGrid::MakeCellVisible( int row, int col ) xpos = x0 + (right - cw); // see comment for ypos above - xpos += m_scrollLineX; + xpos += m_xScrollPixelsPerLine; } if ( xpos != -1 || ypos != -1 ) { if ( xpos != -1 ) - xpos /= m_scrollLineX; + xpos /= m_xScrollPixelsPerLine; if ( ypos != -1 ) - ypos /= m_scrollLineY; + ypos /= m_yScrollPixelsPerLine; Scroll( xpos, ypos ); AdjustScrollbars(); } @@ -7139,11 +7186,21 @@ bool wxGrid::GetCellOverflow( int row, int col ) const return allow; } -void wxGrid::GetCellSize( int row, int col, int *num_rows, int *num_cols ) const +wxGrid::CellSpan +wxGrid::GetCellSize( int row, int col, int *num_rows, int *num_cols ) const { wxGridCellAttr *attr = GetCellAttr(row, col); attr->GetSize( num_rows, num_cols ); attr->DecRef(); + + if ( *num_rows == 1 && *num_cols == 1 ) + return CellSpan_None; // just a normal cell + + if ( *num_rows < 0 || *num_cols < 0 ) + return CellSpan_Inside; // covered by a multi-span cell + + // this cell spans multiple cells to its right/bottom + return CellSpan_Main; } wxGridCellRenderer* wxGrid::GetCellRenderer(int row, int col) const @@ -7802,13 +7859,20 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction) HideCellEditControl(); SaveEditControlValue(); - // init both of them to avoid compiler warnings, even if we only need one - int row = -1, - col = -1; + // initialize both of them just to avoid compiler warnings even if only + // really needs to be initialized here + int row, + col; if ( column ) + { + row = -1; col = colOrRow; + } else + { row = colOrRow; + col = -1; + } wxCoord extent, extentMax = 0; int max = column ? m_numRows : m_numCols; @@ -7819,12 +7883,41 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction) else col = rowOrCol; + // we need to account for the cells spanning multiple columns/rows: + // while they may need a lot of space, they don't need all of it in + // this column/row + int numRows, numCols; + const CellSpan span = GetCellSize(row, col, &numRows, &numCols); + if ( span == CellSpan_Inside ) + { + // we need to get the size of the main cell, not of a cell hidden + // by it + row += numRows; + col += numCols; + + // get the size of the main cell too + GetCellSize(row, col, &numRows, &numCols); + } + wxGridCellAttr *attr = GetCellAttr(row, col); wxGridCellRenderer *renderer = attr->GetRenderer(this, row, col); if ( renderer ) { wxSize size = renderer->GetBestSize(*this, *attr, dc, row, col); extent = column ? size.x : size.y; + + if ( span != CellSpan_None ) + { + // we spread the size of a spanning cell over all the cells it + // covers evenly -- this is probably not ideal but we can't + // really do much better here + // + // notice that numCols and numRows are never 0 as they + // correspond to the size of the main cell of the span and not + // of the cell inside it + extent /= column ? numCols : numRows; + } + if ( extent > extentMax ) extentMax = extent; @@ -8026,10 +8119,8 @@ void wxGrid::AutoSize() // we know that we're not going to have scrollbars so disable them now to // avoid trouble in SetClientSize() which can otherwise set the correct // client size but also leave space for (not needed any more) scrollbars - SetScrollbars(0, 0, 0, 0, 0, 0, true); - - // restore the scroll rate parameters overwritten by SetScrollbars() - SetScrollRate(m_scrollLineX, m_scrollLineY); + SetScrollbars(m_xScrollPixelsPerLine, m_yScrollPixelsPerLine, + 0, 0, 0, 0, true); SetClientSize(size.x + m_rowLabelWidth, size.y + m_colLabelHeight); }