1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        wx/univ/listbox.h
3 // Purpose:     the universal listbox
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     30.08.00
7 // Copyright:   (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
8 // Licence:     wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10 
11 #ifndef _WX_UNIV_LISTBOX_H_
12 #define _WX_UNIV_LISTBOX_H_
13 
14 #include "wx/scrolwin.h"    // for wxScrollHelper
15 #include "wx/dynarray.h"
16 #include "wx/arrstr.h"
17 
18 // ----------------------------------------------------------------------------
19 // the actions supported by this control
20 // ----------------------------------------------------------------------------
21 
22 // change the current item
23 #define wxACTION_LISTBOX_SETFOCUS   wxT("setfocus")  // select the item
24 #define wxACTION_LISTBOX_MOVEDOWN   wxT("down")      // select item below
25 #define wxACTION_LISTBOX_MOVEUP     wxT("up")        // select item above
26 #define wxACTION_LISTBOX_PAGEDOWN   wxT("pagedown")  // go page down
27 #define wxACTION_LISTBOX_PAGEUP     wxT("pageup")    // go page up
28 #define wxACTION_LISTBOX_START      wxT("start")     // go to first item
29 #define wxACTION_LISTBOX_END        wxT("end")       // go to last item
30 #define wxACTION_LISTBOX_FIND       wxT("find")      // find item by 1st letter
31 
32 // do something with the current item
33 #define wxACTION_LISTBOX_ACTIVATE   wxT("activate")  // activate (choose)
34 #define wxACTION_LISTBOX_TOGGLE     wxT("toggle")    // togglee selected state
35 #define wxACTION_LISTBOX_SELECT     wxT("select")    // sel this, unsel others
36 #define wxACTION_LISTBOX_SELECTADD  wxT("selectadd") // add to selection
37 #define wxACTION_LISTBOX_UNSELECT   wxT("unselect")  // unselect
38 #define wxACTION_LISTBOX_ANCHOR     wxT("selanchor") // anchor selection
39 
40 // do something with the selection globally (not for single selection ones)
41 #define wxACTION_LISTBOX_SELECTALL   wxT("selectall")   // select all items
42 #define wxACTION_LISTBOX_UNSELECTALL wxT("unselectall") // unselect all items
43 #define wxACTION_LISTBOX_SELTOGGLE   wxT("togglesel")   // invert the selection
44 #define wxACTION_LISTBOX_EXTENDSEL   wxT("extend")      // extend to item
45 
46 // ----------------------------------------------------------------------------
47 // wxListBox: a list of selectable items
48 // ----------------------------------------------------------------------------
49 
50 class WXDLLIMPEXP_CORE wxListBox : public wxListBoxBase, public wxScrollHelper
51 {
52 public:
53     // ctors and such
wxListBox()54     wxListBox() : wxScrollHelper(this) { Init(); }
55     wxListBox(wxWindow *parent,
56               wxWindowID id,
57               const wxPoint& pos = wxDefaultPosition,
58               const wxSize& size = wxDefaultSize,
59               int n = 0, const wxString choices[] = (const wxString *) NULL,
60               long style = 0,
61               const wxValidator& validator = wxDefaultValidator,
62               const wxString& name = wxASCII_STR(wxListBoxNameStr) )
wxScrollHelper(this)63         : wxScrollHelper(this)
64     {
65         Init();
66 
67         Create(parent, id, pos, size, n, choices, style, validator, name);
68     }
69     wxListBox(wxWindow *parent,
70               wxWindowID id,
71               const wxPoint& pos,
72               const wxSize& size,
73               const wxArrayString& choices,
74               long style = 0,
75               const wxValidator& validator = wxDefaultValidator,
76               const wxString& name = wxASCII_STR(wxListBoxNameStr) );
77 
78     virtual ~wxListBox();
79 
80     bool Create(wxWindow *parent,
81                 wxWindowID id,
82                 const wxPoint& pos = wxDefaultPosition,
83                 const wxSize& size = wxDefaultSize,
84                 int n = 0, const wxString choices[] = (const wxString *) NULL,
85                 long style = 0,
86                 const wxValidator& validator = wxDefaultValidator,
87                 const wxString& name = wxASCII_STR(wxListBoxNameStr));
88     bool Create(wxWindow *parent,
89                 wxWindowID id,
90                 const wxPoint& pos,
91                 const wxSize& size,
92                 const wxArrayString& choices,
93                 long style = 0,
94                 const wxValidator& validator = wxDefaultValidator,
95                 const wxString& name = wxASCII_STR(wxListBoxNameStr));
96 
97     // implement the listbox interface defined by wxListBoxBase
98     virtual void DoClear() wxOVERRIDE;
99     virtual void DoDeleteOneItem(unsigned int n) wxOVERRIDE;
100 
101     virtual unsigned int GetCount() const wxOVERRIDE;
102     virtual wxString GetString(unsigned int n) const wxOVERRIDE;
103     virtual void SetString(unsigned int n, const wxString& s) wxOVERRIDE;
104     virtual int FindString(const wxString& s, bool bCase = false) const wxOVERRIDE;
105 
IsSelected(int n)106     virtual bool IsSelected(int n) const wxOVERRIDE
107         { return m_selections.Index(n) != wxNOT_FOUND; }
108     virtual int GetSelection() const wxOVERRIDE;
109     virtual int GetSelections(wxArrayInt& aSelections) const wxOVERRIDE;
110 
111 protected:
112     virtual void DoSetSelection(int n, bool select) wxOVERRIDE;
113 
114     virtual int DoInsertItems(const wxArrayStringsAdapter& items,
115                               unsigned int pos,
116                               void **clientData,
117                               wxClientDataType type) wxOVERRIDE;
118 
119     virtual int DoListHitTest(const wxPoint& point) const wxOVERRIDE;
120 
121     // universal wxComboBox implementation internally uses wxListBox
122     friend class WXDLLIMPEXP_FWD_CORE wxComboBox;
123 
124     virtual void DoSetFirstItem(int n) wxOVERRIDE;
125 
126     virtual void DoSetItemClientData(unsigned int n, void* clientData) wxOVERRIDE;
127     virtual void* DoGetItemClientData(unsigned int n) const wxOVERRIDE;
128 
129 public:
130     // override some more base class methods
131     virtual bool SetFont(const wxFont& font) wxOVERRIDE;
132 
133     // the wxUniversal-specific methods
134     // --------------------------------
135 
136     // the current item is the same as the selected one for wxLB_SINGLE
137     // listboxes but for the other ones it is just the focused item which may
138     // be selected or not
GetCurrentItem()139     int GetCurrentItem() const { return m_current; }
140     void SetCurrentItem(int n);
141 
142     // select the item which is diff items below the current one
143     void ChangeCurrent(int diff);
144 
145     // activate (i.e. send a LISTBOX_DOUBLECLICKED message) the specified or
146     // current (if -1) item
147     void Activate(int item = -1);
148 
149     // select or unselect the specified or current (if -1) item
150     void DoSelect(int item = -1, bool sel = true);
151 
152     // more readable wrapper
DoUnselect(int item)153     void DoUnselect(int item) { DoSelect(item, false); }
154 
155     // select an item and send a notification about it
156     void SelectAndNotify(int item);
157 
158     // ensure that the given item is visible by scrolling it into view
159     virtual void EnsureVisible(int n) wxOVERRIDE;
160 
161     // find the first item [strictly] after the current one which starts with
162     // the given string and make it the current one, return true if the current
163     // item changed
164     bool FindItem(const wxString& prefix, bool strictlyAfter = false);
FindNextItem(const wxString & prefix)165     bool FindNextItem(const wxString& prefix) { return FindItem(prefix, true); }
166 
167     // extend the selection to span the range from the anchor (see below) to
168     // the specified or current item
169     void ExtendSelection(int itemTo = -1);
170 
171     // make this item the new selection anchor: extending selection with
172     // ExtendSelection() will work with it
AnchorSelection(int itemFrom)173     void AnchorSelection(int itemFrom) { m_selAnchor = itemFrom; }
174 
175     // get, calculating it if necessary, the number of items per page, the
176     // height of each line and the max width of an item
177     int GetItemsPerPage() const;
178     wxCoord GetLineHeight() const;
179     wxCoord GetMaxWidth() const;
180 
181     // override the wxControl virtual methods
182     virtual bool PerformAction(const wxControlAction& action,
183                                long numArg = 0l,
184                                const wxString& strArg = wxEmptyString) wxOVERRIDE;
185 
186     static wxInputHandler *GetStdInputHandler(wxInputHandler *handlerDef);
DoGetStdInputHandler(wxInputHandler * handlerDef)187     virtual wxInputHandler *DoGetStdInputHandler(wxInputHandler *handlerDef) wxOVERRIDE
188     {
189         return GetStdInputHandler(handlerDef);
190     }
191 
192     // idle processing
193     virtual void OnInternalIdle() wxOVERRIDE;
194 
195 protected:
196     // geometry
197     virtual wxSize DoGetBestClientSize() const wxOVERRIDE;
198     virtual void DoSetSize(int x, int y,
199                            int width, int height,
200                            int sizeFlags = wxSIZE_AUTO) wxOVERRIDE;
201 
202     virtual void DoDraw(wxControlRenderer *renderer) wxOVERRIDE;
203     virtual wxBorder GetDefaultBorder() const wxOVERRIDE;
204 
205     // special hook for wxCheckListBox which allows it to update its internal
206     // data when a new item is inserted into the listbox
OnItemInserted(unsigned int WXUNUSED (pos))207     virtual void OnItemInserted(unsigned int WXUNUSED(pos)) { }
208 
209 
210     // common part of all ctors
211     void Init();
212 
213     // event handlers
214     void OnSize(wxSizeEvent& event);
215 
216     // refresh the given item(s) or everything
217     void RefreshItems(int from, int count);
218     void RefreshItem(int n);
219     void RefreshFromItemToEnd(int n);
220     void RefreshAll();
221 
222     // send an event of the given type (using m_current by default)
223     bool SendEvent(wxEventType type, int item = -1);
224 
225     // calculate the number of items per page using our current size
226     void CalcItemsPerPage();
227 
228     // can/should we have a horz scrollbar?
HasHorzScrollbar()229     bool HasHorzScrollbar() const
230         { return (m_windowStyle & wxLB_HSCROLL) != 0; }
231 
232     // redraw the items in the given range only: called from DoDraw()
233     virtual void DoDrawRange(wxControlRenderer *renderer,
234                              int itemFirst, int itemLast);
235 
236     // update the scrollbars and then ensure that the item is visible
237     void DoEnsureVisible(int n);
238 
239     // mark horz scrollbar for updating
240     void RefreshHorzScrollbar();
241 
242     // update (show/hide/adjust) the scrollbars
243     void UpdateScrollbars();
244 
245     // refresh the items specified by m_updateCount and m_updateFrom
246     void UpdateItems();
247 
248     // the array containing all items (it is sorted if the listbox has
249     // wxLB_SORT style)
250     union
251     {
252         wxArrayString *unsorted;
253         wxSortedArrayString *sorted;
254     } m_strings;
255 
256     // this array contains the indices of the selected items (for the single
257     // selection listboxes only the first element of it is used and contains
258     // the current selection)
259     wxArrayInt m_selections;
260 
261     // and this one the client data (either void or wxClientData)
262     wxArrayPtrVoid m_itemsClientData;
263 
264     // this is hold the input handler type. the input handler is different
265     // between ListBox and its subclass--CheckListbox
266     wxString m_inputHandlerType;
267 
268     // the current item
269     int m_current;
270 
271 private:
272     // the range of elements which must be updated: if m_updateCount is 0 no
273     // update is needed, if it is -1 everything must be updated, otherwise
274     // m_updateCount items starting from m_updateFrom have to be redrawn
275     int m_updateFrom,
276         m_updateCount;
277 
278     // the height of one line in the listbox (all lines have the same height)
279     wxCoord m_lineHeight;
280 
281     // the maximal width of a listbox item and the item which has it
282     wxCoord m_maxWidth;
283     int m_maxWidthItem;
284 
285     // the extents of horz and vert scrollbars
286     int m_scrollRangeX,
287         m_scrollRangeY;
288 
289     // the number of items per page
290     size_t m_itemsPerPage;
291 
292     // if the number of items has changed we may need to show/hide the
293     // scrollbar
294     bool m_updateScrollbarX, m_updateScrollbarY,
295          m_showScrollbarX, m_showScrollbarY;
296 
297     // if the current item has changed, we might need to scroll if it went out
298     // of the window
299     bool m_currentChanged;
300 
301     // the anchor from which the selection is extended for the listboxes with
302     // wxLB_EXTENDED style - this is set to the last item which was selected
303     // by not extending the selection but by choosing it directly
304     int m_selAnchor;
305 
306     wxDECLARE_EVENT_TABLE();
307     wxDECLARE_DYNAMIC_CLASS(wxListBox);
308 };
309 
310 #endif // _WX_UNIV_LISTBOX_H_
311