/////////////////////////////////////////////////////////////////////////////
#ifdef __GNUG__
-#pragma implementation "listctrl.h"
+ #pragma implementation "listctrl.h"
+ #pragma implementation "listctrlbase.h"
#endif
// For compilers that support precompilation, includes "wx.h".
{
wxListItemData *item = (wxListItemData*)node->Data();
wxString s = item->GetText();
- long lw,lh;
+ wxCoord lw,lh;
dc->GetTextExtent( s, &lw, &lh );
if (lw > m_spacing) m_bound_all.width = lw;
}
{
wxListItemData *item = (wxListItemData*)node->Data();
wxString s = item->GetText();
- long lw,lh;
+ wxCoord lw,lh;
dc->GetTextExtent( s, &lw, &lh );
m_bound_all.width = lw;
m_bound_all.height = lh;
if (item->HasImage())
{
+#ifdef __WIN16__
int w = 0;
int h = 0;
+#else
+ wxCoord w = 0;
+ wxCoord h = 0;
+#endif
m_owner->GetImageSize( item->GetImage(), w, h );
m_bound_all.width += 4 + w;
if (h > m_bound_all.height) m_bound_all.height = h;
wxString s;
item->GetText( s );
if (s.IsNull()) s = "H";
- long lw,lh;
+ wxCoord lw,lh;
dc->GetTextExtent( s, &lw, &lh );
item->SetSize( item->GetWidth(), lh );
m_bound_all.width += lw;
{
wxString s;
item->GetText( s );
- long lw,lh;
+ wxCoord lw,lh;
dc->GetTextExtent( s, &lw, &lh );
if (m_bound_all.width > m_spacing)
m_bound_label.x = m_bound_all.x;
}
case wxLC_REPORT:
{
- long lw,lh;
+ wxCoord lw,lh;
dc->GetTextExtent( "H", &lw, &lh );
m_bound_all.x = 0;
m_bound_all.y -= 0;
wxString s;
item->GetText( s );
if (s.IsEmpty()) s = wxT("H");
- long lw,lh;
+ wxCoord lw,lh;
dc->GetTextExtent( s, &lw, &lh );
m_bound_label.width = lw;
m_bound_label.height = lh;
void wxListLineData::SetColumnPosition( int index, int x )
{
- int i = index;
- wxNode *node = m_items.Nth( i );
+ wxNode *node = m_items.Nth( (size_t)index );
if (node)
{
wxListItemData *item = (wxListItemData*)node->Data();
void wxListLineData::SetAttributes(wxDC *dc,
const wxListItemAttr *attr,
const wxColour& colText,
- const wxFont& font)
+ const wxFont& font,
+ bool hilight)
{
- if ( attr && attr->HasTextColour() )
+ // don't use foregroud colour for drawing highlighted items - this might
+ // make them completely invisible (and there is no way to do bit
+ // arithmetics on wxColour, unfortunately)
+ if ( !hilight && attr && attr->HasTextColour() )
{
dc->SetTextForeground(attr->GetTextColour());
}
void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG )
{
- long dev_x = dc->LogicalToDeviceX( m_bound_all.x-2 );
- long dev_y = dc->LogicalToDeviceY( m_bound_all.y-2 );
- long dev_w = dc->LogicalToDeviceXRel( m_bound_all.width+4 );
- long dev_h = dc->LogicalToDeviceYRel( m_bound_all.height+4 );
+ wxCoord dev_x = dc->LogicalToDeviceX( m_bound_all.x-2 );
+ wxCoord dev_y = dc->LogicalToDeviceY( m_bound_all.y-2 );
+ wxCoord dev_w = dc->LogicalToDeviceXRel( m_bound_all.width+4 );
+ wxCoord dev_h = dc->LogicalToDeviceYRel( m_bound_all.height+4 );
if (!m_owner->IsExposed( dev_x, dev_y, dev_w, dev_h ))
{
// customize the subitems (in report mode) too.
wxListItemData *item = (wxListItemData*)m_items.First()->Data();
wxListItemAttr *attr = item->GetAttributes();
- SetAttributes(dc, attr, colText, font);
+ SetAttributes(dc, attr, colText, font, hilight);
bool hasBgCol = attr && attr->HasBackgroundColour();
if ( paintBG || hasBgCol )
void wxListLineData::Hilight( bool on )
{
if (on == m_hilighted) return;
+ m_hilighted = on;
if (on)
m_owner->SelectLine( this );
else
m_owner->DeselectLine( this );
- m_hilighted = on;
}
void wxListLineData::ReverseHilight( void )
int cw = item.m_width-2;
#if wxUSE_GENERIC_LIST_EXTENSIONS
if ((i+1 == numColumns) || ( dc.LogicalToDeviceX(x+item.m_width) > w-5))
- cw = dc.DeviceToLogicalX(w)-x-1;
+ cw = dc.DeviceToLogicalX(w)-x-1;
#else
- if ((i+1 == numColumns) || (x+item.m_width > w-5)) cw = w-x-1;
+ if ((i+1 == numColumns) || (x+item.m_width > w-5))
+ cw = w-x-1;
#endif
dc.SetPen( *wxWHITE_PEN );
void wxListHeaderWindow::OnMouse( wxMouseEvent &event )
{
- int x = event.GetX();
- int y = event.GetY();
+ wxCoord x = (wxCoord)event.GetX();
+ wxCoord y = (wxCoord)event.GetY();
if (m_isDragging)
{
DrawCurrent();
EVT_KILL_FOCUS (wxListTextCtrl::OnKillFocus)
END_EVENT_TABLE()
-wxListTextCtrl::wxListTextCtrl( wxWindow *parent, const wxWindowID id,
- bool *accept, wxString *res, wxListMainWindow *owner,
- const wxString &value, const wxPoint &pos, const wxSize &size,
-#if wxUSE_VALIDATORS
- int style, const wxValidator& validator, const wxString &name ) :
-#endif
- wxTextCtrl( parent, id, value, pos, size, style, validator, name )
+wxListTextCtrl::wxListTextCtrl( wxWindow *parent,
+ const wxWindowID id,
+ bool *accept,
+ wxString *res,
+ wxListMainWindow *owner,
+ const wxString &value,
+ const wxPoint &pos,
+ const wxSize &size,
+ int style,
+ const wxValidator& validator,
+ const wxString &name )
+ : wxTextCtrl( parent, id, value, pos, size, style, validator, name )
{
m_res = res;
m_accept = accept;
void wxListMainWindow::RefreshLine( wxListLineData *line )
{
+ if (m_dirty) return;
+
int x = 0;
int y = 0;
int w = 0;
le.SetEventObject( GetParent() );
le.m_itemIndex = GetIndexOfLine( line );
line->GetItem( 0, le.m_item );
-// GetParent()->GetEventHandler()->ProcessEvent( le );
- GetParent()->GetEventHandler()->AddPendingEvent( le );
+ GetParent()->GetEventHandler()->ProcessEvent( le );
+// GetParent()->GetEventHandler()->AddPendingEvent( le );
}
void wxListMainWindow::FocusLine( wxListLineData *WXUNUSED(line) )
void wxListMainWindow::EditLabel( long item )
{
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
wxCHECK_RET( node, wxT("wrong index in wxListCtrl::Edit()") );
m_currentEdit = (wxListLineData*) node->Data();
wxClientDC dc(this);
PrepareDC(dc);
- long x = dc.DeviceToLogicalX( (long)event.GetX() );
- long y = dc.DeviceToLogicalY( (long)event.GetY() );
+ wxCoord x = dc.DeviceToLogicalX( (wxCoord)event.GetX() );
+ wxCoord y = dc.DeviceToLogicalY( (wxCoord)event.GetY() );
/* Did we actually hit an item ? */
long hitResult = 0;
{
if (!m_current) return;
- int x = 0;
- int y = 0;
- int w = 0;
- int h = 0;
- m_current->GetExtent( x, y, w, h );
+ int item_x = 0;
+ int item_y = 0;
+ int item_w = 0;
+ int item_h = 0;
+ m_current->GetExtent( item_x, item_y, item_w, item_h );
- int w_p = 0;
- int h_p = 0;
- GetClientSize( &w_p, &h_p );
+ int client_w = 0;
+ int client_h = 0;
+ GetClientSize( &client_w, &client_h );
+
+ int view_x = m_xScroll*GetScrollPos( wxHORIZONTAL );
+ int view_y = m_yScroll*GetScrollPos( wxVERTICAL );
if (m_mode & wxLC_REPORT)
{
- int y_s = m_yScroll*GetScrollPos( wxVERTICAL );
- if ((y > y_s) && (y+h < y_s+h_p)) return;
- if (y-y_s < 5) { Scroll( -1, (y-5-h_p/2)/m_yScroll ); }
- if (y+h+5 > y_s+h_p) { Scroll( -1, (y+h-h_p/2+h+15)/m_yScroll); }
+ if (item_y-5 < view_y )
+ Scroll( -1, (item_y-5)/m_yScroll );
+ if (item_y+item_h+5 > view_y+client_h)
+ Scroll( -1, (item_y+item_h-client_h+15)/m_yScroll );
}
else
{
- int x_s = m_xScroll*GetScrollPos( wxHORIZONTAL );
- if ((x > x_s) && (x+w < x_s+w_p)) return;
- if (x-x_s < 5) { Scroll( (x-5)/m_xScroll, -1 ); }
- if (x+w-5 > x_s+w_p) { Scroll( (x+w-w_p+15)/m_xScroll, -1 ); }
+ if (item_x-view_x < 5)
+ Scroll( (item_x-5)/m_xScroll, -1 );
+ if (item_x+item_w-5 > view_x+client_w)
+ Scroll( (item_x+item_w-client_w+15)/m_xScroll, -1 );
}
}
if ((m_mode & wxLC_SINGLE_SEL) || (m_usedKeys == FALSE)) m_current->Hilight( FALSE );
wxListLineData *oldCurrent = m_current;
m_current = newCurrent;
- MoveToFocus();
if (shiftDown || (m_mode & wxLC_SINGLE_SEL)) m_current->Hilight( TRUE );
RefreshLine( m_current );
RefreshLine( oldCurrent );
FocusLine( m_current );
UnfocusLine( oldCurrent );
+ MoveToFocus();
}
void wxListMainWindow::OnKeyDown( wxKeyEvent &event )
/* we send a list_key event up */
wxListEvent le( wxEVT_COMMAND_LIST_KEY_DOWN, GetParent()->GetId() );
- le.m_code = event.KeyCode();
+ le.m_code = (int)event.KeyCode();
le.SetEventObject( parent );
parent->GetEventHandler()->ProcessEvent( le );
{
wxNavigationKeyEvent nevent;
nevent.SetDirection( !event.ShiftDown() );
+ nevent.SetEventObject( GetParent()->GetParent() );
nevent.SetCurrentFocus( m_parent );
- if (m_parent->GetEventHandler()->ProcessEvent( nevent )) return;
+ if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent )) return;
}
/* no item -> nothing to do */
m_current->ReverseHilight();
wxNode *node = m_lines.Member( m_current )->Next();
if (node) m_current = (wxListLineData*)node->Data();
- MoveToFocus();
RefreshLine( oldCurrent );
RefreshLine( m_current );
UnfocusLine( oldCurrent );
FocusLine( m_current );
+ MoveToFocus();
}
break;
}
int wxListMainWindow::GetTextLength( wxString &s )
{
wxClientDC dc( this );
- long lw = 0;
- long lh = 0;
+ wxCoord lw = 0;
+ wxCoord lh = 0;
dc.GetTextExtent( s, &lw, &lh );
return lw + 6;
}
{
wxListItemData *item = (wxListItemData*)n->Data();
int current = 0, ix = 0, iy = 0;
- long lx = 0, ly = 0;
+ wxCoord lx = 0, ly = 0;
if (item->HasImage())
{
GetImageSize( item->GetImage(), ix, iy );
void wxListMainWindow::SetItem( wxListItem &item )
{
m_dirty = TRUE;
- wxNode *node = m_lines.Nth( item.m_itemId );
+ wxNode *node = m_lines.Nth( (size_t)item.m_itemId );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
if (stateMask & wxLIST_STATE_FOCUSED)
{
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
if (stateMask & wxLIST_STATE_SELECTED)
{
- bool on = state & wxLIST_STATE_SELECTED;
+ bool on = (state & wxLIST_STATE_SELECTED) != 0;
if (!on && (m_mode & wxLC_SINGLE_SEL)) return;
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
RefreshLine( m_current );
if (oldCurrent) RefreshLine( oldCurrent );
}
- bool on = state & wxLIST_STATE_SELECTED;
+ bool on = (state & wxLIST_STATE_SELECTED) != 0;
if (on != line->IsHilighted())
{
line->Hilight( on );
int ret = wxLIST_STATE_DONTCARE;
if (stateMask & wxLIST_STATE_FOCUSED)
{
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
}
if (stateMask & wxLIST_STATE_SELECTED)
{
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
void wxListMainWindow::GetItem( wxListItem &item )
{
- wxNode *node = m_lines.Nth( item.m_itemId );
+ wxNode *node = m_lines.Nth( (size_t)item.m_itemId );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
void wxListMainWindow::GetItemRect( long index, wxRect &rect )
{
- wxNode *node = m_lines.Nth( index );
+ wxNode *node = m_lines.Nth( (size_t)index );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
bool wxListMainWindow::GetItemPosition(long item, wxPoint& pos)
{
- wxNode *node = m_lines.Nth( item );
+ wxNode *node = m_lines.Nth( (size_t)item );
if (node)
{
wxRect rect;
}
}
-long wxListMainWindow::GetNextItem( long item, int WXUNUSED(geometry), int state )
+long wxListMainWindow::GetNextItem( long item,
+ int WXUNUSED(geometry),
+ int state )
{
- long ret = 0;
- if (item > 0) ret = item;
- if(ret >= GetItemCount()) return -1;
- wxNode *node = m_lines.Nth( ret );
+ long ret = item,
+ max = GetItemCount();
+ wxCHECK_MSG( (ret == -1) || (ret < max), -1,
+ _T("invalid listctrl index in GetNextItem()") );
+
+ // notice that we start with the next item (or the first one if item == -1)
+ // and this is intentional to allow writing a simple loop to iterate over
+ // all selected items
+ ret++;
+ if ( ret == max )
+ {
+ // this is not an error because the index was ok initially, just no
+ // such item
+ return -1;
+ }
+
+ wxNode *node = m_lines.Nth( (size_t)ret );
while (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
- if ((state & wxLIST_STATE_FOCUSED) && (line == m_current)) return ret;
- if ((state & wxLIST_STATE_SELECTED) && (line->IsHilighted())) return ret;
- if (!state) return ret;
+ if ((state & wxLIST_STATE_FOCUSED) && (line == m_current))
+ return ret;
+ if ((state & wxLIST_STATE_SELECTED) && (line->IsHilighted()))
+ return ret;
+ if (!state)
+ return ret;
ret++;
+
node = node->Next();
}
+
return -1;
}
void wxListMainWindow::DeleteItem( long index )
{
m_dirty = TRUE;
- wxNode *node = m_lines.Nth( index );
+ wxNode *node = m_lines.Nth( (size_t)index );
if (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
wxListLineData *oldCurrent = m_current;
m_current = (wxListLineData *) NULL;
- int i = index;
- wxNode *node = m_lines.Nth( i );
+ wxNode *node = m_lines.Nth( (size_t)index );
if (node) m_current = (wxListLineData*)node->Data();
if (m_current) MoveToFocus();
m_current = oldCurrent;
long pos = start;
wxString tmp = str;
if (pos < 0) pos = 0;
- wxNode *node = m_lines.Nth( pos );
+ wxNode *node = m_lines.Nth( (size_t)pos );
while (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
{
long pos = start;
if (pos < 0) pos = 0;
- wxNode *node = m_lines.Nth( pos );
+ wxNode *node = m_lines.Nth( (size_t)pos );
while (node)
{
wxListLineData *line = (wxListLineData*)node->Data();
long ret = line->IsHit( x, y );
if (ret & flags)
{
- flags = ret;
+ flags = (int)ret;
return count;
}
node = node->Next();
line->SetItem( 0, item );
if ((item.m_itemId >= 0) && (item.m_itemId < (int)m_lines.GetCount()))
{
- wxNode *node = m_lines.Nth( item.m_itemId );
+ wxNode *node = m_lines.Nth( (size_t)item.m_itemId );
if (node) m_lines.Insert( node, line );
}
else
wxListHeaderData *column = new wxListHeaderData( item );
if ((col >= 0) && (col < (int)m_columns.GetCount()))
{
- wxNode *node = m_columns.Nth( col );
+ wxNode *node = m_columns.Nth( (size_t)col );
if (node)
m_columns.Insert( node, column );
}
list_ctrl_compare_func_2 = fn;
list_ctrl_compare_data = data;
m_lines.Sort( list_ctrl_compare_func_1 );
+ m_dirty = TRUE;
}
void wxListMainWindow::OnScroll(wxScrollWinEvent& event)
m_attr = NULL;
}
+void wxListItem::Clear()
+{
+ m_mask = 0;
+ m_itemId = 0;
+ m_col = 0;
+ m_state = 0;
+ m_stateMask = 0;
+ m_image = 0;
+ m_data = 0;
+ m_format = wxLIST_FORMAT_CENTRE;
+ m_width = 0;
+ m_text = wxEmptyString;
+
+ if (m_attr) delete m_attr;
+ m_attr = NULL;
+}
+
+void wxListItem::ClearAttributes()
+{
+ if (m_attr) delete m_attr;
+ m_attr = NULL;
+}
+
// -------------------------------------------------------------------------------------
// wxListEvent
// -------------------------------------------------------------------------------------
{
}
-bool wxListCtrl::Create( wxWindow *parent, wxWindowID id,
- const wxPoint &pos, const wxSize &size,
-#if wxUSE_VALIDATORS
- long style, const wxValidator &validator,
-#endif
- const wxString &name )
+bool wxListCtrl::Create(wxWindow *parent,
+ wxWindowID id,
+ const wxPoint &pos,
+ const wxSize &size,
+ long style,
+ const wxValidator &validator,
+ const wxString &name)
{
m_imageListNormal = (wxImageList *) NULL;
m_imageListSmall = (wxImageList *) NULL;
m_mainWin = (wxListMainWindow*) NULL;
m_headerWin = (wxListHeaderWindow*) NULL;
- long s = style;
-
-#ifdef __VMS__
-#pragma message disable codcauunr
- // VMS reports on this part the warning:
- // statement either is unreachable or causes unreachable code
-#endif
- if ((s & wxLC_REPORT == 0) &&
- (s & wxLC_LIST == 0) &&
- (s & wxLC_ICON == 0))
+ if ( !(style & (wxLC_REPORT | wxLC_LIST | wxLC_ICON)) )
{
- s = s | wxLC_LIST;
+ style = style | wxLC_LIST;
}
-#ifdef __VMS__
-#pragma message enable codcauunr
-#endif
-
- bool ret = wxControl::Create( parent, id, pos, size, s, name );
-
-#if wxUSE_VALIDATORS
- SetValidator( validator );
-#endif
-
- if (s & wxSUNKEN_BORDER) s -= wxSUNKEN_BORDER;
+
+ bool ret = wxControl::Create( parent, id, pos, size, style, validator, name );
+
+
+ if (style & wxSUNKEN_BORDER)
+ style -= wxSUNKEN_BORDER;
- m_mainWin = new wxListMainWindow( this, -1, wxPoint(0,0), size, s );
+ m_mainWin = new wxListMainWindow( this, -1, wxPoint(0,0), size, style );
if (HasFlag(wxLC_REPORT))
+ {
m_headerWin = new wxListHeaderWindow( this, -1, m_mainWin, wxPoint(0,0), wxSize(size.x,23), wxTAB_TRAVERSAL );
+ if (HasFlag(wxLC_NO_HEADER))
+ m_headerWin->Show( FALSE );
+ }
else
+ {
m_headerWin = (wxListHeaderWindow *) NULL;
+ }
SetBackgroundColour( *wxWHITE );
long wxListCtrl::InsertColumn( long col, wxListItem &item )
{
+ wxASSERT( m_headerWin );
m_mainWin->InsertColumn( col, item );
+ m_headerWin->Refresh();
+
return 0;
}