X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/71cf399ff0f1ddb966b48e512b0fb4e690f5c440..179a30e2f8c28b2f093b658629c5a827fb29e51a:/src/generic/grid.cpp diff --git a/src/generic/grid.cpp b/src/generic/grid.cpp index 0fba2b3829..2ba9c636e8 100644 --- a/src/generic/grid.cpp +++ b/src/generic/grid.cpp @@ -132,12 +132,14 @@ public: int additionalStyle = 0, const wxString& name = wxPanelNameStr) : wxWindow(owner, id, pos, size, - wxWANTS_CHARS | wxBORDER_NONE | additionalStyle, + wxBORDER_NONE | additionalStyle, name) { m_owner = owner; } + virtual bool AcceptsFocus() const { return false; } + wxGrid *GetOwner() { return m_owner; } protected: @@ -160,9 +162,6 @@ private: void OnPaint( wxPaintEvent& event ); void OnMouseEvent( wxMouseEvent& event ); void OnMouseWheel( wxMouseEvent& event ); - void OnKeyDown( wxKeyEvent& event ); - void OnKeyUp( wxKeyEvent& ); - void OnChar( wxKeyEvent& ); DECLARE_DYNAMIC_CLASS(wxGridRowLabelWindow) DECLARE_EVENT_TABLE() @@ -181,9 +180,6 @@ private: void OnPaint( wxPaintEvent& event ); void OnMouseEvent( wxMouseEvent& event ); void OnMouseWheel( wxMouseEvent& event ); - void OnKeyDown( wxKeyEvent& event ); - void OnKeyUp( wxKeyEvent& ); - void OnChar( wxKeyEvent& ); DECLARE_DYNAMIC_CLASS(wxGridColLabelWindow) DECLARE_EVENT_TABLE() @@ -201,9 +197,6 @@ public: private: void OnMouseEvent( wxMouseEvent& event ); void OnMouseWheel( wxMouseEvent& event ); - void OnKeyDown( wxKeyEvent& event ); - void OnKeyUp( wxKeyEvent& ); - void OnChar( wxKeyEvent& ); void OnPaint( wxPaintEvent& event ); DECLARE_DYNAMIC_CLASS(wxGridCornerLabelWindow) @@ -227,6 +220,8 @@ public: void ScrollWindow( int dx, int dy, const wxRect *rect ); + virtual bool AcceptsFocus() const { return true; } + private: wxGridRowLabelWindow *m_rowLabelWin; wxGridColLabelWindow *m_colLabelWin; @@ -490,7 +485,7 @@ void wxGridCellEditor::PaintBackground(const wxRect& rectCell, gridWindow->GetOwner()->PrepareDC(dc); dc.SetPen(*wxTRANSPARENT_PEN); - dc.SetBrush(wxBrush(attr->GetBackgroundColour(), wxSOLID)); + dc.SetBrush(wxBrush(attr->GetBackgroundColour(), wxBRUSHSTYLE_SOLID)); dc.DrawRectangle(rectCell); // redraw the control we just painted over @@ -1520,12 +1515,16 @@ void wxGridCellChoiceEditor::Create(wxWindow* parent, wxWindowID id, wxEvtHandler* evtHandler) { - int style = wxBORDER_NONE; - if (!m_allowOthers) + int style = wxTE_PROCESS_ENTER | + wxTE_PROCESS_TAB | + wxBORDER_NONE; + + if ( !m_allowOthers ) style |= wxCB_READONLY; m_control = new wxComboBox(parent, id, wxEmptyString, wxDefaultPosition, wxDefaultSize, - m_choices, style ); + m_choices, + style); wxGridCellEditor::Create(parent, id, evtHandler); } @@ -1804,23 +1803,28 @@ void wxGridCellRenderer::Draw(wxGrid& grid, int WXUNUSED(row), int WXUNUSED(col), bool isSelected) { - dc.SetBackgroundMode( wxSOLID ); + dc.SetBackgroundMode( wxBRUSHSTYLE_SOLID ); // grey out fields if the grid is disabled if ( grid.IsEnabled() ) { if ( isSelected ) { - dc.SetBrush( wxBrush(grid.GetSelectionBackground(), wxSOLID) ); + wxColour clr; + if ( grid.HasFocus() ) + clr = grid.GetSelectionBackground(); + else + clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW); + dc.SetBrush( wxBrush(clr, wxBRUSHSTYLE_SOLID) ); } else { - dc.SetBrush( wxBrush(attr.GetBackgroundColour(), wxSOLID) ); + dc.SetBrush( wxBrush(attr.GetBackgroundColour(), wxBRUSHSTYLE_SOLID) ); } } else { - dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE), wxSOLID)); + dc.SetBrush(wxBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE), wxBRUSHSTYLE_SOLID)); } dc.SetPen( *wxTRANSPARENT_PEN ); @@ -1836,7 +1840,7 @@ void wxGridCellStringRenderer::SetTextColoursAndFont(const wxGrid& grid, wxDC& dc, bool isSelected) { - dc.SetBackgroundMode( wxTRANSPARENT ); + dc.SetBackgroundMode( wxBRUSHSTYLE_TRANSPARENT ); // TODO some special colours for attr.IsReadOnly() case? @@ -1845,7 +1849,12 @@ void wxGridCellStringRenderer::SetTextColoursAndFont(const wxGrid& grid, { if ( isSelected ) { - dc.SetTextBackground( grid.GetSelectionBackground() ); + wxColour clr; + if ( grid.HasFocus() ) + clr = grid.GetSelectionBackground(); + else + clr = wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW); + dc.SetTextBackground( clr ); dc.SetTextForeground( grid.GetSelectionForeground() ); } else @@ -3774,9 +3783,6 @@ BEGIN_EVENT_TABLE( wxGridRowLabelWindow, wxGridSubwindow ) EVT_PAINT( wxGridRowLabelWindow::OnPaint ) EVT_MOUSEWHEEL( wxGridRowLabelWindow::OnMouseWheel ) EVT_MOUSE_EVENTS( wxGridRowLabelWindow::OnMouseEvent ) - EVT_KEY_DOWN( wxGridRowLabelWindow::OnKeyDown ) - EVT_KEY_UP( wxGridRowLabelWindow::OnKeyUp ) - EVT_CHAR( wxGridRowLabelWindow::OnChar ) END_EVENT_TABLE() wxGridRowLabelWindow::wxGridRowLabelWindow( wxGrid *parent, @@ -3816,27 +3822,6 @@ void wxGridRowLabelWindow::OnMouseWheel( wxMouseEvent& event ) m_owner->GetEventHandler()->ProcessEvent( event ); } -// This seems to be required for wxMotif otherwise the mouse -// cursor must be in the cell edit control to get key events -// -void wxGridRowLabelWindow::OnKeyDown( wxKeyEvent& event ) -{ - if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) - event.Skip(); -} - -void wxGridRowLabelWindow::OnKeyUp( wxKeyEvent& event ) -{ - if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) - event.Skip(); -} - -void wxGridRowLabelWindow::OnChar( wxKeyEvent& event ) -{ - if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) - event.Skip(); -} - ////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC_CLASS( wxGridColLabelWindow, wxWindow ) @@ -3845,9 +3830,6 @@ BEGIN_EVENT_TABLE( wxGridColLabelWindow, wxGridSubwindow ) EVT_PAINT( wxGridColLabelWindow::OnPaint ) EVT_MOUSEWHEEL( wxGridColLabelWindow::OnMouseWheel ) EVT_MOUSE_EVENTS( wxGridColLabelWindow::OnMouseEvent ) - EVT_KEY_DOWN( wxGridColLabelWindow::OnKeyDown ) - EVT_KEY_UP( wxGridColLabelWindow::OnKeyUp ) - EVT_CHAR( wxGridColLabelWindow::OnChar ) END_EVENT_TABLE() wxGridColLabelWindow::wxGridColLabelWindow( wxGrid *parent, @@ -3890,27 +3872,6 @@ void wxGridColLabelWindow::OnMouseWheel( wxMouseEvent& event ) m_owner->GetEventHandler()->ProcessEvent( event ); } -// This seems to be required for wxMotif otherwise the mouse -// cursor must be in the cell edit control to get key events -// -void wxGridColLabelWindow::OnKeyDown( wxKeyEvent& event ) -{ - if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) - event.Skip(); -} - -void wxGridColLabelWindow::OnKeyUp( wxKeyEvent& event ) -{ - if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) - event.Skip(); -} - -void wxGridColLabelWindow::OnChar( wxKeyEvent& event ) -{ - if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) - event.Skip(); -} - ////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC_CLASS( wxGridCornerLabelWindow, wxWindow ) @@ -3919,9 +3880,6 @@ BEGIN_EVENT_TABLE( wxGridCornerLabelWindow, wxGridSubwindow ) EVT_MOUSEWHEEL( wxGridCornerLabelWindow::OnMouseWheel ) EVT_MOUSE_EVENTS( wxGridCornerLabelWindow::OnMouseEvent ) EVT_PAINT( wxGridCornerLabelWindow::OnPaint ) - EVT_KEY_DOWN( wxGridCornerLabelWindow::OnKeyDown ) - EVT_KEY_UP( wxGridCornerLabelWindow::OnKeyUp ) - EVT_CHAR( wxGridCornerLabelWindow::OnChar ) END_EVENT_TABLE() wxGridCornerLabelWindow::wxGridCornerLabelWindow( wxGrid *parent, @@ -3951,7 +3909,7 @@ def __WXGTK__ wxRendererNative::Get().DrawHeaderButton( this, dc, rect, 0 ); #else // !__WXGTK__ - dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID) ); + dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxPENSTYLE_SOLID) ); dc.DrawLine( client_width - 1, client_height - 1, client_width - 1, 0 ); dc.DrawLine( client_width - 1, client_height - 1, 0, client_height - 1 ); dc.DrawLine( 0, 0, client_width, 0 ); @@ -3973,27 +3931,6 @@ void wxGridCornerLabelWindow::OnMouseWheel( wxMouseEvent& event ) m_owner->GetEventHandler()->ProcessEvent(event); } -// This seems to be required for wxMotif otherwise the mouse -// cursor must be in the cell edit control to get key events -// -void wxGridCornerLabelWindow::OnKeyDown( wxKeyEvent& event ) -{ - if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) - event.Skip(); -} - -void wxGridCornerLabelWindow::OnKeyUp( wxKeyEvent& event ) -{ - if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) - event.Skip(); -} - -void wxGridCornerLabelWindow::OnChar( wxKeyEvent& event ) -{ - if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) - event.Skip(); -} - ////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNAMIC_CLASS( wxGridWindow, wxWindow ) @@ -4017,7 +3954,8 @@ wxGridWindow::wxGridWindow( wxGrid *parent, const wxPoint &pos, const wxSize &size ) : wxGridSubwindow(parent, id, pos, size, - wxCLIP_CHILDREN, wxT("grid window") ) + wxWANTS_CHARS | wxCLIP_CHILDREN, + wxT("grid window") ) { m_owner = parent; m_rowLabelWin = rowLblWin; @@ -4087,6 +4025,29 @@ void wxGridWindow::OnEraseBackground( wxEraseEvent& WXUNUSED(event) ) void wxGridWindow::OnFocus(wxFocusEvent& event) { + // and if we have any selection, it has to be repainted, because it + // uses different colour when the grid is not focused: + if ( m_owner->IsSelection() ) + { + Refresh(); + } + else + { + // NB: Note that this code is in "else" branch only because the other + // branch refreshes everything and so there's no point in calling + // Refresh() again, *not* because it should only be done if + // !IsSelection(). If the above code is ever optimized to refresh + // only selected area, this needs to be moved out of the "else" + // branch so that it's always executed. + + // current cell cursor {dis,re}appears on focus change: + const wxGridCellCoords cursorCoords(m_owner->GetGridCursorRow(), + m_owner->GetGridCursorCol()); + const wxRect cursor = + m_owner->BlockToDeviceRect(cursorCoords, cursorCoords); + Refresh(true, &cursor); + } + if ( !m_owner->GetEventHandler()->ProcessEvent( event ) ) event.Skip(); } @@ -4174,12 +4135,7 @@ END_EVENT_TABLE() wxGrid::wxGrid() { - // in order to make sure that a size event is not - // trigerred in a unfinished state - m_cornerLabelWin = NULL; - m_rowLabelWin = NULL; - m_colLabelWin = NULL; - m_gridWin = NULL; + InitVars(); } wxGrid::wxGrid( wxWindow *parent, @@ -4188,12 +4144,9 @@ wxGrid::wxGrid( wxWindow *parent, const wxSize& size, long style, const wxString& name ) - : wxScrolledWindow( parent, id, pos, size, (style | wxWANTS_CHARS), name ), - m_colMinWidths(GRID_HASH_SIZE), - m_rowMinHeights(GRID_HASH_SIZE) { - Create(); - SetInitialSize(size); + InitVars(); + Create(parent, id, pos, size, style, name); } bool wxGrid::Create(wxWindow *parent, wxWindowID id, @@ -4250,15 +4203,8 @@ wxGrid::~wxGrid() void wxGrid::Create() { - // set to true by CreateGrid - m_created = false; - // create the type registry m_typeRegistry = new wxGridTypeRegistry; - m_selection = NULL; - - m_table = (wxGridTableBase *) NULL; - m_ownTable = false; m_cellEditCtrlEnabled = false; @@ -4452,6 +4398,24 @@ bool wxGrid::SetTable( wxGridTableBase *table, bool takeOwnership, return m_created; } +void wxGrid::InitVars() +{ + m_created = false; + + m_cornerLabelWin = NULL; + m_rowLabelWin = NULL; + m_colLabelWin = NULL; + m_gridWin = NULL; + + m_table = NULL; + m_ownTable = false; + + m_selection = NULL; + m_defaultCellAttr = NULL; + m_typeRegistry = NULL; + m_winCapture = NULL; +} + void wxGrid::Init() { m_rowLabelWidth = WXGRID_DEFAULT_ROW_LABEL_WIDTH; @@ -4712,17 +4676,26 @@ void wxGrid::CalcWindowSizes() } } + // the grid may be too small to have enough space for the labels yet, don't + // size the windows to negative sizes in this case + int gw = cw - m_rowLabelWidth; + int gh = ch - m_colLabelHeight; + if (gw < 0) + gw = 0; + if (gh < 0) + gh = 0; + if ( m_cornerLabelWin && m_cornerLabelWin->IsShown() ) m_cornerLabelWin->SetSize( 0, 0, m_rowLabelWidth, m_colLabelHeight ); if ( m_colLabelWin && m_colLabelWin->IsShown() ) - m_colLabelWin->SetSize( m_rowLabelWidth, 0, cw - m_rowLabelWidth, m_colLabelHeight ); + m_colLabelWin->SetSize( m_rowLabelWidth, 0, gw, m_colLabelHeight ); if ( m_rowLabelWin && m_rowLabelWin->IsShown() ) - m_rowLabelWin->SetSize( 0, m_colLabelHeight, m_rowLabelWidth, ch - m_colLabelHeight ); + m_rowLabelWin->SetSize( 0, m_colLabelHeight, m_rowLabelWidth, gh ); if ( m_gridWin && m_gridWin->IsShown() ) - m_gridWin->SetSize( m_rowLabelWidth, m_colLabelHeight, cw - m_rowLabelWidth, ch - m_colLabelHeight ); + m_gridWin->SetSize( m_rowLabelWidth, m_colLabelHeight, gw, gh ); } // this is called when the grid table sends a message @@ -6856,7 +6829,7 @@ void wxGrid::Refresh(bool eraseb, const wxRect* rect) { // Don't do anything if between Begin/EndBatch... // EndBatch() will do all this on the last nested one anyway. - if (! GetBatchCount()) + if ( m_created && !GetBatchCount() ) { // Refresh to get correct scrolled position: wxScrolledWindow::Refresh(eraseb, rect); @@ -7576,7 +7549,7 @@ void wxGrid::DrawGridSpace( wxDC& dc ) int left, top; CalcUnscrolledPosition( 0, 0, &left, &top ); - dc.SetBrush( wxBrush(GetDefaultCellBackgroundColour(), wxSOLID) ); + dc.SetBrush( wxBrush(GetDefaultCellBackgroundColour(), wxBRUSHSTYLE_SOLID) ); dc.SetPen( *wxTRANSPARENT_PEN ); if ( right > rightCol ) @@ -7638,6 +7611,10 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords ) void wxGrid::DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr ) { + // don't show highlight when the grid doesn't have focus + if ( !HasFocus() ) + return; + int row = m_currentCellCoords.GetRow(); int col = m_currentCellCoords.GetCol(); @@ -7667,7 +7644,7 @@ void wxGrid::DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr ) // Now draw the rectangle // use the cellHighlightColour if the cell is inside a selection, this // will ensure the cell is always visible. - dc.SetPen(wxPen(IsInSelection(row,col) ? m_selectionForeground : m_cellHighlightColour, penWidth, wxSOLID)); + dc.SetPen(wxPen(IsInSelection(row,col) ? m_selectionForeground : m_cellHighlightColour, penWidth, wxPENSTYLE_SOLID)); dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRectangle(rect); } @@ -7696,7 +7673,7 @@ void wxGrid::DrawCellHighlight( wxDC& dc, const wxGridCellAttr *attr ) wxPen wxGrid::GetDefaultGridLinePen() { - return wxPen(GetGridLineColour(), 1, wxSOLID); + return wxPen(GetGridLineColour(), 1, wxPENSTYLE_SOLID); } wxPen wxGrid::GetRowGridLinePen(int WXUNUSED(row)) @@ -7916,7 +7893,7 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row ) int rowTop = GetRowTop(row), rowBottom = GetRowBottom(row) - 1; - dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID) ); + dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxPENSTYLE_SOLID) ); dc.DrawLine( m_rowLabelWidth - 1, rowTop, m_rowLabelWidth - 1, rowBottom ); dc.DrawLine( 0, rowTop, 0, rowBottom ); dc.DrawLine( 0, rowBottom, m_rowLabelWidth, rowBottom ); @@ -7925,7 +7902,7 @@ void wxGrid::DrawRowLabel( wxDC& dc, int row ) dc.DrawLine( 1, rowTop, 1, rowBottom ); dc.DrawLine( 1, rowTop, m_rowLabelWidth - 1, rowTop ); - dc.SetBackgroundMode( wxTRANSPARENT ); + dc.SetBackgroundMode( wxBRUSHSTYLE_TRANSPARENT ); dc.SetTextForeground( GetLabelTextColour() ); dc.SetFont( GetLabelFont() ); @@ -7988,7 +7965,7 @@ void wxGrid::DrawColLabel( wxDC& dc, int col ) { int colRight = GetColRight(col) - 1; - dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID) ); + dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxPENSTYLE_SOLID) ); dc.DrawLine( colRight, 0, colRight, m_colLabelHeight - 1 ); dc.DrawLine( colLeft, 0, colRight, 0 ); dc.DrawLine( colLeft, m_colLabelHeight - 1, @@ -7999,7 +7976,7 @@ void wxGrid::DrawColLabel( wxDC& dc, int col ) dc.DrawLine( colLeft, 1, colRight, 1 ); } - dc.SetBackgroundMode( wxTRANSPARENT ); + dc.SetBackgroundMode( wxBRUSHSTYLE_TRANSPARENT ); dc.SetTextForeground( GetLabelTextColour() ); dc.SetFont( GetLabelFont() ); @@ -8140,6 +8117,7 @@ void wxGrid::DrawTextRectangle(wxDC& dc, // Split multi-line text up into an array of strings. // Any existing contents of the string array are preserved. // +// TODO: refactor wxTextFile::Read() and reuse the same code from here void wxGrid::StringToLines( const wxString& value, wxArrayString& lines ) const { int startPos = 0; @@ -8160,15 +8138,15 @@ void wxGrid::StringToLines( const wxString& value, wxArrayString& lines ) const } else { - lines.Add( value.Mid(startPos, pos) ); + lines.Add( tVal.Mid(startPos, pos) ); } startPos += pos + 1; } - if ( startPos < (int)value.length() ) + if ( startPos < (int)tVal.length() ) { - lines.Add( value.Mid( startPos ) ); + lines.Add( tVal.Mid( startPos ) ); } } @@ -8362,7 +8340,7 @@ void wxGrid::ShowCellEditControl() wxClientDC dc( m_gridWin ); PrepareDC( dc ); wxGridCellAttr* attr = GetCellAttr(row, col); - dc.SetBrush(wxBrush(attr->GetBackgroundColour(), wxSOLID)); + dc.SetBrush(wxBrush(attr->GetBackgroundColour(), wxBRUSHSTYLE_SOLID)); dc.SetPen(*wxTRANSPARENT_PEN); dc.DrawRectangle(rect); @@ -11136,6 +11114,20 @@ wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords &topLeft, return rect; } +// ---------------------------------------------------------------------------- +// drop target +// ---------------------------------------------------------------------------- + +#if wxUSE_DRAG_AND_DROP + +// this allow setting drop target directly on wxGrid +void wxGrid::SetDropTarget(wxDropTarget *dropTarget) +{ + GetGridWindow()->SetDropTarget(dropTarget); +} + +#endif // wxUSE_DRAG_AND_DROP + // ---------------------------------------------------------------------------- // grid event classes // ----------------------------------------------------------------------------