]> git.saurik.com Git - wxWidgets.git/blame - include/wx/generic/private/listctrl.h
small cleanup; move private class definitions in a private header
[wxWidgets.git] / include / wx / generic / private / listctrl.h
CommitLineData
ad486020
FM
1/////////////////////////////////////////////////////////////////////////////
2// Name: listctrl.h
3// Purpose: private definitions of wxListCtrl helpers
4// Author: Robert Roebling
5// Vadim Zeitlin (virtual list control support)
6// Id: $Id$
7// Copyright: (c) 1998 Robert Roebling
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#ifndef _WX_GENERIC_LISTCTRL_PRIVATE_H_
12#define _WX_GENERIC_LISTCTRL_PRIVATE_H_
13
14#include "wx/defs.h"
15
16#if wxUSE_LISTCTRL
17
18#include "wx/listctrl.h"
19#include "wx/selstore.h"
20
21// ============================================================================
22// private classes
23// ============================================================================
24
25//-----------------------------------------------------------------------------
26// wxColWidthInfo (internal)
27//-----------------------------------------------------------------------------
28
29struct wxColWidthInfo
30{
31 int nMaxWidth;
32 bool bNeedsUpdate; // only set to true when an item whose
33 // width == nMaxWidth is removed
34
35 wxColWidthInfo(int w = 0, bool needsUpdate = false)
36 {
37 nMaxWidth = w;
38 bNeedsUpdate = needsUpdate;
39 }
40};
41
42WX_DEFINE_ARRAY_PTR(wxColWidthInfo *, ColWidthArray);
43
44//-----------------------------------------------------------------------------
45// wxListItemData (internal)
46//-----------------------------------------------------------------------------
47
48class wxListItemData
49{
50public:
51 wxListItemData(wxListMainWindow *owner);
52 ~wxListItemData();
53
54 void SetItem( const wxListItem &info );
55 void SetImage( int image ) { m_image = image; }
56 void SetData( wxUIntPtr data ) { m_data = data; }
57 void SetPosition( int x, int y );
58 void SetSize( int width, int height );
59
60 bool HasText() const { return !m_text.empty(); }
61 const wxString& GetText() const { return m_text; }
62 void SetText(const wxString& text) { m_text = text; }
63
64 // we can't use empty string for measuring the string width/height, so
65 // always return something
66 wxString GetTextForMeasuring() const
67 {
68 wxString s = GetText();
69 if ( s.empty() )
70 s = _T('H');
71
72 return s;
73 }
74
75 bool IsHit( int x, int y ) const;
76
77 int GetX() const;
78 int GetY() const;
79 int GetWidth() const;
80 int GetHeight() const;
81
82 int GetImage() const { return m_image; }
83 bool HasImage() const { return GetImage() != -1; }
84
85 void GetItem( wxListItem &info ) const;
86
87 void SetAttr(wxListItemAttr *attr) { m_attr = attr; }
88 wxListItemAttr *GetAttr() const { return m_attr; }
89
90public:
91 // the item image or -1
92 int m_image;
93
94 // user data associated with the item
95 wxUIntPtr m_data;
96
97 // the item coordinates are not used in report mode; instead this pointer is
98 // NULL and the owner window is used to retrieve the item position and size
99 wxRect *m_rect;
100
101 // the list ctrl we are in
102 wxListMainWindow *m_owner;
103
104 // custom attributes or NULL
105 wxListItemAttr *m_attr;
106
107protected:
108 // common part of all ctors
109 void Init();
110
111 wxString m_text;
112};
113
114//-----------------------------------------------------------------------------
115// wxListHeaderData (internal)
116//-----------------------------------------------------------------------------
117
118class wxListHeaderData : public wxObject
119{
120public:
121 wxListHeaderData();
122 wxListHeaderData( const wxListItem &info );
123 void SetItem( const wxListItem &item );
124 void SetPosition( int x, int y );
125 void SetWidth( int w );
126 void SetState( int state );
127 void SetFormat( int format );
128 void SetHeight( int h );
129 bool HasImage() const;
130
131 bool HasText() const { return !m_text.empty(); }
132 const wxString& GetText() const { return m_text; }
133 void SetText(const wxString& text) { m_text = text; }
134
135 void GetItem( wxListItem &item );
136
137 bool IsHit( int x, int y ) const;
138 int GetImage() const;
139 int GetWidth() const;
140 int GetFormat() const;
141 int GetState() const;
142
143protected:
144 long m_mask;
145 int m_image;
146 wxString m_text;
147 int m_format;
148 int m_width;
149 int m_xpos,
150 m_ypos;
151 int m_height;
152 int m_state;
153
154private:
155 void Init();
156};
157
158//-----------------------------------------------------------------------------
159// wxListLineData (internal)
160//-----------------------------------------------------------------------------
161
162WX_DECLARE_LIST(wxListItemData, wxListItemDataList);
163
164class wxListLineData
165{
166public:
167 // the list of subitems: only may have more than one item in report mode
168 wxListItemDataList m_items;
169
170 // this is not used in report view
171 struct GeometryInfo
172 {
173 // total item rect
174 wxRect m_rectAll;
175
176 // label only
177 wxRect m_rectLabel;
178
179 // icon only
180 wxRect m_rectIcon;
181
182 // the part to be highlighted
183 wxRect m_rectHighlight;
184
185 // extend all our rects to be centered inside the one of given width
186 void ExtendWidth(wxCoord w)
187 {
188 wxASSERT_MSG( m_rectAll.width <= w,
189 _T("width can only be increased") );
190
191 m_rectAll.width = w;
192 m_rectLabel.x = m_rectAll.x + (w - m_rectLabel.width) / 2;
193 m_rectIcon.x = m_rectAll.x + (w - m_rectIcon.width) / 2;
194 m_rectHighlight.x = m_rectAll.x + (w - m_rectHighlight.width) / 2;
195 }
196 }
197 *m_gi;
198
199 // is this item selected? [NB: not used in virtual mode]
200 bool m_highlighted;
201
202 // back pointer to the list ctrl
203 wxListMainWindow *m_owner;
204
205public:
206 wxListLineData(wxListMainWindow *owner);
207
208 ~wxListLineData()
209 {
210 WX_CLEAR_LIST(wxListItemDataList, m_items);
211 delete m_gi;
212 }
213
214 // are we in report mode?
215 inline bool InReportView() const;
216
217 // are we in virtual report mode?
218 inline bool IsVirtual() const;
219
220 // these 2 methods shouldn't be called for report view controls, in that
221 // case we determine our position/size ourselves
222
223 // calculate the size of the line
224 void CalculateSize( wxDC *dc, int spacing );
225
226 // remember the position this line appears at
227 void SetPosition( int x, int y, int spacing );
228
229 // wxListCtrl API
230
231 void SetImage( int image ) { SetImage(0, image); }
232 int GetImage() const { return GetImage(0); }
233 void SetImage( int index, int image );
234 int GetImage( int index ) const;
235
236 bool HasImage() const { return GetImage() != -1; }
237 bool HasText() const { return !GetText(0).empty(); }
238
239 void SetItem( int index, const wxListItem &info );
240 void GetItem( int index, wxListItem &info );
241
242 wxString GetText(int index) const;
243 void SetText( int index, const wxString& s );
244
245 wxListItemAttr *GetAttr() const;
246 void SetAttr(wxListItemAttr *attr);
247
248 // return true if the highlighting really changed
249 bool Highlight( bool on );
250
251 void ReverseHighlight();
252
253 bool IsHighlighted() const
254 {
255 wxASSERT_MSG( !IsVirtual(), _T("unexpected call to IsHighlighted") );
256
257 return m_highlighted;
258 }
259
260 // draw the line on the given DC in icon/list mode
261 void Draw( wxDC *dc );
262
263 // the same in report mode
264 void DrawInReportMode( wxDC *dc,
265 const wxRect& rect,
266 const wxRect& rectHL,
267 bool highlighted,
268 bool current );
269
270private:
271 // set the line to contain num items (only can be > 1 in report mode)
272 void InitItems( int num );
273
274 // get the mode (i.e. style) of the list control
275 inline int GetMode() const;
276
277 // prepare the DC for drawing with these item's attributes, return true if
278 // we need to draw the items background to highlight it, false otherwise
279 bool SetAttributes(wxDC *dc,
280 const wxListItemAttr *attr,
281 bool highlight);
282
283 // draw the text on the DC with the correct justification; also add an
284 // ellipsis if the text is too large to fit in the current width
285 void DrawTextFormatted(wxDC *dc,
286 const wxString &text,
287 int col,
288 int x,
289 int yMid, // this is middle, not top, of the text
290 int width);
291};
292
293WX_DECLARE_OBJARRAY(wxListLineData, wxListLineDataArray);
294
295//-----------------------------------------------------------------------------
296// wxListHeaderWindow (internal)
297//-----------------------------------------------------------------------------
298
299class wxListHeaderWindow : public wxWindow
300{
301protected:
302 wxListMainWindow *m_owner;
303 const wxCursor *m_currentCursor;
304 wxCursor *m_resizeCursor;
305 bool m_isDragging;
306
307 // column being resized or -1
308 int m_column;
309
310 // divider line position in logical (unscrolled) coords
311 int m_currentX;
312
313 // minimal position beyond which the divider line
314 // can't be dragged in logical coords
315 int m_minX;
316
317public:
318 wxListHeaderWindow();
319
320 wxListHeaderWindow( wxWindow *win,
321 wxWindowID id,
322 wxListMainWindow *owner,
323 const wxPoint &pos = wxDefaultPosition,
324 const wxSize &size = wxDefaultSize,
325 long style = 0,
326 const wxString &name = wxT("wxlistctrlcolumntitles") );
327
328 virtual ~wxListHeaderWindow();
329
330 void DrawCurrent();
331 void AdjustDC( wxDC& dc );
332
333 void OnPaint( wxPaintEvent &event );
334 void OnMouse( wxMouseEvent &event );
335 void OnSetFocus( wxFocusEvent &event );
336
337 // needs refresh
338 bool m_dirty;
339
340 // Update main window's column later
341 bool m_sendSetColumnWidth;
342 int m_colToSend;
343 int m_widthToSend;
344
345 virtual void OnInternalIdle();
346
347private:
348 // common part of all ctors
349 void Init();
350
351 // generate and process the list event of the given type, return true if
352 // it wasn't vetoed, i.e. if we should proceed
353 bool SendListEvent(wxEventType type, const wxPoint& pos);
354
355 DECLARE_EVENT_TABLE()
356};
357
358//-----------------------------------------------------------------------------
359// wxListRenameTimer (internal)
360//-----------------------------------------------------------------------------
361
362class wxListRenameTimer: public wxTimer
363{
364private:
365 wxListMainWindow *m_owner;
366
367public:
368 wxListRenameTimer( wxListMainWindow *owner );
369 void Notify();
370};
371
372//-----------------------------------------------------------------------------
373// wxListTextCtrlWrapper: wraps a wxTextCtrl to make it work for inline editing
374//-----------------------------------------------------------------------------
375
376class wxListTextCtrlWrapper : public wxEvtHandler
377{
378public:
379 // NB: text must be a valid object but not Create()d yet
380 wxListTextCtrlWrapper(wxListMainWindow *owner,
381 wxTextCtrl *text,
382 size_t itemEdit);
383
384 wxTextCtrl *GetText() const { return m_text; }
385
386 void EndEdit( bool discardChanges );
387
388protected:
389 void OnChar( wxKeyEvent &event );
390 void OnKeyUp( wxKeyEvent &event );
391 void OnKillFocus( wxFocusEvent &event );
392
393 bool AcceptChanges();
394 void Finish( bool setfocus );
395
396private:
397 wxListMainWindow *m_owner;
398 wxTextCtrl *m_text;
399 wxString m_startValue;
400 size_t m_itemEdited;
401 bool m_aboutToFinish;
402
403 DECLARE_EVENT_TABLE()
404};
405
406//-----------------------------------------------------------------------------
407// wxListMainWindow (internal)
408//-----------------------------------------------------------------------------
409
410WX_DECLARE_LIST(wxListHeaderData, wxListHeaderDataList);
411
412class wxListMainWindow : public wxWindow
413{
414public:
415 wxListMainWindow();
416 wxListMainWindow( wxWindow *parent,
417 wxWindowID id,
418 const wxPoint& pos = wxDefaultPosition,
419 const wxSize& size = wxDefaultSize,
420 long style = 0,
421 const wxString &name = _T("listctrlmainwindow") );
422
423 virtual ~wxListMainWindow();
424
425 bool HasFlag(int flag) const { return m_parent->HasFlag(flag); }
426
427 // return true if this is a virtual list control
428 bool IsVirtual() const { return HasFlag(wxLC_VIRTUAL); }
429
430 // return true if the control is in report mode
431 bool InReportView() const { return HasFlag(wxLC_REPORT); }
432
433 // return true if we are in single selection mode, false if multi sel
434 bool IsSingleSel() const { return HasFlag(wxLC_SINGLE_SEL); }
435
436 // do we have a header window?
437 bool HasHeader() const
438 { return InReportView() && !HasFlag(wxLC_NO_HEADER); }
439
440 void HighlightAll( bool on );
441
442 // all these functions only do something if the line is currently visible
443
444 // change the line "selected" state, return true if it really changed
445 bool HighlightLine( size_t line, bool highlight = true);
446
447 // as HighlightLine() but do it for the range of lines: this is incredibly
448 // more efficient for virtual list controls!
449 //
450 // NB: unlike HighlightLine() this one does refresh the lines on screen
451 void HighlightLines( size_t lineFrom, size_t lineTo, bool on = true );
452
453 // toggle the line state and refresh it
454 void ReverseHighlight( size_t line )
455 { HighlightLine(line, !IsHighlighted(line)); RefreshLine(line); }
456
457 // return true if the line is highlighted
458 bool IsHighlighted(size_t line) const;
459
460 // refresh one or several lines at once
461 void RefreshLine( size_t line );
462 void RefreshLines( size_t lineFrom, size_t lineTo );
463
464 // refresh all selected items
465 void RefreshSelected();
466
467 // refresh all lines below the given one: the difference with
468 // RefreshLines() is that the index here might not be a valid one (happens
469 // when the last line is deleted)
470 void RefreshAfter( size_t lineFrom );
471
472 // the methods which are forwarded to wxListLineData itself in list/icon
473 // modes but are here because the lines don't store their positions in the
474 // report mode
475
476 // get the bound rect for the entire line
477 wxRect GetLineRect(size_t line) const;
478
479 // get the bound rect of the label
480 wxRect GetLineLabelRect(size_t line) const;
481
482 // get the bound rect of the items icon (only may be called if we do have
483 // an icon!)
484 wxRect GetLineIconRect(size_t line) const;
485
486 // get the rect to be highlighted when the item has focus
487 wxRect GetLineHighlightRect(size_t line) const;
488
489 // get the size of the total line rect
490 wxSize GetLineSize(size_t line) const
491 { return GetLineRect(line).GetSize(); }
492
493 // return the hit code for the corresponding position (in this line)
494 long HitTestLine(size_t line, int x, int y) const;
495
496 // bring the selected item into view, scrolling to it if necessary
497 void MoveToItem(size_t item);
498
499 bool ScrollList( int WXUNUSED(dx), int dy );
500
501 // bring the current item into view
502 void MoveToFocus() { MoveToItem(m_current); }
503
504 // start editing the label of the given item
505 wxTextCtrl *EditLabel(long item,
506 wxClassInfo* textControlClass = CLASSINFO(wxTextCtrl));
507 wxTextCtrl *GetEditControl() const
508 {
509 return m_textctrlWrapper ? m_textctrlWrapper->GetText() : NULL;
510 }
511
512 void ResetTextControl(wxTextCtrl *text)
513 {
514 delete text;
515 m_textctrlWrapper = NULL;
516 }
517
518 void OnRenameTimer();
519 bool OnRenameAccept(size_t itemEdit, const wxString& value);
520 void OnRenameCancelled(size_t itemEdit);
521
522 void OnMouse( wxMouseEvent &event );
523
524 // called to switch the selection from the current item to newCurrent,
525 void OnArrowChar( size_t newCurrent, const wxKeyEvent& event );
526
527 void OnChar( wxKeyEvent &event );
528 void OnKeyDown( wxKeyEvent &event );
529 void OnKeyUp( wxKeyEvent &event );
530 void OnSetFocus( wxFocusEvent &event );
531 void OnKillFocus( wxFocusEvent &event );
532 void OnScroll( wxScrollWinEvent& event );
533
534 void OnPaint( wxPaintEvent &event );
535
536 void OnChildFocus(wxChildFocusEvent& event);
537
538 void DrawImage( int index, wxDC *dc, int x, int y );
539 void GetImageSize( int index, int &width, int &height ) const;
540 int GetTextLength( const wxString &s ) const;
541
542 void SetImageList( wxImageList *imageList, int which );
543 void SetItemSpacing( int spacing, bool isSmall = false );
544 int GetItemSpacing( bool isSmall = false );
545
546 void SetColumn( int col, wxListItem &item );
547 void SetColumnWidth( int col, int width );
548 void GetColumn( int col, wxListItem &item ) const;
549 int GetColumnWidth( int col ) const;
550 int GetColumnCount() const { return m_columns.GetCount(); }
551
552 // returns the sum of the heights of all columns
553 int GetHeaderWidth() const;
554
555 int GetCountPerPage() const;
556
557 void SetItem( wxListItem &item );
558 void GetItem( wxListItem &item ) const;
559 void SetItemState( long item, long state, long stateMask );
560 void SetItemStateAll( long state, long stateMask );
561 int GetItemState( long item, long stateMask ) const;
562 bool GetItemRect( long item, wxRect &rect ) const
563 {
564 return GetSubItemRect(item, wxLIST_GETSUBITEMRECT_WHOLEITEM, rect);
565 }
566 bool GetSubItemRect( long item, long subItem, wxRect& rect ) const;
567 wxRect GetViewRect() const;
568 bool GetItemPosition( long item, wxPoint& pos ) const;
569 int GetSelectedItemCount() const;
570
571 wxString GetItemText(long item) const
572 {
573 wxListItem info;
574 info.m_mask = wxLIST_MASK_TEXT;
575 info.m_itemId = item;
576 GetItem( info );
577 return info.m_text;
578 }
579
580 void SetItemText(long item, const wxString& value)
581 {
582 wxListItem info;
583 info.m_mask = wxLIST_MASK_TEXT;
584 info.m_itemId = item;
585 info.m_text = value;
586 SetItem( info );
587 }
588
589 wxImageList* GetSmallImageList() const
590 { return m_small_image_list; }
591
592 // set the scrollbars and update the positions of the items
593 void RecalculatePositions(bool noRefresh = false);
594
595 // refresh the window and the header
596 void RefreshAll();
597
598 long GetNextItem( long item, int geometry, int state ) const;
599 void DeleteItem( long index );
600 void DeleteAllItems();
601 void DeleteColumn( int col );
602 void DeleteEverything();
603 void EnsureVisible( long index );
604 long FindItem( long start, const wxString& str, bool partial = false );
605 long FindItem( long start, wxUIntPtr data);
606 long FindItem( const wxPoint& pt );
607 long HitTest( int x, int y, int &flags ) const;
608 void InsertItem( wxListItem &item );
609 void InsertColumn( long col, wxListItem &item );
610 int GetItemWidthWithImage(wxListItem * item);
611 void SortItems( wxListCtrlCompare fn, long data );
612
613 size_t GetItemCount() const;
614 bool IsEmpty() const { return GetItemCount() == 0; }
615 void SetItemCount(long count);
616
617 // change the current (== focused) item, send a notification event
618 void ChangeCurrent(size_t current);
619 void ResetCurrent() { ChangeCurrent((size_t)-1); }
620 bool HasCurrent() const { return m_current != (size_t)-1; }
621
622 // send out a wxListEvent
623 void SendNotify( size_t line,
624 wxEventType command,
625 const wxPoint& point = wxDefaultPosition );
626
627 // override base class virtual to reset m_lineHeight when the font changes
628 virtual bool SetFont(const wxFont& font)
629 {
630 if ( !wxWindow::SetFont(font) )
631 return false;
632
633 m_lineHeight = 0;
634
635 return true;
636 }
637
638 // these are for wxListLineData usage only
639
640 // get the backpointer to the list ctrl
641 wxGenericListCtrl *GetListCtrl() const
642 {
643 return wxStaticCast(GetParent(), wxGenericListCtrl);
644 }
645
646 // get the height of all lines (assuming they all do have the same height)
647 wxCoord GetLineHeight() const;
648
649 // get the y position of the given line (only for report view)
650 wxCoord GetLineY(size_t line) const;
651
652 // get the brush to use for the item highlighting
653 wxBrush *GetHighlightBrush() const
654 {
655 return m_hasFocus ? m_highlightBrush : m_highlightUnfocusedBrush;
656 }
657
658 bool HasFocus() const
659 {
660 return m_hasFocus;
661 }
662
663protected:
664 // the array of all line objects for a non virtual list control (for the
665 // virtual list control we only ever use m_lines[0])
666 wxListLineDataArray m_lines;
667
668 // the list of column objects
669 wxListHeaderDataList m_columns;
670
671 // currently focused item or -1
672 size_t m_current;
673
674 // the number of lines per page
675 int m_linesPerPage;
676
677 // this flag is set when something which should result in the window
678 // redrawing happens (i.e. an item was added or deleted, or its appearance
679 // changed) and OnPaint() doesn't redraw the window while it is set which
680 // allows to minimize the number of repaintings when a lot of items are
681 // being added. The real repainting occurs only after the next OnIdle()
682 // call
683 bool m_dirty;
684
685 wxColour *m_highlightColour;
686 wxImageList *m_small_image_list;
687 wxImageList *m_normal_image_list;
688 int m_small_spacing;
689 int m_normal_spacing;
690 bool m_hasFocus;
691
692 bool m_lastOnSame;
693 wxTimer *m_renameTimer;
694 bool m_isCreated;
695 int m_dragCount;
696 wxPoint m_dragStart;
697 ColWidthArray m_aColWidths;
698
699 // for double click logic
700 size_t m_lineLastClicked,
701 m_lineBeforeLastClicked,
702 m_lineSelectSingleOnUp;
703
704protected:
705 wxWindow *GetMainWindowOfCompositeControl() { return GetParent(); }
706
707 // the total count of items in a virtual list control
708 size_t m_countVirt;
709
710 // the object maintaining the items selection state, only used in virtual
711 // controls
712 wxSelectionStore m_selStore;
713
714 // common part of all ctors
715 void Init();
716
717 // get the line data for the given index
718 wxListLineData *GetLine(size_t n) const
719 {
720 wxASSERT_MSG( n != (size_t)-1, _T("invalid line index") );
721
722 if ( IsVirtual() )
723 {
724 wxConstCast(this, wxListMainWindow)->CacheLineData(n);
725 n = 0;
726 }
727
728 return &m_lines[n];
729 }
730
731 // get a dummy line which can be used for geometry calculations and such:
732 // you must use GetLine() if you want to really draw the line
733 wxListLineData *GetDummyLine() const;
734
735 // cache the line data of the n-th line in m_lines[0]
736 void CacheLineData(size_t line);
737
738 // get the range of visible lines
739 void GetVisibleLinesRange(size_t *from, size_t *to);
740
741 // force us to recalculate the range of visible lines
742 void ResetVisibleLinesRange() { m_lineFrom = (size_t)-1; }
743
744 // get the colour to be used for drawing the rules
745 wxColour GetRuleColour() const
746 {
747 return wxSystemSettings::GetColour(wxSYS_COLOUR_3DLIGHT);
748 }
749
750private:
751 // initialize the current item if needed
752 void UpdateCurrent();
753
754 // delete all items but don't refresh: called from dtor
755 void DoDeleteAllItems();
756
757 // the height of one line using the current font
758 wxCoord m_lineHeight;
759
760 // the total header width or 0 if not calculated yet
761 wxCoord m_headerWidth;
762
763 // the first and last lines being shown on screen right now (inclusive),
764 // both may be -1 if they must be calculated so never access them directly:
765 // use GetVisibleLinesRange() above instead
766 size_t m_lineFrom,
767 m_lineTo;
768
769 // the brushes to use for item highlighting when we do/don't have focus
770 wxBrush *m_highlightBrush,
771 *m_highlightUnfocusedBrush;
772
773 // wrapper around the text control currently used for in place editing or
774 // NULL if no item is being edited
775 wxListTextCtrlWrapper *m_textctrlWrapper;
776
777
778 DECLARE_EVENT_TABLE()
779
780 friend class wxGenericListCtrl;
781};
782
783#endif // wxUSE_LISTCTRL
784#endif // _WX_GENERIC_LISTCTRL_PRIVATE_H_