1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: wx/univ/listbox.h
3 // Purpose: the universal listbox
4 // Author: Vadim Zeitlin
8 // Copyright: (c) 2000 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence: wxWindows licence
10 ///////////////////////////////////////////////////////////////////////////////
12 #ifndef _WX_UNIV_LISTBOX_H_
13 #define _WX_UNIV_LISTBOX_H_
15 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
16 #pragma interface "univlistbox.h"
19 #include "wx/scrolwin.h" // for wxScrollHelper
20 #include "wx/dynarray.h"
21 #include "wx/arrstr.h"
23 // ----------------------------------------------------------------------------
24 // the actions supported by this control
25 // ----------------------------------------------------------------------------
27 // change the current item
28 #define wxACTION_LISTBOX_SETFOCUS _T("setfocus") // select the item
29 #define wxACTION_LISTBOX_MOVEDOWN _T("down") // select item below
30 #define wxACTION_LISTBOX_MOVEUP _T("up") // select item above
31 #define wxACTION_LISTBOX_PAGEDOWN _T("pagedown") // go page down
32 #define wxACTION_LISTBOX_PAGEUP _T("pageup") // go page up
33 #define wxACTION_LISTBOX_START _T("start") // go to first item
34 #define wxACTION_LISTBOX_END _T("end") // go to last item
35 #define wxACTION_LISTBOX_FIND _T("find") // find item by 1st letter
37 // do something with the current item
38 #define wxACTION_LISTBOX_ACTIVATE _T("activate") // activate (choose)
39 #define wxACTION_LISTBOX_TOGGLE _T("toggle") // togglee selected state
40 #define wxACTION_LISTBOX_SELECT _T("select") // sel this, unsel others
41 #define wxACTION_LISTBOX_SELECTADD _T("selectadd") // add to selection
42 #define wxACTION_LISTBOX_UNSELECT _T("unselect") // unselect
43 #define wxACTION_LISTBOX_ANCHOR _T("selanchor") // anchor selection
45 // do something with the selection globally (not for single selection ones)
46 #define wxACTION_LISTBOX_SELECTALL _T("selectall") // select all items
47 #define wxACTION_LISTBOX_UNSELECTALL _T("unselectall") // unselect all items
48 #define wxACTION_LISTBOX_SELTOGGLE _T("togglesel") // invert the selection
49 #define wxACTION_LISTBOX_EXTENDSEL _T("extend") // extend to item
51 // ----------------------------------------------------------------------------
52 // wxListBox: a list of selectable items
53 // ----------------------------------------------------------------------------
55 class WXDLLEXPORT wxListBox
: public wxListBoxBase
, public wxScrollHelper
59 wxListBox() { Init(); }
60 wxListBox(wxWindow
*parent
,
62 const wxPoint
& pos
= wxDefaultPosition
,
63 const wxSize
& size
= wxDefaultSize
,
64 int n
= 0, const wxString choices
[] = (const wxString
*) NULL
,
66 const wxValidator
& validator
= wxDefaultValidator
,
67 const wxString
& name
= wxListBoxNameStr
)
71 Create(parent
, id
, pos
, size
, n
, choices
, style
, validator
, name
);
76 bool Create(wxWindow
*parent
,
78 const wxPoint
& pos
= wxDefaultPosition
,
79 const wxSize
& size
= wxDefaultSize
,
80 int n
= 0, const wxString choices
[] = (const wxString
*) NULL
,
82 const wxValidator
& validator
= wxDefaultValidator
,
83 const wxString
& name
= wxListBoxNameStr
);
85 // implement the listbox interface defined by wxListBoxBase
87 virtual void Delete(int n
);
89 virtual int GetCount() const { return (int)m_strings
->GetCount(); }
90 virtual wxString
GetString(int n
) const { return (*m_strings
)[n
]; }
91 virtual void SetString(int n
, const wxString
& s
);
92 virtual int FindString(const wxString
& s
) const
93 { return IsSorted() ? m_stringsSorted
->Index(s
) : m_strings
->Index(s
); }
95 virtual bool IsSelected(int n
) const
96 { return m_selections
.Index(n
) != wxNOT_FOUND
; }
97 virtual void SetSelection(int n
, bool select
= TRUE
);
98 virtual int GetSelection() const;
99 virtual int GetSelections(wxArrayInt
& aSelections
) const;
102 virtual int DoAppend(const wxString
& item
);
103 virtual void DoInsertItems(const wxArrayString
& items
, int pos
);
104 virtual void DoSetItems(const wxArrayString
& items
, void **clientData
);
106 virtual void DoSetFirstItem(int n
);
108 virtual void DoSetItemClientData(int n
, void* clientData
);
109 virtual void* DoGetItemClientData(int n
) const;
110 virtual void DoSetItemClientObject(int n
, wxClientData
* clientData
);
111 virtual wxClientData
* DoGetItemClientObject(int n
) const;
114 // override some more base class methods
115 virtual bool SetFont(const wxFont
& font
);
117 // the wxUniversal-specific methods
118 // --------------------------------
120 // the current item is the same as the selected one for wxLB_SINGLE
121 // listboxes but for the other ones it is just the focused item which may
122 // be selected or not
123 int GetCurrentItem() const { return m_current
; }
124 void SetCurrentItem(int n
);
126 // select the item which is diff items below the current one
127 void ChangeCurrent(int diff
);
129 // activate (i.e. send a LISTBOX_DOUBLECLICKED message) the specified or
130 // current (if -1) item
131 void Activate(int item
= -1);
133 // select or unselect the specified or current (if -1) item
134 void DoSelect(int item
= -1, bool sel
= TRUE
);
136 // more readable wrapper
137 void DoUnselect(int item
) { DoSelect(item
, FALSE
); }
139 // select an item and send a notification about it
140 void SelectAndNotify(int item
);
142 // ensure that the given item is visible by scrolling it into view
143 virtual void EnsureVisible(int n
);
145 // find the first item [strictly] after the current one which starts with
146 // the given string and make it the current one, return TRUE if the current
148 bool FindItem(const wxString
& prefix
, bool strictlyAfter
= FALSE
);
149 bool FindNextItem(const wxString
& prefix
) { return FindItem(prefix
, TRUE
); }
151 // extend the selection to span the range from the anchor (see below) to
152 // the specified or current item
153 void ExtendSelection(int itemTo
= -1);
155 // make this item the new selection anchor: extending selection with
156 // ExtendSelection() will work with it
157 void AnchorSelection(int itemFrom
) { m_selAnchor
= itemFrom
; }
159 // get, calculating it if necessary, the number of items per page, the
160 // height of each line and the max width of an item
161 int GetItemsPerPage() const;
162 wxCoord
GetLineHeight() const;
163 wxCoord
GetMaxWidth() const;
165 // override the wxControl virtual methods
166 virtual bool PerformAction(const wxControlAction
& action
,
168 const wxString
& strArg
= wxEmptyString
);
170 // let wxColourScheme choose the right colours for us
171 virtual bool IsContainerWindow() const { return TRUE
; }
174 virtual void OnInternalIdle();
177 virtual wxSize
DoGetBestClientSize() const;
178 virtual void DoSetSize(int x
, int y
,
179 int width
, int height
,
180 int sizeFlags
= wxSIZE_AUTO
);
182 virtual void DoDraw(wxControlRenderer
*renderer
);
183 virtual wxBorder
GetDefaultBorder() const;
185 // common part of all ctors
189 void OnSize(wxSizeEvent
& event
);
191 // common part of Clear() and DoSetItems(): clears everything
192 virtual void DoClear();
194 // refresh the given item(s) or everything
195 void RefreshItems(int from
, int count
);
196 void RefreshItem(int n
);
197 void RefreshFromItemToEnd(int n
);
200 // send an event of the given type (using m_current by default)
201 bool SendEvent(wxEventType type
, int item
= -1);
203 // calculate the number of items per page using our current size
204 void CalcItemsPerPage();
206 // can/should we have a horz scrollbar?
207 bool HasHorzScrollbar() const
208 { return (m_windowStyle
& wxLB_HSCROLL
) != 0; }
210 // redraw the items in the given range only: called from DoDraw()
211 virtual void DoDrawRange(wxControlRenderer
*renderer
,
212 int itemFirst
, int itemLast
);
214 // update the scrollbars and then ensure that the item is visible
215 void DoEnsureVisible(int n
);
217 // mark horz scrollbar for updating
218 void RefreshHorzScrollbar();
220 // update (show/hide/adjust) the scrollbars
221 void UpdateScrollbars();
223 // refresh the items specified by m_updateCount and m_updateFrom
226 // the array containing all items (it is sorted if the listbox has
227 // wxLB_SORT style). Note the evil trick: the pointers share the
228 // same location, hence we use m_strings when we don't care if the
229 // array is sorted or not, m_stringsSorted when we do
232 wxArrayString
* m_strings
;
233 wxSortedArrayString
* m_stringsSorted
;
236 // this array contains the indices of the selected items (for the single
237 // selection listboxes only the first element of it is used and contains
238 // the current selection)
239 wxArrayInt m_selections
;
241 // and this one the client data (either void or wxClientData)
242 wxArrayPtrVoid m_itemsClientData
;
248 // the range of elements which must be updated: if m_updateCount is 0 no
249 // update is needed, if it is -1 everything must be updated, otherwise
250 // m_updateCount items starting from m_updateFrom have to be redrawn
254 // the height of one line in the listbox (all lines have the same height)
255 wxCoord m_lineHeight
;
257 // the maximal width of a listbox item and the item which has it
261 // the extents of horz and vert scrollbars
265 // the number of items per page
266 size_t m_itemsPerPage
;
268 // if the number of items has changed we may need to show/hide the
270 bool m_updateScrollbarX
, m_updateScrollbarY
,
271 m_showScrollbarX
, m_showScrollbarY
;
273 // if the current item has changed, we might need to scroll if it went out
275 bool m_currentChanged
;
277 // the anchor from which the selection is extended for the listboxes with
278 // wxLB_EXTENDED style - this is set to the last item which was selected
279 // by not extending the selection but by choosing it directly
282 DECLARE_EVENT_TABLE()
283 DECLARE_DYNAMIC_CLASS(wxListBox
)
286 // ----------------------------------------------------------------------------
287 // wxStdListboxInputHandler: handles mouse and kbd in a single or multi
289 // ----------------------------------------------------------------------------
291 class WXDLLEXPORT wxStdListboxInputHandler
: public wxStdInputHandler
294 // if pressing the mouse button in a multiselection listbox should toggle
295 // the item under mouse immediately, then specify TRUE as the second
296 // parameter (this is the standard behaviour, under GTK the item is toggled
297 // only when the mouse is released in the multi selection listbox)
298 wxStdListboxInputHandler(wxInputHandler
*inphand
,
299 bool toggleOnPressAlways
= TRUE
);
301 // base class methods
302 virtual bool HandleKey(wxInputConsumer
*consumer
,
303 const wxKeyEvent
& event
,
305 virtual bool HandleMouse(wxInputConsumer
*consumer
,
306 const wxMouseEvent
& event
);
307 virtual bool HandleMouseMove(wxInputConsumer
*consumer
,
308 const wxMouseEvent
& event
);
311 // return the item under mouse, 0 if the mouse is above the listbox or
312 // GetCount() if it is below it
313 int HitTest(const wxListBox
*listbox
, const wxMouseEvent
& event
);
315 // parts of HitTest(): first finds the pseudo (because not in range) index
316 // of the item and the second one adjusts it if necessary - that is if the
317 // third one returns FALSE
318 int HitTestUnsafe(const wxListBox
*listbox
, const wxMouseEvent
& event
);
319 int FixItemIndex(const wxListBox
*listbox
, int item
);
320 bool IsValidIndex(const wxListBox
*listbox
, int item
);
322 // init m_btnCapture and m_actionMouse
323 wxControlAction
SetupCapture(wxListBox
*lbox
,
324 const wxMouseEvent
& event
,
327 wxRenderer
*m_renderer
;
329 // the button which initiated the mouse capture (currently 0 or 1)
332 // the action to perform when the mouse moves while we capture it
333 wxControlAction m_actionMouse
;
335 // the ctor parameter toggleOnPressAlways (see comments near it)
336 bool m_toggleOnPressAlways
;
338 // do we track the mouse outside the window when it is captured?
339 bool m_trackMouseOutside
;
342 #endif // _WX_UNIV_LISTBOX_H_