1. Fixed slow-click timer.

2. Fix for full cell background to be painted.  (One line on the edges
was showing through to the background.)

3. Added current cell highlight.  Currently it just draws a thick
border using the gridLineColour just inside the cell borders.

4. Make dragging a little less sensitive by ensuring that the mouse
drags at least 3 pixels before anything is done to the grid.

5. CaptureMouse while drag-selecting cells and fixed to make cells
visible if dragging outside window boundaries.  Still a problem here
though, it moves way to fast to see what's happening (at least on MSW.)


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6002 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2000-02-14 08:53:06 +00:00
parent 0dfef5a812
commit 07296f0b12
3 changed files with 157 additions and 67 deletions

View File

@@ -234,6 +234,8 @@ public:
// takes ownership of the pointer // takes ownership of the pointer
void SetRenderer(wxGridCellRenderer *renderer) void SetRenderer(wxGridCellRenderer *renderer)
{ delete m_renderer; m_renderer = renderer; } { delete m_renderer; m_renderer = renderer; }
void SetEditor(wxGridCellEditor* editor)
{ delete m_editor; m_editor = editor; }
// accessors // accessors
bool HasTextColour() const { return m_colText.Ok(); } bool HasTextColour() const { return m_colText.Ok(); }
@@ -241,21 +243,27 @@ public:
bool HasFont() const { return m_font.Ok(); } bool HasFont() const { return m_font.Ok(); }
bool HasAlignment() const { return m_hAlign || m_vAlign; } bool HasAlignment() const { return m_hAlign || m_vAlign; }
bool HasRenderer() const { return m_renderer != NULL; } bool HasRenderer() const { return m_renderer != NULL; }
bool HasEditor() const { return m_editor != NULL; }
const wxColour& GetTextColour() const; const wxColour& GetTextColour() const;
const wxColour& GetBackgroundColour() const; const wxColour& GetBackgroundColour() const;
const wxFont& GetFont() const; const wxFont& GetFont() const;
void GetAlignment(int *hAlign, int *vAlign) const; void GetAlignment(int *hAlign, int *vAlign) const;
wxGridCellRenderer *GetRenderer() const; wxGridCellRenderer *GetRenderer() const;
wxGridCellEditor *GetEditor() const;
void SetDefAttr(wxGridCellAttr* defAttr) { m_defGridAttr = defAttr; } void SetDefAttr(wxGridCellAttr* defAttr) { m_defGridAttr = defAttr; }
private: private:
// the common part of all ctors // the common part of all ctors
void Init() { m_nRef = 1; m_renderer = (wxGridCellRenderer *)NULL; } void Init() {
m_nRef = 1;
m_renderer = NULL;
m_editor = NULL;
}
// the dtor is private because only DecRef() can delete us // the dtor is private because only DecRef() can delete us
~wxGridCellAttr() { delete m_renderer; } ~wxGridCellAttr() { delete m_renderer; delete m_editor; }
// the ref count - when it goes to 0, we die // the ref count - when it goes to 0, we die
size_t m_nRef; size_t m_nRef;
@@ -267,6 +275,7 @@ private:
m_vAlign; m_vAlign;
wxGridCellRenderer* m_renderer; wxGridCellRenderer* m_renderer;
wxGridCellEditor* m_editor;
wxGridCellAttr* m_defGridAttr; wxGridCellAttr* m_defGridAttr;
// suppress the stupid gcc warning about the class having private dtor and // suppress the stupid gcc warning about the class having private dtor and
@@ -571,19 +580,6 @@ private:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
//-----------------------------------------------------------------------------
// wxGridEditTimer (internal)
//-----------------------------------------------------------------------------
class WXDLLEXPORT wxGridEditTimer: public wxTimer
{
private:
wxGrid *m_owner;
public:
wxGridEditTimer( wxGrid *owner );
void Notify();
};
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGrid // wxGrid
@@ -654,6 +650,7 @@ public:
void DrawCellBorder( wxDC& dc, const wxGridCellCoords& ); void DrawCellBorder( wxDC& dc, const wxGridCellCoords& );
void DrawAllGridLines( wxDC& dc, const wxRegion & reg ); void DrawAllGridLines( wxDC& dc, const wxRegion & reg );
void DrawCell( wxDC& dc, const wxGridCellCoords& ); void DrawCell( wxDC& dc, const wxGridCellCoords& );
void DrawCellHighlight( wxDC& dc );
void DrawRowLabels( wxDC& dc ); void DrawRowLabels( wxDC& dc );
void DrawRowLabel( wxDC& dc, int row ); void DrawRowLabel( wxDC& dc, int row );
@@ -1109,7 +1106,6 @@ protected:
int m_defaultColWidth; int m_defaultColWidth;
wxArrayInt m_colWidths; wxArrayInt m_colWidths;
wxArrayInt m_colRights; wxArrayInt m_colRights;
int m_rowLabelWidth; int m_rowLabelWidth;
int m_colLabelHeight; int m_colLabelHeight;
@@ -1197,8 +1193,10 @@ protected:
int m_dragLastPos; int m_dragLastPos;
int m_dragRowOrCol; int m_dragRowOrCol;
bool m_isDragging; bool m_isDragging;
wxPoint m_startDragPos;
wxTimer* m_editTimer; wxTimer* m_editTimer;
bool m_waitForSlowClick;
wxGridCellCoords m_selectionStart; wxGridCellCoords m_selectionStart;
@@ -1230,6 +1228,7 @@ protected:
void OnSize( wxSizeEvent& ); void OnSize( wxSizeEvent& );
void OnKeyDown( wxKeyEvent& ); void OnKeyDown( wxKeyEvent& );
void OnEraseBackground( wxEraseEvent& ); void OnEraseBackground( wxEraseEvent& );
void OnEditTimer( wxTimerEvent& );
void SetCurrentCell( const wxGridCellCoords& coords ); void SetCurrentCell( const wxGridCellCoords& coords );

View File

@@ -105,7 +105,7 @@ GridFrame::GridFrame()
wxDefaultSize ) wxDefaultSize )
{ {
int gridW = 600, gridH = 300; int gridW = 600, gridH = 300;
int logW = gridW, logH = 80; int logW = gridW, logH = 100;
wxMenu *fileMenu = new wxMenu; wxMenu *fileMenu = new wxMenu;
fileMenu->Append( ID_VTABLE, "&Virtual table test"); fileMenu->Append( ID_VTABLE, "&Virtual table test");

View File

@@ -44,7 +44,8 @@
// this include needs to be outside precomp for BCC // this include needs to be outside precomp for BCC
#include "wx/textfile.h" #include "wx/textfile.h"
#include "wx/generic/grid.h" #include "wx/grid.h"
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// array classes // array classes
@@ -566,6 +567,18 @@ wxGridCellRenderer* wxGridCellAttr::GetRenderer() const
} }
} }
wxGridCellEditor* wxGridCellAttr::GetEditor() const
{
if (HasEditor())
return m_editor;
else if (m_defGridAttr != this)
return m_defGridAttr->GetEditor();
else {
wxFAIL_MSG(wxT("Missing default cell attribute"));
return NULL;
}
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// wxGridCellAttrData // wxGridCellAttrData
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -1658,23 +1671,12 @@ void wxGridWindow::OnEraseBackground(wxEraseEvent&)
{ } { }
//-----------------------------------------------------------------------------
// wxGridEditTimer (internal)
//-----------------------------------------------------------------------------
wxGridEditTimer::wxGridEditTimer( wxGrid *owner )
{
m_owner = owner;
}
void wxGridEditTimer::Notify()
{
m_owner->EnableCellEditControl( TRUE );
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
#define ID_EDIT_TIMER 1001
IMPLEMENT_DYNAMIC_CLASS( wxGrid, wxScrolledWindow ) IMPLEMENT_DYNAMIC_CLASS( wxGrid, wxScrolledWindow )
BEGIN_EVENT_TABLE( wxGrid, wxScrolledWindow ) BEGIN_EVENT_TABLE( wxGrid, wxScrolledWindow )
@@ -1682,6 +1684,7 @@ BEGIN_EVENT_TABLE( wxGrid, wxScrolledWindow )
EVT_SIZE( wxGrid::OnSize ) EVT_SIZE( wxGrid::OnSize )
EVT_KEY_DOWN( wxGrid::OnKeyDown ) EVT_KEY_DOWN( wxGrid::OnKeyDown )
EVT_ERASE_BACKGROUND( wxGrid::OnEraseBackground ) EVT_ERASE_BACKGROUND( wxGrid::OnEraseBackground )
EVT_TIMER( ID_EDIT_TIMER, wxGrid::OnEditTimer )
END_EVENT_TABLE() END_EVENT_TABLE()
wxGrid::wxGrid( wxWindow *parent, wxGrid::wxGrid( wxWindow *parent,
@@ -1879,9 +1882,11 @@ void wxGrid::Init()
m_colRights.Add( colRight ); m_colRights.Add( colRight );
} }
// Set default cell attributes
m_defaultCellAttr->SetFont(GetFont()); m_defaultCellAttr->SetFont(GetFont());
m_defaultCellAttr->SetAlignment(wxLEFT, wxTOP); m_defaultCellAttr->SetAlignment(wxLEFT, wxTOP);
m_defaultCellAttr->SetRenderer(new wxGridCellStringRenderer); m_defaultCellAttr->SetRenderer(new wxGridCellStringRenderer);
m_defaultCellAttr->SetEditor(new wxGridCellTextEditor);
m_defaultCellAttr->SetTextColour( m_defaultCellAttr->SetTextColour(
wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT)); wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT));
m_defaultCellAttr->SetBackgroundColour( m_defaultCellAttr->SetBackgroundColour(
@@ -1896,8 +1901,10 @@ void wxGrid::Init()
m_dragLastPos = -1; m_dragLastPos = -1;
m_dragRowOrCol = -1; m_dragRowOrCol = -1;
m_isDragging = FALSE; m_isDragging = FALSE;
m_startDragPos = wxDefaultPosition;
m_editTimer = new wxGridEditTimer ( this ); m_editTimer = new wxTimer( this, ID_EDIT_TIMER );
m_waitForSlowClick = FALSE;
m_rowResizeCursor = wxCursor( wxCURSOR_SIZENS ); m_rowResizeCursor = wxCursor( wxCURSOR_SIZENS );
m_colResizeCursor = wxCursor( wxCURSOR_SIZEWE ); m_colResizeCursor = wxCursor( wxCURSOR_SIZEWE );
@@ -2756,6 +2763,19 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
if ( event.Dragging() ) if ( event.Dragging() )
{ {
//wxLogDebug("pos(%d, %d) coords(%d, %d)", pos.x, pos.y, coords.GetRow(), coords.GetCol());
// Don't start doing anything until the mouse has been drug at
// least 3 pixels in any direction...
if (! m_isDragging) {
if (m_startDragPos == wxDefaultPosition) {
m_startDragPos = pos;
return;
}
if (abs(m_startDragPos.x - pos.x) < 4 && abs(m_startDragPos.y - pos.y) < 4)
return;
}
m_isDragging = TRUE; m_isDragging = TRUE;
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL ) if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{ {
@@ -2763,6 +2783,13 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
// won't interfer with drag-shrinking. // won't interfer with drag-shrinking.
if ( IsCellEditControlEnabled() ) if ( IsCellEditControlEnabled() )
HideCellEditControl(); HideCellEditControl();
// Have we captured the mouse yet?
if (! m_winCapture) {
m_winCapture = m_gridWin;
m_winCapture->CaptureMouse();
}
if ( coords != wxGridNoCellCoords ) if ( coords != wxGridNoCellCoords )
{ {
if ( !IsSelection() ) if ( !IsSelection() )
@@ -2773,6 +2800,12 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
{ {
SelectBlock( m_currentCellCoords, coords ); SelectBlock( m_currentCellCoords, coords );
} }
if (! IsVisible(coords)) {
MakeCellVisible(coords);
// TODO: need to introduce a delay or something here. The
// scrolling is way to fast, at least on MSW.
}
} }
} }
else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW ) else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
@@ -2819,6 +2852,8 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
} }
m_isDragging = FALSE; m_isDragging = FALSE;
m_startDragPos = wxDefaultPosition;
if ( coords != wxGridNoCellCoords ) if ( coords != wxGridNoCellCoords )
{ {
@@ -2852,7 +2887,18 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
event ) ) event ) )
{ {
MakeCellVisible( coords ); MakeCellVisible( coords );
// if this is the second click on this cell then start
// the edit control
if (m_waitForSlowClick && coords == m_currentCellCoords) {
EnableCellEditControl(TRUE);
ShowCellEditControl();
}
else {
SetCurrentCell( coords ); SetCurrentCell( coords );
m_editTimer->Start( 1500, TRUE );
m_waitForSlowClick = TRUE;
}
} }
} }
} }
@@ -2863,7 +2909,6 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
else if ( event.LeftDClick() ) else if ( event.LeftDClick() )
{ {
EnableCellEditControl( FALSE ); EnableCellEditControl( FALSE );
m_editTimer->Stop();
if ( XToEdgeOfCol(x) < 0 && YToEdgeOfRow(y) < 0 ) if ( XToEdgeOfCol(x) < 0 && YToEdgeOfRow(y) < 0 )
{ {
SendEvent( EVT_GRID_CELL_LEFT_DCLICK, SendEvent( EVT_GRID_CELL_LEFT_DCLICK,
@@ -2882,6 +2927,10 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
{ {
if ( IsSelection() ) if ( IsSelection() )
{ {
if (m_winCapture) {
m_winCapture->ReleaseMouse();
m_winCapture = NULL;
}
SendEvent( EVT_GRID_RANGE_SELECT, -1, -1, event ); SendEvent( EVT_GRID_RANGE_SELECT, -1, -1, event );
} }
@@ -2889,8 +2938,6 @@ void wxGrid::ProcessGridCellMouseEvent( wxMouseEvent& event )
// been hidden for drag-shrinking. // been hidden for drag-shrinking.
if ( IsCellEditControlEnabled() ) if ( IsCellEditControlEnabled() )
ShowCellEditControl(); ShowCellEditControl();
if( IsEditable() && coords == m_currentCellCoords )
m_editTimer->Start( 100, TRUE );
} }
else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW ) else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
{ {
@@ -3463,7 +3510,7 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
{ {
// shouldn't be here - we are going round in circles... // shouldn't be here - we are going round in circles...
// //
wxFAIL_MSG( wxT("wxGrid::OnKeyDown called while alread active") ); wxFAIL_MSG( wxT("wxGrid::OnKeyDown called while already active") );
} }
m_inOnKeyDown = TRUE; m_inOnKeyDown = TRUE;
@@ -3524,17 +3571,6 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
} }
break; break;
case WXK_SPACE:
if ( !IsEditable() )
{
MoveCursorRight();
}
else
{
event.Skip();
}
break;
case WXK_RETURN: case WXK_RETURN:
if ( event.ControlDown() ) if ( event.ControlDown() )
{ {
@@ -3578,16 +3614,29 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
MovePageDown(); MovePageDown();
break; break;
// We don't want these keys to trigger the edit control, any others?
case WXK_SHIFT:
case WXK_ALT:
case WXK_CONTROL:
event.Skip();
break;
case WXK_SPACE:
if ( !IsEditable() )
{
MoveCursorRight();
break;
}
// Otherwise fall through to default
default: default:
// now try the cell edit control // now try the cell edit control
// //
if ( !IsCellEditControlEnabled() ) if ( !IsCellEditControlEnabled() )
EnableCellEditControl( TRUE ); EnableCellEditControl( TRUE );
if ( IsCellEditControlEnabled() ) wxKeyEvent evt(event);
{ evt.SetEventObject( m_cellEditCtrl );
event.SetEventObject( m_cellEditCtrl ); m_cellEditCtrl->GetEventHandler()->ProcessEvent( evt );
m_cellEditCtrl->GetEventHandler()->ProcessEvent( event );
}
break; break;
} }
} }
@@ -3595,9 +3644,18 @@ void wxGrid::OnKeyDown( wxKeyEvent& event )
m_inOnKeyDown = FALSE; m_inOnKeyDown = FALSE;
} }
void wxGrid::OnEraseBackground(wxEraseEvent&) void wxGrid::OnEraseBackground(wxEraseEvent&)
{ } { }
void wxGrid::OnEditTimer(wxTimerEvent&)
{
m_waitForSlowClick = FALSE;
}
void wxGrid::SetCurrentCell( const wxGridCellCoords& coords ) void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
{ {
if ( SendEvent( EVT_GRID_SELECT_CELL, coords.GetRow(), coords.GetCol() ) ) if ( SendEvent( EVT_GRID_SELECT_CELL, coords.GetRow(), coords.GetCol() ) )
@@ -3611,15 +3669,26 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
{ {
HideCellEditControl(); HideCellEditControl();
SaveEditControlValue(); SaveEditControlValue();
// Clear the old current cell highlight
wxRect r = BlockToDeviceRect(m_currentCellCoords, m_currentCellCoords);
r.x--; r.y--; r.width++; r.height++;
m_gridWin->Refresh( FALSE, &r );
} }
m_currentCellCoords = coords; m_currentCellCoords = coords;
SetEditControlValue(); SetEditControlValue();
#if 0
if ( m_displayed ) if ( m_displayed )
{ {
#if 0
ShowCellEditControl(); ShowCellEditControl();
#else
wxClientDC dc(m_gridWin);
PrepareDC(dc);
DrawCellHighlight(dc);
#endif
if ( IsSelection() ) if ( IsSelection() )
{ {
@@ -3628,9 +3697,6 @@ void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
if ( !GetBatchCount() ) m_gridWin->Refresh( FALSE, &r ); if ( !GetBatchCount() ) m_gridWin->Refresh( FALSE, &r );
} }
} }
#else
SelectBlock ( coords, coords );
#endif
} }
@@ -3711,12 +3777,37 @@ void wxGrid::DrawCell( wxDC& dc, const wxGridCellCoords& coords )
wxRect rect; wxRect rect;
rect.x = m_colRights[col] - m_colWidths[col]; rect.x = m_colRights[col] - m_colWidths[col];
rect.y = m_rowBottoms[row] - m_rowHeights[row]; rect.y = m_rowBottoms[row] - m_rowHeights[row];
rect.width = m_colWidths[col] - 1; rect.width = m_colWidths[col];
rect.height = m_rowHeights[row] - 1; rect.height = m_rowHeights[row];
wxGridCellAttr* attr = GetCellAttr(row, col); wxGridCellAttr* attr = GetCellAttr(row, col);
attr->GetRenderer()->Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords)); attr->GetRenderer()->Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords));
attr->DecRef(); attr->DecRef();
if (m_currentCellCoords == coords)
DrawCellHighlight(dc);
}
void wxGrid::DrawCellHighlight( wxDC& dc )
{
int row = m_currentCellCoords.GetRow();
int col = m_currentCellCoords.GetCol();
if ( m_colWidths[col] <= 0 || m_rowHeights[row] <= 0 )
return;
wxRect rect;
rect.x = m_colRights[col] - m_colWidths[col];
rect.y = m_rowBottoms[row] - m_rowHeights[row];
rect.width = m_colWidths[col] - 1;
rect.height = m_rowHeights[row] - 1;
dc.SetPen(wxPen(m_gridLineColour, 3, wxSOLID));
dc.SetBrush(*wxTRANSPARENT_BRUSH);
//dc.SetLogicalFunction(wxINVERT);
dc.DrawRectangle(rect);
} }
void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords ) void wxGrid::DrawCellBorder( wxDC& dc, const wxGridCellCoords& coords )
@@ -4298,7 +4389,7 @@ int wxGrid::YToRow( int y )
if ( y < m_rowBottoms[i] ) return i; if ( y < m_rowBottoms[i] ) return i;
} }
return -1; return m_numRows; //-1;
} }
@@ -4311,7 +4402,7 @@ int wxGrid::XToCol( int x )
if ( x < m_colRights[i] ) return i; if ( x < m_colRights[i] ) return i;
} }
return -1; return m_numCols; //-1;
} }