1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "listctrl.h"
12 #pragma implementation "listctrlbase.h"
15 // For compilers that support precompilation, includes "wx.h".
16 #include "wx/wxprec.h"
22 #include "wx/dcscreen.h"
24 #include "wx/listctrl.h"
25 #include "wx/generic/imaglist.h"
26 #include "wx/dynarray.h"
30 #include "wx/gtk/win_gtk.h"
33 #ifndef wxUSE_GENERIC_LIST_EXTENSIONS
34 #define wxUSE_GENERIC_LIST_EXTENSIONS 1
37 // ============================================================================
39 // ============================================================================
41 //-----------------------------------------------------------------------------
42 // wxListItemData (internal)
43 //-----------------------------------------------------------------------------
45 class WXDLLEXPORT wxListItemData
: public wxObject
54 wxListItemAttr
*m_attr
;
58 ~wxListItemData() { delete m_attr
; }
60 wxListItemData( const wxListItem
&info
);
61 void SetItem( const wxListItem
&info
);
62 void SetText( const wxString
&s
);
63 void SetImage( int image
);
64 void SetData( long data
);
65 void SetPosition( int x
, int y
);
66 void SetSize( int width
, int height
);
67 bool HasImage() const;
69 bool IsHit( int x
, int y
) const;
70 void GetText( wxString
&s
);
71 const wxString
& GetText() { return m_text
; }
72 int GetX( void ) const;
73 int GetY( void ) const;
75 int GetHeight() const;
77 void GetItem( wxListItem
&info
) const;
79 wxListItemAttr
*GetAttributes() const { return m_attr
; }
82 DECLARE_DYNAMIC_CLASS(wxListItemData
);
85 //-----------------------------------------------------------------------------
86 // wxListHeaderData (internal)
87 //-----------------------------------------------------------------------------
89 class WXDLLEXPORT wxListHeaderData
: public wxObject
102 wxListHeaderData( const wxListItem
&info
);
103 void SetItem( const wxListItem
&item
);
104 void SetPosition( int x
, int y
);
105 void SetWidth( int w
);
106 void SetFormat( int format
);
107 void SetHeight( int h
);
108 bool HasImage() const;
109 bool HasText() const;
110 bool IsHit( int x
, int y
) const;
111 void GetItem( wxListItem
&item
);
112 void GetText( wxString
&s
);
113 int GetImage() const;
114 int GetWidth() const;
115 int GetFormat() const;
118 DECLARE_DYNAMIC_CLASS(wxListHeaderData
);
121 //-----------------------------------------------------------------------------
122 // wxListLineData (internal)
123 //-----------------------------------------------------------------------------
125 class WXDLLEXPORT wxListLineData
: public wxObject
130 wxRect m_bound_label
;
132 wxRect m_bound_hilight
;
135 wxBrush
*m_hilightBrush
;
137 wxListMainWindow
*m_owner
;
139 void DoDraw( wxDC
*dc
, bool hilight
, bool paintBG
);
143 wxListLineData( wxListMainWindow
*owner
, int mode
, wxBrush
*hilightBrush
);
144 void CalculateSize( wxDC
*dc
, int spacing
);
145 void SetPosition( wxDC
*dc
, int x
, int y
, int window_width
);
146 void SetColumnPosition( int index
, int x
);
147 void GetSize( int &width
, int &height
);
148 void GetExtent( int &x
, int &y
, int &width
, int &height
);
149 void GetLabelExtent( int &x
, int &y
, int &width
, int &height
);
150 long IsHit( int x
, int y
);
151 void InitItems( int num
);
152 void SetItem( int index
, const wxListItem
&info
);
153 void GetItem( int index
, wxListItem
&info
);
154 void GetText( int index
, wxString
&s
);
155 void SetText( int index
, const wxString s
);
156 int GetImage( int index
);
157 void GetRect( wxRect
&rect
);
158 void Hilight( bool on
);
159 void ReverseHilight();
160 void DrawRubberBand( wxDC
*dc
, bool on
);
161 void Draw( wxDC
*dc
);
162 bool IsInRect( int x
, int y
, const wxRect
&rect
);
164 void AssignRect( wxRect
&dest
, int x
, int y
, int width
, int height
);
165 void AssignRect( wxRect
&dest
, const wxRect
&source
);
168 void SetAttributes(wxDC
*dc
,
169 const wxListItemAttr
*attr
,
170 const wxColour
& colText
, const wxFont
& font
,
173 DECLARE_DYNAMIC_CLASS(wxListLineData
);
177 WX_DECLARE_EXPORTED_OBJARRAY(wxListLineData
, wxListLineDataArray
);
178 #include "wx/arrimpl.cpp"
179 WX_DEFINE_OBJARRAY(wxListLineDataArray
);
181 //-----------------------------------------------------------------------------
182 // wxListHeaderWindow (internal)
183 //-----------------------------------------------------------------------------
185 class WXDLLEXPORT wxListHeaderWindow
: public wxWindow
188 wxListMainWindow
*m_owner
;
189 wxCursor
*m_currentCursor
;
190 wxCursor
*m_resizeCursor
;
193 // column being resized
196 // divider line position in logical (unscrolled) coords
199 // minimal position beyond which the divider line can't be dragged in
204 wxListHeaderWindow();
205 virtual ~wxListHeaderWindow();
207 wxListHeaderWindow( wxWindow
*win
,
209 wxListMainWindow
*owner
,
210 const wxPoint
&pos
= wxDefaultPosition
,
211 const wxSize
&size
= wxDefaultSize
,
213 const wxString
&name
= "wxlistctrlcolumntitles" );
215 void DoDrawRect( wxDC
*dc
, int x
, int y
, int w
, int h
);
217 void AdjustDC(wxDC
& dc
);
219 void OnPaint( wxPaintEvent
&event
);
220 void OnMouse( wxMouseEvent
&event
);
221 void OnSetFocus( wxFocusEvent
&event
);
227 DECLARE_DYNAMIC_CLASS(wxListHeaderWindow
)
228 DECLARE_EVENT_TABLE()
231 //-----------------------------------------------------------------------------
232 // wxListRenameTimer (internal)
233 //-----------------------------------------------------------------------------
235 class WXDLLEXPORT wxListRenameTimer
: public wxTimer
238 wxListMainWindow
*m_owner
;
241 wxListRenameTimer( wxListMainWindow
*owner
);
245 //-----------------------------------------------------------------------------
246 // wxListTextCtrl (internal)
247 //-----------------------------------------------------------------------------
249 class WXDLLEXPORT wxListTextCtrl
: public wxTextCtrl
254 wxListMainWindow
*m_owner
;
255 wxString m_startValue
;
259 wxListTextCtrl( wxWindow
*parent
, const wxWindowID id
,
260 bool *accept
, wxString
*res
, wxListMainWindow
*owner
,
261 const wxString
&value
= "",
262 const wxPoint
&pos
= wxDefaultPosition
, const wxSize
&size
= wxDefaultSize
,
264 const wxValidator
& validator
= wxDefaultValidator
,
265 const wxString
&name
= "listctrltextctrl" );
266 void OnChar( wxKeyEvent
&event
);
267 void OnKillFocus( wxFocusEvent
&event
);
270 DECLARE_DYNAMIC_CLASS(wxListTextCtrl
);
271 DECLARE_EVENT_TABLE()
274 //-----------------------------------------------------------------------------
275 // wxListMainWindow (internal)
276 //-----------------------------------------------------------------------------
278 class WXDLLEXPORT wxListMainWindow
: public wxScrolledWindow
282 wxListLineDataArray m_lines
;
284 wxListLineData
*m_current
;
285 wxListLineData
*m_currentEdit
;
287 wxBrush
*m_hilightBrush
;
288 wxColour
*m_hilightColour
;
289 int m_xScroll
,m_yScroll
;
291 wxImageList
*m_small_image_list
;
292 wxImageList
*m_normal_image_list
;
294 int m_normal_spacing
;
298 wxTimer
*m_renameTimer
;
300 wxString m_renameRes
;
305 // for double click logic
306 wxListLineData
*m_lineLastClicked
,
307 *m_lineBeforeLastClicked
;
311 wxListMainWindow( wxWindow
*parent
, wxWindowID id
,
312 const wxPoint
&pos
= wxDefaultPosition
, const wxSize
&size
= wxDefaultSize
,
313 long style
= 0, const wxString
&name
= "listctrlmainwindow" );
315 void RefreshLine( wxListLineData
*line
);
316 void OnPaint( wxPaintEvent
&event
);
317 void HilightAll( bool on
);
318 void SendNotify( wxListLineData
*line
, wxEventType command
);
319 void FocusLine( wxListLineData
*line
);
320 void UnfocusLine( wxListLineData
*line
);
321 void SelectLine( wxListLineData
*line
);
322 void DeselectLine( wxListLineData
*line
);
323 void DeleteLine( wxListLineData
*line
);
325 void EditLabel( long item
);
326 void Edit( long item
) { EditLabel(item
); } // deprecated
327 void OnRenameTimer();
328 void OnRenameAccept();
330 void OnMouse( wxMouseEvent
&event
);
332 void OnArrowChar( wxListLineData
*newCurrent
, bool shiftDown
);
333 void OnChar( wxKeyEvent
&event
);
334 void OnKeyDown( wxKeyEvent
&event
);
335 void OnSetFocus( wxFocusEvent
&event
);
336 void OnKillFocus( wxFocusEvent
&event
);
337 void OnSize( wxSizeEvent
&event
);
338 void OnScroll(wxScrollWinEvent
& event
) ;
340 void DrawImage( int index
, wxDC
*dc
, int x
, int y
);
341 void GetImageSize( int index
, int &width
, int &height
);
342 int GetIndexOfLine( const wxListLineData
*line
);
343 int GetTextLength( wxString
&s
); // should be const
345 void SetImageList( wxImageList
*imageList
, int which
);
346 void SetItemSpacing( int spacing
, bool isSmall
= FALSE
);
347 int GetItemSpacing( bool isSmall
= FALSE
);
348 void SetColumn( int col
, wxListItem
&item
);
349 void SetColumnWidth( int col
, int width
);
350 void GetColumn( int col
, wxListItem
&item
);
351 int GetColumnWidth( int vol
);
352 int GetColumnCount();
353 int GetCountPerPage();
354 void SetItem( wxListItem
&item
);
355 void GetItem( wxListItem
&item
);
356 void SetItemState( long item
, long state
, long stateMask
);
357 int GetItemState( long item
, long stateMask
);
359 void GetItemRect( long index
, wxRect
&rect
);
360 bool GetItemPosition( long item
, wxPoint
& pos
);
361 int GetSelectedItemCount();
362 void SetMode( long mode
);
363 long GetMode() const;
364 void CalculatePositions();
365 void RealizeChanges();
366 long GetNextItem( long item
, int geometry
, int state
);
367 void DeleteItem( long index
);
368 void DeleteAllItems();
369 void DeleteColumn( int col
);
370 void DeleteEverything();
371 void EnsureVisible( long index
);
372 long FindItem( long start
, const wxString
& str
, bool partial
= FALSE
);
373 long FindItem( long start
, long data
);
374 long HitTest( int x
, int y
, int &flags
);
375 void InsertItem( wxListItem
&item
);
376 // void AddItem( wxListItem &item );
377 void InsertColumn( long col
, wxListItem
&item
);
378 // void AddColumn( wxListItem &item );
379 void SortItems( wxListCtrlCompare fn
, long data
);
382 DECLARE_DYNAMIC_CLASS(wxListMainWindow
);
383 DECLARE_EVENT_TABLE()
386 // ============================================================================
388 // ============================================================================
390 //-----------------------------------------------------------------------------
392 //-----------------------------------------------------------------------------
394 IMPLEMENT_DYNAMIC_CLASS(wxListItemData
,wxObject
);
396 wxListItemData::wxListItemData()
407 wxListItemData::wxListItemData( const wxListItem
&info
)
416 void wxListItemData::SetItem( const wxListItem
&info
)
418 if (info
.m_mask
& wxLIST_MASK_TEXT
) m_text
= info
.m_text
;
419 if (info
.m_mask
& wxLIST_MASK_IMAGE
) m_image
= info
.m_image
;
420 if (info
.m_mask
& wxLIST_MASK_DATA
) m_data
= info
.m_data
;
422 if ( info
.HasAttributes() )
425 *m_attr
= *info
.GetAttributes();
427 m_attr
= new wxListItemAttr(*info
.GetAttributes());
432 m_width
= info
.m_width
;
436 void wxListItemData::SetText( const wxString
&s
)
441 void wxListItemData::SetImage( int image
)
446 void wxListItemData::SetData( long data
)
451 void wxListItemData::SetPosition( int x
, int y
)
457 void wxListItemData::SetSize( int width
, int height
)
459 if (width
!= -1) m_width
= width
;
460 if (height
!= -1) m_height
= height
;
463 bool wxListItemData::HasImage() const
465 return (m_image
>= 0);
468 bool wxListItemData::HasText() const
470 return (!m_text
.IsNull());
473 bool wxListItemData::IsHit( int x
, int y
) const
475 return ((x
>= m_xpos
) && (x
<= m_xpos
+m_width
) && (y
>= m_ypos
) && (y
<= m_ypos
+m_height
));
478 void wxListItemData::GetText( wxString
&s
)
483 int wxListItemData::GetX() const
488 int wxListItemData::GetY() const
493 int wxListItemData::GetWidth() const
498 int wxListItemData::GetHeight() const
503 int wxListItemData::GetImage() const
508 void wxListItemData::GetItem( wxListItem
&info
) const
510 info
.m_text
= m_text
;
511 info
.m_image
= m_image
;
512 info
.m_data
= m_data
;
516 if ( m_attr
->HasTextColour() )
517 info
.SetTextColour(m_attr
->GetTextColour());
518 if ( m_attr
->HasBackgroundColour() )
519 info
.SetBackgroundColour(m_attr
->GetBackgroundColour());
520 if ( m_attr
->HasFont() )
521 info
.SetFont(m_attr
->GetFont());
525 //-----------------------------------------------------------------------------
527 //-----------------------------------------------------------------------------
529 IMPLEMENT_DYNAMIC_CLASS(wxListHeaderData
,wxObject
);
531 wxListHeaderData::wxListHeaderData()
542 wxListHeaderData::wxListHeaderData( const wxListItem
&item
)
550 void wxListHeaderData::SetItem( const wxListItem
&item
)
552 m_mask
= item
.m_mask
;
553 m_text
= item
.m_text
;
554 m_image
= item
.m_image
;
555 m_format
= item
.m_format
;
556 m_width
= item
.m_width
;
557 if (m_width
< 0) m_width
= 80;
558 if (m_width
< 6) m_width
= 6;
561 void wxListHeaderData::SetPosition( int x
, int y
)
567 void wxListHeaderData::SetHeight( int h
)
572 void wxListHeaderData::SetWidth( int w
)
575 if (m_width
< 0) m_width
= 80;
576 if (m_width
< 6) m_width
= 6;
579 void wxListHeaderData::SetFormat( int format
)
584 bool wxListHeaderData::HasImage() const
586 return (m_image
!= 0);
589 bool wxListHeaderData::HasText() const
591 return (m_text
.Length() > 0);
594 bool wxListHeaderData::IsHit( int x
, int y
) const
596 return ((x
>= m_xpos
) && (x
<= m_xpos
+m_width
) && (y
>= m_ypos
) && (y
<= m_ypos
+m_height
));
599 void wxListHeaderData::GetItem( wxListItem
&item
)
601 item
.m_mask
= m_mask
;
602 item
.m_text
= m_text
;
603 item
.m_image
= m_image
;
604 item
.m_format
= m_format
;
605 item
.m_width
= m_width
;
608 void wxListHeaderData::GetText( wxString
&s
)
613 int wxListHeaderData::GetImage() const
618 int wxListHeaderData::GetWidth() const
623 int wxListHeaderData::GetFormat() const
628 //-----------------------------------------------------------------------------
630 //-----------------------------------------------------------------------------
632 IMPLEMENT_DYNAMIC_CLASS(wxListLineData
,wxObject
);
634 wxListLineData::wxListLineData( wxListMainWindow
*owner
, int mode
, wxBrush
*hilightBrush
)
639 m_hilightBrush
= hilightBrush
;
640 m_items
.DeleteContents( TRUE
);
644 void wxListLineData::CalculateSize( wxDC
*dc
, int spacing
)
651 m_bound_all
.width
= m_spacing
;
652 wxNode
*node
= m_items
.First();
655 wxListItemData
*item
= (wxListItemData
*)node
->Data();
656 wxString s
= item
->GetText();
657 if (s
.IsEmpty()) s
= wxT("H");
659 dc
->GetTextExtent( s
, &lw
, &lh
);
660 if (lh
< 15) lh
= 15;
664 m_bound_all
.height
= m_spacing
+lh
;
665 if (lw
> m_spacing
) m_bound_all
.width
= lw
;
666 m_bound_label
.width
= lw
;
667 m_bound_label
.height
= lh
;
669 if (item
->HasImage())
673 m_owner
->GetImageSize( item
->GetImage(), w
, h
);
674 m_bound_icon
.width
= w
+ 8;
675 m_bound_icon
.height
= h
+ 8;
677 if ( m_bound_icon
.width
> m_bound_all
.width
)
678 m_bound_all
.width
= m_bound_icon
.width
;
679 if ( h
+ lh
> m_bound_all
.height
- 4 )
680 m_bound_all
.height
= h
+ lh
+ 4;
683 if (!item
->HasText())
685 m_bound_hilight
.width
= m_bound_icon
.width
;
686 m_bound_hilight
.height
= m_bound_icon
.height
;
690 m_bound_hilight
.width
= m_bound_label
.width
;
691 m_bound_hilight
.height
= m_bound_label
.height
;
698 wxNode
*node
= m_items
.First();
701 wxListItemData
*item
= (wxListItemData
*)node
->Data();
703 wxString s
= item
->GetText();
704 if (s
.IsEmpty()) s
= wxT("H");
706 dc
->GetTextExtent( s
, &lw
, &lh
);
707 if (lh
< 15) lh
= 15;
710 m_bound_label
.width
= lw
;
711 m_bound_label
.height
= lh
;
713 m_bound_all
.width
= lw
;
714 m_bound_all
.height
= lh
;
716 if (item
->HasImage())
720 m_owner
->GetImageSize( item
->GetImage(), w
, h
);
721 m_bound_icon
.width
= w
;
722 m_bound_icon
.height
= h
;
724 m_bound_all
.width
+= 4 + w
;
725 if (h
> m_bound_all
.height
) m_bound_all
.height
= h
;
728 m_bound_hilight
.width
= m_bound_all
.width
;
729 m_bound_hilight
.height
= m_bound_all
.height
;
735 m_bound_all
.width
= 0;
736 m_bound_all
.height
= 0;
737 wxNode
*node
= m_items
.First();
740 wxListItemData
*item
= (wxListItemData
*)node
->Data();
741 if (item
->HasImage())
745 m_owner
->GetImageSize( item
->GetImage(), w
, h
);
746 m_bound_icon
.width
= w
;
747 m_bound_icon
.height
= h
;
751 m_bound_icon
.width
= 0;
752 m_bound_icon
.height
= 0;
757 wxListItemData
*item
= (wxListItemData
*)node
->Data();
758 wxString s
= item
->GetText();
759 if (s
.IsEmpty()) s
= wxT("H");
761 dc
->GetTextExtent( s
, &lw
, &lh
);
762 if (lh
< 15) lh
= 15;
766 item
->SetSize( item
->GetWidth(), lh
);
767 m_bound_all
.width
+= lw
;
768 m_bound_all
.height
= lh
;
776 void wxListLineData::SetPosition( wxDC
* WXUNUSED(dc
),
777 int x
, int y
, int window_width
)
785 wxNode
*node
= m_items
.First();
788 wxListItemData
*item
= (wxListItemData
*)node
->Data();
789 if (item
->HasImage())
791 m_bound_icon
.x
= m_bound_all
.x
+ 4
792 + (m_spacing
- m_bound_icon
.width
)/2;
793 m_bound_icon
.y
= m_bound_all
.y
+ 4;
797 if (m_bound_all
.width
> m_spacing
)
798 m_bound_label
.x
= m_bound_all
.x
+ 2;
800 m_bound_label
.x
= m_bound_all
.x
+ 2 + (m_spacing
/2) - (m_bound_label
.width
/2);
801 m_bound_label
.y
= m_bound_all
.y
+ m_bound_all
.height
+ 2 - m_bound_label
.height
;
802 m_bound_hilight
.x
= m_bound_label
.x
- 2;
803 m_bound_hilight
.y
= m_bound_label
.y
- 2;
807 m_bound_hilight
.x
= m_bound_icon
.x
- 4;
808 m_bound_hilight
.y
= m_bound_icon
.y
- 4;
815 m_bound_hilight
.x
= m_bound_all
.x
;
816 m_bound_hilight
.y
= m_bound_all
.y
;
817 m_bound_label
.y
= m_bound_all
.y
+ 2;
818 wxNode
*node
= m_items
.First();
821 wxListItemData
*item
= (wxListItemData
*)node
->Data();
822 if (item
->HasImage())
824 m_bound_icon
.x
= m_bound_all
.x
+ 2;
825 m_bound_icon
.y
= m_bound_all
.y
+ 2;
826 m_bound_label
.x
= m_bound_all
.x
+ 6 + m_bound_icon
.width
;
830 m_bound_label
.x
= m_bound_all
.x
+ 2;
838 m_bound_all
.width
= window_width
;
839 AssignRect( m_bound_hilight
, m_bound_all
);
840 m_bound_label
.x
= m_bound_all
.x
+ 2;
841 m_bound_label
.y
= m_bound_all
.y
+ 2;
842 wxNode
*node
= m_items
.First();
845 wxListItemData
*item
= (wxListItemData
*)node
->Data();
846 if (item
->HasImage())
848 m_bound_icon
.x
= m_bound_all
.x
+ 2;
849 m_bound_icon
.y
= m_bound_all
.y
+ 2;
850 m_bound_label
.x
+= 4 + m_bound_icon
.width
;
858 void wxListLineData::SetColumnPosition( int index
, int x
)
860 wxNode
*node
= m_items
.Nth( (size_t)index
);
863 wxListItemData
*item
= (wxListItemData
*)node
->Data();
864 item
->SetPosition( x
, m_bound_all
.y
+1 );
868 void wxListLineData::GetSize( int &width
, int &height
)
870 width
= m_bound_all
.width
;
871 height
= m_bound_all
.height
;
874 void wxListLineData::GetExtent( int &x
, int &y
, int &width
, int &height
)
878 width
= m_bound_all
.width
;
879 height
= m_bound_all
.height
;
882 void wxListLineData::GetLabelExtent( int &x
, int &y
, int &width
, int &height
)
886 width
= m_bound_label
.width
;
887 height
= m_bound_label
.height
;
890 void wxListLineData::GetRect( wxRect
&rect
)
892 AssignRect( rect
, m_bound_all
);
895 long wxListLineData::IsHit( int x
, int y
)
897 wxNode
*node
= m_items
.First();
900 wxListItemData
*item
= (wxListItemData
*)node
->Data();
901 if (item
->HasImage() && IsInRect( x
, y
, m_bound_icon
)) return wxLIST_HITTEST_ONITEMICON
;
902 if (item
->HasText() && IsInRect( x
, y
, m_bound_label
)) return wxLIST_HITTEST_ONITEMLABEL
;
903 // if (!(item->HasImage() || item->HasText())) return 0;
905 // if there is no icon or text = empty
906 if (IsInRect( x
, y
, m_bound_all
)) return wxLIST_HITTEST_ONITEMICON
;
910 void wxListLineData::InitItems( int num
)
912 for (int i
= 0; i
< num
; i
++) m_items
.Append( new wxListItemData() );
915 void wxListLineData::SetItem( int index
, const wxListItem
&info
)
917 wxNode
*node
= m_items
.Nth( index
);
920 wxListItemData
*item
= (wxListItemData
*)node
->Data();
921 item
->SetItem( info
);
925 void wxListLineData::GetItem( int index
, wxListItem
&info
)
928 wxNode
*node
= m_items
.Nth( i
);
931 wxListItemData
*item
= (wxListItemData
*)node
->Data();
932 item
->GetItem( info
);
936 void wxListLineData::GetText( int index
, wxString
&s
)
939 wxNode
*node
= m_items
.Nth( i
);
943 wxListItemData
*item
= (wxListItemData
*)node
->Data();
948 void wxListLineData::SetText( int index
, const wxString s
)
951 wxNode
*node
= m_items
.Nth( i
);
954 wxListItemData
*item
= (wxListItemData
*)node
->Data();
959 int wxListLineData::GetImage( int index
)
962 wxNode
*node
= m_items
.Nth( i
);
965 wxListItemData
*item
= (wxListItemData
*)node
->Data();
966 return item
->GetImage();
971 void wxListLineData::SetAttributes(wxDC
*dc
,
972 const wxListItemAttr
*attr
,
973 const wxColour
& colText
,
977 // don't use foregroud colour for drawing highlighted items - this might
978 // make them completely invisible (and there is no way to do bit
979 // arithmetics on wxColour, unfortunately)
980 if ( !hilight
&& attr
&& attr
->HasTextColour() )
982 dc
->SetTextForeground(attr
->GetTextColour());
986 dc
->SetTextForeground(colText
);
989 if ( attr
&& attr
->HasFont() )
991 dc
->SetFont(attr
->GetFont());
999 void wxListLineData::DoDraw( wxDC
*dc
, bool hilight
, bool paintBG
)
1003 m_owner
->CalcScrolledPosition( m_bound_all
.x
, m_bound_all
.y
, &dev_x
, &dev_y
);
1004 wxCoord dev_w
= m_bound_all
.width
;
1005 wxCoord dev_h
= m_bound_all
.height
;
1007 if (!m_owner
->IsExposed( dev_x
, dev_y
, dev_w
, dev_h
))
1010 wxWindow
*listctrl
= m_owner
->GetParent();
1012 // default foreground colour
1016 colText
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT
);
1020 colText
= listctrl
->GetForegroundColour();
1024 wxFont font
= listctrl
->GetFont();
1026 // VZ: currently we set the colours/fonts only once, but like this (i.e.
1027 // using SetAttributes() inside the loop), it will be trivial to
1028 // customize the subitems (in report mode) too.
1029 wxListItemData
*item
= (wxListItemData
*)m_items
.First()->Data();
1030 wxListItemAttr
*attr
= item
->GetAttributes();
1031 SetAttributes(dc
, attr
, colText
, font
, hilight
);
1033 bool hasBgCol
= attr
&& attr
->HasBackgroundColour();
1034 if ( paintBG
|| hasBgCol
)
1038 dc
->SetBrush( * m_hilightBrush
);
1043 dc
->SetBrush(wxBrush(attr
->GetBackgroundColour(), wxSOLID
));
1045 dc
->SetBrush( * wxWHITE_BRUSH
);
1048 dc
->SetPen( * wxTRANSPARENT_PEN
);
1049 dc
->DrawRectangle( m_bound_hilight
.x
, m_bound_hilight
.y
,
1050 m_bound_hilight
.width
, m_bound_hilight
.height
);
1053 if (m_mode
== wxLC_REPORT
)
1055 wxNode
*node
= m_items
.First();
1058 wxListItemData
*item
= (wxListItemData
*)node
->Data();
1059 int x
= item
->GetX();
1060 if (item
->HasImage())
1063 m_owner
->DrawImage( item
->GetImage(), dc
, x
, item
->GetY() );
1064 m_owner
->GetImageSize( item
->GetImage(), x
, y
);
1065 x
+= item
->GetX() + 5;
1067 dc
->SetClippingRegion( item
->GetX(), item
->GetY(), item
->GetWidth()-3, item
->GetHeight() );
1068 if (item
->HasText())
1070 dc
->DrawText( item
->GetText(), x
, item
->GetY()+1 );
1072 dc
->DestroyClippingRegion();
1073 node
= node
->Next();
1078 wxNode
*node
= m_items
.First();
1081 wxListItemData
*item
= (wxListItemData
*)node
->Data();
1082 if (item
->HasImage())
1084 m_owner
->DrawImage( item
->GetImage(), dc
, m_bound_icon
.x
, m_bound_icon
.y
);
1086 if (item
->HasText())
1088 dc
->DrawText( item
->GetText(), m_bound_label
.x
, m_bound_label
.y
);
1094 void wxListLineData::Hilight( bool on
)
1096 if (on
== m_hilighted
) return;
1099 m_owner
->SelectLine( this );
1101 m_owner
->DeselectLine( this );
1104 void wxListLineData::ReverseHilight( void )
1106 m_hilighted
= !m_hilighted
;
1108 m_owner
->SelectLine( this );
1110 m_owner
->DeselectLine( this );
1113 void wxListLineData::DrawRubberBand( wxDC
*dc
, bool on
)
1117 dc
->SetPen( * wxBLACK_PEN
);
1118 dc
->SetBrush( * wxTRANSPARENT_BRUSH
);
1119 dc
->DrawRectangle( m_bound_hilight
.x
, m_bound_hilight
.y
,
1120 m_bound_hilight
.width
, m_bound_hilight
.height
);
1124 void wxListLineData::Draw( wxDC
*dc
)
1126 DoDraw( dc
, m_hilighted
, m_hilighted
);
1129 bool wxListLineData::IsInRect( int x
, int y
, const wxRect
&rect
)
1131 return ((x
>= rect
.x
) && (x
<= rect
.x
+rect
.width
) &&
1132 (y
>= rect
.y
) && (y
<= rect
.y
+rect
.height
));
1135 bool wxListLineData::IsHilighted( void )
1140 void wxListLineData::AssignRect( wxRect
&dest
, int x
, int y
, int width
, int height
)
1145 dest
.height
= height
;
1148 void wxListLineData::AssignRect( wxRect
&dest
, const wxRect
&source
)
1152 dest
.width
= source
.width
;
1153 dest
.height
= source
.height
;
1156 //-----------------------------------------------------------------------------
1157 // wxListHeaderWindow
1158 //-----------------------------------------------------------------------------
1160 IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow
,wxWindow
);
1162 BEGIN_EVENT_TABLE(wxListHeaderWindow
,wxWindow
)
1163 EVT_PAINT (wxListHeaderWindow::OnPaint
)
1164 EVT_MOUSE_EVENTS (wxListHeaderWindow::OnMouse
)
1165 EVT_SET_FOCUS (wxListHeaderWindow::OnSetFocus
)
1168 wxListHeaderWindow::wxListHeaderWindow( void )
1170 m_owner
= (wxListMainWindow
*) NULL
;
1171 m_currentCursor
= (wxCursor
*) NULL
;
1172 m_resizeCursor
= (wxCursor
*) NULL
;
1173 m_isDragging
= FALSE
;
1176 wxListHeaderWindow::wxListHeaderWindow( wxWindow
*win
, wxWindowID id
, wxListMainWindow
*owner
,
1177 const wxPoint
&pos
, const wxSize
&size
,
1178 long style
, const wxString
&name
) :
1179 wxWindow( win
, id
, pos
, size
, style
, name
)
1182 // m_currentCursor = wxSTANDARD_CURSOR;
1183 m_currentCursor
= (wxCursor
*) NULL
;
1184 m_resizeCursor
= new wxCursor( wxCURSOR_SIZEWE
);
1185 m_isDragging
= FALSE
;
1188 SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
) );
1191 wxListHeaderWindow::~wxListHeaderWindow( void )
1193 delete m_resizeCursor
;
1196 void wxListHeaderWindow::DoDrawRect( wxDC
*dc
, int x
, int y
, int w
, int h
)
1199 GtkStateType state
= GTK_STATE_NORMAL
;
1200 if (!m_parent
->IsEnabled()) state
= GTK_STATE_INSENSITIVE
;
1202 x
= dc
->XLOG2DEV( x
);
1204 gtk_paint_box (m_wxwindow
->style
, GTK_PIZZA(m_wxwindow
)->bin_window
, state
, GTK_SHADOW_OUT
,
1205 (GdkRectangle
*) NULL
, m_wxwindow
, "button", x
-1, y
-1, w
+2, h
+2);
1207 const int m_corner
= 1;
1209 dc
->SetBrush( *wxTRANSPARENT_BRUSH
);
1211 dc
->SetPen( *wxBLACK_PEN
);
1212 dc
->DrawLine( x
+w
-m_corner
+1, y
, x
+w
, y
+h
); // right (outer)
1213 dc
->DrawRectangle( x
, y
+h
, w
+1, 1 ); // bottom (outer)
1215 wxPen
pen( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNSHADOW
), 1, wxSOLID
);
1218 dc
->DrawLine( x
+w
-m_corner
, y
, x
+w
-1, y
+h
); // right (inner)
1219 dc
->DrawRectangle( x
+1, y
+h
-1, w
-2, 1 ); // bottom (inner)
1221 dc
->SetPen( *wxWHITE_PEN
);
1222 dc
->DrawRectangle( x
, y
, w
-m_corner
+1, 1 ); // top (outer)
1223 dc
->DrawRectangle( x
, y
, 1, h
); // left (outer)
1224 dc
->DrawLine( x
, y
+h
-1, x
+1, y
+h
-1 );
1225 dc
->DrawLine( x
+w
-1, y
, x
+w
-1, y
+1 );
1229 // shift the DC origin to match the position of the main window horz
1230 // scrollbar: this allows us to always use logical coords
1231 void wxListHeaderWindow::AdjustDC(wxDC
& dc
)
1233 #if wxUSE_GENERIC_LIST_EXTENSIONS
1235 m_owner
->GetScrollPixelsPerUnit( &xpix
, NULL
);
1238 m_owner
->GetViewStart( &x
, NULL
);
1240 // account for the horz scrollbar offset
1241 dc
.SetDeviceOrigin( -x
* xpix
, 0 );
1242 #endif // wxUSE_GENERIC_LIST_EXTENSIONS
1245 void wxListHeaderWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
1247 wxPaintDC
dc( this );
1253 dc
.SetFont( GetFont() );
1255 // width and height of the entire header window
1257 GetClientSize( &w
, &h
);
1258 #if wxUSE_GENERIC_LIST_EXTENSIONS
1259 m_owner
->CalcUnscrolledPosition(w
, 0, &w
, NULL
);
1260 #endif // wxUSE_GENERIC_LIST_EXTENSIONS
1262 dc
.SetBackgroundMode(wxTRANSPARENT
);
1264 // do *not* use the listctrl colour for headers - one day we will have a
1265 // function to set it separately
1266 //dc.SetTextForeground( *wxBLACK );
1267 dc
.SetTextForeground(wxSystemSettings::GetSystemColour( wxSYS_COLOUR_WINDOWTEXT
));
1269 int x
= 1; // left of the header rect
1270 const int y
= 1; // top
1271 int numColumns
= m_owner
->GetColumnCount();
1273 for (int i
= 0; i
< numColumns
; i
++)
1275 m_owner
->GetColumn( i
, item
);
1276 int wCol
= item
.m_width
;
1277 int cw
= wCol
- 2; // the width of the rect to draw
1279 int xEnd
= x
+ wCol
;
1281 // VZ: no, draw it normally - this is better now as we allow resizing
1282 // of the last column as well
1284 // let the last column occupy all available space
1285 if ( i
== numColumns
- 1 )
1289 dc
.SetPen( *wxWHITE_PEN
);
1291 DoDrawRect( &dc
, x
, y
, cw
, h
-2 );
1292 dc
.SetClippingRegion( x
, y
, cw
-5, h
-4 );
1293 dc
.DrawText( item
.m_text
, x
+4, y
+3 );
1294 dc
.DestroyClippingRegion();
1303 void wxListHeaderWindow::DrawCurrent()
1305 int x1
= m_currentX
;
1307 ClientToScreen( &x1
, &y1
);
1309 int x2
= m_currentX
-1;
1311 m_owner
->GetClientSize( NULL
, &y2
);
1312 m_owner
->ClientToScreen( &x2
, &y2
);
1315 dc
.SetLogicalFunction( wxINVERT
);
1316 dc
.SetPen( wxPen( *wxBLACK
, 2, wxSOLID
) );
1317 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
1321 dc
.DrawLine( x1
, y1
, x2
, y2
);
1323 dc
.SetLogicalFunction( wxCOPY
);
1325 dc
.SetPen( wxNullPen
);
1326 dc
.SetBrush( wxNullBrush
);
1329 void wxListHeaderWindow::OnMouse( wxMouseEvent
&event
)
1331 // we want to work with logical coords
1332 #if wxUSE_GENERIC_LIST_EXTENSIONS
1334 m_owner
->CalcUnscrolledPosition(event
.GetX(), 0, &x
, NULL
);
1335 #else // !wxUSE_GENERIC_LIST_EXTENSIONS
1336 int x
= event
.GetX();
1337 #endif // wxUSE_GENERIC_LIST_EXTENSIONS
1338 int y
= event
.GetY();
1342 // we don't draw the line beyond our window, but we allow dragging it
1345 GetClientSize( &w
, NULL
);
1346 #if wxUSE_GENERIC_LIST_EXTENSIONS
1347 m_owner
->CalcUnscrolledPosition(w
, 0, &w
, NULL
);
1348 #endif // wxUSE_GENERIC_LIST_EXTENSIONS
1351 // erase the line if it was drawn
1352 if ( m_currentX
< w
)
1355 if (event
.ButtonUp())
1358 m_isDragging
= FALSE
;
1360 m_owner
->SetColumnWidth( m_column
, m_currentX
- m_minX
);
1367 m_currentX
= m_minX
+ 7;
1369 // draw in the new location
1370 if ( m_currentX
< w
)
1374 else // not dragging
1377 bool hit_border
= FALSE
;
1379 // end of the current column
1382 // find the column where this event occured
1383 int countCol
= m_owner
->GetColumnCount();
1384 for (int j
= 0; j
< countCol
; j
++)
1386 xpos
+= m_owner
->GetColumnWidth( j
);
1389 if ( (abs(x
-xpos
) < 3) && (y
< 22) )
1391 // near the column border
1398 // inside the column
1405 if (event
.LeftDown())
1409 m_isDragging
= TRUE
;
1416 wxWindow
*parent
= GetParent();
1417 wxListEvent
le( wxEVT_COMMAND_LIST_COL_CLICK
, parent
->GetId() );
1418 le
.SetEventObject( parent
);
1419 le
.m_col
= m_column
;
1420 parent
->GetEventHandler()->ProcessEvent( le
);
1423 else if (event
.Moving())
1428 setCursor
= m_currentCursor
== wxSTANDARD_CURSOR
;
1429 m_currentCursor
= m_resizeCursor
;
1433 setCursor
= m_currentCursor
!= wxSTANDARD_CURSOR
;
1434 m_currentCursor
= wxSTANDARD_CURSOR
;
1438 SetCursor(*m_currentCursor
);
1443 void wxListHeaderWindow::OnSetFocus( wxFocusEvent
&WXUNUSED(event
) )
1445 m_owner
->SetFocus();
1448 //-----------------------------------------------------------------------------
1449 // wxListRenameTimer (internal)
1450 //-----------------------------------------------------------------------------
1452 wxListRenameTimer::wxListRenameTimer( wxListMainWindow
*owner
)
1457 void wxListRenameTimer::Notify()
1459 m_owner
->OnRenameTimer();
1462 //-----------------------------------------------------------------------------
1463 // wxListTextCtrl (internal)
1464 //-----------------------------------------------------------------------------
1466 IMPLEMENT_DYNAMIC_CLASS(wxListTextCtrl
,wxTextCtrl
);
1468 BEGIN_EVENT_TABLE(wxListTextCtrl
,wxTextCtrl
)
1469 EVT_CHAR (wxListTextCtrl::OnChar
)
1470 EVT_KILL_FOCUS (wxListTextCtrl::OnKillFocus
)
1473 wxListTextCtrl::wxListTextCtrl( wxWindow
*parent
,
1474 const wxWindowID id
,
1477 wxListMainWindow
*owner
,
1478 const wxString
&value
,
1482 const wxValidator
& validator
,
1483 const wxString
&name
)
1484 : wxTextCtrl( parent
, id
, value
, pos
, size
, style
, validator
, name
)
1489 (*m_accept
) = FALSE
;
1491 m_startValue
= value
;
1494 void wxListTextCtrl::OnChar( wxKeyEvent
&event
)
1496 if (event
.m_keyCode
== WXK_RETURN
)
1499 (*m_res
) = GetValue();
1501 if (!wxPendingDelete
.Member(this))
1502 wxPendingDelete
.Append(this);
1504 if ((*m_accept
) && ((*m_res
) != m_startValue
))
1505 m_owner
->OnRenameAccept();
1509 if (event
.m_keyCode
== WXK_ESCAPE
)
1511 (*m_accept
) = FALSE
;
1514 if (!wxPendingDelete
.Member(this))
1515 wxPendingDelete
.Append(this);
1523 void wxListTextCtrl::OnKillFocus( wxFocusEvent
&WXUNUSED(event
) )
1525 if (!wxPendingDelete
.Member(this))
1526 wxPendingDelete
.Append(this);
1528 if ((*m_accept
) && ((*m_res
) != m_startValue
))
1529 m_owner
->OnRenameAccept();
1532 //-----------------------------------------------------------------------------
1534 //-----------------------------------------------------------------------------
1536 IMPLEMENT_DYNAMIC_CLASS(wxListMainWindow
,wxScrolledWindow
);
1538 BEGIN_EVENT_TABLE(wxListMainWindow
,wxScrolledWindow
)
1539 EVT_PAINT (wxListMainWindow::OnPaint
)
1540 EVT_SIZE (wxListMainWindow::OnSize
)
1541 EVT_MOUSE_EVENTS (wxListMainWindow::OnMouse
)
1542 EVT_CHAR (wxListMainWindow::OnChar
)
1543 EVT_KEY_DOWN (wxListMainWindow::OnKeyDown
)
1544 EVT_SET_FOCUS (wxListMainWindow::OnSetFocus
)
1545 EVT_KILL_FOCUS (wxListMainWindow::OnKillFocus
)
1546 EVT_SCROLLWIN (wxListMainWindow::OnScroll
)
1549 wxListMainWindow::wxListMainWindow()
1552 m_columns
.DeleteContents( TRUE
);
1553 m_current
= (wxListLineData
*) NULL
;
1555 m_hilightBrush
= (wxBrush
*) NULL
;
1559 m_small_image_list
= (wxImageList
*) NULL
;
1560 m_normal_image_list
= (wxImageList
*) NULL
;
1561 m_small_spacing
= 30;
1562 m_normal_spacing
= 40;
1565 m_lastOnSame
= FALSE
;
1566 m_renameTimer
= new wxListRenameTimer( this );
1567 m_isCreated
= FALSE
;
1571 m_lineBeforeLastClicked
= (wxListLineData
*)NULL
;
1574 wxListMainWindow::wxListMainWindow( wxWindow
*parent
, wxWindowID id
,
1575 const wxPoint
&pos
, const wxSize
&size
,
1576 long style
, const wxString
&name
) :
1577 wxScrolledWindow( parent
, id
, pos
, size
, style
|wxHSCROLL
|wxVSCROLL
, name
)
1580 m_columns
.DeleteContents( TRUE
);
1581 m_current
= (wxListLineData
*) NULL
;
1584 m_hilightBrush
= new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT
), wxSOLID
);
1585 m_small_image_list
= (wxImageList
*) NULL
;
1586 m_normal_image_list
= (wxImageList
*) NULL
;
1587 m_small_spacing
= 30;
1588 m_normal_spacing
= 40;
1591 m_isCreated
= FALSE
;
1595 if (m_mode
& wxLC_REPORT
)
1597 #if wxUSE_GENERIC_LIST_EXTENSIONS
1609 SetScrollbars( m_xScroll
, m_yScroll
, 0, 0, 0, 0 );
1612 m_lastOnSame
= FALSE
;
1613 m_renameTimer
= new wxListRenameTimer( this );
1614 m_renameAccept
= FALSE
;
1616 SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_LISTBOX
) );
1619 wxListMainWindow::~wxListMainWindow()
1623 if (m_hilightBrush
) delete m_hilightBrush
;
1625 delete m_renameTimer
;
1628 void wxListMainWindow::RefreshLine( wxListLineData
*line
)
1630 if (m_dirty
) return;
1638 line
->GetExtent( x
, y
, w
, h
);
1639 CalcScrolledPosition( x
, y
, &x
, &y
);
1640 wxRect
rect( x
, y
, w
, h
);
1641 Refresh( TRUE
, &rect
);
1644 void wxListMainWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
1646 // Note: a wxPaintDC must be constructed even if no drawing is
1647 // done (a Windows requirement).
1648 wxPaintDC
dc( this );
1651 if (m_dirty
) return;
1653 if (m_lines
.GetCount() == 0) return;
1657 dc
.SetFont( GetFont() );
1659 if (m_mode
& wxLC_REPORT
)
1661 wxPen
pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT
), 1, wxSOLID
);
1663 dc
.SetBrush(* wxTRANSPARENT_BRUSH
);
1665 wxSize clientSize
= GetClientSize();
1667 int lineSpacing
= 0;
1668 wxListLineData
*line
= &m_lines
[0];
1670 line
->GetSize( dummy
, lineSpacing
);
1673 int y_s
= m_yScroll
*GetScrollPos( wxVERTICAL
);
1675 size_t i_to
= y_s
/ lineSpacing
+ m_visibleLines
+2;
1676 if (i_to
>= m_lines
.GetCount()) i_to
= m_lines
.GetCount();
1678 for (i
= y_s
/ lineSpacing
; i
< i_to
; i
++)
1680 m_lines
[i
].Draw( &dc
);
1681 // Draw horizontal rule if required
1682 if (GetWindowStyle() & wxLC_HRULES
)
1683 dc
.DrawLine(0, i
*lineSpacing
, clientSize
.x
, i
*lineSpacing
);
1686 // Draw last horizontal rule
1687 if ((i
> (size_t) (y_s
/ lineSpacing
)) && (GetWindowStyle() & wxLC_HRULES
))
1688 dc
.DrawLine(0, i
*lineSpacing
, clientSize
.x
, i
*lineSpacing
);
1690 // Draw vertical rules if required
1691 if ((GetWindowStyle() & wxLC_VRULES
) && (GetItemCount() > 0))
1694 wxRect firstItemRect
;
1695 wxRect lastItemRect
;
1696 GetItemRect(0, firstItemRect
);
1697 GetItemRect(GetItemCount() - 1, lastItemRect
);
1698 int x
= firstItemRect
.GetX();
1699 for (col
= 0; col
< GetColumnCount(); col
++)
1701 int colWidth
= GetColumnWidth(col
);
1703 dc
.DrawLine(x
, firstItemRect
.GetY() - 1, x
, lastItemRect
.GetBottom() + 1);
1709 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
1710 m_lines
[i
].Draw( &dc
);
1713 if (m_current
) m_current
->DrawRubberBand( &dc
, m_hasFocus
);
1718 void wxListMainWindow::HilightAll( bool on
)
1720 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
1722 wxListLineData
*line
= &m_lines
[i
];
1723 if (line
->IsHilighted() != on
)
1725 line
->Hilight( on
);
1726 RefreshLine( line
);
1731 void wxListMainWindow::SendNotify( wxListLineData
*line
, wxEventType command
)
1733 wxListEvent
le( command
, GetParent()->GetId() );
1734 le
.SetEventObject( GetParent() );
1735 le
.m_itemIndex
= GetIndexOfLine( line
);
1736 line
->GetItem( 0, le
.m_item
);
1737 GetParent()->GetEventHandler()->ProcessEvent( le
);
1738 // GetParent()->GetEventHandler()->AddPendingEvent( le );
1741 void wxListMainWindow::FocusLine( wxListLineData
*WXUNUSED(line
) )
1743 // SendNotify( line, wxEVT_COMMAND_LIST_ITEM_FOCUSSED );
1746 void wxListMainWindow::UnfocusLine( wxListLineData
*WXUNUSED(line
) )
1748 // SendNotify( line, wxEVT_COMMAND_LIST_ITEM_UNFOCUSSED );
1751 void wxListMainWindow::SelectLine( wxListLineData
*line
)
1753 SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_SELECTED
);
1756 void wxListMainWindow::DeselectLine( wxListLineData
*line
)
1758 SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_DESELECTED
);
1761 void wxListMainWindow::DeleteLine( wxListLineData
*line
)
1763 SendNotify( line
, wxEVT_COMMAND_LIST_DELETE_ITEM
);
1768 void wxListMainWindow::EditLabel( long item
)
1770 wxCHECK_RET( ((size_t)item
< m_lines
.GetCount()),
1771 wxT("wrong index in wxListCtrl::Edit()") );
1773 m_currentEdit
= &m_lines
[(size_t)item
];
1775 wxListEvent
le( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
, GetParent()->GetId() );
1776 le
.SetEventObject( GetParent() );
1777 le
.m_itemIndex
= GetIndexOfLine( m_currentEdit
);
1778 m_currentEdit
->GetItem( 0, le
.m_item
);
1779 GetParent()->GetEventHandler()->ProcessEvent( le
);
1781 if (!le
.IsAllowed())
1784 // We have to call this here because the label in
1785 // question might just have been added and no screen
1786 // update taken place.
1787 if (m_dirty
) wxYield();
1790 m_currentEdit
->GetText( 0, s
);
1795 m_currentEdit
->GetLabelExtent( x
, y
, w
, h
);
1797 wxClientDC
dc(this);
1799 x
= dc
.LogicalToDeviceX( x
);
1800 y
= dc
.LogicalToDeviceY( y
);
1802 wxListTextCtrl
*text
= new wxListTextCtrl(
1803 this, -1, &m_renameAccept
, &m_renameRes
, this, s
, wxPoint(x
-4,y
-4), wxSize(w
+11,h
+8) );
1807 void wxListMainWindow::OnRenameTimer()
1809 wxCHECK_RET( m_current
, wxT("invalid m_current") );
1811 Edit( m_lines
.Index( *m_current
) );
1814 void wxListMainWindow::OnRenameAccept()
1816 wxListEvent
le( wxEVT_COMMAND_LIST_END_LABEL_EDIT
, GetParent()->GetId() );
1817 le
.SetEventObject( GetParent() );
1818 le
.m_itemIndex
= GetIndexOfLine( m_currentEdit
);
1819 m_currentEdit
->GetItem( 0, le
.m_item
);
1820 le
.m_item
.m_text
= m_renameRes
;
1821 GetParent()->GetEventHandler()->ProcessEvent( le
);
1823 if (!le
.IsAllowed()) return;
1826 info
.m_mask
= wxLIST_MASK_TEXT
;
1827 info
.m_itemId
= le
.m_itemIndex
;
1828 info
.m_text
= m_renameRes
;
1829 info
.SetTextColour(le
.m_item
.GetTextColour());
1833 void wxListMainWindow::OnMouse( wxMouseEvent
&event
)
1835 event
.SetEventObject( GetParent() );
1836 if (GetParent()->GetEventHandler()->ProcessEvent( event
)) return;
1838 if (!m_current
) return;
1839 if (m_dirty
) return;
1840 if ( !(event
.Dragging() || event
.ButtonDown() || event
.LeftUp() || event
.ButtonDClick()) ) return;
1842 int x
= event
.GetX();
1843 int y
= event
.GetY();
1844 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1846 /* Did we actually hit an item ? */
1848 wxListLineData
*line
= (wxListLineData
*) NULL
;
1849 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
1852 hitResult
= line
->IsHit( x
, y
);
1853 if (hitResult
) break;
1854 line
= (wxListLineData
*) NULL
;
1857 if (event
.Dragging())
1859 if (m_dragCount
== 0)
1860 m_dragStart
= wxPoint(x
,y
);
1864 if (m_dragCount
!= 3) return;
1866 int command
= wxEVT_COMMAND_LIST_BEGIN_DRAG
;
1867 if (event
.RightIsDown()) command
= wxEVT_COMMAND_LIST_BEGIN_RDRAG
;
1869 wxListEvent
le( command
, GetParent()->GetId() );
1870 le
.SetEventObject( GetParent() );
1871 le
.m_pointDrag
= m_dragStart
;
1872 GetParent()->GetEventHandler()->ProcessEvent( le
);
1883 bool forceClick
= FALSE
;
1884 if (event
.ButtonDClick())
1886 m_renameTimer
->Stop();
1887 m_lastOnSame
= FALSE
;
1889 if ( line
== m_lineBeforeLastClicked
)
1893 SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_ACTIVATED
);
1899 // the first click was on another item, so don't interpret this as
1900 // a double click, but as a simple click instead
1905 if (event
.LeftUp() && m_lastOnSame
)
1908 if ((line
== m_current
) &&
1909 (hitResult
== wxLIST_HITTEST_ONITEMLABEL
) &&
1910 (m_mode
& wxLC_EDIT_LABELS
) )
1912 m_renameTimer
->Start( 100, TRUE
);
1914 m_lastOnSame
= FALSE
;
1918 if (event
.RightDown())
1920 SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK
);
1924 if (event
.MiddleDown())
1926 SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK
);
1930 if ( event
.LeftDown() || forceClick
)
1932 m_lineBeforeLastClicked
= m_lineLastClicked
;
1933 m_lineLastClicked
= line
;
1936 wxListLineData
*oldCurrent
= m_current
;
1937 if (m_mode
& wxLC_SINGLE_SEL
)
1940 HilightAll( FALSE
);
1941 m_current
->ReverseHilight();
1942 RefreshLine( m_current
);
1946 if (event
.ControlDown())
1949 m_current
->ReverseHilight();
1950 RefreshLine( m_current
);
1952 else if (event
.ShiftDown())
1958 int numOfCurrent
= -1;
1959 for (j
= 0; j
< m_lines
.GetCount(); j
++)
1961 wxListLineData
*test_line
= &m_lines
[j
];
1963 if (test_line
== oldCurrent
) break;
1968 for (j
= 0; j
< m_lines
.GetCount(); j
++)
1970 wxListLineData
*test_line
= &m_lines
[j
];
1972 if (test_line
== line
) break;
1975 if (numOfLine
< numOfCurrent
)
1978 numOfLine
= numOfCurrent
;
1982 for (int i
= 0; i
<= numOfLine
-numOfCurrent
; i
++)
1984 wxListLineData
*test_line
= &m_lines
[numOfCurrent
+ i
];
1985 test_line
->Hilight(TRUE
);
1986 RefreshLine( test_line
);
1992 HilightAll( FALSE
);
1993 m_current
->ReverseHilight();
1994 RefreshLine( m_current
);
1997 if (m_current
!= oldCurrent
)
1999 RefreshLine( oldCurrent
);
2000 UnfocusLine( oldCurrent
);
2001 FocusLine( m_current
);
2004 // forceClick is only set if the previous click was on another item
2005 m_lastOnSame
= !forceClick
&& (m_current
== oldCurrent
);
2011 void wxListMainWindow::MoveToFocus()
2013 if (!m_current
) return;
2019 m_current
->GetExtent( item_x
, item_y
, item_w
, item_h
);
2023 GetClientSize( &client_w
, &client_h
);
2025 int view_x
= m_xScroll
*GetScrollPos( wxHORIZONTAL
);
2026 int view_y
= m_yScroll
*GetScrollPos( wxVERTICAL
);
2028 if (m_mode
& wxLC_REPORT
)
2030 if (item_y
-5 < view_y
)
2031 Scroll( -1, (item_y
-5)/m_yScroll
);
2032 if (item_y
+item_h
+5 > view_y
+client_h
)
2033 Scroll( -1, (item_y
+item_h
-client_h
+15)/m_yScroll
);
2037 if (item_x
-view_x
< 5)
2038 Scroll( (item_x
-5)/m_xScroll
, -1 );
2039 if (item_x
+item_w
-5 > view_x
+client_w
)
2040 Scroll( (item_x
+item_w
-client_w
+15)/m_xScroll
, -1 );
2044 void wxListMainWindow::OnArrowChar( wxListLineData
*newCurrent
, bool shiftDown
)
2046 if ((m_mode
& wxLC_SINGLE_SEL
) || (m_usedKeys
== FALSE
)) m_current
->Hilight( FALSE
);
2047 wxListLineData
*oldCurrent
= m_current
;
2048 m_current
= newCurrent
;
2049 if (shiftDown
|| (m_mode
& wxLC_SINGLE_SEL
)) m_current
->Hilight( TRUE
);
2050 RefreshLine( m_current
);
2051 RefreshLine( oldCurrent
);
2052 FocusLine( m_current
);
2053 UnfocusLine( oldCurrent
);
2057 void wxListMainWindow::OnKeyDown( wxKeyEvent
&event
)
2059 wxWindow
*parent
= GetParent();
2061 /* we propagate the key event up */
2062 wxKeyEvent
ke( wxEVT_KEY_DOWN
);
2063 ke
.m_shiftDown
= event
.m_shiftDown
;
2064 ke
.m_controlDown
= event
.m_controlDown
;
2065 ke
.m_altDown
= event
.m_altDown
;
2066 ke
.m_metaDown
= event
.m_metaDown
;
2067 ke
.m_keyCode
= event
.m_keyCode
;
2070 ke
.SetEventObject( parent
);
2071 if (parent
->GetEventHandler()->ProcessEvent( ke
)) return;
2076 void wxListMainWindow::OnChar( wxKeyEvent
&event
)
2078 wxWindow
*parent
= GetParent();
2080 /* we send a list_key event up */
2083 wxListEvent
le( wxEVT_COMMAND_LIST_KEY_DOWN
, GetParent()->GetId() );
2084 le
.m_itemIndex
= GetIndexOfLine( m_current
);
2085 m_current
->GetItem( 0, le
.m_item
);
2086 le
.m_code
= (int)event
.KeyCode();
2087 le
.SetEventObject( parent
);
2088 parent
->GetEventHandler()->ProcessEvent( le
);
2091 /* we propagate the char event up */
2092 wxKeyEvent
ke( wxEVT_CHAR
);
2093 ke
.m_shiftDown
= event
.m_shiftDown
;
2094 ke
.m_controlDown
= event
.m_controlDown
;
2095 ke
.m_altDown
= event
.m_altDown
;
2096 ke
.m_metaDown
= event
.m_metaDown
;
2097 ke
.m_keyCode
= event
.m_keyCode
;
2100 ke
.SetEventObject( parent
);
2101 if (parent
->GetEventHandler()->ProcessEvent( ke
)) return;
2103 if (event
.KeyCode() == WXK_TAB
)
2105 wxNavigationKeyEvent nevent
;
2106 nevent
.SetWindowChange( event
.ControlDown() );
2107 nevent
.SetDirection( !event
.ShiftDown() );
2108 nevent
.SetEventObject( GetParent()->GetParent() );
2109 nevent
.SetCurrentFocus( m_parent
);
2110 if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent
)) return;
2113 /* no item -> nothing to do */
2120 switch (event
.KeyCode())
2124 int index
= m_lines
.Index(*m_current
);
2125 if (index
!= wxNOT_FOUND
&& index
> 0)
2126 OnArrowChar( &m_lines
[index
-1], event
.ShiftDown() );
2131 int index
= m_lines
.Index(*m_current
);
2132 if (index
!= wxNOT_FOUND
&& (size_t)index
< m_lines
.GetCount()-1)
2133 OnArrowChar( &m_lines
[index
+1], event
.ShiftDown() );
2138 if (!m_lines
.IsEmpty())
2139 OnArrowChar( &m_lines
.Last(), event
.ShiftDown() );
2144 if (!m_lines
.IsEmpty())
2145 OnArrowChar( &m_lines
[0], event
.ShiftDown() );
2151 int index
= m_lines
.Index(*m_current
);
2152 if (m_mode
& wxLC_REPORT
)
2154 steps
= m_visibleLines
-1;
2158 steps
= index
% m_visibleLines
;
2160 if (index
!= wxNOT_FOUND
)
2163 if (index
< 0) index
= 0;
2164 OnArrowChar( &m_lines
[index
], event
.ShiftDown() );
2171 int index
= m_lines
.Index(*m_current
);
2172 if (m_mode
& wxLC_REPORT
)
2174 steps
= m_visibleLines
-1;
2178 steps
= m_visibleLines
-(index
% m_visibleLines
)-1;
2181 if (index
!= wxNOT_FOUND
)
2184 if ((size_t)index
>= m_lines
.GetCount())
2185 index
= m_lines
.GetCount()-1;
2186 OnArrowChar( &m_lines
[index
], event
.ShiftDown() );
2192 if (!(m_mode
& wxLC_REPORT
))
2194 int index
= m_lines
.Index(*m_current
);
2195 if (index
!= wxNOT_FOUND
)
2197 index
-= m_visibleLines
;
2198 if (index
< 0) index
= 0;
2199 OnArrowChar( &m_lines
[index
], event
.ShiftDown() );
2206 if (!(m_mode
& wxLC_REPORT
))
2208 int index
= m_lines
.Index(*m_current
);
2209 if (index
!= wxNOT_FOUND
)
2211 index
+= m_visibleLines
;
2212 if ((size_t)index
>= m_lines
.GetCount())
2213 index
= m_lines
.GetCount()-1;
2214 OnArrowChar( &m_lines
[index
], event
.ShiftDown() );
2221 if (m_mode
& wxLC_SINGLE_SEL
)
2223 wxListEvent
le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED
, GetParent()->GetId() );
2224 le
.SetEventObject( GetParent() );
2225 le
.m_itemIndex
= GetIndexOfLine( m_current
);
2226 m_current
->GetItem( 0, le
.m_item
);
2227 GetParent()->GetEventHandler()->ProcessEvent( le
);
2231 m_current
->ReverseHilight();
2232 RefreshLine( m_current
);
2238 if (!(m_mode
& wxLC_SINGLE_SEL
))
2240 wxListLineData
*oldCurrent
= m_current
;
2241 m_current
->ReverseHilight();
2242 int index
= m_lines
.Index( *m_current
) + 1;
2243 if ( (size_t)index
< m_lines
.GetCount() )
2244 m_current
= &m_lines
[index
];
2245 RefreshLine( oldCurrent
);
2246 RefreshLine( m_current
);
2247 UnfocusLine( oldCurrent
);
2248 FocusLine( m_current
);
2256 wxListEvent
le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED
, GetParent()->GetId() );
2257 le
.SetEventObject( GetParent() );
2258 le
.m_itemIndex
= GetIndexOfLine( m_current
);
2259 m_current
->GetItem( 0, le
.m_item
);
2260 GetParent()->GetEventHandler()->ProcessEvent( le
);
2273 extern wxWindow
*g_focusWindow
;
2276 void wxListMainWindow::OnSetFocus( wxFocusEvent
&WXUNUSED(event
) )
2279 RefreshLine( m_current
);
2281 if (!GetParent()) return;
2284 g_focusWindow
= GetParent();
2287 wxFocusEvent
event( wxEVT_SET_FOCUS
, GetParent()->GetId() );
2288 event
.SetEventObject( GetParent() );
2289 GetParent()->GetEventHandler()->ProcessEvent( event
);
2292 void wxListMainWindow::OnKillFocus( wxFocusEvent
&WXUNUSED(event
) )
2295 RefreshLine( m_current
);
2298 void wxListMainWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2301 We don't even allow the wxScrolledWindow::AdjustScrollbars() call
2307 void wxListMainWindow::DrawImage( int index
, wxDC
*dc
, int x
, int y
)
2309 if ((m_mode
& wxLC_ICON
) && (m_normal_image_list
))
2311 m_normal_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT
);
2314 if ((m_mode
& wxLC_SMALL_ICON
) && (m_small_image_list
))
2316 m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT
);
2318 if ((m_mode
& wxLC_LIST
) && (m_small_image_list
))
2320 m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT
);
2322 if ((m_mode
& wxLC_REPORT
) && (m_small_image_list
))
2324 m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT
);
2329 void wxListMainWindow::GetImageSize( int index
, int &width
, int &height
)
2331 if ((m_mode
& wxLC_ICON
) && (m_normal_image_list
))
2333 m_normal_image_list
->GetSize( index
, width
, height
);
2336 if ((m_mode
& wxLC_SMALL_ICON
) && (m_small_image_list
))
2338 m_small_image_list
->GetSize( index
, width
, height
);
2341 if ((m_mode
& wxLC_LIST
) && (m_small_image_list
))
2343 m_small_image_list
->GetSize( index
, width
, height
);
2346 if ((m_mode
& wxLC_REPORT
) && (m_small_image_list
))
2348 m_small_image_list
->GetSize( index
, width
, height
);
2355 int wxListMainWindow::GetTextLength( wxString
&s
)
2357 wxClientDC
dc( this );
2360 dc
.GetTextExtent( s
, &lw
, &lh
);
2364 int wxListMainWindow::GetIndexOfLine( const wxListLineData
*line
)
2366 int i
= m_lines
.Index(*line
);
2367 if (i
== wxNOT_FOUND
) return -1;
2371 void wxListMainWindow::SetImageList( wxImageList
*imageList
, int which
)
2375 // calc the spacing from the icon size
2378 if ((imageList
) && (imageList
->GetImageCount()) )
2380 imageList
->GetSize(0, width
, height
);
2383 if (which
== wxIMAGE_LIST_NORMAL
)
2385 m_normal_image_list
= imageList
;
2386 m_normal_spacing
= width
+ 8;
2389 if (which
== wxIMAGE_LIST_SMALL
)
2391 m_small_image_list
= imageList
;
2392 m_small_spacing
= width
+ 14;
2396 void wxListMainWindow::SetItemSpacing( int spacing
, bool isSmall
)
2401 m_small_spacing
= spacing
;
2405 m_normal_spacing
= spacing
;
2409 int wxListMainWindow::GetItemSpacing( bool isSmall
)
2411 return isSmall
? m_small_spacing
: m_normal_spacing
;
2414 void wxListMainWindow::SetColumn( int col
, wxListItem
&item
)
2417 wxNode
*node
= m_columns
.Nth( col
);
2420 if (item
.m_width
== wxLIST_AUTOSIZE_USEHEADER
) item
.m_width
= GetTextLength( item
.m_text
)+7;
2421 wxListHeaderData
*column
= (wxListHeaderData
*)node
->Data();
2422 column
->SetItem( item
);
2425 wxListHeaderWindow
*headerWin
= ((wxListCtrl
*) GetParent())->m_headerWin
;
2427 headerWin
->m_dirty
= TRUE
;
2430 void wxListMainWindow::SetColumnWidth( int col
, int width
)
2432 wxCHECK_RET( m_mode
& wxLC_REPORT
,
2433 _T("SetColumnWidth() can only be called in report mode.") );
2437 wxNode
*node
= (wxNode
*) NULL
;
2439 if (width
== wxLIST_AUTOSIZE_USEHEADER
)
2441 // TODO do use the header
2444 else if (width
== wxLIST_AUTOSIZE
)
2446 wxClientDC
dc(this);
2447 dc
.SetFont( GetFont() );
2450 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
2452 wxListLineData
*line
= &m_lines
[i
];
2453 wxNode
*n
= line
->m_items
.Nth( col
);
2456 wxListItemData
*item
= (wxListItemData
*)n
->Data();
2457 int current
= 0, ix
= 0, iy
= 0;
2458 wxCoord lx
= 0, ly
= 0;
2459 if (item
->HasImage())
2461 GetImageSize( item
->GetImage(), ix
, iy
);
2464 if (item
->HasText())
2467 item
->GetText( str
);
2468 dc
.GetTextExtent( str
, &lx
, &ly
);
2471 if (current
> max
) max
= current
;
2477 node
= m_columns
.Nth( col
);
2480 wxListHeaderData
*column
= (wxListHeaderData
*)node
->Data();
2481 column
->SetWidth( width
);
2484 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
2486 wxListLineData
*line
= &m_lines
[i
];
2487 wxNode
*n
= line
->m_items
.Nth( col
);
2490 wxListItemData
*item
= (wxListItemData
*)n
->Data();
2491 item
->SetSize( width
, -1 );
2495 wxListHeaderWindow
*headerWin
= ((wxListCtrl
*) GetParent())->m_headerWin
;
2497 headerWin
->m_dirty
= TRUE
;
2500 void wxListMainWindow::GetColumn( int col
, wxListItem
&item
)
2502 wxNode
*node
= m_columns
.Nth( col
);
2505 wxListHeaderData
*column
= (wxListHeaderData
*)node
->Data();
2506 column
->GetItem( item
);
2518 int wxListMainWindow::GetColumnWidth( int col
)
2520 wxNode
*node
= m_columns
.Nth( col
);
2523 wxListHeaderData
*column
= (wxListHeaderData
*)node
->Data();
2524 return column
->GetWidth();
2532 int wxListMainWindow::GetColumnCount()
2534 return m_columns
.Number();
2537 int wxListMainWindow::GetCountPerPage()
2539 return m_visibleLines
;
2542 void wxListMainWindow::SetItem( wxListItem
&item
)
2545 if (item
.m_itemId
>= 0 && (size_t)item
.m_itemId
< m_lines
.GetCount())
2547 wxListLineData
*line
= &m_lines
[(size_t)item
.m_itemId
];
2548 if (m_mode
& wxLC_REPORT
) item
.m_width
= GetColumnWidth( item
.m_col
)-3;
2549 line
->SetItem( item
.m_col
, item
);
2553 void wxListMainWindow::SetItemState( long item
, long state
, long stateMask
)
2555 // m_dirty = TRUE; no recalcs needed
2557 wxListLineData
*oldCurrent
= m_current
;
2559 if (stateMask
& wxLIST_STATE_FOCUSED
)
2561 if (item
>= 0 && (size_t)item
< m_lines
.GetCount())
2563 wxListLineData
*line
= &m_lines
[(size_t)item
];
2564 UnfocusLine( m_current
);
2566 FocusLine( m_current
);
2567 if ((m_mode
& wxLC_SINGLE_SEL
) && oldCurrent
) oldCurrent
->Hilight( FALSE
);
2568 RefreshLine( m_current
);
2569 if (oldCurrent
) RefreshLine( oldCurrent
);
2573 if (stateMask
& wxLIST_STATE_SELECTED
)
2575 bool on
= (state
& wxLIST_STATE_SELECTED
) != 0;
2576 if (!on
&& (m_mode
& wxLC_SINGLE_SEL
)) return;
2578 if (item
>= 0 && (size_t)item
< m_lines
.GetCount())
2580 wxListLineData
*line
= &m_lines
[(size_t)item
];
2581 if (m_mode
& wxLC_SINGLE_SEL
)
2583 UnfocusLine( m_current
);
2585 FocusLine( m_current
);
2586 if (oldCurrent
) oldCurrent
->Hilight( FALSE
);
2587 RefreshLine( m_current
);
2588 if (oldCurrent
) RefreshLine( oldCurrent
);
2590 bool on
= (state
& wxLIST_STATE_SELECTED
) != 0;
2591 if (on
!= line
->IsHilighted())
2593 line
->Hilight( on
);
2594 RefreshLine( line
);
2600 int wxListMainWindow::GetItemState( long item
, long stateMask
)
2602 int ret
= wxLIST_STATE_DONTCARE
;
2603 if (stateMask
& wxLIST_STATE_FOCUSED
)
2605 if (item
>= 0 && (size_t)item
< m_lines
.GetCount())
2607 wxListLineData
*line
= &m_lines
[(size_t)item
];
2608 if (line
== m_current
) ret
|= wxLIST_STATE_FOCUSED
;
2611 if (stateMask
& wxLIST_STATE_SELECTED
)
2613 if (item
>= 0 && (size_t)item
< m_lines
.GetCount())
2615 wxListLineData
*line
= &m_lines
[(size_t)item
];
2616 if (line
->IsHilighted()) ret
|= wxLIST_STATE_FOCUSED
;
2622 void wxListMainWindow::GetItem( wxListItem
&item
)
2624 if (item
.m_itemId
>= 0 && (size_t)item
.m_itemId
< m_lines
.GetCount())
2626 wxListLineData
*line
= &m_lines
[(size_t)item
.m_itemId
];
2627 line
->GetItem( item
.m_col
, item
);
2638 int wxListMainWindow::GetItemCount()
2640 return m_lines
.GetCount();
2643 void wxListMainWindow::GetItemRect( long index
, wxRect
&rect
)
2645 if (index
>= 0 && (size_t)index
< m_lines
.GetCount())
2647 m_lines
[(size_t)index
].GetRect( rect
);
2658 bool wxListMainWindow::GetItemPosition(long item
, wxPoint
& pos
)
2660 if (item
>= 0 && (size_t)item
< m_lines
.GetCount())
2663 m_lines
[(size_t)item
].GetRect( rect
);
2675 int wxListMainWindow::GetSelectedItemCount()
2678 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
2680 if (m_lines
[i
].IsHilighted()) ret
++;
2685 void wxListMainWindow::SetMode( long mode
)
2692 if (m_mode
& wxLC_REPORT
)
2694 #if wxUSE_GENERIC_LIST_EXTENSIONS
2708 long wxListMainWindow::GetMode() const
2713 void wxListMainWindow::CalculatePositions()
2715 if (m_lines
.IsEmpty()) return;
2717 wxClientDC
dc( this );
2718 dc
.SetFont( GetFont() );
2720 int iconSpacing
= 0;
2721 if (m_mode
& wxLC_ICON
) iconSpacing
= m_normal_spacing
;
2722 if (m_mode
& wxLC_SMALL_ICON
) iconSpacing
= m_small_spacing
;
2724 // we take the first line (which also can be an icon or
2725 // an a text item in wxLC_ICON and wxLC_LIST modes) to
2726 // measure the size of the line
2730 int lineSpacing
= 0;
2732 wxListLineData
*line
= &m_lines
[0];
2733 line
->CalculateSize( &dc
, iconSpacing
);
2735 line
->GetSize( dummy
, lineSpacing
);
2738 int clientWidth
= 0;
2739 int clientHeight
= 0;
2741 if (m_mode
& wxLC_REPORT
)
2745 int entireHeight
= m_lines
.GetCount() * lineSpacing
+ 2;
2746 int scroll_pos
= GetScrollPos( wxVERTICAL
);
2747 #if wxUSE_GENERIC_LIST_EXTENSIONS
2748 int x_scroll_pos
= GetScrollPos( wxHORIZONTAL
);
2750 SetScrollbars( m_xScroll
, m_yScroll
, 0, (entireHeight
+15) / m_yScroll
, 0, scroll_pos
, TRUE
);
2752 GetClientSize( &clientWidth
, &clientHeight
);
2754 int entireWidth
= 0 ;
2755 for (size_t j
= 0; j
< m_lines
.GetCount(); j
++)
2757 wxListLineData
*line
= &m_lines
[j
];
2758 line
->CalculateSize( &dc
, iconSpacing
);
2759 line
->SetPosition( &dc
, x
, y
, clientWidth
);
2761 for (int i
= 0; i
< GetColumnCount(); i
++)
2763 line
->SetColumnPosition( i
, col_x
);
2764 col_x
+= GetColumnWidth( i
);
2766 entireWidth
= wxMax( entireWidth
, col_x
) ;
2767 #if wxUSE_GENERIC_LIST_EXTENSIONS
2768 line
->SetPosition( &dc
, x
, y
, col_x
);
2770 y
+= lineSpacing
; // one pixel blank line between items
2772 m_visibleLines
= clientHeight
/ lineSpacing
;
2773 #if wxUSE_GENERIC_LIST_EXTENSIONS
2774 SetScrollbars( m_xScroll
, m_yScroll
, entireWidth
/ m_xScroll
, (entireHeight
+15) / m_yScroll
, x_scroll_pos
, scroll_pos
, TRUE
);
2779 // at first we try without any scrollbar. if the items don't
2780 // fit into the window, we recalculate after subtracting an
2781 // approximated 15 pt for the horizontal scrollbar
2783 GetSize( &clientWidth
, &clientHeight
);
2784 clientHeight
-= 4; // sunken frame
2786 int entireWidth
= 0;
2788 for (int tries
= 0; tries
< 2; tries
++)
2795 int m_currentVisibleLines
= 0;
2796 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
2798 m_currentVisibleLines
++;
2799 wxListLineData
*line
= &m_lines
[i
];
2800 line
->CalculateSize( &dc
, iconSpacing
);
2801 line
->SetPosition( &dc
, x
, y
, clientWidth
);
2802 line
->GetSize( lineWidth
, lineHeight
);
2803 if (lineWidth
> maxWidth
) maxWidth
= lineWidth
;
2805 if (m_currentVisibleLines
> m_visibleLines
)
2806 m_visibleLines
= m_currentVisibleLines
;
2807 if (y
+lineSpacing
-6 >= clientHeight
) // -6 for earlier "line breaking"
2809 m_currentVisibleLines
= 0;
2812 entireWidth
+= maxWidth
+6;
2815 if (i
== m_lines
.GetCount()-1) entireWidth
+= maxWidth
;
2816 if ((tries
== 0) && (entireWidth
> clientWidth
))
2818 clientHeight
-= 15; // scrollbar height
2820 m_currentVisibleLines
= 0;
2823 if (i
== m_lines
.GetCount()-1) tries
= 1; // everything fits, no second try required
2827 int scroll_pos
= GetScrollPos( wxHORIZONTAL
);
2828 SetScrollbars( m_xScroll
, m_yScroll
, (entireWidth
+15) / m_xScroll
, 0, scroll_pos
, 0, TRUE
);
2832 void wxListMainWindow::RealizeChanges()
2836 if (!m_lines
.IsEmpty())
2837 m_current
= &m_lines
[0];
2841 FocusLine( m_current
);
2842 // TODO: MSW doesn't automatically hilight the
2844 // if (m_mode & wxLC_SINGLE_SEL) m_current->Hilight( TRUE );
2848 long wxListMainWindow::GetNextItem( long item
,
2849 int WXUNUSED(geometry
),
2853 max
= GetItemCount();
2854 wxCHECK_MSG( (ret
== -1) || (ret
< max
), -1,
2855 _T("invalid listctrl index in GetNextItem()") );
2857 // notice that we start with the next item (or the first one if item == -1)
2858 // and this is intentional to allow writing a simple loop to iterate over
2859 // all selected items
2863 // this is not an error because the index was ok initially, just no
2868 for (size_t i
= (size_t)ret
; i
< m_lines
.GetCount(); i
++)
2870 wxListLineData
*line
= &m_lines
[i
];
2871 if ((state
& wxLIST_STATE_FOCUSED
) && (line
== m_current
))
2873 if ((state
& wxLIST_STATE_SELECTED
) && (line
->IsHilighted()))
2883 void wxListMainWindow::DeleteItem( long index
)
2886 if (index
>= 0 && (size_t)index
< m_lines
.GetCount())
2888 wxListLineData
*line
= &m_lines
[(size_t)index
];
2889 if (m_current
== line
) m_current
= (wxListLineData
*) NULL
;
2891 m_lines
.RemoveAt( (size_t)index
);
2895 void wxListMainWindow::DeleteColumn( int col
)
2897 wxCHECK_RET( col
< (int)m_columns
.GetCount(),
2898 wxT("attempting to delete inexistent column in wxListView") );
2901 wxNode
*node
= m_columns
.Nth( col
);
2902 if (node
) m_columns
.DeleteNode( node
);
2905 void wxListMainWindow::DeleteAllItems()
2908 m_current
= (wxListLineData
*) NULL
;
2910 // to make the deletion of all items faster, we don't send the
2911 // notifications in this case: this is compatible with wxMSW and
2912 // documented in DeleteAllItems() description
2914 wxListEvent
event( wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS
, GetParent()->GetId() );
2915 event
.SetEventObject( GetParent() );
2916 GetParent()->GetEventHandler()->ProcessEvent( event
);
2921 void wxListMainWindow::DeleteEverything()
2928 void wxListMainWindow::EnsureVisible( long index
)
2930 // We have to call this here because the label in
2931 // question might just have been added and no screen
2932 // update taken place.
2933 if (m_dirty
) wxYield();
2935 wxListLineData
*oldCurrent
= m_current
;
2936 m_current
= (wxListLineData
*) NULL
;
2937 if (index
>= 0 && (size_t)index
< m_lines
.GetCount())
2938 m_current
= &m_lines
[(size_t)index
];
2939 if (m_current
) MoveToFocus();
2940 m_current
= oldCurrent
;
2943 long wxListMainWindow::FindItem(long start
, const wxString
& str
, bool WXUNUSED(partial
) )
2947 if (pos
< 0) pos
= 0;
2948 for (size_t i
= (size_t)pos
; i
< m_lines
.GetCount(); i
++)
2950 wxListLineData
*line
= &m_lines
[i
];
2952 line
->GetText( 0, s
);
2953 if (s
== tmp
) return pos
;
2959 long wxListMainWindow::FindItem(long start
, long data
)
2962 if (pos
< 0) pos
= 0;
2963 for (size_t i
= (size_t)pos
; i
< m_lines
.GetCount(); i
++)
2965 wxListLineData
*line
= &m_lines
[i
];
2967 line
->GetItem( 0, item
);
2968 if (item
.m_data
== data
) return pos
;
2974 long wxListMainWindow::HitTest( int x
, int y
, int &flags
)
2976 CalcUnscrolledPosition( x
, y
, &x
, &y
);
2979 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
2981 wxListLineData
*line
= &m_lines
[i
];
2982 long ret
= line
->IsHit( x
, y
);
2983 if (ret
) // & flags) // No: flags is output-only so may be garbage at this point
2993 void wxListMainWindow::InsertItem( wxListItem
&item
)
2997 if (m_mode
& wxLC_REPORT
) mode
= wxLC_REPORT
;
2998 else if (m_mode
& wxLC_LIST
) mode
= wxLC_LIST
;
2999 else if (m_mode
& wxLC_ICON
) mode
= wxLC_ICON
;
3000 else if (m_mode
& wxLC_SMALL_ICON
) mode
= wxLC_ICON
; // no typo
3002 wxListLineData
*line
= new wxListLineData( this, mode
, m_hilightBrush
);
3004 if (m_mode
& wxLC_REPORT
)
3006 line
->InitItems( GetColumnCount() );
3007 item
.m_width
= GetColumnWidth( 0 )-3;
3011 line
->InitItems( 1 );
3014 line
->SetItem( 0, item
);
3015 if ((item
.m_itemId
>= 0) && ((size_t)item
.m_itemId
< m_lines
.GetCount()))
3017 m_lines
.Insert( line
, (size_t)item
.m_itemId
);
3021 m_lines
.Add( line
);
3022 item
.m_itemId
= m_lines
.GetCount()-1;
3026 void wxListMainWindow::InsertColumn( long col
, wxListItem
&item
)
3029 if (m_mode
& wxLC_REPORT
)
3031 if (item
.m_width
== wxLIST_AUTOSIZE_USEHEADER
) item
.m_width
= GetTextLength( item
.m_text
);
3032 wxListHeaderData
*column
= new wxListHeaderData( item
);
3033 if ((col
>= 0) && (col
< (int)m_columns
.GetCount()))
3035 wxNode
*node
= m_columns
.Nth( (size_t)col
);
3037 m_columns
.Insert( node
, column
);
3041 m_columns
.Append( column
);
3046 wxListCtrlCompare list_ctrl_compare_func_2
;
3047 long list_ctrl_compare_data
;
3049 int LINKAGEMODE
list_ctrl_compare_func_1( wxListLineData
**arg1
, wxListLineData
**arg2
)
3051 wxListLineData
*line1
= *arg1
;
3052 wxListLineData
*line2
= *arg2
;
3054 line1
->GetItem( 0, item
);
3055 long data1
= item
.m_data
;
3056 line2
->GetItem( 0, item
);
3057 long data2
= item
.m_data
;
3058 return list_ctrl_compare_func_2( data1
, data2
, list_ctrl_compare_data
);
3061 void wxListMainWindow::SortItems( wxListCtrlCompare fn
, long data
)
3063 list_ctrl_compare_func_2
= fn
;
3064 list_ctrl_compare_data
= data
;
3065 m_lines
.Sort( list_ctrl_compare_func_1
);
3069 void wxListMainWindow::OnScroll(wxScrollWinEvent
& event
)
3071 wxScrolledWindow::OnScroll( event
) ;
3072 #if wxUSE_GENERIC_LIST_EXTENSIONS
3074 if (event
.GetOrientation() == wxHORIZONTAL
&& ( m_mode
& wxLC_REPORT
))
3076 wxListCtrl
* lc
= wxDynamicCast( GetParent() , wxListCtrl
) ;
3079 lc
->m_headerWin
->Refresh() ;
3081 lc
->m_headerWin
->MacUpdateImmediately() ;
3088 // -------------------------------------------------------------------------------------
3090 // -------------------------------------------------------------------------------------
3092 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
)
3094 wxListItem::wxListItem()
3103 m_format
= wxLIST_FORMAT_CENTRE
;
3109 void wxListItem::Clear()
3118 m_format
= wxLIST_FORMAT_CENTRE
;
3120 m_text
= wxEmptyString
;
3122 if (m_attr
) delete m_attr
;
3126 void wxListItem::ClearAttributes()
3128 if (m_attr
) delete m_attr
;
3132 // -------------------------------------------------------------------------------------
3134 // -------------------------------------------------------------------------------------
3136 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
)
3138 wxListEvent::wxListEvent( wxEventType commandType
, int id
):
3139 wxNotifyEvent( commandType
, id
)
3145 m_cancelled
= FALSE
;
3150 void wxListEvent::CopyObject(wxObject
& object_dest
) const
3152 wxListEvent
*obj
= (wxListEvent
*)&object_dest
;
3154 wxNotifyEvent::CopyObject(object_dest
);
3156 obj
->m_code
= m_code
;
3157 obj
->m_itemIndex
= m_itemIndex
;
3158 obj
->m_oldItemIndex
= m_oldItemIndex
;
3160 obj
->m_cancelled
= m_cancelled
;
3161 obj
->m_pointDrag
= m_pointDrag
;
3162 obj
->m_item
.m_mask
= m_item
.m_mask
;
3163 obj
->m_item
.m_itemId
= m_item
.m_itemId
;
3164 obj
->m_item
.m_col
= m_item
.m_col
;
3165 obj
->m_item
.m_state
= m_item
.m_state
;
3166 obj
->m_item
.m_stateMask
= m_item
.m_stateMask
;
3167 obj
->m_item
.m_text
= m_item
.m_text
;
3168 obj
->m_item
.m_image
= m_item
.m_image
;
3169 obj
->m_item
.m_data
= m_item
.m_data
;
3170 obj
->m_item
.m_format
= m_item
.m_format
;
3171 obj
->m_item
.m_width
= m_item
.m_width
;
3173 if ( m_item
.HasAttributes() )
3175 obj
->m_item
.SetTextColour(m_item
.GetTextColour());
3179 // -------------------------------------------------------------------------------------
3181 // -------------------------------------------------------------------------------------
3183 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
)
3185 BEGIN_EVENT_TABLE(wxListCtrl
,wxControl
)
3186 EVT_SIZE (wxListCtrl::OnSize
)
3187 EVT_IDLE (wxListCtrl::OnIdle
)
3190 wxListCtrl::wxListCtrl()
3192 m_imageListNormal
= (wxImageList
*) NULL
;
3193 m_imageListSmall
= (wxImageList
*) NULL
;
3194 m_imageListState
= (wxImageList
*) NULL
;
3195 m_ownsImageListNormal
= m_ownsImageListSmall
= m_ownsImageListState
= FALSE
;
3196 m_mainWin
= (wxListMainWindow
*) NULL
;
3197 m_headerWin
= (wxListHeaderWindow
*) NULL
;
3200 wxListCtrl::~wxListCtrl()
3202 if (m_ownsImageListNormal
) delete m_imageListNormal
;
3203 if (m_ownsImageListSmall
) delete m_imageListSmall
;
3204 if (m_ownsImageListState
) delete m_imageListState
;
3207 bool wxListCtrl::Create(wxWindow
*parent
,
3212 const wxValidator
&validator
,
3213 const wxString
&name
)
3215 m_imageListNormal
= (wxImageList
*) NULL
;
3216 m_imageListSmall
= (wxImageList
*) NULL
;
3217 m_imageListState
= (wxImageList
*) NULL
;
3218 m_ownsImageListNormal
= m_ownsImageListSmall
= m_ownsImageListState
= FALSE
;
3219 m_mainWin
= (wxListMainWindow
*) NULL
;
3220 m_headerWin
= (wxListHeaderWindow
*) NULL
;
3222 if ( !(style
& (wxLC_REPORT
| wxLC_LIST
| wxLC_ICON
)) )
3224 style
= style
| wxLC_LIST
;
3227 bool ret
= wxControl::Create( parent
, id
, pos
, size
, style
, validator
, name
);
3230 if (style
& wxSUNKEN_BORDER
)
3231 style
-= wxSUNKEN_BORDER
;
3233 m_mainWin
= new wxListMainWindow( this, -1, wxPoint(0,0), size
, style
);
3235 if (HasFlag(wxLC_REPORT
))
3237 m_headerWin
= new wxListHeaderWindow( this, -1, m_mainWin
, wxPoint(0,0), wxSize(size
.x
,23), wxTAB_TRAVERSAL
);
3238 if (HasFlag(wxLC_NO_HEADER
))
3239 m_headerWin
->Show( FALSE
);
3243 m_headerWin
= (wxListHeaderWindow
*) NULL
;
3249 void wxListCtrl::OnSize( wxSizeEvent
&WXUNUSED(event
) )
3251 /* handled in OnIdle */
3253 if (m_mainWin
) m_mainWin
->m_dirty
= TRUE
;
3256 void wxListCtrl::SetSingleStyle( long style
, bool add
)
3258 long flag
= GetWindowStyle();
3262 if (style
& wxLC_MASK_TYPE
) flag
= flag
& ~wxLC_MASK_TYPE
;
3263 if (style
& wxLC_MASK_ALIGN
) flag
= flag
& ~wxLC_MASK_ALIGN
;
3264 if (style
& wxLC_MASK_SORT
) flag
= flag
& ~wxLC_MASK_SORT
;
3273 if (flag
& style
) flag
-= style
;
3276 SetWindowStyleFlag( flag
);
3279 void wxListCtrl::SetWindowStyleFlag( long flag
)
3283 m_mainWin
->DeleteEverything();
3287 GetClientSize( &width
, &height
);
3289 m_mainWin
->SetMode( flag
);
3291 if (flag
& wxLC_REPORT
)
3293 if (!HasFlag(wxLC_REPORT
))
3297 m_headerWin
= new wxListHeaderWindow( this, -1, m_mainWin
,
3298 wxPoint(0,0), wxSize(width
,23), wxTAB_TRAVERSAL
);
3299 if (HasFlag(wxLC_NO_HEADER
))
3300 m_headerWin
->Show( FALSE
);
3304 if (flag
& wxLC_NO_HEADER
)
3305 m_headerWin
->Show( FALSE
);
3307 m_headerWin
->Show( TRUE
);
3313 if (HasFlag(wxLC_REPORT
) && !(HasFlag(wxLC_NO_HEADER
)))
3315 m_headerWin
->Show( FALSE
);
3320 wxWindow::SetWindowStyleFlag( flag
);
3323 bool wxListCtrl::GetColumn(int col
, wxListItem
&item
) const
3325 m_mainWin
->GetColumn( col
, item
);
3329 bool wxListCtrl::SetColumn( int col
, wxListItem
& item
)
3331 m_mainWin
->SetColumn( col
, item
);
3335 int wxListCtrl::GetColumnWidth( int col
) const
3337 return m_mainWin
->GetColumnWidth( col
);
3340 bool wxListCtrl::SetColumnWidth( int col
, int width
)
3342 m_mainWin
->SetColumnWidth( col
, width
);
3346 int wxListCtrl::GetCountPerPage() const
3348 return m_mainWin
->GetCountPerPage(); // different from Windows ?
3351 bool wxListCtrl::GetItem( wxListItem
&info
) const
3353 m_mainWin
->GetItem( info
);
3357 bool wxListCtrl::SetItem( wxListItem
&info
)
3359 m_mainWin
->SetItem( info
);
3363 long wxListCtrl::SetItem( long index
, int col
, const wxString
& label
, int imageId
)
3366 info
.m_text
= label
;
3367 info
.m_mask
= wxLIST_MASK_TEXT
;
3368 info
.m_itemId
= index
;
3372 info
.m_image
= imageId
;
3373 info
.m_mask
|= wxLIST_MASK_IMAGE
;
3375 m_mainWin
->SetItem(info
);
3379 int wxListCtrl::GetItemState( long item
, long stateMask
) const
3381 return m_mainWin
->GetItemState( item
, stateMask
);
3384 bool wxListCtrl::SetItemState( long item
, long state
, long stateMask
)
3386 m_mainWin
->SetItemState( item
, state
, stateMask
);
3390 bool wxListCtrl::SetItemImage( long item
, int image
, int WXUNUSED(selImage
) )
3393 info
.m_image
= image
;
3394 info
.m_mask
= wxLIST_MASK_IMAGE
;
3395 info
.m_itemId
= item
;
3396 m_mainWin
->SetItem( info
);
3400 wxString
wxListCtrl::GetItemText( long item
) const
3403 info
.m_itemId
= item
;
3404 m_mainWin
->GetItem( info
);
3408 void wxListCtrl::SetItemText( long item
, const wxString
&str
)
3411 info
.m_mask
= wxLIST_MASK_TEXT
;
3412 info
.m_itemId
= item
;
3414 m_mainWin
->SetItem( info
);
3417 long wxListCtrl::GetItemData( long item
) const
3420 info
.m_itemId
= item
;
3421 m_mainWin
->GetItem( info
);
3425 bool wxListCtrl::SetItemData( long item
, long data
)
3428 info
.m_mask
= wxLIST_MASK_DATA
;
3429 info
.m_itemId
= item
;
3431 m_mainWin
->SetItem( info
);
3435 bool wxListCtrl::GetItemRect( long item
, wxRect
&rect
, int WXUNUSED(code
) ) const
3437 m_mainWin
->GetItemRect( item
, rect
);
3441 bool wxListCtrl::GetItemPosition( long item
, wxPoint
& pos
) const
3443 m_mainWin
->GetItemPosition( item
, pos
);
3447 bool wxListCtrl::SetItemPosition( long WXUNUSED(item
), const wxPoint
& WXUNUSED(pos
) )
3452 int wxListCtrl::GetItemCount() const
3454 return m_mainWin
->GetItemCount();
3457 int wxListCtrl::GetColumnCount() const
3459 return m_mainWin
->GetColumnCount();
3462 void wxListCtrl::SetItemSpacing( int spacing
, bool isSmall
)
3464 m_mainWin
->SetItemSpacing( spacing
, isSmall
);
3467 int wxListCtrl::GetItemSpacing( bool isSmall
) const
3469 return m_mainWin
->GetItemSpacing( isSmall
);
3472 int wxListCtrl::GetSelectedItemCount() const
3474 return m_mainWin
->GetSelectedItemCount();
3477 wxColour
wxListCtrl::GetTextColour() const
3479 return GetForegroundColour();
3482 void wxListCtrl::SetTextColour(const wxColour
& col
)
3484 SetForegroundColour(col
);
3487 long wxListCtrl::GetTopItem() const
3492 long wxListCtrl::GetNextItem( long item
, int geom
, int state
) const
3494 return m_mainWin
->GetNextItem( item
, geom
, state
);
3497 wxImageList
*wxListCtrl::GetImageList(int which
) const
3499 if (which
== wxIMAGE_LIST_NORMAL
)
3501 return m_imageListNormal
;
3503 else if (which
== wxIMAGE_LIST_SMALL
)
3505 return m_imageListSmall
;
3507 else if (which
== wxIMAGE_LIST_STATE
)
3509 return m_imageListState
;
3511 return (wxImageList
*) NULL
;
3514 void wxListCtrl::SetImageList( wxImageList
*imageList
, int which
)
3516 if ( which
== wxIMAGE_LIST_NORMAL
)
3518 if (m_ownsImageListNormal
) delete m_imageListNormal
;
3519 m_imageListNormal
= imageList
;
3520 m_ownsImageListNormal
= FALSE
;
3522 else if ( which
== wxIMAGE_LIST_SMALL
)
3524 if (m_ownsImageListSmall
) delete m_imageListSmall
;
3525 m_imageListSmall
= imageList
;
3526 m_ownsImageListSmall
= FALSE
;
3528 else if ( which
== wxIMAGE_LIST_STATE
)
3530 if (m_ownsImageListState
) delete m_imageListState
;
3531 m_imageListState
= imageList
;
3532 m_ownsImageListState
= FALSE
;
3535 m_mainWin
->SetImageList( imageList
, which
);
3538 void wxListCtrl::AssignImageList(wxImageList
*imageList
, int which
)
3540 SetImageList(imageList
, which
);
3541 if ( which
== wxIMAGE_LIST_NORMAL
)
3542 m_ownsImageListNormal
= TRUE
;
3543 else if ( which
== wxIMAGE_LIST_SMALL
)
3544 m_ownsImageListSmall
= TRUE
;
3545 else if ( which
== wxIMAGE_LIST_STATE
)
3546 m_ownsImageListState
= TRUE
;
3549 bool wxListCtrl::Arrange( int WXUNUSED(flag
) )
3554 bool wxListCtrl::DeleteItem( long item
)
3556 m_mainWin
->DeleteItem( item
);
3560 bool wxListCtrl::DeleteAllItems()
3562 m_mainWin
->DeleteAllItems();
3566 bool wxListCtrl::DeleteAllColumns()
3568 for ( size_t n
= 0; n
< m_mainWin
->m_columns
.GetCount(); n
++ )
3574 void wxListCtrl::ClearAll()
3576 m_mainWin
->DeleteEverything();
3579 bool wxListCtrl::DeleteColumn( int col
)
3581 m_mainWin
->DeleteColumn( col
);
3585 void wxListCtrl::Edit( long item
)
3587 m_mainWin
->Edit( item
);
3590 bool wxListCtrl::EnsureVisible( long item
)
3592 m_mainWin
->EnsureVisible( item
);
3596 long wxListCtrl::FindItem( long start
, const wxString
& str
, bool partial
)
3598 return m_mainWin
->FindItem( start
, str
, partial
);
3601 long wxListCtrl::FindItem( long start
, long data
)
3603 return m_mainWin
->FindItem( start
, data
);
3606 long wxListCtrl::FindItem( long WXUNUSED(start
), const wxPoint
& WXUNUSED(pt
),
3607 int WXUNUSED(direction
))
3612 long wxListCtrl::HitTest( const wxPoint
&point
, int &flags
)
3614 return m_mainWin
->HitTest( (int)point
.x
, (int)point
.y
, flags
);
3617 long wxListCtrl::InsertItem( wxListItem
& info
)
3619 m_mainWin
->InsertItem( info
);
3620 return info
.m_itemId
;
3623 long wxListCtrl::InsertItem( long index
, const wxString
&label
)
3626 info
.m_text
= label
;
3627 info
.m_mask
= wxLIST_MASK_TEXT
;
3628 info
.m_itemId
= index
;
3629 return InsertItem( info
);
3632 long wxListCtrl::InsertItem( long index
, int imageIndex
)
3635 info
.m_mask
= wxLIST_MASK_IMAGE
;
3636 info
.m_image
= imageIndex
;
3637 info
.m_itemId
= index
;
3638 return InsertItem( info
);
3641 long wxListCtrl::InsertItem( long index
, const wxString
&label
, int imageIndex
)
3644 info
.m_text
= label
;
3645 info
.m_image
= imageIndex
;
3646 info
.m_mask
= wxLIST_MASK_TEXT
| wxLIST_MASK_IMAGE
;
3647 info
.m_itemId
= index
;
3648 return InsertItem( info
);
3651 long wxListCtrl::InsertColumn( long col
, wxListItem
&item
)
3653 wxASSERT( m_headerWin
);
3654 m_mainWin
->InsertColumn( col
, item
);
3655 m_headerWin
->Refresh();
3660 long wxListCtrl::InsertColumn( long col
, const wxString
&heading
,
3661 int format
, int width
)
3664 item
.m_mask
= wxLIST_MASK_TEXT
| wxLIST_MASK_FORMAT
;
3665 item
.m_text
= heading
;
3668 item
.m_mask
|= wxLIST_MASK_WIDTH
;
3669 item
.m_width
= width
;
3671 item
.m_format
= format
;
3673 return InsertColumn( col
, item
);
3676 bool wxListCtrl::ScrollList( int WXUNUSED(dx
), int WXUNUSED(dy
) )
3682 // fn is a function which takes 3 long arguments: item1, item2, data.
3683 // item1 is the long data associated with a first item (NOT the index).
3684 // item2 is the long data associated with a second item (NOT the index).
3685 // data is the same value as passed to SortItems.
3686 // The return value is a negative number if the first item should precede the second
3687 // item, a positive number of the second item should precede the first,
3688 // or zero if the two items are equivalent.
3689 // data is arbitrary data to be passed to the sort function.
3691 bool wxListCtrl::SortItems( wxListCtrlCompare fn
, long data
)
3693 m_mainWin
->SortItems( fn
, data
);
3697 void wxListCtrl::OnIdle( wxIdleEvent
&WXUNUSED(event
) )
3699 if (!m_mainWin
->m_dirty
) return;
3703 GetClientSize( &cw
, &ch
);
3710 if (HasFlag(wxLC_REPORT
) && !HasFlag(wxLC_NO_HEADER
))
3712 m_headerWin
->GetPosition( &x
, &y
);
3713 m_headerWin
->GetSize( &w
, &h
);
3714 if ((x
!= 0) || (y
!= 0) || (w
!= cw
) || (h
!= 23))
3715 m_headerWin
->SetSize( 0, 0, cw
, 23 );
3717 m_mainWin
->GetPosition( &x
, &y
);
3718 m_mainWin
->GetSize( &w
, &h
);
3719 if ((x
!= 0) || (y
!= 24) || (w
!= cw
) || (h
!= ch
-24))
3720 m_mainWin
->SetSize( 0, 24, cw
, ch
-24 );
3724 m_mainWin
->GetPosition( &x
, &y
);
3725 m_mainWin
->GetSize( &w
, &h
);
3726 if ((x
!= 0) || (y
!= 24) || (w
!= cw
) || (h
!= ch
))
3727 m_mainWin
->SetSize( 0, 0, cw
, ch
);
3730 m_mainWin
->CalculatePositions();
3731 m_mainWin
->RealizeChanges();
3732 m_mainWin
->m_dirty
= FALSE
;
3733 m_mainWin
->Refresh();
3735 if ( m_headerWin
&& m_headerWin
->m_dirty
)
3737 m_headerWin
->m_dirty
= FALSE
;
3738 m_headerWin
->Refresh();
3742 bool wxListCtrl::SetBackgroundColour( const wxColour
&colour
)
3746 m_mainWin
->SetBackgroundColour( colour
);
3747 m_mainWin
->m_dirty
= TRUE
;
3753 bool wxListCtrl::SetForegroundColour( const wxColour
&colour
)
3755 if ( !wxWindow::SetForegroundColour( colour
) )
3760 m_mainWin
->SetForegroundColour( colour
);
3761 m_mainWin
->m_dirty
= TRUE
;
3766 m_headerWin
->SetForegroundColour( colour
);
3772 bool wxListCtrl::SetFont( const wxFont
&font
)
3774 if ( !wxWindow::SetFont( font
) )
3779 m_mainWin
->SetFont( font
);
3780 m_mainWin
->m_dirty
= TRUE
;
3785 m_headerWin
->SetFont( font
);
3791 #if wxUSE_DRAG_AND_DROP
3793 void wxListCtrl::SetDropTarget( wxDropTarget
*dropTarget
)
3795 m_mainWin
->SetDropTarget( dropTarget
);
3798 wxDropTarget
*wxListCtrl::GetDropTarget() const
3800 return m_mainWin
->GetDropTarget();
3803 #endif // wxUSE_DRAG_AND_DROP
3805 bool wxListCtrl::SetCursor( const wxCursor
&cursor
)
3807 return m_mainWin
? m_mainWin
->wxWindow::SetCursor(cursor
) : FALSE
;
3810 wxColour
wxListCtrl::GetBackgroundColour() const
3812 return m_mainWin
? m_mainWin
->GetBackgroundColour() : wxColour();
3815 wxColour
wxListCtrl::GetForegroundColour() const
3817 return m_mainWin
? m_mainWin
->GetForegroundColour() : wxColour();
3820 bool wxListCtrl::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
3822 return m_mainWin
->PopupMenu( menu
, x
, y
);
3825 void wxListCtrl::SetFocus()
3827 /* The test in window.cpp fails as we are a composite
3828 window, so it checks against "this", but not m_mainWin. */
3829 if ( FindFocus() != this )
3830 m_mainWin
->SetFocus();