X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/670d01778a69731665cbb7c77726f067a1c8ce17..38914d5a514fffc34111a33a01a55bd42e135a54:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index d19952c919..887ba87cf0 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -476,6 +476,15 @@ void wxGridCellAttr::GetAlignment(int *hAlign, int *vAlign) const } } +void wxGridCellAttr::GetNonDefaultAlignment(int *hAlign, int *vAlign) const +{ + if ( hAlign && m_hAlign != wxALIGN_INVALID ) + *hAlign = m_hAlign; + + if ( vAlign && m_vAlign != wxALIGN_INVALID ) + *vAlign = m_vAlign; +} + void wxGridCellAttr::GetSize( int *num_rows, int *num_cols ) const { if ( num_rows ) @@ -2091,8 +2100,7 @@ wxGrid::SetTable(wxGridTableBase *table, m_table = NULL; } - delete m_selection; - m_selection = NULL; + wxDELETE(m_selection); m_ownTable = false; m_numRows = 0; @@ -3460,7 +3468,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; @@ -3573,7 +3608,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"), @@ -3756,6 +3791,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(); } @@ -3801,6 +3838,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 ); @@ -3935,6 +3995,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 @@ -3960,17 +4028,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() ) { @@ -5443,9 +5500,15 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row ) wxGridCellAttrProvider * const attrProvider = m_table ? m_table->GetAttrProvider() : NULL; + + // notice that an explicit static_cast is needed to avoid a compilation + // error with VC7.1 which, for some reason, tries to instantiate (abstract) + // wxGridRowHeaderRenderer class without it const wxGridRowHeaderRenderer& rend = attrProvider ? attrProvider->GetRowHeaderRenderer(row) - : gs_defaultHeaderRenderers.rowRenderer; + : static_cast + (gs_defaultHeaderRenderers.rowRenderer); + wxRect rect(0, GetRowTop(row), m_rowLabelWidth, GetRowHeight(row)); rend.DrawBorder(*this, dc, rect); @@ -5518,7 +5581,8 @@ void wxGrid::DrawCornerLabel(wxDC& dc) attrProvider = m_table ? m_table->GetAttrProvider() : NULL; const wxGridCornerHeaderRenderer& rend = attrProvider ? attrProvider->GetCornerRenderer() - : gs_defaultHeaderRenderers.cornerRenderer; + : static_cast + (gs_defaultHeaderRenderers.cornerRenderer); rend.DrawBorder(*this, dc, rect); } @@ -5536,7 +5600,8 @@ void wxGrid::DrawColLabel(wxDC& dc, int col) attrProvider = m_table ? m_table->GetAttrProvider() : NULL; const wxGridColumnHeaderRenderer& rend = attrProvider ? attrProvider->GetColumnHeaderRenderer(col) - : gs_defaultHeaderRenderers.colRenderer; + : static_cast + (gs_defaultHeaderRenderers.colRenderer); if ( m_nativeColumnLabels ) { @@ -5556,6 +5621,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); } @@ -7122,11 +7192,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 @@ -7785,22 +7865,40 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction) HideCellEditControl(); SaveEditControlValue(); - // init both of them to avoid compiler warnings, even if we only need one + // initialize both of them just to avoid compiler warnings int row = -1, col = -1; - if ( column ) - col = colOrRow; - else - row = colOrRow; wxCoord extent, extentMax = 0; int max = column ? m_numRows : m_numCols; for ( int rowOrCol = 0; rowOrCol < max; rowOrCol++ ) { if ( column ) + { row = rowOrCol; + col = colOrRow; + } else + { + row = colOrRow; 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); @@ -7808,6 +7906,19 @@ wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction) { 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;