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:
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()
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()
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)
void ScrollWindow( int dx, int dy, const wxRect *rect );
+ virtual bool AcceptsFocus() const { return true; }
+
private:
wxGridRowLabelWindow *m_rowLabelWin;
wxGridColLabelWindow *m_colLabelWin;
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
wxWindowID id,
wxEvtHandler* evtHandler)
{
+ DoCreate(parent, id, evtHandler);
+}
+
+void wxGridCellTextEditor::DoCreate(wxWindow* parent,
+ wxWindowID id,
+ wxEvtHandler* evtHandler,
+ long style)
+{
+ style |= wxTE_PROCESS_ENTER |
+ wxTE_PROCESS_TAB |
+ wxTE_AUTO_SCROLL |
+ wxNO_BORDER;
+
m_control = new wxTextCtrl(parent, id, wxEmptyString,
- wxDefaultPosition, wxDefaultSize
-#if defined(__WXMSW__)
- ,
- wxTE_PROCESS_ENTER |
- wxTE_PROCESS_TAB |
- wxTE_AUTO_SCROLL |
- wxNO_BORDER
-#endif
- );
+ wxDefaultPosition, wxDefaultSize,
+ style);
// set max length allowed in the textctrl, if the parameter was set
- if (m_maxChars != 0)
+ if ( m_maxChars != 0 )
{
- ((wxTextCtrl*)m_control)->SetMaxLength(m_maxChars);
+ Text()->SetMaxLength(m_maxChars);
}
wxGridCellEditor::Create(parent, id, evtHandler);
wxWindowID id,
wxEvtHandler* evtHandler)
{
+ 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,
- m_allowOthers ? 0 : wxCB_READONLY);
+ style);
wxGridCellEditor::Create(parent, id, evtHandler);
}
if (m_allowOthers)
{
Combo()->SetValue(m_startValue);
+ Combo()->SetInsertionPointEnd();
}
- else
+ else // the combobox is read-only
{
// find the right position, or default to the first if not found
int pos = Combo()->FindString(m_startValue);
Combo()->SetSelection(pos);
}
- Combo()->SetInsertionPointEnd();
Combo()->SetFocus();
if (evtHandler)
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 );
wxDC& dc,
bool isSelected)
{
- dc.SetBackgroundMode( wxTRANSPARENT );
+ dc.SetBackgroundMode( wxBRUSHSTYLE_TRANSPARENT );
// TODO some special colours for attr.IsReadOnly() case?
{
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
wxSize size = checkbox->GetBestSize();
wxCoord checkSize = size.y + 2 * wxGRID_CHECKMARK_MARGIN;
- // FIXME wxGTK::wxCheckBox::GetBestSize() gives "wrong" result
-#if defined(__WXGTK__) || defined(__WXMOTIF__)
+#if defined(__WXMOTIF__)
checkSize -= size.y / 2;
#endif
if ( size.x >= minSize || size.y >= minSize )
{
// and even leave (at least) 1 pixel margin
- size.x = size.y = minSize - 2;
+ size.x = size.y = minSize;
}
// draw a border around checkmark
value = wxGridCellBoolEditor::IsTrueValue(cellval);
}
- if ( value )
- {
- wxRect rectMark = rectBorder;
+ int flags = 0;
+ if (value)
+ flags |= wxCONTROL_CHECKED;
-#ifdef __WXMSW__
- // MSW DrawCheckMark() is weird (and should probably be changed...)
- rectMark.Inflate(-wxGRID_CHECKMARK_MARGIN / 2);
- rectMark.x++;
- rectMark.y++;
-#else
- rectMark.Inflate(-wxGRID_CHECKMARK_MARGIN);
-#endif
-
- dc.SetTextForeground(attr.GetTextColour());
- dc.DrawCheckMark(rectMark);
- }
-
- dc.SetBrush(*wxTRANSPARENT_BRUSH);
- dc.SetPen(wxPen(attr.GetTextColour(), 1, wxSOLID));
- dc.DrawRectangle(rectBorder);
+ wxRendererNative::Get().DrawCheckBox( &grid, dc, rectBorder, flags );
}
// ----------------------------------------------------------------------------
int n = FindIndex(row, col);
if ( n == wxNOT_FOUND )
{
- // add the attribute
- m_attrs.Add(new wxGridCellWithAttr(row, col, attr));
+ if ( attr )
+ {
+ // add the attribute
+ m_attrs.Add(new wxGridCellWithAttr(row, col, attr));
+ }
+ //else: nothing to do
}
else
{
wxGridRowOrColAttrData::~wxGridRowOrColAttrData()
{
- size_t count = m_attrs.Count();
+ size_t count = m_attrs.GetCount();
for ( size_t n = 0; n < count; n++ )
{
m_attrs[n]->DecRef();
int i = m_rowsOrCols.Index(rowOrCol);
if ( i == wxNOT_FOUND )
{
- // add the attribute
- m_rowsOrCols.Add(rowOrCol);
- m_attrs.Add(attr);
+ if ( attr )
+ {
+ // add the attribute
+ m_rowsOrCols.Add(rowOrCol);
+ m_attrs.Add(attr);
+ }
+ // nothing to remove
}
else
{
wxGridTypeRegistry::~wxGridTypeRegistry()
{
- size_t count = m_typeinfo.Count();
+ size_t count = m_typeinfo.GetCount();
for ( size_t i = 0; i < count; i++ )
delete m_typeinfo[i];
}
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,
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 )
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,
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 )
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,
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 );
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 )
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;
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();
}
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,
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,
Create();
SetInitialSize(size);
+ CalcDimensions();
return true;
}
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;
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;
m_dragRowOrCol = -1;
m_isDragging = false;
m_startDragPos = wxDefaultPosition;
+ m_nativeColumnLabels = false;
m_waitForSlowClick = false;
}
}
+ // 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
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
if ( CanDragRowSize() && CanDragGridSize() )
- ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW);
+ ChangeCursorMode(WXGRID_CURSOR_RESIZE_ROW, NULL, false);
}
}
else if ( dragCol >= 0 )
if ( m_cursorMode == WXGRID_CURSOR_SELECT_CELL )
{
if ( CanDragColSize() && CanDragGridSize() )
- ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL);
+ ChangeCursorMode(WXGRID_CURSOR_RESIZE_COL, NULL, false);
}
}
else // Neither on a row or col edge
{
// 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);
void wxGrid::OnSize(wxSizeEvent& WXUNUSED(event))
{
- // update our children window positions and scrollbars
- CalcDimensions();
+ if (m_targetWindow != this) // check whether initialisation has been done
+ {
+ // update our children window positions and scrollbars
+ CalcDimensions();
+ }
}
void wxGrid::OnKeyDown( wxKeyEvent& event )
return;
}
-#if !(defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS)
+#if !defined(__WXMAC__)
wxClientDC dc( m_gridWin );
PrepareDC( dc );
#endif
// Otherwise refresh redraws the highlight!
m_currentCellCoords = coords;
-#if defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS
+#if defined(__WXMAC__)
m_gridWin->Refresh(true /*, & r */);
#else
DrawGridCellArea( dc, cells );
m_currentCellCoords = coords;
wxGridCellAttr *attr = GetCellAttr( coords );
-#if !(defined(__WXMAC__) && wxMAC_USE_CORE_GRAPHICS)
+#if !defined(__WXMAC__)
DrawCellHighlight( dc, attr );
#endif
attr->DecRef();
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 )
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();
// 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);
}
wxPen wxGrid::GetDefaultGridLinePen()
{
- return wxPen(GetGridLineColour(), 1, wxSOLID);
+ return wxPen(GetGridLineColour(), 1, wxPENSTYLE_SOLID);
}
wxPen wxGrid::GetRowGridLinePen(int WXUNUSED(row))
int rightCol = GetColPos( internalXToCol(right) );
int bottomRow = internalYToRow(bottom);
-#if !defined(__WXMAC__) || wxMAC_USE_CORE_GRAPHICS
wxRegion clippedcells(0, 0, cw, ch);
int i, j, cell_rows, cell_cols;
}
}
}
-#else
- wxRegion clippedcells( left, top, right - left, bottom - top );
- int i, j, cell_rows, cell_cols;
- wxRect rect;
-
- for (j=topRow; j<=bottomRow; j++)
- {
- for (i=leftCol; i<=rightCol; i++)
- {
- GetCellSize( j, i, &cell_rows, &cell_cols );
- if ((cell_rows > 1) || (cell_cols > 1))
- {
- rect = CellToRect(j, i);
- clippedcells.Subtract(rect);
- }
- else if ((cell_rows < 0) || (cell_cols < 0))
- {
- rect = CellToRect(j + cell_rows, i + cell_cols);
- clippedcells.Subtract(rect);
- }
- }
- }
-#endif
-
- dc.SetClippingRegion( clippedcells );
+ dc.SetDeviceClippingRegion( clippedcells );
// horizontal grid lines
wxRect rect;
-#if 0
-def __WXGTK20__
- rect.SetX( 1 );
- rect.SetY( GetRowTop(row) + 1 );
- rect.SetWidth( m_rowLabelWidth - 2 );
- rect.SetHeight( GetRowHeight(row) - 2 );
-
- CalcScrolledPosition( 0, rect.y, NULL, &rect.y );
-
- wxWindowDC *win_dc = (wxWindowDC*) &dc;
-
- wxRendererNative::Get().DrawHeaderButton( win_dc->m_owner, dc, rect, 0 );
-#else
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 );
dc.SetPen( *wxWHITE_PEN );
dc.DrawLine( 1, rowTop, 1, rowBottom );
dc.DrawLine( 1, rowTop, m_rowLabelWidth - 1, rowTop );
-#endif
- dc.SetBackgroundMode( wxTRANSPARENT );
+ dc.SetBackgroundMode( wxBRUSHSTYLE_TRANSPARENT );
dc.SetTextForeground( GetLabelTextColour() );
dc.SetFont( GetLabelFont() );
DrawTextRectangle( dc, GetRowLabelValue( row ), rect, hAlign, vAlign );
}
+void wxGrid::SetUseNativeColLabels( bool native )
+{
+ m_nativeColumnLabels = native;
+ if (native)
+ {
+ int height = wxRendererNative::Get().GetHeaderButtonHeight( this );
+ SetColLabelSize( height );
+ }
+
+ m_colLabelWin->Refresh();
+}
+
void wxGrid::DrawColLabels( wxDC& dc,const wxArrayInt& cols )
{
if ( !m_numCols )
wxRect rect;
-#if 0
-def __WXGTK20__
- rect.SetX( colLeft + 1 );
- rect.SetY( 1 );
- rect.SetWidth( GetColWidth(col) - 2 );
- rect.SetHeight( m_colLabelHeight - 2 );
-
- wxWindowDC *win_dc = (wxWindowDC*) &dc;
+ if (m_nativeColumnLabels)
+ {
+ rect.SetX( colLeft);
+ rect.SetY( 0 );
+ rect.SetWidth( GetColWidth(col));
+ rect.SetHeight( m_colLabelHeight );
- wxRendererNative::Get().DrawHeaderButton( win_dc->m_owner, dc, rect, 0 );
-#else
- int colRight = GetColRight(col) - 1;
+ wxWindowDC *win_dc = (wxWindowDC*) &dc;
+ wxRendererNative::Get().DrawHeaderButton( win_dc->GetWindow(), dc, rect, 0 );
+ }
+ else
+ {
+ int colRight = GetColRight(col) - 1;
- dc.SetPen( wxPen(wxSystemSettings::GetColour(wxSYS_COLOUR_3DSHADOW), 1, wxSOLID) );
- dc.DrawLine( colRight, 0, colRight, m_colLabelHeight - 1 );
- dc.DrawLine( colLeft, 0, colRight, 0 );
- dc.DrawLine( colLeft, m_colLabelHeight - 1,
+ 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,
colRight + 1, m_colLabelHeight - 1 );
- dc.SetPen( *wxWHITE_PEN );
- dc.DrawLine( colLeft, 1, colLeft, m_colLabelHeight - 1 );
- dc.DrawLine( colLeft, 1, colRight, 1 );
-#endif
+ dc.SetPen( *wxWHITE_PEN );
+ dc.DrawLine( colLeft, 1, colLeft, m_colLabelHeight - 1 );
+ dc.DrawLine( colLeft, 1, colRight, 1 );
+ }
- dc.SetBackgroundMode( wxTRANSPARENT );
+ dc.SetBackgroundMode( wxBRUSHSTYLE_TRANSPARENT );
dc.SetTextForeground( GetLabelTextColour() );
dc.SetFont( GetLabelFont() );
continue;
}
- long lineWidth = 0,
+ wxCoord lineWidth = 0,
lineHeight = 0;
dc.GetTextExtent(line, &lineWidth, &lineHeight);
// 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;
}
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 ) );
}
}
const wxArrayString& lines,
long *width, long *height ) const
{
- long w = 0;
- long h = 0;
- long lineW = 0, lineH = 0;
+ wxCoord w = 0;
+ wxCoord h = 0;
+ wxCoord lineW = 0, lineH = 0;
size_t i;
for ( i = 0; i < lines.GetCount(); i++ )
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);
void wxGrid::SetRowLabelSize( int width )
{
- width = wxMax( width, 0 );
+ wxASSERT( width >= 0 || width == wxGRID_AUTOSIZE );
+
+ if ( width == wxGRID_AUTOSIZE )
+ {
+ width = CalcColOrRowLabelAreaMinSize(wxGRID_ROW);
+ }
+
if ( width != m_rowLabelWidth )
{
if ( width == 0 )
void wxGrid::SetColLabelSize( int height )
{
- height = wxMax( height, 0 );
+ wxASSERT( height >=0 || height == wxGRID_AUTOSIZE );
+
+ if ( height == wxGRID_AUTOSIZE )
+ {
+ height = CalcColOrRowLabelAreaMinSize(wxGRID_COLUMN);
+ }
+
if ( height != m_colLabelHeight )
{
if ( height == 0 )
// make any visible change if the the thickness is getting smaller.
int row = m_currentCellCoords.GetRow();
int col = m_currentCellCoords.GetCol();
- if ( GetColWidth(col) <= 0 || GetRowHeight(row) <= 0 )
+ if ( row == -1 || col == -1 || GetColWidth(col) <= 0 || GetRowHeight(row) <= 0 )
return;
wxRect rect = CellToRect(row, col);
// make any visible change if the the thickness is getting smaller.
int row = m_currentCellCoords.GetRow();
int col = m_currentCellCoords.GetCol();
- if ( GetColWidth(col) <= 0 || GetRowHeight(row) <= 0 )
+ if ( row == -1 || col == -1 ||
+ GetColWidth(col) <= 0 || GetRowHeight(row) <= 0 )
return;
wxRect rect = CellToRect(row, col);
int index = m_typeRegistry->FindOrCloneDataType(typeName);
if ( index == wxNOT_FOUND )
{
- wxString errStr;
-
- errStr.Printf(wxT("Unknown data type name [%s]"), typeName.c_str());
- wxFAIL_MSG(errStr.c_str());
+ wxFAIL_MSG(wxString::Format(wxT("Unknown data type name [%s]"), typeName.c_str()));
return NULL;
}
int index = m_typeRegistry->FindOrCloneDataType(typeName);
if ( index == wxNOT_FOUND )
{
- wxString errStr;
-
- errStr.Printf(wxT("Unknown data type name [%s]"), typeName.c_str());
- wxFAIL_MSG(errStr.c_str());
+ wxFAIL_MSG(wxString::Format(wxT("Unknown data type name [%s]"), typeName.c_str()));
return NULL;
}
// auto sizing
// ----------------------------------------------------------------------------
-void wxGrid::AutoSizeColOrRow( int colOrRow, bool setAsMin, bool column )
+void
+wxGrid::AutoSizeColOrRow(int colOrRow, bool setAsMin, wxGridDirection direction)
{
+ const bool column = direction == wxGRID_COLUMN;
+
wxClientDC dc(m_gridWin);
// cancel editing of cell
if ( column )
{
+ // Ensure automatic width is not less than minimal width. See the
+ // comment in SetColSize() for explanation of why this isn't done
+ // in SetColSize().
+ if ( !setAsMin )
+ extentMax = wxMax(extentMax, GetColMinimalWidth(col));
+
SetColSize( col, extentMax );
if ( !GetBatchCount() )
{
}
else
{
+ // Ensure automatic width is not less than minimal height. See the
+ // comment in SetColSize() for explanation of why this isn't done
+ // in SetRowSize().
+ if ( !setAsMin )
+ extentMax = wxMax(extentMax, GetRowMinimalHeight(row));
+
SetRowSize(row, extentMax);
if ( !GetBatchCount() )
{
}
}
+wxCoord wxGrid::CalcColOrRowLabelAreaMinSize(wxGridDirection direction)
+{
+ // calculate size for the rows or columns?
+ const bool calcRows = direction == wxGRID_ROW;
+
+ wxClientDC dc(calcRows ? GetGridRowLabelWindow()
+ : GetGridColLabelWindow());
+ dc.SetFont(GetLabelFont());
+
+ // which dimension should we take into account for calculations?
+ //
+ // for columns, the text can be only horizontal so it's easy but for rows
+ // we also have to take into account the text orientation
+ const bool
+ useWidth = calcRows || (GetColLabelTextOrientation() == wxVERTICAL);
+
+ wxArrayString lines;
+ wxCoord extentMax = 0;
+
+ const int numRowsOrCols = calcRows ? m_numRows : m_numCols;
+ for ( int rowOrCol = 0; rowOrCol < numRowsOrCols; rowOrCol++ )
+ {
+ lines.Clear();
+
+ wxString label = calcRows ? GetRowLabelValue(rowOrCol)
+ : GetColLabelValue(rowOrCol);
+ StringToLines(label, lines);
+
+ long w, h;
+ GetTextBoxSize(dc, lines, &w, &h);
+
+ const wxCoord extent = useWidth ? w : h;
+ if ( extent > extentMax )
+ extentMax = extent;
+ }
+
+ if ( !extentMax )
+ {
+ // empty column - give default extent (notice that if extentMax is less
+ // than default extent but != 0, it's OK)
+ extentMax = calcRows ? GetDefaultRowLabelSize()
+ : GetDefaultColLabelSize();
+ }
+
+ // leave some space around text (taken from AutoSizeColOrRow)
+ if ( calcRows )
+ extentMax += 10;
+ else
+ extentMax += 6;
+
+ return extentMax;
+}
+
int wxGrid::SetOrCalcColumnSizes(bool calcOnly, bool setAsMin)
{
int width = m_rowLabelWidth;
- if ( !calcOnly )
- BeginBatch();
+ wxGridUpdateLocker locker;
+ if(!calcOnly)
+ locker.Create(this);
for ( int col = 0; col < m_numCols; col++ )
{
width += GetColWidth(col);
}
- if ( !calcOnly )
- EndBatch();
-
return width;
}
{
int height = m_colLabelHeight;
- if ( !calcOnly )
- BeginBatch();
+ wxGridUpdateLocker locker;
+ if(!calcOnly)
+ locker.Create(this);
for ( int row = 0; row < m_numRows; row++ )
{
height += GetRowHeight(row);
}
- if ( !calcOnly )
- EndBatch();
-
return height;
}
void wxGrid::AutoSize()
{
- BeginBatch();
+ wxGridUpdateLocker locker(this);
// we need to round up the size of the scrollable area to a multiple of
// scroll step to ensure that we don't get the scrollbars when we're sized
// client size but also leave space for (not needed any more) scrollbars
SetScrollbars(0, 0, 0, 0, 0, 0, true);
SetClientSize(sizeFit.x + m_rowLabelWidth, sizeFit.y + m_colLabelHeight);
-
- EndBatch();
}
void wxGrid::AutoSizeRowLabelSize( int row )
// This function returns the rectangle that encloses the given block
// in device coords clipped to the client size of the grid window.
//
-wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords &topLeft,
- const wxGridCellCoords &bottomRight ) const
+wxRect wxGrid::BlockToDeviceRect( const wxGridCellCoords& topLeft,
+ const wxGridCellCoords& bottomRight ) const
{
- wxRect rect( wxGridNoCellRect );
- wxRect cellRect;
-
- cellRect = CellToRect( topLeft );
- if ( cellRect != wxGridNoCellRect )
+ wxRect resultRect;
+ wxRect tempCellRect = CellToRect(topLeft);
+ if ( tempCellRect != wxGridNoCellRect )
{
- rect = cellRect;
+ resultRect = tempCellRect;
}
else
{
- rect = wxRect(0, 0, 0, 0);
+ resultRect = wxRect(0, 0, 0, 0);
}
- cellRect = CellToRect( bottomRight );
- if ( cellRect != wxGridNoCellRect )
+ tempCellRect = CellToRect(bottomRight);
+ if ( tempCellRect != wxGridNoCellRect )
{
- rect += cellRect;
+ resultRect += tempCellRect;
}
else
{
+ // If both inputs were "wxGridNoCellRect," then there's nothing to do.
return wxGridNoCellRect;
}
- int i, j;
- int left = rect.GetLeft();
- int top = rect.GetTop();
- int right = rect.GetRight();
- int bottom = rect.GetBottom();
+ // Ensure that left/right and top/bottom pairs are in order.
+ int left = resultRect.GetLeft();
+ int top = resultRect.GetTop();
+ int right = resultRect.GetRight();
+ int bottom = resultRect.GetBottom();
int leftCol = topLeft.GetCol();
int topRow = topLeft.GetRow();
if (left > right)
{
- i = left;
+ int tmp = left;
left = right;
- right = i;
- i = leftCol;
+ right = tmp;
+
+ tmp = leftCol;
leftCol = rightCol;
- rightCol = i;
+ rightCol = tmp;
}
if (top > bottom)
{
- i = top;
+ int tmp = top;
top = bottom;
- bottom = i;
- i = topRow;
+ bottom = tmp;
+
+ tmp = topRow;
topRow = bottomRow;
- bottomRow = i;
+ bottomRow = tmp;
}
- for ( j = topRow; j <= bottomRow; j++ )
+ // The following loop is ONLY necessary to detect and handle merged cells.
+ int cw, ch;
+ m_gridWin->GetClientSize( &cw, &ch );
+
+ // Get the origin coordinates: notice that they will be negative if the
+ // grid is scrolled downwards/to the right.
+ int gridOriginX = 0;
+ int gridOriginY = 0;
+ CalcScrolledPosition(gridOriginX, gridOriginY, &gridOriginX, &gridOriginY);
+
+ int onScreenLeftmostCol = internalXToCol(-gridOriginX);
+ int onScreenUppermostRow = internalYToRow(-gridOriginY);
+
+ int onScreenRightmostCol = internalXToCol(-gridOriginX + cw);
+ int onScreenBottommostRow = internalYToRow(-gridOriginY + ch);
+
+ // Bound our loop so that we only examine the portion of the selected block
+ // that is shown on screen. Therefore, we compare the Top-Left block values
+ // to the Top-Left screen values, and the Bottom-Right block values to the
+ // Bottom-Right screen values, choosing appropriately.
+ const int visibleTopRow = wxMax(topRow, onScreenUppermostRow);
+ const int visibleBottomRow = wxMin(bottomRow, onScreenBottommostRow);
+ const int visibleLeftCol = wxMax(leftCol, onScreenLeftmostCol);
+ const int visibleRightCol = wxMin(rightCol, onScreenRightmostCol);
+
+ for ( int j = visibleTopRow; j <= visibleBottomRow; j++ )
{
- for ( i = leftCol; i <= rightCol; i++ )
+ for ( int i = visibleLeftCol; i <= visibleRightCol; i++ )
{
- if ((j == topRow) || (j == bottomRow) || (i == leftCol) || (i == rightCol))
+ if ( (j == visibleTopRow) || (j == visibleBottomRow) ||
+ (i == visibleLeftCol) || (i == visibleRightCol) )
{
- cellRect = CellToRect( j, i );
+ tempCellRect = CellToRect( j, i );
- if (cellRect.x < left)
- left = cellRect.x;
- if (cellRect.y < top)
- top = cellRect.y;
- if (cellRect.x + cellRect.width > right)
- right = cellRect.x + cellRect.width;
- if (cellRect.y + cellRect.height > bottom)
- bottom = cellRect.y + cellRect.height;
+ if (tempCellRect.x < left)
+ left = tempCellRect.x;
+ if (tempCellRect.y < top)
+ top = tempCellRect.y;
+ if (tempCellRect.x + tempCellRect.width > right)
+ right = tempCellRect.x + tempCellRect.width;
+ if (tempCellRect.y + tempCellRect.height > bottom)
+ bottom = tempCellRect.y + tempCellRect.height;
}
else
{
- i = rightCol; // jump over inner cells.
+ i = visibleRightCol; // jump over inner cells.
}
}
}
- // convert to scrolled coords
- //
+ // Convert to scrolled coords
CalcScrolledPosition( left, top, &left, &top );
CalcScrolledPosition( right, bottom, &right, &bottom );
- int cw, ch;
- m_gridWin->GetClientSize( &cw, &ch );
-
if (right < 0 || bottom < 0 || left > cw || top > ch)
return wxRect(0,0,0,0);
- rect.SetLeft( wxMax(0, left) );
- rect.SetTop( wxMax(0, top) );
- rect.SetRight( wxMin(cw, right) );
- rect.SetBottom( wxMin(ch, bottom) );
+ resultRect.SetLeft( wxMax(0, left) );
+ resultRect.SetTop( wxMax(0, top) );
+ resultRect.SetRight( wxMin(cw, right) );
+ resultRect.SetBottom( wxMin(ch, bottom) );
- return rect;
+ return resultRect;
}
+// ----------------------------------------------------------------------------
+// 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
// ----------------------------------------------------------------------------