// takes ownership of the pointer
void SetRenderer(wxGridCellRenderer *renderer)
{ delete m_renderer; m_renderer = renderer; }
+ void SetEditor(wxGridCellEditor* editor)
+ { delete m_editor; m_editor = editor; }
// accessors
bool HasTextColour() const { return m_colText.Ok(); }
bool HasFont() const { return m_font.Ok(); }
bool HasAlignment() const { return m_hAlign || m_vAlign; }
bool HasRenderer() const { return m_renderer != NULL; }
+ bool HasEditor() const { return m_editor != NULL; }
const wxColour& GetTextColour() const;
const wxColour& GetBackgroundColour() const;
const wxFont& GetFont() const;
void GetAlignment(int *hAlign, int *vAlign) const;
wxGridCellRenderer *GetRenderer() const;
+ wxGridCellEditor *GetEditor() const;
void SetDefAttr(wxGridCellAttr* defAttr) { m_defGridAttr = defAttr; }
private:
// 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
- ~wxGridCellAttr() { delete m_renderer; }
+ ~wxGridCellAttr() { delete m_renderer; delete m_editor; }
// the ref count - when it goes to 0, we die
size_t m_nRef;
int m_hAlign,
m_vAlign;
- wxGridCellRenderer *m_renderer;
- wxGridCellAttr* m_defGridAttr;
+ wxGridCellRenderer* m_renderer;
+ wxGridCellEditor* m_editor;
+ wxGridCellAttr* m_defGridAttr;
// suppress the stupid gcc warning about the class having private dtor and
// no friends
DECLARE_EVENT_TABLE()
};
-//-----------------------------------------------------------------------------
-// wxGridEditTimer (internal)
-//-----------------------------------------------------------------------------
-
-class WXDLLEXPORT wxGridEditTimer: public wxTimer
-{
- private:
- wxGrid *m_owner;
-
- public:
- wxGridEditTimer( wxGrid *owner );
- void Notify();
-};
// ----------------------------------------------------------------------------
// wxGrid
void DrawCellBorder( wxDC& dc, const wxGridCellCoords& );
void DrawAllGridLines( wxDC& dc, const wxRegion & reg );
void DrawCell( wxDC& dc, const wxGridCellCoords& );
+ void DrawCellHighlight( wxDC& dc );
void DrawRowLabels( wxDC& dc );
void DrawRowLabel( wxDC& dc, int row );
int m_defaultColWidth;
wxArrayInt m_colWidths;
wxArrayInt m_colRights;
-
int m_rowLabelWidth;
int m_colLabelHeight;
wxWindow *m_winCapture; // the window which captured the mouse
CursorMode m_cursorMode;
- int m_dragLastPos;
- int m_dragRowOrCol;
- bool m_isDragging;
+ int m_dragLastPos;
+ int m_dragRowOrCol;
+ bool m_isDragging;
+ wxPoint m_startDragPos;
- wxTimer *m_editTimer;
+ wxTimer* m_editTimer;
+ bool m_waitForSlowClick;
wxGridCellCoords m_selectionStart;
void OnSize( wxSizeEvent& );
void OnKeyDown( wxKeyEvent& );
void OnEraseBackground( wxEraseEvent& );
+ void OnEditTimer( wxTimerEvent& );
void SetCurrentCell( const wxGridCellCoords& coords );
// this include needs to be outside precomp for BCC
#include "wx/textfile.h"
-#include "wx/generic/grid.h"
+#include "wx/grid.h"
+
// ----------------------------------------------------------------------------
// array classes
}
}
+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
// ----------------------------------------------------------------------------
{ }
-//-----------------------------------------------------------------------------
-// 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 )
BEGIN_EVENT_TABLE( wxGrid, wxScrolledWindow )
EVT_SIZE( wxGrid::OnSize )
EVT_KEY_DOWN( wxGrid::OnKeyDown )
EVT_ERASE_BACKGROUND( wxGrid::OnEraseBackground )
+ EVT_TIMER( ID_EDIT_TIMER, wxGrid::OnEditTimer )
END_EVENT_TABLE()
wxGrid::wxGrid( wxWindow *parent,
m_colRights.Add( colRight );
}
+ // Set default cell attributes
m_defaultCellAttr->SetFont(GetFont());
m_defaultCellAttr->SetAlignment(wxLEFT, wxTOP);
m_defaultCellAttr->SetRenderer(new wxGridCellStringRenderer);
+ m_defaultCellAttr->SetEditor(new wxGridCellTextEditor);
m_defaultCellAttr->SetTextColour(
wxSystemSettings::GetSystemColour(wxSYS_COLOUR_WINDOWTEXT));
m_defaultCellAttr->SetBackgroundColour(
m_dragLastPos = -1;
m_dragRowOrCol = -1;
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_colResizeCursor = wxCursor( wxCURSOR_SIZEWE );
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;
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
// won't interfer with drag-shrinking.
if ( IsCellEditControlEnabled() )
HideCellEditControl();
+
+ // Have we captured the mouse yet?
+ if (! m_winCapture) {
+ m_winCapture = m_gridWin;
+ m_winCapture->CaptureMouse();
+ }
+
if ( coords != wxGridNoCellCoords )
{
if ( !IsSelection() )
{
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 )
}
m_isDragging = FALSE;
+ m_startDragPos = wxDefaultPosition;
+
if ( coords != wxGridNoCellCoords )
{
event ) )
{
MakeCellVisible( coords );
- SetCurrentCell( 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 );
+ m_editTimer->Start( 1500, TRUE );
+ m_waitForSlowClick = TRUE;
+ }
}
}
}
else if ( event.LeftDClick() )
{
EnableCellEditControl( FALSE );
- m_editTimer->Stop();
if ( XToEdgeOfCol(x) < 0 && YToEdgeOfRow(y) < 0 )
{
SendEvent( EVT_GRID_CELL_LEFT_DCLICK,
{
if ( IsSelection() )
{
+ if (m_winCapture) {
+ m_winCapture->ReleaseMouse();
+ m_winCapture = NULL;
+ }
SendEvent( EVT_GRID_RANGE_SELECT, -1, -1, event );
}
// been hidden for drag-shrinking.
if ( IsCellEditControlEnabled() )
ShowCellEditControl();
- if( IsEditable() && coords == m_currentCellCoords )
- m_editTimer->Start( 100, TRUE );
}
else if ( m_cursorMode == WXGRID_CURSOR_RESIZE_ROW )
{
{
// 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;
}
break;
- case WXK_SPACE:
- if ( !IsEditable() )
- {
- MoveCursorRight();
- }
- else
- {
- event.Skip();
- }
- break;
-
case WXK_RETURN:
if ( event.ControlDown() )
{
MovePageDown();
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:
// now try the cell edit control
//
if ( !IsCellEditControlEnabled() )
EnableCellEditControl( TRUE );
- if ( IsCellEditControlEnabled() )
- {
- event.SetEventObject( m_cellEditCtrl );
- m_cellEditCtrl->GetEventHandler()->ProcessEvent( event );
- }
+ wxKeyEvent evt(event);
+ evt.SetEventObject( m_cellEditCtrl );
+ m_cellEditCtrl->GetEventHandler()->ProcessEvent( evt );
break;
}
}
m_inOnKeyDown = FALSE;
}
+
void wxGrid::OnEraseBackground(wxEraseEvent&)
{ }
+
+void wxGrid::OnEditTimer(wxTimerEvent&)
+{
+ m_waitForSlowClick = FALSE;
+}
+
+
+
void wxGrid::SetCurrentCell( const wxGridCellCoords& coords )
{
if ( SendEvent( EVT_GRID_SELECT_CELL, coords.GetRow(), coords.GetCol() ) )
{
HideCellEditControl();
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;
SetEditControlValue();
-#if 0
+
if ( m_displayed )
{
+#if 0
ShowCellEditControl();
+#else
+ wxClientDC dc(m_gridWin);
+ PrepareDC(dc);
+ DrawCellHighlight(dc);
+#endif
if ( IsSelection() )
{
if ( !GetBatchCount() ) m_gridWin->Refresh( FALSE, &r );
}
}
-#else
- SelectBlock ( coords, coords );
-#endif
}
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;
+ rect.width = m_colWidths[col];
+ rect.height = m_rowHeights[row];
wxGridCellAttr* attr = GetCellAttr(row, col);
attr->GetRenderer()->Draw(*this, *attr, dc, rect, row, col, IsInSelection(coords));
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 )
if ( y < m_rowBottoms[i] ) return i;
}
- return -1;
+ return m_numRows; //-1;
}
if ( x < m_colRights[i] ) return i;
}
- return -1;
+ return m_numCols; //-1;
}