added virtual list control functions (but not implemented them yet) to the native wxListCtrl

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10842 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2001-07-05 13:08:37 +00:00
parent 018d679e79
commit 2c1f73eecf
2 changed files with 147 additions and 72 deletions

View File

@ -122,6 +122,8 @@ public:
bool DeleteAllColumns();
bool DeleteColumn( int col );
void SetItemCount(long count);
void EditLabel( long item ) { Edit(item); }
void Edit( long item );
@ -141,6 +143,9 @@ public:
bool SortItems( wxListCtrlCompare fn, long data );
bool Update( long item );
// returns true if it is a virtual list control
bool IsVirtual() const { return (GetWindowStyle() & wxLC_VIRTUAL) != 0; }
void OnIdle( wxIdleEvent &event );
void OnSize( wxSizeEvent &event );
@ -173,6 +178,16 @@ public:
wxListHeaderWindow *m_headerWin;
wxListMainWindow *m_mainWin;
protected:
// return the text for the given column of the given item
virtual wxString OnGetItemText(long item, long column) const;
// return the icon for the given item
virtual int OnGetItemImage(long item) const;
// it calls our OnGetXXX() functions
friend wxListMainWindow;
private:
DECLARE_EVENT_TABLE()
DECLARE_DYNAMIC_CLASS(wxListCtrl);

View File

@ -123,7 +123,8 @@ protected:
wxString m_text;
int m_format;
int m_width;
int m_xpos,m_ypos;
int m_xpos,
m_ypos;
int m_height;
public:
@ -155,10 +156,14 @@ private:
// wxListLineData (internal)
//-----------------------------------------------------------------------------
WX_DECLARE_LIST(wxListItemData, wxListItemDataList);
#include "wx/listimpl.cpp"
WX_DEFINE_LIST(wxListItemDataList);
class WXDLLEXPORT wxListLineData : public wxObject
{
public:
wxList m_items;
wxListItemDataList m_items;
wxRect m_bound_all;
wxRect m_bound_label;
wxRect m_bound_icon;
@ -414,6 +419,8 @@ public:
// void AddColumn( wxListItem &item );
void SortItems( wxListCtrlCompare fn, long data );
void SetItemCount(long count);
private:
DECLARE_DYNAMIC_CLASS(wxListMainWindow);
DECLARE_EVENT_TABLE()
@ -657,26 +664,31 @@ wxListLineData::wxListLineData( wxListMainWindow *owner, int mode, wxBrush *hili
void wxListLineData::CalculateSize( wxDC *dc, int spacing )
{
wxListItemDataList::Node *node = m_items.GetFirst();
m_spacing = spacing;
switch (m_mode)
{
case wxLC_ICON:
{
m_bound_all.width = m_spacing;
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
wxString s = item->GetText();
if (s.IsEmpty()) s = wxT("H");
if (s.IsEmpty())
s = wxT("H");
wxCoord lw,lh;
dc->GetTextExtent( s, &lw, &lh );
if (lh < 15) lh = 15;
if (lh < 15)
lh = 15;
lw += 4;
lh += 3;
m_bound_all.height = m_spacing+lh;
if (lw > m_spacing) m_bound_all.width = lw;
if (lw > m_spacing)
m_bound_all.width = lw;
m_bound_label.width = lw;
m_bound_label.height = lh;
@ -709,18 +721,21 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
}
case wxLC_LIST:
{
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
wxString s = item->GetText();
if (s.IsEmpty()) s = wxT("H");
if (s.IsEmpty())
s = wxT("H");
wxCoord lw,lh;
dc->GetTextExtent( s, &lw, &lh );
if (lh < 15) lh = 15;
if (lh < 15)
lh = 15;
lw += 4;
lh += 3;
m_bound_label.width = lw;
m_bound_label.height = lh;
@ -748,10 +763,9 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
{
m_bound_all.width = 0;
m_bound_all.height = 0;
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
if (item->HasImage())
{
int w = 0;
@ -766,21 +780,25 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
m_bound_icon.height = 0;
}
}
while (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
wxString s = item->GetText();
if (s.IsEmpty()) s = wxT("H");
if (s.IsEmpty())
s = wxT("H");
wxCoord lw,lh;
dc->GetTextExtent( s, &lw, &lh );
if (lh < 15) lh = 15;
if (lh < 15)
lh = 15;
lw += 4;
lh += 3;
item->SetSize( item->GetWidth(), lh );
m_bound_all.width += lw;
m_bound_all.height = lh;
node = node->Next();
node = node->GetNext();
}
m_bound_label.width = m_bound_all.width;
m_bound_label.height = m_bound_all.height;
@ -792,16 +810,18 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing )
void wxListLineData::SetPosition( wxDC * WXUNUSED(dc),
int x, int y, int window_width )
{
wxListItemDataList::Node *node = m_items.GetFirst();
m_bound_all.x = x;
m_bound_all.y = y;
switch (m_mode)
{
case wxLC_ICON:
{
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
if (item->HasImage())
{
m_bound_icon.x = m_bound_all.x + 4
@ -831,10 +851,9 @@ void wxListLineData::SetPosition( wxDC * WXUNUSED(dc),
m_bound_hilight.x = m_bound_all.x;
m_bound_hilight.y = m_bound_all.y;
m_bound_label.y = m_bound_all.y + 2;
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
if (item->HasImage())
{
m_bound_icon.x = m_bound_all.x + 2;
@ -855,10 +874,9 @@ void wxListLineData::SetPosition( wxDC * WXUNUSED(dc),
AssignRect( m_bound_hilight, m_bound_all );
m_bound_label.x = m_bound_all.x + 2;
m_bound_label.y = m_bound_all.y + 2;
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
if (item->HasImage())
{
m_bound_icon.x = m_bound_all.x + 2;
@ -873,10 +891,10 @@ void wxListLineData::SetPosition( wxDC * WXUNUSED(dc),
void wxListLineData::SetColumnPosition( int index, int x )
{
wxNode *node = m_items.Nth( (size_t)index );
wxListItemDataList::Node *node = m_items.Item( (size_t)index );
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
item->SetPosition( x, m_bound_all.y+1 );
}
}
@ -910,41 +928,46 @@ void wxListLineData::GetRect( wxRect &rect )
long wxListLineData::IsHit( int x, int y )
{
wxNode *node = m_items.First();
wxListItemDataList::Node *node = m_items.GetFirst();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
if (item->HasImage() && IsInRect( x, y, m_bound_icon )) return wxLIST_HITTEST_ONITEMICON;
if (item->HasText() && IsInRect( x, y, m_bound_label )) return wxLIST_HITTEST_ONITEMLABEL;
// if (!(item->HasImage() || item->HasText())) return 0;
wxListItemData *item = node->GetData();
if (item->HasImage() && IsInRect( x, y, m_bound_icon ))
return wxLIST_HITTEST_ONITEMICON;
if (item->HasText() && IsInRect( x, y, m_bound_label ))
return wxLIST_HITTEST_ONITEMLABEL;
}
// if there is no icon or text = empty
if (IsInRect( x, y, m_bound_all )) return wxLIST_HITTEST_ONITEMICON;
if (IsInRect( x, y, m_bound_all ))
return wxLIST_HITTEST_ONITEMICON;
return 0;
}
void wxListLineData::InitItems( int num )
{
for (int i = 0; i < num; i++) m_items.Append( new wxListItemData() );
for (int i = 0; i < num; i++)
m_items.Append( new wxListItemData() );
}
void wxListLineData::SetItem( int index, const wxListItem &info )
{
wxNode *node = m_items.Nth( index );
wxListItemDataList::Node *node = m_items.Item( index );
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
item->SetItem( info );
}
}
void wxListLineData::GetItem( int index, wxListItem &info )
{
int i = index;
wxNode *node = m_items.Nth( i );
wxListItemDataList::Node *node = m_items.Item( index );
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
item->GetItem( info );
}
}
@ -953,10 +976,10 @@ wxString wxListLineData::GetText(int index) const
{
wxString s;
wxNode *node = m_items.Nth( index );
wxListItemDataList::Node *node = m_items.Item( index );
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
s = item->GetText();
}
@ -965,22 +988,20 @@ wxString wxListLineData::GetText(int index) const
void wxListLineData::SetText( int index, const wxString s )
{
int i = index;
wxNode *node = m_items.Nth( i );
wxListItemDataList::Node *node = m_items.Item( index );
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
item->SetText( s );
}
}
int wxListLineData::GetImage( int index )
{
int i = index;
wxNode *node = m_items.Nth( i );
wxListItemDataList::Node *node = m_items.Item( index );
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
return item->GetImage();
}
return -1;
@ -1044,7 +1065,7 @@ void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG )
// VZ: currently we set the colours/fonts only once, but like this (i.e.
// using SetAttributes() inside the loop), it will be trivial to
// customize the subitems (in report mode) too.
wxListItemData *item = (wxListItemData*)m_items.First()->Data();
wxListItemData *item = m_items.GetFirst()->GetData();
wxListItemAttr *attr = item->GetAttributes();
SetAttributes(dc, attr, colText, font, hilight);
@ -1068,12 +1089,13 @@ void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG )
m_bound_hilight.width, m_bound_hilight.height );
}
wxListItemDataList::Node *node = m_items.GetFirst();
if (m_mode == wxLC_REPORT)
{
wxNode *node = m_items.First();
while (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
int x = item->GetX();
if (item->HasImage())
{
@ -1088,15 +1110,14 @@ void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG )
dc->DrawText( item->GetText(), x, item->GetY()+1 );
}
dc->DestroyClippingRegion();
node = node->Next();
node = node->GetNext();
}
}
else
else // !report
{
wxNode *node = m_items.First();
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
wxListItemData *item = node->GetData();
if (item->HasImage())
{
m_owner->DrawImage( item->GetImage(), dc, m_bound_icon.x, m_bound_icon.y );
@ -1685,15 +1706,23 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
// Note: a wxPaintDC must be constructed even if no drawing is
// done (a Windows requirement).
wxPaintDC dc( this );
if (m_dirty)
{
// postpone redrawing until the next OnIdle() call to minimize flicker
return;
}
PrepareDC( dc );
int dev_x = 0;
int dev_y = 0;
int dev_x, dev_y;
CalcScrolledPosition( 0, 0, &dev_x, &dev_y );
if (m_dirty) return;
if (m_lines.GetCount() == 0) return;
if (m_lines.GetCount() == 0)
{
// empty control. nothing to draw
return;
}
dc.BeginDrawing();
@ -1724,7 +1753,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
dc.SetPen(pen);
dc.SetBrush(* wxTRANSPARENT_BRUSH);
dc.DrawLine(0 - dev_x , i*lineSpacing , clientSize.x - dev_x , i*lineSpacing );
}
}
}
// Draw last horizontal rule
@ -1733,7 +1762,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
dc.SetPen(pen);
dc.SetBrush(* wxTRANSPARENT_BRUSH);
dc.DrawLine(0 - dev_x , i*lineSpacing , clientSize.x - dev_x , i*lineSpacing );
}
}
// Draw vertical rules if required
if ((m_mode & wxLC_VRULES) && (GetItemCount() > 0))
@ -1754,13 +1783,14 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
}
}
}
else
else // !report mode
{
for (size_t i = 0; i < m_lines.GetCount(); i++)
m_lines[i].Draw( &dc );
}
if (m_current) m_current->DrawRubberBand( &dc, m_hasFocus );
if (m_current)
m_current->DrawRubberBand( &dc, m_hasFocus );
dc.EndDrawing();
}
@ -2508,10 +2538,10 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
for (size_t i = 0; i < m_lines.GetCount(); i++)
{
wxListLineData *line = &m_lines[i];
wxNode *n = line->m_items.Nth( col );
wxListItemDataList::Node *n = line->m_items.Item( col );
if (n)
{
wxListItemData *item = (wxListItemData*)n->Data();
wxListItemData *item = n->GetData();
int current = 0, ix = 0, iy = 0;
wxCoord lx = 0, ly = 0;
if (item->HasImage())
@ -2525,7 +2555,8 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
dc.GetTextExtent( str, &lx, &ly );
current += lx;
}
if (current > max) max = current;
if (current > max)
max = current;
}
}
width = max+10;
@ -2538,13 +2569,14 @@ void wxListMainWindow::SetColumnWidth( int col, int width )
column->SetWidth( width );
}
for (size_t i = 0; i < m_lines.GetCount(); i++)
size_t count = m_lines.GetCount();
for (size_t i = 0; i < count; i++)
{
wxListLineData *line = &m_lines[i];
wxNode *n = line->m_items.Nth( col );
wxListItemDataList::Node *n = line->m_items.Item( col );
if (n)
{
wxListItemData *item = (wxListItemData*)n->Data();
wxListItemData *item = n->GetData();
item->SetSize( width, -1 );
}
}
@ -3913,4 +3945,32 @@ void wxListCtrl::SetFocus()
m_mainWin->SetFocus();
}
// ----------------------------------------------------------------------------
// virtual list control support
// ----------------------------------------------------------------------------
wxString wxListCtrl::OnGetItemText(long item, long col) const
{
// this is a pure virtual function, in fact - which is not really pure
// because the controls which are not virtual don't need to implement it
wxFAIL_MSG( _T("not supposed to be called") );
return wxEmptyString;
}
int wxListCtrl::OnGetItemImage(long item) const
{
// same as above
wxFAIL_MSG( _T("not supposed to be called") );
return -1;
}
void wxListCtrl::SetItemCount(long count)
{
wxASSERT_MSG( IsVirtual(), _T("this is for virtual controls only") );
m_mainWin->SetItemCount(count);
}
#endif // wxUSE_LISTCTRL