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
7 // RCS-ID:      $Id: vlbox.h 61872 2009-09-09 22:37:05Z VZ $
8 // Copyright:   (c) 2003 Vadim Zeitlin <vadim@wxwidgets.org>
9 // Licence:     wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 #ifndef _WX_VLBOX_H_
13 #define _WX_VLBOX_H_
14 
15 #include "wx/vscroll.h"         // base class
16 #include "wx/bitmap.h"
17 
18 class WXDLLIMPEXP_FWD_CORE wxSelectionStore;
19 
20 #define wxVListBoxNameStr wxT("wxVListBox")
21 
22 // ----------------------------------------------------------------------------
23 // wxVListBox
24 // ----------------------------------------------------------------------------
25 
26 /*
27     This class has two main differences from a regular listbox: it can have an
28     arbitrarily huge number of items because it doesn't store them itself but
29     uses OnDrawItem() callback to draw them and its items can have variable
30     height as determined by OnMeasureItem().
31 
32     It emits the same events as wxListBox and the same event macros may be used
33     with it.
34  */
35 class WXDLLEXPORT wxVListBox : public wxVScrolledWindow
36 {
37 public:
38     // constructors and such
39     // ---------------------
40 
41     // default constructor, you must call Create() later
wxVListBox()42     wxVListBox() { Init(); }
43 
44     // normal constructor which calls Create() internally
45     wxVListBox(wxWindow *parent,
46                wxWindowID id = wxID_ANY,
47                const wxPoint& pos = wxDefaultPosition,
48                const wxSize& size = wxDefaultSize,
49                long style = 0,
50                const wxString& name = wxVListBoxNameStr)
51     {
52         Init();
53 
54         (void)Create(parent, id, pos, size, style, name);
55     }
56 
57     // really creates the control and sets the initial number of items in it
58     // (which may be changed later with SetItemCount())
59     //
60     // the only special style which may be specified here is wxLB_MULTIPLE
61     //
62     // returns true on success or false if the control couldn't be created
63     bool Create(wxWindow *parent,
64                 wxWindowID id = wxID_ANY,
65                 const wxPoint& pos = wxDefaultPosition,
66                 const wxSize& size = wxDefaultSize,
67                 long style = 0,
68                 const wxString& name = wxVListBoxNameStr);
69 
70     // dtor does some internal cleanup (deletes m_selStore if any)
71     virtual ~wxVListBox();
72 
73 
74     // accessors
75     // ---------
76 
77     // get the number of items in the control
GetItemCount()78     size_t GetItemCount() const { return GetLineCount(); }
79 
80     // does this control use multiple selection?
HasMultipleSelection()81     bool HasMultipleSelection() const { return m_selStore != NULL; }
82 
83     // get the currently selected item or wxNOT_FOUND if there is no selection
84     //
85     // this method is only valid for the single selection listboxes
GetSelection()86     int GetSelection() const
87     {
88         wxASSERT_MSG( !HasMultipleSelection(),
89                         wxT("GetSelection() can't be used with wxLB_MULTIPLE") );
90 
91         return m_current;
92     }
93 
94     // is this item the current one?
IsCurrent(size_t item)95     bool IsCurrent(size_t item) const { return item == (size_t)m_current; }
96     #ifdef __WXUNIVERSAL__
IsCurrent()97     bool IsCurrent() const { return wxVScrolledWindow::IsCurrent(); }
98     #endif
99 
100     // is this item selected?
101     bool IsSelected(size_t item) const;
102 
103     // get the number of the selected items (maybe 0)
104     //
105     // this method is valid for both single and multi selection listboxes
106     size_t GetSelectedCount() const;
107 
108     // get the first selected item, returns wxNOT_FOUND if none
109     //
110     // cookie is an opaque parameter which should be passed to
111     // GetNextSelected() later
112     //
113     // this method is only valid for the multi selection listboxes
114     int GetFirstSelected(unsigned long& cookie) const;
115 
116     // get next selection item, return wxNOT_FOUND if no more
117     //
118     // cookie must be the same parameter that was passed to GetFirstSelected()
119     // before
120     //
121     // this method is only valid for the multi selection listboxes
122     int GetNextSelected(unsigned long& cookie) const;
123 
124     // get the margins around each item
GetMargins()125     wxPoint GetMargins() const { return m_ptMargins; }
126 
127     // get the background colour of selected cells
GetSelectionBackground()128     const wxColour& GetSelectionBackground() const { return m_colBgSel; }
129 
130 
131     // operations
132     // ----------
133 
134     // set the number of items to be shown in the control
135     //
136     // this is just a synonym for wxVScrolledWindow::SetLineCount()
137     virtual void SetItemCount(size_t count);
138 
139     // delete all items from the control
Clear()140     void Clear() { SetItemCount(0); }
141 
142     // set the selection to the specified item, if it is wxNOT_FOUND the
143     // selection is unset
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
149     // equal to wxNOT_FOUND)
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
Toggle(size_t item)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)
SelectAll()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()
DeselectAll()179     bool DeselectAll() { return DoSelectAll(false); }
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);
SetMargins(wxCoord x,wxCoord y)187     void SetMargins(wxCoord x, wxCoord y) { SetMargins(wxPoint(x, y)); }
188 
189     // change the background colour of the selected cells
190     void SetSelectionBackground(const wxColour& col);
191 
192 
GetDefaultAttributes()193     virtual wxVisualAttributes GetDefaultAttributes() const
194     {
195         return GetClassDefaultAttributes(GetWindowVariant());
196     }
197 
198     static wxVisualAttributes
199     GetClassDefaultAttributes(wxWindowVariant variant = wxWINDOW_VARIANT_NORMAL);
200 
201 protected:
202     // the derived class must implement this function to actually draw the item
203     // with the given index on the provided DC
204     virtual void OnDrawItem(wxDC& dc, const wxRect& rect, size_t n) const = 0;
205 
206     // the derived class must implement this method to return the height of the
207     // specified item
208     virtual wxCoord OnMeasureItem(size_t n) const = 0;
209 
210     // this method may be used to draw separators between the lines; note that
211     // the rectangle may be modified, typically to deflate it a bit before
212     // passing to OnDrawItem()
213     //
214     // the base class version doesn't do anything
215     virtual void OnDrawSeparator(wxDC& dc, wxRect& rect, size_t n) const;
216 
217     // this method is used to draw the items background and, maybe, a border
218     // around it
219     //
220     // the base class version implements a reasonable default behaviour which
221     // consists in drawing the selected item with the standard background
222     // colour and drawing a border around the item if it is either selected or
223     // current
224     virtual void OnDrawBackground(wxDC& dc, const wxRect& rect, size_t n) const;
225 
226     // we implement OnGetLineHeight() in terms of OnMeasureItem() because this
227     // allows us to add borders to the items easily
228     //
229     // this function is not supposed to be overridden by the derived classes
230     virtual wxCoord OnGetLineHeight(size_t line) const;
231 
232 
233     // event handlers
234     void OnPaint(wxPaintEvent& event);
235     void OnKeyDown(wxKeyEvent& event);
236     void OnLeftDown(wxMouseEvent& event);
237     void OnLeftDClick(wxMouseEvent& event);
238 
239 
240     // common part of all ctors
241     void Init();
242 
243     // send the wxEVT_COMMAND_LISTBOX_SELECTED event
244     void SendSelectedEvent();
245 
246     // common implementation of SelectAll() and DeselectAll()
247     bool DoSelectAll(bool select);
248 
249     // change the current item (in single selection listbox it also implicitly
250     // changes the selection); current may be wxNOT_FOUND in which case there
251     // will be no current item any more
252     //
253     // return true if the current item changed, false otherwise
254     bool DoSetCurrent(int current);
255 
256     // flags for DoHandleItemClick
257     enum
258     {
259         ItemClick_Shift = 1,        // item shift-clicked
260         ItemClick_Ctrl  = 2,        //       ctrl
261         ItemClick_Kbd   = 4         // item selected from keyboard
262     };
263 
264     // common part of keyboard and mouse handling processing code
265     void DoHandleItemClick(int item, int flags);
266 
267 private:
268     // the current item or wxNOT_FOUND
269     //
270     // if m_selStore == NULL this is also the selected item, otherwise the
271     // selections are managed by m_selStore
272     int m_current;
273 
274     // the anchor of the selection for the multiselection listboxes:
275     // shift-clicking an item extends the selection from m_anchor to the item
276     // clicked, for example
277     //
278     // always wxNOT_FOUND for single selection listboxes
279     int m_anchor;
280 
281     // the object managing our selected items if not NULL
282     wxSelectionStore *m_selStore;
283 
284     // margins
285     wxPoint m_ptMargins;
286 
287     // the selection bg colour
288     wxColour m_colBgSel;
289 
290     DECLARE_EVENT_TABLE()
291     DECLARE_NO_COPY_CLASS(wxVListBox)
292     DECLARE_ABSTRACT_CLASS(wxVListBox)
293 };
294 
295 #endif // _WX_VLBOX_H_
296 
297