// classes
//-----------------------------------------------------------------------------
+class wxDataViewColumn;
+class wxDataViewHeaderWindow;
class wxDataViewCtrl;
+//-----------------------------------------------------------------------------
+// classes
+//-----------------------------------------------------------------------------
+
static const int SCROLL_UNIT_X = 15;
// the cell padding on the left/right
static int g_column = -2;
static bool g_asending = true;
+//-----------------------------------------------------------------------------
+// wxDataViewColumn
+//-----------------------------------------------------------------------------
+
+void wxDataViewColumn::Init(int width, wxAlignment align, int flags)
+{
+ m_width = width == wxCOL_WIDTH_DEFAULT ? wxDVC_DEFAULT_WIDTH : width;
+ m_minWidth = 0;
+ m_align = align;
+ m_flags = flags;
+ m_sort = false;
+ m_sortAscending = true;
+}
+
+void wxDataViewColumn::UpdateDisplay()
+{
+ if (m_owner)
+ {
+ int idx = m_owner->GetColumnIndex( this );
+ m_owner->OnColumnChange( idx );
+ }
+}
+
//-----------------------------------------------------------------------------
// wxDataViewHeaderWindow
//-----------------------------------------------------------------------------
if (GetMode() != wxDATAVIEW_CELL_ACTIVATABLE)
flags |= wxCONTROL_DISABLED;
+ // check boxes we draw must always have the same, standard size (if it's
+ // bigger than the cell size the checkbox will be truncated because the
+ // caller had set the clipping rectangle to prevent us from drawing outside
+ // the cell)
+ cell.SetSize(GetSize());
+
wxRendererNative::Get().DrawCheckBox(
GetOwner()->GetOwner(),
*dc,
return true;
}
-bool wxDataViewToggleRenderer::Activate( wxRect WXUNUSED(cell),
- wxDataViewModel *model,
- const wxDataViewItem & item, unsigned int col)
+void wxDataViewToggleRenderer::WXOnActivate(wxDataViewModel *model,
+ const wxVariant& valueOld,
+ const wxDataViewItem & item,
+ unsigned int col)
{
- model->ChangeValue(!m_toggle, item, col);
- return true;
+ model->ChangeValue(!valueOld.GetBool(), item, col);
}
wxSize wxDataViewToggleRenderer::GetSize() const
return wxSize(x,y+d);
}
-bool wxDataViewDateRenderer::Activate( wxRect WXUNUSED(cell), wxDataViewModel *model,
- const wxDataViewItem & item, unsigned int col )
+void wxDataViewDateRenderer::WXOnActivate(wxDataViewModel *model,
+ const wxVariant& valueOld,
+ const wxDataViewItem & item,
+ unsigned int col )
{
- wxVariant variant;
- model->GetValue( variant, item, col );
- wxDateTime value = variant.GetDateTime();
+ wxDateTime dtOld = valueOld.GetDateTime();
#if wxUSE_DATE_RENDERER_POPUP
wxDataViewDateRendererPopupTransient *popup = new wxDataViewDateRendererPopupTransient(
- GetOwner()->GetOwner()->GetParent(), &value, model, item, col);
+ GetOwner()->GetOwner()->GetParent(), &dtOld, model, item, col);
wxPoint pos = wxGetMousePosition();
popup->Move( pos );
popup->Layout();
popup->Popup( popup->m_cal );
#else // !wxUSE_DATE_RENDERER_POPUP
- wxMessageBox(value.Format());
+ wxMessageBox(dtOld.Format());
#endif // wxUSE_DATE_RENDERER_POPUP/!wxUSE_DATE_RENDERER_POPUP
- return true;
}
// ---------------------------------------------------------
// compute which columns needs to be redrawn
unsigned int cols = GetOwner()->GetColumnCount();
+ if ( !cols )
+ {
+ // we assume that we have at least one column below and painting an
+ // empty control is unnecessary anyhow
+ return;
+ }
+
unsigned int col_start = 0;
unsigned int x_start;
for (x_start = 0; col_start < cols; col_start++)
if (m_hasFocus)
flags |= wxCONTROL_FOCUSED;
- wxRect rect( x_start, GetLineStart( item ), x_last, GetLineHeight( item ) );
+ wxRect rect( x_start, GetLineStart( item ),
+ x_last - x_start, GetLineHeight( item ) );
wxRendererNative::Get().DrawItemSelectionRect
(
this,
if (m_dropHint)
{
wxRect rect( x_start, GetLineStart( m_dropHintLine ),
- x_last, GetLineHeight( m_dropHintLine ) );
+ x_last - x_start, GetLineHeight( m_dropHintLine ) );
dc.SetPen( *wxBLACK_PEN );
dc.SetBrush( *wxTRANSPARENT_BRUSH );
dc.DrawRectangle( rect );
wxDataViewRenderer *cell = col->GetRenderer();
cell_rect.width = col->GetWidth();
- if (col->IsHidden())
+ if ( col->IsHidden() || cell_rect.width <= 0 )
continue; // skip it!
for (unsigned int item = item_start; item < item_last; item++)
cell_rect.y = GetLineStart( item );
cell_rect.height = GetLineHeight( item );
- // Draw the expander here.
+ // deal with the expander
int indent = 0;
if ((!IsVirtualList()) && (col == expander))
{
- indent = node->GetIndentLevel();
-
// Calculate the indent first
- indent = cell_rect.x + GetOwner()->GetIndent() * indent;
+ indent = GetOwner()->GetIndent() * node->GetIndentLevel();
- int expander_width = m_lineHeight - 2*EXPANDER_MARGIN;
+ // we reserve m_lineHeight of horizontal space for the expander
+ // but leave EXPANDER_MARGIN around the expander itself
+ int exp_x = cell_rect.x + indent + EXPANDER_MARGIN;
- // change the cell_rect.x to the appropriate pos
- int expander_x = indent + EXPANDER_MARGIN;
- int expander_y = cell_rect.y + EXPANDER_MARGIN + (GetLineHeight(item) / 2)
- - (expander_width/2) - EXPANDER_OFFSET;
+ indent += m_lineHeight;
- indent = indent + m_lineHeight;
- // try to use the m_lineHeight as the expander space
-
- dc.SetPen( m_penExpander );
- dc.SetBrush( wxNullBrush );
- if( node->HasChildren() )
+ // draw expander if needed and visible
+ if ( node->HasChildren() && exp_x < cell_rect.GetRight() )
{
- wxRect rect( expander_x , expander_y, expander_width, expander_width);
+ dc.SetPen( m_penExpander );
+ dc.SetBrush( wxNullBrush );
+
+ int exp_size = m_lineHeight - 2*EXPANDER_MARGIN;
+ int exp_y = cell_rect.y + (cell_rect.height - exp_size)/2
+ + EXPANDER_MARGIN - EXPANDER_OFFSET;
+
+ const wxRect rect(exp_x, exp_y, exp_size, exp_size);
+
int flag = 0;
- if (m_underMouse == node)
- {
+ if ( m_underMouse == node )
flag |= wxCONTROL_CURRENT;
- }
- if( node->IsOpen() )
- wxRendererNative::Get().DrawTreeItemButton( this, dc, rect,
- flag|wxCONTROL_EXPANDED );
- else
- wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag);
+ if ( node->IsOpen() )
+ flag |= wxCONTROL_EXPANDED;
+
+ // ensure that we don't overflow the cell (which might
+ // happen if the column is very narrow)
+ wxDCClipper clip(dc, cell_rect);
+
+ wxRendererNative::Get().DrawTreeItemButton( this, dc, rect, flag);
}
// force the expander column to left-center align
item_rect.x += indent;
item_rect.width -= indent;
+ if ( item_rect.width <= 0 )
+ continue;
+
int state = 0;
if (m_hasFocus && (m_selection.Index(item) != wxNOT_FOUND))
state |= wxDATAVIEW_CELL_SELECTED;
void wxDataViewMainWindow::OnChar( wxKeyEvent &event )
{
- if ( GetParent()->HandleAsNavigationKey(event) )
+ wxWindow * const parent = GetParent();
+
+ // propagate the char event upwards
+ wxKeyEvent eventForParent(event);
+ eventForParent.SetEventObject(parent);
+ if ( parent->ProcessWindowEvent(eventForParent) )
+ return;
+
+ if ( parent->HandleAsNavigationKey(event) )
return;
// no item -> nothing to do
{
case WXK_RETURN:
{
- wxWindow *parent = GetParent();
wxDataViewEvent le(wxEVT_COMMAND_DATAVIEW_ITEM_ACTIVATED,
parent->GetId());
le.SetItem( GetItemByRow(m_currentRow) );
{
if ((!ignore_other_columns) && (cell->GetMode() == wxDATAVIEW_CELL_ACTIVATABLE))
{
+ const unsigned colIdx = col->GetModelColumn();
+
+ wxVariant value;
+ model->GetValue( value, item, colIdx );
+
+ cell->WXOnActivate(model, value, item, colIdx);
+
if ( wxDataViewCustomRenderer *custom = cell->WXGetAsCustom() )
{
- wxVariant value;
- model->GetValue( value, item, col->GetModelColumn() );
- custom->SetValue( value );
+ cell->SetValue( value );
+
wxRect cell_rect( xpos, GetLineStart( current ),
col->GetWidth(), GetLineHeight( current ) );
- custom->Activate( cell_rect, model, item, col->GetModelColumn() );
+ custom->Activate( cell_rect, model, item, colIdx );
}
}
else
{
ChangeCurrentRow(current);
ReverseRowSelection(m_currentRow);
- SendSelectionChangedEvent(GetItemByRow(m_selection[0]) );
+ SendSelectionChangedEvent(GetItemByRow(m_currentRow));
}
else if (event.ShiftDown())
{
m_clientArea = new wxDataViewMainWindow( this, wxID_ANY );
+ // We use the cursor keys for moving the selection, not scrolling, so call
+ // this method to ensure wxScrollHelperEvtHandler doesn't catch all
+ // keyboard events forwarded to us from wxListMainWindow.
+ DisableKeyboardScrolling();
+
if (HasFlag(wxDV_NO_HEADER))
m_headerArea = NULL;
else
int wxDataViewCtrl::GetColumnPosition( const wxDataViewColumn *column ) const
{
+#if 1
+ unsigned int len = GetColumnCount();
+ for ( unsigned int i = 0; i < len; i++ )
+ {
+ wxDataViewColumn * col = GetColumnAt(i);
+ if (column==col)
+ return i;
+ }
+
+ return wxNOT_FOUND;
+#else
+ // This returns the position in pixels which is not what we want.
int ret = 0,
dummy = 0;
unsigned int len = GetColumnCount();
}
}
return ret;
+#endif
}
wxDataViewColumn *wxDataViewCtrl::GetSortingColumn() const
// Unselect all rows before select another in the single select mode
if (m_clientArea->IsSingleSel())
m_clientArea->SelectAllRows(false);
+
m_clientArea->SelectRow(row, true);
+
+ // Also set focus to the selected item
+ m_clientArea->ChangeCurrentRow( row );
}
}