1 /////////////////////////////////////////////////////////////////////////////
2 // Name: generic/listctrl.cpp
3 // Purpose: generic implementation of wxListCtrl
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 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_DRAG
)
42 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_RDRAG
)
43 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
)
44 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_END_LABEL_EDIT
)
45 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ITEM
)
46 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS
)
47 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_GET_INFO
)
48 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_SET_INFO
)
49 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_SELECTED
)
50 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_DESELECTED
)
51 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_KEY_DOWN
)
52 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_INSERT_ITEM
)
53 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_COL_CLICK
)
54 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK
)
55 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK
)
56 DEFINE_EVENT_TYPE(wxEVT_COMMAND_LIST_ITEM_ACTIVATED
)
58 // ============================================================================
60 // ============================================================================
62 //-----------------------------------------------------------------------------
63 // wxListItemData (internal)
64 //-----------------------------------------------------------------------------
66 class WXDLLEXPORT wxListItemData
: public wxObject
70 ~wxListItemData() { delete m_attr
; }
72 wxListItemData( const wxListItem
&info
);
73 void SetItem( const wxListItem
&info
);
74 void SetImage( int image
);
75 void SetData( long data
);
76 void SetPosition( int x
, int y
);
77 void SetSize( int width
, int height
);
78 bool HasImage() const;
80 bool HasText() const { return !m_text
.empty(); }
81 const wxString
& GetText() const { return m_text
; }
82 void SetText(const wxString
& text
) { m_text
= text
; }
84 bool IsHit( int x
, int y
) const;
86 int GetX( void ) const;
87 int GetY( void ) const;
89 int GetHeight() const;
91 void GetItem( wxListItem
&info
) const;
93 wxListItemAttr
*GetAttributes() const { return m_attr
; }
103 wxListItemAttr
*m_attr
;
109 DECLARE_DYNAMIC_CLASS(wxListItemData
);
112 //-----------------------------------------------------------------------------
113 // wxListHeaderData (internal)
114 //-----------------------------------------------------------------------------
116 class WXDLLEXPORT wxListHeaderData
: public wxObject
129 wxListHeaderData( const wxListItem
&info
);
130 void SetItem( const wxListItem
&item
);
131 void SetPosition( int x
, int y
);
132 void SetWidth( int w
);
133 void SetFormat( int format
);
134 void SetHeight( int h
);
135 bool HasImage() const;
137 bool HasText() const { return !m_text
.empty(); }
138 const wxString
& GetText() const { return m_text
; }
139 void SetText(const wxString
& text
) { m_text
= text
; }
141 void GetItem( wxListItem
&item
);
143 bool IsHit( int x
, int y
) const;
144 int GetImage() const;
145 int GetWidth() const;
146 int GetFormat() const;
149 DECLARE_DYNAMIC_CLASS(wxListHeaderData
);
152 //-----------------------------------------------------------------------------
153 // wxListLineData (internal)
154 //-----------------------------------------------------------------------------
156 class WXDLLEXPORT wxListLineData
: public wxObject
161 wxRect m_bound_label
;
163 wxRect m_bound_hilight
;
166 wxBrush
*m_hilightBrush
;
168 wxListMainWindow
*m_owner
;
170 void DoDraw( wxDC
*dc
, bool hilight
, bool paintBG
);
174 wxListLineData( wxListMainWindow
*owner
, int mode
, wxBrush
*hilightBrush
);
175 void CalculateSize( wxDC
*dc
, int spacing
);
176 void SetPosition( wxDC
*dc
, int x
, int y
, int window_width
);
177 void SetColumnPosition( int index
, int x
);
178 void GetSize( int &width
, int &height
);
179 void GetExtent( int &x
, int &y
, int &width
, int &height
);
180 void GetLabelExtent( int &x
, int &y
, int &width
, int &height
);
181 long IsHit( int x
, int y
);
182 void InitItems( int num
);
183 void SetItem( int index
, const wxListItem
&info
);
184 void GetItem( int index
, wxListItem
&info
);
185 wxString
GetText(int index
) const;
186 void SetText( int index
, const wxString s
);
187 int GetImage( int index
);
188 void GetRect( wxRect
&rect
);
189 void Hilight( bool on
);
190 void ReverseHilight();
191 void DrawRubberBand( wxDC
*dc
, bool on
);
192 void Draw( wxDC
*dc
);
193 bool IsInRect( int x
, int y
, const wxRect
&rect
);
195 void AssignRect( wxRect
&dest
, int x
, int y
, int width
, int height
);
196 void AssignRect( wxRect
&dest
, const wxRect
&source
);
199 void SetAttributes(wxDC
*dc
,
200 const wxListItemAttr
*attr
,
201 const wxColour
& colText
, const wxFont
& font
,
204 DECLARE_DYNAMIC_CLASS(wxListLineData
);
208 WX_DECLARE_EXPORTED_OBJARRAY(wxListLineData
, wxListLineDataArray
);
209 #include "wx/arrimpl.cpp"
210 WX_DEFINE_OBJARRAY(wxListLineDataArray
);
212 //-----------------------------------------------------------------------------
213 // wxListHeaderWindow (internal)
214 //-----------------------------------------------------------------------------
216 class WXDLLEXPORT wxListHeaderWindow
: public wxWindow
219 wxListMainWindow
*m_owner
;
220 wxCursor
*m_currentCursor
;
221 wxCursor
*m_resizeCursor
;
224 // column being resized
227 // divider line position in logical (unscrolled) coords
230 // minimal position beyond which the divider line can't be dragged in
235 wxListHeaderWindow();
236 virtual ~wxListHeaderWindow();
238 wxListHeaderWindow( wxWindow
*win
,
240 wxListMainWindow
*owner
,
241 const wxPoint
&pos
= wxDefaultPosition
,
242 const wxSize
&size
= wxDefaultSize
,
244 const wxString
&name
= "wxlistctrlcolumntitles" );
246 void DoDrawRect( wxDC
*dc
, int x
, int y
, int w
, int h
);
248 void AdjustDC(wxDC
& dc
);
250 void OnPaint( wxPaintEvent
&event
);
251 void OnMouse( wxMouseEvent
&event
);
252 void OnSetFocus( wxFocusEvent
&event
);
258 DECLARE_DYNAMIC_CLASS(wxListHeaderWindow
)
259 DECLARE_EVENT_TABLE()
262 //-----------------------------------------------------------------------------
263 // wxListRenameTimer (internal)
264 //-----------------------------------------------------------------------------
266 class WXDLLEXPORT wxListRenameTimer
: public wxTimer
269 wxListMainWindow
*m_owner
;
272 wxListRenameTimer( wxListMainWindow
*owner
);
276 //-----------------------------------------------------------------------------
277 // wxListTextCtrl (internal)
278 //-----------------------------------------------------------------------------
280 class WXDLLEXPORT wxListTextCtrl
: public wxTextCtrl
285 wxListMainWindow
*m_owner
;
286 wxString m_startValue
;
290 wxListTextCtrl( wxWindow
*parent
, const wxWindowID id
,
291 bool *accept
, wxString
*res
, wxListMainWindow
*owner
,
292 const wxString
&value
= "",
293 const wxPoint
&pos
= wxDefaultPosition
, const wxSize
&size
= wxDefaultSize
,
295 const wxValidator
& validator
= wxDefaultValidator
,
296 const wxString
&name
= "listctrltextctrl" );
297 void OnChar( wxKeyEvent
&event
);
298 void OnKeyUp( wxKeyEvent
&event
);
299 void OnKillFocus( wxFocusEvent
&event
);
302 DECLARE_DYNAMIC_CLASS(wxListTextCtrl
);
303 DECLARE_EVENT_TABLE()
306 //-----------------------------------------------------------------------------
307 // wxListMainWindow (internal)
308 //-----------------------------------------------------------------------------
310 class WXDLLEXPORT wxListMainWindow
: public wxScrolledWindow
314 wxListLineDataArray m_lines
;
316 wxListLineData
*m_current
;
317 wxListLineData
*m_currentEdit
;
319 wxBrush
*m_hilightBrush
;
320 wxColour
*m_hilightColour
;
321 int m_xScroll
,m_yScroll
;
323 wxImageList
*m_small_image_list
;
324 wxImageList
*m_normal_image_list
;
326 int m_normal_spacing
;
330 wxTimer
*m_renameTimer
;
332 wxString m_renameRes
;
337 // for double click logic
338 wxListLineData
*m_lineLastClicked
,
339 *m_lineBeforeLastClicked
;
343 wxListMainWindow( wxWindow
*parent
, wxWindowID id
,
344 const wxPoint
&pos
= wxDefaultPosition
, const wxSize
&size
= wxDefaultSize
,
345 long style
= 0, const wxString
&name
= "listctrlmainwindow" );
347 void RefreshLine( wxListLineData
*line
);
348 void OnPaint( wxPaintEvent
&event
);
349 void HilightAll( bool on
);
350 void SendNotify( wxListLineData
*line
,
352 wxPoint point
= wxDefaultPosition
);
353 void FocusLine( wxListLineData
*line
);
354 void UnfocusLine( wxListLineData
*line
);
355 void SelectLine( wxListLineData
*line
);
356 void DeselectLine( wxListLineData
*line
);
357 void DeleteLine( wxListLineData
*line
);
359 void EditLabel( long item
);
360 void Edit( long item
) { EditLabel(item
); } // deprecated
361 void OnRenameTimer();
362 void OnRenameAccept();
364 void OnMouse( wxMouseEvent
&event
);
366 void OnArrowChar( wxListLineData
*newCurrent
, bool shiftDown
);
367 void OnChar( wxKeyEvent
&event
);
368 void OnKeyDown( wxKeyEvent
&event
);
369 void OnSetFocus( wxFocusEvent
&event
);
370 void OnKillFocus( wxFocusEvent
&event
);
371 void OnSize( wxSizeEvent
&event
);
372 void OnScroll(wxScrollWinEvent
& event
) ;
374 void DrawImage( int index
, wxDC
*dc
, int x
, int y
);
375 void GetImageSize( int index
, int &width
, int &height
);
376 int GetIndexOfLine( const wxListLineData
*line
);
377 int GetTextLength( wxString
&s
); // should be const
379 void SetImageList( wxImageList
*imageList
, int which
);
380 void SetItemSpacing( int spacing
, bool isSmall
= FALSE
);
381 int GetItemSpacing( bool isSmall
= FALSE
);
382 void SetColumn( int col
, wxListItem
&item
);
383 void SetColumnWidth( int col
, int width
);
384 void GetColumn( int col
, wxListItem
&item
);
385 int GetColumnWidth( int vol
);
386 int GetColumnCount();
387 int GetCountPerPage();
388 void SetItem( wxListItem
&item
);
389 void GetItem( wxListItem
&item
);
390 void SetItemState( long item
, long state
, long stateMask
);
391 int GetItemState( long item
, long stateMask
);
393 void GetItemRect( long index
, wxRect
&rect
);
394 bool GetItemPosition( long item
, wxPoint
& pos
);
395 int GetSelectedItemCount();
396 void SetMode( long mode
);
397 long GetMode() const;
398 void CalculatePositions();
399 void RealizeChanges();
400 long GetNextItem( long item
, int geometry
, int state
);
401 void DeleteItem( long index
);
402 void DeleteAllItems();
403 void DeleteColumn( int col
);
404 void DeleteEverything();
405 void EnsureVisible( long index
);
406 long FindItem( long start
, const wxString
& str
, bool partial
= FALSE
);
407 long FindItem( long start
, long data
);
408 long HitTest( int x
, int y
, int &flags
);
409 void InsertItem( wxListItem
&item
);
410 // void AddItem( wxListItem &item );
411 void InsertColumn( long col
, wxListItem
&item
);
412 // void AddColumn( wxListItem &item );
413 void SortItems( wxListCtrlCompare fn
, long data
);
416 DECLARE_DYNAMIC_CLASS(wxListMainWindow
);
417 DECLARE_EVENT_TABLE()
420 // ============================================================================
422 // ============================================================================
424 //-----------------------------------------------------------------------------
426 //-----------------------------------------------------------------------------
428 IMPLEMENT_DYNAMIC_CLASS(wxListItemData
,wxObject
);
430 wxListItemData::wxListItemData()
441 wxListItemData::wxListItemData( const wxListItem
&info
)
450 void wxListItemData::SetItem( const wxListItem
&info
)
452 if (info
.m_mask
& wxLIST_MASK_TEXT
)
453 SetText(info
.m_text
);
454 if (info
.m_mask
& wxLIST_MASK_IMAGE
)
455 m_image
= info
.m_image
;
456 if (info
.m_mask
& wxLIST_MASK_DATA
)
457 m_data
= info
.m_data
;
459 if ( info
.HasAttributes() )
462 *m_attr
= *info
.GetAttributes();
464 m_attr
= new wxListItemAttr(*info
.GetAttributes());
469 m_width
= info
.m_width
;
473 void wxListItemData::SetImage( int image
)
478 void wxListItemData::SetData( long data
)
483 void wxListItemData::SetPosition( int x
, int y
)
489 void wxListItemData::SetSize( int width
, int height
)
491 if (width
!= -1) m_width
= width
;
492 if (height
!= -1) m_height
= height
;
495 bool wxListItemData::HasImage() const
497 return (m_image
>= 0);
500 bool wxListItemData::IsHit( int x
, int y
) const
502 return ((x
>= m_xpos
) && (x
<= m_xpos
+m_width
) && (y
>= m_ypos
) && (y
<= m_ypos
+m_height
));
505 int wxListItemData::GetX() const
510 int wxListItemData::GetY() const
515 int wxListItemData::GetWidth() const
520 int wxListItemData::GetHeight() const
525 int wxListItemData::GetImage() const
530 void wxListItemData::GetItem( wxListItem
&info
) const
532 info
.m_text
= m_text
;
533 info
.m_image
= m_image
;
534 info
.m_data
= m_data
;
538 if ( m_attr
->HasTextColour() )
539 info
.SetTextColour(m_attr
->GetTextColour());
540 if ( m_attr
->HasBackgroundColour() )
541 info
.SetBackgroundColour(m_attr
->GetBackgroundColour());
542 if ( m_attr
->HasFont() )
543 info
.SetFont(m_attr
->GetFont());
547 //-----------------------------------------------------------------------------
549 //-----------------------------------------------------------------------------
551 IMPLEMENT_DYNAMIC_CLASS(wxListHeaderData
,wxObject
);
553 wxListHeaderData::wxListHeaderData()
564 wxListHeaderData::wxListHeaderData( const wxListItem
&item
)
572 void wxListHeaderData::SetItem( const wxListItem
&item
)
574 m_mask
= item
.m_mask
;
575 m_text
= item
.m_text
;
576 m_image
= item
.m_image
;
577 m_format
= item
.m_format
;
578 m_width
= item
.m_width
;
579 if (m_width
< 0) m_width
= 80;
580 if (m_width
< 6) m_width
= 6;
583 void wxListHeaderData::SetPosition( int x
, int y
)
589 void wxListHeaderData::SetHeight( int h
)
594 void wxListHeaderData::SetWidth( int w
)
597 if (m_width
< 0) m_width
= 80;
598 if (m_width
< 6) m_width
= 6;
601 void wxListHeaderData::SetFormat( int format
)
606 bool wxListHeaderData::HasImage() const
608 return (m_image
!= 0);
611 bool wxListHeaderData::IsHit( int x
, int y
) const
613 return ((x
>= m_xpos
) && (x
<= m_xpos
+m_width
) && (y
>= m_ypos
) && (y
<= m_ypos
+m_height
));
616 void wxListHeaderData::GetItem( wxListItem
&item
)
618 item
.m_mask
= m_mask
;
619 item
.m_text
= m_text
;
620 item
.m_image
= m_image
;
621 item
.m_format
= m_format
;
622 item
.m_width
= m_width
;
625 int wxListHeaderData::GetImage() const
630 int wxListHeaderData::GetWidth() const
635 int wxListHeaderData::GetFormat() const
640 //-----------------------------------------------------------------------------
642 //-----------------------------------------------------------------------------
644 IMPLEMENT_DYNAMIC_CLASS(wxListLineData
,wxObject
);
646 wxListLineData::wxListLineData( wxListMainWindow
*owner
, int mode
, wxBrush
*hilightBrush
)
651 m_hilightBrush
= hilightBrush
;
652 m_items
.DeleteContents( TRUE
);
656 void wxListLineData::CalculateSize( wxDC
*dc
, int spacing
)
663 m_bound_all
.width
= m_spacing
;
664 wxNode
*node
= m_items
.First();
667 wxListItemData
*item
= (wxListItemData
*)node
->Data();
668 wxString s
= item
->GetText();
669 if (s
.IsEmpty()) s
= wxT("H");
671 dc
->GetTextExtent( s
, &lw
, &lh
);
672 if (lh
< 15) lh
= 15;
676 m_bound_all
.height
= m_spacing
+lh
;
677 if (lw
> m_spacing
) m_bound_all
.width
= lw
;
678 m_bound_label
.width
= lw
;
679 m_bound_label
.height
= lh
;
681 if (item
->HasImage())
685 m_owner
->GetImageSize( item
->GetImage(), w
, h
);
686 m_bound_icon
.width
= w
+ 8;
687 m_bound_icon
.height
= h
+ 8;
689 if ( m_bound_icon
.width
> m_bound_all
.width
)
690 m_bound_all
.width
= m_bound_icon
.width
;
691 if ( h
+ lh
> m_bound_all
.height
- 4 )
692 m_bound_all
.height
= h
+ lh
+ 4;
695 if (!item
->HasText())
697 m_bound_hilight
.width
= m_bound_icon
.width
;
698 m_bound_hilight
.height
= m_bound_icon
.height
;
702 m_bound_hilight
.width
= m_bound_label
.width
;
703 m_bound_hilight
.height
= m_bound_label
.height
;
710 wxNode
*node
= m_items
.First();
713 wxListItemData
*item
= (wxListItemData
*)node
->Data();
715 wxString s
= item
->GetText();
716 if (s
.IsEmpty()) s
= wxT("H");
718 dc
->GetTextExtent( s
, &lw
, &lh
);
719 if (lh
< 15) lh
= 15;
722 m_bound_label
.width
= lw
;
723 m_bound_label
.height
= lh
;
725 m_bound_all
.width
= lw
;
726 m_bound_all
.height
= lh
;
728 if (item
->HasImage())
732 m_owner
->GetImageSize( item
->GetImage(), w
, h
);
733 m_bound_icon
.width
= w
;
734 m_bound_icon
.height
= h
;
736 m_bound_all
.width
+= 4 + w
;
737 if (h
> m_bound_all
.height
) m_bound_all
.height
= h
;
740 m_bound_hilight
.width
= m_bound_all
.width
;
741 m_bound_hilight
.height
= m_bound_all
.height
;
747 m_bound_all
.width
= 0;
748 m_bound_all
.height
= 0;
749 wxNode
*node
= m_items
.First();
752 wxListItemData
*item
= (wxListItemData
*)node
->Data();
753 if (item
->HasImage())
757 m_owner
->GetImageSize( item
->GetImage(), w
, h
);
758 m_bound_icon
.width
= w
;
759 m_bound_icon
.height
= h
;
763 m_bound_icon
.width
= 0;
764 m_bound_icon
.height
= 0;
769 wxListItemData
*item
= (wxListItemData
*)node
->Data();
770 wxString s
= item
->GetText();
771 if (s
.IsEmpty()) s
= wxT("H");
773 dc
->GetTextExtent( s
, &lw
, &lh
);
774 if (lh
< 15) lh
= 15;
778 item
->SetSize( item
->GetWidth(), lh
);
779 m_bound_all
.width
+= lw
;
780 m_bound_all
.height
= lh
;
783 m_bound_label
.width
= m_bound_all
.width
;
784 m_bound_label
.height
= m_bound_all
.height
;
790 void wxListLineData::SetPosition( wxDC
* WXUNUSED(dc
),
791 int x
, int y
, int window_width
)
799 wxNode
*node
= m_items
.First();
802 wxListItemData
*item
= (wxListItemData
*)node
->Data();
803 if (item
->HasImage())
805 m_bound_icon
.x
= m_bound_all
.x
+ 4
806 + (m_spacing
- m_bound_icon
.width
)/2;
807 m_bound_icon
.y
= m_bound_all
.y
+ 4;
811 if (m_bound_all
.width
> m_spacing
)
812 m_bound_label
.x
= m_bound_all
.x
+ 2;
814 m_bound_label
.x
= m_bound_all
.x
+ 2 + (m_spacing
/2) - (m_bound_label
.width
/2);
815 m_bound_label
.y
= m_bound_all
.y
+ m_bound_all
.height
+ 2 - m_bound_label
.height
;
816 m_bound_hilight
.x
= m_bound_label
.x
- 2;
817 m_bound_hilight
.y
= m_bound_label
.y
- 2;
821 m_bound_hilight
.x
= m_bound_icon
.x
- 4;
822 m_bound_hilight
.y
= m_bound_icon
.y
- 4;
829 m_bound_hilight
.x
= m_bound_all
.x
;
830 m_bound_hilight
.y
= m_bound_all
.y
;
831 m_bound_label
.y
= m_bound_all
.y
+ 2;
832 wxNode
*node
= m_items
.First();
835 wxListItemData
*item
= (wxListItemData
*)node
->Data();
836 if (item
->HasImage())
838 m_bound_icon
.x
= m_bound_all
.x
+ 2;
839 m_bound_icon
.y
= m_bound_all
.y
+ 2;
840 m_bound_label
.x
= m_bound_all
.x
+ 6 + m_bound_icon
.width
;
844 m_bound_label
.x
= m_bound_all
.x
+ 2;
852 m_bound_all
.width
= window_width
;
853 AssignRect( m_bound_hilight
, m_bound_all
);
854 m_bound_label
.x
= m_bound_all
.x
+ 2;
855 m_bound_label
.y
= m_bound_all
.y
+ 2;
856 wxNode
*node
= m_items
.First();
859 wxListItemData
*item
= (wxListItemData
*)node
->Data();
860 if (item
->HasImage())
862 m_bound_icon
.x
= m_bound_all
.x
+ 2;
863 m_bound_icon
.y
= m_bound_all
.y
+ 2;
864 m_bound_label
.x
+= 4 + m_bound_icon
.width
;
872 void wxListLineData::SetColumnPosition( int index
, int x
)
874 wxNode
*node
= m_items
.Nth( (size_t)index
);
877 wxListItemData
*item
= (wxListItemData
*)node
->Data();
878 item
->SetPosition( x
, m_bound_all
.y
+1 );
882 void wxListLineData::GetSize( int &width
, int &height
)
884 width
= m_bound_all
.width
;
885 height
= m_bound_all
.height
;
888 void wxListLineData::GetExtent( int &x
, int &y
, int &width
, int &height
)
892 width
= m_bound_all
.width
;
893 height
= m_bound_all
.height
;
896 void wxListLineData::GetLabelExtent( int &x
, int &y
, int &width
, int &height
)
900 width
= m_bound_label
.width
;
901 height
= m_bound_label
.height
;
904 void wxListLineData::GetRect( wxRect
&rect
)
906 AssignRect( rect
, m_bound_all
);
909 long wxListLineData::IsHit( int x
, int y
)
911 wxNode
*node
= m_items
.First();
914 wxListItemData
*item
= (wxListItemData
*)node
->Data();
915 if (item
->HasImage() && IsInRect( x
, y
, m_bound_icon
)) return wxLIST_HITTEST_ONITEMICON
;
916 if (item
->HasText() && IsInRect( x
, y
, m_bound_label
)) return wxLIST_HITTEST_ONITEMLABEL
;
917 // if (!(item->HasImage() || item->HasText())) return 0;
919 // if there is no icon or text = empty
920 if (IsInRect( x
, y
, m_bound_all
)) return wxLIST_HITTEST_ONITEMICON
;
924 void wxListLineData::InitItems( int num
)
926 for (int i
= 0; i
< num
; i
++) m_items
.Append( new wxListItemData() );
929 void wxListLineData::SetItem( int index
, const wxListItem
&info
)
931 wxNode
*node
= m_items
.Nth( index
);
934 wxListItemData
*item
= (wxListItemData
*)node
->Data();
935 item
->SetItem( info
);
939 void wxListLineData::GetItem( int index
, wxListItem
&info
)
942 wxNode
*node
= m_items
.Nth( i
);
945 wxListItemData
*item
= (wxListItemData
*)node
->Data();
946 item
->GetItem( info
);
950 wxString
wxListLineData::GetText(int index
) const
954 wxNode
*node
= m_items
.Nth( index
);
957 wxListItemData
*item
= (wxListItemData
*)node
->Data();
964 void wxListLineData::SetText( int index
, const wxString s
)
967 wxNode
*node
= m_items
.Nth( i
);
970 wxListItemData
*item
= (wxListItemData
*)node
->Data();
975 int wxListLineData::GetImage( int index
)
978 wxNode
*node
= m_items
.Nth( i
);
981 wxListItemData
*item
= (wxListItemData
*)node
->Data();
982 return item
->GetImage();
987 void wxListLineData::SetAttributes(wxDC
*dc
,
988 const wxListItemAttr
*attr
,
989 const wxColour
& colText
,
993 // don't use foregroud colour for drawing highlighted items - this might
994 // make them completely invisible (and there is no way to do bit
995 // arithmetics on wxColour, unfortunately)
996 if ( !hilight
&& attr
&& attr
->HasTextColour() )
998 dc
->SetTextForeground(attr
->GetTextColour());
1002 dc
->SetTextForeground(colText
);
1005 if ( attr
&& attr
->HasFont() )
1007 dc
->SetFont(attr
->GetFont());
1015 void wxListLineData::DoDraw( wxDC
*dc
, bool hilight
, bool paintBG
)
1019 m_owner
->CalcScrolledPosition( m_bound_all
.x
, m_bound_all
.y
, &dev_x
, &dev_y
);
1020 wxCoord dev_w
= m_bound_all
.width
;
1021 wxCoord dev_h
= m_bound_all
.height
;
1023 if (!m_owner
->IsExposed( dev_x
, dev_y
, dev_w
, dev_h
))
1026 wxWindow
*listctrl
= m_owner
->GetParent();
1028 // default foreground colour
1032 colText
= wxSystemSettings::GetSystemColour( wxSYS_COLOUR_HIGHLIGHTTEXT
);
1036 colText
= listctrl
->GetForegroundColour();
1040 wxFont font
= listctrl
->GetFont();
1042 // VZ: currently we set the colours/fonts only once, but like this (i.e.
1043 // using SetAttributes() inside the loop), it will be trivial to
1044 // customize the subitems (in report mode) too.
1045 wxListItemData
*item
= (wxListItemData
*)m_items
.First()->Data();
1046 wxListItemAttr
*attr
= item
->GetAttributes();
1047 SetAttributes(dc
, attr
, colText
, font
, hilight
);
1049 bool hasBgCol
= attr
&& attr
->HasBackgroundColour();
1050 if ( paintBG
|| hasBgCol
)
1054 dc
->SetBrush( * m_hilightBrush
);
1059 dc
->SetBrush(wxBrush(attr
->GetBackgroundColour(), wxSOLID
));
1061 dc
->SetBrush( * wxWHITE_BRUSH
);
1064 dc
->SetPen( * wxTRANSPARENT_PEN
);
1065 dc
->DrawRectangle( m_bound_hilight
.x
, m_bound_hilight
.y
,
1066 m_bound_hilight
.width
, m_bound_hilight
.height
);
1069 if (m_mode
== wxLC_REPORT
)
1071 wxNode
*node
= m_items
.First();
1074 wxListItemData
*item
= (wxListItemData
*)node
->Data();
1075 int x
= item
->GetX();
1076 if (item
->HasImage())
1079 m_owner
->DrawImage( item
->GetImage(), dc
, x
, item
->GetY() );
1080 m_owner
->GetImageSize( item
->GetImage(), x
, y
);
1081 x
+= item
->GetX() + 5;
1083 dc
->SetClippingRegion( item
->GetX(), item
->GetY(), item
->GetWidth()-3, item
->GetHeight() );
1084 if (item
->HasText())
1086 dc
->DrawText( item
->GetText(), x
, item
->GetY()+1 );
1088 dc
->DestroyClippingRegion();
1089 node
= node
->Next();
1094 wxNode
*node
= m_items
.First();
1097 wxListItemData
*item
= (wxListItemData
*)node
->Data();
1098 if (item
->HasImage())
1100 m_owner
->DrawImage( item
->GetImage(), dc
, m_bound_icon
.x
, m_bound_icon
.y
);
1102 if (item
->HasText())
1104 dc
->DrawText( item
->GetText(), m_bound_label
.x
, m_bound_label
.y
);
1110 void wxListLineData::Hilight( bool on
)
1112 if (on
== m_hilighted
) return;
1115 m_owner
->SelectLine( this );
1117 m_owner
->DeselectLine( this );
1120 void wxListLineData::ReverseHilight( void )
1122 m_hilighted
= !m_hilighted
;
1124 m_owner
->SelectLine( this );
1126 m_owner
->DeselectLine( this );
1129 void wxListLineData::DrawRubberBand( wxDC
*dc
, bool on
)
1133 dc
->SetPen( * wxBLACK_PEN
);
1134 dc
->SetBrush( * wxTRANSPARENT_BRUSH
);
1135 dc
->DrawRectangle( m_bound_hilight
.x
, m_bound_hilight
.y
,
1136 m_bound_hilight
.width
, m_bound_hilight
.height
);
1140 void wxListLineData::Draw( wxDC
*dc
)
1142 DoDraw( dc
, m_hilighted
, m_hilighted
);
1145 bool wxListLineData::IsInRect( int x
, int y
, const wxRect
&rect
)
1147 return ((x
>= rect
.x
) && (x
<= rect
.x
+rect
.width
) &&
1148 (y
>= rect
.y
) && (y
<= rect
.y
+rect
.height
));
1151 bool wxListLineData::IsHilighted( void )
1156 void wxListLineData::AssignRect( wxRect
&dest
, int x
, int y
, int width
, int height
)
1161 dest
.height
= height
;
1164 void wxListLineData::AssignRect( wxRect
&dest
, const wxRect
&source
)
1168 dest
.width
= source
.width
;
1169 dest
.height
= source
.height
;
1172 //-----------------------------------------------------------------------------
1173 // wxListHeaderWindow
1174 //-----------------------------------------------------------------------------
1176 IMPLEMENT_DYNAMIC_CLASS(wxListHeaderWindow
,wxWindow
);
1178 BEGIN_EVENT_TABLE(wxListHeaderWindow
,wxWindow
)
1179 EVT_PAINT (wxListHeaderWindow::OnPaint
)
1180 EVT_MOUSE_EVENTS (wxListHeaderWindow::OnMouse
)
1181 EVT_SET_FOCUS (wxListHeaderWindow::OnSetFocus
)
1184 wxListHeaderWindow::wxListHeaderWindow( void )
1186 m_owner
= (wxListMainWindow
*) NULL
;
1187 m_currentCursor
= (wxCursor
*) NULL
;
1188 m_resizeCursor
= (wxCursor
*) NULL
;
1189 m_isDragging
= FALSE
;
1192 wxListHeaderWindow::wxListHeaderWindow( wxWindow
*win
, wxWindowID id
, wxListMainWindow
*owner
,
1193 const wxPoint
&pos
, const wxSize
&size
,
1194 long style
, const wxString
&name
) :
1195 wxWindow( win
, id
, pos
, size
, style
, name
)
1198 // m_currentCursor = wxSTANDARD_CURSOR;
1199 m_currentCursor
= (wxCursor
*) NULL
;
1200 m_resizeCursor
= new wxCursor( wxCURSOR_SIZEWE
);
1201 m_isDragging
= FALSE
;
1204 SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE
) );
1207 wxListHeaderWindow::~wxListHeaderWindow( void )
1209 delete m_resizeCursor
;
1212 void wxListHeaderWindow::DoDrawRect( wxDC
*dc
, int x
, int y
, int w
, int h
)
1215 GtkStateType state
= GTK_STATE_NORMAL
;
1216 if (!m_parent
->IsEnabled()) state
= GTK_STATE_INSENSITIVE
;
1218 x
= dc
->XLOG2DEV( x
);
1220 gtk_paint_box (m_wxwindow
->style
, GTK_PIZZA(m_wxwindow
)->bin_window
, state
, GTK_SHADOW_OUT
,
1221 (GdkRectangle
*) NULL
, m_wxwindow
, "button", x
-1, y
-1, w
+2, h
+2);
1223 const int m_corner
= 1;
1225 dc
->SetBrush( *wxTRANSPARENT_BRUSH
);
1227 dc
->SetPen( *wxBLACK_PEN
);
1228 dc
->DrawLine( x
+w
-m_corner
+1, y
, x
+w
, y
+h
); // right (outer)
1229 dc
->DrawRectangle( x
, y
+h
, w
+1, 1 ); // bottom (outer)
1231 wxPen
pen( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNSHADOW
), 1, wxSOLID
);
1234 dc
->DrawLine( x
+w
-m_corner
, y
, x
+w
-1, y
+h
); // right (inner)
1235 dc
->DrawRectangle( x
+1, y
+h
-1, w
-2, 1 ); // bottom (inner)
1237 dc
->SetPen( *wxWHITE_PEN
);
1238 dc
->DrawRectangle( x
, y
, w
-m_corner
+1, 1 ); // top (outer)
1239 dc
->DrawRectangle( x
, y
, 1, h
); // left (outer)
1240 dc
->DrawLine( x
, y
+h
-1, x
+1, y
+h
-1 );
1241 dc
->DrawLine( x
+w
-1, y
, x
+w
-1, y
+1 );
1245 // shift the DC origin to match the position of the main window horz
1246 // scrollbar: this allows us to always use logical coords
1247 void wxListHeaderWindow::AdjustDC(wxDC
& dc
)
1249 #if wxUSE_GENERIC_LIST_EXTENSIONS
1251 m_owner
->GetScrollPixelsPerUnit( &xpix
, NULL
);
1254 m_owner
->GetViewStart( &x
, NULL
);
1256 // account for the horz scrollbar offset
1257 dc
.SetDeviceOrigin( -x
* xpix
, 0 );
1258 #endif // wxUSE_GENERIC_LIST_EXTENSIONS
1261 void wxListHeaderWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
1264 wxClientDC
dc( this );
1266 wxPaintDC
dc( this );
1274 dc
.SetFont( GetFont() );
1276 // width and height of the entire header window
1278 GetClientSize( &w
, &h
);
1279 #if wxUSE_GENERIC_LIST_EXTENSIONS
1280 m_owner
->CalcUnscrolledPosition(w
, 0, &w
, NULL
);
1281 #endif // wxUSE_GENERIC_LIST_EXTENSIONS
1283 dc
.SetBackgroundMode(wxTRANSPARENT
);
1285 // do *not* use the listctrl colour for headers - one day we will have a
1286 // function to set it separately
1287 //dc.SetTextForeground( *wxBLACK );
1288 dc
.SetTextForeground(wxSystemSettings::GetSystemColour( wxSYS_COLOUR_WINDOWTEXT
));
1290 int x
= 1; // left of the header rect
1291 const int y
= 1; // top
1292 int numColumns
= m_owner
->GetColumnCount();
1294 for (int i
= 0; i
< numColumns
; i
++)
1296 m_owner
->GetColumn( i
, item
);
1297 int wCol
= item
.m_width
;
1298 int cw
= wCol
- 2; // the width of the rect to draw
1300 int xEnd
= x
+ wCol
;
1302 // VZ: no, draw it normally - this is better now as we allow resizing
1303 // of the last column as well
1305 // let the last column occupy all available space
1306 if ( i
== numColumns
- 1 )
1310 dc
.SetPen( *wxWHITE_PEN
);
1312 DoDrawRect( &dc
, x
, y
, cw
, h
-2 );
1313 dc
.SetClippingRegion( x
, y
, cw
-5, h
-4 );
1314 dc
.DrawText( item
.GetText(), x
+4, y
+3 );
1315 dc
.DestroyClippingRegion();
1324 void wxListHeaderWindow::DrawCurrent()
1326 int x1
= m_currentX
;
1328 ClientToScreen( &x1
, &y1
);
1330 int x2
= m_currentX
-1;
1332 m_owner
->GetClientSize( NULL
, &y2
);
1333 m_owner
->ClientToScreen( &x2
, &y2
);
1336 dc
.SetLogicalFunction( wxINVERT
);
1337 dc
.SetPen( wxPen( *wxBLACK
, 2, wxSOLID
) );
1338 dc
.SetBrush( *wxTRANSPARENT_BRUSH
);
1342 dc
.DrawLine( x1
, y1
, x2
, y2
);
1344 dc
.SetLogicalFunction( wxCOPY
);
1346 dc
.SetPen( wxNullPen
);
1347 dc
.SetBrush( wxNullBrush
);
1350 void wxListHeaderWindow::OnMouse( wxMouseEvent
&event
)
1352 // we want to work with logical coords
1353 #if wxUSE_GENERIC_LIST_EXTENSIONS
1355 m_owner
->CalcUnscrolledPosition(event
.GetX(), 0, &x
, NULL
);
1356 #else // !wxUSE_GENERIC_LIST_EXTENSIONS
1357 int x
= event
.GetX();
1358 #endif // wxUSE_GENERIC_LIST_EXTENSIONS
1359 int y
= event
.GetY();
1363 // we don't draw the line beyond our window, but we allow dragging it
1366 GetClientSize( &w
, NULL
);
1367 #if wxUSE_GENERIC_LIST_EXTENSIONS
1368 m_owner
->CalcUnscrolledPosition(w
, 0, &w
, NULL
);
1369 #endif // wxUSE_GENERIC_LIST_EXTENSIONS
1372 // erase the line if it was drawn
1373 if ( m_currentX
< w
)
1376 if (event
.ButtonUp())
1379 m_isDragging
= FALSE
;
1381 m_owner
->SetColumnWidth( m_column
, m_currentX
- m_minX
);
1388 m_currentX
= m_minX
+ 7;
1390 // draw in the new location
1391 if ( m_currentX
< w
)
1395 else // not dragging
1398 bool hit_border
= FALSE
;
1400 // end of the current column
1403 // find the column where this event occured
1404 int countCol
= m_owner
->GetColumnCount();
1405 for (int j
= 0; j
< countCol
; j
++)
1407 xpos
+= m_owner
->GetColumnWidth( j
);
1410 if ( (abs(x
-xpos
) < 3) && (y
< 22) )
1412 // near the column border
1419 // inside the column
1426 if (event
.LeftDown())
1430 m_isDragging
= TRUE
;
1437 wxWindow
*parent
= GetParent();
1438 wxListEvent
le( wxEVT_COMMAND_LIST_COL_CLICK
, parent
->GetId() );
1439 le
.SetEventObject( parent
);
1440 le
.m_col
= m_column
;
1441 parent
->GetEventHandler()->ProcessEvent( le
);
1444 else if (event
.Moving())
1449 setCursor
= m_currentCursor
== wxSTANDARD_CURSOR
;
1450 m_currentCursor
= m_resizeCursor
;
1454 setCursor
= m_currentCursor
!= wxSTANDARD_CURSOR
;
1455 m_currentCursor
= wxSTANDARD_CURSOR
;
1459 SetCursor(*m_currentCursor
);
1464 void wxListHeaderWindow::OnSetFocus( wxFocusEvent
&WXUNUSED(event
) )
1466 m_owner
->SetFocus();
1469 //-----------------------------------------------------------------------------
1470 // wxListRenameTimer (internal)
1471 //-----------------------------------------------------------------------------
1473 wxListRenameTimer::wxListRenameTimer( wxListMainWindow
*owner
)
1478 void wxListRenameTimer::Notify()
1480 m_owner
->OnRenameTimer();
1483 //-----------------------------------------------------------------------------
1484 // wxListTextCtrl (internal)
1485 //-----------------------------------------------------------------------------
1487 IMPLEMENT_DYNAMIC_CLASS(wxListTextCtrl
,wxTextCtrl
);
1489 BEGIN_EVENT_TABLE(wxListTextCtrl
,wxTextCtrl
)
1490 EVT_CHAR (wxListTextCtrl::OnChar
)
1491 EVT_KEY_UP (wxListTextCtrl::OnKeyUp
)
1492 EVT_KILL_FOCUS (wxListTextCtrl::OnKillFocus
)
1495 wxListTextCtrl::wxListTextCtrl( wxWindow
*parent
,
1496 const wxWindowID id
,
1499 wxListMainWindow
*owner
,
1500 const wxString
&value
,
1504 const wxValidator
& validator
,
1505 const wxString
&name
)
1506 : wxTextCtrl( parent
, id
, value
, pos
, size
, style
, validator
, name
)
1511 (*m_accept
) = FALSE
;
1513 m_startValue
= value
;
1516 void wxListTextCtrl::OnChar( wxKeyEvent
&event
)
1518 if (event
.m_keyCode
== WXK_RETURN
)
1521 (*m_res
) = GetValue();
1523 if (!wxPendingDelete
.Member(this))
1524 wxPendingDelete
.Append(this);
1526 if ((*m_accept
) && ((*m_res
) != m_startValue
))
1527 m_owner
->OnRenameAccept();
1531 if (event
.m_keyCode
== WXK_ESCAPE
)
1533 (*m_accept
) = FALSE
;
1536 if (!wxPendingDelete
.Member(this))
1537 wxPendingDelete
.Append(this);
1545 void wxListTextCtrl::OnKeyUp( wxKeyEvent
&event
)
1547 // auto-grow the textctrl:
1548 wxSize parentSize
= m_owner
->GetSize();
1549 wxPoint myPos
= GetPosition();
1550 wxSize mySize
= GetSize();
1552 GetTextExtent(GetValue() + _T("MM"), &sx
, &sy
);
1553 if (myPos
.x
+ sx
> parentSize
.x
) sx
= parentSize
.x
- myPos
.x
;
1554 if (mySize
.x
> sx
) sx
= mySize
.x
;
1560 void wxListTextCtrl::OnKillFocus( wxFocusEvent
&WXUNUSED(event
) )
1562 if (!wxPendingDelete
.Member(this))
1563 wxPendingDelete
.Append(this);
1565 if ((*m_accept
) && ((*m_res
) != m_startValue
))
1566 m_owner
->OnRenameAccept();
1569 //-----------------------------------------------------------------------------
1571 //-----------------------------------------------------------------------------
1573 IMPLEMENT_DYNAMIC_CLASS(wxListMainWindow
,wxScrolledWindow
);
1575 BEGIN_EVENT_TABLE(wxListMainWindow
,wxScrolledWindow
)
1576 EVT_PAINT (wxListMainWindow::OnPaint
)
1577 EVT_SIZE (wxListMainWindow::OnSize
)
1578 EVT_MOUSE_EVENTS (wxListMainWindow::OnMouse
)
1579 EVT_CHAR (wxListMainWindow::OnChar
)
1580 EVT_KEY_DOWN (wxListMainWindow::OnKeyDown
)
1581 EVT_SET_FOCUS (wxListMainWindow::OnSetFocus
)
1582 EVT_KILL_FOCUS (wxListMainWindow::OnKillFocus
)
1583 EVT_SCROLLWIN (wxListMainWindow::OnScroll
)
1586 wxListMainWindow::wxListMainWindow()
1589 m_columns
.DeleteContents( TRUE
);
1590 m_current
= (wxListLineData
*) NULL
;
1592 m_hilightBrush
= (wxBrush
*) NULL
;
1596 m_small_image_list
= (wxImageList
*) NULL
;
1597 m_normal_image_list
= (wxImageList
*) NULL
;
1598 m_small_spacing
= 30;
1599 m_normal_spacing
= 40;
1602 m_lastOnSame
= FALSE
;
1603 m_renameTimer
= new wxListRenameTimer( this );
1604 m_isCreated
= FALSE
;
1608 m_lineBeforeLastClicked
= (wxListLineData
*)NULL
;
1611 wxListMainWindow::wxListMainWindow( wxWindow
*parent
, wxWindowID id
,
1612 const wxPoint
&pos
, const wxSize
&size
,
1613 long style
, const wxString
&name
) :
1614 wxScrolledWindow( parent
, id
, pos
, size
, style
|wxHSCROLL
|wxVSCROLL
, name
)
1617 m_columns
.DeleteContents( TRUE
);
1618 m_current
= (wxListLineData
*) NULL
;
1621 m_hilightBrush
= new wxBrush( wxSystemSettings::GetSystemColour(wxSYS_COLOUR_HIGHLIGHT
), wxSOLID
);
1622 m_small_image_list
= (wxImageList
*) NULL
;
1623 m_normal_image_list
= (wxImageList
*) NULL
;
1624 m_small_spacing
= 30;
1625 m_normal_spacing
= 40;
1628 m_isCreated
= FALSE
;
1632 if (m_mode
& wxLC_REPORT
)
1634 #if wxUSE_GENERIC_LIST_EXTENSIONS
1646 SetScrollbars( m_xScroll
, m_yScroll
, 0, 0, 0, 0 );
1649 m_lastOnSame
= FALSE
;
1650 m_renameTimer
= new wxListRenameTimer( this );
1651 m_renameAccept
= FALSE
;
1653 SetBackgroundColour( wxSystemSettings::GetSystemColour( wxSYS_COLOUR_LISTBOX
) );
1656 wxListMainWindow::~wxListMainWindow()
1660 if (m_hilightBrush
) delete m_hilightBrush
;
1662 delete m_renameTimer
;
1665 void wxListMainWindow::RefreshLine( wxListLineData
*line
)
1667 if (m_dirty
) return;
1675 line
->GetExtent( x
, y
, w
, h
);
1676 CalcScrolledPosition( x
, y
, &x
, &y
);
1677 wxRect
rect( x
, y
, w
, h
);
1678 Refresh( TRUE
, &rect
);
1681 void wxListMainWindow::OnPaint( wxPaintEvent
&WXUNUSED(event
) )
1683 // Note: a wxPaintDC must be constructed even if no drawing is
1684 // done (a Windows requirement).
1685 wxPaintDC
dc( this );
1690 CalcScrolledPosition( 0, 0, &dev_x
, &dev_y
);
1692 if (m_dirty
) return;
1694 if (m_lines
.GetCount() == 0) return;
1698 dc
.SetFont( GetFont() );
1700 if (m_mode
& wxLC_REPORT
)
1702 wxPen
pen(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_3DLIGHT
), 1, wxSOLID
);
1703 wxSize clientSize
= GetClientSize();
1705 int lineSpacing
= 0;
1706 wxListLineData
*line
= &m_lines
[0];
1708 line
->GetSize( dummy
, lineSpacing
);
1711 int y_s
= m_yScroll
*GetScrollPos( wxVERTICAL
);
1713 size_t i_to
= y_s
/ lineSpacing
+ m_visibleLines
+2;
1714 if (i_to
>= m_lines
.GetCount()) i_to
= m_lines
.GetCount();
1716 for (i
= y_s
/ lineSpacing
; i
< i_to
; i
++)
1718 m_lines
[i
].Draw( &dc
);
1719 // Draw horizontal rule if required
1720 if (GetWindowStyle() & wxLC_HRULES
)
1723 dc
.SetBrush(* wxTRANSPARENT_BRUSH
);
1724 dc
.DrawLine(0 - dev_x
, i
*lineSpacing
, clientSize
.x
- dev_x
, i
*lineSpacing
);
1728 // Draw last horizontal rule
1729 if ((i
> (size_t) (y_s
/ lineSpacing
)) && (GetWindowStyle() & wxLC_HRULES
))
1732 dc
.SetBrush(* wxTRANSPARENT_BRUSH
);
1733 dc
.DrawLine(0 - dev_x
, i
*lineSpacing
, clientSize
.x
- dev_x
, i
*lineSpacing
);
1736 // Draw vertical rules if required
1737 if ((GetWindowStyle() & wxLC_VRULES
) && (GetItemCount() > 0))
1740 wxRect firstItemRect
;
1741 wxRect lastItemRect
;
1742 GetItemRect(0, firstItemRect
);
1743 GetItemRect(GetItemCount() - 1, lastItemRect
);
1744 int x
= firstItemRect
.GetX();
1746 dc
.SetBrush(* wxTRANSPARENT_BRUSH
);
1747 for (col
= 0; col
< GetColumnCount(); col
++)
1749 int colWidth
= GetColumnWidth(col
);
1751 dc
.DrawLine(x
- dev_x
, firstItemRect
.GetY() - 1 - dev_y
, x
- dev_x
, lastItemRect
.GetBottom() + 1 - dev_y
);
1757 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
1758 m_lines
[i
].Draw( &dc
);
1761 if (m_current
) m_current
->DrawRubberBand( &dc
, m_hasFocus
);
1766 void wxListMainWindow::HilightAll( bool on
)
1768 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
1770 wxListLineData
*line
= &m_lines
[i
];
1771 if (line
->IsHilighted() != on
)
1773 line
->Hilight( on
);
1774 RefreshLine( line
);
1779 void wxListMainWindow::SendNotify( wxListLineData
*line
,
1780 wxEventType command
,
1783 wxListEvent
le( command
, GetParent()->GetId() );
1784 le
.SetEventObject( GetParent() );
1785 le
.m_itemIndex
= GetIndexOfLine( line
);
1787 // set only for events which have position
1788 if ( point
!= wxDefaultPosition
)
1789 le
.m_pointDrag
= point
;
1791 line
->GetItem( 0, le
.m_item
);
1792 GetParent()->GetEventHandler()->ProcessEvent( le
);
1793 // GetParent()->GetEventHandler()->AddPendingEvent( le );
1796 void wxListMainWindow::FocusLine( wxListLineData
*WXUNUSED(line
) )
1798 // SendNotify( line, wxEVT_COMMAND_LIST_ITEM_FOCUSSED );
1801 void wxListMainWindow::UnfocusLine( wxListLineData
*WXUNUSED(line
) )
1803 // SendNotify( line, wxEVT_COMMAND_LIST_ITEM_UNFOCUSSED );
1806 void wxListMainWindow::SelectLine( wxListLineData
*line
)
1808 SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_SELECTED
);
1811 void wxListMainWindow::DeselectLine( wxListLineData
*line
)
1813 SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_DESELECTED
);
1816 void wxListMainWindow::DeleteLine( wxListLineData
*line
)
1818 SendNotify( line
, wxEVT_COMMAND_LIST_DELETE_ITEM
);
1823 void wxListMainWindow::EditLabel( long item
)
1825 wxCHECK_RET( ((size_t)item
< m_lines
.GetCount()),
1826 wxT("wrong index in wxListCtrl::Edit()") );
1828 m_currentEdit
= &m_lines
[(size_t)item
];
1830 wxListEvent
le( wxEVT_COMMAND_LIST_BEGIN_LABEL_EDIT
, GetParent()->GetId() );
1831 le
.SetEventObject( GetParent() );
1832 le
.m_itemIndex
= GetIndexOfLine( m_currentEdit
);
1833 m_currentEdit
->GetItem( 0, le
.m_item
);
1834 GetParent()->GetEventHandler()->ProcessEvent( le
);
1836 if (!le
.IsAllowed())
1839 // We have to call this here because the label in
1840 // question might just have been added and no screen
1841 // update taken place.
1842 if (m_dirty
) wxYield();
1844 wxString s
= m_currentEdit
->GetText(0);
1849 m_currentEdit
->GetLabelExtent( x
, y
, w
, h
);
1851 wxClientDC
dc(this);
1853 x
= dc
.LogicalToDeviceX( x
);
1854 y
= dc
.LogicalToDeviceY( y
);
1856 wxListTextCtrl
*text
= new wxListTextCtrl(
1857 this, -1, &m_renameAccept
, &m_renameRes
, this, s
, wxPoint(x
-4,y
-4), wxSize(w
+11,h
+8) );
1861 void wxListMainWindow::OnRenameTimer()
1863 wxCHECK_RET( m_current
, wxT("invalid m_current") );
1865 Edit( m_lines
.Index( *m_current
) );
1868 void wxListMainWindow::OnRenameAccept()
1870 wxListEvent
le( wxEVT_COMMAND_LIST_END_LABEL_EDIT
, GetParent()->GetId() );
1871 le
.SetEventObject( GetParent() );
1872 le
.m_itemIndex
= GetIndexOfLine( m_currentEdit
);
1873 m_currentEdit
->GetItem( 0, le
.m_item
);
1874 le
.m_item
.m_text
= m_renameRes
;
1875 GetParent()->GetEventHandler()->ProcessEvent( le
);
1877 if (!le
.IsAllowed()) return;
1880 info
.m_mask
= wxLIST_MASK_TEXT
;
1881 info
.m_itemId
= le
.m_itemIndex
;
1882 info
.m_text
= m_renameRes
;
1883 info
.SetTextColour(le
.m_item
.GetTextColour());
1887 void wxListMainWindow::OnMouse( wxMouseEvent
&event
)
1889 event
.SetEventObject( GetParent() );
1890 if (GetParent()->GetEventHandler()->ProcessEvent( event
)) return;
1892 if (!m_current
) return;
1893 if (m_dirty
) return;
1894 if ( !(event
.Dragging() || event
.ButtonDown() || event
.LeftUp() || event
.ButtonDClick()) ) return;
1896 int x
= event
.GetX();
1897 int y
= event
.GetY();
1898 CalcUnscrolledPosition( x
, y
, &x
, &y
);
1900 /* Did we actually hit an item ? */
1902 wxListLineData
*line
= (wxListLineData
*) NULL
;
1903 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
1906 hitResult
= line
->IsHit( x
, y
);
1907 if (hitResult
) break;
1908 line
= (wxListLineData
*) NULL
;
1911 if (event
.Dragging())
1913 if (m_dragCount
== 0)
1914 m_dragStart
= wxPoint(x
,y
);
1918 if (m_dragCount
!= 3) return;
1920 int command
= event
.RightIsDown() ? wxEVT_COMMAND_LIST_BEGIN_RDRAG
1921 : wxEVT_COMMAND_LIST_BEGIN_DRAG
;
1923 wxListEvent
le( command
, GetParent()->GetId() );
1924 le
.SetEventObject( GetParent() );
1925 le
.m_pointDrag
= m_dragStart
;
1926 GetParent()->GetEventHandler()->ProcessEvent( le
);
1937 bool forceClick
= FALSE
;
1938 if (event
.ButtonDClick())
1940 m_renameTimer
->Stop();
1941 m_lastOnSame
= FALSE
;
1943 if ( line
== m_lineBeforeLastClicked
)
1947 SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_ACTIVATED
);
1953 // the first click was on another item, so don't interpret this as
1954 // a double click, but as a simple click instead
1959 if (event
.LeftUp() && m_lastOnSame
)
1962 if ((line
== m_current
) &&
1963 (hitResult
== wxLIST_HITTEST_ONITEMLABEL
) &&
1964 (m_mode
& wxLC_EDIT_LABELS
) )
1966 m_renameTimer
->Start( 100, TRUE
);
1968 m_lastOnSame
= FALSE
;
1972 if (event
.RightDown())
1974 SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_RIGHT_CLICK
,
1975 event
.GetPosition() );
1979 if (event
.MiddleDown())
1981 SendNotify( line
, wxEVT_COMMAND_LIST_ITEM_MIDDLE_CLICK
);
1985 if ( event
.LeftDown() || forceClick
)
1987 m_lineBeforeLastClicked
= m_lineLastClicked
;
1988 m_lineLastClicked
= line
;
1991 wxListLineData
*oldCurrent
= m_current
;
1992 if (m_mode
& wxLC_SINGLE_SEL
)
1995 HilightAll( FALSE
);
1996 m_current
->ReverseHilight();
1997 RefreshLine( m_current
);
2001 if (event
.ControlDown())
2004 m_current
->ReverseHilight();
2005 RefreshLine( m_current
);
2007 else if (event
.ShiftDown())
2013 int numOfCurrent
= -1;
2014 for (j
= 0; j
< m_lines
.GetCount(); j
++)
2016 wxListLineData
*test_line
= &m_lines
[j
];
2018 if (test_line
== oldCurrent
) break;
2023 for (j
= 0; j
< m_lines
.GetCount(); j
++)
2025 wxListLineData
*test_line
= &m_lines
[j
];
2027 if (test_line
== line
) break;
2030 if (numOfLine
< numOfCurrent
)
2033 numOfLine
= numOfCurrent
;
2037 for (int i
= 0; i
<= numOfLine
-numOfCurrent
; i
++)
2039 wxListLineData
*test_line
= &m_lines
[numOfCurrent
+ i
];
2040 test_line
->Hilight(TRUE
);
2041 RefreshLine( test_line
);
2047 HilightAll( FALSE
);
2048 m_current
->ReverseHilight();
2049 RefreshLine( m_current
);
2052 if (m_current
!= oldCurrent
)
2054 RefreshLine( oldCurrent
);
2055 UnfocusLine( oldCurrent
);
2056 FocusLine( m_current
);
2059 // forceClick is only set if the previous click was on another item
2060 m_lastOnSame
= !forceClick
&& (m_current
== oldCurrent
);
2066 void wxListMainWindow::MoveToFocus()
2068 if (!m_current
) return;
2074 m_current
->GetExtent( item_x
, item_y
, item_w
, item_h
);
2078 GetClientSize( &client_w
, &client_h
);
2080 int view_x
= m_xScroll
*GetScrollPos( wxHORIZONTAL
);
2081 int view_y
= m_yScroll
*GetScrollPos( wxVERTICAL
);
2083 if (m_mode
& wxLC_REPORT
)
2085 if (item_y
< view_y
)
2086 Scroll( -1, (item_y
)/m_yScroll
);
2087 if (item_y
+item_h
+5 > view_y
+client_h
)
2088 Scroll( -1, (item_y
+item_h
-client_h
+15)/m_yScroll
);
2092 if (item_x
-view_x
< 5)
2093 Scroll( (item_x
-5)/m_xScroll
, -1 );
2094 if (item_x
+item_w
-5 > view_x
+client_w
)
2095 Scroll( (item_x
+item_w
-client_w
+15)/m_xScroll
, -1 );
2099 void wxListMainWindow::OnArrowChar( wxListLineData
*newCurrent
, bool shiftDown
)
2101 if ((m_mode
& wxLC_SINGLE_SEL
) || (m_usedKeys
== FALSE
)) m_current
->Hilight( FALSE
);
2102 wxListLineData
*oldCurrent
= m_current
;
2103 m_current
= newCurrent
;
2104 if (shiftDown
|| (m_mode
& wxLC_SINGLE_SEL
)) m_current
->Hilight( TRUE
);
2105 RefreshLine( m_current
);
2106 RefreshLine( oldCurrent
);
2107 FocusLine( m_current
);
2108 UnfocusLine( oldCurrent
);
2112 void wxListMainWindow::OnKeyDown( wxKeyEvent
&event
)
2114 wxWindow
*parent
= GetParent();
2116 /* we propagate the key event up */
2117 wxKeyEvent
ke( wxEVT_KEY_DOWN
);
2118 ke
.m_shiftDown
= event
.m_shiftDown
;
2119 ke
.m_controlDown
= event
.m_controlDown
;
2120 ke
.m_altDown
= event
.m_altDown
;
2121 ke
.m_metaDown
= event
.m_metaDown
;
2122 ke
.m_keyCode
= event
.m_keyCode
;
2125 ke
.SetEventObject( parent
);
2126 if (parent
->GetEventHandler()->ProcessEvent( ke
)) return;
2131 void wxListMainWindow::OnChar( wxKeyEvent
&event
)
2133 wxWindow
*parent
= GetParent();
2135 /* we send a list_key event up */
2138 wxListEvent
le( wxEVT_COMMAND_LIST_KEY_DOWN
, GetParent()->GetId() );
2139 le
.m_itemIndex
= GetIndexOfLine( m_current
);
2140 m_current
->GetItem( 0, le
.m_item
);
2141 le
.m_code
= (int)event
.KeyCode();
2142 le
.SetEventObject( parent
);
2143 parent
->GetEventHandler()->ProcessEvent( le
);
2146 /* we propagate the char event up */
2147 wxKeyEvent
ke( wxEVT_CHAR
);
2148 ke
.m_shiftDown
= event
.m_shiftDown
;
2149 ke
.m_controlDown
= event
.m_controlDown
;
2150 ke
.m_altDown
= event
.m_altDown
;
2151 ke
.m_metaDown
= event
.m_metaDown
;
2152 ke
.m_keyCode
= event
.m_keyCode
;
2155 ke
.SetEventObject( parent
);
2156 if (parent
->GetEventHandler()->ProcessEvent( ke
)) return;
2158 if (event
.KeyCode() == WXK_TAB
)
2160 wxNavigationKeyEvent nevent
;
2161 nevent
.SetWindowChange( event
.ControlDown() );
2162 nevent
.SetDirection( !event
.ShiftDown() );
2163 nevent
.SetEventObject( GetParent()->GetParent() );
2164 nevent
.SetCurrentFocus( m_parent
);
2165 if (GetParent()->GetParent()->GetEventHandler()->ProcessEvent( nevent
)) return;
2168 /* no item -> nothing to do */
2175 switch (event
.KeyCode())
2179 int index
= m_lines
.Index(*m_current
);
2180 if (index
!= wxNOT_FOUND
&& index
> 0)
2181 OnArrowChar( &m_lines
[index
-1], event
.ShiftDown() );
2186 int index
= m_lines
.Index(*m_current
);
2187 if (index
!= wxNOT_FOUND
&& (size_t)index
< m_lines
.GetCount()-1)
2188 OnArrowChar( &m_lines
[index
+1], event
.ShiftDown() );
2193 if (!m_lines
.IsEmpty())
2194 OnArrowChar( &m_lines
.Last(), event
.ShiftDown() );
2199 if (!m_lines
.IsEmpty())
2200 OnArrowChar( &m_lines
[0], event
.ShiftDown() );
2206 int index
= m_lines
.Index(*m_current
);
2207 if (m_mode
& wxLC_REPORT
)
2209 steps
= m_visibleLines
-1;
2213 steps
= index
% m_visibleLines
;
2215 if (index
!= wxNOT_FOUND
)
2218 if (index
< 0) index
= 0;
2219 OnArrowChar( &m_lines
[index
], event
.ShiftDown() );
2226 int index
= m_lines
.Index(*m_current
);
2227 if (m_mode
& wxLC_REPORT
)
2229 steps
= m_visibleLines
-1;
2233 steps
= m_visibleLines
-(index
% m_visibleLines
)-1;
2236 if (index
!= wxNOT_FOUND
)
2239 if ((size_t)index
>= m_lines
.GetCount())
2240 index
= m_lines
.GetCount()-1;
2241 OnArrowChar( &m_lines
[index
], event
.ShiftDown() );
2247 if (!(m_mode
& wxLC_REPORT
))
2249 int index
= m_lines
.Index(*m_current
);
2250 if (index
!= wxNOT_FOUND
)
2252 index
-= m_visibleLines
;
2253 if (index
< 0) index
= 0;
2254 OnArrowChar( &m_lines
[index
], event
.ShiftDown() );
2261 if (!(m_mode
& wxLC_REPORT
))
2263 int index
= m_lines
.Index(*m_current
);
2264 if (index
!= wxNOT_FOUND
)
2266 index
+= m_visibleLines
;
2267 if ((size_t)index
>= m_lines
.GetCount())
2268 index
= m_lines
.GetCount()-1;
2269 OnArrowChar( &m_lines
[index
], event
.ShiftDown() );
2276 if (m_mode
& wxLC_SINGLE_SEL
)
2278 wxListEvent
le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED
, GetParent()->GetId() );
2279 le
.SetEventObject( GetParent() );
2280 le
.m_itemIndex
= GetIndexOfLine( m_current
);
2281 m_current
->GetItem( 0, le
.m_item
);
2282 GetParent()->GetEventHandler()->ProcessEvent( le
);
2286 m_current
->ReverseHilight();
2287 RefreshLine( m_current
);
2293 if (!(m_mode
& wxLC_SINGLE_SEL
))
2295 wxListLineData
*oldCurrent
= m_current
;
2296 m_current
->ReverseHilight();
2297 int index
= m_lines
.Index( *m_current
) + 1;
2298 if ( (size_t)index
< m_lines
.GetCount() )
2299 m_current
= &m_lines
[index
];
2300 RefreshLine( oldCurrent
);
2301 RefreshLine( m_current
);
2302 UnfocusLine( oldCurrent
);
2303 FocusLine( m_current
);
2311 wxListEvent
le( wxEVT_COMMAND_LIST_ITEM_ACTIVATED
, GetParent()->GetId() );
2312 le
.SetEventObject( GetParent() );
2313 le
.m_itemIndex
= GetIndexOfLine( m_current
);
2314 m_current
->GetItem( 0, le
.m_item
);
2315 GetParent()->GetEventHandler()->ProcessEvent( le
);
2328 extern wxWindow
*g_focusWindow
;
2331 void wxListMainWindow::OnSetFocus( wxFocusEvent
&WXUNUSED(event
) )
2334 RefreshLine( m_current
);
2336 if (!GetParent()) return;
2339 g_focusWindow
= GetParent();
2342 wxFocusEvent
event( wxEVT_SET_FOCUS
, GetParent()->GetId() );
2343 event
.SetEventObject( GetParent() );
2344 GetParent()->GetEventHandler()->ProcessEvent( event
);
2347 void wxListMainWindow::OnKillFocus( wxFocusEvent
&WXUNUSED(event
) )
2350 RefreshLine( m_current
);
2353 void wxListMainWindow::OnSize( wxSizeEvent
&WXUNUSED(event
) )
2356 We don't even allow the wxScrolledWindow::AdjustScrollbars() call
2362 void wxListMainWindow::DrawImage( int index
, wxDC
*dc
, int x
, int y
)
2364 if ((m_mode
& wxLC_ICON
) && (m_normal_image_list
))
2366 m_normal_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT
);
2369 if ((m_mode
& wxLC_SMALL_ICON
) && (m_small_image_list
))
2371 m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT
);
2373 if ((m_mode
& wxLC_LIST
) && (m_small_image_list
))
2375 m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT
);
2377 if ((m_mode
& wxLC_REPORT
) && (m_small_image_list
))
2379 m_small_image_list
->Draw( index
, *dc
, x
, y
, wxIMAGELIST_DRAW_TRANSPARENT
);
2384 void wxListMainWindow::GetImageSize( int index
, int &width
, int &height
)
2386 if ((m_mode
& wxLC_ICON
) && (m_normal_image_list
))
2388 m_normal_image_list
->GetSize( index
, width
, height
);
2391 if ((m_mode
& wxLC_SMALL_ICON
) && (m_small_image_list
))
2393 m_small_image_list
->GetSize( index
, width
, height
);
2396 if ((m_mode
& wxLC_LIST
) && (m_small_image_list
))
2398 m_small_image_list
->GetSize( index
, width
, height
);
2401 if ((m_mode
& wxLC_REPORT
) && (m_small_image_list
))
2403 m_small_image_list
->GetSize( index
, width
, height
);
2410 int wxListMainWindow::GetTextLength( wxString
&s
)
2412 wxClientDC
dc( this );
2415 dc
.GetTextExtent( s
, &lw
, &lh
);
2419 int wxListMainWindow::GetIndexOfLine( const wxListLineData
*line
)
2421 int i
= m_lines
.Index(*line
);
2422 if (i
== wxNOT_FOUND
) return -1;
2426 void wxListMainWindow::SetImageList( wxImageList
*imageList
, int which
)
2430 // calc the spacing from the icon size
2433 if ((imageList
) && (imageList
->GetImageCount()) )
2435 imageList
->GetSize(0, width
, height
);
2438 if (which
== wxIMAGE_LIST_NORMAL
)
2440 m_normal_image_list
= imageList
;
2441 m_normal_spacing
= width
+ 8;
2444 if (which
== wxIMAGE_LIST_SMALL
)
2446 m_small_image_list
= imageList
;
2447 m_small_spacing
= width
+ 14;
2451 void wxListMainWindow::SetItemSpacing( int spacing
, bool isSmall
)
2456 m_small_spacing
= spacing
;
2460 m_normal_spacing
= spacing
;
2464 int wxListMainWindow::GetItemSpacing( bool isSmall
)
2466 return isSmall
? m_small_spacing
: m_normal_spacing
;
2469 void wxListMainWindow::SetColumn( int col
, wxListItem
&item
)
2472 wxNode
*node
= m_columns
.Nth( col
);
2475 if (item
.m_width
== wxLIST_AUTOSIZE_USEHEADER
)
2476 item
.m_width
= GetTextLength( item
.m_text
)+7;
2477 wxListHeaderData
*column
= (wxListHeaderData
*)node
->Data();
2478 column
->SetItem( item
);
2481 wxListHeaderWindow
*headerWin
= ((wxListCtrl
*) GetParent())->m_headerWin
;
2483 headerWin
->m_dirty
= TRUE
;
2486 void wxListMainWindow::SetColumnWidth( int col
, int width
)
2488 wxCHECK_RET( m_mode
& wxLC_REPORT
,
2489 _T("SetColumnWidth() can only be called in report mode.") );
2493 wxNode
*node
= (wxNode
*) NULL
;
2495 if (width
== wxLIST_AUTOSIZE_USEHEADER
)
2497 // TODO do use the header
2500 else if (width
== wxLIST_AUTOSIZE
)
2502 wxClientDC
dc(this);
2503 dc
.SetFont( GetFont() );
2506 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
2508 wxListLineData
*line
= &m_lines
[i
];
2509 wxNode
*n
= line
->m_items
.Nth( col
);
2512 wxListItemData
*item
= (wxListItemData
*)n
->Data();
2513 int current
= 0, ix
= 0, iy
= 0;
2514 wxCoord lx
= 0, ly
= 0;
2515 if (item
->HasImage())
2517 GetImageSize( item
->GetImage(), ix
, iy
);
2520 if (item
->HasText())
2522 wxString str
= item
->GetText();
2523 dc
.GetTextExtent( str
, &lx
, &ly
);
2526 if (current
> max
) max
= current
;
2532 node
= m_columns
.Nth( col
);
2535 wxListHeaderData
*column
= (wxListHeaderData
*)node
->Data();
2536 column
->SetWidth( width
);
2539 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
2541 wxListLineData
*line
= &m_lines
[i
];
2542 wxNode
*n
= line
->m_items
.Nth( col
);
2545 wxListItemData
*item
= (wxListItemData
*)n
->Data();
2546 item
->SetSize( width
, -1 );
2550 wxListHeaderWindow
*headerWin
= ((wxListCtrl
*) GetParent())->m_headerWin
;
2552 headerWin
->m_dirty
= TRUE
;
2555 void wxListMainWindow::GetColumn( int col
, wxListItem
&item
)
2557 wxNode
*node
= m_columns
.Nth( col
);
2560 wxListHeaderData
*column
= (wxListHeaderData
*)node
->Data();
2561 column
->GetItem( item
);
2567 item
.m_text
= _T("");
2573 int wxListMainWindow::GetColumnWidth( int col
)
2575 wxNode
*node
= m_columns
.Nth( col
);
2578 wxListHeaderData
*column
= (wxListHeaderData
*)node
->Data();
2579 return column
->GetWidth();
2587 int wxListMainWindow::GetColumnCount()
2589 return m_columns
.Number();
2592 int wxListMainWindow::GetCountPerPage()
2594 return m_visibleLines
;
2597 void wxListMainWindow::SetItem( wxListItem
&item
)
2600 if (item
.m_itemId
>= 0 && (size_t)item
.m_itemId
< m_lines
.GetCount())
2602 wxListLineData
*line
= &m_lines
[(size_t)item
.m_itemId
];
2603 if (m_mode
& wxLC_REPORT
) item
.m_width
= GetColumnWidth( item
.m_col
)-3;
2604 line
->SetItem( item
.m_col
, item
);
2608 void wxListMainWindow::SetItemState( long item
, long state
, long stateMask
)
2610 wxCHECK_RET( item
>= 0 && (size_t)item
< m_lines
.GetCount(),
2611 _T("invalid list ctrl item index in SetItem") );
2613 // m_dirty = TRUE; no recalcs needed
2615 wxListLineData
*oldCurrent
= m_current
;
2617 if ( stateMask
& wxLIST_STATE_FOCUSED
)
2619 wxListLineData
*line
= &m_lines
[(size_t)item
];
2620 if ( state
& wxLIST_STATE_FOCUSED
)
2622 // don't do anything if this item is already focused
2623 if ( line
!= m_current
)
2625 UnfocusLine( m_current
);
2627 FocusLine( m_current
);
2628 if ( (m_mode
& wxLC_SINGLE_SEL
) && oldCurrent
)
2629 oldCurrent
->Hilight( FALSE
);
2631 RefreshLine( m_current
);
2633 RefreshLine( oldCurrent
);
2638 // don't do anything if this item is not focused
2639 if ( line
== m_current
)
2641 UnfocusLine( m_current
);
2647 if ( stateMask
& wxLIST_STATE_SELECTED
)
2649 bool on
= (state
& wxLIST_STATE_SELECTED
) != 0;
2650 if (!on
&& (m_mode
& wxLC_SINGLE_SEL
))
2653 wxListLineData
*line
= &m_lines
[(size_t)item
];
2654 if (m_mode
& wxLC_SINGLE_SEL
)
2656 UnfocusLine( m_current
);
2658 FocusLine( m_current
);
2660 oldCurrent
->Hilight( FALSE
);
2661 RefreshLine( m_current
);
2663 RefreshLine( oldCurrent
);
2666 if (on
!= line
->IsHilighted())
2668 line
->Hilight( on
);
2669 RefreshLine( line
);
2674 int wxListMainWindow::GetItemState( long item
, long stateMask
)
2676 int ret
= wxLIST_STATE_DONTCARE
;
2677 if (stateMask
& wxLIST_STATE_FOCUSED
)
2679 if (item
>= 0 && (size_t)item
< m_lines
.GetCount())
2681 wxListLineData
*line
= &m_lines
[(size_t)item
];
2682 if (line
== m_current
) ret
|= wxLIST_STATE_FOCUSED
;
2685 if (stateMask
& wxLIST_STATE_SELECTED
)
2687 if (item
>= 0 && (size_t)item
< m_lines
.GetCount())
2689 wxListLineData
*line
= &m_lines
[(size_t)item
];
2690 if (line
->IsHilighted()) ret
|= wxLIST_STATE_SELECTED
;
2696 void wxListMainWindow::GetItem( wxListItem
&item
)
2698 if (item
.m_itemId
>= 0 && (size_t)item
.m_itemId
< m_lines
.GetCount())
2700 wxListLineData
*line
= &m_lines
[(size_t)item
.m_itemId
];
2701 line
->GetItem( item
.m_col
, item
);
2706 item
.m_text
= _T("");
2712 int wxListMainWindow::GetItemCount()
2714 return m_lines
.GetCount();
2717 void wxListMainWindow::GetItemRect( long index
, wxRect
&rect
)
2719 if (index
>= 0 && (size_t)index
< m_lines
.GetCount())
2721 m_lines
[(size_t)index
].GetRect( rect
);
2722 this->CalcScrolledPosition(rect
.x
,rect
.y
,&rect
.x
,&rect
.y
);
2733 bool wxListMainWindow::GetItemPosition(long item
, wxPoint
& pos
)
2736 this->GetItemRect(item
,rect
);
2737 pos
.x
=rect
.x
; pos
.y
=rect
.y
;
2741 int wxListMainWindow::GetSelectedItemCount()
2744 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
2746 if (m_lines
[i
].IsHilighted()) ret
++;
2751 void wxListMainWindow::SetMode( long mode
)
2758 if (m_mode
& wxLC_REPORT
)
2760 #if wxUSE_GENERIC_LIST_EXTENSIONS
2774 long wxListMainWindow::GetMode() const
2779 void wxListMainWindow::CalculatePositions()
2781 if (m_lines
.IsEmpty()) return;
2783 wxClientDC
dc( this );
2784 dc
.SetFont( GetFont() );
2786 int iconSpacing
= 0;
2787 if (m_mode
& wxLC_ICON
) iconSpacing
= m_normal_spacing
;
2788 if (m_mode
& wxLC_SMALL_ICON
) iconSpacing
= m_small_spacing
;
2790 // we take the first line (which also can be an icon or
2791 // an a text item in wxLC_ICON and wxLC_LIST modes) to
2792 // measure the size of the line
2796 int lineSpacing
= 0;
2798 wxListLineData
*line
= &m_lines
[0];
2799 line
->CalculateSize( &dc
, iconSpacing
);
2801 line
->GetSize( dummy
, lineSpacing
);
2804 int clientWidth
= 0;
2805 int clientHeight
= 0;
2807 if (m_mode
& wxLC_REPORT
)
2809 // scroll one line per step
2810 m_yScroll
= lineSpacing
;
2814 int entireHeight
= m_lines
.GetCount() * lineSpacing
+ 2;
2815 int scroll_pos
= GetScrollPos( wxVERTICAL
);
2816 #if wxUSE_GENERIC_LIST_EXTENSIONS
2817 int x_scroll_pos
= GetScrollPos( wxHORIZONTAL
);
2819 SetScrollbars( m_xScroll
, m_yScroll
, 0, entireHeight
/m_yScroll
+1, 0, scroll_pos
, TRUE
);
2821 GetClientSize( &clientWidth
, &clientHeight
);
2823 int entireWidth
= 0 ;
2824 for (size_t j
= 0; j
< m_lines
.GetCount(); j
++)
2826 wxListLineData
*line
= &m_lines
[j
];
2827 line
->CalculateSize( &dc
, iconSpacing
);
2828 line
->SetPosition( &dc
, x
, y
, clientWidth
);
2830 for (int i
= 0; i
< GetColumnCount(); i
++)
2832 line
->SetColumnPosition( i
, col_x
);
2833 col_x
+= GetColumnWidth( i
);
2835 entireWidth
= wxMax( entireWidth
, col_x
) ;
2836 #if wxUSE_GENERIC_LIST_EXTENSIONS
2837 line
->SetPosition( &dc
, x
, y
, col_x
);
2839 y
+= lineSpacing
; // one pixel blank line between items
2841 m_visibleLines
= clientHeight
/ lineSpacing
;
2842 #if wxUSE_GENERIC_LIST_EXTENSIONS
2843 SetScrollbars( m_xScroll
, m_yScroll
, entireWidth
/m_xScroll
+1, entireHeight
/m_yScroll
+1, x_scroll_pos
, scroll_pos
, TRUE
);
2848 // at first we try without any scrollbar. if the items don't
2849 // fit into the window, we recalculate after subtracting an
2850 // approximated 15 pt for the horizontal scrollbar
2852 GetSize( &clientWidth
, &clientHeight
);
2853 clientHeight
-= 4; // sunken frame
2855 int entireWidth
= 0;
2857 for (int tries
= 0; tries
< 2; tries
++)
2864 int m_currentVisibleLines
= 0;
2865 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
2867 m_currentVisibleLines
++;
2868 wxListLineData
*line
= &m_lines
[i
];
2869 line
->CalculateSize( &dc
, iconSpacing
);
2870 line
->SetPosition( &dc
, x
, y
, clientWidth
);
2871 line
->GetSize( lineWidth
, lineHeight
);
2872 if (lineWidth
> maxWidth
) maxWidth
= lineWidth
;
2874 if (m_currentVisibleLines
> m_visibleLines
)
2875 m_visibleLines
= m_currentVisibleLines
;
2876 if (y
+lineSpacing
-6 >= clientHeight
) // -6 for earlier "line breaking"
2878 m_currentVisibleLines
= 0;
2881 entireWidth
+= maxWidth
+6;
2884 if (i
== m_lines
.GetCount()-1) entireWidth
+= maxWidth
;
2885 if ((tries
== 0) && (entireWidth
> clientWidth
))
2887 clientHeight
-= 15; // scrollbar height
2889 m_currentVisibleLines
= 0;
2892 if (i
== m_lines
.GetCount()-1) tries
= 1; // everything fits, no second try required
2896 int scroll_pos
= GetScrollPos( wxHORIZONTAL
);
2897 SetScrollbars( m_xScroll
, m_yScroll
, (entireWidth
+15) / m_xScroll
, 0, scroll_pos
, 0, TRUE
);
2901 void wxListMainWindow::RealizeChanges()
2905 if (!m_lines
.IsEmpty())
2906 m_current
= &m_lines
[0];
2910 FocusLine( m_current
);
2911 // TODO: MSW doesn't automatically hilight the
2913 // if (m_mode & wxLC_SINGLE_SEL) m_current->Hilight( TRUE );
2917 long wxListMainWindow::GetNextItem( long item
,
2918 int WXUNUSED(geometry
),
2922 max
= GetItemCount();
2923 wxCHECK_MSG( (ret
== -1) || (ret
< max
), -1,
2924 _T("invalid listctrl index in GetNextItem()") );
2926 // notice that we start with the next item (or the first one if item == -1)
2927 // and this is intentional to allow writing a simple loop to iterate over
2928 // all selected items
2932 // this is not an error because the index was ok initially, just no
2937 for (size_t i
= (size_t)ret
; i
< m_lines
.GetCount(); i
++)
2939 wxListLineData
*line
= &m_lines
[i
];
2940 if ((state
& wxLIST_STATE_FOCUSED
) && (line
== m_current
))
2942 if ((state
& wxLIST_STATE_SELECTED
) && (line
->IsHilighted()))
2952 void wxListMainWindow::DeleteItem( long index
)
2955 if (index
>= 0 && (size_t)index
< m_lines
.GetCount())
2957 wxListLineData
*line
= &m_lines
[(size_t)index
];
2958 if (m_current
== line
) m_current
= (wxListLineData
*) NULL
;
2960 m_lines
.RemoveAt( (size_t)index
);
2964 void wxListMainWindow::DeleteColumn( int col
)
2966 wxCHECK_RET( col
< (int)m_columns
.GetCount(),
2967 wxT("attempting to delete inexistent column in wxListView") );
2970 wxNode
*node
= m_columns
.Nth( col
);
2971 if (node
) m_columns
.DeleteNode( node
);
2974 void wxListMainWindow::DeleteAllItems()
2977 m_current
= (wxListLineData
*) NULL
;
2979 // to make the deletion of all items faster, we don't send the
2980 // notifications in this case: this is compatible with wxMSW and
2981 // documented in DeleteAllItems() description
2983 wxListEvent
event( wxEVT_COMMAND_LIST_DELETE_ALL_ITEMS
, GetParent()->GetId() );
2984 event
.SetEventObject( GetParent() );
2985 GetParent()->GetEventHandler()->ProcessEvent( event
);
2990 void wxListMainWindow::DeleteEverything()
2997 void wxListMainWindow::EnsureVisible( long index
)
2999 // We have to call this here because the label in
3000 // question might just have been added and no screen
3001 // update taken place.
3002 if (m_dirty
) wxYield();
3004 wxListLineData
*oldCurrent
= m_current
;
3005 m_current
= (wxListLineData
*) NULL
;
3006 if (index
>= 0 && (size_t)index
< m_lines
.GetCount())
3007 m_current
= &m_lines
[(size_t)index
];
3008 if (m_current
) MoveToFocus();
3009 m_current
= oldCurrent
;
3012 long wxListMainWindow::FindItem(long start
, const wxString
& str
, bool WXUNUSED(partial
) )
3016 if (pos
< 0) pos
= 0;
3017 for (size_t i
= (size_t)pos
; i
< m_lines
.GetCount(); i
++)
3019 wxListLineData
*line
= &m_lines
[i
];
3020 wxString s
= line
->GetText(0);
3029 long wxListMainWindow::FindItem(long start
, long data
)
3032 if (pos
< 0) pos
= 0;
3033 for (size_t i
= (size_t)pos
; i
< m_lines
.GetCount(); i
++)
3035 wxListLineData
*line
= &m_lines
[i
];
3037 line
->GetItem( 0, item
);
3038 if (item
.m_data
== data
) return pos
;
3044 long wxListMainWindow::HitTest( int x
, int y
, int &flags
)
3046 CalcUnscrolledPosition( x
, y
, &x
, &y
);
3049 for (size_t i
= 0; i
< m_lines
.GetCount(); i
++)
3051 wxListLineData
*line
= &m_lines
[i
];
3052 long ret
= line
->IsHit( x
, y
);
3053 if (ret
) // & flags) // No: flags is output-only so may be garbage at this point
3063 void wxListMainWindow::InsertItem( wxListItem
&item
)
3067 if (m_mode
& wxLC_REPORT
) mode
= wxLC_REPORT
;
3068 else if (m_mode
& wxLC_LIST
) mode
= wxLC_LIST
;
3069 else if (m_mode
& wxLC_ICON
) mode
= wxLC_ICON
;
3070 else if (m_mode
& wxLC_SMALL_ICON
) mode
= wxLC_ICON
; // no typo
3072 wxListLineData
*line
= new wxListLineData( this, mode
, m_hilightBrush
);
3074 if (m_mode
& wxLC_REPORT
)
3076 line
->InitItems( GetColumnCount() );
3077 item
.m_width
= GetColumnWidth( 0 )-3;
3081 line
->InitItems( 1 );
3084 line
->SetItem( 0, item
);
3085 if ((item
.m_itemId
>= 0) && ((size_t)item
.m_itemId
< m_lines
.GetCount()))
3087 m_lines
.Insert( line
, (size_t)item
.m_itemId
);
3091 m_lines
.Add( line
);
3092 item
.m_itemId
= m_lines
.GetCount()-1;
3096 void wxListMainWindow::InsertColumn( long col
, wxListItem
&item
)
3099 if (m_mode
& wxLC_REPORT
)
3101 if (item
.m_width
== wxLIST_AUTOSIZE_USEHEADER
)
3102 item
.m_width
= GetTextLength( item
.m_text
);
3103 wxListHeaderData
*column
= new wxListHeaderData( item
);
3104 if ((col
>= 0) && (col
< (int)m_columns
.GetCount()))
3106 wxNode
*node
= m_columns
.Nth( (size_t)col
);
3108 m_columns
.Insert( node
, column
);
3112 m_columns
.Append( column
);
3117 wxListCtrlCompare list_ctrl_compare_func_2
;
3118 long list_ctrl_compare_data
;
3120 int LINKAGEMODE
list_ctrl_compare_func_1( wxListLineData
**arg1
, wxListLineData
**arg2
)
3122 wxListLineData
*line1
= *arg1
;
3123 wxListLineData
*line2
= *arg2
;
3125 line1
->GetItem( 0, item
);
3126 long data1
= item
.m_data
;
3127 line2
->GetItem( 0, item
);
3128 long data2
= item
.m_data
;
3129 return list_ctrl_compare_func_2( data1
, data2
, list_ctrl_compare_data
);
3132 void wxListMainWindow::SortItems( wxListCtrlCompare fn
, long data
)
3134 list_ctrl_compare_func_2
= fn
;
3135 list_ctrl_compare_data
= data
;
3136 m_lines
.Sort( list_ctrl_compare_func_1
);
3140 void wxListMainWindow::OnScroll(wxScrollWinEvent
& event
)
3142 wxScrolledWindow::OnScroll( event
) ;
3144 #if wxUSE_GENERIC_LIST_EXTENSIONS
3146 if (event
.GetOrientation() == wxHORIZONTAL
&& ( m_mode
& wxLC_REPORT
))
3148 wxListCtrl
* lc
= wxDynamicCast( GetParent() , wxListCtrl
) ;
3151 lc
->m_headerWin
->Refresh() ;
3153 lc
->m_headerWin
->MacUpdateImmediately() ;
3160 // -------------------------------------------------------------------------------------
3162 // -------------------------------------------------------------------------------------
3164 IMPLEMENT_DYNAMIC_CLASS(wxListItem
, wxObject
)
3166 wxListItem::wxListItem()
3175 m_format
= wxLIST_FORMAT_CENTRE
;
3181 void wxListItem::Clear()
3190 m_format
= wxLIST_FORMAT_CENTRE
;
3194 if (m_attr
) delete m_attr
;
3198 void wxListItem::ClearAttributes()
3200 if (m_attr
) delete m_attr
;
3204 // -------------------------------------------------------------------------------------
3206 // -------------------------------------------------------------------------------------
3208 IMPLEMENT_DYNAMIC_CLASS(wxListEvent
, wxNotifyEvent
)
3210 wxListEvent::wxListEvent( wxEventType commandType
, int id
):
3211 wxNotifyEvent( commandType
, id
)
3217 m_cancelled
= FALSE
;
3222 void wxListEvent::CopyObject(wxObject
& object_dest
) const
3224 wxListEvent
*obj
= (wxListEvent
*)&object_dest
;
3226 wxNotifyEvent::CopyObject(object_dest
);
3228 obj
->m_code
= m_code
;
3229 obj
->m_itemIndex
= m_itemIndex
;
3230 obj
->m_oldItemIndex
= m_oldItemIndex
;
3232 obj
->m_cancelled
= m_cancelled
;
3233 obj
->m_pointDrag
= m_pointDrag
;
3234 obj
->m_item
.m_mask
= m_item
.m_mask
;
3235 obj
->m_item
.m_itemId
= m_item
.m_itemId
;
3236 obj
->m_item
.m_col
= m_item
.m_col
;
3237 obj
->m_item
.m_state
= m_item
.m_state
;
3238 obj
->m_item
.m_stateMask
= m_item
.m_stateMask
;
3239 obj
->m_item
.m_text
= m_item
.m_text
;
3240 obj
->m_item
.m_image
= m_item
.m_image
;
3241 obj
->m_item
.m_data
= m_item
.m_data
;
3242 obj
->m_item
.m_format
= m_item
.m_format
;
3243 obj
->m_item
.m_width
= m_item
.m_width
;
3245 if ( m_item
.HasAttributes() )
3247 obj
->m_item
.SetTextColour(m_item
.GetTextColour());
3251 // -------------------------------------------------------------------------------------
3253 // -------------------------------------------------------------------------------------
3255 IMPLEMENT_DYNAMIC_CLASS(wxListCtrl
, wxControl
)
3257 BEGIN_EVENT_TABLE(wxListCtrl
,wxControl
)
3258 EVT_SIZE (wxListCtrl::OnSize
)
3259 EVT_IDLE (wxListCtrl::OnIdle
)
3262 wxListCtrl::wxListCtrl()
3264 m_imageListNormal
= (wxImageList
*) NULL
;
3265 m_imageListSmall
= (wxImageList
*) NULL
;
3266 m_imageListState
= (wxImageList
*) NULL
;
3267 m_ownsImageListNormal
= m_ownsImageListSmall
= m_ownsImageListState
= FALSE
;
3268 m_mainWin
= (wxListMainWindow
*) NULL
;
3269 m_headerWin
= (wxListHeaderWindow
*) NULL
;
3272 wxListCtrl::~wxListCtrl()
3274 if (m_ownsImageListNormal
) delete m_imageListNormal
;
3275 if (m_ownsImageListSmall
) delete m_imageListSmall
;
3276 if (m_ownsImageListState
) delete m_imageListState
;
3279 bool wxListCtrl::Create(wxWindow
*parent
,
3284 const wxValidator
&validator
,
3285 const wxString
&name
)
3287 m_imageListNormal
= (wxImageList
*) NULL
;
3288 m_imageListSmall
= (wxImageList
*) NULL
;
3289 m_imageListState
= (wxImageList
*) NULL
;
3290 m_ownsImageListNormal
= m_ownsImageListSmall
= m_ownsImageListState
= FALSE
;
3291 m_mainWin
= (wxListMainWindow
*) NULL
;
3292 m_headerWin
= (wxListHeaderWindow
*) NULL
;
3294 if ( !(style
& (wxLC_REPORT
| wxLC_LIST
| wxLC_ICON
)) )
3296 style
= style
| wxLC_LIST
;
3299 bool ret
= wxControl::Create( parent
, id
, pos
, size
, style
, validator
, name
);
3302 if (style
& wxSUNKEN_BORDER
)
3303 style
-= wxSUNKEN_BORDER
;
3305 m_mainWin
= new wxListMainWindow( this, -1, wxPoint(0,0), size
, style
);
3307 if (HasFlag(wxLC_REPORT
))
3309 m_headerWin
= new wxListHeaderWindow( this, -1, m_mainWin
, wxPoint(0,0), wxSize(size
.x
,23), wxTAB_TRAVERSAL
);
3310 if (HasFlag(wxLC_NO_HEADER
))
3311 m_headerWin
->Show( FALSE
);
3315 m_headerWin
= (wxListHeaderWindow
*) NULL
;
3321 void wxListCtrl::OnSize( wxSizeEvent
&WXUNUSED(event
) )
3323 /* handled in OnIdle */
3325 if (m_mainWin
) m_mainWin
->m_dirty
= TRUE
;
3328 void wxListCtrl::SetSingleStyle( long style
, bool add
)
3330 long flag
= GetWindowStyle();
3334 if (style
& wxLC_MASK_TYPE
) flag
= flag
& ~wxLC_MASK_TYPE
;
3335 if (style
& wxLC_MASK_ALIGN
) flag
= flag
& ~wxLC_MASK_ALIGN
;
3336 if (style
& wxLC_MASK_SORT
) flag
= flag
& ~wxLC_MASK_SORT
;
3345 if (flag
& style
) flag
-= style
;
3348 SetWindowStyleFlag( flag
);
3351 void wxListCtrl::SetWindowStyleFlag( long flag
)
3355 m_mainWin
->DeleteEverything();
3359 GetClientSize( &width
, &height
);
3361 m_mainWin
->SetMode( flag
);
3363 if (flag
& wxLC_REPORT
)
3365 if (!HasFlag(wxLC_REPORT
))
3369 m_headerWin
= new wxListHeaderWindow( this, -1, m_mainWin
,
3370 wxPoint(0,0), wxSize(width
,23), wxTAB_TRAVERSAL
);
3371 if (HasFlag(wxLC_NO_HEADER
))
3372 m_headerWin
->Show( FALSE
);
3376 if (flag
& wxLC_NO_HEADER
)
3377 m_headerWin
->Show( FALSE
);
3379 m_headerWin
->Show( TRUE
);
3385 if (HasFlag(wxLC_REPORT
) && !(HasFlag(wxLC_NO_HEADER
)))
3387 m_headerWin
->Show( FALSE
);
3392 wxWindow::SetWindowStyleFlag( flag
);
3395 bool wxListCtrl::GetColumn(int col
, wxListItem
&item
) const
3397 m_mainWin
->GetColumn( col
, item
);
3401 bool wxListCtrl::SetColumn( int col
, wxListItem
& item
)
3403 m_mainWin
->SetColumn( col
, item
);
3407 int wxListCtrl::GetColumnWidth( int col
) const
3409 return m_mainWin
->GetColumnWidth( col
);
3412 bool wxListCtrl::SetColumnWidth( int col
, int width
)
3414 m_mainWin
->SetColumnWidth( col
, width
);
3418 int wxListCtrl::GetCountPerPage() const
3420 return m_mainWin
->GetCountPerPage(); // different from Windows ?
3423 bool wxListCtrl::GetItem( wxListItem
&info
) const
3425 m_mainWin
->GetItem( info
);
3429 bool wxListCtrl::SetItem( wxListItem
&info
)
3431 m_mainWin
->SetItem( info
);
3435 long wxListCtrl::SetItem( long index
, int col
, const wxString
& label
, int imageId
)
3438 info
.m_text
= label
;
3439 info
.m_mask
= wxLIST_MASK_TEXT
;
3440 info
.m_itemId
= index
;
3444 info
.m_image
= imageId
;
3445 info
.m_mask
|= wxLIST_MASK_IMAGE
;
3447 m_mainWin
->SetItem(info
);
3451 int wxListCtrl::GetItemState( long item
, long stateMask
) const
3453 return m_mainWin
->GetItemState( item
, stateMask
);
3456 bool wxListCtrl::SetItemState( long item
, long state
, long stateMask
)
3458 m_mainWin
->SetItemState( item
, state
, stateMask
);
3462 bool wxListCtrl::SetItemImage( long item
, int image
, int WXUNUSED(selImage
) )
3465 info
.m_image
= image
;
3466 info
.m_mask
= wxLIST_MASK_IMAGE
;
3467 info
.m_itemId
= item
;
3468 m_mainWin
->SetItem( info
);
3472 wxString
wxListCtrl::GetItemText( long item
) const
3475 info
.m_itemId
= item
;
3476 m_mainWin
->GetItem( info
);
3480 void wxListCtrl::SetItemText( long item
, const wxString
&str
)
3483 info
.m_mask
= wxLIST_MASK_TEXT
;
3484 info
.m_itemId
= item
;
3486 m_mainWin
->SetItem( info
);
3489 long wxListCtrl::GetItemData( long item
) const
3492 info
.m_itemId
= item
;
3493 m_mainWin
->GetItem( info
);
3497 bool wxListCtrl::SetItemData( long item
, long data
)
3500 info
.m_mask
= wxLIST_MASK_DATA
;
3501 info
.m_itemId
= item
;
3503 m_mainWin
->SetItem( info
);
3507 bool wxListCtrl::GetItemRect( long item
, wxRect
&rect
, int WXUNUSED(code
) ) const
3509 m_mainWin
->GetItemRect( item
, rect
);
3513 bool wxListCtrl::GetItemPosition( long item
, wxPoint
& pos
) const
3515 m_mainWin
->GetItemPosition( item
, pos
);
3519 bool wxListCtrl::SetItemPosition( long WXUNUSED(item
), const wxPoint
& WXUNUSED(pos
) )
3524 int wxListCtrl::GetItemCount() const
3526 return m_mainWin
->GetItemCount();
3529 int wxListCtrl::GetColumnCount() const
3531 return m_mainWin
->GetColumnCount();
3534 void wxListCtrl::SetItemSpacing( int spacing
, bool isSmall
)
3536 m_mainWin
->SetItemSpacing( spacing
, isSmall
);
3539 int wxListCtrl::GetItemSpacing( bool isSmall
) const
3541 return m_mainWin
->GetItemSpacing( isSmall
);
3544 int wxListCtrl::GetSelectedItemCount() const
3546 return m_mainWin
->GetSelectedItemCount();
3549 wxColour
wxListCtrl::GetTextColour() const
3551 return GetForegroundColour();
3554 void wxListCtrl::SetTextColour(const wxColour
& col
)
3556 SetForegroundColour(col
);
3559 long wxListCtrl::GetTopItem() const
3564 long wxListCtrl::GetNextItem( long item
, int geom
, int state
) const
3566 return m_mainWin
->GetNextItem( item
, geom
, state
);
3569 wxImageList
*wxListCtrl::GetImageList(int which
) const
3571 if (which
== wxIMAGE_LIST_NORMAL
)
3573 return m_imageListNormal
;
3575 else if (which
== wxIMAGE_LIST_SMALL
)
3577 return m_imageListSmall
;
3579 else if (which
== wxIMAGE_LIST_STATE
)
3581 return m_imageListState
;
3583 return (wxImageList
*) NULL
;
3586 void wxListCtrl::SetImageList( wxImageList
*imageList
, int which
)
3588 if ( which
== wxIMAGE_LIST_NORMAL
)
3590 if (m_ownsImageListNormal
) delete m_imageListNormal
;
3591 m_imageListNormal
= imageList
;
3592 m_ownsImageListNormal
= FALSE
;
3594 else if ( which
== wxIMAGE_LIST_SMALL
)
3596 if (m_ownsImageListSmall
) delete m_imageListSmall
;
3597 m_imageListSmall
= imageList
;
3598 m_ownsImageListSmall
= FALSE
;
3600 else if ( which
== wxIMAGE_LIST_STATE
)
3602 if (m_ownsImageListState
) delete m_imageListState
;
3603 m_imageListState
= imageList
;
3604 m_ownsImageListState
= FALSE
;
3607 m_mainWin
->SetImageList( imageList
, which
);
3610 void wxListCtrl::AssignImageList(wxImageList
*imageList
, int which
)
3612 SetImageList(imageList
, which
);
3613 if ( which
== wxIMAGE_LIST_NORMAL
)
3614 m_ownsImageListNormal
= TRUE
;
3615 else if ( which
== wxIMAGE_LIST_SMALL
)
3616 m_ownsImageListSmall
= TRUE
;
3617 else if ( which
== wxIMAGE_LIST_STATE
)
3618 m_ownsImageListState
= TRUE
;
3621 bool wxListCtrl::Arrange( int WXUNUSED(flag
) )
3626 bool wxListCtrl::DeleteItem( long item
)
3628 m_mainWin
->DeleteItem( item
);
3632 bool wxListCtrl::DeleteAllItems()
3634 m_mainWin
->DeleteAllItems();
3638 bool wxListCtrl::DeleteAllColumns()
3640 for ( size_t n
= 0; n
< m_mainWin
->m_columns
.GetCount(); n
++ )
3646 void wxListCtrl::ClearAll()
3648 m_mainWin
->DeleteEverything();
3651 bool wxListCtrl::DeleteColumn( int col
)
3653 m_mainWin
->DeleteColumn( col
);
3657 void wxListCtrl::Edit( long item
)
3659 m_mainWin
->Edit( item
);
3662 bool wxListCtrl::EnsureVisible( long item
)
3664 m_mainWin
->EnsureVisible( item
);
3668 long wxListCtrl::FindItem( long start
, const wxString
& str
, bool partial
)
3670 return m_mainWin
->FindItem( start
, str
, partial
);
3673 long wxListCtrl::FindItem( long start
, long data
)
3675 return m_mainWin
->FindItem( start
, data
);
3678 long wxListCtrl::FindItem( long WXUNUSED(start
), const wxPoint
& WXUNUSED(pt
),
3679 int WXUNUSED(direction
))
3684 long wxListCtrl::HitTest( const wxPoint
&point
, int &flags
)
3686 return m_mainWin
->HitTest( (int)point
.x
, (int)point
.y
, flags
);
3689 long wxListCtrl::InsertItem( wxListItem
& info
)
3691 m_mainWin
->InsertItem( info
);
3692 return info
.m_itemId
;
3695 long wxListCtrl::InsertItem( long index
, const wxString
&label
)
3698 info
.m_text
= label
;
3699 info
.m_mask
= wxLIST_MASK_TEXT
;
3700 info
.m_itemId
= index
;
3701 return InsertItem( info
);
3704 long wxListCtrl::InsertItem( long index
, int imageIndex
)
3707 info
.m_mask
= wxLIST_MASK_IMAGE
;
3708 info
.m_image
= imageIndex
;
3709 info
.m_itemId
= index
;
3710 return InsertItem( info
);
3713 long wxListCtrl::InsertItem( long index
, const wxString
&label
, int imageIndex
)
3716 info
.m_text
= label
;
3717 info
.m_image
= imageIndex
;
3718 info
.m_mask
= wxLIST_MASK_TEXT
| wxLIST_MASK_IMAGE
;
3719 info
.m_itemId
= index
;
3720 return InsertItem( info
);
3723 long wxListCtrl::InsertColumn( long col
, wxListItem
&item
)
3725 wxASSERT( m_headerWin
);
3726 m_mainWin
->InsertColumn( col
, item
);
3727 m_headerWin
->Refresh();
3732 long wxListCtrl::InsertColumn( long col
, const wxString
&heading
,
3733 int format
, int width
)
3736 item
.m_mask
= wxLIST_MASK_TEXT
| wxLIST_MASK_FORMAT
;
3737 item
.m_text
= heading
;
3740 item
.m_mask
|= wxLIST_MASK_WIDTH
;
3741 item
.m_width
= width
;
3743 item
.m_format
= format
;
3745 return InsertColumn( col
, item
);
3748 bool wxListCtrl::ScrollList( int WXUNUSED(dx
), int WXUNUSED(dy
) )
3754 // fn is a function which takes 3 long arguments: item1, item2, data.
3755 // item1 is the long data associated with a first item (NOT the index).
3756 // item2 is the long data associated with a second item (NOT the index).
3757 // data is the same value as passed to SortItems.
3758 // The return value is a negative number if the first item should precede the second
3759 // item, a positive number of the second item should precede the first,
3760 // or zero if the two items are equivalent.
3761 // data is arbitrary data to be passed to the sort function.
3763 bool wxListCtrl::SortItems( wxListCtrlCompare fn
, long data
)
3765 m_mainWin
->SortItems( fn
, data
);
3769 void wxListCtrl::OnIdle( wxIdleEvent
&WXUNUSED(event
) )
3771 if (!m_mainWin
->m_dirty
) return;
3775 GetClientSize( &cw
, &ch
);
3782 if (HasFlag(wxLC_REPORT
) && !HasFlag(wxLC_NO_HEADER
))
3784 m_headerWin
->GetPosition( &x
, &y
);
3785 m_headerWin
->GetSize( &w
, &h
);
3786 if ((x
!= 0) || (y
!= 0) || (w
!= cw
) || (h
!= 23))
3787 m_headerWin
->SetSize( 0, 0, cw
, 23 );
3789 m_mainWin
->GetPosition( &x
, &y
);
3790 m_mainWin
->GetSize( &w
, &h
);
3791 if ((x
!= 0) || (y
!= 24) || (w
!= cw
) || (h
!= ch
-24))
3792 m_mainWin
->SetSize( 0, 24, cw
, ch
-24 );
3796 m_mainWin
->GetPosition( &x
, &y
);
3797 m_mainWin
->GetSize( &w
, &h
);
3798 if ((x
!= 0) || (y
!= 24) || (w
!= cw
) || (h
!= ch
))
3799 m_mainWin
->SetSize( 0, 0, cw
, ch
);
3802 m_mainWin
->CalculatePositions();
3803 m_mainWin
->RealizeChanges();
3804 m_mainWin
->m_dirty
= FALSE
;
3805 m_mainWin
->Refresh();
3807 if ( m_headerWin
&& m_headerWin
->m_dirty
)
3809 m_headerWin
->m_dirty
= FALSE
;
3810 m_headerWin
->Refresh();
3814 bool wxListCtrl::SetBackgroundColour( const wxColour
&colour
)
3818 m_mainWin
->SetBackgroundColour( colour
);
3819 m_mainWin
->m_dirty
= TRUE
;
3825 bool wxListCtrl::SetForegroundColour( const wxColour
&colour
)
3827 if ( !wxWindow::SetForegroundColour( colour
) )
3832 m_mainWin
->SetForegroundColour( colour
);
3833 m_mainWin
->m_dirty
= TRUE
;
3838 m_headerWin
->SetForegroundColour( colour
);
3844 bool wxListCtrl::SetFont( const wxFont
&font
)
3846 if ( !wxWindow::SetFont( font
) )
3851 m_mainWin
->SetFont( font
);
3852 m_mainWin
->m_dirty
= TRUE
;
3857 m_headerWin
->SetFont( font
);
3863 #if wxUSE_DRAG_AND_DROP
3865 void wxListCtrl::SetDropTarget( wxDropTarget
*dropTarget
)
3867 m_mainWin
->SetDropTarget( dropTarget
);
3870 wxDropTarget
*wxListCtrl::GetDropTarget() const
3872 return m_mainWin
->GetDropTarget();
3875 #endif // wxUSE_DRAG_AND_DROP
3877 bool wxListCtrl::SetCursor( const wxCursor
&cursor
)
3879 return m_mainWin
? m_mainWin
->wxWindow::SetCursor(cursor
) : FALSE
;
3882 wxColour
wxListCtrl::GetBackgroundColour() const
3884 return m_mainWin
? m_mainWin
->GetBackgroundColour() : wxColour();
3887 wxColour
wxListCtrl::GetForegroundColour() const
3889 return m_mainWin
? m_mainWin
->GetForegroundColour() : wxColour();
3892 bool wxListCtrl::DoPopupMenu( wxMenu
*menu
, int x
, int y
)
3894 return m_mainWin
->PopupMenu( menu
, x
, y
);
3897 void wxListCtrl::SetFocus()
3899 /* The test in window.cpp fails as we are a composite
3900 window, so it checks against "this", but not m_mainWin. */
3901 if ( FindFocus() != this )
3902 m_mainWin
->SetFocus();