]>
Commit | Line | Data |
---|---|---|
e0c6027b VZ |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Name: wx/vlbox.h | |
3 | // Purpose: wxVListBox is a virtual listbox with lines of variable height | |
4 | // Author: Vadim Zeitlin | |
5 | // Modified by: | |
6 | // Created: 31.05.03 | |
77ffb593 | 7 | // Copyright: (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org> |
65571936 | 8 | // Licence: wxWindows licence |
e0c6027b VZ |
9 | /////////////////////////////////////////////////////////////////////////////// |
10 | ||
11 | #ifndef _WX_VLBOX_H_ | |
12 | #define _WX_VLBOX_H_ | |
13 | ||
14 | #include "wx/vscroll.h" // base class | |
4c81b431 | 15 | #include "wx/bitmap.h" |
e0c6027b | 16 | |
b5dbe15d | 17 | class WXDLLIMPEXP_FWD_CORE wxSelectionStore; |
a805142d | 18 | extern WXDLLIMPEXP_DATA_CORE(const char) wxVListBoxNameStr[]; |
e0c6027b VZ |
19 | |
20 | // ---------------------------------------------------------------------------- | |
21 | // wxVListBox | |
22 | // ---------------------------------------------------------------------------- | |
23 | ||
24 | /* | |
25 | This class has two main differences from a regular listbox: it can have an | |
26 | arbitrarily huge number of items because it doesn't store them itself but | |
27 | uses OnDrawItem() callback to draw them and its items can have variable | |
28 | height as determined by OnMeasureItem(). | |
29 | ||
30 | It emits the same events as wxListBox and the same event macros may be used | |
31 | with it. | |
32 | */ | |
53a2db12 | 33 | class WXDLLIMPEXP_CORE wxVListBox : public wxVScrolledWindow |
e0c6027b VZ |
34 | { |
35 | public: | |
36 | // constructors and such | |
37 | // --------------------- | |
38 | ||
39 | // default constructor, you must call Create() later | |
40 | wxVListBox() { Init(); } | |
41 | ||
42 | // normal constructor which calls Create() internally | |
43 | wxVListBox(wxWindow *parent, | |
44 | wxWindowID id = wxID_ANY, | |
45 | const wxPoint& pos = wxDefaultPosition, | |
46 | const wxSize& size = wxDefaultSize, | |
e0c6027b VZ |
47 | long style = 0, |
48 | const wxString& name = wxVListBoxNameStr) | |
49 | { | |
50 | Init(); | |
51 | ||
be465555 | 52 | (void)Create(parent, id, pos, size, style, name); |
e0c6027b VZ |
53 | } |
54 | ||
55 | // really creates the control and sets the initial number of items in it | |
56 | // (which may be changed later with SetItemCount()) | |
57 | // | |
be465555 | 58 | // the only special style which may be specified here is wxLB_MULTIPLE |
e0c6027b VZ |
59 | // |
60 | // returns true on success or false if the control couldn't be created | |
61 | bool Create(wxWindow *parent, | |
62 | wxWindowID id = wxID_ANY, | |
63 | const wxPoint& pos = wxDefaultPosition, | |
64 | const wxSize& size = wxDefaultSize, | |
e0c6027b VZ |
65 | long style = 0, |
66 | const wxString& name = wxVListBoxNameStr); | |
67 | ||
be465555 VZ |
68 | // dtor does some internal cleanup (deletes m_selStore if any) |
69 | virtual ~wxVListBox(); | |
70 | ||
71 | ||
72 | // accessors | |
73 | // --------- | |
74 | ||
75 | // get the number of items in the control | |
f18eaf26 | 76 | size_t GetItemCount() const { return GetRowCount(); } |
be465555 VZ |
77 | |
78 | // does this control use multiple selection? | |
79 | bool HasMultipleSelection() const { return m_selStore != NULL; } | |
80 | ||
81 | // get the currently selected item or wxNOT_FOUND if there is no selection | |
82 | // | |
83 | // this method is only valid for the single selection listboxes | |
84 | int GetSelection() const | |
85 | { | |
86 | wxASSERT_MSG( !HasMultipleSelection(), | |
9a83f860 | 87 | wxT("GetSelection() can't be used with wxLB_MULTIPLE") ); |
be465555 VZ |
88 | |
89 | return m_current; | |
90 | } | |
91 | ||
92 | // is this item the current one? | |
93 | bool IsCurrent(size_t item) const { return item == (size_t)m_current; } | |
8a39593e JS |
94 | #ifdef __WXUNIVERSAL__ |
95 | bool IsCurrent() const { return wxVScrolledWindow::IsCurrent(); } | |
96 | #endif | |
be465555 VZ |
97 | |
98 | // is this item selected? | |
99 | bool IsSelected(size_t item) const; | |
100 | ||
101 | // get the number of the selected items (maybe 0) | |
102 | // | |
103 | // this method is valid for both single and multi selection listboxes | |
104 | size_t GetSelectedCount() const; | |
105 | ||
106 | // get the first selected item, returns wxNOT_FOUND if none | |
107 | // | |
108 | // cookie is an opaque parameter which should be passed to | |
109 | // GetNextSelected() later | |
110 | // | |
111 | // this method is only valid for the multi selection listboxes | |
112 | int GetFirstSelected(unsigned long& cookie) const; | |
113 | ||
114 | // get next selection item, return wxNOT_FOUND if no more | |
115 | // | |
116 | // cookie must be the same parameter that was passed to GetFirstSelected() | |
117 | // before | |
118 | // | |
119 | // this method is only valid for the multi selection listboxes | |
120 | int GetNextSelected(unsigned long& cookie) const; | |
121 | ||
122 | // get the margins around each item | |
123 | wxPoint GetMargins() const { return m_ptMargins; } | |
124 | ||
9a9b4940 VZ |
125 | // get the background colour of selected cells |
126 | const wxColour& GetSelectionBackground() const { return m_colBgSel; } | |
127 | ||
293b15f7 VZ |
128 | // get the item rect, returns empty rect if the item is not visible |
129 | wxRect GetItemRect(size_t n) const; | |
e0c6027b VZ |
130 | |
131 | // operations | |
132 | // ---------- | |
133 | ||
134 | // set the number of items to be shown in the control | |
135 | // | |
f18eaf26 | 136 | // this is just a synonym for wxVScrolledWindow::SetRowCount() |
03495767 | 137 | virtual void SetItemCount(size_t count); |
e0c6027b VZ |
138 | |
139 | // delete all items from the control | |
140 | void Clear() { SetItemCount(0); } | |
141 | ||
970b97a2 VZ |
142 | // set the selection to the specified item, if it is wxNOT_FOUND the |
143 | // selection is unset | |
be465555 VZ |
144 | // |
145 | // this function is only valid for the single selection listboxes | |
146 | void SetSelection(int selection); | |
147 | ||
148 | // selects or deselects the specified item which must be valid (i.e. not | |
970b97a2 | 149 | // equal to wxNOT_FOUND) |
be465555 VZ |
150 | // |
151 | // return true if the items selection status has changed or false | |
152 | // otherwise | |
153 | // | |
154 | // this function is only valid for the multiple selection listboxes | |
155 | bool Select(size_t item, bool select = true); | |
156 | ||
157 | // selects the items in the specified range whose end points may be given | |
158 | // in any order | |
159 | // | |
160 | // return true if any items selection status has changed, false otherwise | |
161 | // | |
162 | // this function is only valid for the single selection listboxes | |
163 | bool SelectRange(size_t from, size_t to); | |
164 | ||
165 | // toggle the selection of the specified item (must be valid) | |
166 | // | |
167 | // this function is only valid for the multiple selection listboxes | |
168 | void Toggle(size_t item) { Select(item, !IsSelected(item)); } | |
169 | ||
170 | // select all items in the listbox | |
171 | // | |
172 | // the return code indicates if any items were affected by this operation | |
173 | // (true) or if nothing has changed (false) | |
174 | bool SelectAll() { return DoSelectAll(true); } | |
175 | ||
176 | // unselect all items in the listbox | |
177 | // | |
178 | // the return code has the same meaning as for SelectAll() | |
179 | bool DeselectAll() { return DoSelectAll(false); } | |
e0c6027b VZ |
180 | |
181 | // set the margins: horizontal margin is the distance between the window | |
182 | // border and the item contents while vertical margin is half of the | |
183 | // distance between items | |
184 | // | |
185 | // by default both margins are 0 | |
186 | void SetMargins(const wxPoint& pt); | |
187 | void SetMargins(wxCoord x, wxCoord y) { SetMargins(wxPoint(x, y)); } | |
188 | ||
9a9b4940 VZ |
189 | // change the background colour of the selected cells |
190 | void SetSelectionBackground(const wxColour& col); | |
191 | ||
04125489 VZ |
192 | // refreshes only the selected items |
193 | void RefreshSelected(); | |
194 | ||
e0c6027b | 195 | |
dc596072 RD |
196 | virtual wxVisualAttributes GetDefaultAttributes() const |
197 | { | |
198 | return GetClassDefaultAttributes(GetWindowVariant()); | |
199 | } | |
200 | ||
201 | static wxVisualAttributes | |
202 | GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL); | |
cab1a605 | 203 | |
3c75d8ba | 204 | protected: |
28319afe | 205 | virtual wxBorder GetDefaultBorder() const { return wxBORDER_THEME; } |
a047aff2 | 206 | |
e0c6027b VZ |
207 | // the derived class must implement this function to actually draw the item |
208 | // with the given index on the provided DC | |
209 | virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const = 0; | |
210 | ||
211 | // the derived class must implement this method to return the height of the | |
212 | // specified item | |
213 | virtual wxCoord OnMeasureItem(size_t n) const = 0; | |
214 | ||
215 | // this method may be used to draw separators between the lines; note that | |
216 | // the rectangle may be modified, typically to deflate it a bit before | |
217 | // passing to OnDrawItem() | |
218 | // | |
219 | // the base class version doesn't do anything | |
220 | virtual void OnDrawSeparator(wxDC& dc, wxRect& rect, size_t n) const; | |
221 | ||
27d0dcd0 VZ |
222 | // this method is used to draw the items background and, maybe, a border |
223 | // around it | |
224 | // | |
225 | // the base class version implements a reasonable default behaviour which | |
226 | // consists in drawing the selected item with the standard background | |
227 | // colour and drawing a border around the item if it is either selected or | |
228 | // current | |
229 | virtual void OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const; | |
e0c6027b | 230 | |
e02c72fa | 231 | // we implement OnGetRowHeight() in terms of OnMeasureItem() because this |
e0c6027b VZ |
232 | // allows us to add borders to the items easily |
233 | // | |
0c8392ca | 234 | // this function is not supposed to be overridden by the derived classes |
e02c72fa | 235 | virtual wxCoord OnGetRowHeight(size_t line) const; |
e0c6027b VZ |
236 | |
237 | ||
238 | // event handlers | |
239 | void OnPaint(wxPaintEvent& event); | |
240 | void OnKeyDown(wxKeyEvent& event); | |
241 | void OnLeftDown(wxMouseEvent& event); | |
242 | void OnLeftDClick(wxMouseEvent& event); | |
04125489 | 243 | void OnSetOrKillFocus(wxFocusEvent& event); |
858ad670 | 244 | void OnSize(wxSizeEvent& event); |
e0c6027b VZ |
245 | |
246 | // common part of all ctors | |
247 | void Init(); | |
248 | ||
ce7fe42e | 249 | // send the wxEVT_LISTBOX event |
be465555 | 250 | void SendSelectedEvent(); |
538483d8 | 251 | virtual void InitEvent(wxCommandEvent& event, int n); |
be465555 VZ |
252 | |
253 | // common implementation of SelectAll() and DeselectAll() | |
254 | bool DoSelectAll(bool select); | |
255 | ||
256 | // change the current item (in single selection listbox it also implicitly | |
970b97a2 VZ |
257 | // changes the selection); current may be wxNOT_FOUND in which case there |
258 | // will be no current item any more | |
be465555 VZ |
259 | // |
260 | // return true if the current item changed, false otherwise | |
261 | bool DoSetCurrent(int current); | |
262 | ||
970b97a2 VZ |
263 | // flags for DoHandleItemClick |
264 | enum | |
265 | { | |
266 | ItemClick_Shift = 1, // item shift-clicked | |
267 | ItemClick_Ctrl = 2, // ctrl | |
268 | ItemClick_Kbd = 4 // item selected from keyboard | |
269 | }; | |
270 | ||
be465555 | 271 | // common part of keyboard and mouse handling processing code |
970b97a2 | 272 | void DoHandleItemClick(int item, int flags); |
e0c6027b | 273 | |
c848185a VZ |
274 | // paint the background of the given item using the provided colour if it's |
275 | // valid, otherwise just return false and do nothing (this is used by | |
276 | // OnDrawBackground()) | |
277 | bool DoDrawSolidBackground(const wxColour& col, | |
278 | wxDC& dc, | |
279 | const wxRect& rect, | |
280 | size_t n) const; | |
281 | ||
e0c6027b | 282 | private: |
970b97a2 | 283 | // the current item or wxNOT_FOUND |
be465555 VZ |
284 | // |
285 | // if m_selStore == NULL this is also the selected item, otherwise the | |
286 | // selections are managed by m_selStore | |
287 | int m_current; | |
288 | ||
970b97a2 VZ |
289 | // the anchor of the selection for the multiselection listboxes: |
290 | // shift-clicking an item extends the selection from m_anchor to the item | |
291 | // clicked, for example | |
292 | // | |
293 | // always wxNOT_FOUND for single selection listboxes | |
294 | int m_anchor; | |
295 | ||
be465555 VZ |
296 | // the object managing our selected items if not NULL |
297 | wxSelectionStore *m_selStore; | |
e0c6027b VZ |
298 | |
299 | // margins | |
300 | wxPoint m_ptMargins; | |
301 | ||
9a9b4940 VZ |
302 | // the selection bg colour |
303 | wxColour m_colBgSel; | |
304 | ||
e0c6027b | 305 | DECLARE_EVENT_TABLE() |
c0c133e1 | 306 | wxDECLARE_NO_COPY_CLASS(wxVListBox); |
0c8392ca | 307 | DECLARE_ABSTRACT_CLASS(wxVListBox) |
e0c6027b VZ |
308 | }; |
309 | ||
310 | #endif // _WX_VLBOX_H_ | |
311 |