]> git.saurik.com Git - wxWidgets.git/blob - src/common/listctrlcmn.cpp
Return NULL from wxWindow::GetCapture() when the capture is being lost.
[wxWidgets.git] / src / common / listctrlcmn.cpp
1 ////////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/listctrlcmn.cpp
3 // Purpose: Common defines for wxListCtrl and wxListCtrl-based classes.
4 // Author: Kevin Ollivier
5 // Created: 09/15/06
6 // Copyright: (c) Kevin Ollivier
7 // Licence: wxWindows licence
8 ////////////////////////////////////////////////////////////////////////////////
9
10 // =============================================================================
11 // declarations
12 // =============================================================================
13
14 // -----------------------------------------------------------------------------
15 // headers
16 // -----------------------------------------------------------------------------
17
18 // For compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 #if wxUSE_LISTCTRL
26
27 #include "wx/listctrl.h"
28
29 #ifndef WX_PRECOMP
30 #include "wx/dcclient.h"
31 #endif
32
33 const char wxListCtrlNameStr[] = "listCtrl";
34
35 // ListCtrl events
36 wxDEFINE_EVENT( wxEVT_LIST_BEGIN_DRAG, wxListEvent );
37 wxDEFINE_EVENT( wxEVT_LIST_BEGIN_RDRAG, wxListEvent );
38 wxDEFINE_EVENT( wxEVT_LIST_BEGIN_LABEL_EDIT, wxListEvent );
39 wxDEFINE_EVENT( wxEVT_LIST_END_LABEL_EDIT, wxListEvent );
40 wxDEFINE_EVENT( wxEVT_LIST_DELETE_ITEM, wxListEvent );
41 wxDEFINE_EVENT( wxEVT_LIST_DELETE_ALL_ITEMS, wxListEvent );
42 wxDEFINE_EVENT( wxEVT_LIST_ITEM_SELECTED, wxListEvent );
43 wxDEFINE_EVENT( wxEVT_LIST_ITEM_DESELECTED, wxListEvent );
44 wxDEFINE_EVENT( wxEVT_LIST_KEY_DOWN, wxListEvent );
45 wxDEFINE_EVENT( wxEVT_LIST_INSERT_ITEM, wxListEvent );
46 wxDEFINE_EVENT( wxEVT_LIST_COL_CLICK, wxListEvent );
47 wxDEFINE_EVENT( wxEVT_LIST_COL_RIGHT_CLICK, wxListEvent );
48 wxDEFINE_EVENT( wxEVT_LIST_COL_BEGIN_DRAG, wxListEvent );
49 wxDEFINE_EVENT( wxEVT_LIST_COL_DRAGGING, wxListEvent );
50 wxDEFINE_EVENT( wxEVT_LIST_COL_END_DRAG, wxListEvent );
51 wxDEFINE_EVENT( wxEVT_LIST_ITEM_RIGHT_CLICK, wxListEvent );
52 wxDEFINE_EVENT( wxEVT_LIST_ITEM_MIDDLE_CLICK, wxListEvent );
53 wxDEFINE_EVENT( wxEVT_LIST_ITEM_ACTIVATED, wxListEvent );
54 wxDEFINE_EVENT( wxEVT_LIST_ITEM_FOCUSED, wxListEvent );
55 wxDEFINE_EVENT( wxEVT_LIST_CACHE_HINT, wxListEvent );
56
57 // -----------------------------------------------------------------------------
58 // XTI
59 // -----------------------------------------------------------------------------
60
61 wxDEFINE_FLAGS( wxListCtrlStyle )
62 wxBEGIN_FLAGS( wxListCtrlStyle )
63 // new style border flags, we put them first to
64 // use them for streaming out
65 wxFLAGS_MEMBER(wxBORDER_SIMPLE)
66 wxFLAGS_MEMBER(wxBORDER_SUNKEN)
67 wxFLAGS_MEMBER(wxBORDER_DOUBLE)
68 wxFLAGS_MEMBER(wxBORDER_RAISED)
69 wxFLAGS_MEMBER(wxBORDER_STATIC)
70 wxFLAGS_MEMBER(wxBORDER_NONE)
71
72 // old style border flags
73 wxFLAGS_MEMBER(wxSIMPLE_BORDER)
74 wxFLAGS_MEMBER(wxSUNKEN_BORDER)
75 wxFLAGS_MEMBER(wxDOUBLE_BORDER)
76 wxFLAGS_MEMBER(wxRAISED_BORDER)
77 wxFLAGS_MEMBER(wxSTATIC_BORDER)
78 wxFLAGS_MEMBER(wxBORDER)
79
80 // standard window styles
81 wxFLAGS_MEMBER(wxTAB_TRAVERSAL)
82 wxFLAGS_MEMBER(wxCLIP_CHILDREN)
83 wxFLAGS_MEMBER(wxTRANSPARENT_WINDOW)
84 wxFLAGS_MEMBER(wxWANTS_CHARS)
85 wxFLAGS_MEMBER(wxFULL_REPAINT_ON_RESIZE)
86 wxFLAGS_MEMBER(wxALWAYS_SHOW_SB )
87 wxFLAGS_MEMBER(wxVSCROLL)
88 wxFLAGS_MEMBER(wxHSCROLL)
89
90 wxFLAGS_MEMBER(wxLC_LIST)
91 wxFLAGS_MEMBER(wxLC_REPORT)
92 wxFLAGS_MEMBER(wxLC_ICON)
93 wxFLAGS_MEMBER(wxLC_SMALL_ICON)
94 wxFLAGS_MEMBER(wxLC_ALIGN_TOP)
95 wxFLAGS_MEMBER(wxLC_ALIGN_LEFT)
96 wxFLAGS_MEMBER(wxLC_AUTOARRANGE)
97 wxFLAGS_MEMBER(wxLC_USER_TEXT)
98 wxFLAGS_MEMBER(wxLC_EDIT_LABELS)
99 wxFLAGS_MEMBER(wxLC_NO_HEADER)
100 wxFLAGS_MEMBER(wxLC_SINGLE_SEL)
101 wxFLAGS_MEMBER(wxLC_SORT_ASCENDING)
102 wxFLAGS_MEMBER(wxLC_SORT_DESCENDING)
103 wxFLAGS_MEMBER(wxLC_VIRTUAL)
104 wxEND_FLAGS( wxListCtrlStyle )
105
106 #if ((!defined(__WXMSW__) && !(defined(__WXMAC__) && wxOSX_USE_CARBON)) || defined(__WXUNIVERSAL__))
107 wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxListCtrl, wxGenericListCtrl, "wx/listctrl.h")
108 #else
109 wxIMPLEMENT_DYNAMIC_CLASS_XTI(wxListCtrl, wxControl, "wx/listctrl.h")
110 #endif
111
112 wxBEGIN_PROPERTIES_TABLE(wxListCtrl)
113 wxEVENT_PROPERTY( TextUpdated, wxEVT_TEXT, wxCommandEvent )
114
115 wxPROPERTY_FLAGS( WindowStyle, wxListCtrlStyle, long, SetWindowStyleFlag, \
116 GetWindowStyleFlag, wxEMPTY_PARAMETER_VALUE, 0 /*flags*/, \
117 wxT("Helpstring"), wxT("group")) // style
118 wxEND_PROPERTIES_TABLE()
119
120 wxEMPTY_HANDLERS_TABLE(wxListCtrl)
121
122 wxCONSTRUCTOR_5( wxListCtrl, wxWindow*, Parent, wxWindowID, Id, \
123 wxPoint, Position, wxSize, Size, long, WindowStyle )
124
125 /*
126 TODO : Expose more information of a list's layout etc. via appropriate objects
127 (see NotebookPageInfo)
128 */
129
130 IMPLEMENT_DYNAMIC_CLASS(wxListView, wxListCtrl)
131 IMPLEMENT_DYNAMIC_CLASS(wxListItem, wxObject)
132 IMPLEMENT_DYNAMIC_CLASS(wxListEvent, wxNotifyEvent)
133
134 // ----------------------------------------------------------------------------
135 // wxListCtrlBase implementation
136 // ----------------------------------------------------------------------------
137
138 long
139 wxListCtrlBase::AppendColumn(const wxString& heading,
140 wxListColumnFormat format,
141 int width)
142 {
143 return InsertColumn(GetColumnCount(), heading, format, width);
144 }
145
146 long
147 wxListCtrlBase::InsertColumn(long col,
148 const wxString& heading,
149 int format,
150 int width)
151 {
152 wxListItem item;
153 item.m_mask = wxLIST_MASK_TEXT | wxLIST_MASK_FORMAT;
154 item.m_text = heading;
155 if ( width >= 0
156 || width == wxLIST_AUTOSIZE
157 || width == wxLIST_AUTOSIZE_USEHEADER )
158 {
159 item.m_mask |= wxLIST_MASK_WIDTH;
160 item.m_width = width;
161 }
162 item.m_format = format;
163
164 return InsertColumn(col, item);
165 }
166
167 long wxListCtrlBase::InsertColumn(long col, const wxListItem& info)
168 {
169 long rc = DoInsertColumn(col, info);
170 if ( rc != -1 )
171 {
172 // As our best size calculation depends on the column headers,
173 // invalidate the previously cached best size when a column is added.
174 InvalidateBestSize();
175 }
176
177 return rc;
178 }
179
180 wxSize wxListCtrlBase::DoGetBestClientSize() const
181 {
182 // There is no obvious way to determine the best size in icon and list
183 // modes so just don't do it for now.
184 if ( !InReportView() )
185 return wxControl::DoGetBestClientSize();
186
187 int totalWidth;
188 wxClientDC dc(const_cast<wxListCtrlBase*>(this));
189
190 // In report mode, we use only the column headers, not items, to determine
191 // the best width. The reason for this is that it's easier (we can't just
192 // iterate over all items, especially not in a virtual control, so we'd
193 // have to do something relatively complicated such as checking the size of
194 // some items in the beginning and the end only) and also because the
195 // columns are usually static while the list contents is dynamic so it
196 // usually doesn't make much sense to adjust the control size to it anyhow.
197 // And finally, scrollbars can always be used with the items while the
198 // headers are just truncated if there is not enough place for them.
199 const int columns = GetColumnCount();
200 if ( HasFlag(wxLC_NO_HEADER) || !columns )
201 {
202 // Use some arbitrary width.
203 totalWidth = 50*dc.GetCharWidth();
204 }
205 else // We do have columns, use them to determine the best width.
206 {
207 totalWidth = 0;
208 for ( int col = 0; col < columns; col++ )
209 {
210 totalWidth += GetColumnWidth(col);
211 }
212 }
213
214 // Use some arbitrary height, there is no good way to determine it.
215 return wxSize(totalWidth, 10*dc.GetCharHeight());
216 }
217
218 void wxListCtrlBase::SetAlternateRowColour(const wxColour& colour)
219 {
220 wxASSERT(HasFlag(wxLC_VIRTUAL));
221 m_alternateRowColour.SetBackgroundColour(colour);
222 }
223
224 void wxListCtrlBase::EnableAlternateRowColours(bool enable)
225 {
226 if ( enable )
227 {
228 // This code is copied from wxDataViewMainWindow::OnPaint()
229
230 // Determine the alternate rows colour automatically from the
231 // background colour.
232 const wxColour bgColour = GetBackgroundColour();
233
234 // Depending on the background, alternate row color
235 // will be 3% more dark or 50% brighter.
236 int alpha = bgColour.GetRGB() > 0x808080 ? 97 : 150;
237 SetAlternateRowColour(bgColour.ChangeLightness(alpha));
238 }
239 else // Disable striping by setting invalid alternative colour.
240 {
241 SetAlternateRowColour(wxColour());
242 }
243 }
244
245 wxListItemAttr *wxListCtrlBase::OnGetItemAttr(long item) const
246 {
247 return (m_alternateRowColour.GetBackgroundColour().IsOk() && (item % 2))
248 ? wxConstCast(&m_alternateRowColour, wxListItemAttr)
249 : NULL; // no attributes by default
250 }
251
252 #endif // wxUSE_LISTCTRL