more steps toward virtual listctrl

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10845 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2001-07-05 13:40:52 +00:00
parent 54800df8d8
commit 1370703e03

View File

@ -7,6 +7,14 @@
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// ============================================================================
// declarations
// ============================================================================
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#ifdef __GNUG__
#pragma implementation "listctrl.h"
#pragma implementation "listctrlbase.h"
@ -273,7 +281,7 @@ private:
class WXDLLEXPORT wxListRenameTimer: public wxTimer
{
private:
wxListMainWindow *m_owner;
wxListMainWindow *m_owner;
public:
wxListRenameTimer( wxListMainWindow *owner );
@ -321,15 +329,29 @@ WX_DEFINE_LIST(wxListHeaderDataList);
class WXDLLEXPORT wxListMainWindow: public wxScrolledWindow
{
public:
// the style of the control (combination of wxLC_XXX)
long m_mode;
// the array of all line objects for a non virtual list control
wxListLineDataArray m_lines;
// the total count of items in a virtual list control
long m_countVirt;
// the list of column objects
wxListHeaderDataList m_columns;
// currently focused item or NULL
wxListLineData *m_current;
wxListLineData *m_currentEdit;
// the item currently being edited or -1
size_t m_currentEdit;
int m_visibleLines;
wxBrush *m_hilightBrush;
wxColour *m_hilightColour;
int m_xScroll,m_yScroll;
int m_xScroll,
m_yScroll;
bool m_dirty;
wxImageList *m_small_image_list;
wxImageList *m_normal_image_list;
@ -346,15 +368,23 @@ public:
wxPoint m_dragStart;
// for double click logic
wxListLineData *m_lineLastClicked,
*m_lineBeforeLastClicked;
size_t m_lineLastClicked,
m_lineBeforeLastClicked;
public:
wxListMainWindow();
wxListMainWindow( wxWindow *parent, wxWindowID id,
const wxPoint &pos = wxDefaultPosition, const wxSize &size = wxDefaultSize,
long style = 0, const wxString &name = "listctrlmainwindow" );
~wxListMainWindow();
wxListMainWindow( wxWindow *parent,
wxWindowID id,
const wxPoint& pos = wxDefaultPosition,
const wxSize& size = wxDefaultSize,
long style = 0,
const wxString &name = _T("listctrlmainwindow") );
virtual ~wxListMainWindow();
// return true if this is a virtual list control
bool IsVirtual() const { return (m_mode & wxLC_VIRTUAL) != 0; }
void RefreshLine( wxListLineData *line );
void OnPaint( wxPaintEvent &event );
void HilightAll( bool on );
@ -400,7 +430,6 @@ public:
void GetItem( wxListItem &item );
void SetItemState( long item, long state, long stateMask );
int GetItemState( long item, long stateMask );
int GetItemCount();
void GetItemRect( long index, wxRect &rect );
bool GetItemPosition( long item, wxPoint& pos );
int GetSelectedItemCount();
@ -423,8 +452,22 @@ public:
// void AddColumn( wxListItem &item );
void SortItems( wxListCtrlCompare fn, long data );
int GetItemCount() const;
bool IsEmpty() const { return GetItemCount() == 0; }
void SetItemCount(long count);
protected:
// common part of all ctors
void Init();
// get the line data for the given index
wxListLineData *GetLine(size_t n) const
{
wxASSERT_MSG( n != (size_t)-1, _T("invalid line index") );
return &m_lines[n];
}
private:
DECLARE_DYNAMIC_CLASS(wxListMainWindow);
DECLARE_EVENT_TABLE()
@ -959,11 +1002,10 @@ void wxListLineData::InitItems( int num )
void wxListLineData::SetItem( int index, const wxListItem &info )
{
wxListItemDataList::Node *node = m_items.Item( index );
if (node)
{
wxListItemData *item = node->GetData();
item->SetItem( info );
}
wxCHECK_RET( node, _T("invalid column index in SetItem") );
wxListItemData *item = node->GetData();
item->SetItem( info );
}
void wxListLineData::GetItem( int index, wxListItem &info )
@ -1610,49 +1652,59 @@ BEGIN_EVENT_TABLE(wxListMainWindow,wxScrolledWindow)
EVT_SCROLLWIN (wxListMainWindow::OnScroll)
END_EVENT_TABLE()
wxListMainWindow::wxListMainWindow()
void wxListMainWindow::Init()
{
m_mode = 0;
m_columns.DeleteContents( TRUE );
m_current = (wxListLineData *) NULL;
m_visibleLines = 0;
m_hilightBrush = (wxBrush *) NULL;
m_xScroll = 0;
m_yScroll = 0;
m_dirty = TRUE;
m_visibleLines = 0;
m_small_image_list = (wxImageList *) NULL;
m_normal_image_list = (wxImageList *) NULL;
m_small_spacing = 30;
m_normal_spacing = 40;
m_hasFocus = FALSE;
m_dragCount = 0;
m_isCreated = FALSE;
m_usedKeys = TRUE;
m_lastOnSame = FALSE;
m_renameTimer = new wxListRenameTimer( this );
m_isCreated = FALSE;
m_dragCount = 0;
m_renameAccept = FALSE;
m_currentEdit = (size_t)-1;
m_lineLastClicked =
m_lineBeforeLastClicked = (wxListLineData *)NULL;
m_lineBeforeLastClicked = (size_t)-1;
}
wxListMainWindow::wxListMainWindow( wxWindow *parent, wxWindowID id,
const wxPoint &pos, const wxSize &size,
long style, const wxString &name ) :
wxScrolledWindow( parent, id, pos, size, style|wxHSCROLL|wxVSCROLL, name )
wxListMainWindow::wxListMainWindow()
{
Init();
m_mode = 0;
m_hilightBrush = (wxBrush *) NULL;
m_xScroll =
m_yScroll = 0;
}
wxListMainWindow::wxListMainWindow( wxWindow *parent,
wxWindowID id,
const wxPoint& pos,
const wxSize& size,
long style,
const wxString &name )
: wxScrolledWindow( parent, id, pos, size,
style | wxHSCROLL | wxVSCROLL, name )
{
Init();
m_mode = style;
m_columns.DeleteContents( TRUE );
m_current = (wxListLineData *) NULL;
m_dirty = TRUE;
m_visibleLines = 0;
m_hilightBrush = new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT), wxSOLID );
m_small_image_list = (wxImageList *) NULL;
m_normal_image_list = (wxImageList *) NULL;
m_small_spacing = 30;
m_normal_spacing = 40;
m_hasFocus = FALSE;
m_dragCount = 0;
m_isCreated = FALSE;
wxSize sz = size;
sz.y = 25;
@ -1672,11 +1724,6 @@ wxListMainWindow::wxListMainWindow( wxWindow *parent, wxWindowID id,
}
SetScrollbars( m_xScroll, m_yScroll, 0, 0, 0, 0 );
m_usedKeys = TRUE;
m_lastOnSame = FALSE;
m_renameTimer = new wxListRenameTimer( this );
m_renameAccept = FALSE;
SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_LISTBOX ) );
}
@ -1722,7 +1769,7 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
int dev_x, dev_y;
CalcScrolledPosition( 0, 0, &dev_x, &dev_y );
if (m_lines.GetCount() == 0)
if ( GetItemCount() == 0 )
{
// empty control. nothing to draw
return;
@ -1746,7 +1793,9 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
int y_s = m_yScroll*GetScrollPos( wxVERTICAL );
size_t i_to = y_s / lineSpacing + m_visibleLines+2;
if (i_to >= m_lines.GetCount()) i_to = m_lines.GetCount();
if (i_to >= m_lines.GetCount())
i_to = m_lines.GetCount();
size_t i;
for (i = y_s / lineSpacing; i < i_to; i++)
{
@ -1789,7 +1838,8 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
}
else // !report mode
{
for (size_t i = 0; i < m_lines.GetCount(); i++)
size_t count = GetItemCount();
for (size_t i = 0; i < count; i++)
m_lines[i].Draw( &dc );
}
@ -1801,7 +1851,8 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) )
void wxListMainWindow::HilightAll( bool on )
{
for (size_t i = 0; i < m_lines.GetCount(); i++)
size_t count = GetItemCount();
for (size_t i = 0; i < count; i++)
{
wxListLineData *line = &m_lines[i];
if (line->IsHilighted() != on)
@ -1858,15 +1909,17 @@ void wxListMainWindow::DeleteLine( wxListLineData *line )
void wxListMainWindow::EditLabel( long item )
{
wxCHECK_RET( ((size_t)item < m_lines.GetCount()),
wxCHECK_RET( (item >= 0) && (item < GetItemCount()),
wxT("wrong index in wxListCtrl::Edit()") );
m_currentEdit = &m_lines[(size_t)item];
m_currentEdit = (size_t)item;
wxListEvent le( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT, GetParent()->GetId() );
le.SetEventObject( GetParent() );
le.m_itemIndex = GetIndexOfLine( m_currentEdit );
m_currentEdit->GetItem( 0, le.m_item );
le.m_itemIndex = item;
wxListLineData *data = GetLine(m_currentEdit);
wxCHECK_RET( data, _T("invalid index in EditLabel()") );
data->GetItem( 0, le.m_item );
GetParent()->GetEventHandler()->ProcessEvent( le );
if (!le.IsAllowed())
@ -1877,12 +1930,12 @@ void wxListMainWindow::EditLabel( long item )
// update taken place.
if (m_dirty) wxYield();
wxString s = m_currentEdit->GetText(0);
wxString s = data->GetText(0);
int x = 0;
int y = 0;
int w = 0;
int h = 0;
m_currentEdit->GetLabelExtent( x, y, w, h );
data->GetLabelExtent( x, y, w, h );
wxClientDC dc(this);
PrepareDC( dc );
@ -1905,8 +1958,12 @@ void wxListMainWindow::OnRenameAccept()
{
wxListEvent le( wxEVT_COMMAND_LIST_END_LABEL_EDIT, GetParent()->GetId() );
le.SetEventObject( GetParent() );
le.m_itemIndex = GetIndexOfLine( m_currentEdit );
m_currentEdit->GetItem( 0, le.m_item );
le.m_itemIndex = m_currentEdit;
wxListLineData *data = GetLine(m_currentEdit);
wxCHECK_RET( data, _T("invalid index in OnRenameAccept()") );
data->GetItem( 0, le.m_item );
le.m_item.m_text = m_renameRes;
GetParent()->GetEventHandler()->ProcessEvent( le );
@ -1936,11 +1993,14 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
/* Did we actually hit an item ? */
long hitResult = 0;
wxListLineData *line = (wxListLineData *) NULL;
for (size_t i = 0; i < m_lines.GetCount(); i++)
size_t idx;
for (idx = 0; idx < m_lines.GetCount(); idx++)
{
line = &m_lines[i];
line = &m_lines[idx];
hitResult = line->IsHit( x, y );
if (hitResult) break;
if (hitResult)
break;
line = (wxListLineData *) NULL;
}
@ -1976,7 +2036,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
m_renameTimer->Stop();
m_lastOnSame = FALSE;
if ( line == m_lineBeforeLastClicked )
if ( idx == m_lineBeforeLastClicked )
{
m_usedKeys = FALSE;
@ -2021,7 +2081,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event )
if ( event.LeftDown() || forceClick )
{
m_lineBeforeLastClicked = m_lineLastClicked;
m_lineLastClicked = line;
m_lineLastClicked = idx;
m_usedKeys = FALSE;
wxListLineData *oldCurrent = m_current;
@ -2226,13 +2286,13 @@ void wxListMainWindow::OnChar( wxKeyEvent &event )
}
case WXK_END:
{
if (!m_lines.IsEmpty())
if (!IsEmpty())
OnArrowChar( &m_lines.Last(), event.ShiftDown() );
break;
}
case WXK_HOME:
{
if (!m_lines.IsEmpty())
if (!IsEmpty())
OnArrowChar( &m_lines[0], event.ShiftDown() );
break;
}
@ -2454,9 +2514,7 @@ int wxListMainWindow::GetTextLength( wxString &s )
int wxListMainWindow::GetIndexOfLine( const wxListLineData *line )
{
int i = m_lines.Index(*line);
if (i == wxNOT_FOUND) return -1;
else return i;
return m_lines.Index(*line);
}
void wxListMainWindow::SetImageList( wxImageList *imageList, int which )
@ -2740,9 +2798,16 @@ void wxListMainWindow::GetItem( wxListItem &item )
}
}
int wxListMainWindow::GetItemCount()
int wxListMainWindow::GetItemCount() const
{
return m_lines.GetCount();
return IsVirtual() ? m_countVirt : m_lines.GetCount();
}
void wxListMainWindow::SetItemCount(long count)
{
m_countVirt = count;
Refresh();
}
void wxListMainWindow::GetItemRect( long index, wxRect &rect )
@ -2809,7 +2874,8 @@ long wxListMainWindow::GetMode() const
void wxListMainWindow::CalculatePositions()
{
if (m_lines.IsEmpty()) return;
if ( IsEmpty() )
return;
wxClientDC dc( this );
dc.SetFont( GetFont() );
@ -2933,7 +2999,7 @@ void wxListMainWindow::RealizeChanges()
{
if (!m_current)
{
if (!m_lines.IsEmpty())
if ( !IsEmpty() )
m_current = &m_lines[0];
}
if (m_current)
@ -3095,10 +3161,18 @@ void wxListMainWindow::InsertItem( wxListItem &item )
{
m_dirty = TRUE;
int mode = 0;
if (m_mode & wxLC_REPORT) mode = wxLC_REPORT;
else if (m_mode & wxLC_LIST) mode = wxLC_LIST;
else if (m_mode & wxLC_ICON) mode = wxLC_ICON;
else if (m_mode & wxLC_SMALL_ICON) mode = wxLC_ICON; // no typo
if (m_mode & wxLC_REPORT)
mode = wxLC_REPORT;
else if (m_mode & wxLC_LIST)
mode = wxLC_LIST;
else if (m_mode & wxLC_ICON)
mode = wxLC_ICON;
else if (m_mode & wxLC_SMALL_ICON)
mode = wxLC_ICON; // no typo
else
{
wxFAIL_MSG( _T("unknown mode") );
}
wxListLineData *line = new wxListLineData( this, mode, m_hilightBrush );