X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/3ca6a5f04692678cd2d9f3ea0843fc3f5a0b254f..4b7b750dd1ffd0d26b78728adb613b282a37c058:/src/generic/listctrl.cpp?ds=inline diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index 607477e3eb..38985b43ff 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: listctrl.cpp -// Purpose: +// Name: generic/listctrl.cpp +// Purpose: generic implementation of wxListCtrl // Author: Robert Roebling // Id: $Id$ // Copyright: (c) 1998 Robert Roebling @@ -19,16 +19,44 @@ #pragma hdrstop #endif +#if wxUSE_LISTCTRL + #include "wx/dcscreen.h" #include "wx/app.h" #include "wx/listctrl.h" #include "wx/generic/imaglist.h" #include "wx/dynarray.h" +#ifdef __WXGTK__ +#include +#include "wx/gtk/win_gtk.h" +#endif + #ifndef wxUSE_GENERIC_LIST_EXTENSIONS #define wxUSE_GENERIC_LIST_EXTENSIONS 1 #endif +// ---------------------------------------------------------------------------- +// events +// ---------------------------------------------------------------------------- + +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_DRAG) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_RDRAG) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_END_LABEL_EDIT) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ITEM) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_GET_INFO) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_SET_INFO) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_SELECTED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_DESELECTED) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_KEY_DOWN) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_INSERT_ITEM) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_CLICK) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK) +DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_ACTIVATED) + // ============================================================================ // private classes // ============================================================================ @@ -39,31 +67,24 @@ class WXDLLEXPORT wxListItemData : public wxObject { -public: - wxString m_text; - int m_image; - long m_data; - int m_xpos,m_ypos; - int m_width,m_height; - - wxListItemAttr *m_attr; - public: wxListItemData(); ~wxListItemData() { delete m_attr; } wxListItemData( const wxListItem &info ); void SetItem( const wxListItem &info ); - void SetText( const wxString &s ); void SetImage( int image ); void SetData( long data ); void SetPosition( int x, int y ); void SetSize( int width, int height ); bool HasImage() const; - bool HasText() const; + + bool HasText() const { return !m_text.empty(); } + const wxString& GetText() const { return m_text; } + void SetText(const wxString& text) { m_text = text; } + bool IsHit( int x, int y ) const; - void GetText( wxString &s ); - const wxString& GetText() { return m_text; } + int GetX( void ) const; int GetY( void ) const; int GetWidth() const; @@ -73,6 +94,19 @@ public: wxListItemAttr *GetAttributes() const { return m_attr; } +public: + int m_image; + long m_data; + int m_xpos, + m_ypos; + int m_width, + m_height; + + wxListItemAttr *m_attr; + +protected: + wxString m_text; + private: DECLARE_DYNAMIC_CLASS(wxListItemData); }; @@ -101,10 +135,14 @@ public: void SetFormat( int format ); void SetHeight( int h ); bool HasImage() const; - bool HasText() const; - bool IsHit( int x, int y ) const; + + bool HasText() const { return !m_text.empty(); } + const wxString& GetText() const { return m_text; } + void SetText(const wxString& text) { m_text = text; } + void GetItem( wxListItem &item ); - void GetText( wxString &s ); + + bool IsHit( int x, int y ) const; int GetImage() const; int GetWidth() const; int GetFormat() const; @@ -146,7 +184,7 @@ public: void InitItems( int num ); void SetItem( int index, const wxListItem &info ); void GetItem( int index, wxListItem &info ); - void GetText( int index, wxString &s ); + wxString GetText(int index) const; void SetText( int index, const wxString s ); int GetImage( int index ); void GetRect( wxRect &rect ); @@ -259,6 +297,7 @@ public: const wxValidator& validator = wxDefaultValidator, const wxString &name = "listctrltextctrl" ); void OnChar( wxKeyEvent &event ); + void OnKeyUp( wxKeyEvent &event ); void OnKillFocus( wxFocusEvent &event ); private: @@ -310,7 +349,9 @@ public: void RefreshLine( wxListLineData *line ); void OnPaint( wxPaintEvent &event ); void HilightAll( bool on ); - void SendNotify( wxListLineData *line, wxEventType command ); + void SendNotify( wxListLineData *line, + wxEventType command, + wxPoint point = wxDefaultPosition ); void FocusLine( wxListLineData *line ); void UnfocusLine( wxListLineData *line ); void SelectLine( wxListLineData *line ); @@ -410,9 +451,12 @@ wxListItemData::wxListItemData( const wxListItem &info ) void wxListItemData::SetItem( const wxListItem &info ) { - if (info.m_mask & wxLIST_MASK_TEXT) m_text = info.m_text; - if (info.m_mask & wxLIST_MASK_IMAGE) m_image = info.m_image; - if (info.m_mask & wxLIST_MASK_DATA) m_data = info.m_data; + if (info.m_mask & wxLIST_MASK_TEXT) + SetText(info.m_text); + if (info.m_mask & wxLIST_MASK_IMAGE) + m_image = info.m_image; + if (info.m_mask & wxLIST_MASK_DATA) + m_data = info.m_data; if ( info.HasAttributes() ) { @@ -428,11 +472,6 @@ void wxListItemData::SetItem( const wxListItem &info ) m_height = 0; } -void wxListItemData::SetText( const wxString &s ) -{ - m_text = s; -} - void wxListItemData::SetImage( int image ) { m_image = image; @@ -460,21 +499,11 @@ bool wxListItemData::HasImage() const return (m_image >= 0); } -bool wxListItemData::HasText() const -{ - return (!m_text.IsNull()); -} - bool wxListItemData::IsHit( int x, int y ) const { return ((x >= m_xpos) && (x <= m_xpos+m_width) && (y >= m_ypos) && (y <= m_ypos+m_height)); } -void wxListItemData::GetText( wxString &s ) -{ - s = m_text; -} - int wxListItemData::GetX() const { return m_xpos; @@ -581,11 +610,6 @@ bool wxListHeaderData::HasImage() const return (m_image != 0); } -bool wxListHeaderData::HasText() const -{ - return (m_text.Length() > 0); -} - bool wxListHeaderData::IsHit( int x, int y ) const { return ((x >= m_xpos) && (x <= m_xpos+m_width) && (y >= m_ypos) && (y <= m_ypos+m_height)); @@ -600,11 +624,6 @@ void wxListHeaderData::GetItem( wxListItem &item ) item.m_width = m_width; } -void wxListHeaderData::GetText( wxString &s ) -{ - s = m_text; -} - int wxListHeaderData::GetImage() const { return m_image; @@ -730,6 +749,23 @@ 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(); + if (item->HasImage()) + { + int w = 0; + int h = 0; + m_owner->GetImageSize( item->GetImage(), w, h ); + m_bound_icon.width = w; + m_bound_icon.height = h; + } + else + { + m_bound_icon.width = 0; + m_bound_icon.height = 0; + } + } while (node) { wxListItemData *item = (wxListItemData*)node->Data(); @@ -746,6 +782,8 @@ void wxListLineData::CalculateSize( wxDC *dc, int spacing ) m_bound_all.height = lh; node = node->Next(); } + m_bound_label.width = m_bound_all.width; + m_bound_label.height = m_bound_all.height; break; } } @@ -911,16 +949,18 @@ void wxListLineData::GetItem( int index, wxListItem &info ) } } -void wxListLineData::GetText( int index, wxString &s ) +wxString wxListLineData::GetText(int index) const { - int i = index; - wxNode *node = m_items.Nth( i ); - s = ""; + wxString s; + + wxNode *node = m_items.Nth( index ); if (node) { wxListItemData *item = (wxListItemData*)node->Data(); - item->GetText( s ); + s = item->GetText(); } + + return s; } void wxListLineData::SetText( int index, const wxString s ) @@ -1173,6 +1213,15 @@ wxListHeaderWindow::~wxListHeaderWindow( void ) void wxListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h ) { +#ifdef __WXGTK__ + GtkStateType state = GTK_STATE_NORMAL; + if (!m_parent->IsEnabled()) state = GTK_STATE_INSENSITIVE; + + x = dc->XLOG2DEV( x ); + + gtk_paint_box (m_wxwindow->style, GTK_PIZZA(m_wxwindow)->bin_window, state, GTK_SHADOW_OUT, + (GdkRectangle*) NULL, m_wxwindow, "button", x-1, y-1, w+2, h+2); +#else const int m_corner = 1; dc->SetBrush( *wxTRANSPARENT_BRUSH ); @@ -1192,6 +1241,7 @@ void wxListHeaderWindow::DoDrawRect( wxDC *dc, int x, int y, int w, int h ) dc->DrawRectangle( x, y, 1, h ); // left (outer) dc->DrawLine( x, y+h-1, x+1, y+h-1 ); dc->DrawLine( x+w-1, y, x+w-1, y+1 ); +#endif } // shift the DC origin to match the position of the main window horz @@ -1212,7 +1262,12 @@ void wxListHeaderWindow::AdjustDC(wxDC& dc) void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) { +#ifdef __WXGTK__ + wxClientDC dc( this ); +#else wxPaintDC dc( this ); +#endif + PrepareDC( dc ); AdjustDC( dc ); @@ -1231,7 +1286,8 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) // do *not* use the listctrl colour for headers - one day we will have a // function to set it separately - dc.SetTextForeground( *wxBLACK ); + //dc.SetTextForeground( *wxBLACK ); + dc.SetTextForeground(wxSystemSettings::GetSystemColour( wxSYS_COLOUR_WINDOWTEXT )); int x = 1; // left of the header rect const int y = 1; // top @@ -1257,7 +1313,7 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) DoDrawRect( &dc, x, y, cw, h-2 ); dc.SetClippingRegion( x, y, cw-5, h-4 ); - dc.DrawText( item.m_text, x+4, y+3 ); + dc.DrawText( item.GetText(), x+4, y+3 ); dc.DestroyClippingRegion(); x += wCol; @@ -1434,6 +1490,7 @@ IMPLEMENT_DYNAMIC_CLASS(wxListTextCtrl,wxTextCtrl); BEGIN_EVENT_TABLE(wxListTextCtrl,wxTextCtrl) EVT_CHAR (wxListTextCtrl::OnChar) + EVT_KEY_UP (wxListTextCtrl::OnKeyUp) EVT_KILL_FOCUS (wxListTextCtrl::OnKillFocus) END_EVENT_TABLE() @@ -1487,6 +1544,21 @@ void wxListTextCtrl::OnChar( wxKeyEvent &event ) event.Skip(); } +void wxListTextCtrl::OnKeyUp( wxKeyEvent &event ) +{ + // auto-grow the textctrl: + wxSize parentSize = m_owner->GetSize(); + wxPoint myPos = GetPosition(); + wxSize mySize = GetSize(); + int sx, sy; + GetTextExtent(GetValue() + _T("MM"), &sx, &sy); + if (myPos.x + sx > parentSize.x) sx = parentSize.x - myPos.x; + if (mySize.x > sx) sx = mySize.x; + SetSize(sx, -1); + + event.Skip(); +} + void wxListTextCtrl::OnKillFocus( wxFocusEvent &WXUNUSED(event) ) { if (!wxPendingDelete.Member(this)) @@ -1615,6 +1687,10 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) wxPaintDC dc( this ); PrepareDC( dc ); + int dev_x = 0; + int dev_y = 0; + CalcScrolledPosition( 0, 0, &dev_x, &dev_y ); + if (m_dirty) return; if (m_lines.GetCount() == 0) return; @@ -1625,6 +1701,9 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) if (m_mode & wxLC_REPORT) { + wxPen pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT), 1, wxSOLID); + wxSize clientSize = GetClientSize(); + int lineSpacing = 0; wxListLineData *line = &m_lines[0]; int dummy = 0; @@ -1635,9 +1714,44 @@ void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) size_t i_to = y_s / lineSpacing + m_visibleLines+2; if (i_to >= m_lines.GetCount()) i_to = m_lines.GetCount(); - for (size_t i = y_s / lineSpacing; i < i_to; i++) + size_t i; + for (i = y_s / lineSpacing; i < i_to; i++) { m_lines[i].Draw( &dc ); + // Draw horizontal rule if required + if (GetWindowStyle() & wxLC_HRULES) + { + dc.SetPen(pen); + dc.SetBrush(* wxTRANSPARENT_BRUSH); + dc.DrawLine(0 - dev_x , i*lineSpacing , clientSize.x - dev_x , i*lineSpacing ); + } + } + + // Draw last horizontal rule + if ((i > (size_t) (y_s / lineSpacing)) && (GetWindowStyle() & wxLC_HRULES)) + { + 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 ((GetWindowStyle() & wxLC_VRULES) && (GetItemCount() > 0)) + { + int col = 0; + wxRect firstItemRect; + wxRect lastItemRect; + GetItemRect(0, firstItemRect); + GetItemRect(GetItemCount() - 1, lastItemRect); + int x = firstItemRect.GetX(); + dc.SetPen(pen); + dc.SetBrush(* wxTRANSPARENT_BRUSH); + for (col = 0; col < GetColumnCount(); col++) + { + int colWidth = GetColumnWidth(col); + x += colWidth ; + dc.DrawLine(x - dev_x, firstItemRect.GetY() - 1 - dev_y, x - dev_x, lastItemRect.GetBottom() + 1 - dev_y); + } } } else @@ -1664,11 +1778,18 @@ void wxListMainWindow::HilightAll( bool on ) } } -void wxListMainWindow::SendNotify( wxListLineData *line, wxEventType command ) +void wxListMainWindow::SendNotify( wxListLineData *line, + wxEventType command, + wxPoint point ) { wxListEvent le( command, GetParent()->GetId() ); le.SetEventObject( GetParent() ); le.m_itemIndex = GetIndexOfLine( line ); + + // set only for events which have position + if ( point != wxDefaultPosition ) + le.m_pointDrag = point; + line->GetItem( 0, le.m_item ); GetParent()->GetEventHandler()->ProcessEvent( le ); // GetParent()->GetEventHandler()->AddPendingEvent( le ); @@ -1703,7 +1824,7 @@ void wxListMainWindow::DeleteLine( wxListLineData *line ) void wxListMainWindow::EditLabel( long item ) { - wxCHECK_RET( ((size_t)item < m_lines.GetCount()), + wxCHECK_RET( ((size_t)item < m_lines.GetCount()), wxT("wrong index in wxListCtrl::Edit()") ); m_currentEdit = &m_lines[(size_t)item]; @@ -1722,8 +1843,7 @@ void wxListMainWindow::EditLabel( long item ) // update taken place. if (m_dirty) wxYield(); - wxString s; - m_currentEdit->GetText( 0, s ); + wxString s = m_currentEdit->GetText(0); int x = 0; int y = 0; int w = 0; @@ -1768,6 +1888,7 @@ void wxListMainWindow::OnRenameAccept() void wxListMainWindow::OnMouse( wxMouseEvent &event ) { + event.SetEventObject( GetParent() ); if (GetParent()->GetEventHandler()->ProcessEvent( event)) return; if (!m_current) return; @@ -1798,8 +1919,8 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) if (m_dragCount != 3) return; - int command = wxEVT_COMMAND_LIST_BEGIN_DRAG; - if (event.RightIsDown()) command = wxEVT_COMMAND_LIST_BEGIN_RDRAG; + int command = event.RightIsDown() ? wxEVT_COMMAND_LIST_BEGIN_RDRAG + : wxEVT_COMMAND_LIST_BEGIN_DRAG; wxListEvent le( command, GetParent()->GetId() ); le.SetEventObject( GetParent() ); @@ -1852,7 +1973,8 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) if (event.RightDown()) { - SendNotify( line, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK ); + SendNotify( line, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK, + event.GetPosition() ); return; } @@ -1887,7 +2009,7 @@ void wxListMainWindow::OnMouse( wxMouseEvent &event ) else if (event.ShiftDown()) { size_t j; - + m_current = line; int numOfCurrent = -1; @@ -1962,8 +2084,8 @@ void wxListMainWindow::MoveToFocus() if (m_mode & wxLC_REPORT) { - if (item_y-5 < view_y ) - Scroll( -1, (item_y-5)/m_yScroll ); + if (item_y < view_y ) + Scroll( -1, (item_y)/m_yScroll ); if (item_y+item_h+5 > view_y+client_h) Scroll( -1, (item_y+item_h-client_h+15)/m_yScroll ); } @@ -2095,7 +2217,7 @@ void wxListMainWindow::OnChar( wxKeyEvent &event ) if (index != wxNOT_FOUND) { index -= steps; - if (index < 0) index = 0; + if (index < 0) index = 0; OnArrowChar( &m_lines[index], event.ShiftDown() ); } break; @@ -2116,7 +2238,7 @@ void wxListMainWindow::OnChar( wxKeyEvent &event ) if (index != wxNOT_FOUND) { index += steps; - if ((size_t)index >= m_lines.GetCount()) + if ((size_t)index >= m_lines.GetCount()) index = m_lines.GetCount()-1; OnArrowChar( &m_lines[index], event.ShiftDown() ); } @@ -2144,7 +2266,7 @@ void wxListMainWindow::OnChar( wxKeyEvent &event ) if (index != wxNOT_FOUND) { index += m_visibleLines; - if ((size_t)index >= m_lines.GetCount()) + if ((size_t)index >= m_lines.GetCount()) index = m_lines.GetCount()-1; OnArrowChar( &m_lines[index], event.ShiftDown() ); } @@ -2352,7 +2474,8 @@ void wxListMainWindow::SetColumn( int col, wxListItem &item ) wxNode *node = m_columns.Nth( col ); if (node) { - if (item.m_width == wxLIST_AUTOSIZE_USEHEADER) item.m_width = GetTextLength( item.m_text )+7; + if (item.m_width == wxLIST_AUTOSIZE_USEHEADER) + item.m_width = GetTextLength( item.m_text )+7; wxListHeaderData *column = (wxListHeaderData*)node->Data(); column->SetItem( item ); } @@ -2381,7 +2504,7 @@ void wxListMainWindow::SetColumnWidth( int col, int width ) wxClientDC dc(this); dc.SetFont( GetFont() ); int max = 10; - + for (size_t i = 0; i < m_lines.GetCount(); i++) { wxListLineData *line = &m_lines[i]; @@ -2398,8 +2521,7 @@ void wxListMainWindow::SetColumnWidth( int col, int width ) } if (item->HasText()) { - wxString str; - item->GetText( str ); + wxString str = item->GetText(); dc.GetTextExtent( str, &lx, &ly ); current += lx; } @@ -2444,7 +2566,7 @@ void wxListMainWindow::GetColumn( int col, wxListItem &item ) { item.m_format = 0; item.m_width = 0; - item.m_text = ""; + item.m_text = _T(""); item.m_image = 0; item.m_data = 0; } @@ -2487,49 +2609,68 @@ void wxListMainWindow::SetItem( wxListItem &item ) void wxListMainWindow::SetItemState( long item, long state, long stateMask ) { + wxCHECK_RET( item >= 0 && (size_t)item < m_lines.GetCount(), + _T("invalid list ctrl item index in SetItem") ); + // m_dirty = TRUE; no recalcs needed wxListLineData *oldCurrent = m_current; - if (stateMask & wxLIST_STATE_FOCUSED) - { - if (item >= 0 && (size_t)item < m_lines.GetCount()) - { - wxListLineData *line = &m_lines[(size_t)item]; - UnfocusLine( m_current ); - m_current = line; - FocusLine( m_current ); - if ((m_mode & wxLC_SINGLE_SEL) && oldCurrent) oldCurrent->Hilight( FALSE ); - RefreshLine( m_current ); - if (oldCurrent) RefreshLine( oldCurrent ); - } - } - - if (stateMask & wxLIST_STATE_SELECTED) + if ( stateMask & wxLIST_STATE_FOCUSED ) { - bool on = (state & wxLIST_STATE_SELECTED) != 0; - if (!on && (m_mode & wxLC_SINGLE_SEL)) return; - - if (item >= 0 && (size_t)item < m_lines.GetCount()) + wxListLineData *line = &m_lines[(size_t)item]; + if ( state & wxLIST_STATE_FOCUSED ) { - wxListLineData *line = &m_lines[(size_t)item]; - if (m_mode & wxLC_SINGLE_SEL) + // don't do anything if this item is already focused + if ( line != m_current ) { UnfocusLine( m_current ); m_current = line; FocusLine( m_current ); - if (oldCurrent) oldCurrent->Hilight( FALSE ); + if ( (m_mode & wxLC_SINGLE_SEL) && oldCurrent ) + oldCurrent->Hilight( FALSE ); + RefreshLine( m_current ); - if (oldCurrent) RefreshLine( oldCurrent ); + if ( oldCurrent ) + RefreshLine( oldCurrent ); } - bool on = (state & wxLIST_STATE_SELECTED) != 0; - if (on != line->IsHilighted()) + } + else // unfocus + { + // don't do anything if this item is not focused + if ( line == m_current ) { - line->Hilight( on ); - RefreshLine( line ); + UnfocusLine( m_current ); + m_current = NULL; } } } + + if ( stateMask & wxLIST_STATE_SELECTED ) + { + bool on = (state & wxLIST_STATE_SELECTED) != 0; + if (!on && (m_mode & wxLC_SINGLE_SEL)) + return; + + wxListLineData *line = &m_lines[(size_t)item]; + if (m_mode & wxLC_SINGLE_SEL) + { + UnfocusLine( m_current ); + m_current = line; + FocusLine( m_current ); + if (oldCurrent) + oldCurrent->Hilight( FALSE ); + RefreshLine( m_current ); + if (oldCurrent) + RefreshLine( oldCurrent ); + } + + if (on != line->IsHilighted()) + { + line->Hilight( on ); + RefreshLine( line ); + } + } } int wxListMainWindow::GetItemState( long item, long stateMask ) @@ -2548,7 +2689,7 @@ int wxListMainWindow::GetItemState( long item, long stateMask ) if (item >= 0 && (size_t)item < m_lines.GetCount()) { wxListLineData *line = &m_lines[(size_t)item]; - if (line->IsHilighted()) ret |= wxLIST_STATE_FOCUSED; + if (line->IsHilighted()) ret |= wxLIST_STATE_SELECTED; } } return ret; @@ -2564,7 +2705,7 @@ void wxListMainWindow::GetItem( wxListItem &item ) else { item.m_mask = 0; - item.m_text = ""; + item.m_text = _T(""); item.m_image = 0; item.m_data = 0; } @@ -2580,6 +2721,7 @@ void wxListMainWindow::GetItemRect( long index, wxRect &rect ) if (index >= 0 && (size_t)index < m_lines.GetCount()) { m_lines[(size_t)index].GetRect( rect ); + this->CalcScrolledPosition(rect.x,rect.y,&rect.x,&rect.y); } else { @@ -2592,18 +2734,9 @@ void wxListMainWindow::GetItemRect( long index, wxRect &rect ) bool wxListMainWindow::GetItemPosition(long item, wxPoint& pos) { - if (item >= 0 && (size_t)item < m_lines.GetCount()) - { - wxRect rect; - m_lines[(size_t)item].GetRect( rect ); - pos.x = rect.x; - pos.y = rect.y; - } - else - { - pos.x = 0; - pos.y = 0; - } + wxRect rect; + this->GetItemRect(item,rect); + pos.x=rect.x; pos.y=rect.y; return TRUE; } @@ -2675,6 +2808,9 @@ void wxListMainWindow::CalculatePositions() if (m_mode & wxLC_REPORT) { + // scroll one line per step + m_yScroll = lineSpacing; + int x = 4; int y = 1; int entireHeight = m_lines.GetCount() * lineSpacing + 2; @@ -2682,7 +2818,7 @@ void wxListMainWindow::CalculatePositions() #if wxUSE_GENERIC_LIST_EXTENSIONS int x_scroll_pos = GetScrollPos( wxHORIZONTAL ); #else - SetScrollbars( m_xScroll, m_yScroll, 0, (entireHeight+15) / m_yScroll, 0, scroll_pos, TRUE ); + SetScrollbars( m_xScroll, m_yScroll, 0, entireHeight/m_yScroll +1, 0, scroll_pos, TRUE ); #endif GetClientSize( &clientWidth, &clientHeight ); @@ -2704,9 +2840,9 @@ void wxListMainWindow::CalculatePositions() #endif y += lineSpacing; // one pixel blank line between items } - m_visibleLines = clientHeight / lineSpacing; + m_visibleLines = clientHeight / lineSpacing; #if wxUSE_GENERIC_LIST_EXTENSIONS - SetScrollbars( m_xScroll, m_yScroll, entireWidth / m_xScroll , (entireHeight+15) / m_yScroll, x_scroll_pos , scroll_pos, TRUE ); + SetScrollbars( m_xScroll, m_yScroll, entireWidth/m_xScroll +1, entireHeight/m_yScroll +1, x_scroll_pos , scroll_pos, TRUE ); #endif } else @@ -2883,9 +3019,10 @@ long wxListMainWindow::FindItem(long start, const wxString& str, bool WXUNUSED(p for (size_t i = (size_t)pos; i < m_lines.GetCount(); i++) { wxListLineData *line = &m_lines[i]; - wxString s = ""; - line->GetText( 0, s ); - if (s == tmp) return pos; + wxString s = line->GetText(0); + if (s == tmp) + return pos; + pos++; } return -1; @@ -2915,7 +3052,7 @@ long wxListMainWindow::HitTest( int x, int y, int &flags ) { wxListLineData *line = &m_lines[i]; long ret = line->IsHit( x, y ); - if (ret & flags) + if (ret) // & flags) // No: flags is output-only so may be garbage at this point { flags = (int)ret; return count; @@ -2954,6 +3091,7 @@ void wxListMainWindow::InsertItem( wxListItem &item ) else { m_lines.Add( line ); + item.m_itemId = m_lines.GetCount()-1; } } @@ -2962,7 +3100,8 @@ void wxListMainWindow::InsertColumn( long col, wxListItem &item ) m_dirty = TRUE; if (m_mode & wxLC_REPORT) { - if (item.m_width == wxLIST_AUTOSIZE_USEHEADER) item.m_width = GetTextLength( item.m_text ); + if (item.m_width == wxLIST_AUTOSIZE_USEHEADER) + item.m_width = GetTextLength( item.m_text ); wxListHeaderData *column = new wxListHeaderData( item ); if ((col >= 0) && (col < (int)m_columns.GetCount())) { @@ -3002,7 +3141,13 @@ void wxListMainWindow::SortItems( wxListCtrlCompare fn, long data ) void wxListMainWindow::OnScroll(wxScrollWinEvent& event) { - wxScrolledWindow::OnScroll( event ) ; + // FIXME +#ifdef __WXGTK__ + wxScrolledWindow::OnScroll(event); +#else + HandleOnScroll( event ); +#endif + #if wxUSE_GENERIC_LIST_EXTENSIONS if (event.GetOrientation() == wxHORIZONTAL && ( m_mode & wxLC_REPORT )) @@ -3012,7 +3157,7 @@ void wxListMainWindow::OnScroll(wxScrollWinEvent& event) { lc->m_headerWin->Refresh() ; #ifdef __WXMAC__ - lc->m_headerWin->MacUpdateImmediately() ; + lc->m_headerWin->MacUpdateImmediately() ; #endif } } @@ -3051,7 +3196,7 @@ void wxListItem::Clear() m_data = 0; m_format = wxLIST_FORMAT_CENTRE; m_width = 0; - m_text = wxEmptyString; + m_text = _T(""); if (m_attr) delete m_attr; m_attr = NULL; @@ -3126,12 +3271,16 @@ wxListCtrl::wxListCtrl() m_imageListNormal = (wxImageList *) NULL; m_imageListSmall = (wxImageList *) NULL; m_imageListState = (wxImageList *) NULL; + m_ownsImageListNormal = m_ownsImageListSmall = m_ownsImageListState = FALSE; m_mainWin = (wxListMainWindow*) NULL; m_headerWin = (wxListHeaderWindow*) NULL; } wxListCtrl::~wxListCtrl() { + if (m_ownsImageListNormal) delete m_imageListNormal; + if (m_ownsImageListSmall) delete m_imageListSmall; + if (m_ownsImageListState) delete m_imageListState; } bool wxListCtrl::Create(wxWindow *parent, @@ -3145,6 +3294,7 @@ bool wxListCtrl::Create(wxWindow *parent, m_imageListNormal = (wxImageList *) NULL; m_imageListSmall = (wxImageList *) NULL; m_imageListState = (wxImageList *) NULL; + m_ownsImageListNormal = m_ownsImageListSmall = m_ownsImageListState = FALSE; m_mainWin = (wxListMainWindow*) NULL; m_headerWin = (wxListHeaderWindow*) NULL; @@ -3442,9 +3592,39 @@ wxImageList *wxListCtrl::GetImageList(int which) const void wxListCtrl::SetImageList( wxImageList *imageList, int which ) { + if ( which == wxIMAGE_LIST_NORMAL ) + { + if (m_ownsImageListNormal) delete m_imageListNormal; + m_imageListNormal = imageList; + m_ownsImageListNormal = FALSE; + } + else if ( which == wxIMAGE_LIST_SMALL ) + { + if (m_ownsImageListSmall) delete m_imageListSmall; + m_imageListSmall = imageList; + m_ownsImageListSmall = FALSE; + } + else if ( which == wxIMAGE_LIST_STATE ) + { + if (m_ownsImageListState) delete m_imageListState; + m_imageListState = imageList; + m_ownsImageListState = FALSE; + } + m_mainWin->SetImageList( imageList, which ); } +void wxListCtrl::AssignImageList(wxImageList *imageList, int which) +{ + SetImageList(imageList, which); + if ( which == wxIMAGE_LIST_NORMAL ) + m_ownsImageListNormal = TRUE; + else if ( which == wxIMAGE_LIST_SMALL ) + m_ownsImageListSmall = TRUE; + else if ( which == wxIMAGE_LIST_STATE ) + m_ownsImageListState = TRUE; +} + bool wxListCtrl::Arrange( int WXUNUSED(flag) ) { return 0; @@ -3728,3 +3908,5 @@ void wxListCtrl::SetFocus() if ( FindFocus() != this ) m_mainWin->SetFocus(); } + +#endif // wxUSE_LISTCTRL