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 = 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 = 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 = 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 = wxListBoxNameStr);
96 
97     // implement the listbox interface defined by wxListBoxBase
98     virtual void DoClear();
99     virtual void DoDeleteOneItem(unsigned int n);
100 
101     virtual unsigned int GetCount() const;
102     virtual wxString GetString(unsigned int n) const;
103     virtual void SetString(unsigned int n, const wxString& s);
104     virtual int FindString(const wxString& s, bool bCase = false) const;
105 
IsSelected(int n)106     virtual bool IsSelected(int n) const
107         { return m_selections.Index(n) != wxNOT_FOUND; }
108     virtual int GetSelection() const;
109     virtual int GetSelections(wxArrayInt& aSelections) const;
110 
111 protected:
112     virtual void DoSetSelection(int n, bool select);
113 
114     virtual int DoInsertItems(const wxArrayStringsAdapter& items,
115                               unsigned int pos,
116                               void **clientData,
117                               wxClientDataType type);
118 
119     // universal wxComboBox implementation internally uses wxListBox
120     friend class WXDLLIMPEXP_FWD_CORE wxComboBox;
121 
122     virtual void DoSetFirstItem(int n);
123 
124     virtual void DoSetItemClientData(unsigned int n, void* clientData);
125     virtual void* DoGetItemClientData(unsigned int n) const;
126 
127 public:
128     // override some more base class methods
129     virtual bool SetFont(const wxFont& font);
130 
131     // the wxUniversal-specific methods
132     // --------------------------------
133 
134     // the current item is the same as the selected one for wxLB_SINGLE
135     // listboxes but for the other ones it is just the focused item which may
136     // be selected or not
GetCurrentItem()137     int GetCurrentItem() const { return m_current; }
138     void SetCurrentItem(int n);
139 
140     // select the item which is diff items below the current one
141     void ChangeCurrent(int diff);
142 
143     // activate (i.e. send a LISTBOX_DOUBLECLICKED message) the specified or
144     // current (if -1) item
145     void Activate(int item = -1);
146 
147     // select or unselect the specified or current (if -1) item
148     void DoSelect(int item = -1, bool sel = true);
149 
150     // more readable wrapper
DoUnselect(int item)151     void DoUnselect(int item) { DoSelect(item, false); }
152 
153     // select an item and send a notification about it
154     void SelectAndNotify(int item);
155 
156     // ensure that the given item is visible by scrolling it into view
157     virtual void EnsureVisible(int n);
158 
159     // find the first item [strictly] after the current one which starts with
160     // the given string and make it the current one, return true if the current
161     // item changed
162     bool FindItem(const wxString& prefix, bool strictlyAfter = false);
FindNextItem(const wxString & prefix)163     bool FindNextItem(const wxString& prefix) { return FindItem(prefix, true); }
164 
165     // extend the selection to span the range from the anchor (see below) to
166     // the specified or current item
167     void ExtendSelection(int itemTo = -1);
168 
169     // make this item the new selection anchor: extending selection with
170     // ExtendSelection() will work with it
AnchorSelection(int itemFrom)171     void AnchorSelection(int itemFrom) { m_selAnchor = itemFrom; }
172 
173     // get, calculating it if necessary, the number of items per page, the
174     // height of each line and the max width of an item
175     int GetItemsPerPage() const;
176     wxCoord GetLineHeight() const;
177     wxCoord GetMaxWidth() const;
178 
179     // override the wxControl virtual methods
180     virtual bool PerformAction(const wxControlAction& action,
181                                long numArg = 0l,
182                                const wxString& strArg = wxEmptyString);
183 
184     static wxInputHandler *GetStdInputHandler(wxInputHandler *handlerDef);
DoGetStdInputHandler(wxInputHandler * handlerDef)185     virtual wxInputHandler *DoGetStdInputHandler(wxInputHandler *handlerDef)
186     {
187         return GetStdInputHandler(handlerDef);
188     }
189 
190     // idle processing
191     virtual void OnInternalIdle();
192 
193 protected:
194     // geometry
195     virtual wxSize DoGetBestClientSize() const;
196     virtual void DoSetSize(int x, int y,
197                            int width, int height,
198                            int sizeFlags = wxSIZE_AUTO);
199 
200     virtual void DoDraw(wxControlRenderer *renderer);
201     virtual wxBorder GetDefaultBorder() const;
202 
203     // special hook for wxCheckListBox which allows it to update its internal
204     // data when a new item is inserted into the listbox
OnItemInserted(unsigned int WXUNUSED (pos))205     virtual void OnItemInserted(unsigned int WXUNUSED(pos)) { }
206 
207 
208     // common part of all ctors
209     void Init();
210 
211     // event handlers
212     void OnSize(wxSizeEvent& event);
213 
214     // refresh the given item(s) or everything
215     void RefreshItems(int from, int count);
216     void RefreshItem(int n);
217     void RefreshFromItemToEnd(int n);
218     void RefreshAll();
219 
220     // send an event of the given type (using m_current by default)
221     bool SendEvent(wxEventType type, int item = -1);
222 
223     // calculate the number of items per page using our current size
224     void CalcItemsPerPage();
225 
226     // can/should we have a horz scrollbar?
HasHorzScrollbar()227     bool HasHorzScrollbar() const
228         { return (m_windowStyle & wxLB_HSCROLL) != 0; }
229 
230     // redraw the items in the given range only: called from DoDraw()
231     virtual void DoDrawRange(wxControlRenderer *renderer,
232                              int itemFirst, int itemLast);
233 
234     // update the scrollbars and then ensure that the item is visible
235     void DoEnsureVisible(int n);
236 
237     // mark horz scrollbar for updating
238     void RefreshHorzScrollbar();
239 
240     // update (show/hide/adjust) the scrollbars
241     void UpdateScrollbars();
242 
243     // refresh the items specified by m_updateCount and m_updateFrom
244     void UpdateItems();
245 
246     // the array containing all items (it is sorted if the listbox has
247     // wxLB_SORT style)
248     union
249     {
250         wxArrayString *unsorted;
251         wxSortedArrayString *sorted;
252     } m_strings;
253 
254     // this array contains the indices of the selected items (for the single
255     // selection listboxes only the first element of it is used and contains
256     // the current selection)
257     wxArrayInt m_selections;
258 
259     // and this one the client data (either void or wxClientData)
260     wxArrayPtrVoid m_itemsClientData;
261 
262     // the current item
263     int m_current;
264 
265 private:
266     // the range of elements which must be updated: if m_updateCount is 0 no
267     // update is needed, if it is -1 everything must be updated, otherwise
268     // m_updateCount items starting from m_updateFrom have to be redrawn
269     int m_updateFrom,
270         m_updateCount;
271 
272     // the height of one line in the listbox (all lines have the same height)
273     wxCoord m_lineHeight;
274 
275     // the maximal width of a listbox item and the item which has it
276     wxCoord m_maxWidth;
277     int m_maxWidthItem;
278 
279     // the extents of horz and vert scrollbars
280     int m_scrollRangeX,
281         m_scrollRangeY;
282 
283     // the number of items per page
284     size_t m_itemsPerPage;
285 
286     // if the number of items has changed we may need to show/hide the
287     // scrollbar
288     bool m_updateScrollbarX, m_updateScrollbarY,
289          m_showScrollbarX, m_showScrollbarY;
290 
291     // if the current item has changed, we might need to scroll if it went out
292     // of the window
293     bool m_currentChanged;
294 
295     // the anchor from which the selection is extended for the listboxes with
296     // wxLB_EXTENDED style - this is set to the last item which was selected
297     // by not extending the selection but by choosing it directly
298     int m_selAnchor;
299 
300     DECLARE_EVENT_TABLE()
301     DECLARE_DYNAMIC_CLASS(wxListBox)
302 };
303 
304 #endif // _WX_UNIV_LISTBOX_H_
305