1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: private definitions of wxListCtrl helpers
4 // Author: Robert Roebling
5 // Vadim Zeitlin (virtual list control support)
7 // Copyright: (c) 1998 Robert Roebling
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 #ifndef _WX_GENERIC_LISTCTRL_PRIVATE_H_
12 #define _WX_GENERIC_LISTCTRL_PRIVATE_H_
18 #include "wx/listctrl.h"
19 #include "wx/selstore.h"
21 #include "wx/settings.h"
23 // ============================================================================
25 // ============================================================================
27 //-----------------------------------------------------------------------------
28 // wxColWidthInfo (internal)
29 //-----------------------------------------------------------------------------
34 bool bNeedsUpdate
; // only set to true when an item whose
35 // width == nMaxWidth is removed
37 wxColWidthInfo(int w
= 0, bool needsUpdate
= false)
40 bNeedsUpdate
= needsUpdate
;
44 WX_DEFINE_ARRAY_PTR(wxColWidthInfo
*, ColWidthArray
);
46 //-----------------------------------------------------------------------------
47 // wxListItemData (internal)
48 //-----------------------------------------------------------------------------
53 wxListItemData(wxListMainWindow
*owner
);
56 void SetItem( const wxListItem
&info
);
57 void SetImage( int image
) { m_image
= image
; }
58 void SetData( wxUIntPtr data
) { m_data
= data
; }
59 void SetPosition( int x
, int y
);
60 void SetSize( int width
, int height
);
62 bool HasText() const { return !m_text
.empty(); }
63 const wxString
& GetText() const { return m_text
; }
64 void SetText(const wxString
& text
) { m_text
= text
; }
66 // we can't use empty string for measuring the string width/height, so
67 // always return something
68 wxString
GetTextForMeasuring() const
70 wxString s
= GetText();
77 bool IsHit( int x
, int y
) const;
82 int GetHeight() const;
84 int GetImage() const { return m_image
; }
85 bool HasImage() const { return GetImage() != -1; }
87 void GetItem( wxListItem
&info
) const;
89 void SetAttr(wxListItemAttr
*attr
) { m_attr
= attr
; }
90 wxListItemAttr
*GetAttr() const { return m_attr
; }
93 // the item image or -1
96 // user data associated with the item
99 // the item coordinates are not used in report mode; instead this pointer is
100 // NULL and the owner window is used to retrieve the item position and size
103 // the list ctrl we are in
104 wxListMainWindow
*m_owner
;
106 // custom attributes or NULL
107 wxListItemAttr
*m_attr
;
110 // common part of all ctors
116 //-----------------------------------------------------------------------------
117 // wxListHeaderData (internal)
118 //-----------------------------------------------------------------------------
120 class wxListHeaderData
: public wxObject
124 wxListHeaderData( const wxListItem
&info
);
125 void SetItem( const wxListItem
&item
);
126 void SetPosition( int x
, int y
);
127 void SetWidth( int w
);
128 void SetState( int state
);
129 void SetFormat( int format
);
130 void SetHeight( int h
);
131 bool HasImage() const;
133 bool HasText() const { return !m_text
.empty(); }
134 const wxString
& GetText() const { return m_text
; }
135 void SetText(const wxString
& text
) { m_text
= text
; }
137 void GetItem( wxListItem
&item
);
139 bool IsHit( int x
, int y
) const;
140 int GetImage() const;
141 int GetWidth() const;
142 int GetFormat() const;
143 int GetState() const;
160 //-----------------------------------------------------------------------------
161 // wxListLineData (internal)
162 //-----------------------------------------------------------------------------
164 WX_DECLARE_LIST(wxListItemData
, wxListItemDataList
);
169 // the list of subitems: only may have more than one item in report mode
170 wxListItemDataList m_items
;
172 // this is not used in report view
184 // the part to be highlighted
185 wxRect m_rectHighlight
;
187 // extend all our rects to be centered inside the one of given width
188 void ExtendWidth(wxCoord w
)
190 wxASSERT_MSG( m_rectAll
.width
<= w
,
191 _T("width can only be increased") );
194 m_rectLabel
.x
= m_rectAll
.x
+ (w
- m_rectLabel
.width
) / 2;
195 m_rectIcon
.x
= m_rectAll
.x
+ (w
- m_rectIcon
.width
) / 2;
196 m_rectHighlight
.x
= m_rectAll
.x
+ (w
- m_rectHighlight
.width
) / 2;
201 // is this item selected? [NB: not used in virtual mode]
204 // back pointer to the list ctrl
205 wxListMainWindow
*m_owner
;
208 wxListLineData(wxListMainWindow
*owner
);
212 WX_CLEAR_LIST(wxListItemDataList
, m_items
);
216 // are we in report mode?
217 inline bool InReportView() const;
219 // are we in virtual report mode?
220 inline bool IsVirtual() const;
222 // these 2 methods shouldn't be called for report view controls, in that
223 // case we determine our position/size ourselves
225 // calculate the size of the line
226 void CalculateSize( wxDC
*dc
, int spacing
);
228 // remember the position this line appears at
229 void SetPosition( int x
, int y
, int spacing
);
233 void SetImage( int image
) { SetImage(0, image
); }
234 int GetImage() const { return GetImage(0); }
235 void SetImage( int index
, int image
);
236 int GetImage( int index
) const;
238 bool HasImage() const { return GetImage() != -1; }
239 bool HasText() const { return !GetText(0).empty(); }
241 void SetItem( int index
, const wxListItem
&info
);
242 void GetItem( int index
, wxListItem
&info
);
244 wxString
GetText(int index
) const;
245 void SetText( int index
, const wxString
& s
);
247 wxListItemAttr
*GetAttr() const;
248 void SetAttr(wxListItemAttr
*attr
);
250 // return true if the highlighting really changed
251 bool Highlight( bool on
);
253 void ReverseHighlight();
255 bool IsHighlighted() const
257 wxASSERT_MSG( !IsVirtual(), _T("unexpected call to IsHighlighted") );
259 return m_highlighted
;
262 // draw the line on the given DC in icon/list mode
263 void Draw( wxDC
*dc
);
265 // the same in report mode
266 void DrawInReportMode( wxDC
*dc
,
268 const wxRect
& rectHL
,
273 // set the line to contain num items (only can be > 1 in report mode)
274 void InitItems( int num
);
276 // get the mode (i.e. style) of the list control
277 inline int GetMode() const;
279 // prepare the DC for drawing with these item's attributes, return true if
280 // we need to draw the items background to highlight it, false otherwise
281 bool SetAttributes(wxDC
*dc
,
282 const wxListItemAttr
*attr
,
285 // draw the text on the DC with the correct justification; also add an
286 // ellipsis if the text is too large to fit in the current width
287 void DrawTextFormatted(wxDC
*dc
,
288 const wxString
&text
,
291 int yMid
, // this is middle, not top, of the text
295 WX_DECLARE_OBJARRAY(wxListLineData
, wxListLineDataArray
);
297 //-----------------------------------------------------------------------------
298 // wxListHeaderWindow (internal)
299 //-----------------------------------------------------------------------------
301 class wxListHeaderWindow
: public wxWindow
304 wxListMainWindow
*m_owner
;
305 const wxCursor
*m_currentCursor
;
306 wxCursor
*m_resizeCursor
;
309 // column being resized or -1
312 // divider line position in logical (unscrolled) coords
315 // minimal position beyond which the divider line
316 // can't be dragged in logical coords
320 wxListHeaderWindow();
322 wxListHeaderWindow( wxWindow
*win
,
324 wxListMainWindow
*owner
,
325 const wxPoint
&pos
= wxDefaultPosition
,
326 const wxSize
&size
= wxDefaultSize
,
328 const wxString
&name
= wxT("wxlistctrlcolumntitles") );
330 virtual ~wxListHeaderWindow();
333 void AdjustDC( wxDC
& dc
);
335 void OnPaint( wxPaintEvent
&event
);
336 void OnMouse( wxMouseEvent
&event
);
337 void OnSetFocus( wxFocusEvent
&event
);
342 // Update main window's column later
343 bool m_sendSetColumnWidth
;
347 virtual void OnInternalIdle();
350 // common part of all ctors
353 // generate and process the list event of the given type, return true if
354 // it wasn't vetoed, i.e. if we should proceed
355 bool SendListEvent(wxEventType type
, const wxPoint
& pos
);
357 DECLARE_EVENT_TABLE()
360 //-----------------------------------------------------------------------------
361 // wxListRenameTimer (internal)
362 //-----------------------------------------------------------------------------
364 class wxListRenameTimer
: public wxTimer
367 wxListMainWindow
*m_owner
;
370 wxListRenameTimer( wxListMainWindow
*owner
);
374 //-----------------------------------------------------------------------------
375 // wxListTextCtrlWrapper: wraps a wxTextCtrl to make it work for inline editing
376 //-----------------------------------------------------------------------------
378 class wxListTextCtrlWrapper
: public wxEvtHandler
381 // NB: text must be a valid object but not Create()d yet
382 wxListTextCtrlWrapper(wxListMainWindow
*owner
,
386 wxTextCtrl
*GetText() const { return m_text
; }
388 void EndEdit( bool discardChanges
);
391 void OnChar( wxKeyEvent
&event
);
392 void OnKeyUp( wxKeyEvent
&event
);
393 void OnKillFocus( wxFocusEvent
&event
);
395 bool AcceptChanges();
396 void Finish( bool setfocus
);
399 wxListMainWindow
*m_owner
;
401 wxString m_startValue
;
403 bool m_aboutToFinish
;
405 DECLARE_EVENT_TABLE()
408 //-----------------------------------------------------------------------------
409 // wxListMainWindow (internal)
410 //-----------------------------------------------------------------------------
412 WX_DECLARE_LIST(wxListHeaderData
, wxListHeaderDataList
);
414 class wxListMainWindow
: public wxWindow
418 wxListMainWindow( wxWindow
*parent
,
420 const wxPoint
& pos
= wxDefaultPosition
,
421 const wxSize
& size
= wxDefaultSize
,
423 const wxString
&name
= _T("listctrlmainwindow") );
425 virtual ~wxListMainWindow();
427 bool HasFlag(int flag
) const { return m_parent
->HasFlag(flag
); }
429 // return true if this is a virtual list control
430 bool IsVirtual() const { return HasFlag(wxLC_VIRTUAL
); }
432 // return true if the control is in report mode
433 bool InReportView() const { return HasFlag(wxLC_REPORT
); }
435 // return true if we are in single selection mode, false if multi sel
436 bool IsSingleSel() const { return HasFlag(wxLC_SINGLE_SEL
); }
438 // do we have a header window?
439 bool HasHeader() const
440 { return InReportView() && !HasFlag(wxLC_NO_HEADER
); }
442 void HighlightAll( bool on
);
444 // all these functions only do something if the line is currently visible
446 // change the line "selected" state, return true if it really changed
447 bool HighlightLine( size_t line
, bool highlight
= true);
449 // as HighlightLine() but do it for the range of lines: this is incredibly
450 // more efficient for virtual list controls!
452 // NB: unlike HighlightLine() this one does refresh the lines on screen
453 void HighlightLines( size_t lineFrom
, size_t lineTo
, bool on
= true );
455 // toggle the line state and refresh it
456 void ReverseHighlight( size_t line
)
457 { HighlightLine(line
, !IsHighlighted(line
)); RefreshLine(line
); }
459 // return true if the line is highlighted
460 bool IsHighlighted(size_t line
) const;
462 // refresh one or several lines at once
463 void RefreshLine( size_t line
);
464 void RefreshLines( size_t lineFrom
, size_t lineTo
);
466 // refresh all selected items
467 void RefreshSelected();
469 // refresh all lines below the given one: the difference with
470 // RefreshLines() is that the index here might not be a valid one (happens
471 // when the last line is deleted)
472 void RefreshAfter( size_t lineFrom
);
474 // the methods which are forwarded to wxListLineData itself in list/icon
475 // modes but are here because the lines don't store their positions in the
478 // get the bound rect for the entire line
479 wxRect
GetLineRect(size_t line
) const;
481 // get the bound rect of the label
482 wxRect
GetLineLabelRect(size_t line
) const;
484 // get the bound rect of the items icon (only may be called if we do have
486 wxRect
GetLineIconRect(size_t line
) const;
488 // get the rect to be highlighted when the item has focus
489 wxRect
GetLineHighlightRect(size_t line
) const;
491 // get the size of the total line rect
492 wxSize
GetLineSize(size_t line
) const
493 { return GetLineRect(line
).GetSize(); }
495 // return the hit code for the corresponding position (in this line)
496 long HitTestLine(size_t line
, int x
, int y
) const;
498 // bring the selected item into view, scrolling to it if necessary
499 void MoveToItem(size_t item
);
501 bool ScrollList( int WXUNUSED(dx
), int dy
);
503 // bring the current item into view
504 void MoveToFocus() { MoveToItem(m_current
); }
506 // start editing the label of the given item
507 wxTextCtrl
*EditLabel(long item
,
508 wxClassInfo
* textControlClass
= CLASSINFO(wxTextCtrl
));
509 wxTextCtrl
*GetEditControl() const
511 return m_textctrlWrapper
? m_textctrlWrapper
->GetText() : NULL
;
514 void ResetTextControl(wxTextCtrl
*text
)
517 m_textctrlWrapper
= NULL
;
520 void OnRenameTimer();
521 bool OnRenameAccept(size_t itemEdit
, const wxString
& value
);
522 void OnRenameCancelled(size_t itemEdit
);
524 void OnMouse( wxMouseEvent
&event
);
526 // called to switch the selection from the current item to newCurrent,
527 void OnArrowChar( size_t newCurrent
, const wxKeyEvent
& event
);
529 void OnChar( wxKeyEvent
&event
);
530 void OnKeyDown( wxKeyEvent
&event
);
531 void OnKeyUp( wxKeyEvent
&event
);
532 void OnSetFocus( wxFocusEvent
&event
);
533 void OnKillFocus( wxFocusEvent
&event
);
534 void OnScroll( wxScrollWinEvent
& event
);
536 void OnPaint( wxPaintEvent
&event
);
538 void OnChildFocus(wxChildFocusEvent
& event
);
540 void DrawImage( int index
, wxDC
*dc
, int x
, int y
);
541 void GetImageSize( int index
, int &width
, int &height
) const;
542 int GetTextLength( const wxString
&s
) const;
544 void SetImageList( wxImageList
*imageList
, int which
);
545 void SetItemSpacing( int spacing
, bool isSmall
= false );
546 int GetItemSpacing( bool isSmall
= false );
548 void SetColumn( int col
, wxListItem
&item
);
549 void SetColumnWidth( int col
, int width
);
550 void GetColumn( int col
, wxListItem
&item
) const;
551 int GetColumnWidth( int col
) const;
552 int GetColumnCount() const { return m_columns
.GetCount(); }
554 // returns the sum of the heights of all columns
555 int GetHeaderWidth() const;
557 int GetCountPerPage() const;
559 void SetItem( wxListItem
&item
);
560 void GetItem( wxListItem
&item
) const;
561 void SetItemState( long item
, long state
, long stateMask
);
562 void SetItemStateAll( long state
, long stateMask
);
563 int GetItemState( long item
, long stateMask
) const;
564 bool GetItemRect( long item
, wxRect
&rect
) const
566 return GetSubItemRect(item
, wxLIST_GETSUBITEMRECT_WHOLEITEM
, rect
);
568 bool GetSubItemRect( long item
, long subItem
, wxRect
& rect
) const;
569 wxRect
GetViewRect() const;
570 bool GetItemPosition( long item
, wxPoint
& pos
) const;
571 int GetSelectedItemCount() const;
573 wxString
GetItemText(long item
) const
576 info
.m_mask
= wxLIST_MASK_TEXT
;
577 info
.m_itemId
= item
;
582 void SetItemText(long item
, const wxString
& value
)
585 info
.m_mask
= wxLIST_MASK_TEXT
;
586 info
.m_itemId
= item
;
591 wxImageList
* GetSmallImageList() const
592 { return m_small_image_list
; }
594 // set the scrollbars and update the positions of the items
595 void RecalculatePositions(bool noRefresh
= false);
597 // refresh the window and the header
600 long GetNextItem( long item
, int geometry
, int state
) const;
601 void DeleteItem( long index
);
602 void DeleteAllItems();
603 void DeleteColumn( int col
);
604 void DeleteEverything();
605 void EnsureVisible( long index
);
606 long FindItem( long start
, const wxString
& str
, bool partial
= false );
607 long FindItem( long start
, wxUIntPtr data
);
608 long FindItem( const wxPoint
& pt
);
609 long HitTest( int x
, int y
, int &flags
) const;
610 void InsertItem( wxListItem
&item
);
611 void InsertColumn( long col
, wxListItem
&item
);
612 int GetItemWidthWithImage(wxListItem
* item
);
613 void SortItems( wxListCtrlCompare fn
, wxIntPtr data
);
615 size_t GetItemCount() const;
616 bool IsEmpty() const { return GetItemCount() == 0; }
617 void SetItemCount(long count
);
619 // change the current (== focused) item, send a notification event
620 void ChangeCurrent(size_t current
);
621 void ResetCurrent() { ChangeCurrent((size_t)-1); }
622 bool HasCurrent() const { return m_current
!= (size_t)-1; }
624 // send out a wxListEvent
625 void SendNotify( size_t line
,
627 const wxPoint
& point
= wxDefaultPosition
);
629 // override base class virtual to reset m_lineHeight when the font changes
630 virtual bool SetFont(const wxFont
& font
)
632 if ( !wxWindow::SetFont(font
) )
640 // these are for wxListLineData usage only
642 // get the backpointer to the list ctrl
643 wxGenericListCtrl
*GetListCtrl() const
645 return wxStaticCast(GetParent(), wxGenericListCtrl
);
648 // get the height of all lines (assuming they all do have the same height)
649 wxCoord
GetLineHeight() const;
651 // get the y position of the given line (only for report view)
652 wxCoord
GetLineY(size_t line
) const;
654 // get the brush to use for the item highlighting
655 wxBrush
*GetHighlightBrush() const
657 return m_hasFocus
? m_highlightBrush
: m_highlightUnfocusedBrush
;
660 bool HasFocus() const
666 // the array of all line objects for a non virtual list control (for the
667 // virtual list control we only ever use m_lines[0])
668 wxListLineDataArray m_lines
;
670 // the list of column objects
671 wxListHeaderDataList m_columns
;
673 // currently focused item or -1
676 // the number of lines per page
679 // this flag is set when something which should result in the window
680 // redrawing happens (i.e. an item was added or deleted, or its appearance
681 // changed) and OnPaint() doesn't redraw the window while it is set which
682 // allows to minimize the number of repaintings when a lot of items are
683 // being added. The real repainting occurs only after the next OnIdle()
687 wxColour
*m_highlightColour
;
688 wxImageList
*m_small_image_list
;
689 wxImageList
*m_normal_image_list
;
691 int m_normal_spacing
;
695 wxTimer
*m_renameTimer
;
699 ColWidthArray m_aColWidths
;
701 // for double click logic
702 size_t m_lineLastClicked
,
703 m_lineBeforeLastClicked
,
704 m_lineSelectSingleOnUp
;
707 wxWindow
*GetMainWindowOfCompositeControl() { return GetParent(); }
709 // the total count of items in a virtual list control
712 // the object maintaining the items selection state, only used in virtual
714 wxSelectionStore m_selStore
;
716 // common part of all ctors
719 // get the line data for the given index
720 wxListLineData
*GetLine(size_t n
) const
722 wxASSERT_MSG( n
!= (size_t)-1, _T("invalid line index") );
726 wxConstCast(this, wxListMainWindow
)->CacheLineData(n
);
733 // get a dummy line which can be used for geometry calculations and such:
734 // you must use GetLine() if you want to really draw the line
735 wxListLineData
*GetDummyLine() const;
737 // cache the line data of the n-th line in m_lines[0]
738 void CacheLineData(size_t line
);
740 // get the range of visible lines
741 void GetVisibleLinesRange(size_t *from
, size_t *to
);
743 // force us to recalculate the range of visible lines
744 void ResetVisibleLinesRange() { m_lineFrom
= (size_t)-1; }
746 // get the colour to be used for drawing the rules
747 wxColour
GetRuleColour() const
749 return wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT
);
753 // initialize the current item if needed
754 void UpdateCurrent();
756 // delete all items but don't refresh: called from dtor
757 void DoDeleteAllItems();
759 // the height of one line using the current font
760 wxCoord m_lineHeight
;
762 // the total header width or 0 if not calculated yet
763 wxCoord m_headerWidth
;
765 // the first and last lines being shown on screen right now (inclusive),
766 // both may be -1 if they must be calculated so never access them directly:
767 // use GetVisibleLinesRange() above instead
771 // the brushes to use for item highlighting when we do/don't have focus
772 wxBrush
*m_highlightBrush
,
773 *m_highlightUnfocusedBrush
;
775 // wrapper around the text control currently used for in place editing or
776 // NULL if no item is being edited
777 wxListTextCtrlWrapper
*m_textctrlWrapper
;
780 DECLARE_EVENT_TABLE()
782 friend class wxGenericListCtrl
;
785 #endif // wxUSE_LISTCTRL
786 #endif // _WX_GENERIC_LISTCTRL_PRIVATE_H_