// Name: gridg.cpp
// Purpose: wxGenericGrid
// Author: Julian Smart
-// Modified by:
+// Modified by: Michael Bedward
+// Added edit in place facility, 20 Apr 1999
+// Added cursor key control, 29 Jun 1999
+// Gerhard Gruber
+// Added keyboard navigation, client data, other fixes
// Created: 04/01/98
// RCS-ID: $Id$
// Copyright: (c) Julian Smart and Markus Holzem
-// Licence: wxWindows license
+// Licence: wxWindows license
/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
-#pragma implementation "gridg.h"
-#pragma interface
+ #pragma implementation "gridg.h"
+ #pragma interface
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
-#pragma hdrstop
+ #pragma hdrstop
#endif
#ifndef WX_PRECOMP
-#include "wx/wx.h"
+ #include "wx/utils.h"
+ #include "wx/dcclient.h"
+ #include "wx/dcmemory.h"
+ #include "wx/textctrl.h"
+ #include "wx/settings.h"
#endif
#include <string.h>
#include "wx/string.h"
+
#include "wx/generic/gridg.h"
-#include "wx/settings.h"
// Set to zero to use no double-buffering
#ifdef __WXMSW__
-#define wxUSE_DOUBLE_BUFFERING 1
+ #define wxUSE_DOUBLE_BUFFERING 1
#else
-#define wxUSE_DOUBLE_BUFFERING 0
+ #define wxUSE_DOUBLE_BUFFERING 0
#endif
#define wxGRID_DRAG_NONE 0
EVT_ERASE_BACKGROUND(wxGenericGrid::OnEraseBackground)
EVT_MOUSE_EVENTS(wxGenericGrid::OnMouseEvent)
EVT_TEXT(wxGRID_TEXT_CTRL, wxGenericGrid::OnText)
+ EVT_TEXT(wxGRID_EDIT_IN_PLACE_TEXT_CTRL, wxGenericGrid::OnTextInPlace)
+ EVT_TEXT_ENTER(wxGRID_TEXT_CTRL, wxGenericGrid::OnTextEnter)
+ EVT_TEXT_ENTER(wxGRID_EDIT_IN_PLACE_TEXT_CTRL, wxGenericGrid::OnTextInPlaceEnter)
EVT_COMMAND_SCROLL(wxGRID_HSCROLL, wxGenericGrid::OnGridScroll)
EVT_COMMAND_SCROLL(wxGRID_VSCROLL, wxGenericGrid::OnGridScroll)
END_EVENT_TABLE()
-
-
-wxGenericGrid::wxGenericGrid(void)
+wxGenericGrid::wxGenericGrid()
{
+ m_viewWidth = 0;
+ m_viewHeight = 0;
m_batchCount = 0;
m_hScrollBar = (wxScrollBar *) NULL;
m_vScrollBar = (wxScrollBar *) NULL;
m_textItem = (wxTextCtrl *) NULL;
m_currentRectVisible = FALSE;
m_editable = TRUE;
+
+ m_editInPlace = TRUE;
+ m_inOnTextInPlace = FALSE;
+
#if defined(__WIN95__)
m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X);
#elif defined(__WXGTK__)
m_textItem = (wxTextCtrl *) NULL;
}
-bool wxGenericGrid::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size,
- long style, const wxString& name)
+bool wxGenericGrid::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name)
{
+ m_viewWidth = 0;
+ m_viewHeight = 0;
m_batchCount = 0;
m_editingPanel = (wxPanel *) NULL;
m_hScrollBar = (wxScrollBar *) NULL;
m_editingPanel = new wxPanel(this);
m_textItem = new wxTextCtrl(m_editingPanel, wxGRID_TEXT_CTRL, "",
- wxPoint(m_editControlPosition.x, m_editControlPosition.y), wxSize(m_editControlPosition.width, -1),
- 0);
+ wxPoint(m_editControlPosition.x, m_editControlPosition.y),
+ wxSize(m_editControlPosition.width, -1),
+ wxTE_PROCESS_ENTER);
m_textItem->Show(TRUE);
m_textItem->SetFocus();
int controlW, controlH;
// SetSize(pos.x, pos.y, size.x, size.y);
+ m_inPlaceTextItem = new wxTextCtrl( (wxPanel*)this, wxGRID_EDIT_IN_PLACE_TEXT_CTRL, "",
+ wxPoint( m_currentRect.x-2, m_currentRect.y-2 ),
+ wxSize( m_currentRect.width+4, m_currentRect.height+4 ),
+ wxNO_BORDER | wxTE_PROCESS_ENTER );
+ m_inPlaceTextItem->Show(TRUE);
+ m_inPlaceTextItem->SetFocus();
+
return TRUE;
}
-wxGenericGrid::~wxGenericGrid(void)
+wxGenericGrid::~wxGenericGrid()
{
ClearGrid();
}
-void wxGenericGrid::ClearGrid(void)
+void wxGenericGrid::ClearGrid()
{
int i,j;
if (m_gridCells)
}
// Need to determine various dimensions
-void wxGenericGrid::UpdateDimensions(void)
+void wxGenericGrid::UpdateDimensions()
{
int canvasWidth, canvasHeight;
GetSize(&canvasWidth, &canvasHeight);
/* Hilight present cell */
SetCurrentRect(m_wCursorRow, m_wCursorColumn);
- if (m_currentRectVisible)
+ if (m_currentRectVisible && !(m_editable && m_editInPlace))
HighlightCell(& dc);
dc.DestroyClippingRegion();
rect2.height -= 4;
dc->SetTextForeground(GetLabelTextColour());
dc->SetFont(GetLabelTextFont());
- if ( !cell->GetTextValue().IsNull() )
- DrawTextRect(dc, cell->GetTextValue(), &rect2, GetLabelAlignment(wxHORIZONTAL));
+ if ( !cell->GetTextValue().IsNull() )
+ DrawTextRect(dc, cell->GetTextValue(), &rect2, GetLabelAlignment(wxHORIZONTAL));
}
}
rect2.height -= 4;
dc->SetTextForeground(GetLabelTextColour());
dc->SetFont(GetLabelTextFont());
- if ( !cell->GetTextValue().IsNull() )
- DrawTextRect(dc, cell->GetTextValue(), &rect2, GetLabelAlignment(wxVERTICAL));
+ if ( !cell->GetTextValue().IsNull() )
+ DrawTextRect(dc, cell->GetTextValue(), &rect2, GetLabelAlignment(wxVERTICAL));
}
}
dc->SetTextForeground(cell->GetTextColour());
dc->SetFont(cell->GetFont());
- if ( !cell->GetTextValue().IsNull() )
- DrawTextRect(dc, cell->GetTextValue(), &rect2, cell->GetAlignment());
+ if ( !cell->GetTextValue().IsNull() )
+ DrawTextRect(dc, cell->GetTextValue(), &rect2, cell->GetAlignment());
}
}
}
-void wxGenericGrid::AdjustScrollbars(void)
+void wxGenericGrid::AdjustScrollbars()
{
int cw, ch;
GetClientSize(&cw, &ch);
int noHorizSteps = 0;
int noVertSteps = 0;
- if (m_totalGridWidth + vertScrollBarWidth <= cw)
- noHorizSteps = 0;
- else
+ if (m_totalGridWidth + vertScrollBarWidth > cw)
{
- noHorizSteps = 0;
int widthCount = 0;
int i;
- int nx = 0;
+ int nx = 0;
for (i = m_scrollPosX ; i < m_totalCols; i++)
{
widthCount += m_colWidths[i];
- // A partial bit doesn't count, we still have to scroll to see the
- // rest of it
+ // A partial bit doesn't count, we still have to scroll to see the
+ // rest of it
if (widthCount + m_leftOfSheet + m_verticalLabelWidth > (cw-vertScrollBarWidth))
break;
- else
- nx ++;
-
+ else
+ nx ++;
}
noHorizSteps += nx;
}
- if (m_totalGridHeight + horizScrollBarHeight <= ch)
- noVertSteps = 0;
- else
+ m_viewWidth = noHorizSteps;
+
+ if (m_totalGridHeight + horizScrollBarHeight > ch)
{
- noVertSteps = 0;
int heightCount = 0;
int i;
- int ny = 0;
+ int ny = 0;
for (i = m_scrollPosY ; i < m_totalRows; i++)
{
heightCount += m_rowHeights[i];
- // A partial bit doesn't count, we still have to scroll to see the
- // rest of it
+ // A partial bit doesn't count, we still have to scroll to see the
+ // rest of it
if (heightCount + m_topOfSheet + m_horizontalLabelHeight > (ch-horizScrollBarHeight))
break;
- else
- ny ++;
+ else
+ ny ++;
}
noVertSteps += ny;
}
+ m_viewHeight = noVertSteps;
+
if (m_totalGridWidth + vertScrollBarWidth <= cw)
{
- if ( m_hScrollBar )
- m_hScrollBar->Show(FALSE);
+ if ( m_hScrollBar )
+ m_hScrollBar->Show(FALSE);
SetScrollPosX(0);
}
else
void wxGenericGrid::OnSize(wxSizeEvent& WXUNUSED(event) )
{
if (!m_vScrollBar || !m_hScrollBar)
- return;
+ return;
AdjustScrollbars();
SetCursor(*wxSTANDARD_CURSOR);
int cw, ch;
GetClientSize(&cw, &ch);
- wxSizeEvent evt;
+ wxSizeEvent evt;
OnSize(evt);
break;
}
SetGridClippingRegion(dc);
// Remove the highlight from the old cell
- if (m_currentRectVisible)
- HighlightCell(dc);
+ if ( m_currentRectVisible && !(m_editable && m_editInPlace) )
+ {
+ HighlightCell(dc);
+ }
+
// Highlight the new cell and copy its content to the edit control
SetCurrentRect(m_wCursorRow, m_wCursorColumn);
wxGridCell *cell = GetCell(m_wCursorRow, m_wCursorColumn);
if (cell)
{
- if ( cell->GetTextValue().IsNull() )
- m_textItem->SetValue("");
- else
- m_textItem->SetValue(cell->GetTextValue());
+ if ( cell->GetTextValue().IsNull() )
+ m_textItem->SetValue("");
+ else
+ m_textItem->SetValue(cell->GetTextValue());
}
SetGridClippingRegion(dc);
- // 1) Why isn't this needed for Windows??
- // Probably because of the SetValue?? JS.
- // 2) Arrrrrgh. This isn't needed anywhere,
- // of course. One hour of debugging... RR.
+
+ if ( m_editable && m_editInPlace )
+ {
+ int x, y, width, height;
+ if ( m_currentRect.x <= 0 )
+ {
+ x = 0;
+ width = m_currentRect.width + 2;
+ }
+ else
+ {
+ x = m_currentRect.x - 2;
+ width = m_currentRect.width + 4;
+ }
+
+ if ( m_currentRect.y <= 0 )
+ {
+ y = 0;
+ height = m_currentRect.height + 2;
+ }
+ else
+ {
+ y = m_currentRect.y - 2;
+ height = m_currentRect.height + 4;
+ }
+
+ m_inPlaceTextItem->SetSize( x, y, width, height );
+
+ if ( cell )
+ {
+ if ( cell->GetTextValue().IsNull() )
+ {
+ m_inPlaceTextItem->SetValue( "" );
+ }
+ else
+ {
+ m_inPlaceTextItem->SetFont( cell->GetFont() );
+ m_inPlaceTextItem->SetValue( cell->GetTextValue() );
+ }
+ }
+
+ m_inPlaceTextItem->Show(TRUE);
+ m_inPlaceTextItem->SetFocus();
+ }
+ else
+ {
+ // 1) Why isn't this needed for Windows??
+ // Probably because of the SetValue?? JS.
+ // 2) Arrrrrgh. This isn't needed anywhere,
+ // of course. One hour of debugging... RR.
+ //
+ // 3) It *is* needed for Motif - michael
+ //
#ifdef __WXMOTIF__
- HighlightCell(dc);
-#endif // motif
+ if ( !(m_editable && m_editInPlace) )
+ HighlightCell(dc);
+#endif
+ }
dc->DestroyClippingRegion();
- //OnSelectCell(row, col);
+ OnSelectCell(row, col);
wxGridEvent g_evt2(GetId(), wxEVT_GRID_SELECT_CELL, this, row, col);
GetEventHandler()->ProcessEvent(g_evt2);
}
-wxGridCell *wxGenericGrid::OnCreateCell(void)
+wxGridCell *wxGenericGrid::OnCreateCell()
{
return new wxGridCell(this);
}
-void wxGenericGrid::OnChangeLabels(void)
+void wxGenericGrid::OnChangeLabels()
{
char buf[100];
int i;
}
}
-void wxGenericGrid::OnChangeSelectionLabel(void)
+void wxGenericGrid::OnChangeSelectionLabel()
{
if (!GetEditable())
return;
dc->DrawLine( m_currentRect.x + 1,
m_currentRect.y + 1,
m_currentRect.x + m_currentRect.width - 1,
- m_currentRect.y + 1);
+ m_currentRect.y + 1);
// Right
dc->DrawLine( m_currentRect.x + m_currentRect.width - 1,
m_currentRect.y + 1,
m_currentRect.x + m_currentRect.width - 1,
- m_currentRect.y +m_currentRect.height - 1 );
+ m_currentRect.y +m_currentRect.height - 1 );
// Bottom
dc->DrawLine( m_currentRect.x + m_currentRect.width - 1,
m_currentRect.y + m_currentRect.height - 1,
m_currentRect.x + 1,
- m_currentRect.y + m_currentRect.height - 1);
+ m_currentRect.y + m_currentRect.height - 1);
// Left
dc->DrawLine( m_currentRect.x + 1,
m_currentRect.y + m_currentRect.height - 1,
- m_currentRect.x + 1,
- m_currentRect.y + 1);
+ m_currentRect.x + 1,
+ m_currentRect.y + 1);
dc->SetLogicalFunction(wxCOPY);
}
-void wxGenericGrid::DrawCellText(void)
+void wxGenericGrid::DrawCellText()
{
if (!m_currentRectVisible)
return;
if (!cell)
return;
- static char szEdit[300];
-
wxClientDC dc(this);
dc.BeginDrawing();
dc.SetBackgroundMode(wxTRANSPARENT);
dc.SetBrush(cell->GetBackgroundBrush());
- strcpy(szEdit, m_textItem->GetValue());
+ wxString editValue = m_textItem->GetValue();
wxRect rect;
rect = m_currentRect;
rect.width -= 5;
rect.height -= 4;
+ // FIXME: what's this string of spaces supposed to represent?
DrawTextRect(& dc, " ", &rect, wxLEFT);
- DrawTextRect(& dc, szEdit, &rect, cell->GetAlignment());
+ DrawTextRect(& dc, editValue, &rect, cell->GetAlignment());
dc.DestroyClippingRegion();
m_textItem->Show(TRUE);
m_textItem->SetFocus();
}
+
+ if (m_inPlaceTextItem)
+ {
+ m_inPlaceTextItem->Show(TRUE);
+ m_inPlaceTextItem->SetFocus();
+ }
}
else
{
m_textItem->Show(FALSE);
m_editingPanel->Show(FALSE);
}
+
+ if ( m_inPlaceTextItem )
+ {
+ m_inPlaceTextItem->Show(FALSE);
+ }
}
UpdateDimensions();
SetCurrentRect(GetCursorRow(), GetCursorColumn());
*/
}
+
+void wxGenericGrid::SetEditInPlace(bool edit)
+{
+ if ( m_editInPlace != edit )
+ {
+ m_editInPlace = edit;
+
+ if ( m_editInPlace ) // switched on
+ {
+ if ( m_currentRectVisible && m_editable )
+ {
+ m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2,
+ m_currentRect.width+4, m_currentRect.height+4 );
+
+ wxGridCell *cell = GetCell(m_wCursorRow, m_wCursorColumn);
+
+ if ( cell )
+ {
+ if ( cell->GetTextValue().IsNull() )
+ {
+ m_inPlaceTextItem->SetValue( "" );
+ }
+ else
+ {
+ m_inPlaceTextItem->SetFont( cell->GetFont() );
+ m_inPlaceTextItem->SetValue( cell->GetTextValue() );
+ }
+ }
+
+ m_inPlaceTextItem->Show( TRUE );
+ m_inPlaceTextItem->SetFocus();
+ }
+ }
+ else // switched off
+ {
+ m_inPlaceTextItem->Show( FALSE );
+ }
+ }
+}
+
+
void wxGenericGrid::SetCellAlignment(int flag, int row, int col)
{
wxGridCell *cell = GetCell(row, col);
SetGridClippingRegion(& dc);
- if (m_currentRectVisible)
+ if (m_currentRectVisible && !(m_editable && m_editInPlace) )
HighlightCell(& dc);
m_wCursorRow = row;
SetCurrentRect(row, col, cw, ch);
- if (m_currentRectVisible)
+ if (m_currentRectVisible && !(m_editable && m_editInPlace) )
HighlightCell(& dc);
dc.DestroyClippingRegion();
dc.EndDrawing();
}
-/*
- * Grid cell
- */
+// ----------------------------------------------------------------------------
+// Grid cell
+// ----------------------------------------------------------------------------
wxGridCell::wxGridCell(wxGenericGrid *window)
{
alignment = window->GetCellAlignment();
else
alignment = wxLEFT;
+
+ cellData = (void *)NULL;
}
-wxGridCell::~wxGridCell(void)
+wxGridCell::~wxGridCell()
{
}
void wxGenericGrid::OnText(wxCommandEvent& WXUNUSED(ev) )
{
- wxGenericGrid *grid = this;
- wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn());
- if (cell && grid->CurrentCellVisible())
- {
- cell->SetTextValue(grid->GetTextItem()->GetValue());
- wxClientDC dc(grid);
+ // michael - added this conditional to prevent change to
+ // grid cell text when edit control is hidden but still has
+ // focus
+ //
+ if ( m_editable )
+ {
+ wxGenericGrid *grid = this;
+ wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn());
+ if (cell && grid->CurrentCellVisible())
+ {
+ cell->SetTextValue(grid->GetTextItem()->GetValue());
+ if ( m_editInPlace && !m_inOnTextInPlace )
+ {
+ m_inPlaceTextItem->SetValue( grid->GetTextItem()->GetValue() );
+ }
- dc.BeginDrawing();
- grid->SetGridClippingRegion(& dc);
- grid->DrawCellBackground(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn());
- grid->DrawCellValue(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn());
- grid->HighlightCell(& dc);
- dc.DestroyClippingRegion();
- dc.EndDrawing();
+ wxClientDC dc(grid);
- //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
- wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_CHANGE, grid,
- grid->GetCursorRow(), grid->GetCursorColumn());
- GetEventHandler()->ProcessEvent(g_evt);
+ dc.BeginDrawing();
+ grid->SetGridClippingRegion(& dc);
+ grid->DrawCellBackground(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn());
+ grid->DrawCellValue(& dc, &grid->GetCurrentRect(), grid->GetCursorRow(), grid->GetCursorColumn());
+ if ( !(m_editable && m_editInPlace ) ) grid->HighlightCell(& dc);
+ dc.DestroyClippingRegion();
+ dc.EndDrawing();
-// grid->DrawCellText();
- }
+ //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn());
+ wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_CHANGE, grid,
+ grid->GetCursorRow(), grid->GetCursorColumn());
+ GetEventHandler()->ProcessEvent(g_evt);
+
+ // grid->DrawCellText();
+ }
+ }
+}
+
+void wxGenericGrid::OnTextEnter(wxCommandEvent& WXUNUSED(ev) )
+{
+ // move the cursor down the current row (if possible)
+ // when the enter key has been pressed
+ //
+ if ( m_editable )
+ {
+ if ( GetCursorRow() < GetRows()-1 )
+ {
+ wxClientDC dc( this );
+ dc.BeginDrawing();
+ OnSelectCellImplementation(& dc,
+ GetCursorRow()+1,
+ GetCursorColumn() );
+ dc.EndDrawing();
+ }
+ }
+}
+
+void wxGenericGrid::OnTextInPlace(wxCommandEvent& ev )
+{
+ if ( m_editable )
+ {
+ wxGenericGrid *grid = this;
+ wxGridCell *cell = grid->GetCell(grid->GetCursorRow(), grid->GetCursorColumn());
+ if (cell && grid->CurrentCellVisible())
+ {
+ m_inOnTextInPlace = TRUE;
+ grid->GetTextItem()->SetValue( m_inPlaceTextItem->GetValue() );
+ OnText( ev );
+ m_inOnTextInPlace = FALSE;
+ }
+ }
+}
+
+void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent& WXUNUSED(ev) )
+{
+ // move the cursor down the current row (if possible)
+ // when the enter key has been pressed
+ //
+ if ( m_editable )
+ {
+ if ( GetCursorRow() < GetRows()-1 )
+ {
+ wxClientDC dc( this );
+ dc.BeginDrawing();
+ OnSelectCellImplementation(& dc,
+ GetCursorRow()+1,
+ GetCursorColumn() );
+ dc.EndDrawing();
+ }
+ }
}
void wxGenericGrid::OnGridScroll(wxScrollEvent& ev)
static bool inScroll = FALSE;
if ( inScroll )
- return;
+ return;
+
+ if ( m_editInPlace ) m_inPlaceTextItem->Show(FALSE);
inScroll = TRUE;
wxGenericGrid *win = this;
AdjustScrollbars();
if (change) win->Refresh(FALSE);
+
+ if ( m_editInPlace && m_currentRectVisible )
+ {
+ m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2,
+ m_currentRect.width+4, m_currentRect.height+4 );
+ m_inPlaceTextItem->Show( TRUE );
+ m_inPlaceTextItem->SetFocus();
+ }
+
inScroll = FALSE;
}
OnLabelRightClick(ev.m_row, ev.m_col, ev.m_x, ev.m_y, ev.m_control, ev.m_shift);
}
+void *wxGenericGrid::SetCellData(void *data, int row, int col)
+{
+ void *rc = NULL;
+
+ wxGridCell *cell = GetCell(row, col);
+ if ( cell )
+ rc = cell->SetCellData(data);
+
+ return rc;
+}
+
+void *wxGenericGrid::GetCellData(int row, int col)
+{
+ void *rc = NULL;
+
+ wxGridCell *cell = GetCell(row, col);
+ if ( cell )
+ rc = cell->GetCellData();
+
+ return rc;
+}