Option for variable line heights (MSW and GTK+ sofar)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@53604 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling
2008-05-16 12:37:32 +00:00
parent 2a23042680
commit 344ed1f386
6 changed files with 227 additions and 88 deletions

View File

@@ -478,9 +478,7 @@ public:
: m_text(text), m_icon(icon) : m_text(text), m_icon(icon)
{ } { }
wxDataViewIconText( const wxDataViewIconText &other ) wxDataViewIconText( const wxDataViewIconText &other )
: wxObject() { m_icon = other.m_icon; m_text = other.m_text; }
, m_text(other.m_text), m_icon(other.m_icon)
{ }
void SetText( const wxString &text ) { m_text = text; } void SetText( const wxString &text ) { m_text = text; }
wxString GetText() const { return m_text; } wxString GetText() const { return m_text; }
@@ -586,6 +584,7 @@ protected:
#define wxDV_VERT_RULES 0x0008 // light vertical rules between columns #define wxDV_VERT_RULES 0x0008 // light vertical rules between columns
#define wxDV_ROW_LINES 0x0010 // alternating colour in rows #define wxDV_ROW_LINES 0x0010 // alternating colour in rows
#define wxDV_VARIABLE_LINE_HEIGHT 0x0020 // variable line height
class WXDLLIMPEXP_ADV wxDataViewCtrlBase: public wxControl class WXDLLIMPEXP_ADV wxDataViewCtrlBase: public wxControl
{ {

View File

@@ -676,6 +676,8 @@ public:
Display fine rules between row if supported. Display fine rules between row if supported.
@style{wxDV_VERT_RULES} @style{wxDV_VERT_RULES}
Display fine rules between columns is supported. Display fine rules between columns is supported.
@style{wxDV_VARIABLE_LINE_HEIGHT)
Allow variable line heights. This can be inefficient when displaying large number of items.
@endStyleTable @endStyleTable
@library{wxadv} @library{wxadv}

View File

@@ -595,7 +595,7 @@ public:
virtual wxSize GetSize() const virtual wxSize GetSize() const
{ {
return wxSize(60,20); return wxSize(60,40);
} }
virtual bool SetValue( const wxVariant &WXUNUSED(value) ) { return true; } virtual bool SetValue( const wxVariant &WXUNUSED(value) ) { return true; }
@@ -780,7 +780,7 @@ MyFrame::MyFrame(wxFrame *frame, const wxString &title, int x, int y, int w, int
// MyMusic // MyMusic
m_musicCtrl = new wxDataViewCtrl( this, ID_MUSIC_CTRL, wxDefaultPosition, m_musicCtrl = new wxDataViewCtrl( this, ID_MUSIC_CTRL, wxDefaultPosition,
wxDefaultSize, wxDV_MULTIPLE ); wxDefaultSize, wxDV_MULTIPLE|wxDV_VARIABLE_LINE_HEIGHT );
m_music_model = new MyMusicModel; m_music_model = new MyMusicModel;
m_musicCtrl->AssociateModel( m_music_model.get() ); m_musicCtrl->AssociateModel( m_music_model.get() );

View File

@@ -60,6 +60,12 @@ static const int PADDING_RIGHTLEFT = 3;
// the expander space margin // the expander space margin
static const int EXPANDER_MARGIN = 4; static const int EXPANDER_MARGIN = 4;
#ifdef __WXMSW__
static const int EXPANDER_OFFSET = 4;
#else
static const int EXPANDER_OFFSET = 1;
#endif
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// wxDataViewHeaderWindow // wxDataViewHeaderWindow
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -297,7 +303,7 @@ public:
{ {
} }
wxDataViewTreeNode * GetParent() { return m_parent; } wxDataViewTreeNode * GetParent() const { return m_parent; }
void SetParent( wxDataViewTreeNode * parent ) { m_parent = parent; } void SetParent( wxDataViewTreeNode * parent ) { m_parent = parent; }
wxDataViewTreeNodes & GetNodes() { return m_nodes; } wxDataViewTreeNodes & GetNodes() { return m_nodes; }
wxDataViewTreeLeaves & GetChildren() { return m_leaves; } wxDataViewTreeLeaves & GetChildren() { return m_leaves; }
@@ -319,14 +325,15 @@ public:
} }
wxDataViewItem & GetItem() { return m_item; } wxDataViewItem & GetItem() { return m_item; }
const wxDataViewItem & GetItem() const { return m_item; }
void SetItem( const wxDataViewItem & item ) { m_item = item; } void SetItem( const wxDataViewItem & item ) { m_item = item; }
unsigned int GetChildrenNumber() { return m_leaves.GetCount(); } unsigned int GetChildrenNumber() const { return m_leaves.GetCount(); }
unsigned int GetNodeNumber() { return m_nodes.GetCount(); } unsigned int GetNodeNumber() const { return m_nodes.GetCount(); }
int GetIndentLevel() int GetIndentLevel() const
{ {
int ret = 0 ; int ret = 0 ;
wxDataViewTreeNode * node = this; const wxDataViewTreeNode * node = this;
while( node->GetParent()->GetParent() != NULL ) while( node->GetParent()->GetParent() != NULL )
{ {
node = node->GetParent(); node = node->GetParent();
@@ -335,7 +342,7 @@ public:
return ret; return ret;
} }
bool IsOpen() bool IsOpen() const
{ {
return m_open ; return m_open ;
} }
@@ -359,11 +366,11 @@ public:
ChangeSubTreeCount(sum); ChangeSubTreeCount(sum);
} }
} }
bool HasChildren() { return m_hasChildren; } bool HasChildren() const { return m_hasChildren; }
void SetHasChildren( bool has ){ m_hasChildren = has; } void SetHasChildren( bool has ){ m_hasChildren = has; }
void SetSubTreeCount( int num ) { m_subTreeCount = num; } void SetSubTreeCount( int num ) { m_subTreeCount = num; }
int GetSubTreeCount() { return m_subTreeCount; } int GetSubTreeCount() const { return m_subTreeCount; }
void ChangeSubTreeCount( int num ) void ChangeSubTreeCount( int num )
{ {
if( !m_open ) if( !m_open )
@@ -426,6 +433,8 @@ public:
const wxString &name = wxT("wxdataviewctrlmainwindow") ); const wxString &name = wxT("wxdataviewctrlmainwindow") );
virtual ~wxDataViewMainWindow(); virtual ~wxDataViewMainWindow();
bool IsVirtualList() const { return m_root == NULL; }
// notifications from wxDataViewModel // notifications from wxDataViewModel
bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item ); bool ItemAdded( const wxDataViewItem &parent, const wxDataViewItem &item );
bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item ); bool ItemDeleted( const wxDataViewItem &parent, const wxDataViewItem &item );
@@ -434,7 +443,7 @@ public:
bool Cleared(); bool Cleared();
void Resort() void Resort()
{ {
if (m_root) if (!IsVirtualList())
{ {
SortPrepare(); SortPrepare();
m_root->Resort(); m_root->Resort();
@@ -516,9 +525,13 @@ public:
wxRect GetLineRect( unsigned int row ) const; wxRect GetLineRect( unsigned int row ) const;
int GetLineStart( unsigned int row ) const; // row * m_lineHeight in fixed mode
int GetLineHeight( unsigned int row ) const; // m_lineHeight in fixed mode
int GetLineAt( unsigned int y ) const; // y / m_lineHeight in fixed mode
//Some useful functions for row and item mapping //Some useful functions for row and item mapping
wxDataViewItem GetItemByRow( unsigned int row ) const; wxDataViewItem GetItemByRow( unsigned int row ) const;
int GetRowByItem( const wxDataViewItem & item ); int GetRowByItem( const wxDataViewItem & item ) const;
//Methods for building the mapping tree //Methods for building the mapping tree
void BuildTree( wxDataViewModel * model ); void BuildTree( wxDataViewModel * model );
@@ -529,7 +542,7 @@ public:
void Expand( unsigned int row ) { OnExpanding( row ); } void Expand( unsigned int row ) { OnExpanding( row ); }
void Collapse( unsigned int row ) { OnCollapsing( row ); } void Collapse( unsigned int row ) { OnCollapsing( row ); }
private: private:
wxDataViewTreeNode * GetTreeNodeByRow( unsigned int row ); wxDataViewTreeNode * GetTreeNodeByRow( unsigned int row ) const;
//We did not need this temporarily //We did not need this temporarily
//wxDataViewTreeNode * GetTreeNodeByItem( const wxDataViewItem & item ); //wxDataViewTreeNode * GetTreeNodeByItem( const wxDataViewItem & item );
@@ -2051,9 +2064,9 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
m_owner->CalcUnscrolledPosition( update.x, update.y, &update.x, &update.y ); m_owner->CalcUnscrolledPosition( update.x, update.y, &update.x, &update.y );
// compute which items needs to be redrawn // compute which items needs to be redrawn
unsigned int item_start = wxMax( 0, (update.y / m_lineHeight) ); unsigned int item_start = GetLineAt( wxMax(0,update.y) );
unsigned int item_count = unsigned int item_count =
wxMin( (int)(((update.y + update.height) / m_lineHeight) - item_start + 1), wxMin( (int)( GetLineAt( wxMax(0,update.y+update.height) ) - item_start + 1),
(int)(GetRowCount( ) - item_start)); (int)(GetRowCount( ) - item_start));
unsigned int item_last = item_start + item_count; unsigned int item_last = item_start + item_count;
@@ -2096,7 +2109,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
for (unsigned int i = item_start; i <= item_last+1; i++) for (unsigned int i = item_start; i <= item_last+1; i++)
{ {
int y = i * m_lineHeight; int y = GetLineStart( i );
dc.DrawLine(x_start, y, x_last, y); dc.DrawLine(x_start, y, x_last, y);
} }
} }
@@ -2114,15 +2127,15 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
if (col->IsHidden()) if (col->IsHidden())
continue; // skip it continue; // skip it
dc.DrawLine(x, item_start * m_lineHeight, dc.DrawLine(x, GetLineStart( item_start ),
x, item_last * m_lineHeight); x, GetLineStart( item_last ) );
x += col->GetWidth(); x += col->GetWidth();
} }
// Draw last vertical rule // Draw last vertical rule
dc.DrawLine(x, item_start * m_lineHeight, dc.DrawLine(x, GetLineStart( item_start ),
x, item_last * m_lineHeight); x, GetLineStart( item_last ) );
} }
// redraw the background for the items which are selected/current // redraw the background for the items which are selected/current
@@ -2137,7 +2150,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
if (m_hasFocus) if (m_hasFocus)
flags |= wxCONTROL_FOCUSED; flags |= wxCONTROL_FOCUSED;
wxRect rect( x_start, item*m_lineHeight, x_last, m_lineHeight ); wxRect rect( x_start, GetLineStart( item ), x_last, GetLineHeight( item ) );
wxRendererNative::Get().DrawItemSelectionRect wxRendererNative::Get().DrawItemSelectionRect
( (
this, this,
@@ -2156,19 +2169,19 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
GetOwner()->SetExpanderColumn(expander); GetOwner()->SetExpanderColumn(expander);
} }
// redraw all cells for all rows which must be repainted and for all columns // redraw all cells for all rows which must be repainted and all columns
wxRect cell_rect; wxRect cell_rect;
cell_rect.x = x_start; cell_rect.x = x_start;
cell_rect.height = m_lineHeight; // -1 is for the horizontal rules
for (unsigned int i = col_start; i < col_last; i++) for (unsigned int i = col_start; i < col_last; i++)
{ {
cell_rect.height = GetLineHeight( i ); // -1 is for the horizontal rules (?)
wxDataViewColumn *col = GetOwner()->GetColumn( i ); wxDataViewColumn *col = GetOwner()->GetColumn( i );
wxDataViewRenderer *cell = col->GetRenderer(); wxDataViewRenderer *cell = col->GetRenderer();
cell_rect.width = col->GetWidth(); cell_rect.width = col->GetWidth();
if (col->IsHidden()) if (col->IsHidden())
continue; // skipt it! continue; // skip it!
for (unsigned int item = item_start; item < item_last; item++) for (unsigned int item = item_start; item < item_last; item++)
{ {
@@ -2177,7 +2190,7 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
wxDataViewTreeNode *node = NULL; wxDataViewTreeNode *node = NULL;
wxDataViewItem dataitem; wxDataViewItem dataitem;
if (m_root) if (!IsVirtualList())
{ {
node = GetTreeNodeByRow(item); node = GetTreeNodeByRow(item);
if( node == NULL ) if( node == NULL )
@@ -2206,11 +2219,11 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
} }
// update the y offset // update the y offset
cell_rect.y = item * m_lineHeight; cell_rect.y = GetLineStart( item );
//Draw the expander here. //Draw the expander here.
int indent = 0; int indent = 0;
if ((m_root) && (col == expander)) if ((!IsVirtualList()) && (col == expander))
{ {
indent = node->GetIndentLevel(); indent = node->GetIndentLevel();
@@ -2219,7 +2232,8 @@ void wxDataViewMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
int expander_width = m_lineHeight - 2*EXPANDER_MARGIN; int expander_width = m_lineHeight - 2*EXPANDER_MARGIN;
// change the cell_rect.x to the appropriate pos // change the cell_rect.x to the appropriate pos
int expander_x = indent + EXPANDER_MARGIN , expander_y = cell_rect.y + EXPANDER_MARGIN ; int expander_x = indent + EXPANDER_MARGIN;
int expander_y = cell_rect.y + EXPANDER_MARGIN + (GetLineHeight(item) / 2) - (expander_width/2) - EXPANDER_OFFSET;
indent = indent + m_lineHeight ; //try to use the m_lineHeight as the expander space indent = indent + m_lineHeight ; //try to use the m_lineHeight as the expander space
dc.SetPen( m_penExpander ); dc.SetPen( m_penExpander );
dc.SetBrush( wxNullBrush ); dc.SetBrush( wxNullBrush );
@@ -2319,8 +2333,10 @@ void wxDataViewMainWindow::OnRenameTimer()
break; break;
xpos += c->GetWidth(); xpos += c->GetWidth();
} }
wxRect labelRect( xpos, m_currentRow * m_lineHeight, wxRect labelRect( xpos,
m_currentCol->GetWidth(), m_lineHeight ); GetLineStart( m_currentRow ),
m_currentCol->GetWidth(),
GetLineHeight( m_currentRow ) );
GetOwner()->CalcScrolledPosition( labelRect.x, labelRect.y, GetOwner()->CalcScrolledPosition( labelRect.x, labelRect.y,
&labelRect.x, &labelRect.y); &labelRect.x, &labelRect.y);
@@ -2589,7 +2605,7 @@ void wxDataViewMainWindow::RecalculateDisplay()
} }
int width = GetEndOfLastCol(); int width = GetEndOfLastCol();
int height = GetRowCount() * m_lineHeight; int height = GetLineStart( GetRowCount() );
SetVirtualSize( width, height ); SetVirtualSize( width, height );
GetOwner()->SetScrollRate( 10, m_lineHeight ); GetOwner()->SetScrollRate( 10, m_lineHeight );
@@ -2609,7 +2625,7 @@ void wxDataViewMainWindow::ScrollTo( int rows, int column )
{ {
int x, y; int x, y;
m_owner->GetScrollPixelsPerUnit( &x, &y ); m_owner->GetScrollPixelsPerUnit( &x, &y );
int sy = rows*m_lineHeight/y; int sy = GetLineStart( rows )/y;
int sx = 0; int sx = 0;
if( column != -1 ) if( column != -1 )
{ {
@@ -2669,7 +2685,7 @@ unsigned int wxDataViewMainWindow::GetFirstVisibleRow() const
int y = 0; int y = 0;
m_owner->CalcUnscrolledPosition( x, y, &x, &y ); m_owner->CalcUnscrolledPosition( x, y, &x, &y );
return y / m_lineHeight; return GetLineAt( y );
} }
unsigned int wxDataViewMainWindow::GetLastVisibleRow() unsigned int wxDataViewMainWindow::GetLastVisibleRow()
@@ -2679,7 +2695,7 @@ unsigned int wxDataViewMainWindow::GetLastVisibleRow()
&client_size.x, &client_size.y ); &client_size.x, &client_size.y );
//we should deal with the pixel here //we should deal with the pixel here
unsigned int row = ((client_size.y)/m_lineHeight) - 1; unsigned int row = GetLineAt(client_size.y) - 1;
return wxMin( GetRowCount()-1, row ); return wxMin( GetRowCount()-1, row );
} }
@@ -2689,11 +2705,7 @@ unsigned int wxDataViewMainWindow::GetRowCount()
if ( m_count == -1 ) if ( m_count == -1 )
{ {
m_count = RecalculateCount(); m_count = RecalculateCount();
int width, height; UpdateDisplay();
GetVirtualSize( &width, &height );
height = m_count * m_lineHeight;
SetVirtualSize( width, height );
} }
return m_count; return m_count;
} }
@@ -2817,7 +2829,7 @@ void wxDataViewMainWindow::SendSelectionChangedEvent( const wxDataViewItem& item
void wxDataViewMainWindow::RefreshRow( unsigned int row ) void wxDataViewMainWindow::RefreshRow( unsigned int row )
{ {
wxRect rect( 0, row*m_lineHeight, GetEndOfLastCol(), m_lineHeight ); wxRect rect( 0, GetLineStart( row ), GetEndOfLastCol(), GetLineHeight( row ) );
m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y ); m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
wxSize client_size = GetClientSize(); wxSize client_size = GetClientSize();
@@ -2836,7 +2848,7 @@ void wxDataViewMainWindow::RefreshRows( unsigned int from, unsigned int to )
from = tmp; from = tmp;
} }
wxRect rect( 0, from*m_lineHeight, GetEndOfLastCol(), (to-from+1) * m_lineHeight ); wxRect rect( 0, GetLineStart( from ), GetEndOfLastCol(), GetLineStart( (to-from+1) ) );
m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y ); m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
wxSize client_size = GetClientSize(); wxSize client_size = GetClientSize();
@@ -2848,18 +2860,14 @@ void wxDataViewMainWindow::RefreshRows( unsigned int from, unsigned int to )
void wxDataViewMainWindow::RefreshRowsAfter( unsigned int firstRow ) void wxDataViewMainWindow::RefreshRowsAfter( unsigned int firstRow )
{ {
unsigned int count = GetRowCount();
if (firstRow > count)
return;
wxRect rect( 0, firstRow*m_lineHeight, GetEndOfLastCol(), count * m_lineHeight );
m_owner->CalcScrolledPosition( rect.x, rect.y, &rect.x, &rect.y );
wxSize client_size = GetClientSize(); wxSize client_size = GetClientSize();
wxRect client_rect( 0, 0, client_size.x, client_size.y ); int start = GetLineStart( firstRow );
wxRect intersect_rect = client_rect.Intersect( rect ); m_owner->CalcScrolledPosition( start, 0, &start, NULL );
if (intersect_rect.width > 0) if (start > client_size.y) return;
Refresh( true, &intersect_rect );
wxRect rect( 0, start, client_size.x, client_size.y - start );
Refresh( true, &rect );
} }
void wxDataViewMainWindow::OnArrowChar(unsigned int newCurrent, const wxKeyEvent& event) void wxDataViewMainWindow::OnArrowChar(unsigned int newCurrent, const wxKeyEvent& event)
@@ -2918,13 +2926,130 @@ wxRect wxDataViewMainWindow::GetLineRect( unsigned int row ) const
{ {
wxRect rect; wxRect rect;
rect.x = 0; rect.x = 0;
rect.y = m_lineHeight * row; rect.y = GetLineStart( row );
rect.width = GetEndOfLastCol(); rect.width = GetEndOfLastCol();
rect.height = m_lineHeight; rect.height = GetLineHeight( row );
return rect; return rect;
} }
int wxDataViewMainWindow::GetLineStart( unsigned int row ) const
{
if (GetOwner()->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT)
{
// TODO make more efficient
int start = 0;
unsigned int r;
for (r = 0; r < row; r++)
{
const wxDataViewTreeNode* node = GetTreeNodeByRow(r);
if (!node) return start;
unsigned int cols = GetOwner()->GetColumnCount();
unsigned int col;
int height = 0;
for (col = 0; col < cols; col++)
{
const wxDataViewColumn *column = GetOwner()->GetColumn(col);
if (column->IsHidden())
continue; // skip it!
const wxDataViewRenderer *renderer = column->GetRenderer();
height = wxMax( height, renderer->GetSize().y );
}
start += height;
}
return start;
}
else
{
return row * m_lineHeight;
}
}
int wxDataViewMainWindow::GetLineAt( unsigned int y ) const
{
if (GetOwner()->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT)
{
// TODO make more efficient
unsigned int row = 0;
unsigned int yy = 0;
for (;;)
{
const wxDataViewTreeNode* node = GetTreeNodeByRow(row);
if (!node)
{
// not really correct...
return row + ((y-yy) / m_lineHeight);
}
unsigned int cols = GetOwner()->GetColumnCount();
unsigned int col;
int height = 0;
for (col = 0; col < cols; col++)
{
const wxDataViewColumn *column = GetOwner()->GetColumn(col);
if (column->IsHidden())
continue; // skip it!
const wxDataViewRenderer *renderer = column->GetRenderer();
height = wxMax( height, renderer->GetSize().y );
}
yy += height;
if (y < yy)
return row;
row++;
}
return -1;
}
else
{
return y / m_lineHeight;
}
}
int wxDataViewMainWindow::GetLineHeight( unsigned int row ) const
{
if (GetOwner()->GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT)
{
wxASSERT( !IsVirtualList() );
const wxDataViewTreeNode* node = GetTreeNodeByRow(row);
// wxASSERT( node );
if (!node) return m_lineHeight;
wxDataViewItem item( node->GetItem() );
int height = 0;
unsigned int cols = GetOwner()->GetColumnCount();
unsigned int col;
for (col = 0; col < cols; col++)
{
const wxDataViewColumn *column = GetOwner()->GetColumn(col);
if (column->IsHidden())
continue; // skip it!
const wxDataViewRenderer *renderer = column->GetRenderer();
height = wxMax( height, renderer->GetSize().y );
}
return height;
}
else
{
return m_lineHeight;
}
}
class RowToItemJob: public DoJob class RowToItemJob: public DoJob
{ {
public: public:
@@ -3058,18 +3183,13 @@ private:
}; };
wxDataViewTreeNode * wxDataViewMainWindow::GetTreeNodeByRow(unsigned int row) wxDataViewTreeNode * wxDataViewMainWindow::GetTreeNodeByRow(unsigned int row) const
{ {
if (!m_root) wxASSERT( !IsVirtualList() );
{
return NULL;
}
else
{
RowToTreeNodeJob job( row , -2, m_root ); RowToTreeNodeJob job( row , -2, m_root );
Walker( m_root , job ); Walker( m_root , job );
return job.GetResult(); return job.GetResult();
}
} }
wxDataViewEvent wxDataViewMainWindow::SendExpanderEvent( wxEventType type, const wxDataViewItem & item ) wxDataViewEvent wxDataViewMainWindow::SendExpanderEvent( wxEventType type, const wxDataViewItem & item )
@@ -3238,14 +3358,14 @@ void wxDataViewMainWindow::HitTest( const wxPoint & point, wxDataViewItem & item
} }
column = col; column = col;
item = GetItemByRow( y/m_lineHeight ); item = GetItemByRow( GetLineAt( y ) );
} }
wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, const wxDataViewColumn* column ) wxRect wxDataViewMainWindow::GetItemRect( const wxDataViewItem & item, const wxDataViewColumn* column )
{ {
int row = GetRowByItem(item); int row = GetRowByItem(item);
int y = row*m_lineHeight; int y = GetLineStart( row );
int h = m_lineHeight; int h = GetLineHeight( m_lineHeight );
int x = 0; int x = 0;
wxDataViewColumn *col = NULL; wxDataViewColumn *col = NULL;
for( int i = 0, cols = GetOwner()->GetColumnCount(); i < cols; i ++ ) for( int i = 0, cols = GetOwner()->GetColumnCount(); i < cols; i ++ )
@@ -3322,9 +3442,9 @@ private:
}; };
int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) int wxDataViewMainWindow::GetRowByItem(const wxDataViewItem & item) const
{ {
wxDataViewModel * model = GetOwner()->GetModel(); const wxDataViewModel * model = GetOwner()->GetModel();
if( model == NULL ) if( model == NULL )
return -1; return -1;
@@ -3424,7 +3544,7 @@ static void DestroyTreeHelper( wxDataViewTreeNode * node )
void wxDataViewMainWindow::DestroyTree() void wxDataViewMainWindow::DestroyTree()
{ {
if (m_root) if (!IsVirtualList())
{ {
::DestroyTreeHelper(m_root); ::DestroyTreeHelper(m_root);
m_count = 0; m_count = 0;
@@ -3552,7 +3672,7 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
return; return;
wxDataViewRenderer *cell = col->GetRenderer(); wxDataViewRenderer *cell = col->GetRenderer();
unsigned int current = y / m_lineHeight; unsigned int current = GetLineAt( y );
if ((current > GetRowCount()) || (x > GetEndOfLastCol())) if ((current > GetRowCount()) || (x > GetEndOfLastCol()))
{ {
// Unselect all if below the last row ? // Unselect all if below the last row ?
@@ -3561,14 +3681,17 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
//Test whether the mouse is hovered on the tree item button //Test whether the mouse is hovered on the tree item button
bool hover = false; bool hover = false;
if ((m_root) && (GetOwner()->GetExpanderColumn() == col)) if ((!IsVirtualList()) && (GetOwner()->GetExpanderColumn() == col))
{ {
wxDataViewTreeNode * node = GetTreeNodeByRow(current); wxDataViewTreeNode * node = GetTreeNodeByRow(current);
if( node!=NULL && node->HasChildren() ) if( node!=NULL && node->HasChildren() )
{ {
int indent = node->GetIndentLevel(); int indent = node->GetIndentLevel();
indent = GetOwner()->GetIndent()*indent; indent = GetOwner()->GetIndent()*indent;
wxRect rect( xpos + indent + EXPANDER_MARGIN, current * m_lineHeight + EXPANDER_MARGIN, m_lineHeight-2*EXPANDER_MARGIN,m_lineHeight-2*EXPANDER_MARGIN); wxRect rect( xpos + indent + EXPANDER_MARGIN,
GetLineStart( current ) + EXPANDER_MARGIN + (GetLineHeight(current)/2) - (m_lineHeight/2) - EXPANDER_OFFSET,
m_lineHeight-2*EXPANDER_MARGIN,
m_lineHeight-2*EXPANDER_MARGIN);
if( rect.Contains( x, y) ) if( rect.Contains( x, y) )
{ {
//So the mouse is over the expander //So the mouse is over the expander
@@ -3650,8 +3773,8 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
wxVariant value; wxVariant value;
model->GetValue( value, item, col->GetModelColumn() ); model->GetValue( value, item, col->GetModelColumn() );
cell->SetValue( value ); cell->SetValue( value );
wxRect cell_rect( xpos, current * m_lineHeight, wxRect cell_rect( xpos, GetLineStart( current ),
col->GetWidth(), m_lineHeight ); col->GetWidth(), GetLineHeight( current ) );
cell->Activate( cell_rect, model, item, col->GetModelColumn() ); cell->Activate( cell_rect, model, item, col->GetModelColumn() );
} }
@@ -3686,14 +3809,18 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
//Process the event of user clicking the expander //Process the event of user clicking the expander
bool expander = false; bool expander = false;
if ((m_root) && (GetOwner()->GetExpanderColumn() == col)) if ((!IsVirtualList()) && (GetOwner()->GetExpanderColumn() == col))
{ {
wxDataViewTreeNode * node = GetTreeNodeByRow(current); wxDataViewTreeNode * node = GetTreeNodeByRow(current);
if( node!=NULL && node->HasChildren() ) if( node!=NULL && node->HasChildren() )
{ {
int indent = node->GetIndentLevel(); int indent = node->GetIndentLevel();
indent = GetOwner()->GetIndent()*indent; indent = GetOwner()->GetIndent()*indent;
wxRect rect( xpos + indent + EXPANDER_MARGIN, current * m_lineHeight + EXPANDER_MARGIN, m_lineHeight-2*EXPANDER_MARGIN,m_lineHeight-2*EXPANDER_MARGIN); wxRect rect( xpos + indent + EXPANDER_MARGIN,
GetLineStart( current ) + EXPANDER_MARGIN + (GetLineHeight(current)/2) - (m_lineHeight/2) - EXPANDER_OFFSET,
m_lineHeight-2*EXPANDER_MARGIN,
m_lineHeight-2*EXPANDER_MARGIN);
if( rect.Contains( x, y) ) if( rect.Contains( x, y) )
{ {
expander = true; expander = true;
@@ -3831,8 +3958,8 @@ void wxDataViewMainWindow::OnMouse( wxMouseEvent &event )
wxVariant value; wxVariant value;
model->GetValue( value, item, col->GetModelColumn() ); model->GetValue( value, item, col->GetModelColumn() );
cell->SetValue( value ); cell->SetValue( value );
wxRect cell_rect( xpos, current * m_lineHeight, wxRect cell_rect( xpos, GetLineStart( current ),
col->GetWidth(), m_lineHeight ); col->GetWidth(), GetLineHeight( current ) );
/* ignore ret */ cell->LeftClick( event.GetPosition(), cell_rect, model, item, col->GetModelColumn()); /* ignore ret */ cell->LeftClick( event.GetPosition(), cell_rect, model, item, col->GetModelColumn());
} }
} }

View File

@@ -3620,7 +3620,10 @@ bool wxDataViewCtrl::Create(wxWindow *parent, wxWindowID id,
#ifdef __WXGTK26__ #ifdef __WXGTK26__
if (!gtk_check_version(2,6,0)) if (!gtk_check_version(2,6,0))
gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview), TRUE ); {
bool fixed = (style & wxDV_VARIABLE_LINE_HEIGHT) == 0;
gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview), fixed );
}
#endif #endif
if (style & wxDV_MULTIPLE) if (style & wxDV_MULTIPLE)
@@ -3712,6 +3715,14 @@ bool wxDataViewCtrl::AssociateModel( wxDataViewModel *model )
if (!wxDataViewCtrlBase::AssociateModel( model )) if (!wxDataViewCtrlBase::AssociateModel( model ))
return false; return false;
#ifdef __WXGTK26__
if (!gtk_check_version(2,6,0))
{
bool fixed = (((GetWindowStyle() & wxDV_VARIABLE_LINE_HEIGHT) == 0) || (model->IsVirtualListModel()));
gtk_tree_view_set_fixed_height_mode( GTK_TREE_VIEW(m_treeview), fixed );
}
#endif
GtkWxTreeModel *gtk_model = wxgtk_tree_model_new(); GtkWxTreeModel *gtk_model = wxgtk_tree_model_new();
m_internal = new wxDataViewCtrlInternal( this, model, gtk_model ); m_internal = new wxDataViewCtrlInternal( this, model, gtk_model );
gtk_model->internal = m_internal; gtk_model->internal = m_internal;

View File

@@ -169,7 +169,7 @@ wxMacDataBrowserTableViewControl::wxMacDataBrowserTableViewControl(wxWindow* pee
this->SetCustomCallbacks(&customCallbacks); this->SetCustomCallbacks(&customCallbacks);
// style setting: // style setting:
this->EnableCellSizeModification(); this->EnableCellSizeModification( ((style & wxDV_VARIABLE_LINE_HEIGHT) != 0), true );
DataBrowserSelectionFlags flags; // variable definition DataBrowserSelectionFlags flags; // variable definition