X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dfe1eee3bb9ecde8c4490ea69c07b5030d69530c..8b260fbe33b67311ab69043e8fb1bc4c4d7ac1f2:/src/generic/gridg.cpp?ds=sidebyside diff --git a/src/generic/gridg.cpp b/src/generic/gridg.cpp index 3f21090c23..cb590108cb 100644 --- a/src/generic/gridg.cpp +++ b/src/generic/gridg.cpp @@ -5,6 +5,8 @@ // 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 @@ -37,13 +39,46 @@ #include "wx/generic/gridg.h" -// Set to zero to use no double-buffering + +// Values used to adjust the size of the in-place-edit control, and other +// goodies. Per-platform tweaks should be done here. #ifdef __WXMSW__ - #define wxUSE_DOUBLE_BUFFERING 1 -#else - #define wxUSE_DOUBLE_BUFFERING 0 +#define wxIPE_ADJUST -2 +#define wxIPE_STYLE wxNO_BORDER +#define wxIPE_HIGHLIGHT 1 +#define wxUSE_DOUBLE_BUFFERING 1 +#endif + +#ifdef __WXPM__ +#define wxIPE_ADJUST -1 +#define wxIPE_STYLE wxNO_BORDER +#define wxIPE_HIGHLIGHT 1 +#define wxUSE_DOUBLE_BUFFERING 1 +#endif + +#ifdef __WXGTK__ +#define wxIPE_ADJUST -1 +#define wxIPE_STYLE wxNO_BORDER +#define wxIPE_HIGHLIGHT 0 +#define wxUSE_DOUBLE_BUFFERING 1 +#endif + +#ifdef __WXMOTIF__ +#define wxIPE_ADJUST 2 +#define wxIPE_STYLE wxNO_BORDER +#define wxIPE_HIGHLIGHT 0 +#define wxUSE_DOUBLE_BUFFERING 0 #endif +#ifndef wxIPE_ADJUST +#define wxIPE_ADJUST 2 +#define wxIPE_STYLE wxNO_BORDER +#define wxIPE_HIGHLIGHT 0 +#define wxUSE_DOUBLE_BUFFERING 0 +#endif + + + #define wxGRID_DRAG_NONE 0 #define wxGRID_DRAG_LEFT_RIGHT 1 #define wxGRID_DRAG_UP_DOWN 2 @@ -77,8 +112,10 @@ BEGIN_EVENT_TABLE(wxGenericGrid, wxPanel) 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; @@ -94,8 +131,9 @@ wxGenericGrid::wxGenericGrid(void) m_currentRectVisible = FALSE; m_editable = TRUE; - m_editInPlace = TRUE; + m_editInPlace = FALSE; m_inOnTextInPlace = FALSE; + m_inScroll = FALSE; #if defined(__WIN95__) m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X); @@ -109,6 +147,7 @@ wxGenericGrid::wxGenericGrid(void) m_dragStartPosition = 0; m_dragLastPosition = 0; m_divisionPen = wxNullPen; + m_highlightPen = wxNullPen; m_leftOfSheet = wxGRID_DEFAULT_SHEET_LEFT; m_topOfSheet = wxGRID_DEFAULT_SHEET_TOP; m_cellHeight = wxGRID_DEFAULT_CELL_HEIGHT; @@ -137,9 +176,15 @@ wxGenericGrid::wxGenericGrid(void) 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; @@ -155,6 +200,9 @@ bool wxGenericGrid::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, m_textItem = (wxTextCtrl *) NULL; m_currentRectVisible = FALSE; m_editable = TRUE; + m_editInPlace = FALSE; + m_inOnTextInPlace = FALSE; + m_inScroll = FALSE; #if defined(__WIN95__) m_scrollWidth = wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X); #elif defined(__WXGTK__) @@ -167,6 +215,7 @@ bool wxGenericGrid::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, m_dragStartPosition = 0; m_dragLastPosition = 0; m_divisionPen = * wxThePenList->FindOrCreatePen("LIGHT GREY", 1, wxSOLID); + m_highlightPen = * wxBLACK_PEN; m_doubleBufferingBitmap = (wxBitmap *) NULL; if (!m_horizontalSashCursor.Ok()) @@ -237,21 +286,22 @@ bool wxGenericGrid::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, // 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 ), + wxPoint( m_currentRect.x-wxIPE_ADJUST, m_currentRect.y-wxIPE_ADJUST ), + wxSize( m_currentRect.width+wxIPE_ADJUST*2, m_currentRect.height+wxIPE_ADJUST*2 ), wxNO_BORDER | wxTE_PROCESS_ENTER ); - m_inPlaceTextItem->Show(TRUE); - m_inPlaceTextItem->SetFocus(); + m_inPlaceTextItem->Show(m_editInPlace); + if ( m_editInPlace ) + m_inPlaceTextItem->SetFocus(); return TRUE; } -wxGenericGrid::~wxGenericGrid(void) +wxGenericGrid::~wxGenericGrid() { ClearGrid(); } -void wxGenericGrid::ClearGrid(void) +void wxGenericGrid::ClearGrid() { int i,j; if (m_gridCells) @@ -380,7 +430,7 @@ bool wxGenericGrid::CreateGrid(int nRows, int nCols, wxString **cellValues, shor } // Need to determine various dimensions -void wxGenericGrid::UpdateDimensions(void) +void wxGenericGrid::UpdateDimensions() { int canvasWidth, canvasHeight; GetSize(&canvasWidth, &canvasHeight); @@ -533,8 +583,8 @@ void wxGenericGrid::PaintGrid(wxDC& dc) /* Hilight present cell */ SetCurrentRect(m_wCursorRow, m_wCursorColumn); - if (m_currentRectVisible && !(m_editable && m_editInPlace)) - HighlightCell(& dc); + if (m_currentRectVisible && (wxIPE_HIGHLIGHT || !(m_editable && m_editInPlace))) + HighlightCell(& dc, TRUE); dc.DestroyClippingRegion(); dc.SetOptimization(TRUE); @@ -941,7 +991,7 @@ void wxGenericGrid::DrawCellValue(wxDC *dc, wxRect *rect, int row, int col) } } -void wxGenericGrid::AdjustScrollbars(void) +void wxGenericGrid::AdjustScrollbars() { int cw, ch; GetClientSize(&cw, &ch); @@ -966,56 +1016,53 @@ void wxGenericGrid::AdjustScrollbars(void) 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 @@ -1416,9 +1463,9 @@ void wxGenericGrid::OnSelectCellImplementation(wxDC *dc, int row, int col) SetGridClippingRegion(dc); // Remove the highlight from the old cell - if ( m_currentRectVisible && !(m_editable && m_editInPlace) ) + if ( m_currentRectVisible && (wxIPE_HIGHLIGHT || !(m_editable && m_editInPlace))) { - HighlightCell(dc); + HighlightCell(dc, FALSE); } @@ -1438,24 +1485,56 @@ void wxGenericGrid::OnSelectCellImplementation(wxDC *dc, int row, int col) if ( m_editable && m_editInPlace ) { - m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2, - m_currentRect.width+4, m_currentRect.height+4 ); + int x, y, width, height; + if ( m_currentRect.x <= 0 ) + { + x = 0; + width = m_currentRect.width + wxIPE_ADJUST; + } + else + { + x = m_currentRect.x - wxIPE_ADJUST; + width = m_currentRect.width + wxIPE_ADJUST*2; + } - if ( cell ) + if ( m_currentRect.y <= 0 ) { - if ( cell->GetTextValue().IsNull() ) - { + y = 0; + height = m_currentRect.height + wxIPE_ADJUST; + } + else + { + y = m_currentRect.y - wxIPE_ADJUST; + height = m_currentRect.height + wxIPE_ADJUST*2; + } + + m_inPlaceTextItem->SetSize( x, y, width, height ); + + if ( cell ) { + m_inPlaceTextItem->SetFont( cell->GetFont() ); + m_inPlaceTextItem->SetBackgroundColour(cell->GetBackgroundColour()); + m_inPlaceTextItem->SetForegroundColour(cell->GetTextColour()); + + if ( cell->GetTextValue().IsNull() ) { m_inPlaceTextItem->SetValue( "" ); - } - else - { - m_inPlaceTextItem->SetFont( cell->GetFont() ); + } + else { m_inPlaceTextItem->SetValue( cell->GetTextValue() ); - } - } + } + } m_inPlaceTextItem->Show(TRUE); m_inPlaceTextItem->SetFocus(); +#if defined(__VISAGECPP__) + { + int highlight = wxIPE_HIGHLIGHT; + if (highlight != 0) + HighlightCell(dc, TRUE); + } +#else + if (wxIPE_HIGHLIGHT != 0) + HighlightCell(dc, TRUE); +#endif } else { @@ -1466,9 +1545,9 @@ void wxGenericGrid::OnSelectCellImplementation(wxDC *dc, int row, int col) // // 3) It *is* needed for Motif - michael // -#ifdef __WXMOTIF__ - if ( !(m_editable && m_editInPlace) ) - HighlightCell(dc); +#if defined(__WXMOTIF__) + if ((wxIPE_HIGHLIGHT || !(m_editable && m_editInPlace))) + HighlightCell(dc, TRUE); #endif } @@ -1479,12 +1558,12 @@ void wxGenericGrid::OnSelectCellImplementation(wxDC *dc, int row, int 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; @@ -1510,7 +1589,7 @@ void wxGenericGrid::OnChangeLabels(void) } } -void wxGenericGrid::OnChangeSelectionLabel(void) +void wxGenericGrid::OnChangeSelectionLabel() { if (!GetEditable()) return; @@ -1525,9 +1604,13 @@ void wxGenericGrid::OnChangeSelectionLabel(void) } } -void wxGenericGrid::HighlightCell(wxDC *dc) +void wxGenericGrid::HighlightCell(wxDC *dc, bool doHighlight) { - dc->SetLogicalFunction(wxINVERT); + wxPen savePen = dc->GetPen(); + if (doHighlight) + dc->SetPen(m_highlightPen); + else + dc->SetPen(*wxThePenList->FindOrCreatePen(m_cellBackgroundColour, 1, wxSOLID)); // Top dc->DrawLine( m_currentRect.x + 1, @@ -1538,7 +1621,7 @@ void wxGenericGrid::HighlightCell(wxDC *dc) 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, @@ -1550,10 +1633,10 @@ void wxGenericGrid::HighlightCell(wxDC *dc) m_currentRect.x + 1, m_currentRect.y + 1); - dc->SetLogicalFunction(wxCOPY); + dc->SetPen(savePen); } -void wxGenericGrid::DrawCellText(void) +void wxGenericGrid::DrawCellText() { if (!m_currentRectVisible) return; @@ -1703,21 +1786,21 @@ void wxGenericGrid::DrawTextRect(wxDC *dc, const wxString& text, wxRect *rect, i { case wxRIGHT: { - x = (rect->x + rect->width - textWidth - 1.0); - y = (rect->y + (rect->height - textHeight)/2.0); + x = (rect->x + rect->width - textWidth - (float)1.0); + y = (rect->y + (rect->height - textHeight)/(float)2.0); break; } case wxCENTRE: { - x = (rect->x + (rect->width - textWidth)/2.0); - y = (rect->y + (rect->height - textHeight)/2.0); + x = (rect->x + (rect->width - textWidth)/(float)2.0); + y = (rect->y + (rect->height - textHeight)/(float)2.0); break; } case wxLEFT: default: { - x = (rect->x + 1.0); - y = (rect->y + (rect->height - textHeight)/2.0); + x = (rect->x + (float)1.0); + y = (rect->y + (rect->height - textHeight)/(float)2.0); break; } } @@ -2062,23 +2145,25 @@ void wxGenericGrid::SetEditInPlace(bool edit) { if ( m_currentRectVisible && m_editable ) { - m_inPlaceTextItem->SetSize( m_currentRect.x-2, m_currentRect.y-2, - m_currentRect.width+4, m_currentRect.height+4 ); + m_inPlaceTextItem->SetSize( m_currentRect.x-wxIPE_ADJUST, + m_currentRect.y-wxIPE_ADJUST, + m_currentRect.width+wxIPE_ADJUST*2, + m_currentRect.height+wxIPE_ADJUST*2 ); wxGridCell *cell = GetCell(m_wCursorRow, m_wCursorColumn); - if ( cell ) - { - if ( cell->GetTextValue().IsNull() ) - { + if ( cell ) { + m_inPlaceTextItem->SetFont( cell->GetFont() ); + m_inPlaceTextItem->SetBackgroundColour(cell->GetBackgroundColour()); + m_inPlaceTextItem->SetForegroundColour(cell->GetTextColour()); + + if ( cell->GetTextValue().IsNull() ) { m_inPlaceTextItem->SetValue( "" ); - } - else - { - m_inPlaceTextItem->SetFont( cell->GetFont() ); + } + else { m_inPlaceTextItem->SetValue( cell->GetTextValue() ); - } - } + } + } m_inPlaceTextItem->Show( TRUE ); m_inPlaceTextItem->SetFocus(); @@ -2492,8 +2577,8 @@ void wxGenericGrid::SetGridCursor(int row, int col) SetGridClippingRegion(& dc); - if (m_currentRectVisible && !(m_editable && m_editInPlace) ) - HighlightCell(& dc); + if (m_currentRectVisible && (wxIPE_HIGHLIGHT || !(m_editable && m_editInPlace))) + HighlightCell(& dc, FALSE); m_wCursorRow = row; m_wCursorColumn = col; @@ -2503,16 +2588,16 @@ void wxGenericGrid::SetGridCursor(int row, int col) SetCurrentRect(row, col, cw, ch); - if (m_currentRectVisible && !(m_editable && m_editInPlace) ) - HighlightCell(& dc); + if (m_currentRectVisible && (wxIPE_HIGHLIGHT || !(m_editable && m_editInPlace))) + HighlightCell(& dc, TRUE); dc.DestroyClippingRegion(); dc.EndDrawing(); } -/* - * Grid cell - */ +// ---------------------------------------------------------------------------- +// Grid cell +// ---------------------------------------------------------------------------- wxGridCell::wxGridCell(wxGenericGrid *window) { @@ -2539,9 +2624,11 @@ wxGridCell::wxGridCell(wxGenericGrid *window) alignment = window->GetCellAlignment(); else alignment = wxLEFT; + + cellData = (void *)NULL; } -wxGridCell::~wxGridCell(void) +wxGridCell::~wxGridCell() { } @@ -2569,15 +2656,17 @@ void wxGenericGrid::OnText(wxCommandEvent& WXUNUSED(ev) ) m_inPlaceTextItem->SetValue( grid->GetTextItem()->GetValue() ); } - wxClientDC dc(grid); + if (!m_editInPlace) { + wxClientDC dc(grid); - 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(); + 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, TRUE); + dc.DestroyClippingRegion(); + dc.EndDrawing(); + } //grid->OnCellChange(grid->GetCursorRow(), grid->GetCursorColumn()); wxGridEvent g_evt(GetId(), wxEVT_GRID_CELL_CHANGE, grid, @@ -2645,14 +2734,12 @@ void wxGenericGrid::OnTextInPlaceEnter(wxCommandEvent& WXUNUSED(ev) ) void wxGenericGrid::OnGridScroll(wxScrollEvent& ev) { - static bool inScroll = FALSE; - - if ( inScroll ) + if ( m_inScroll ) return; if ( m_editInPlace ) m_inPlaceTextItem->Show(FALSE); - inScroll = TRUE; + m_inScroll = TRUE; wxGenericGrid *win = this; bool change = FALSE; @@ -2681,13 +2768,15 @@ void wxGenericGrid::OnGridScroll(wxScrollEvent& ev) 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->SetSize( m_currentRect.x-wxIPE_ADJUST, + m_currentRect.y-wxIPE_ADJUST, + m_currentRect.width+wxIPE_ADJUST*2, + m_currentRect.height+wxIPE_ADJUST*2 ); m_inPlaceTextItem->Show( TRUE ); m_inPlaceTextItem->SetFocus(); } - inScroll = FALSE; + m_inScroll = FALSE; } @@ -2741,4 +2830,25 @@ void wxGenericGrid::_OnLabelRightClick(wxGridEvent& ev) 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; +}