diff --git a/include/wx/renderer.h b/include/wx/renderer.h index 3fe946139d..627c142e12 100644 --- a/include/wx/renderer.h +++ b/include/wx/renderer.h @@ -62,6 +62,7 @@ enum wxCONTROL_EXPANDED = wxCONTROL_SPECIAL, // only for the tree items wxCONTROL_SIZEGRIP = wxCONTROL_SPECIAL, // only for the status bar panes wxCONTROL_FLAT = wxCONTROL_SPECIAL, // checkboxes only: flat border + wxCONTROL_CELL = wxCONTROL_SPECIAL, // only for item selection rect wxCONTROL_CURRENT = 0x00000010, // mouse is currently over the control wxCONTROL_SELECTED = 0x00000020, // selected item in e.g. listbox wxCONTROL_CHECKED = 0x00000040, // (check/radio button) is checked diff --git a/interface/wx/renderer.h b/interface/wx/renderer.h index ee71ee992b..07a8a82755 100644 --- a/interface/wx/renderer.h +++ b/interface/wx/renderer.h @@ -46,6 +46,9 @@ enum /** Checkboxes only: flat border. */ wxCONTROL_FLAT = wxCONTROL_SPECIAL, + /** Item selection rect only: cell inside selection. */ + wxCONTROL_CELL = wxCONTROL_SPECIAL, + /** Mouse is currently over the control. */ wxCONTROL_CURRENT = 0x00000010, @@ -404,7 +407,8 @@ public: @c wxCONTROL_FOCUSED may be used to indicate if the control has the focus (otherwise the selection rectangle is e.g. often grey and not blue). This may be ignored by the renderer or deduced by the code directly from - the @a win. + the @a win. Additionally @c wxCONTROL_CELL may be used to draw a cell inside + a bigger selection area. @see DrawItemText() */ diff --git a/src/generic/datavgen.cpp b/src/generic/datavgen.cpp index 316f0609d8..f369504ada 100644 --- a/src/generic/datavgen.cpp +++ b/src/generic/datavgen.cpp @@ -1801,44 +1801,6 @@ wxBitmap wxDataViewMainWindow::CreateItemBitmap( unsigned int row, int &indent ) #endif // wxUSE_DRAG_AND_DROP - -// Draw focus rect for individual cell. Unlike native focus rect, we render -// this in foreground text color (typically white) to enhance contrast and -// make it visible. -static void DrawSelectedCellFocusRect(wxDC& dc, const wxRect& rect) -{ - // (This code is based on wxRendererGeneric::DrawFocusRect and modified.) - - // draw the pixels manually because the "dots" in wxPen with wxDOT style - // may be short traits and not really dots - // - // note that to behave in the same manner as DrawRect(), we must exclude - // the bottom and right borders from the rectangle - wxCoord x1 = rect.GetLeft(), - y1 = rect.GetTop(), - x2 = rect.GetRight(), - y2 = rect.GetBottom(); - - wxDCPenChanger pen(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); - - wxCoord z; - for ( z = x1 + 1; z < x2; z += 2 ) - dc.DrawPoint(z, rect.GetTop()); - - wxCoord shift = z == x2 ? 0 : 1; - for ( z = y1 + shift; z < y2; z += 2 ) - dc.DrawPoint(x2, z); - - shift = z == y2 ? 0 : 1; - for ( z = x2 - shift; z > x1; z -= 2 ) - dc.DrawPoint(z, y2); - - shift = z == x1 ? 0 : 1; - for ( z = y2 - shift; z > y1; z -= 2 ) - dc.DrawPoint(x1, z); -} - - void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) { wxDataViewModel *model = GetModel(); @@ -1994,29 +1956,18 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) if (selected || item == m_currentRow) { - wxRect rect( x_start, GetLineStart( item ), + wxRect rowRect( x_start, GetLineStart( item ), x_last - x_start, GetLineHeight( item ) ); - // draw selection and whole-item focus: - if ( selected ) - { - int flags = wxCONTROL_SELECTED; - if (m_hasFocus) - flags |= wxCONTROL_FOCUSED; + bool renderColumnFocus = false; - wxRendererNative::Get().DrawItemSelectionRect - ( - this, - dc, - rect, - flags - ); - } + int flags = wxCONTROL_SELECTED; + if ( m_hasFocus ) + flags |= wxCONTROL_FOCUSED; // draw keyboard focus rect if applicable if ( item == m_currentRow && m_hasFocus ) { - bool renderColumnFocus = false; if ( m_useCellFocus && m_currentCol && m_currentColSetByKeyboard ) { @@ -2033,54 +1984,76 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) if ( renderColumnFocus ) { + wxRect colRect(rowRect); + for ( unsigned int i = col_start; i < col_last; i++ ) { wxDataViewColumn *col = GetOwner()->GetColumnAt(i); if ( col->IsHidden() ) continue; - rect.width = col->GetWidth(); + colRect.width = col->GetWidth(); if ( col == m_currentCol ) { - // make the rect more visible by adding a small - // margin around it: - rect.Deflate(1, 1); + // Draw selection rect left of column + { + wxRect clipRect(rowRect); + clipRect.width = colRect.x; - if ( selected ) - { - // DrawFocusRect() uses XOR and is all but - // invisible against dark-blue background. Use - // the same color used for selected text. - DrawSelectedCellFocusRect(dc, rect); + wxDCClipper clip(dc, clipRect); + wxRendererNative::Get().DrawItemSelectionRect + ( + this, + dc, + rowRect, + flags + ); } - else + + // Draw selection rect right of column { - wxRendererNative::Get().DrawFocusRect - ( - this, - dc, - rect, - 0 - ); + wxRect clipRect(rowRect); + clipRect.x = colRect.x + colRect.width; + clipRect.width = rowRect.width - clipRect.x; + + wxDCClipper clip(dc, clipRect); + wxRendererNative::Get().DrawItemSelectionRect + ( + this, + dc, + rowRect, + flags + ); } + + // Draw column selection rect + wxRendererNative::Get().DrawItemSelectionRect + ( + this, + dc, + colRect, + flags | wxCONTROL_CURRENT | wxCONTROL_CELL + ); + break; } - rect.x += rect.width; + colRect.x += colRect.width; } } - else - { - // render focus rectangle for the whole row - wxRendererNative::Get().DrawFocusRect - ( - this, - dc, - rect, - selected ? (int)wxCONTROL_SELECTED : 0 - ); - } + } + + // draw selection and whole-item focus: + if ( selected && !renderColumnFocus ) + { + wxRendererNative::Get().DrawItemSelectionRect + ( + this, + dc, + rowRect, + flags | wxCONTROL_CURRENT + ); } } } diff --git a/src/generic/renderg.cpp b/src/generic/renderg.cpp index 9cc9eebc32..3de6859a98 100644 --- a/src/generic/renderg.cpp +++ b/src/generic/renderg.cpp @@ -183,6 +183,46 @@ protected: static wxRendererGeneric* sm_rendererGeneric; }; +// ---------------------------------------------------------------------------- +// misc. drawing functions +// ---------------------------------------------------------------------------- + +// Draw focus rect for individual cell. Unlike native focus rect, we render +// this in foreground text color (typically white) to enhance contrast and +// make it visible. +static void DrawSelectedCellFocusRect(wxDC& dc, const wxRect& rect) +{ + // (This code is based on wxRendererGeneric::DrawFocusRect and modified.) + + // draw the pixels manually because the "dots" in wxPen with wxDOT style + // may be short traits and not really dots + // + // note that to behave in the same manner as DrawRect(), we must exclude + // the bottom and right borders from the rectangle + wxCoord x1 = rect.GetLeft(), + y1 = rect.GetTop(), + x2 = rect.GetRight(), + y2 = rect.GetBottom(); + + wxDCPenChanger pen(dc, wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT)); + + wxCoord z; + for (z = x1 + 1; z < x2; z += 2) + dc.DrawPoint(z, rect.GetTop()); + + wxCoord shift = z == x2 ? 0 : 1; + for (z = y1 + shift; z < y2; z += 2) + dc.DrawPoint(x2, z); + + shift = z == y2 ? 0 : 1; + for (z = x2 - shift; z > x1; z -= 2) + dc.DrawPoint(z, y2); + + shift = z == x1 ? 0 : 1; + for (z = y2 - shift; z > y1; z -= 2) + dc.DrawPoint(x1, z); +} + // ============================================================================ // wxRendererGeneric implementation // ============================================================================ @@ -754,17 +794,27 @@ wxRendererGeneric::DrawItemSelectionRect(wxWindow * win, } dc.SetBrush(brush); - if ((flags & wxCONTROL_CURRENT) && (flags & wxCONTROL_FOCUSED) + bool drawFocusRect = (flags & wxCONTROL_CURRENT) && (flags & wxCONTROL_FOCUSED) #if defined( __WXMAC__ ) && !defined(__WXUNIVERSAL__) && wxOSX_USE_CARBON && IsControlActive( (ControlRef)win->GetHandle() ) #endif - ) + ; + + if ( drawFocusRect && !(flags & wxCONTROL_CELL) ) dc.SetPen( *wxBLACK_PEN ); else dc.SetPen( *wxTRANSPARENT_PEN ); dc.DrawRectangle( rect ); + if ( drawFocusRect && (flags & wxCONTROL_CELL) ) + { + wxRect focusRect(rect); + focusRect.Deflate(1); + + DrawSelectedCellFocusRect(dc, focusRect); + } + // it's unused everywhere except in wxOSX/Carbon wxUnusedVar(win); } diff --git a/src/msw/renderer.cpp b/src/msw/renderer.cpp index f0a81a82e4..2f1bf7e1a4 100644 --- a/src/msw/renderer.cpp +++ b/src/msw/renderer.cpp @@ -387,6 +387,12 @@ void wxRendererMSWBase::DrawItemSelectionRect(wxWindow *win, const wxRect& rect, int flags) { + if ( flags & wxCONTROL_CELL ) + { + m_rendererNative.DrawItemSelectionRect(win, dc, rect, flags); + return; + } + wxBrush brush; if ( flags & wxCONTROL_SELECTED ) {